@3dsource/angular-unreal-module 0.0.155 → 0.0.156

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.
@@ -1 +1 @@
1
- {"version":3,"file":"3dsource-angular-unreal-module.mjs","sources":["../../../../projects/3dsource/angular-unreal-module/src/lib/constants/buttons-codes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/control-scheme.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/message-type.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/to-client-message-types.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/initial-config.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/input-options.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/CustomCloseCodes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/disconnect-reasons.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/SignalingMessage.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/destroy-disconnect-reasons.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/unreal.constant.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.actions.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.reducer.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.feature.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/sub.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/AnswerHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/ConfigHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/IceCandidateHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/InstanceReadyHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/InstanceReservedHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/PingHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/PlayerCountHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/SSInfoHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnCloseHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnErrorHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnMessageHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OpenHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/keep-max-until-reset.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/data-decoder.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/data-flow-monitor.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/dispatch-resize.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/error-codes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/float-to-smooth-percents.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-image-from-video-stream.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-next-url.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/KalmanFilter1D.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/latency-timings.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/qp-to-quality.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/uint8-to-base64.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/resize-observer.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/make-even.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-resize-values.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.selectors.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/webrtc-error-modal/webrtc-error-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/webrtc-error-modal/webrtc-error-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/services/command-telemetry.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/dev-mode.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/regions-ping.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/StreamerListHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/OfferHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/http-to-ws-url.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/create-websocket.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/ForceDisconnect.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/OrchestrationErrorHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/signalling.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/DataFlowConstants.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/video.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/web-rtc-player.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-adoption.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/unreal-callback.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/unreal-communicator.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-error-modal/unreal-error-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-error-modal/unreal-error-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.effects.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/afk.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/loading-progress.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/freeze-frame.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/deepEqual.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/file-receiver.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/aggregator.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/console-extensions.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/input.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-status-telemetry.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-status-telemetry2.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/ReceivedMimeTypes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/file-handler.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/analytics.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/fps-monitor.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/afk-timeout-modal/afk-timeout-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/afk-timeout-modal/afk-timeout-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/freeze-frame/freeze-frame.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/freeze-frame/freeze-frame.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/pipes/safe-html.pipe.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/low-bandwidth-modal/low-bandwidth-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/low-bandwidth-modal/low-bandwidth-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/image-loading-src/image-loading-src.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/image-loading-src/image-loading-src.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/stat-graph/stat-graph.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/stat-graph/stat-graph.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-status/unreal-status.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-status/unreal-status.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/video-stats/video-stats.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/video-stats/video-stats.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/resume-stream-button/resume-stream-button.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/resume-stream-button/resume-stream-button.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/intro-src/intro-src.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/intro-src/intro-src.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-scene/unreal-scene.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-scene/unreal-scene.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/filter-settings/filter-settings.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/filter-settings/filter-settings.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-state.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-detector.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-detector.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/providers/index.ts","../../../../projects/3dsource/angular-unreal-module/src/3dsource-angular-unreal-module.ts"],"sourcesContent":["export const SpecialKeyCodes = {\n BackSpace: 8,\n Shift: 16,\n Control: 17,\n Alt: 18,\n RightShift: 253,\n RightControl: 254,\n RightAlt: 255,\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\nexport const MouseButton = {\n MainButton: 0, // Left button.\n AuxiliaryButton: 1, // Wheel button.\n SecondaryButton: 2, // Right button.\n FourthButton: 3, // Browser Back button.\n FifthButton: 4, // Browser Forward button.\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons\nexport const MouseButtonsMask = {\n PrimaryButton: 1, // Left button.\n SecondaryButton: 2, // Right button.\n AuxiliaryButton: 4, // Wheel button.\n FourthButton: 8, // Browser Back button.\n FifthButton: 16, // Browser Forward button.\n};\n","export const ControlScheme = {\n // A mouse can lock inside the WebRTC player, so the user can simply move the\n // mouse to control the orientation of the camera. The user presses the\n // Escape key to unlock the mouse.\n LockedMouse: 0,\n // A mouse can hover over the WebRTC player, so the user needs to click and\n // drag to control the orientation of the camera.\n HoveringMouse: 1,\n Default: 2,\n} as const;\n\nexport type ControlSchemeValues =\n (typeof ControlScheme)[keyof typeof ControlScheme];\n","// Must be kept in sync with PixelStreamingProtocol::EToUE4Msg C++ descriptors.\nexport const MessageType = {\n /*\n * Control Messages. Range = 0..49.\n */\n IFrameRequest: 0,\n RequestQualityControl: 1,\n MaxFpsRequest: 2,\n AverageBitrateRequest: 3,\n StartStreaming: 4,\n StopStreaming: 5,\n LatencyTest: 6,\n RequestInitialSettings: 7,\n\n /*\n * Input Messages. Range = 50..89.\n */\n\n // Generic Input Messages. Range = 50..59.\n UIInteraction: 50,\n Command: 51,\n\n // Keyboard Input Message. Range = 60..69.\n KeyDown: 60,\n KeyUp: 61,\n KeyPress: 62,\n\n // Mouse Input Messages. Range = 70..79.\n MouseEnter: 70,\n MouseLeave: 71,\n MouseDown: 72,\n MouseUp: 73,\n MouseMove: 74,\n MouseWheel: 75,\n\n // Touch Input Messages. Range = 80..89.\n TouchStart: 80,\n TouchEnd: 81,\n TouchMove: 82,\n} as const;\n\nexport type MessageTypeValues = (typeof MessageType)[keyof typeof MessageType];\n","export const ToClientMessage = {\n QualityControlOwnership: 0,\n Response: 1,\n Command: 2,\n FreezeFrame: 3,\n UnfreezeFrame: 4,\n VideoEncoderAvgQP: 5,\n LatencyTest: 6,\n InitialSettings: 7,\n FileExtension: 8,\n FileMimeType: 9,\n FileContents: 10,\n TestEcho: 11,\n InputControlOwnership: 12,\n GamepadResponse: 13,\n Protocol: 255,\n} as const;\n","import { InjectionToken } from '@angular/core';\nimport type { UnrealInitialConfig } from '../interfaces';\n\nexport const UNREAL_CONFIG = new InjectionToken<UnrealInitialConfig>(\n 'Unreal Initial Configuration',\n);\n","import { ControlScheme } from './control-scheme';\nimport type { InputProps } from '../interfaces';\n\nexport const InputOptions: InputProps = {\n controlScheme: ControlScheme.Default,\n suppressBrowserKeys: true,\n};\n","export const WSCloseCode_NORMAL_CLOSURE = 3000;\nexport const WSCloseCode_NORMAL_AFK_TIMEOUT = 3001;\nexport const WSCloseCode_NORMAL_MANUAL_DISCONNECT = 3002;\nexport const WSCloseCode_FORCE_CIRRUS_CLOSE = 3003;\n\nexport const WSCloseCode_UNKNOWN = 1000;\n\nexport const WSCloseCode_CIRRUS_PLAYER_DISCONNECTED = 1001;\nexport const WSCloseCode_CIRRUS_ABNORMAL_CLOSURE = 1006;\nexport const WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR = 1013;\nexport const WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER = 1011;\n\nexport const WSCloseCodes = [\n WSCloseCode_NORMAL_CLOSURE,\n WSCloseCode_NORMAL_AFK_TIMEOUT,\n WSCloseCode_NORMAL_MANUAL_DISCONNECT,\n WSCloseCode_FORCE_CIRRUS_CLOSE,\n WSCloseCode_UNKNOWN,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n] as const;\n\nexport type WSCloseCodesValues = (typeof WSCloseCodes)[number];\n","export const DisconnectReason = {\n Afk: 'Afk',\n None: 'None',\n Destroy: 'Destroy',\n DataChannelClosed: 'DataChannelClosed',\n DataChannelTimeout: 'DataChannelTimeout',\n WebRTCError: 'WebRTCError',\n WebSocketError: 'WebSocketError',\n WebSocketClose: 'WebSocketClose',\n DropConnection: 'DropConnection',\n OrchestrationPlayerDisconnected: 'OrchestrationPlayerDisconnected',\n OrchestrationStreamerDisconnected: 'OrchestrationStreamerDisconnected',\n IceConnectionFailed: 'IceConnectionFailed',\n ReconnectFailed: 'ReconnectFailed',\n NewConnectionAttempt: 'NewConnectionAttempt',\n AbortEstablishingConnection: 'AbortEstablishingConnection',\n} as const;\n\nexport type DisconnectReasonType =\n (typeof DisconnectReason)[keyof typeof DisconnectReason];\n\nexport interface ConnectionError {\n reason: DisconnectReasonType;\n message: string;\n}\n","/*\nexport interface RequestReservation extends InstanceMessageBase {\n type: 'requestReservation';\n}\n*/\n\nimport type { SignalingData } from './SignalingData';\n\nexport const OrchestrationMessageTypes = {\n ping: 'ping',\n error: 'error',\n offer: 'offer',\n answer: 'answer',\n ssInfo: 'ssInfo',\n config: 'config',\n playerCount: 'playerCount',\n iceCandidate: 'iceCandidate',\n streamerList: 'streamerList',\n requestStream: 'requestStream',\n listStreamers: 'listStreamers',\n instanceReady: 'instanceReady',\n p2pEstablished: 'p2pEstablished',\n instanceReserved: 'instanceReserved',\n playerDisconnected: 'playerDisconnected',\n streamPreparedForUserInteraction: 'streamPreparedForUserInteraction',\n streamerDisconnected: 'streamerDisconnected',\n interruptClientStream: 'interruptClientStream',\n} as const;\n\nexport interface InstanceReady extends InstanceMessageBase {\n type: 'instanceReady';\n}\n\nexport interface InstanceReserved extends InstanceMessageBase {\n type: 'instanceReserved';\n}\n\nexport interface OrchestrationErrorMessage {\n type: 'error';\n payload: { code: number; message: string };\n}\n\ninterface InstanceMessageBase extends MessageBase {\n correlationId: string;\n payload: {\n instanceId: string;\n streamRequestId: string;\n eta: number;\n };\n}\n\nexport interface MessageBase {\n type: OrchestrationMessageType;\n}\n\nexport interface SSInfo extends MessageBase {\n type: 'ssInfo';\n message: string;\n data: SignalingData;\n}\n\nexport interface PlayerCountMessage extends MessageBase {\n type: 'playerCount';\n playerCount: number;\n}\nexport interface StreamerListMessage extends MessageBase {\n type: 'streamerList';\n ids: string[];\n}\n\nexport interface ConfigMessage extends MessageBase, UnknownFields {\n type: 'config';\n peerConnectionOptions: RTCConfiguration;\n}\n\nexport interface CandidateMessage extends MessageBase {\n type: 'iceCandidate';\n candidate: RTCIceCandidate;\n}\n\nexport interface PingMessage extends MessageBase {\n type: 'ping';\n playerId: string;\n appConnectionCounter: number;\n}\n\nexport type UnknownFields = Record<string, unknown>;\n\nexport interface InterruptClientStream extends MessageBase {\n type: 'interruptClientStream';\n correlationId: string;\n payload: {\n environmentId: string;\n };\n}\n\nexport interface ForceClientDisconnect extends MessageBase {\n type: 'streamerDisconnected' | 'playerDisconnected';\n connectionId: string;\n}\n\nexport interface ListStreamersMessage extends MessageBase {\n type: 'listStreamers';\n correlationId: string;\n}\n\nexport interface P2PEstablishedMessage extends MessageBase {\n type: 'p2pEstablished';\n source: string;\n sessionId: string;\n}\n\nexport interface streamPreparedForUserInteractionMessage extends MessageBase {\n type: 'streamPreparedForUserInteraction';\n correlationId: string;\n}\n\nexport interface RequestStream extends MessageBase {\n type: 'requestStream';\n correlationId: string;\n payload: {\n environmentId: string;\n region?: string;\n /**\n * The context field is used for plugins of the external\n * applications for collecting additional statistics, etc.\n */\n context: StreamRequestContext;\n };\n}\n\ninterface MetaboxBasicConfiguratorContext {\n id: 'metaboxBasicConfigurator';\n data: {\n configuratorId: string;\n };\n}\n\ninterface MetaboxModularConfiguratorContext {\n id: 'metaboxModularConfigurator';\n data: {\n configuratorId: string;\n };\n}\n\ninterface MetaboxProductContext {\n id: 'metaboxProduct';\n data: {\n productId: string;\n };\n}\n\ninterface MetaboxEnvironmentContext {\n id: 'metaboxEnvironment';\n data: {\n environmentId: string;\n };\n}\ninterface MetaboxStudioContext {\n id: 'metaboxStudio';\n data: {\n userId: string;\n workspaceId: string;\n };\n}\ninterface CustomApplicationContext {\n id: 'customApplication';\n data: {\n clientId: string;\n applicationId: string;\n };\n}\n\ninterface MetaboxCustomApplicationContext {\n id: 'metaboxCustomApplication';\n data: {\n clientId: string;\n };\n}\n\nexport type StreamRequestContext =\n | MetaboxStudioContext\n | MetaboxProductContext\n | CustomApplicationContext\n | MetaboxCustomApplicationContext\n | MetaboxEnvironmentContext\n | MetaboxBasicConfiguratorContext\n | MetaboxModularConfiguratorContext;\n\nexport interface SignalingMessageMap {\n [OrchestrationMessageTypes.ping]: PingMessage;\n [OrchestrationMessageTypes.offer]: RTCSessionDescriptionInit;\n [OrchestrationMessageTypes.error]: OrchestrationErrorMessage;\n [OrchestrationMessageTypes.ssInfo]: SSInfo;\n [OrchestrationMessageTypes.config]: ConfigMessage;\n [OrchestrationMessageTypes.answer]: RTCSessionDescriptionInit;\n [OrchestrationMessageTypes.playerCount]: PlayerCountMessage;\n [OrchestrationMessageTypes.iceCandidate]: CandidateMessage;\n [OrchestrationMessageTypes.streamerList]: StreamerListMessage;\n [OrchestrationMessageTypes.instanceReady]: InstanceReady;\n [OrchestrationMessageTypes.requestStream]: RequestStream;\n [OrchestrationMessageTypes.listStreamers]: ListStreamersMessage;\n [OrchestrationMessageTypes.p2pEstablished]: P2PEstablishedMessage;\n [OrchestrationMessageTypes.instanceReserved]: InstanceReserved;\n [OrchestrationMessageTypes.playerDisconnected]: ForceClientDisconnect;\n [OrchestrationMessageTypes.streamPreparedForUserInteraction]: streamPreparedForUserInteractionMessage;\n [OrchestrationMessageTypes.streamerDisconnected]: ForceClientDisconnect;\n [OrchestrationMessageTypes.interruptClientStream]: InterruptClientStream;\n}\n\nexport type OrchestrationMessageType = keyof SignalingMessageMap;\n\n// New strict outbound union type (only valid signaling messages allowed)\nexport type AnySignalingMessage =\n SignalingMessageMap[OrchestrationMessageType] | string;\n\nexport type SignalingMessageHandler<T extends keyof SignalingMessageMap> = (\n msg: SignalingMessageMap[T],\n) => void;\n\nexport interface PollingOrchestrationMessage {\n mm_message?: string;\n signallingServer?: string;\n error?: string;\n info?: {\n age: number | null;\n left: number | null;\n percent: number | null;\n total: number | null;\n };\n}\n","import type { DisconnectReasonType } from '../interfaces';\nimport { DisconnectReason } from '../interfaces';\n\n/** Disconnect reasons that should trigger remote connection cleanup. */\nexport const DESTROY_DISCONNECT_REASONS: DisconnectReasonType[] = [\n DisconnectReason.Afk,\n DisconnectReason.DropConnection,\n DisconnectReason.WebRTCError,\n DisconnectReason.WebSocketError,\n DisconnectReason.WebSocketClose,\n DisconnectReason.ReconnectFailed,\n DisconnectReason.DataChannelClosed,\n DisconnectReason.DataChannelTimeout,\n DisconnectReason.OrchestrationPlayerDisconnected,\n DisconnectReason.OrchestrationStreamerDisconnected,\n];\n","export const DEBOUNCE_TO_MANY_RESIZE_CALLS = 100;\nexport const AUTO_HIGH_RESOLUTION_IDLE_MS = 5000;\nexport const SAME_SIZE_THRESHOLD = 1.01;\n// Minimum container dimension in px — prevents division by zero in resize calculations\nexport const MIN_CONTAINER_SIZE = 2;\nexport const MINIMAL_FPS = 6;\nexport const STREAMING_VIDEO_ID = 'streamingVideo';\nexport const STREAMING_AUDIO_ID = 'streamingAudio';\nexport const FULL_HD_WIDTH = 1920;\nexport const FULL_HD_HEIGHT = 1080;\n// Bound on a single WS upgrade attempt (`createWebSocket`). On cold\n// connections the TCP+TLS+WS handshake can legitimately take 3-5 s\n// (cold DNS, TLS session miss). 2 s was too aggressive — first\n// attempts kept timing out and the second attempt (with warm caches)\n// would connect in <500 ms. 10 s gives slow networks room without\n// letting a truly hung handshake hold up `connectToCirrus` forever.\nexport const WS_TIMEOUT = 6000;\nexport const POLLING_TIME = 4000;\n// Staged retry policy for `SignallingService.connectToSignaling`:\n// INNER_RETRY_LIMIT = max number of WS+orchestration attempts before\n// the pipeline gives up on the current region and bubbles the error\n// to the outer retry. URL rotation (`urlGen`) advances across these.\n// OUTER_RETRY_DELAY = backoff between region re-picks. Intentionally\n// longer than POLLING_TIME so region discovery is rare relative to\n// WS retries.\nexport const INNER_RETRY_LIMIT = 3;\nexport const OUTER_RETRY_DELAY = POLLING_TIME * 2;\n// Extra WS-only retries on the SAME wsUrl (cached AwsInstance) BEFORE\n// falling through to a URL-rotating retry that re-polls orchestration.\n// Why: a fresh `default` poll asks orchestrator to RESERVE a new\n// instance — the previous reservation is orphaned (server-side leak).\n// One quick same-wsUrl retry catches transient WS failures (network\n// blip, brief unavailability) without burning a second reservation.\n// Total WS attempts before URL rotation = 1 + WS_RETRY_PER_INSTANCE.\nexport const WS_RETRY_PER_INSTANCE = 1;\nexport const WS_OPEN_STATE = 1;\nexport const DEFAULT_AFK_TIMEOUT_PERIOD = 15;\nexport const DEFAULT_AFK_TIMEOUT = 300; // 5 minutes\nexport const DATA_CHANNEL_CONNECTION_TIMEOUT = 8000; //ms;\nexport const SIGNALLING_PERCENT_VALUE = 56;\nexport const SCREEN_LOCKER_CONTAINER_ID = '3dsource_start_screen';\n\n// Region-ping prefetch cache. A standalone script\n// (`src/js/region-ping-prefetch.js`) pings the regions the same way\n// `RegionsPingService` does and stores the winner here, so the service can\n// skip live pinging right before a connection. The script CANNOT import these\n// constants (it is framework-free, loaded straight into the host page), so it\n// hardcodes the same literals — keep all three in sync if you change them.\nexport const REGION_PING_CACHE_KEY = '3dsource:region-ping';\n// 1 month. Beyond this the cached winner is considered stale and the service\n// falls back to live pinging.\nexport const REGION_PING_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n// Accurate (background / prefetch) measurement: number of post-warm-up probes\n// per region. The winner is chosen by the MEDIAN of these (tie-break: min),\n// which is robust to jitter — unlike the fast `getFastest` race that just\n// takes the first region to finish.\nexport const REGION_PING_ACCURATE_SAMPLES = 3;\n// Upper bound on the parallel warm-up phase (DNS/TCP/TLS for every region at\n// once). Generous on purpose: warm-up runs OFF the connection critical path\n// (page-load prefetch + post-connection refresh), so accuracy beats speed —\n// a slow-cold-start region must finish warming before it is measured, else it\n// is unfairly penalised (e.g. a 737 ms cold start hiding a 34 ms real RTT).\nexport const REGION_PING_WARMUP_DEADLINE_MS = 1500;\n// Delay after the data channel is ready before the background accurate refresh\n// runs — lets the stream stabilise so the ping sweep does not compete with the\n// freshly-started media for bandwidth.\nexport const REGION_PING_BACKGROUND_REFRESH_DELAY_MS = 5000;\n\n// Reconnection defaults\nexport const RECONNECT_CONFIG = {\n enabled: true,\n maxAttempts: 3,\n delayMs: 1000,\n} as const;\n\nexport const UnrealStatusMessage = {\n CONNECTING_TO_SESSION: 'Connecting to session.',\n STARTING_YOUR_SESSION: 'Starting your session',\n} as const;\n","import { createAction, props } from '@ngrx/store';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport type {\n DisconnectReasonType,\n SignalingData,\n StreamConfig,\n StreamRequestContext,\n} from '../../interfaces';\n\nconst scoped = (templateString: TemplateStringsArray) =>\n `[UNREAL] ${templateString[0]}`;\n\n/**\n * Raw JSON from Unreal can either be wrapped in `commandCallback`\n * (e.g. `{ commandCallback: { command: '...', correlationId: '...' } }`)\n * or be a direct command/event object (e.g. `{ command: 'cameraChanged', payload: {...} }`).\n */\nexport interface UnrealCallbackJsonWrapped {\n commandCallback: MetaBoxCommandPacket;\n timeStamp?: unknown;\n}\n\nexport type UnrealCallbackJson =\n UnrealCallbackJsonWrapped | MetaBoxCommandPacket;\n\nexport const unrealCommandCallback = createAction(\n scoped`unreal command callback`,\n props<{ json: UnrealCallbackJson }>(),\n);\nexport const commandStarted = createAction(\n scoped`command started`,\n props<{ id: string; command: string; timeStamp: number }>(),\n);\nexport const commandCompleted = createAction(\n scoped`command completed`,\n props<{ id: string; now: number }>(),\n);\n\nexport const trackMixpanelEvent = createAction(\n scoped`track Mixpanel event`,\n props<{ event: string; data?: unknown }>(),\n);\nexport const trackTelemetryData = createAction(\n scoped`track telemetry data`,\n props<{ event: string; data?: unknown }>(),\n);\nexport const setMaxFps = createAction(\n scoped`change fps`,\n props<{ maxFps: number }>(),\n);\nexport const destroyRemoteConnections = createAction(\n scoped`destroyRemoteConnections`,\n props<{ reason: DisconnectReasonType }>(),\n);\nexport const destroyUnrealScene = createAction(scoped`destroyUnrealScene`);\nexport const setCirrusConnected = createAction(scoped`cirrusConnected`);\nexport const setCirrusDisconnected = createAction(scoped`cirrusDisconnected`);\nexport const changeStatusMainVideoOnScene = createAction(\n scoped`change status main video on scene`,\n props<{ isVideoPlaying: boolean }>(),\n);\nexport const setAwsInstance = createAction(\n scoped`set aws instance`,\n props<{\n wsUrl: string | null;\n pollingUrl: string | null;\n instanceName: string | null;\n }>(),\n);\nexport const setStatusMessage = createAction(\n scoped`set status message`,\n props<{ statusMessage: string | null }>(),\n);\nexport const setStatusPercentSignallingServer = createAction(\n scoped`change status percent signalling server`,\n props<{ percent: number | null }>(),\n);\nexport const setFreezeFrame = createAction(\n scoped`set freeze frame`,\n props<{\n dataUrl: string | null;\n progress: number | null;\n }>(),\n);\nexport const setStreamClientCompanyId = createAction(\n scoped`set stream client company id`,\n props<{ id: string }>(),\n);\nexport const setStreamViewId = createAction(\n scoped`set stream view id`,\n props<{ id: string }>(),\n);\nexport const setIntroImageSrc = createAction(\n scoped`set intro image src`,\n props<{ src: string }>(),\n);\n\nexport const setLoadingImageSrc = createAction(\n scoped`set loading image src`,\n props<{ src: string }>(),\n);\nexport const setIntroVideoSrc = createAction(\n scoped`set intro video src`,\n props<{ src: string }>(),\n);\nexport const resetIntroSrc = createAction(scoped`reset intro src`);\nexport const setFreezeFrameFromVideo = createAction(\n scoped`set freeze frame from video`,\n props<{\n dataUrl: string | null;\n progress: number | null;\n }>(),\n);\nexport const setEstablishingConnection = createAction(\n scoped`set establishing connection`,\n props<{ value: boolean }>(),\n);\nexport const dataChannelConnected = createAction(\n scoped`data channel connected`,\n props<{ statusMessage: string }>(),\n);\nexport const dataChannelReady = createAction(scoped`dataChannelReady`);\nexport const setConfig = createAction(\n scoped`set config`,\n props<{ config: Partial<StreamConfig> }>(),\n);\nexport const disconnectStream = createAction(\n scoped`disconnectStream`,\n props<{\n reason: DisconnectReasonType;\n message: string;\n }>(),\n);\nexport const dropConnection = createAction(scoped`dropConnection`);\nexport const setViewportReady = createAction(scoped`set viewport ready`);\nexport const setViewportNotReady = createAction(scoped`set viewport not ready`);\nexport const changeStreamResolutionAction = createAction(\n scoped`change stream resolution`,\n props<{\n width: number | null;\n height: number | null;\n }>(),\n);\nexport const setSignalingName = createAction(\n scoped`set aws instanceName`,\n props<{ instanceName: string }>(),\n);\nexport const setOrchestrationParameters = createAction(\n scoped`set orchestration parameters`,\n props<{ instanceName: string; streamRequestId: string; eta: number }>(),\n);\n/**\n * Dispatched when the orchestration server signals that the reserved\n * instance is ready to serve the stream (`instanceReady` WS message).\n * Emitted for observability only — no reducer state change.\n */\nexport const instanceReady = createAction(scoped`instance ready`);\n/**\n * Dispatched when `RegionsPingService.getFastest()` begins — right\n * before the region-list HTTP request goes out. Bookends the entire\n * region-discovery flow together with {@link regionResolved}.\n * Observability-only — no state change.\n */\nexport const regionPingFetchStart = createAction(\n scoped`region ping fetch start`,\n);\n/**\n * Dispatched once `RegionsPingService.getProviders()` returns the region\n * list — i.e., the fetch step is done and the actual per-region ping\n * sweep is about to start. Splits the region-discovery waterfall into\n * two legs: config fetch vs. ping sweep. Observability-only.\n */\nexport const regionPingFetchEnd = createAction(scoped`region ping fetch end`);\n/**\n * Dispatched once the closest region has been resolved by the\n * regions-ping service. Carries every sampled ping RTT to the winning\n * region (one entry per probe — `checkLatency` issues `ping_count`\n * sequential pings per region) so consumers can inspect variance /\n * jitter, not just the mean. Observability-only — no state change.\n */\nexport const regionResolved = createAction(\n scoped`region resolved`,\n props<{\n region: string;\n pingsMs: number[];\n }>(),\n);\n/**\n * Dispatched around the HTTP polling roundup inside `getAwsInstance`\n * (old orchestration flow). Only fires when polling is actually used\n * (i.e., signaling URL is not a direct `ws://` / `wss://` endpoint).\n * Observability-only — no state change.\n */\nexport const pollingStarted = createAction(scoped`polling started`);\nexport const pollingEnded = createAction(scoped`polling ended`);\n/**\n * Dispatched once for every `retry()` attempt inside the signalling\n * connect pipeline. Two kinds:\n *\n * - `'connect'` — outer retry around the whole connect pipeline\n * (region ping → AWS instance → WebSocket). Fires when the WS\n * errors (e.g. \"WebSocket closed before open\") and the entire\n * pipeline is re-subscribed. See `SIGNALLING.md` — every one of\n * these currently triggers a fresh region-ping storm.\n * - `'orchestration'` — inner retry inside `getAwsInstance`,\n * advancing `urlGen` to the next candidate signalling URL when\n * polling fails or returns an error payload.\n *\n * Observability-only — no state change. Surfaces in the viewer's\n * Anomalies table as `signaling_retry` rows so a session that\n * needed N tries shows N entries with their reasons.\n */\nexport const signalingRetryAttempted = createAction(\n scoped`signaling retry attempted`,\n props<{\n attempt: number;\n reason: string;\n // `ws-retry` — WS-only retry on the SAME wsUrl (cached AwsInstance);\n // does NOT re-poll orchestration → no orphaned reservation.\n // `connect` — full inner retry: urlGen rotates → new orchestration poll.\n // `orchestration` — legacy; kept for store-compat.\n // `region-cycle` — outer retry: `getRegion()` re-pinged.\n kind: 'ws-retry' | 'connect' | 'orchestration' | 'region-cycle';\n }>(),\n);\n/**\n * Dispatched when the client has just sent an SDP answer back to Cirrus\n * after receiving the server-initiated offer. Observability-only.\n */\nexport const answerSent = createAction(scoped`answer sent`);\nexport const setOrchestrationMessage = createAction(\n scoped`set orchestration message`,\n props<{ message: string }>(),\n);\nexport const setOrchestrationProgress = createAction(\n scoped`set orchestration progress`,\n props<{ progressComplete: number }>(),\n);\nexport const setOrchestrationContext = createAction(\n scoped`set orchestration params`,\n props<{\n urls: string[];\n environmentId: string;\n streamRequestContext: StreamRequestContext;\n }>(),\n);\nexport const updateCirrusInfo = createAction(\n scoped`set unrealInfo`,\n props<{ ssData: SignalingData }>(),\n);\nexport const setLoopBackCommandIsCompleted = createAction(\n scoped`set loopBack command is completed`,\n);\nexport const setAfkTimerVisible = createAction(scoped`set afk timer visible`);\nexport const setAfkTimerHide = createAction(scoped`set afk timer hide`);\nexport const setAfkTimerCountdown = createAction(\n scoped`set afk timer count down`,\n props<{ countdown: number }>(),\n);\nexport const showUnrealErrorMessage = createAction(\n scoped`show unreal error message`,\n props<{ code: number | null; error?: string }>(),\n);\nexport const initSignalling = createAction(scoped`init signalling`);\n/**\n * Dispatched when a prefetched connection parked on `window.__stream` by the\n * `stream-prefetch.js` head-script is adopted instead of opening a fresh\n * `connectToSignaling`. Marks cirrus connected and records the adopted machine\n * in one transaction; the data channel / app-init chain then proceeds via\n * `dataChannelConnected` dispatched from `WebRtcPlayerService`.\n *\n * Deliberately does NOT touch `streamClientCompanyId` / `streamViewId`: the host\n * app (e.g. metabox) sets those authoritatively from its own data before\n * `initSignalling`, and the prefetch script's ids are connection-internal only.\n */\nexport const streamAdopted = createAction(\n scoped`stream adopted`,\n props<{\n machineId: string | null;\n ssData: SignalingData | null;\n /**\n * `performance.now()` marks the prefetch script recorded while it\n * established the connection (`prefetch_start` / `ws_open` / `dc_open` /\n * `ready`), on the page navigation timeline. The telemetry service uses\n * them to attribute the signaling / webrtc phase durations to the time the\n * prefetch actually spent — instead of dumping the whole pre-adoption wait\n * onto whichever phase closer happens to fire first. `null` when adopting a\n * stream that carried no timings.\n */\n timings: Record<string, number> | null;\n }>(),\n);\nexport const startStream = createAction(\n scoped`startStream`,\n props<{ config: Partial<StreamConfig> }>(),\n);\nexport const resetConfig = createAction(scoped`reset config`);\nexport const resetAfk = createAction(scoped`reset afk action`);\nexport const resetWarnTimeout = createAction(scoped`reset config warn timeout`);\n/**\n * Fan-in for \"cancel an in-flight signalling attempt\". Dispatched by the\n * abortEstablishingConnection$ effect whenever any of these source actions\n * fire: `setCirrusDisconnected` (cirrus dropped), `dropConnection` (user\n * called drop), `destroyUnrealScene` (component teardown). Consumers\n * (`SignallingService.abort$`, `setDataChannelTimeoutCheck$.abort$`) listen\n * to this one action instead of the trio so the \"abort\" intent has a single\n * named entry in Redux DevTools and one subscription site to update.\n */\nexport const abortEstablishingConnection = createAction(\n scoped`abortEstablishingConnection`,\n);\nexport const setUnrealPlaywrightConfig = createAction(\n scoped`set unreal playwright config`,\n);\nexport const saveAnalyticsEvent = createAction(\n scoped`save analytics event`,\n props<{ event: { name: string; params: Record<string, unknown> } }>(),\n);\n/** Action to trigger WebRTC peer reconnection (keeps signaling connection) */\nexport const reconnectPeer = createAction(\n scoped`reconnect peer`,\n props<{ attempt: number; maxAttempts: number; delay?: number }>(),\n);\n/** Action to reset the data channel state before reconnection */\nexport const resetDataChannelForReconnect = createAction(\n scoped`reset data channel for reconnect`,\n);\n/** Action dispatched when peer reconnection succeeds */\nexport const reconnectPeerSuccess = createAction(\n scoped`reconnect peer success`,\n);\n/** Action dispatched when all peer reconnection attempts are exhausted */\nexport const reconnectPeerFailed = createAction(\n scoped`reconnect peer failed`,\n props<{ reason: string }>(),\n);\n/** Action dispatched when ICE connection state changes to failed/disconnected */\nexport const iceConnectionFailed = createAction(\n scoped`ice connection failed`,\n props<{ state: RTCIceConnectionState }>(),\n);\nexport const forceResizeViewport = createAction(scoped`force resize viewport`);\nexport const videoAdaptedToContainer = createAction(\n scoped`video adapted to container`,\n);\nexport const videoStreamInitialized = createAction(\n scoped`video stream initialized`,\n);\nexport const dropDC = createAction(scoped`drop data channel`);\nexport const dropPC = createAction(scoped`drop peer connection`);\nexport const showLoadingProgress = createAction(\n scoped`show loading progress`,\n props<{ visible: boolean }>(),\n);\nexport const showResumeStreamPopup = createAction(\n scoped`show resume stream popup`,\n props<{ visible: boolean }>(),\n);\nexport const showUserInactivityTimeoutPopup = createAction(\n scoped`show user inactivity timeout popup`,\n props<{ visible: boolean }>(),\n);\nexport const setUserInactivityTimeout = createAction(\n scoped`set user inactivity timeout`,\n props<{ timeout: number }>(),\n);\nexport const resetUserInactivityTimeout = createAction(\n scoped`reset user inactivity timeout`,\n);\n","import {\n changeStatusMainVideoOnScene,\n changeStreamResolutionAction,\n commandCompleted,\n commandStarted,\n dataChannelConnected,\n destroyUnrealScene,\n disconnectStream,\n dropConnection,\n initSignalling,\n reconnectPeerSuccess,\n resetConfig,\n resetDataChannelForReconnect,\n resetIntroSrc,\n resetWarnTimeout,\n saveAnalyticsEvent,\n setAfkTimerCountdown,\n setAfkTimerHide,\n setAfkTimerVisible,\n setAwsInstance,\n setCirrusConnected,\n setCirrusDisconnected,\n setConfig,\n setEstablishingConnection,\n setFreezeFrame,\n setFreezeFrameFromVideo,\n setIntroImageSrc,\n setIntroVideoSrc,\n setLoadingImageSrc,\n setLoopBackCommandIsCompleted,\n setOrchestrationContext,\n setOrchestrationMessage,\n setOrchestrationParameters,\n setOrchestrationProgress,\n setSignalingName,\n setStatusMessage,\n setStatusPercentSignallingServer,\n setStreamClientCompanyId,\n setStreamViewId,\n setUnrealPlaywrightConfig,\n setUserInactivityTimeout,\n setViewportNotReady,\n setViewportReady,\n showLoadingProgress,\n showResumeStreamPopup,\n showUserInactivityTimeoutPopup,\n startStream,\n streamAdopted,\n updateCirrusInfo,\n} from './unreal.actions';\nimport { createReducer, on } from '@ngrx/store';\nimport { whereNot } from '@3dsource/utils';\nimport type {\n AwsInstance,\n ConnectionError,\n DisconnectReasonType,\n FreezeFrameMessage,\n SignalingData,\n StreamConfig,\n StreamRequestContext,\n StreamResolutionProps,\n} from '../../interfaces';\nimport { DisconnectReason } from '../../interfaces';\nimport { DEFAULT_AFK_TIMEOUT } from '../../constants';\n\nconst COMMAND_EXILE_TIMEOUT_MS = 10_000;\n\nexport interface CommandInProgress {\n timeStamp: number;\n command: string;\n id: string;\n}\n\nfunction exileExpiredCommands(\n commandsInProgress: CommandInProgress[],\n idToRemove: string,\n now: number,\n): { commandsInProgress: CommandInProgress[]; exiled: number } {\n let remaining = commandsInProgress.filter(whereNot({ id: idToRemove }));\n const expired = remaining.filter(\n ({ timeStamp }) => now - timeStamp > COMMAND_EXILE_TIMEOUT_MS,\n );\n if (expired.length) {\n const expiredIds = new Set(expired.map(({ id }) => id));\n remaining = remaining.filter(({ id }) => !expiredIds.has(id));\n }\n return { commandsInProgress: remaining, exiled: expired.length };\n}\n\nexport interface UnrealState {\n streamConfig: StreamConfig;\n userInactivityTimeout: number;\n awsInstance: AwsInstance;\n isFirstSuccessLoad: boolean;\n isAfkTimerVisible: boolean;\n afkCountdown: number;\n cirrusConnected: boolean;\n /**\n * True once a prefetched connection has been adopted (`streamAdopted`).\n * Read synchronously by the telemetry service so the connection-phase\n * closers know to defer to the prefetch-timed attribution instead of the\n * live-event one. Reset on every fresh attempt / disconnect.\n */\n adopted: boolean;\n viewportReady: boolean;\n freezeFrameFromVideo: FreezeFrameMessage;\n freezeFrame: FreezeFrameMessage;\n statusMessage: string | null;\n ssData: SignalingData | null;\n statusPercentSignallingServer: number | null;\n errorMessage: ConnectionError | null;\n isReconnecting: boolean;\n dataChannelConnected: boolean;\n streamResolution: StreamResolutionProps;\n isVideoPlaying: boolean;\n establishingConnection: boolean;\n disconnectReason: DisconnectReasonType;\n matchUrls: string[];\n environmentId: string | null;\n streamClientCompanyId: string | null;\n streamViewId: string | null;\n videoIntroSrc: string | null;\n imageIntroSrc: string | null;\n imageLoadingSrc: string;\n streamRequestContext: StreamRequestContext | null;\n analyticsEvent: { name: string; params: Record<string, unknown> } | null;\n showLoadingProgress: boolean;\n showResumeStreamPopup: boolean;\n showAfkTimeoutPopup: boolean;\n // Command tracking — drives `selectCommandProgress` (% of loading bar).\n commandsInProgress: CommandInProgress[];\n totalCommandsStarted: number;\n totalCommandsCompleted: number;\n}\n\nconst initialState: UnrealState = {\n streamRequestContext: null,\n environmentId: null,\n isFirstSuccessLoad: false,\n isAfkTimerVisible: false,\n afkCountdown: 0,\n cirrusConnected: false,\n adopted: false,\n establishingConnection: false,\n isReconnecting: false,\n viewportReady: false,\n dataChannelConnected: false,\n isVideoPlaying: false,\n statusPercentSignallingServer: null,\n statusMessage: null,\n errorMessage: null,\n ssData: null,\n streamResolution: { width: null, height: null },\n freezeFrameFromVideo: { dataUrl: null, progress: null },\n freezeFrame: { dataUrl: null, progress: null },\n disconnectReason: DisconnectReason.None,\n awsInstance: {\n wsUrl: null,\n instanceName: null,\n pollingUrl: null,\n progressComplete: 0,\n },\n streamConfig: {\n autoStart: true,\n warnTimeout: DEFAULT_AFK_TIMEOUT,\n },\n userInactivityTimeout: DEFAULT_AFK_TIMEOUT,\n matchUrls: [],\n streamClientCompanyId: '',\n streamViewId: 'default',\n videoIntroSrc: null,\n imageIntroSrc: null,\n imageLoadingSrc: '',\n analyticsEvent: null,\n showLoadingProgress: true,\n showResumeStreamPopup: true,\n showAfkTimeoutPopup: true,\n commandsInProgress: [],\n totalCommandsStarted: 0,\n totalCommandsCompleted: 0,\n};\nexport const unrealReducer = createReducer(\n initialState,\n on(changeStatusMainVideoOnScene, (state, { isVideoPlaying }): UnrealState => {\n return { ...state, isVideoPlaying };\n }),\n on(\n setAwsInstance,\n (state, { instanceName, wsUrl, pollingUrl }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n instanceName,\n wsUrl,\n pollingUrl,\n progressComplete: 0,\n },\n };\n },\n ),\n on(setViewportReady, (state): UnrealState => {\n return {\n ...state,\n viewportReady: true,\n statusMessage: null,\n errorMessage: null,\n };\n }),\n on(setViewportNotReady, (state): UnrealState => {\n return { ...state, viewportReady: false };\n }),\n on(updateCirrusInfo, (state, { ssData }): UnrealState => {\n return { ...state, ssData: ssData };\n }),\n on(changeStreamResolutionAction, (state, { width, height }): UnrealState => {\n if (\n !width ||\n !height ||\n (state.streamResolution.width === width &&\n state.streamResolution.height === height)\n ) {\n return state;\n }\n return { ...state, streamResolution: { width, height } };\n }),\n on(setFreezeFrame, (state, freezeFrame): UnrealState => {\n return {\n ...state,\n freezeFrame: {\n dataUrl:\n freezeFrame.progress === 0 ||\n freezeFrame.progress === 1 ||\n freezeFrame.progress === null\n ? freezeFrame.dataUrl\n : state.freezeFrame.dataUrl,\n progress: freezeFrame.progress ?? null,\n },\n };\n }),\n on(disconnectStream, (state, errorMessage): UnrealState => {\n // Skip user-explicit destroy: the user already initiated cleanup, no\n // disconnect message should overwrite that intent.\n if (state.disconnectReason === DisconnectReason.Destroy) {\n return state;\n }\n // The first non-None reason wins, so the resume popup keeps showing the\n // original cause (e.g. 'Afk' isn't overwritten by 'DataChannelClosed'\n // when the AFK teardown closes the channel). Cleanup effects still run\n // on every disconnectStream dispatch — only the state stays pinned.\n const disconnectReason =\n state.disconnectReason === DisconnectReason.None\n ? errorMessage.reason\n : state.disconnectReason;\n return { ...state, errorMessage, statusMessage: null, disconnectReason };\n }),\n on(setFreezeFrameFromVideo, (state, freezeFrameFromVideo): UnrealState => {\n return {\n ...state,\n freezeFrameFromVideo: {\n dataUrl: freezeFrameFromVideo.dataUrl,\n progress: freezeFrameFromVideo.progress || null,\n },\n };\n }),\n on(setStatusMessage, (state, { statusMessage }): UnrealState => {\n return { ...state, statusMessage };\n }),\n on(setEstablishingConnection, (state, { value }): UnrealState => {\n return { ...state, establishingConnection: value };\n }),\n on(setStatusPercentSignallingServer, (state, { percent }): UnrealState => {\n return { ...state, statusPercentSignallingServer: percent };\n }),\n on(dataChannelConnected, (state, { statusMessage }): UnrealState => {\n return {\n ...state,\n statusMessage,\n dataChannelConnected: true,\n establishingConnection: false,\n };\n }),\n on(setConfig, startStream, (state, { config }): UnrealState => {\n return { ...state, streamConfig: { ...state.streamConfig, ...config } };\n }),\n on(resetWarnTimeout, (state): UnrealState => {\n return {\n ...state,\n streamConfig: {\n ...state.streamConfig,\n warnTimeout: state.userInactivityTimeout,\n },\n };\n }),\n on(resetConfig, (state): UnrealState => {\n return {\n ...state,\n streamConfig: {\n ...initialState.streamConfig,\n warnTimeout: state.userInactivityTimeout,\n },\n };\n }),\n on(initSignalling, (state): UnrealState => {\n return {\n ...state,\n adopted: false,\n disconnectReason: DisconnectReason.None,\n };\n }),\n on(reconnectPeerSuccess, (state): UnrealState => {\n return { ...state, isReconnecting: false };\n }),\n on(setSignalingName, (state, { instanceName }): UnrealState => {\n return { ...state, awsInstance: { ...state.awsInstance, instanceName } };\n }),\n on(\n setOrchestrationParameters,\n (state, { instanceName, streamRequestId, eta }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n message: undefined,\n instanceName,\n streamRequestId,\n eta,\n },\n };\n },\n ),\n on(setOrchestrationProgress, (state, { progressComplete }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n progressComplete,\n },\n };\n }),\n on(setOrchestrationMessage, (state, { message }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n message,\n },\n };\n }),\n on(setLoopBackCommandIsCompleted, (state): UnrealState => {\n return { ...state, isFirstSuccessLoad: true };\n }),\n on(setAfkTimerCountdown, (state, { countdown }): UnrealState => {\n return { ...state, afkCountdown: countdown };\n }),\n on(setAfkTimerVisible, (state): UnrealState => {\n return { ...state, isAfkTimerVisible: true };\n }),\n on(setAfkTimerHide, (state): UnrealState => {\n return { ...state, isAfkTimerVisible: false, afkCountdown: 0 };\n }),\n on(\n setOrchestrationContext,\n (state, { urls, environmentId, streamRequestContext }): UnrealState => {\n return {\n ...state,\n matchUrls: urls,\n environmentId,\n streamRequestContext,\n };\n },\n ),\n on(setStreamClientCompanyId, (state, { id }): UnrealState => {\n return { ...state, streamClientCompanyId: id };\n }),\n on(setStreamViewId, (state, { id }): UnrealState => {\n return { ...state, streamViewId: id };\n }),\n on(setIntroImageSrc, (state, { src }): UnrealState => {\n return { ...state, imageIntroSrc: src };\n }),\n on(setLoadingImageSrc, (state, { src }): UnrealState => {\n return { ...state, imageLoadingSrc: src };\n }),\n on(setIntroVideoSrc, (state, { src }): UnrealState => {\n return { ...state, videoIntroSrc: src };\n }),\n on(resetIntroSrc, (state): UnrealState => {\n return { ...state, imageIntroSrc: '', videoIntroSrc: '' };\n }),\n on(saveAnalyticsEvent, (state, { event }): UnrealState => {\n return { ...state, analyticsEvent: event };\n }),\n on(setCirrusConnected, (state): UnrealState => {\n return { ...state, cirrusConnected: true };\n }),\n on(streamAdopted, (state, { machineId, ssData }): UnrealState => {\n return {\n ...state,\n cirrusConnected: true,\n adopted: true,\n ssData: ssData ?? state.ssData,\n awsInstance: {\n ...state.awsInstance,\n wsUrl: machineId,\n pollingUrl: null,\n instanceName: 'Adopted Connection',\n progressComplete: 0,\n },\n };\n }),\n on(showLoadingProgress, (state, { visible }): UnrealState => {\n return { ...state, showLoadingProgress: visible };\n }),\n on(showResumeStreamPopup, (state, { visible }): UnrealState => {\n return { ...state, showResumeStreamPopup: visible };\n }),\n on(showUserInactivityTimeoutPopup, (state, { visible }): UnrealState => {\n return { ...state, showAfkTimeoutPopup: visible };\n }),\n on(setUserInactivityTimeout, (state, { timeout }): UnrealState => {\n return {\n ...state,\n userInactivityTimeout: timeout,\n streamConfig: { ...state.streamConfig, warnTimeout: timeout },\n };\n }),\n on(setCirrusDisconnected, (state): UnrealState => {\n // Reset only the live connection / video pipeline fields. Anything not\n // listed here survives the drop (config, intro media, identifiers, etc.)\n // and is therefore implicitly safe when new state fields are added.\n // `errorMessage` and `disconnectReason` are explicitly kept so the UI\n // can render the reason after the connection drops.\n return {\n ...state,\n cirrusConnected: false,\n adopted: false,\n dataChannelConnected: false,\n viewportReady: false,\n isVideoPlaying: false,\n isReconnecting: false,\n isAfkTimerVisible: false,\n afkCountdown: 0,\n ssData: null,\n statusPercentSignallingServer: null,\n statusMessage: null,\n streamResolution: { width: null, height: null },\n freezeFrame: { dataUrl: null, progress: null },\n freezeFrameFromVideo: { dataUrl: null, progress: null },\n awsInstance: { ...initialState.awsInstance },\n commandsInProgress: [],\n totalCommandsStarted: 0,\n totalCommandsCompleted: 0,\n };\n }),\n on(dropConnection, (state): UnrealState => {\n return { ...state, establishingConnection: false };\n }),\n on(resetDataChannelForReconnect, (state): UnrealState => {\n return {\n ...state,\n isReconnecting: true,\n dataChannelConnected: false,\n viewportReady: false,\n statusMessage: 'Reconnecting...',\n };\n }),\n on(setUnrealPlaywrightConfig, (state): UnrealState => {\n return {\n ...state,\n cirrusConnected: true,\n viewportReady: true,\n dataChannelConnected: true,\n isVideoPlaying: true,\n };\n }),\n on(destroyUnrealScene, (): UnrealState => {\n // Pin `disconnectReason: Destroy` so any in-flight disconnectStream\n // actions are ignored by the sticky-Destroy guard above.\n return { ...initialState, disconnectReason: DisconnectReason.Destroy };\n }),\n on(commandStarted, (state, { id, command, timeStamp }): UnrealState => ({\n ...state,\n totalCommandsStarted: state.totalCommandsStarted + 1,\n commandsInProgress: [\n ...state.commandsInProgress,\n { id, command, timeStamp },\n ],\n })),\n on(commandCompleted, (state, { id, now }): UnrealState => {\n const { commandsInProgress, exiled } = exileExpiredCommands(\n state.commandsInProgress,\n id,\n now,\n );\n return {\n ...state,\n commandsInProgress,\n // +1 for the just-completed command, +exiled for stragglers we GC'd.\n totalCommandsCompleted: state.totalCommandsCompleted + 1 + exiled,\n };\n }),\n);\n","import { createFeature } from '@ngrx/store';\nimport { unrealReducer } from './unreal.reducer';\n\nexport const unrealFeature = createFeature({\n name: 'unrealFeature',\n reducer: unrealReducer,\n});\n","import { share, skip, Subject } from 'rxjs';\nimport { Store } from '@ngrx/store';\nimport { DestroyRef, inject } from '@angular/core';\n// Import from the leaf file rather than the `../store` barrel: the barrel\n// pulls in `unreal.effects.ts`, which depends on the services module, which\n// re-exports `SubService` — a circular load order that surfaces as\n// `Class extends value undefined` when test files trigger the chain.\nimport { unrealFeature } from '../store/unreal/unreal.feature';\nimport { filter } from 'rxjs/operators';\nimport { Falsy } from '@3dsource/utils';\nimport { Actions } from '@ngrx/effects';\n\nexport class SubService {\n protected readonly destroyRef = inject(DestroyRef);\n protected readonly destroy$ = new Subject<void>();\n protected readonly actions$ = inject(Actions);\n protected readonly store = inject(Store);\n\n disconnect$ = this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(skip(1), filter(Falsy), share());\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.destroy$.next();\n this.destroy$.complete();\n });\n }\n}\n","import type { SignallingService } from '../../services';\n\nexport function AnswerHandler(\n this: SignallingService,\n msg: RTCSessionDescriptionInit,\n) {\n this.onWebRtcAnswer$.next(msg);\n}\n","import type { SignallingService } from '../../services';\nimport type { ConfigMessage } from '../../interfaces';\n\nexport function ConfigHandler(this: SignallingService, msg: ConfigMessage) {\n this.onConfig$.next(msg);\n\n //DO NOT REMOVE. Possible required in future for SFU\n /*this.send({\n type: OrchestrationMessageTypes.listStreamers,\n correlationId: this.correlationId,\n });*/\n}\n","import type { SignallingService } from '../../services';\n\nexport function IceCandidateHandler(\n this: SignallingService,\n msg: { candidate: RTCIceCandidate },\n) {\n this.onWebRtcIce$.next(msg.candidate);\n}\n","import type { SignallingService } from '../../services';\nimport { instanceReady } from '../../store';\n\nexport function InstanceReadyHandler(this: SignallingService) {\n // No state change — emit the action purely so services that want to\n // observe orchestration progress (e.g. telemetry) have a hook.\n this.store.dispatch(instanceReady());\n}\n","import type { InstanceReserved } from '../../interfaces';\nimport type { SignallingService } from '../../services';\nimport { setOrchestrationParameters } from '../../store';\n\nexport function InstanceReservedHandler(\n this: SignallingService,\n msg: InstanceReserved,\n) {\n this.store.dispatch(\n setOrchestrationParameters({\n instanceName: msg.payload.instanceId,\n streamRequestId: msg.payload.streamRequestId,\n eta: msg.payload.eta ?? 150,\n }),\n );\n}\n","import type { SignallingService } from '../../services';\n\nexport function PingHandler(this: SignallingService) {\n this.send(\n JSON.stringify({\n type: 'pong',\n source: 'front',\n }),\n );\n}\n","import type { SignallingService } from '../..//services';\nimport type { PlayerCountMessage } from '../..//interfaces';\nimport { Logger } from '@3dsource/utils';\n\nexport function PlayerCountHandler(\n this: SignallingService,\n msg: PlayerCountMessage,\n) {\n Logger.log(msg);\n}\n","import type { SignallingService } from '../../services';\nimport type { SSInfo } from '../../interfaces';\nimport { updateCirrusInfo } from '../../store';\n\nexport function SSInfoHandler(this: SignallingService, msg: SSInfo) {\n this.store.dispatch(updateCirrusInfo({ ssData: msg.data }));\n return null;\n}\n","import type { SignallingService } from '../../services';\nimport { dropConnection, setCirrusDisconnected } from '../../store';\nimport { Logger } from '@3dsource/utils';\nimport {\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n WSCloseCode_UNKNOWN,\n} from '../../interfaces';\n\nconst dropCodes = [\n WSCloseCode_UNKNOWN,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n];\n\nexport function OnCloseHandler(this: SignallingService, e: CloseEvent) {\n const message = `WebSocket closed: ${JSON.stringify(e.code)} - ${e.reason}`;\n Logger.warn(message);\n this.store.dispatch(setCirrusDisconnected());\n\n if (dropCodes.includes(e.code)) {\n this.store.dispatch(dropConnection());\n }\n}\n","import type { SignallingService } from '../../services';\nimport { Logger } from '@3dsource/utils';\nimport { disconnectStream } from '../../store';\nimport { DisconnectReason } from '../../interfaces';\n\nexport function OnErrorHandler(this: SignallingService, e: Event) {\n Logger.warn(`WS error: ${JSON.stringify(e)}`);\n\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebSocketError,\n message: 'WebSocket Error',\n }),\n );\n}\n","import type { SignallingService } from '../../services';\nimport { Logger } from '@3dsource/utils';\n\nexport function OnMessageHandler(\n this: SignallingService,\n e: MessageEvent<string | Blob>,\n) {\n const handleData = (data: string) => {\n //Logger.colored(...COLOR_CODES.FROM_SIGNALING, data);\n const msg = JSON.parse(data);\n this.handleMessage(msg);\n };\n\n if (typeof e.data === 'string') {\n try {\n handleData(e.data);\n } catch (err) {\n Logger.warn('OnMessageHandler: failed to parse string message', err);\n }\n } else if (e.data instanceof Blob) {\n e.data\n .text()\n .then(handleData)\n .catch((err) =>\n Logger.warn('OnMessageHandler: failed to parse Blob message', err),\n );\n }\n}\n","import type { SignallingService } from '../../services';\nimport { setCirrusConnected } from '../../store';\n\nexport function OnOpenHandler(this: SignallingService) {\n this.store.dispatch(setCirrusConnected());\n this.sendRequestStream();\n}\n","import type { Observable, OperatorFunction } from 'rxjs';\nimport { map, merge, scan } from 'rxjs';\n\n/**\n * Keeps the max of numbers seen so far; resets to 0 whenever `reset$` emits.\n */\nexport const keepMaxUntilReset =\n (reset$: Observable<unknown>): OperatorFunction<number, number> =>\n (source$) =>\n merge(source$, reset$.pipe(map(() => null))).pipe(\n scan<number | null, number>(\n (max, value) => (value === null ? 0 : Math.max(max, value)),\n 0,\n ),\n );\n","// Reused across every inbound data-channel message — instantiating a\n// TextDecoder per call adds needless GC churn on a hot path.\nconst utf16Decoder = new TextDecoder('utf-16');\n\nexport function decodeData(anyData: ArrayBuffer) {\n try {\n return utf16Decoder.decode(anyData);\n } catch {\n return '';\n }\n}\n","import type { Quality } from '../interfaces';\nimport { calculateMedian, clampf } from '@3dsource/utils';\nimport type { FilterSettings } from '../components/low-bandwidth/DataFlowConstants';\n\nexport interface DataFlowCheckResult {\n isDropDetected: boolean;\n dropPercentage: number;\n activeMedian: number;\n quality: Quality;\n message: string;\n /** Optional diagnostic snapshot — only populated on demand to avoid a\n * per-tick array copy on this 4 Hz hot path. */\n dataHistory?: number[];\n config: {\n yellowFlagThresholdPercentage: number;\n redFlagThresholdPercentage: number;\n historyBufferLength: number;\n splitPoint: number;\n };\n}\n\nexport class DataFlowMonitor {\n protected dataHistory: number[] = [];\n\n /**\n * Initializes the DataFlowMonitor monitor.\n * @param yellowFlagThresholdPercentage - The percentage drop to trigger a YELLOW warning (default: 15%).\n * @param redFlagThresholdPercentage - The percentage drop to trigger a RED warning (default: 30%).\n * @param historyBufferLength - buffer length (default: 100).\n * @param splitPoint - The point at which to split the history buffer into two halves (default: 0.5).\n */\n constructor(\n protected yellowFlagThresholdPercentage = 15,\n protected redFlagThresholdPercentage = 30,\n protected historyBufferLength = 100,\n protected splitPoint = 0.5,\n ) {}\n\n reset() {\n this.dataHistory.length = 0;\n }\n\n config(data: FilterSettings) {\n this.reset();\n this.yellowFlagThresholdPercentage = data.yellowFlag;\n this.redFlagThresholdPercentage = data.redFlag;\n }\n\n /**\n * Adds a new bitrate measurement and checks for significant drops.\n * @param currentValue - The current bitrate in kbps.\n * @returns BitrateCheckResult indicating if a drop was detected.\n */\n addValue(currentValue: number): DataFlowCheckResult {\n if (isNaN(currentValue) || currentValue < 1) {\n return {} as DataFlowCheckResult;\n }\n const historyLength = this.dataHistory.length;\n\n if (historyLength > this.historyBufferLength) {\n this.dataHistory.shift();\n }\n this.dataHistory.push(currentValue);\n\n if (historyLength < this.historyBufferLength) {\n this.dataHistory.length = this.historyBufferLength;\n this.dataHistory.fill(currentValue, 0, this.historyBufferLength);\n }\n\n const splitIndex = Math.floor(historyLength * this.splitPoint);\n const firstHalf = this.dataHistory.slice(0, splitIndex);\n const secondHalf = this.dataHistory.slice(splitIndex);\n const firstHalfMedian = calculateMedian(firstHalf);\n const secondHalfMedian = calculateMedian(secondHalf);\n\n const dropPercentage = clampf(\n 0,\n 100,\n ((firstHalfMedian - secondHalfMedian) / firstHalfMedian) * 100,\n );\n\n const isRedFlag = dropPercentage >= this.redFlagThresholdPercentage;\n if (dropPercentage >= this.yellowFlagThresholdPercentage) {\n return {\n config: {\n yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,\n redFlagThresholdPercentage: this.redFlagThresholdPercentage,\n historyBufferLength: this.historyBufferLength,\n splitPoint: this.splitPoint,\n },\n isDropDetected: true,\n dropPercentage,\n activeMedian: secondHalfMedian,\n quality: isRedFlag ? 'red' : 'orange',\n message: `Significant flow drop detected: ${dropPercentage.toFixed(2)}% (from ${firstHalfMedian} to ${secondHalfMedian})`,\n };\n }\n\n return {\n config: {\n yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,\n redFlagThresholdPercentage: this.redFlagThresholdPercentage,\n historyBufferLength: this.historyBufferLength,\n splitPoint: this.splitPoint,\n },\n isDropDetected: false,\n dropPercentage,\n activeMedian: secondHalfMedian,\n quality: 'lime',\n message: 'Stable flow',\n };\n }\n}\n","export const dispatchResize = () => {\n window.dispatchEvent(new Event('resize'));\n};\n","const errorCodes: Record<`code${number}`, string | undefined> = {\n code404:\n 'Your asset is being synced on Metabox servers and is not yet available in Metabox Studio or Metabox Configurator. Please check again later after syncing is complete. ',\n};\n\nexport function getRtcErrorMessage(code: number | null) {\n if (code === null) {\n return undefined;\n }\n\n return errorCodes[`code${code}`];\n}\n","import type { Observable, OperatorFunction } from 'rxjs';\nimport {\n animationFrameScheduler,\n concatMap,\n interval,\n of,\n pairwise,\n startWith,\n timestamp,\n} from 'rxjs';\nimport { distinctUntilChanged, map, takeWhile } from 'rxjs/operators';\nimport { clampf, lerp } from '@3dsource/utils';\n\nconst JUMP_THRESHOLD = 0.95;\nconst MAX_TRANSITION_DURATION_MS = 200;\n\n/**\n * Maps a 0..1 stream directly to a 0..100 integer percent stream.\n * No animation — emits whatever the source emits, rounded and clamped.\n */\nexport const floatToPercents =\n (): OperatorFunction<number, number> => (source) =>\n source.pipe(map((value) => clampf(0, 100, Math.round(value * 100))));\n\n/**\n * Maps a 0..1 progress stream to a smoothed 0..100 integer percent stream.\n * Animates between consecutive values over up to 200ms; jumps directly when\n * the delta exceeds 0.95 (treated as a reset, not a real progression).\n */\nexport const floatToSmoothPercents =\n (): OperatorFunction<number, number> => (source) =>\n source.pipe(\n timestamp(),\n startWith({ value: 0, timestamp: 0 }),\n pairwise(),\n concatMap(([prev, curr]) => {\n const isJump = Math.abs(curr.value - prev.value) > JUMP_THRESHOLD;\n const dt = prev.timestamp ? curr.timestamp - prev.timestamp : 0;\n if (isJump || dt === 0) {\n return of(curr.value);\n }\n return smoothTransition(\n prev.value,\n curr.value,\n Math.min(dt, MAX_TRANSITION_DURATION_MS),\n );\n }),\n floatToPercents(),\n );\n\n/**\n * Smoothly interpolates from `start` to `end` over `duration`ms using the\n * animation frame scheduler. Completes when the transition finishes.\n *\n * NOTE: duplicates `smoothTransition` from `@3dsource/utils`. The utils version\n * is missing `takeWhile(... < 1, true)` and never completes — which would\n * deadlock the `concatMap` above. Keep this local copy until utils is fixed.\n */\nexport const smoothTransition = (\n start: number,\n end: number,\n duration: number,\n): Observable<number> => {\n const startTime = animationFrameScheduler.now();\n return interval(0, animationFrameScheduler).pipe(\n map(() =>\n clampf(0, 1, (animationFrameScheduler.now() - startTime) / duration),\n ),\n distinctUntilChanged(),\n takeWhile((fraction) => fraction < 1, true),\n map((fraction) => lerp(start, end, fraction)),\n );\n};\n","import {\n FULL_HD_HEIGHT,\n FULL_HD_WIDTH,\n STREAMING_VIDEO_ID,\n} from '../constants';\nimport type { ImageOutputValues } from '@3dsource/utils';\nimport { getCanvasCached, getSnapshot } from '@3dsource/utils';\nimport type { StreamResolutionProps } from '../interfaces';\n\nexport const getImageFromVideoStream = (\n takeSizeFrom: 'video' | 'constant' = 'video',\n imageOutput?: ImageOutputValues,\n sizes?: StreamResolutionProps,\n) => {\n try {\n const video = document.getElementById(\n STREAMING_VIDEO_ID,\n ) as HTMLVideoElement;\n const { canvas, ctx } = getCanvasCached('video');\n\n canvas.width =\n takeSizeFrom === 'video'\n ? sizes?.width || video?.clientWidth || FULL_HD_WIDTH\n : FULL_HD_WIDTH;\n canvas.height =\n takeSizeFrom === 'video'\n ? sizes?.height || video?.clientHeight || FULL_HD_HEIGHT\n : FULL_HD_HEIGHT;\n\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n\n return getSnapshot(canvas, canvas.width, imageOutput) as string;\n } catch {\n return null;\n }\n};\n","/**\n * Generator that cycles through `urls` indefinitely. Each call to\n * `getActiveUrl(urls)` returns a fresh generator with its own counter,\n * so concurrent generators (e.g., overlapping reconnect attempts) do\n * not share state. The counter is initialized once per generator\n * instance — before any `yield` — so each `.next()` call advances\n * within that single generator.\n */\nexport function* getActiveUrl(urls: string[]) {\n let index = 0;\n while (true) {\n yield urls[index++ % urls.length];\n }\n}\n","import type { FilterSettings } from '../components/low-bandwidth/DataFlowConstants';\n\nexport class KalmanFilter1D {\n private estimate: number;\n private uncertainty: number;\n private processNoise: number;\n private measurementNoise: number;\n\n /**\n * @param initialEstimate Initial guess of the state.\n * @param initialUncertainty Initial uncertainty in the guess.\n * @param processNoise Process variance (Q) representing model uncertainty.\n * @param measurementNoise Measurement variance (R) representing noise in measurements.\n */\n constructor(\n initialEstimate: number,\n initialUncertainty: number,\n processNoise: number,\n measurementNoise: number,\n ) {\n this.estimate = initialEstimate;\n this.uncertainty = initialUncertainty;\n this.processNoise = processNoise;\n this.measurementNoise = measurementNoise;\n }\n\n /**\n * Incorporates a new measurement and returns the updated estimate.\n * @param measurement The new measurement value.\n */\n update(measurement: number): number {\n // === Prediction Step ===\n // For a constant model, the predicted state is the previous estimate.\n const predictedEstimate = this.estimate;\n // Increase the uncertainty by the process noise.\n const predictedUncertainty = this.uncertainty + this.processNoise;\n\n // === Update Step ===\n // Compute the innovation or measurement residual.\n const innovation = measurement - predictedEstimate;\n // Compute the innovation covariance.\n const innovationCovariance = predictedUncertainty + this.measurementNoise;\n // Compute the Kalman Gain.\n const kalmanGain = predictedUncertainty / innovationCovariance;\n\n // Update the estimate with the measurement, weighted by the Kalman Gain.\n this.estimate = predictedEstimate + kalmanGain * innovation;\n // Update the uncertainty.\n this.uncertainty = (1 - kalmanGain) * predictedUncertainty;\n\n return this.estimate;\n }\n\n config(data: FilterSettings) {\n const {\n initialBitrateEstimate,\n initialErrorCovariance,\n processNoise,\n measurementNoise,\n } = data;\n this.estimate = initialBitrateEstimate;\n this.uncertainty = initialErrorCovariance;\n this.processNoise = processNoise;\n this.measurementNoise = measurementNoise;\n }\n}\n","export class LatencyTimings {\n TestStartTimeMs: number | null = null;\n UEReceiptTimeMs: number | null = null;\n UEEncodeMs: number | null = null;\n UECaptureToSendMs: number | null = null;\n UETransmissionTimeMs: number | null = null;\n BrowserReceiptTimeMs: number | null = null;\n FrameDisplayDeltaTimeMs: number | null = null;\n\n Reset() {\n this.TestStartTimeMs = null;\n this.UEReceiptTimeMs = null;\n this.UEEncodeMs = null;\n this.UECaptureToSendMs = null;\n this.UETransmissionTimeMs = null;\n this.BrowserReceiptTimeMs = null;\n this.FrameDisplayDeltaTimeMs = null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n SetUETimings(UETimings: any) {\n this.UEReceiptTimeMs = UETimings.ReceiptTimeMs;\n this.UEEncodeMs = UETimings.EncodeMs;\n this.UECaptureToSendMs = UETimings.CaptureToSendMs;\n this.UETransmissionTimeMs = UETimings.TransmissionTimeMs;\n this.BrowserReceiptTimeMs = Date.now();\n }\n\n SetFrameDisplayDeltaTime(DeltaTimeMs: number) {\n if (this.FrameDisplayDeltaTimeMs == null) {\n this.FrameDisplayDeltaTimeMs = Math.round(DeltaTimeMs);\n }\n }\n}\n","import type { Quality } from '../interfaces';\n\nexport function qpToQuality(VideoEncoderQP: number) {\n const orangeQP = 26;\n const redQP = 35;\n\n let quality: Quality = 'lime';\n if (VideoEncoderQP > redQP) {\n quality = 'red';\n } else if (VideoEncoderQP > orangeQP) {\n quality = 'orange';\n }\n return quality;\n}\n","/**\n * Base64-encodes a byte array.\n *\n * Builds the intermediate binary string in fixed-size chunks instead of\n * concatenating one character at a time. The naive `bytes.reduce((s, b) => s +\n * String.fromCharCode(b), '')` is O(n²) (each `+` re-copies the growing string)\n * and stalls the main thread for a full-resolution frame; chunking keeps it\n * O(n). The chunk size stays under the argument-count limit of\n * `String.fromCharCode.apply`/spread.\n *\n * @param bytes - The raw bytes to encode.\n * @returns The Base64 representation of `bytes`.\n */\nexport function uint8ToBase64(bytes: Uint8Array): string {\n const CHUNK_SIZE = 0x8000;\n let binary = '';\n for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {\n binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK_SIZE));\n }\n return btoa(binary);\n}\n","import { Observable } from 'rxjs';\n\nexport function fromResizeObserver(\n elem: HTMLElement,\n): Observable<ResizeObserverEntry[]> {\n return new Observable((subscriber) => {\n const observer = new window.ResizeObserver((entries) =>\n subscriber.next(entries),\n );\n observer.observe(elem);\n\n return () => observer.unobserve(elem);\n });\n}\n","/*\n * Copyright (c) 2026.\n * 3DSource.com. Sergii Karanda steve@3dsource.com. All Rights Reserved.\n */\n\n/**\n * Rounds a number to the nearest even integer (rounding up for odd values).\n *\n * Video encoders (H.264/H.265) require even dimensions because chroma subsampling\n * operates on 2×2 pixel blocks. Odd dimensions cause encoding artifacts or failures.\n *\n * @param value - The number to round to the nearest even integer.\n * @returns The nearest even integer greater than or equal to the input.\n *\n * @example\n * makeEven(1079) // 1080\n * makeEven(1080) // 1080\n * makeEven(1081) // 1082\n */\nexport function makeEven(value: number): number {\n return Math.floor((value + 1) / 2) * 2;\n}\n","import type { Area } from '@3dsource/utils';\nimport { fitIntoRectangle } from '@3dsource/utils';\nimport { FULL_HD_HEIGHT, FULL_HD_WIDTH } from '../constants';\nimport { makeEven } from './make-even';\n\nconst FULL_HD_PIXELS = FULL_HD_WIDTH * FULL_HD_HEIGHT;\nconst UHD_PIXELS = FULL_HD_WIDTH * 2 * (FULL_HD_HEIGHT * 2);\n\n/**\n * Calculates the optimal stream resolution for studio mode.\n *\n * Fits the studio aspect ratio into the container (scaled by pixelRatio), then\n * caps the total pixel count to a budget (Full HD or 4K) to avoid overloading\n * the GPU/encoder while maximizing visual quality.\n *\n * The pixel budget approach (instead of per-dimension caps) ensures that\n * non-standard aspect ratios (portrait, ultra-wide, square) utilize available\n * pixels efficiently — e.g. a tall 1080×1920 stream uses the same pixel budget\n * as a wide 1920×1080 stream.\n *\n * Resolution is always capped at the studio dimensions — never upscaled beyond\n * what the Unreal scene was designed for.\n *\n * @param params.pixelRatio - Device pixel ratio (`window.devicePixelRatio`).\n * @param params.containerWidth - CSS width of the video container in pixels.\n * @param params.containerHeight - CSS height of the video container in pixels.\n * @param params.studioWidth - Target width of the MetaBox Studio scene.\n * @param params.studioHeight - Target height of the MetaBox Studio scene.\n * @param params.maxResolution - When `true`, uses 4K pixel budget (3840×2160);\n * otherwise Full HD (1920×1080). Controlled by `?maxresolution` query param.\n * @returns An {@link Area} with the calculated `w`, `h`, position (`x`, `y`),\n * and `scale` factor relative to the container's device-pixel size.\n */\nexport function getResizeStudioValues(params: {\n pixelRatio: number;\n containerWidth: number;\n containerHeight: number;\n studioWidth: number;\n studioHeight: number;\n maxResolution: boolean;\n}): Area {\n const {\n pixelRatio,\n containerWidth,\n containerHeight,\n studioWidth,\n studioHeight,\n maxResolution,\n } = params;\n\n const maxSpace = {\n w: containerWidth * pixelRatio,\n h: containerHeight * pixelRatio,\n };\n const maxPixels = maxResolution ? UHD_PIXELS : FULL_HD_PIXELS;\n\n const videoSizePixelPerfect = fitIntoRectangle(\n { x: 0, y: 0, w: studioWidth, h: studioHeight },\n { x: 0, y: 0, ...maxSpace },\n );\n\n let w = videoSizePixelPerfect.w;\n let h = videoSizePixelPerfect.h;\n\n if (w * h > maxPixels) {\n // Derive uniform scale factor `s` from: (w*s) * (h*s) = maxPixels\n // → w * h * s² = maxPixels → s = √(maxPixels / (w * h)).\n // Applying the same `s` to both dimensions preserves the aspect ratio.\n const scaleFactor = Math.sqrt(maxPixels / (w * h));\n w = w * scaleFactor;\n h = h * scaleFactor;\n }\n\n const out = fitIntoRectangle(videoSizePixelPerfect, {\n x: videoSizePixelPerfect.x,\n y: videoSizePixelPerfect.y,\n w,\n h,\n });\n\n out.w = makeEven(out.w);\n out.h = makeEven(out.h);\n return out;\n}\n\n/**\n * Calculates the optimal stream resolution for configurator (non-studio) mode.\n *\n * Uses the full container area (scaled by pixelRatio) as the stream resolution,\n * then caps total pixel count to a budget (Full HD or 4K) to prevent excessive\n * GPU/encoder load while preserving the container's aspect ratio.\n *\n * Unlike {@link getResizeStudioValues}, there is no fixed studio resolution to\n * fit into — the container itself defines the aspect ratio, and the stream fills\n * it entirely (no letterboxing).\n *\n * @param params.pixelRatio - Device pixel ratio (`window.devicePixelRatio`).\n * @param params.containerWidth - CSS width of the video container in pixels.\n * @param params.containerHeight - CSS height of the video container in pixels.\n * @param params.maxResolution - When `true`, uses 4K pixel budget (3840×2160);\n * otherwise Full HD (1920×1080). Controlled by `?maxresolution` query param.\n * @returns An {@link Area} with the calculated `w`, `h`, position (`x`, `y`),\n * and `scale` factor (1 when no downscale needed, <1 when capped).\n */\nexport function getResizeValuesUniversal(params: {\n pixelRatio: number;\n containerWidth: number;\n containerHeight: number;\n maxResolution: boolean;\n}): Area {\n const { pixelRatio, containerWidth, containerHeight, maxResolution } = params;\n\n const maxSpace = {\n w: containerWidth * pixelRatio,\n h: containerHeight * pixelRatio,\n };\n const maxPixels = maxResolution ? UHD_PIXELS : FULL_HD_PIXELS;\n\n let w = maxSpace.w;\n let h = maxSpace.h;\n\n if (w * h > maxPixels) {\n // Derive uniform scale factor `s` from: (w*s) * (h*s) = maxPixels\n // → w * h * s² = maxPixels → s = √(maxPixels / (w * h)).\n // Applying the same `s` to both dimensions preserves the aspect ratio.\n const scaleFactor = Math.sqrt(maxPixels / (w * h));\n w = w * scaleFactor;\n h = h * scaleFactor;\n }\n\n return { w: makeEven(w), h: makeEven(h), x: 0, y: 0, scale: w / maxSpace.w };\n}\n","import { createSelector } from '@ngrx/store';\nimport { unrealFeature } from './unreal.feature';\nimport { DEFAULT_AFK_TIMEOUT, SIGNALLING_PERCENT_VALUE } from '../../constants';\nimport { clampf, lerp } from '@3dsource/utils';\n\n/**\n * Fraction of commands completed (0–1). Drives the second half of the\n * loading bar, after signaling reaches `SIGNALLING_PERCENT_VALUE`.\n */\nexport const selectCommandProgress = createSelector(\n unrealFeature.selectTotalCommandsStarted,\n unrealFeature.selectTotalCommandsCompleted,\n (started, completed) => (started ? completed / started : 0),\n);\n\nexport const selectFreezeFrameDataUrlFromVideo = createSelector(\n unrealFeature.selectFreezeFrameFromVideo,\n (freezeFrameFromVideo) => freezeFrameFromVideo?.dataUrl || null,\n);\nexport const selectFreezeFrameProgressMessageFromVideo = createSelector(\n unrealFeature.selectFreezeFrameFromVideo,\n (freezeFrameFromVideo) => freezeFrameFromVideo?.progress || null,\n);\nexport const selectFreezeFrameDataUrl = createSelector(\n unrealFeature.selectFreezeFrame,\n (freezeFrame) => (freezeFrame?.dataUrl ? freezeFrame?.dataUrl : null),\n);\nexport const selectIsFreezeFrameLoading = createSelector(\n unrealFeature.selectFreezeFrame,\n (freezeFrame) =>\n freezeFrame?.progress\n ? freezeFrame.progress > 0 && freezeFrame.progress < 1\n : false,\n);\nexport const selectFreezeFrameCombinedDataUrl = createSelector(\n selectFreezeFrameDataUrlFromVideo,\n selectFreezeFrameDataUrl,\n (dataUrlFromVideo, remoteDataUrl) =>\n dataUrlFromVideo || remoteDataUrl || null,\n);\nexport const selectStreamConfig = createSelector(\n unrealFeature.selectStreamConfig,\n (config) => config,\n);\nexport const selectWarnTimeout = createSelector(\n selectStreamConfig,\n (config) => config?.warnTimeout || DEFAULT_AFK_TIMEOUT,\n);\nexport const selectIsExistMatchUrls = createSelector(\n unrealFeature.selectMatchUrls,\n (urls) => urls?.length > 0,\n);\nexport const selectIsAutostart = createSelector(\n selectStreamConfig,\n (config) => config?.autoStart,\n);\nexport const selectShowReconnectPopup = createSelector(\n unrealFeature.selectCirrusConnected,\n unrealFeature.selectEstablishingConnection,\n (cirrusConnected, establishingConnection) =>\n !cirrusConnected && !establishingConnection,\n);\nexport const selectShowLoader = createSelector(\n selectShowReconnectPopup,\n unrealFeature.selectViewportReady,\n (showPopup, viewportReady) => !showPopup && !viewportReady,\n);\nexport const selectSignalingParameters = createSelector(\n unrealFeature.selectSsData,\n unrealFeature.selectAwsInstance,\n (data, instance) => {\n const info: string[] = [];\n if (data) {\n info.push(\n `${data.cirrusVersion}, ${data.branchInfo}, ${data.instanceType}`,\n );\n info.push(`Unreal App Version: ${data.streamerVersion}`);\n info.push(`APP: ${data.streamPath}${data.streamApp}`);\n }\n info.push(`Polling: ${instance.pollingUrl}`);\n info.push(`WS: ${instance.wsUrl}`);\n return info.join('<br>');\n },\n);\nexport const selectClientAndViewIds = createSelector(\n unrealFeature.selectStreamClientCompanyId,\n unrealFeature.selectStreamViewId,\n (clientId, viewId) => ({ clientId, viewId }),\n);\nexport const selectIsFullyConnected = createSelector(\n unrealFeature.selectViewportReady,\n unrealFeature.selectDataChannelConnected,\n unrealFeature.selectCirrusConnected,\n (viewportReady, dataChannelConnected, cirrusConnected) =>\n viewportReady && dataChannelConnected && cirrusConnected,\n);\nexport const selectIsLoaderScreenVisible = createSelector(\n selectIsFullyConnected,\n (fullyConnected) => !fullyConnected,\n);\n/**\n * Returns Scene load progress as a float value between 0 and 1.\n *\n * Progress is split into two phases:\n * 1. **Signaling** (0 → ~56%): connection polling or orchestration progress.\n * Starts at 0.1%, so the bar is never visually empty while connecting.\n * 2. **Commands** (~56% → 100%): Unreal command progress after the data channel connects.\n *\n * The split point bumps by +1% once the WebSocket URL is known,\n * producing a small visual step that indicates the WS handshake succeeded.\n */\nexport const selectTotalProgress = createSelector(\n unrealFeature.selectStatusPercentSignallingServer,\n selectCommandProgress,\n unrealFeature.selectAwsInstance,\n unrealFeature.selectDataChannelConnected,\n (\n statusPercentSignallingServer,\n commandProgress,\n awsInstance,\n dataChannelConnected,\n ) => {\n const SIGNALLING_MAX = SIGNALLING_PERCENT_VALUE / 100;\n const ORCHESTRATION_WS_PATTERN = /^wss:\\/\\/orchestration-websocket/i;\n\n const isNewOrchestration = ORCHESTRATION_WS_PATTERN.test(\n awsInstance?.wsUrl ?? '',\n );\n\n // Once the data channel is connected, signaling is fully complete (1.0) —\n // regardless of orchestration type. This is what makes an ADOPTED stream\n // (whose wsUrl is the machine host, not the orchestration-websocket URL,\n // and which never set `statusPercentSignallingServer`) correctly show the\n // whole first phase done instead of stalling near the command-only value.\n // Otherwise: new orchestration reports 0–1 progress; legacy uses the\n // polling percent.\n const signalingProgress = dataChannelConnected\n ? 1\n : isNewOrchestration\n ? (awsInstance?.progressComplete ?? 0)\n : (statusPercentSignallingServer ?? 0) / 100;\n\n // +1% bump once WS URL is known (visual step for WS handshake)\n const splitPoint = awsInstance?.wsUrl\n ? SIGNALLING_MAX + 0.01\n : SIGNALLING_MAX;\n\n // 0.001 minimum so the bar is never completely empty while loading\n const progressSignaling = lerp(0.001, splitPoint, signalingProgress);\n const progressRest = lerp(0, 1 - splitPoint, commandProgress);\n\n return clampf(0, 1, progressSignaling + progressRest);\n },\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectCirrusConnectionId = createSelector(\n unrealFeature.selectSsData,\n (data) => data?.connectionId,\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectUserInactivityDetected = createSelector(\n unrealFeature.selectAfkCountdown,\n unrealFeature.selectIsAfkTimerVisible,\n (remainingSecondsToDisconnect, countdownVisible) => ({\n remainingSecondsToDisconnect,\n countdownVisible,\n }),\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectIsVideoPlayingAndDataChannelConnected = createSelector(\n unrealFeature.selectIsVideoPlaying,\n unrealFeature.selectDataChannelConnected,\n (isVideoPlaying, isDataChannelConnected) =>\n isVideoPlaying && isDataChannelConnected,\n);\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { disconnectStream, unrealFeature } from '../../store';\nimport { DisconnectReason } from '../../interfaces';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-webrtc-error-modal',\n templateUrl: './webrtc-error-modal.component.html',\n styleUrl: './webrtc-error-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class WebrtcErrorModalComponent {\n #dialogRef = inject(DialogRef);\n #store = inject(Store);\n readonly isCirrusConnected = inject(Store).selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n\n closeModalWithCirrusDisconnect() {\n if (!this.isCirrusConnected()) {\n this.#store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DropConnection,\n message: 'Modal Drop Connection',\n }),\n );\n }\n this.close();\n }\n\n private close() {\n this.#dialogRef.close();\n }\n}\n","<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"src-modal\">\n <header class=\"src-modal__header\"></header>\n <section class=\"src-modal__body\">\n <div [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n WebRTC error\n </div>\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"src-modal__footer\">\n <src-button\n (onClick)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n weight=\"primary\"\n >\n Ok\n </src-button>\n </footer>\n</div>\n","import { inject, Injectable } from '@angular/core';\nimport { catchError, filter, takeUntil } from 'rxjs/operators';\nimport type { TelemetryType } from '../interfaces';\nimport { of, take, timer } from 'rxjs';\nimport { generateUuid, Truthy } from '@3dsource/utils';\nimport { HttpClient } from '@angular/common/http';\nimport { UNREAL_CONFIG } from '../constants';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { ofType } from '@ngrx/effects';\nimport { unrealCommandCallback } from '../store';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class CommandTelemetryService extends SubService {\n private readonly appId: string = 'metabox-telemetry';\n private commandsSent: Record<string, CommandToSend> = {};\n private exileTimeout = 60000;\n private pollingTime = 5000;\n private commandSequenceNumber = 0;\n\n /**\n * The time the telemetry service was started.\n * Initialized at a moment when connectToSignaling() was called.\n * @private\n */\n private startTime!: number;\n private lastTime!: number;\n private uuid!: string;\n private viewId!: string;\n private sessionId!: string;\n private userId!: string;\n private payloads: Payload[] = [];\n\n private readonly httpClient = inject(HttpClient);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (\n !this.unrealConfig?.commandTelemetryReceiver ||\n this.unrealConfig?.playwright\n ) {\n return;\n }\n\n this.reset();\n this.sessionId = sessionStorage.getItem(this.appId) || this.uuid;\n this.userId = localStorage.getItem(this.appId) || this.uuid;\n sessionStorage.setItem(this.appId, this.sessionId);\n localStorage.setItem(this.appId, this.userId);\n timer(0, this.pollingTime)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n this.send(this.payloads);\n });\n }\n\n private get timeNow() {\n return Date.now();\n }\n\n private get sessionTime() {\n return this.timeNow - this.startTime;\n }\n\n private get canSkipSending() {\n return !(this.timeNow - this.lastTime > this.pollingTime * 2);\n }\n\n decorate(funcToDecorate: ToBeDecorated) {\n this.listenCallbacks();\n return this.wrapper.bind(this, funcToDecorate);\n }\n\n trackStartCommand(trackingId: string) {\n const out = {\n command: trackingId,\n trackingId,\n };\n const timers = {\n sessionElapsedTime: this.sessionTime,\n } as ComputedTimers;\n this.pushStatToBuffer('commandSent', out, timers);\n this.trackTime(out);\n }\n\n trackStopCommand(\n trackingId: string,\n multi = false,\n response: { multi?: boolean } & Record<string, unknown> = {},\n timeStampsRaw?: TimeStampsRaw,\n ) {\n const commandResponse = this.commandsSent[trackingId];\n if (!commandResponse) {\n return;\n }\n const totalRoundTripTime = this.timeNow - commandResponse.timeStampJs;\n\n /**\n * Time between telemetry was reset and a command was sent.\n */\n const commandSentJsTime = commandResponse.timeStampJs - this.startTime;\n let unrealTimers = {};\n\n const t = timeStampsRaw?.timeStampCommand;\n if (t) {\n unrealTimers = {\n unrealRoundTripTime:\n t.onCompleteCommand.timestamp - t.onRequestCommand.timestamp,\n\n unrealExecutionDuration:\n t.onCompleteCommand.timestamp - t.onStartCommand.timestamp,\n\n timeDiffRequest:\n t.onRequestCommand.timestamp - commandResponse.timeStampJs,\n\n timeDiffCallBack: this.timeNow - t.onCompleteCommand.timestamp,\n };\n }\n\n const timers = {\n sessionElapsedTime: this.sessionTime,\n commandSentJsTime,\n totalRoundTripTime,\n ...unrealTimers,\n } as ComputedTimers;\n\n this.pushStatToBuffer(\n 'commandStop',\n { ...commandResponse.command, response },\n timers,\n timeStampsRaw,\n );\n if (!multi) {\n delete this.commandsSent[trackingId];\n }\n }\n\n reset() {\n this.uuid = generateUuid();\n this.commandSequenceNumber = 0;\n this.viewId = this.uuid;\n this.startTime = this.timeNow;\n this.payloads.length = 0;\n this.commandsSent = {};\n }\n\n private pushStatToBuffer(\n type: TelemetryType,\n commandContent: Record<string, unknown>,\n computedTimers: ComputedTimers,\n timeStampsRaw?: TimeStampsRaw,\n ) {\n this.pushData({\n type,\n commandSequenceNumber: this.commandSequenceNumber++,\n commandContent,\n timeStampsRaw,\n computedTimers,\n });\n }\n\n private trackTime(command: { trackingId: string }) {\n this.commandsSent[command.trackingId] = {\n timeStampJs: this.timeNow,\n command,\n };\n }\n\n private send(payload: Payload[]) {\n if (payload.length === 0 || (this.canSkipSending && payload.length < 10)) {\n return;\n }\n this.lastTime = this.timeNow;\n const out: TelemetryBatch = {\n appId: this.appId,\n sessionId: this.sessionId,\n viewId: this.viewId,\n userId: this.userId,\n ua: navigator.userAgent,\n timeStamp: new Date(this.timeNow).toString(),\n href: location.href,\n resolution: {\n width: window.screen.width,\n height: window.screen.height,\n pixelRatio: window.devicePixelRatio,\n },\n payload,\n };\n const lastIndex = payload[payload.length - 1].commandSequenceNumber;\n this.httpClient\n .post(this.unrealConfig?.commandTelemetryReceiver || '', out)\n .pipe(\n catchError(() => of(null)),\n take(1),\n )\n .subscribe(() => {\n this.payloads = this.payloads.filter(\n (p) => p.commandSequenceNumber > lastIndex,\n );\n });\n }\n\n /**\n * Listens for Unreal Engine callbacks.\n * Subscribes to the Unreal Engine event loop back and filters out events that do not have a tracking ID.\n * When a callback with a tracking ID is received,\n * it stops tracking the time for that command and filters out commands\n * that have exceeded the timeout limit.\n */\n protected listenCallbacks() {\n this.actions$\n .pipe(\n ofType(unrealCommandCallback),\n filter(({ json }) => {\n const callback =\n 'commandCallback' in json ? json.commandCallback : json;\n return Truthy(callback?.trackingId);\n }),\n takeUntil(this.destroy$),\n )\n .subscribe(({ json }) => {\n const callback =\n 'commandCallback' in json ? json.commandCallback : json;\n const timeStampsRaw =\n 'timeStamp' in json ? (json?.timeStamp as TimeStampsRaw) : undefined;\n const trackingId = callback?.trackingId || '';\n\n this.trackStopCommand(trackingId, false, {}, timeStampsRaw);\n this.removeExileCommands();\n });\n }\n\n private pushData(payload: Payload) {\n this.payloads.push(payload);\n }\n\n /**\n * Removes commands that have exceeded the timeout limit.\n * Iterates over all the commands sent and checks if the difference between the current time\n * and the time the command was sent is greater than the timeout limit.\n * If it is, the command is marked for deletion.\n * After checking all commands, those marked for deletion are removed from the commands sent.\n * This method is used to ensure that commands that are not responded to within a certain time frame\n * do not remain in the commandsSent object indefinitely, which could lead to memory leaks over time.\n */\n private removeExileCommands() {\n const time: number = new Date().getTime();\n const markForDelete: string[] = [];\n Object.entries<CommandToSend>(this.commandsSent).forEach(\n ([trackingId, { timeStampJs }]) => {\n if (time - timeStampJs > this.exileTimeout) {\n markForDelete.push(trackingId);\n }\n },\n );\n\n markForDelete.forEach((trackingId) => {\n delete this.commandsSent[trackingId];\n });\n }\n\n /**\n * Wraps the provided function with telemetry tracking.\n * Generates a unique tracking ID and adds it to the data object.\n * Pushes the command sent to the payloads with the tracking ID.\n * Starts tracking the time for the command.\n * Finally, calls the provided function with the modified data object.\n *\n * @param {ToBeDecorated} funcToDecorate - The function to be decorated with telemetry tracking.\n * @param {MetaBoxCommandPacket} data - The data object to be passed to the function. It will be augmented with a unique tracking ID.\n */\n private wrapper(funcToDecorate: ToBeDecorated, data: MetaBoxCommandPacket) {\n const out = { ...data, trackingId: generateUuid() };\n const timers = {\n sessionElapsedTime: this.sessionTime,\n } as ComputedTimers;\n this.pushStatToBuffer(\n 'commandSent',\n {\n ...out,\n trackingId: `${out.trackingId}`,\n },\n timers,\n );\n this.trackTime(out);\n funcToDecorate(out);\n }\n}\n\ntype ToBeDecorated = (data: MetaBoxCommandPacket) => void;\n\ninterface TelemetryBatch {\n appId: string;\n sessionId: string;\n viewId: string;\n userId: string;\n ua: string;\n timeStamp: string;\n href: string;\n payload: Payload[];\n resolution: {\n width: number;\n height: number;\n pixelRatio: number;\n };\n}\n\ninterface Payload {\n type: TelemetryType;\n commandSequenceNumber: number;\n commandContent: Record<string, unknown>;\n timeStampsRaw?: TimeStampsRaw;\n computedTimers: ComputedTimers;\n}\n\ninterface TimeStampsRaw {\n timeStampPak: TimeStampPakCollection;\n timeStampCommand: TimeStampCommandCollection;\n}\n\ninterface TimeStampPakCollection {\n onLoadPak: TimeStampMemory;\n onRenderPak: TimeStampMemory;\n onSequencePak: TimeStampMemory;\n onSpawnPak: TimeStampMemory;\n}\n\ninterface TimeStampMemory {\n timestamp: number;\n ram: number;\n vRam: number;\n}\n\ninterface TimeStampCommandCollection {\n onRequestCommand: TimeStampMemory;\n onStartCommand: TimeStampMemory;\n onCompleteCommand: TimeStampMemory;\n}\n\ninterface ComputedTimers {\n unrealRoundTripTime: number;\n totalRoundTripTime: number;\n unrealExecutionDuration: number;\n sessionElapsedTime: number;\n timeDiffRequest: number;\n timeDiffCallBack: number;\n commandSentJsTime: number;\n}\n\ninterface CommandToSend {\n timeStampJs: number;\n command: { trackingId: string };\n}\n","import { Injectable } from '@angular/core';\nimport { Truthy } from '@3dsource/utils';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class DevModeService {\n get isDevMode() {\n return Truthy(localStorage.getItem('devMode'));\n }\n /**\n * Called from the browser console to toggle dev mode at runtime.\n * @preserve\n */\n setDevMode(value: boolean) {\n if (value) {\n localStorage.setItem('devMode', value.toString());\n } else {\n localStorage.removeItem('devMode');\n }\n }\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Store } from '@ngrx/store';\nimport { defer, from, of, switchMap } from 'rxjs';\nimport { catchError, map, tap } from 'rxjs/operators';\nimport { Semaphore, tapLog } from '@3dsource/utils';\nimport {\n REGION_PING_ACCURATE_SAMPLES,\n REGION_PING_CACHE_KEY,\n REGION_PING_CACHE_TTL_MS,\n REGION_PING_WARMUP_DEADLINE_MS,\n UNREAL_CONFIG,\n} from '../constants';\nimport {\n regionPingFetchEnd,\n regionPingFetchStart,\n regionResolved,\n} from '../store';\n\n@Injectable({ providedIn: 'root' })\nexport class RegionsPingService {\n private httpClient = inject(HttpClient);\n private store = inject(Store);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n // Aborted when the injector is destroyed. Forwarded into every\n // `startPinging` call's winnerController so in-flight fetches cancel\n // immediately on route exit instead of running to natural completion.\n private readonly destroyController = new AbortController();\n\n public config = {\n ping_count: 2,\n ping_timeout: 2000,\n max_parallel_requests: 10,\n bust_cache: true,\n };\n\n constructor() {\n this.destroyRef.onDestroy(() => this.destroyController.abort());\n }\n\n public getFastest(regionListUrl = this.unrealConfig?.regionsPingUrl || '') {\n // Self-announce every lifecycle waypoint of the region-discovery\n // flow (start / providers-fetched / resolved). The final\n // `regionResolved` forwards the winner's full ping-sample array\n // straight from `PingResult.result` — no aggregation.\n return defer(() => {\n this.store.dispatch(regionPingFetchStart());\n\n // Cache hit: a standalone prefetch script\n // (`src/js/region-ping-prefetch.js`) may already have pinged the\n // regions and stored the winner. If that entry is still fresh, skip\n // the HTTP fetch + live ping sweep entirely — this is the whole point\n // of the prefetch: keep the ping cost off the connection critical path.\n const cached = this.readCachedWinner();\n if (cached) {\n // Bookend the waterfall the same way the live path does so observers\n // see start → end → resolved even though discovery was instant.\n // Dispatches are split across operators (not fired back-to-back) to\n // keep the same shape as the live pipe below.\n return of(cached).pipe(\n tap(() => this.store.dispatch(regionPingFetchEnd())),\n tap((data) =>\n this.store.dispatch(\n regionResolved({\n region: data.region_code,\n pingsMs: data.result,\n }),\n ),\n ),\n map((data) => data.region_code),\n );\n }\n\n return this.getProviders(regionListUrl).pipe(\n tap(() => this.store.dispatch(regionPingFetchEnd())),\n switchMap((providers: ProvidersData) => this.getPingResult(providers)),\n catchError(() => of(null)),\n tapLog('PingResult'),\n // Warm the cache with the live result so the next connection (and any\n // reload within the TTL) can skip pinging even if the prefetch script\n // never ran.\n tap((data) => {\n if (data?.region_code) {\n this.writeCachedWinner(data.region_code, data.result);\n }\n }),\n tap((data) =>\n this.store.dispatch(\n regionResolved({\n region: data?.region_code ?? '',\n pingsMs: data?.result ?? [],\n }),\n ),\n ),\n map((data) => data?.region_code),\n );\n });\n }\n\n /**\n * Read the prefetched winner from `localStorage`, returning it only if the\n * entry is well-formed and still within {@link REGION_PING_CACHE_TTL_MS}.\n * All access is guarded — `localStorage` can throw (private mode, disabled\n * storage) or be absent (non-browser).\n *\n * Public so adopted connections (which skip `getFastest`) can replay the\n * region-resolving telemetry phase from the same cached winner — see\n * `UnrealEffects.regionTelemetryOnAdopt$`.\n */\n readCachedWinner(): { region_code: string; result: number[] } | null {\n try {\n if (typeof localStorage === 'undefined') return null;\n const raw = localStorage.getItem(REGION_PING_CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as {\n region_code?: unknown;\n result?: unknown;\n ts?: unknown;\n };\n if (\n typeof parsed?.region_code !== 'string' ||\n !Array.isArray(parsed.result) ||\n typeof parsed.ts !== 'number' ||\n Date.now() - parsed.ts >= REGION_PING_CACHE_TTL_MS\n ) {\n return null;\n }\n return { region_code: parsed.region_code, result: parsed.result };\n } catch {\n return null;\n }\n }\n\n private writeCachedWinner(regionCode: string, result: number[] = []) {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(\n REGION_PING_CACHE_KEY,\n JSON.stringify({ region_code: regionCode, result, ts: Date.now() }),\n );\n } catch {\n // Storage unavailable — cache stays cold, live ping still works.\n }\n }\n\n /**\n * Accurate, OFF-critical-path refresh of the region cache. Mirrors the\n * prefetch script: warm up every region in parallel (barrier), then measure\n * {@link REGION_PING_ACCURATE_SAMPLES} probes each and pick the lowest\n * MEDIAN RTT (tie-break: min). Writes the winner to `localStorage` ONLY — it\n * does NOT dispatch `regionResolved` or touch current-session state, since\n * the connection is already established on a region; this just improves the\n * pick for the NEXT connection.\n *\n * Invoked from an effect a few seconds after the data channel is ready (see\n * `REGION_PING_BACKGROUND_REFRESH_DELAY_MS`), so it never competes with the\n * connection handshake. Aborts with the injector via `destroyController`.\n */\n public refreshCacheInBackground(\n regionListUrl = this.unrealConfig?.regionsPingUrl || '',\n ) {\n return defer(() => this.getProviders(regionListUrl)).pipe(\n switchMap((providers: ProvidersData) =>\n from(\n this.measureAccurate(\n providers.regions,\n providers.timeout ?? this.config.ping_timeout,\n ),\n ),\n ),\n tap((winner) => {\n if (winner) {\n this.writeCachedWinner(winner.region_code, winner.result);\n }\n }),\n catchError(() => of(null)),\n );\n }\n\n private async measureAccurate(endpoints: Region[], defaultTimeout: number) {\n const signal = this.destroyController.signal;\n await this.warmUpAll(endpoints, defaultTimeout, signal);\n if (signal.aborted) return null;\n\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n const tasks = endpoints.map(async ({ region_code, url, timeout }) => {\n await semaphore.acquire();\n try {\n const result = await this.checkLatency(\n url,\n timeout ?? defaultTimeout,\n signal,\n REGION_PING_ACCURATE_SAMPLES,\n );\n return result.length >= 2 ? { region_code, result } : null;\n } catch {\n return null;\n } finally {\n semaphore.release();\n }\n });\n\n const results = (await Promise.all(tasks)).filter(\n (r): r is { region_code: string; result: number[] } => r !== null,\n );\n return this.pickByMedian(results);\n }\n\n /**\n * Phase 1 of the accurate measure: one throwaway probe to every region in\n * parallel to pay the DNS/TCP/TLS cold-start. Resolves once all settle OR\n * the warm-up deadline elapses, whichever is first.\n */\n private async warmUpAll(\n endpoints: Region[],\n defaultTimeout: number,\n signal: AbortSignal,\n ) {\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n const warmups = endpoints.map(async ({ url, timeout }) => {\n await semaphore.acquire();\n try {\n await this.checkLatency(url, timeout ?? defaultTimeout, signal, 1);\n } finally {\n semaphore.release();\n }\n });\n await Promise.race([\n Promise.allSettled(warmups),\n new Promise((resolve) =>\n setTimeout(resolve, REGION_PING_WARMUP_DEADLINE_MS),\n ),\n ]);\n }\n\n private pickByMedian(\n results: { region_code: string; result: number[] }[],\n ): { region_code: string; result: number[] } | null {\n let best: { region_code: string; result: number[] } | null = null;\n let bestMedian = Infinity;\n let bestMin = Infinity;\n for (const r of results) {\n const med = this.median(r.result);\n const min = Math.min(...r.result);\n if (med < bestMedian || (med === bestMedian && min < bestMin)) {\n bestMedian = med;\n bestMin = min;\n best = r;\n }\n }\n return best;\n }\n\n private median(samples: number[]) {\n const sorted = [...samples].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2\n ? sorted[mid]\n : (sorted[mid - 1] + sorted[mid]) / 2;\n }\n\n public getPingResult(providers: ProvidersData) {\n const defaultTimeout = providers.timeout ?? this.config.ping_timeout;\n return from(this.startPinging(providers.regions, defaultTimeout));\n }\n\n public getProviders(regionListUrl = this.unrealConfig?.regionsPingUrl || '') {\n return this.httpClient.get<ProvidersData>(regionListUrl);\n }\n\n private async startPinging(endpoints: Region[], defaultTimeout: number) {\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n // Shared \"stop\" signal. Aborted when EITHER:\n // - one region finishes successfully (winner found → cancel losers); OR\n // - the service's injector is destroyed (route exit → cancel everything).\n // Without this, losing regions keep pinging to their own `ping_timeout`,\n // generating up to `(endpoints.length - 1) × ping_count` wasted requests\n // every time `getFastest` runs, and in-flight fetches outlive the route.\n const winnerController = new AbortController();\n const destroySignal = this.destroyController.signal;\n let onDestroyAbort: (() => void) | undefined;\n if (destroySignal.aborted) {\n // Service already destroyed — bail every task synchronously.\n winnerController.abort(destroySignal.reason);\n } else {\n onDestroyAbort = () => winnerController.abort(destroySignal.reason);\n destroySignal.addEventListener('abort', onDestroyAbort, { once: true });\n }\n\n const tasks = endpoints.map(async ({ region_code, url, timeout }) => {\n await semaphore.acquire();\n try {\n const result = await this.checkLatency(\n url,\n timeout ?? defaultTimeout,\n winnerController.signal,\n );\n if (result.length < 2) throw new Error('insufficient pings');\n return { region_code, result };\n } finally {\n semaphore.release();\n }\n });\n\n try {\n return await Promise.any(tasks);\n } catch {\n return null;\n } finally {\n // Cancel losing in-flight pings. Safe to call on success (we already\n // captured the winner) AND on all-failed (no-op, all tasks settled).\n winnerController.abort();\n // Detach the destroy listener so it doesn't linger on the long-lived\n // destroyController.signal across multiple `getFastest` invocations.\n if (onDestroyAbort) {\n destroySignal.removeEventListener('abort', onDestroyAbort);\n }\n }\n }\n\n private async checkLatency(\n endpoint: string,\n timeout: number,\n abortSignal?: AbortSignal,\n count = this.config.ping_count,\n ) {\n const pingResults: number[] = [];\n const sep = endpoint.includes('?') ? '&' : '?';\n\n for (let i = 0; i < count; i++) {\n // Bail out as soon as another region's task has won — no point\n // burning further `ping_timeout` budget here.\n if (abortSignal?.aborted) {\n break;\n }\n\n const startTime = performance.now();\n try {\n await this.fetchWithTimeout(\n this.config.bust_cache\n ? `${endpoint}${sep}cache_buster=${performance.now()}`\n : endpoint,\n {\n method: 'GET',\n mode: 'no-cors',\n headers: {\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n Pragma: 'no-cache',\n Expires: '0',\n },\n credentials: 'omit',\n },\n timeout,\n abortSignal,\n );\n } catch {\n // intentional: finally pushes the elapsed time as the latency sample\n } finally {\n const latency = Math.round(performance.now() - startTime);\n pingResults.push(latency);\n }\n }\n return pingResults;\n }\n\n private async fetchWithTimeout(\n url: string,\n options: RequestInit = {},\n timeout: number,\n abortSignal?: AbortSignal,\n ) {\n const controller = new AbortController();\n options.signal = controller.signal;\n\n // Forward an external abort into our local controller so a winner-found signal cancels the in-flight `fetch` immediately. If the\n // external signal is already aborted, abort synchronously before\n // even starting the fetch.\n let onExternalAbort: (() => void) | undefined;\n if (abortSignal) {\n if (abortSignal.aborted) {\n controller.abort(abortSignal.reason);\n } else {\n onExternalAbort = () => controller.abort(abortSignal.reason);\n abortSignal.addEventListener('abort', onExternalAbort, { once: true });\n }\n }\n\n const timeoutId = setTimeout(\n () =>\n controller.abort(new DOMException('Request timed out', 'TimeoutError')),\n timeout,\n );\n\n try {\n return await fetch(url, options);\n } finally {\n clearTimeout(timeoutId);\n if (abortSignal && onExternalAbort) {\n abortSignal.removeEventListener('abort', onExternalAbort);\n }\n }\n }\n}\n\ninterface ProvidersData {\n timeout?: number;\n regions: Region[];\n}\n\ninterface Region {\n region_code: string;\n url: string;\n timeout?: number;\n}\n","import type { SignallingService } from '../../services';\nimport type { StreamerListMessage } from '../../interfaces';\n\nexport function StreamerListHandler(\n this: SignallingService,\n msg: StreamerListMessage,\n) {\n this.send(\n JSON.stringify({\n type: 'subscribe',\n streamerId: msg.ids[0],\n }),\n );\n}\n","import type { SignallingService } from '../../services';\n\nexport function OfferHandler(\n this: SignallingService,\n msg: RTCSessionDescriptionInit,\n) {\n this.onOffer$.next(msg);\n}\n","export function httpUrlToWs(url: string) {\n return url.replace('http://', 'ws://').replace('https://', 'wss://');\n}\n","import { defer, Observable, throwError } from 'rxjs';\nimport { timeout } from 'rxjs/operators';\nimport { Logger } from '@3dsource/utils';\nimport { WS_TIMEOUT } from '../constants';\n\n/**\n * Factory that creates a WebSocket connection and wraps it in an RxJS Observable.\n *\n * Returns a **single-value Observable**: it emits the open `WebSocket` instance\n * once the connection is established, then completes. This design allows\n * downstream operators (e.g. `tap` in `connectToCirrus`) to attach their own\n * event handlers before any messages arrive.\n *\n * ## Ownership model\n *\n * The factory **transfers ownership** of the WebSocket to the consumer upon\n * emission. Once `observer.next(ws)` fires, the consumer is responsible for\n * the socket's lifecycle (attaching handlers, closing when done). The teardown\n * logic will **never** close a socket that has been successfully delivered.\n *\n * ## Timeout\n *\n * The observable is piped through `timeout({ first: WS_TIMEOUT })`. If the\n * WebSocket `open` event does not fire within `WS_TIMEOUT` milliseconds, the\n * stream errors with a timeout message and the teardown disposes the socket.\n *\n * ## Teardown & leak prevention\n *\n * When the observable is unsubscribed (timeout, manual unsubscribe, or error),\n * the teardown function runs and handles two cases:\n *\n * 1. **Socket was emitted (`emitted === true`):** The consumer owns the socket.\n * Teardown only removes the internal event listeners — it does NOT close\n * the socket. Closing it here would break downstream consumers like\n * `connectToCirrus` that rely on the connection staying alive.\n *\n * 2. **Socket was NOT emitted (`emitted === false`):** The socket is orphaned\n * (nobody has a reference to it). Teardown must close it to prevent a leak.\n * However, calling `ws.close()` on a `CONNECTING` socket does not reliably\n * abort the underlying HTTP upgrade request in all browsers — the TCP\n * handshake may still complete asynchronously. To handle this edge case,\n * teardown replaces the `open` listener with a one-shot handler that calls\n * `ws.close()` if the connection succeeds after teardown has already run.\n * This ensures the orphaned socket is closed regardless of timing:\n *\n * - If `close()` aborts the connection immediately — done.\n * - If the browser lets the handshake complete anyway — the `open` handler\n * fires and closes the now-connected socket, so it doesn't linger in\n * the browser's network tab as a \"Pending\" request.\n *\n * ## Why `defer`?\n *\n * The outer `defer()` ensures a **new WebSocket** is created on each\n * subscription. Without it, retry operators would reuse the same (possibly\n * closed) socket instance. With `defer`, each retry gets a fresh connection.\n *\n * ## SSR guard\n *\n * If `window` or `WebSocket` is not available (server-side rendering),\n * the function returns an error observable immediately without attempting\n * a connection.\n *\n * ## Lifecycle flags\n *\n * - `opened` — set to `true` when the `open` event fires. Guards the `close`\n * handler so it only errors the observable if the socket was closed *before*\n * the connection was established (e.g. server rejected the upgrade).\n *\n * - `emitted` — set to `true` right before `observer.next(ws)`. Tells the\n * teardown function whether the socket was delivered to the consumer.\n * This is the flag that controls whether teardown closes the socket or\n * leaves it for the consumer.\n *\n * ## Abort\n *\n * The factory does **not** accept an abort signal — cancellation is handled\n * by the caller via standard RxJS unsubscription. When the caller's\n * `takeUntil` (or manual `unsubscribe`) fires, the observable tears down\n * and the orphaned socket is closed. For retry loops, place `takeUntil`\n * at two levels:\n *\n * 1. **Inside the per-attempt chain** (e.g. in `connectToCirrus`) — cancels\n * the current in-flight WebSocket attempt and triggers teardown.\n * 2. **Outside `retry`** (e.g. in `connectToSignaling`) — kills the entire\n * retry loop so no further re-subscriptions occur.\n *\n * ## Usage\n *\n * ```typescript\n * // In connectToCirrus — takeUntil cancels the current attempt:\n * createWebSocket(wsUrl).pipe(\n * takeUntil(abort$),\n * tap(ws => addWsHandlers(ws)),\n * );\n *\n * // In connectToSignaling — takeUntil outside retry kills the loop:\n * defer(() => innerChain$).pipe(\n * retry({ delay: ... }),\n * takeUntil(abort$),\n * );\n * ```\n *\n * @param wsUrl - The `ws://` or `wss://` URL to connect to.\n * @returns Observable that emits a single open WebSocket, then completes.\n * Errors if the connection fails, times out, or the environment\n * does not support WebSocket.\n */\nexport function createWebSocket(\n wsUrl: string,\n timeoutMs: number = WS_TIMEOUT,\n): Observable<WebSocket> {\n // --- SSR guard: bail immediately if WebSocket API is unavailable ---\n if (typeof window === 'undefined' || !('WebSocket' in window)) {\n return throwError(\n () => new Error(\"Your browser doesn't support WebSocket\"),\n );\n }\n\n Logger.info('Creating socket', wsUrl);\n\n return defer(\n () =>\n new Observable<WebSocket>((observer) => {\n const ws = new WebSocket(wsUrl);\n\n // Lifecycle flags — see JSDoc above for detailed explanation.\n let opened = false;\n let emitted = false;\n\n // --- Event handlers (attached during connection, removed in teardown) ---\n\n const onOpen = () => {\n opened = true;\n emitted = true;\n observer.next(ws);\n observer.complete();\n };\n\n const onError = (ev: Event) => {\n const err =\n ev && 'error' in ev && ev?.error instanceof Error\n ? ev.error\n : new Error('WebSocket failed to connect');\n observer.error(err);\n };\n\n const onClose = (ev: CloseEvent) => {\n if (!opened) {\n observer.error(\n new Error(`WebSocket closed before open (code ${ev.code})`),\n );\n }\n };\n\n ws.addEventListener('open', onOpen);\n ws.addEventListener('error', onError);\n ws.addEventListener('close', onClose);\n\n // --- Teardown: runs on unsubscribe, timeout, error, or complete ---\n return () => {\n ws.removeEventListener('error', onError);\n ws.removeEventListener('close', onClose);\n\n if (\n !emitted &&\n (ws.readyState === WebSocket.CONNECTING ||\n ws.readyState === WebSocket.OPEN)\n ) {\n // Socket was never delivered — it's orphaned. Must close it.\n // Replace the open listener with a cleanup handler: if the\n // browser completes the handshake after this teardown, the\n // handler will close the orphaned socket immediately.\n ws.removeEventListener('open', onOpen);\n ws.addEventListener('open', () => ws.close());\n\n // Some strict implementations (including `ws`) emit an `error`\n // when a CONNECTING socket is closed. The observable is already\n // torn down, so consume that expected lifecycle error and remove\n // the temporary handlers once the socket closes.\n const onOrphanError = () => undefined;\n const onOrphanClose = () => {\n ws.removeEventListener('error', onOrphanError);\n ws.removeEventListener('close', onOrphanClose);\n };\n ws.addEventListener('error', onOrphanError);\n ws.addEventListener('close', onOrphanClose);\n ws.close();\n } else {\n // Socket was delivered to consumer — they own it now.\n // Just remove our internal listener; don't touch the socket.\n ws.removeEventListener('open', onOpen);\n }\n };\n }),\n ).pipe(\n timeout({\n first: timeoutMs,\n with: () =>\n throwError(\n () =>\n new Error(`WebSocket connection timed out after ${timeoutMs}ms`),\n ),\n }),\n );\n}\n","import { disconnectStream } from '../../store';\nimport type { SignallingService } from '../../services';\nimport { DisconnectReason } from '../../interfaces';\n\nexport function PlayerDisconnectHandler(this: SignallingService) {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.OrchestrationPlayerDisconnected,\n message: 'Orchestration: PlayerDisconnectHandler',\n }),\n );\n}\nexport function StreamerDisconnectHandler(this: SignallingService) {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.OrchestrationStreamerDisconnected,\n message: 'Orchestration: StreamerDisconnectHandler',\n }),\n );\n}\n","import type { SignallingService } from '../../services';\nimport type { OrchestrationErrorMessage } from '../../interfaces';\nimport { POLLING_TIME } from '../../constants';\nimport { setOrchestrationMessage } from '../../store';\nimport { timer } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n// Structured constants holding code + description\nexport const ORCHESTRATION_ERROR_CODES = {\n NO_AVAILABLE_INSTANCES: {\n code: 4001,\n description: 'There are no instances to run for the requested environment.',\n },\n LIMIT_REACHED: {\n code: 4002,\n description:\n 'The limit of instances for the requested environment is reached.',\n },\n DIFFERENT_ORIGIN: {\n code: 4003,\n description:\n 'Origin instance and client are on different connection servers on instance.',\n },\n} as const;\n\n// Set for codes that should trigger a retry\nconst RETRY_CODES = new Set<number>([\n ORCHESTRATION_ERROR_CODES.NO_AVAILABLE_INSTANCES.code,\n ORCHESTRATION_ERROR_CODES.LIMIT_REACHED.code,\n]);\n\nexport function OrchestrationErrorHandler(\n this: SignallingService,\n msg: OrchestrationErrorMessage,\n) {\n if (RETRY_CODES.has(msg.payload.code)) {\n const errorInfo = Object.values(ORCHESTRATION_ERROR_CODES).find(\n ({ code }) => code === msg.payload.code,\n );\n this.store.dispatch(\n setOrchestrationMessage({ message: errorInfo?.description as string }),\n );\n this.orchestrationRetrySub?.unsubscribe();\n this.orchestrationRetrySub = timer(POLLING_TIME)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.sendRequestStream());\n }\n}\n","import { inject, Injectable, signal } from '@angular/core';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport type { Observable, Subscription } from 'rxjs';\nimport {\n defer,\n EMPTY,\n repeat,\n retry,\n Subject,\n switchMap,\n take,\n throwError,\n timeout,\n timer,\n} from 'rxjs';\nimport {\n catchError,\n filter,\n finalize,\n first,\n map,\n takeUntil,\n tap,\n} from 'rxjs/operators';\nimport {\n abortEstablishingConnection,\n dataChannelConnected,\n dataChannelReady,\n pollingEnded,\n pollingStarted,\n selectClientAndViewIds,\n setAwsInstance,\n setEstablishingConnection,\n setStatusMessage,\n setStatusPercentSignallingServer,\n setUnrealPlaywrightConfig,\n signalingRetryAttempted,\n unrealFeature,\n} from '../store';\nimport { HttpClient } from '@angular/common/http';\nimport { SubService } from './sub.service';\nimport {\n INNER_RETRY_LIMIT,\n OUTER_RETRY_DELAY,\n POLLING_TIME,\n UNREAL_CONFIG,\n UnrealStatusMessage,\n WS_OPEN_STATE,\n WS_RETRY_PER_INSTANCE,\n} from '../constants';\nimport type {\n AnySignalingMessage,\n AwsInstance,\n CloseReason,\n ConfigMessage,\n MessageBase,\n PollingOrchestrationMessage,\n SignalingMessageHandler,\n SignalingMessageMap,\n} from '../interfaces';\nimport { DisconnectReason, OrchestrationMessageTypes } from '../interfaces';\nimport {\n COLOR_CODES,\n generateUuid,\n Logger,\n tapLog,\n Truthy,\n} from '@3dsource/utils';\nimport {\n AnswerHandler,\n ConfigHandler,\n getActiveUrl,\n IceCandidateHandler,\n InstanceReadyHandler,\n InstanceReservedHandler,\n OnCloseHandler,\n OnErrorHandler,\n OnMessageHandler,\n OnOpenHandler,\n PingHandler,\n PlayerCountHandler,\n SSInfoHandler,\n} from '../helpers';\n// Direct file import (not the barrel) so the `extends SubService` graph\n// loads in a deterministic order during spec compile.\nimport { RegionsPingService } from './regions-ping.service';\nimport { StreamerListHandler } from '../helpers/FromStreamerHandlers/StreamerListHandler';\nimport { OfferHandler } from '../helpers/FromStreamerHandlers/OfferHandler';\nimport { ofType } from '@ngrx/effects';\nimport { httpUrlToWs } from '../helpers/http-to-ws-url';\nimport { createWebSocket } from '../helpers/create-websocket';\nimport {\n PlayerDisconnectHandler,\n StreamerDisconnectHandler,\n} from '../helpers/FromStreamerHandlers/ForceDisconnect';\nimport { OrchestrationErrorHandler } from '../helpers/FromStreamerHandlers/OrchestrationErrorHandler';\n\n@Injectable({ providedIn: 'root' })\nexport class SignallingService extends SubService {\n private readonly httpClient = inject(HttpClient);\n private readonly regionsPingService = inject(RegionsPingService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n readonly region = signal('');\n\n readonly selectClientAndViewIds = this.store.selectSignal(\n selectClientAndViewIds,\n );\n readonly environmentId = this.store.selectSignal(\n unrealFeature.selectEnvironmentId,\n );\n readonly streamRequestContext = this.store.selectSignal(\n unrealFeature.selectStreamRequestContext,\n );\n\n onOffer$ = new Subject<RTCSessionDescriptionInit>();\n onConfig$ = new Subject<ConfigMessage>();\n onWebRtcIce$ = new Subject<RTCIceCandidate>();\n onWebRtcAnswer$ = new Subject<RTCSessionDescriptionInit | null>();\n // Pure signal — no side-effects. The `close()` is wired ONCE in init()\n // below so a single abort event triggers exactly one close, regardless\n // of how many pipelines have `takeUntil(this.abort$)` attached.\n abort$ = this.actions$.pipe(ofType(abortEstablishingConnection));\n\n private ws: WebSocket | null = null;\n orchestrationRetrySub?: Subscription;\n\n private wsMsgHandlers: Partial<{\n [K in keyof SignalingMessageMap]: SignalingMessageHandler<K>;\n }> = {};\n\n protected correlationId!: string;\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.setHandlersFromStream();\n\n // Single owner of the \"close on abort\" side-effect. Previously this\n // lived as a `tap` inside `abort$` itself, which made every\n // `takeUntil(this.abort$)` subscriber fire its own close().\n this.abort$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.close({\n code: 1000,\n reason: DisconnectReason.AbortEstablishingConnection,\n });\n });\n\n // `dataChannelReady` is a per-session event. Bind ONLY to destroy$, not\n // to abort$ — `abort$` fires on every destroyUnrealScene (route swap),\n // and `init()` runs once in the constructor. If these subs were torn\n // down by abort$, a second in-injector session (e.g. navigating between\n // two routes that both host <app-unreal-scene>) would never send\n // `p2pEstablished` / `streamPreparedForUserInteraction`. `send()` is\n // already a no-op on a closed WS, so there's no risk of stray messages.\n this.actions$\n .pipe(ofType(dataChannelReady), takeUntil(this.destroy$))\n .subscribe(() => {\n this.send({\n type: 'p2pEstablished',\n source: 'front',\n sessionId: generateUuid(),\n });\n });\n\n this.actions$\n .pipe(\n ofType(dataChannelReady),\n switchMap(() =>\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy), take(1)),\n ),\n takeUntil(this.destroy$),\n )\n .subscribe(() => {\n this.send({\n type: 'streamPreparedForUserInteraction',\n correlationId: generateUuid(),\n });\n });\n }\n\n connectToSignaling(urlList: string[]) {\n if (this.unrealConfig?.playwright) {\n this.store.dispatch(setUnrealPlaywrightConfig());\n this.store.dispatch(\n dataChannelConnected({\n statusMessage: 'Playwright set data channel connected',\n }),\n );\n return EMPTY;\n }\n\n Logger.log('CONNECT TO SIGNALLING');\n\n // Side-effects that belong to one logical `connectToSignaling`\n // invocation (NOT one retry attempt). Wrapping them in a `defer`\n // makes them fire on subscribe (lazy), but only ONCE — the retry\n // below sits INSIDE this defer's projection so re-subscribing the\n // inner pipeline does not re-trigger these.\n return defer(() => {\n this.correlationId = generateUuid();\n this.commandTelemetryService.reset();\n this.startEstablishingConnection();\n\n // Staged retry:\n // * `getRegion()` is pulled in front of the retry — region\n // discovery happens once per outer cycle.\n // * `connectAttempt(urls)` owns inner retry + URL rotation +\n // WS connect. WS/orch failures stay inside it (capped at\n // `INNER_RETRY_LIMIT`).\n // * If the inner retry exhausts, the error propagates to the\n // OUTER retry below which re-runs `getRegion()` (rare, real\n // \"region down\" case). Outer delay > inner so escalation is\n // bounded.\n const connectCycle$ = this.getRegion().pipe(\n tap((region) => this.region.set(region ?? '')),\n map((region) => this.adaptUrlsToRegion(urlList, region)),\n switchMap((urls) => this.connectAttempt(urls)),\n takeUntil(this.abort$),\n );\n\n return connectCycle$.pipe(\n retry({\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'region-cycle',\n }),\n );\n Logger.info(\n `Outer retry (region re-pick) in ${OUTER_RETRY_DELAY}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(OUTER_RETRY_DELAY);\n },\n }),\n );\n }).pipe(takeUntil(this.abort$));\n }\n\n /**\n * One inner cycle: rotate `urlGen` over the pool, resolve via\n * {@link getAwsInstance}, open WS via {@link connectToCirrus},\n * retry up to {@link INNER_RETRY_LIMIT} on any hard failure. The\n * urlGen lives in this closure so retries advance through the\n * pool. Exhaustion bubbles to {@link connectToSignaling}'s outer\n * retry which re-pings the region.\n */\n private connectAttempt(urls: string[]): Observable<WebSocket> {\n const urlGen = getActiveUrl(urls);\n\n return defer(() => this.getAwsInstance(`${urlGen.next().value}`)).pipe(\n tap((awsInstance) => this.store.dispatch(setAwsInstance(awsInstance))),\n switchMap(({ wsUrl }) =>\n // ── WS-only retry tier ─────────────────────────────────────────────\n // Tries the SAME `wsUrl` up to `WS_RETRY_PER_INSTANCE` extra times\n // before letting the error bubble up to the outer (URL-rotating)\n // retry. This is important because the outer retry calls\n // `getAwsInstance(url)` again, which polls orchestration again,\n // which causes orchestrator to RESERVE A NEW instance — the\n // previous reservation is orphaned (server-side leak).\n //\n // The same-wsUrl retry catches transient WS failures (network\n // blip, brief region unavailability, slow cold handshake) without\n // burning a second reservation. If WS still fails after these\n // extra attempts, the instance is genuinely unusable and we\n // accept the cost of rotating.\n this.connectToCirrus(wsUrl ?? '').pipe(\n filter(Truthy),\n take(1),\n retry({\n count: WS_RETRY_PER_INSTANCE,\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'ws-retry',\n }),\n );\n this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);\n Logger.info(\n `WS-only retry on SAME url in ${POLLING_TIME}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(POLLING_TIME);\n },\n }),\n ),\n ),\n // ── URL-rotating retry tier ─────────────────────────────────────────\n // Triggers only when the WS-only retries above are exhausted. Each\n // attempt advances `urlGen` → new `getAwsInstance(url)` → new\n // orchestration poll → new AwsInstance reservation.\n retry({\n count: INNER_RETRY_LIMIT,\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'connect',\n }),\n );\n this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);\n Logger.info(\n `Inner retry (WS+orch) in ${POLLING_TIME}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(POLLING_TIME);\n },\n }),\n );\n }\n\n protected startEstablishingConnection() {\n this.showStatusMessage(UnrealStatusMessage.STARTING_YOUR_SESSION);\n this.store.dispatch(setEstablishingConnection({ value: true }));\n }\n\n private adaptUrlsToRegion(urlList: string[], region?: string) {\n return urlList.map((url) => {\n if (region && !url.includes(':region')) {\n return url.replace(\n /signallingserver/gi,\n `signallingserver/region:${region}`,\n );\n }\n return url;\n });\n }\n\n /**\n * Resolve one URL to an `AwsInstance`. Dispatches to\n * {@link directWsInstance} for `ws://` / `wss://` URLs, otherwise\n * to {@link pollOrchestration}.\n */\n private getAwsInstance(url: string): Observable<AwsInstance> {\n return url.match(/^ws(s?):\\/\\//i)\n ? this.directWsInstance(url)\n : this.pollOrchestration(url);\n }\n\n /**\n * Direct `ws://` / `wss://` short-circuit — no HTTP orchestration.\n * Waits for `clientId` and `viewId` to be truthy in the store, then\n * emits a `Direct Connection` `AwsInstance` and completes.\n */\n private directWsInstance(url: string): Observable<AwsInstance> {\n return this.store.select(selectClientAndViewIds).pipe(\n filter(({ clientId, viewId }) => !!clientId && !!viewId),\n take(1),\n map(\n () =>\n ({\n wsUrl: url,\n pollingUrl: null,\n instanceName: 'Direct Connection',\n }) as AwsInstance,\n ),\n );\n }\n\n /**\n * HTTP-orchestration path. Brackets {@link pollLoop} with the\n * `pollingStarted`/`pollingEnded` actions and the `EXT-getSignaling`\n * telemetry span (start in `defer`, stop in `finalize` with the\n * last response captured in the closure). Maps the final ready\n * response to an `AwsInstance`.\n */\n private pollOrchestration(url: string): Observable<AwsInstance> {\n return defer(() => {\n let lastResp: PollingOrchestrationMessage | undefined;\n this.store.dispatch(pollingStarted());\n this.commandTelemetryService.trackStartCommand('EXT-getSignaling');\n\n return this.store.select(selectClientAndViewIds).pipe(\n tap(({ clientId, viewId }) => {\n if (!clientId || !viewId) {\n Logger.error('Client ID or View ID is not set');\n }\n }),\n filter(({ clientId, viewId }) => !!clientId && !!viewId),\n take(1),\n switchMap(({ clientId, viewId }) =>\n this.pollLoop(`${url}${clientId}/${viewId}`).pipe(\n tap((data) => {\n lastResp = data;\n }),\n ),\n ),\n map((data): AwsInstance => ({\n wsUrl: httpUrlToWs(`${location.protocol}//${data.signallingServer}`),\n pollingUrl: url,\n instanceName: data.signallingServer ?? '',\n })),\n finalize(() => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-getSignaling',\n true,\n { ...(lastResp ?? {}), multi: true } as never,\n );\n this.store.dispatch(pollingEnded());\n }),\n );\n });\n }\n\n /**\n * Poll the SAME `url` until ready, or until HTTP 4xx says the URL\n * is dead.\n *\n * | Response | Class | Action |\n * | ---------------------------------------- | ---------- | ---------------------------- |\n * | 200 `{ signallingServer: 'cirrus', ... }`| ✅ Ready | `first()` emits, loop ends |\n * | 200 empty `signallingServer` (any error/info/mm_message) | ⏳ Progress | Dispatch status+percent, re-poll same URL |\n * | HTTP 4xx (except 429) | ❌ Hard | Re-throw → caller rotates URL |\n * | HTTP 5xx / 429 / timeout / network | ⚠️ Soft | `EMPTY` → `repeat` same URL |\n *\n * `data.error` is NOT treated as fatal — the backend reuses it for\n * progress strings like `\"Ready in ~2m 23s\"`. The only fatal exits\n * are HTTP 4xx and `abort$` upstream.\n */\n private pollLoop(url: string): Observable<PollingOrchestrationMessage> {\n return defer(() =>\n this.httpClient.get<PollingOrchestrationMessage>(url),\n ).pipe(\n timeout(POLLING_TIME),\n catchError((err) => {\n // HTTP 4xx (except 429) = the URL itself is dead → rotate.\n const status = (err as { status?: number } | null)?.status;\n if (\n typeof status === 'number' &&\n status >= 400 &&\n status < 500 &&\n status !== 429\n ) {\n Logger.warn(\n `Polling HARD error on ${url} (HTTP ${status}); rotating URL`,\n );\n return throwError(() => err);\n }\n // Everything else = soft → re-poll same URL.\n Logger.warn(\n `Polling soft error on ${url} (${err?.message ?? err}); re-polling same URL`,\n );\n return EMPTY;\n }),\n tap((data: PollingOrchestrationMessage) => {\n // Ready response is handled by `first()` below — nothing to\n // dispatch here. Empty `signallingServer` = progress.\n if (data.signallingServer) return;\n\n this.showStatusMessage(data?.mm_message || 'Server not found');\n if (data?.info) {\n this.store.dispatch(\n setStatusPercentSignallingServer({\n percent: data.info.percent,\n }),\n );\n }\n }),\n // Re-subscribe (= poll again) after each completed response OR\n // after `catchError` swallowed a transient failure.\n repeat({ delay: () => timer(POLLING_TIME) }),\n // Stop the poll loop as soon as we get a ready response.\n first((data: PollingOrchestrationMessage) => !!data.signallingServer),\n );\n }\n\n private connectToCirrus(wsUrl: string) {\n // Wrapped in `defer` so each subscription (including ws-retry\n // re-subscriptions from `connectAttempt`) starts a FRESH WS attempt:\n // the previous socket is closed and a new one is created. Without\n // this, the WS-only retry would just re-subscribe the SAME WS\n // observable, which in production-defer'd `createWebSocket` would\n // still create a new socket, but in tests would re-emit the same\n // (already-errored) mock observable.\n return defer(() => {\n this.close({ code: 1000, reason: DisconnectReason.NewConnectionAttempt });\n return createWebSocket(wsUrl);\n }).pipe(\n takeUntil(this.abort$),\n tapLog('WS CREATED'),\n tap((ws) => {\n this.commandTelemetryService.trackStartCommand('EXT-iceCandidate');\n this.addWsHandlers(ws);\n }),\n );\n }\n\n private addWsHandlers(ws: WebSocket) {\n ws.onmessage = OnMessageHandler.bind(this);\n ws.onclose = OnCloseHandler.bind(this);\n ws.onerror = OnErrorHandler.bind(this);\n this.ws = ws;\n Logger.log('WS HANDLERS ADDED');\n OnOpenHandler.call(this);\n }\n\n /**\n * Adopt a live signalling socket opened by the `stream-prefetch.js`\n * head-script. The socket is already OPEN and `requestStream` was already\n * sent, so — unlike {@link addWsHandlers} — we attach message/close/error\n * handlers but deliberately skip {@link OnOpenHandler} (which would\n * `setCirrusConnected` + re-`sendRequestStream`). Reuses the head-script's\n * `correlationId` so subsequent correlated messages line up.\n */\n adoptSocket(ws: WebSocket, correlationId: string) {\n this.correlationId = correlationId;\n ws.onmessage = OnMessageHandler.bind(this);\n ws.onclose = OnCloseHandler.bind(this);\n ws.onerror = OnErrorHandler.bind(this);\n this.ws = ws;\n Logger.log(\n 'WS ADOPTED (handshake already done, requestStream already sent)',\n );\n }\n\n private showStatusMessage(statusMessage: string | null) {\n this.store.dispatch(setStatusMessage({ statusMessage }));\n }\n\n /**\n * Close the connection with the signaling server\n * @param data\n */\n close(data: CloseReason) {\n const { code, reason } = data;\n this.onWebRtcAnswer$.next(null);\n this.orchestrationRetrySub?.unsubscribe();\n\n if (this.ws) {\n Logger.warn('Closing existing WebSocket connection');\n const ws = this.ws;\n ws.onmessage = () => null;\n ws.onerror = () => null;\n ws.onclose = () => null;\n ws.onopen = () => null;\n this.ws = null;\n\n if (\n ws.readyState === WebSocket.CONNECTING ||\n ws.readyState === WebSocket.OPEN\n ) {\n ws.addEventListener('open', () => ws.close(code, reason), {\n once: true,\n });\n ws.close(code, reason);\n }\n }\n }\n\n send(data: AnySignalingMessage) {\n let dataString = data;\n if (typeof dataString !== 'string') {\n dataString = JSON.stringify(data);\n }\n if (this.ws && this.ws.readyState === WS_OPEN_STATE) {\n // Only parse-for-display when the logger would actually print — avoids a\n // JSON.parse on every outbound message in production (logger is a no-op).\n if (Logger.isDevMode) {\n Logger.colored(...COLOR_CODES.TO_CIRRUS, JSON.parse(dataString));\n }\n try {\n this.ws.send(dataString);\n } catch {\n Logger.error('No Websocket');\n }\n }\n }\n\n protected handleMessage(msg: MessageBase) {\n try {\n Logger.colored(...COLOR_CODES.FROM_CIRRUS, msg);\n this.wsMsgHandlers?.[msg.type]?.(msg as never);\n } catch {\n Logger.colored(\n ...COLOR_CODES.FROM_CIRRUS_ERROR,\n `Invalid CIRRUS message type: ${msg.type}`,\n );\n }\n }\n\n private setHandlersFromStream() {\n this.wsMsgHandlers.ping = PingHandler.bind(this);\n this.wsMsgHandlers.error = OrchestrationErrorHandler.bind(this);\n this.wsMsgHandlers.config = ConfigHandler.bind(this);\n this.wsMsgHandlers.answer = AnswerHandler.bind(this);\n this.wsMsgHandlers.ssInfo = SSInfoHandler.bind(this);\n this.wsMsgHandlers.playerCount = PlayerCountHandler.bind(this);\n this.wsMsgHandlers.streamerList = StreamerListHandler.bind(this);\n this.wsMsgHandlers.iceCandidate = IceCandidateHandler.bind(this);\n this.wsMsgHandlers.instanceReady = InstanceReadyHandler.bind(this);\n this.wsMsgHandlers.instanceReserved = InstanceReservedHandler.bind(this);\n this.wsMsgHandlers.playerDisconnected = PlayerDisconnectHandler.bind(this);\n this.wsMsgHandlers.streamerDisconnected =\n StreamerDisconnectHandler.bind(this);\n this.wsMsgHandlers.offer = OfferHandler.bind(this);\n }\n\n protected sendRequestStream() {\n const context = this.streamRequestContext();\n const environmentId = this.environmentId();\n if (!context || !environmentId) {\n return;\n }\n\n this.send({\n type: OrchestrationMessageTypes.requestStream,\n correlationId: this.correlationId,\n payload: {\n region: this.region(),\n environmentId,\n context,\n },\n });\n }\n\n /**\n * Check if the WebSocket connection is open and ready.\n */\n isConnected() {\n return !!(this.ws && this.ws.readyState === WS_OPEN_STATE);\n }\n\n private getRegion() {\n Logger.log('Start Getting Region');\n return this.regionsPingService.getFastest().pipe(take(1));\n }\n}\n","import { DataFlowMonitor } from '../../helpers/data-flow-monitor';\n\nexport interface FilterSettings {\n /**\n * Minimum number of kilobits per second to trigger low bandwidth\n */\n minimumBitrate: number;\n /**\n * Amount of a percentage drop to trigger a yellow warning\n */\n yellowFlag: number;\n /**\n * Amount of a percentage drop to trigger a red warning\n */\n redFlag: number;\n /**\n * Minimum number of frames per second to trigger low bandwidth\n */\n minimumFps: number;\n /**\n * Time to wait before checking if we can switch to low bandwidth\n */\n monitoringDelayTime: number;\n // initial guess in kbps\n initialBitrateEstimate: number;\n // initial error covariance\n initialErrorCovariance: number;\n // Q: how much we expect the bitrate to change between measurements\n processNoise: number;\n // R: variance of measurement noise\n measurementNoise: number;\n panelOpen: boolean;\n}\n\n/**\n * Default LBM Filter Parameters\n */\nexport const DefaultFilterModel: FilterSettings = {\n minimumBitrate: 1600,\n yellowFlag: 30,\n redFlag: 50,\n minimumFps: 5,\n monitoringDelayTime: 5000,\n initialBitrateEstimate: 1600,\n initialErrorCovariance: 1,\n processNoise: 3,\n measurementNoise: 500,\n panelOpen: false,\n} as const;\n\n/**\n * Global LBM Filter Parameters\n */\nexport const FilterModel = { ...DefaultFilterModel };\n\n/**\n * Bitrate Monitor Static Class\n */\nexport const BITRATE_MONITOR = new DataFlowMonitor(\n FilterModel.yellowFlag,\n FilterModel.redFlag,\n 20,\n);\n","import {\n BehaviorSubject,\n from,\n fromEvent,\n interval,\n map,\n merge,\n of,\n share,\n take,\n takeUntil,\n} from 'rxjs';\nimport { SubService } from './sub.service';\nimport { Injectable } from '@angular/core';\nimport { type AggregatedStat, type InboundVideoStats } from '../interfaces';\nimport { filter, switchMap } from 'rxjs/operators';\nimport {\n decodeData,\n dispatchResize,\n KalmanFilter1D,\n LatencyTimings,\n qpToQuality,\n} from '../helpers';\nimport {\n changeStatusMainVideoOnScene,\n unrealFeature,\n videoStreamInitialized,\n} from '../store';\nimport { STREAMING_AUDIO_ID, STREAMING_VIDEO_ID } from '../constants';\nimport { Logger, tapLog, Truthy } from '@3dsource/utils';\nimport {\n BITRATE_MONITOR,\n FilterModel,\n} from '../components/low-bandwidth/DataFlowConstants';\n\n@Injectable({ providedIn: 'root' })\nexport class VideoService extends SubService {\n private readonly isVideoPlaying = this.store.selectSignal(\n unrealFeature.selectIsVideoPlaying,\n );\n video: HTMLVideoElement | null = null;\n audio: HTMLAudioElement | null = null;\n\n private container: HTMLDivElement | null = null;\n private latencyTestTimings = new LatencyTimings();\n\n // BehaviorSubject (not Subject) so a late subscriber to `videoStats$` still\n // gets the current track. Adoption (`WebRtcPlayerService.adopt`) calls\n // `attachVideoStream` synchronously/early — before the resize and app-init\n // (`initAppByDataChannelReady$`) subscribers attach — and a plain Subject\n // would drop that emission, so the stats interval (and `setViewportReady`,\n // gated on `framesPerSecond`) would never start.\n private videoTrack$ = new BehaviorSubject<{\n stream: MediaStream;\n pcClient: RTCPeerConnection;\n } | null>(null);\n\n private VideoEncoderQP = 0;\n private aggregatedStats = {} as InboundVideoStats;\n kalmanFilter1D = new KalmanFilter1D(\n FilterModel.initialBitrateEstimate,\n FilterModel.initialErrorCovariance,\n FilterModel.processNoise,\n FilterModel.measurementNoise,\n );\n\n /**\n * Aggregate video stats and emit it as videoStats$\n */\n videoStats$ = this.videoTrack$.pipe(\n // If videoTrack$ emits null, switch to EMPTY → the current interval is canceled.\n switchMap((track) =>\n track\n ? // IMPORTANT! DO NOT CHANGE THOSE NUMBERS, LBM Stats are based on those values\n interval(250).pipe(\n map(() => track.pcClient),\n switchMap((pcClient) => from(this.getStats(pcClient))),\n filter(Truthy),\n )\n : of(null),\n ),\n filter(Truthy),\n share(),\n );\n\n private destroyAbort = new AbortController();\n\n constructor() {\n super();\n this.destroyRef.onDestroy(() => this.destroy());\n }\n\n setContainer(container: HTMLDivElement | null = null) {\n this.container = container;\n }\n\n setLatencyTimings(latencyTimings: string) {\n this.latencyTestTimings.SetUETimings(latencyTimings);\n }\n\n setEncoder(data: ArrayBuffer) {\n this.VideoEncoderQP = Number(decodeData(data));\n }\n\n create() {\n if (!this.container) {\n Logger.warn(\n 'VideoService.create(): no container set; <video> will be built but never attached to the DOM, which suppresses autoplay.',\n );\n }\n this.disconnect$\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe(() => this.destroy());\n this.destroy();\n this.createWebRtcVideo();\n this.createWebRtcAudio();\n }\n\n attachVideoStream(stream: MediaStream, pcClient: RTCPeerConnection) {\n if (!this.video) {\n Logger.error('Video element is not defined.');\n return;\n }\n // Safari refuses muted-autoplay for MediaStreams that carry unmuted\n // audio tracks, even when the <video> is muted. Route video tracks to\n // the video element and audio tracks (if any) to the audio element.\n this.video.srcObject = new MediaStream(stream.getVideoTracks());\n const audioTracks = stream.getAudioTracks();\n if (audioTracks.length && this.audio) {\n this.audio.srcObject = new MediaStream(audioTracks);\n this.playAudio(this.audio);\n }\n this.videoTrack$.next({ stream, pcClient });\n // Safari does not reliably honor the autoplay attribute when srcObject\n // is bound post-creation for a WebRTC MediaStream; trigger play()\n // explicitly and let safePlay() fall back if Safari refuses.\n void this.safePlay(this.video);\n }\n\n attachAudioStream(stream: MediaStream) {\n if (!this.audio) {\n return;\n }\n const audioTracks = stream.getAudioTracks();\n if (!audioTracks.length) {\n return;\n }\n this.audio.srcObject = new MediaStream(audioTracks);\n this.playAudio(this.audio);\n }\n\n play() {\n void this.safePlay(this.video);\n }\n\n async safePlay(video: HTMLVideoElement | null) {\n if (!video) {\n return;\n }\n\n try {\n await video.play();\n return;\n } catch (error: unknown) {\n if (\n error &&\n typeof error === 'object' &&\n 'name' in error &&\n error?.name !== 'NotAllowedError'\n ) {\n Logger.warn('safePlay() rejected with non-autoplay error:', error);\n return;\n }\n\n // Try silent inline autoplay\n video.muted = true;\n video.setAttribute('playsinline', '');\n try {\n await video.play();\n return;\n } catch {\n /* fall through */\n }\n\n // Last resort: wait for the next real user gesture and play with/without sound\n const resume = async () => {\n try {\n // choose whether to unmute here\n // video.muted = false;\n await video.play();\n } catch {\n /* ignore, maybe another gesture needed */\n } finally {\n window.removeEventListener('pointerdown', resume, true);\n window.removeEventListener('keydown', resume, true);\n }\n };\n\n window.addEventListener('pointerdown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n window.addEventListener('keydown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n }\n }\n\n private async getStats(\n pcClient: RTCPeerConnection | null,\n ): Promise<AggregatedStat | null> {\n if (!pcClient || pcClient.connectionState === 'closed') {\n return null;\n }\n\n try {\n const stats = await pcClient.getStats(null);\n // The service may have been destroyed while pcClient.getStats() was\n // pending; bail before writing back to this.aggregatedStats.\n if (!this.video) {\n return null;\n }\n return this.generateAggregatedStatsFunction(stats);\n } catch (err) {\n // Handle InvalidStateError or any transient WebRTC errors gracefully\n if (err instanceof DOMException && err.name === 'InvalidStateError') {\n Logger.warn('Peer connection is closed or unusable, skipping stats.');\n return null;\n }\n throw err;\n }\n }\n\n private generateAggregatedStatsFunction(\n stats: RTCStatsReport,\n ): AggregatedStat {\n const newStat: InboundVideoStats = {} as InboundVideoStats;\n\n // store each type of codec we can get stats on\n newStat.codecs = {};\n newStat.currentRoundTripTime = -1;\n\n stats.forEach((report) => {\n // Get the inbound-rtp for video\n if (report.type === 'inbound-rtp' && report.kind === 'video') {\n Object.assign(newStat, report);\n\n newStat.bytesReceivedStart =\n this.aggregatedStats && this.aggregatedStats.bytesReceivedStart\n ? this.aggregatedStats.bytesReceivedStart\n : report.bytesReceived;\n\n newStat.framesDecodedStart =\n this.aggregatedStats && this.aggregatedStats.framesDecodedStart\n ? this.aggregatedStats.framesDecodedStart\n : report.framesDecoded;\n\n newStat.timestampStart =\n this.aggregatedStats && this.aggregatedStats.timestampStart\n ? this.aggregatedStats.timestampStart\n : report.timestamp;\n\n if (this.aggregatedStats && this.aggregatedStats.timestamp) {\n // Get the mimetype of the video codec being used\n if (\n report.codecId &&\n this.aggregatedStats.codecs &&\n Object.hasOwn(this.aggregatedStats.codecs, report.codecId)\n ) {\n newStat.videoCodec = this.aggregatedStats.codecs[report.codecId];\n }\n\n if (this.aggregatedStats.bytesReceived) {\n // bitrate = bits received since last time / number of ms since last time\n // This is automatically in kbits (where k=1000) since time is in ms and stat we want is in seconds (so a '* 1000' then a '/ 1000' would negate each other)\n newStat.bitrate = Math.floor(\n (8 *\n ((newStat.bytesReceived || 0) -\n this.aggregatedStats.bytesReceived)) /\n (newStat.timestamp - this.aggregatedStats.timestamp),\n );\n }\n\n if (this.aggregatedStats.bytesReceivedStart) {\n newStat.avgBitrate = Math.floor(\n (8 *\n ((newStat.bytesReceived || 0) -\n this.aggregatedStats.bytesReceivedStart)) /\n (newStat.timestamp - this.aggregatedStats.timestampStart),\n );\n }\n\n if (this.aggregatedStats.framesDecodedStart) {\n newStat.avgFrameRate = Math.floor(\n ((newStat.framesDecoded || 0) -\n this.aggregatedStats.framesDecodedStart) /\n ((newStat.timestamp - this.aggregatedStats.timestampStart) /\n 1000),\n );\n }\n }\n }\n\n // Only read RTT from the *nominated* ICE candidate pair. The\n // stats report contains multiple `candidate-pair` entries (one\n // per host/srflx/relay combination tried during ICE); only the\n // nominated pair carries a meaningful `currentRoundTripTime`,\n // the rest typically report 0 or stale values. Without the\n // `nominated` filter, browser-specific iteration order decides\n // who \"wins\" the assignment — Chrome happens to put the\n // nominated pair last and gets the real number, Firefox puts it\n // first and the loop overwrites it with 0 from a non-selected\n // pair, so RTT in the viewer is always 0 in Firefox.\n if (\n report.type === 'candidate-pair' &&\n report.nominated === true &&\n Object.hasOwn(report, 'currentRoundTripTime')\n ) {\n newStat.currentRoundTripTime = report.currentRoundTripTime ?? 0;\n }\n\n if (\n report.type === 'transport' &&\n Object.hasOwn(report, 'selectedCandidatePairId')\n ) {\n const selectedPair = stats.get(report.selectedCandidatePairId);\n if (selectedPair) {\n const local = stats.get(selectedPair.localCandidateId);\n const remote = stats.get(selectedPair.remoteCandidateId);\n newStat.selectedPair = {\n local: { type: local?.candidateType, url: local?.url },\n remote: { type: remote?.candidateType, url: remote?.url },\n };\n }\n }\n\n // Store mimetype of each codec\n if (\n Object.hasOwn(newStat, 'codecs') &&\n report.type === 'codec' &&\n report.mimeType &&\n report.id\n ) {\n const codecId = report.id;\n newStat.codecs[codecId] = report.mimeType\n .replace('video/', '')\n .replace('audio/', '');\n }\n });\n\n newStat.pixelRatio = +window.devicePixelRatio.toFixed(2);\n if (this.aggregatedStats.receiveToCompositeMs) {\n newStat.receiveToCompositeMs = this.aggregatedStats.receiveToCompositeMs;\n this.latencyTestTimings.SetFrameDisplayDeltaTime(\n this.aggregatedStats.receiveToCompositeMs,\n );\n }\n\n // Calculate duration of run\n newStat.runTime = Math.floor(\n (newStat.timestamp - newStat.timestampStart) / 1000,\n );\n newStat.kalmanBitrate = Math.floor(\n this.kalmanFilter1D.update(\n newStat.bitrate || FilterModel.initialBitrateEstimate,\n ),\n );\n\n newStat.dataFlowCheckResult = BITRATE_MONITOR.addValue(\n newStat.kalmanBitrate,\n );\n\n newStat.bitrateDrop = Math.floor(\n newStat.dataFlowCheckResult.dropPercentage,\n );\n this.aggregatedStats = newStat;\n return this.onAggregatedStats(newStat);\n }\n\n private onAggregatedStats(aggregatedStats: InboundVideoStats) {\n return {\n quality: qpToQuality(this.VideoEncoderQP),\n aggregatedStats: {\n ...aggregatedStats,\n VideoEncoderQP: this.VideoEncoderQP,\n },\n };\n }\n\n private destroy() {\n if (!this.video) {\n return;\n }\n this.changeStatusMainVideoOnScene(false);\n // Cancel any gesture listeners armed by safePlay/playAudio in this\n // session, then arm a fresh controller for the next one. Without this,\n // listeners survive mid-session disconnect$ → destroy() cycles.\n this.destroyAbort.abort();\n this.destroyAbort = new AbortController();\n // Pause and detach streams before nulling — Safari can otherwise hold\n // on to the RTCRtpReceiver until GC eventually clears srcObject.\n this.video.pause();\n this.video.srcObject = null;\n if (this.audio) {\n this.audio.pause();\n this.audio.srcObject = null;\n }\n this.video = null;\n this.audio = null;\n this.videoTrack$.next(null);\n\n // Reset stat state to prevent stale deltas on next session\n this.aggregatedStats = {} as InboundVideoStats;\n this.VideoEncoderQP = 0;\n this.kalmanFilter1D = new KalmanFilter1D(\n FilterModel.initialBitrateEstimate,\n FilterModel.initialErrorCovariance,\n FilterModel.processNoise,\n FilterModel.measurementNoise,\n );\n BITRATE_MONITOR.reset();\n\n while (this.container?.firstChild) {\n this.container.removeChild(this.container.firstChild);\n }\n }\n\n private changeStatusMainVideoOnScene(isVideoPlaying: boolean) {\n if (this.isVideoPlaying() === isVideoPlaying) {\n return;\n }\n this.store.dispatch(changeStatusMainVideoOnScene({ isVideoPlaying }));\n }\n\n private createWebRtcVideo() {\n dispatchResize();\n const video = document.createElement('video');\n video.id = STREAMING_VIDEO_ID;\n video.playsInline = true;\n video.muted = true;\n // Safari occasionally resets `muted` when srcObject is rebound; the\n // `defaultMuted` reflection makes the muted state sticky and keeps the\n // muted-autoplay policy intact.\n video.defaultMuted = true;\n // No `autoplay` attribute on purpose: attachVideoStream() always calls\n // safePlay() explicitly, and the attribute would create a second\n // browser-internal play() Promise that we can't catch — which surfaces\n // as an unhandled rejection when destroy() pauses the element.\n video.preload = 'auto';\n video.disablePictureInPicture = true;\n\n this.video = video;\n this.container?.appendChild(this.video);\n\n fromEvent(this.video, 'play')\n .pipe(takeUntil(merge(this.disconnect$, this.destroy$)))\n .subscribe(() => this.changeStatusMainVideoOnScene(true));\n\n fromEvent(this.video, 'loadedmetadata')\n .pipe(\n take(1),\n filter((data) => this.video === data.target),\n tapLog('VideoService loadedmetadata:'),\n filter(() => !!this.video),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.store.dispatch(videoStreamInitialized()));\n }\n\n private createWebRtcAudio() {\n const audio = new Audio();\n audio.id = STREAMING_AUDIO_ID;\n this.audio = audio;\n }\n\n private async playAudio(audio: HTMLAudioElement) {\n try {\n await audio.play();\n return;\n } catch {\n // Wait for the next real user gesture and retry.\n const resume = async () => {\n try {\n await audio.play();\n } catch {\n /* ignore — caller may need another gesture */\n } finally {\n window.removeEventListener('pointerdown', resume, true);\n window.removeEventListener('keydown', resume, true);\n }\n };\n\n window.addEventListener('pointerdown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n window.addEventListener('keydown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { fromEvent, merge, share, Subject, take, tap } from 'rxjs';\nimport { filter, map, takeUntil } from 'rxjs/operators';\nimport {\n answerSent,\n dataChannelConnected,\n disconnectStream,\n dropDC,\n dropPC,\n reconnectPeer,\n unrealFeature,\n} from '../store';\nimport { SubService } from './sub.service';\nimport { RECONNECT_CONFIG } from '../constants';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport type { ConfigMessage, DisconnectReasonType } from '../interfaces';\nimport {\n DisconnectReason,\n WSCloseCode_FORCE_CIRRUS_CLOSE,\n} from '../interfaces';\nimport { SignallingService } from './signalling.service';\nimport { VideoService } from './video.service';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport { ofType } from '@ngrx/effects';\n\n@Injectable({ providedIn: 'root' })\nexport class WebRtcPlayerService extends SubService {\n onDataChannelMessage$ = new Subject<ArrayBuffer>();\n\n private pcClient: RTCPeerConnection | null = null;\n private dcClient: RTCDataChannel | null = null;\n private readonly signallingSrv = inject(SignallingService);\n private readonly videoService = inject(VideoService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private cfg: RTCConfiguration = {};\n private useMic = false;\n private forceTURN = false;\n private forceMonoAudio = false;\n\n /** Whether the remote SDP has been applied to the current peer connection */\n private remoteDescriptionSet = false;\n /** ICE candidates received before the remote description was set */\n private iceCandidateBuffer: RTCIceCandidate[] = [];\n\n private isReconnecting = this.store.selectSignal(\n unrealFeature.selectIsReconnecting,\n );\n\n constructor() {\n super();\n this.init();\n this.actions$\n .pipe(ofType(dropDC), takeUntil(this.destroy$))\n .subscribe(() => this.dcClient?.close());\n this.actions$\n .pipe(ofType(dropPC), takeUntil(this.destroy$))\n .subscribe(() => this.pcClient?.close());\n this.destroyRef.onDestroy(() => this.closePC());\n }\n\n protected init() {\n this.signallingSrv.onConfig$\n .pipe(takeUntil(this.destroy$))\n .subscribe((config: ConfigMessage) => {\n this.videoService.create();\n this.setConfig(config);\n });\n\n // Server-initiated offer: set remote description and respond with answer\n this.signallingSrv.onOffer$\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe((offer) => {\n void this.handleServerOffer(offer);\n });\n\n // Answer to a client-initiated offer\n this.signallingSrv.onWebRtcAnswer$\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe((answer) => {\n void this.handleServerAnswer(answer);\n });\n\n // ICE candidates — buffered until remote description is set\n this.signallingSrv.onWebRtcIce$\n .pipe(takeUntil(this.destroy$))\n .subscribe((candidate) => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-iceCandidate',\n true,\n { multi: true },\n );\n\n if (this.remoteDescriptionSet) {\n this.handleCandidateFromServer(candidate);\n } else {\n this.iceCandidateBuffer.push(candidate);\n }\n });\n }\n\n /**\n * Handles an SDP offer received from the server.\n * Creates a new peer connection, applies the remote offer,\n * then responds with an SDP answer.\n *\n * The DataChannel is NOT created here — the server creates it,\n * and we receive it via the `datachannel` event on the peer connection.\n */\n private async handleServerOffer(\n offer: RTCSessionDescriptionInit,\n ): Promise<void> {\n Logger.info('Received offer from server, creating answer');\n try {\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n\n if (!this.pcClient) {\n this.setupPeerConnection(this.cfg);\n }\n\n const pc = this.pcClient;\n if (!pc) {\n return;\n }\n\n // Offer already defines media transceivers — don't add extras\n await pc.setRemoteDescription(offer);\n this.remoteDescriptionSet = true;\n this.flushIceCandidateBuffer();\n\n await this.createAnswer(pc);\n } catch (e) {\n Logger.error('Failed to handle server offer', e);\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebRTCError,\n message: 'WebRTCError: Failed to handle server offer',\n }),\n );\n }\n }\n\n /**\n * Handles an SDP answer received from the server in response to our offer.\n * Applies the remote description and flushes any buffered ICE candidates.\n */\n private async handleServerAnswer(\n answer: RTCSessionDescriptionInit,\n ): Promise<void> {\n Logger.info('Received answer from server');\n try {\n await this.pcClient?.setRemoteDescription(answer);\n this.remoteDescriptionSet = true;\n this.flushIceCandidateBuffer();\n } catch (e) {\n Logger.error('Failed to set remote description from answer', e);\n }\n }\n\n /** Drains buffered ICE candidates after the remote description has been set */\n private flushIceCandidateBuffer() {\n for (const candidate of this.iceCandidateBuffer) {\n this.handleCandidateFromServer(candidate);\n }\n this.iceCandidateBuffer.length = 0;\n }\n\n /**\n * Creates a client-initiated WebRTC offer and sends it to the server.\n * When the client offers, it also creates the DataChannel.\n * Used for peer reconnection through the existing signaling connection.\n */\n private async createWebRtcOffer(): Promise<void> {\n Logger.info('Creating client-initiated offer');\n try {\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n\n if (!this.pcClient) {\n this.setupPeerConnection(this.cfg);\n }\n\n const pc = this.pcClient;\n if (!pc) {\n return;\n }\n\n // Client offers: transceivers first, then DC, then offer\n await this.setupTransceiversAsync(pc);\n\n this.dcClient = this.createDataChannel(pc, 'UnrealDcConnection', {\n ordered: true,\n });\n\n await this.createOffer(pc);\n } catch (e) {\n Logger.error('Failed to create WebRTC offer', e);\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebRTCError,\n message: 'WebRTCError: Offer Error',\n }),\n );\n }\n }\n\n /**\n * Initializes a new RTCPeerConnection with event handlers.\n * Transceivers are NOT added here — the caller is responsible for adding\n * them at the correct point depending on the negotiation flow.\n */\n private setupPeerConnection(config: RTCConfiguration) {\n this.closePC();\n Logger.log('Creating new RTCPeerConnection with config');\n this.pcClient = new RTCPeerConnection(config);\n\n this.commandTelemetryService.trackStartCommand('EXT-Browser ICE gathering');\n this.commandTelemetryService.trackStartCommand(\n 'EXT-Browser ICE connection',\n );\n this.commandTelemetryService.trackStartCommand(\n 'EXT-Signaling state change',\n );\n\n this.handlePeerConnectionEvents(this.pcClient);\n\n this.disconnect$.pipe(take(1), takeUntil(this.destroy$)).subscribe(() => {\n this.closePC();\n });\n }\n\n private createDataChannel(\n pc: RTCPeerConnection,\n label: string,\n options: RTCDataChannelInit,\n ) {\n const datachannel = pc.createDataChannel(label, options);\n return this.setupDataChannelCallbacks(datachannel);\n }\n\n private handleCandidateFromServer(iceCandidate: RTCIceCandidate) {\n try {\n const candidate = new RTCIceCandidate(iceCandidate);\n Logger.info(\n '[Unreal ICE candidate]',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n );\n\n // If forcing TURN, reject any candidates not relay\n if (this.forceTURN) {\n if (candidate.candidate.indexOf('relay') < 0) {\n Logger.warn(\n 'Dropping candidate because it was not TURN relay.',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n );\n return;\n }\n }\n this.pcClient?.addIceCandidate(candidate).catch((e) => {\n Logger.warn('Failed to add ICE candidate', e);\n });\n } catch (e) {\n Logger.error('Error handleCandidateFromServer', e);\n }\n }\n\n /**\n * Reorders the `m=video` line in the SDP so that payload types matching\n * the given H.264 `profile-level-id` appear first, making the browser\n * prefer that profile during codec negotiation.\n *\n * A `profile-level-id` is a 3-byte hex string (`XXYYZZ`) defined in\n * RFC 6184 that encodes three H.264 parameters:\n * - **Profile IDC** (`XX`) — the H.264 profile.\n * - **Profile IOP** (`YY`) — constraint flags that further narrow the profile.\n * - **Level IDC** (`ZZ`) — the level which caps resolution/framerate/bitrate.\n *\n * ### H.264 profiles relevant to Unreal Engine Pixel Streaming\n *\n * | profile-level-id | Profile | Level | Notes |\n * |------------------|----------------------------|-------|----------------------------------------------|\n * | `42001f` | Baseline | 3.1 | No B-frames, low latency; legacy devices |\n * | `42e01f` | Constrained Baseline | 3.1 | Widest HW decode support; **recommended** |\n * | `4d001f` | Main | 3.1 | B-frames + CABAC; better compression |\n * | `4d4028` | Main | 4.0 | Up to 1080p60; common desktop target |\n * | `640028` | High | 4.0 | Best quality/compression; most GPUs support |\n * | `64002a` | High | 4.2 | Up to 1080p120 or 4K30 |\n * | `640033` | High | 5.1 | Up to 4K60; requires modern HW |\n * | `640034` | High | 5.2 | Up to 4K120; high-end HW only |\n * | `6e001f` | High 10 | 3.1 | 10-bit color; limited browser support |\n * | `f4001f` | High 4:4:4 Predictive | 3.1 | Lossless capable; rare in browsers |\n *\n * UE Pixel Streaming defaults to Constrained Baseline (`42e01f`) or High (`6400xx`)\n * depending on the engine version and `WebRTC.H264Profile` CVar.\n *\n * We prioritize `42e01f` because it guarantees hardware decoding on\n * virtually all client devices (desktop, mobile, embedded), avoiding\n * fallback to software decoding or negotiation of a higher profile\n * that the client GPU may not speed up.\n */\n private prioritizeH264Profile(sdp: string, profileLevelId: string): string {\n const lines = sdp.split('\\r\\n');\n const targetPts: string[] = [];\n\n for (const line of lines) {\n if (\n line.startsWith('a=fmtp:') &&\n line.toLowerCase().includes(`profile-level-id=${profileLevelId}`)\n ) {\n const pt = line.split(':')[1]?.split(' ')[0];\n if (pt) targetPts.push(pt);\n }\n }\n\n if (targetPts.length === 0) return sdp;\n\n return lines\n .map((line) => {\n if (!line.startsWith('m=video')) return line;\n const parts = line.split(' ');\n // parts: m=video <port> <proto> <pt1> <pt2> ...\n const header = parts.slice(0, 3);\n const pts = parts.slice(3);\n const prioritized = [\n ...targetPts.filter((pt) => pts.includes(pt)),\n ...pts.filter((pt) => !targetPts.includes(pt)),\n ];\n return [...header, ...prioritized].join(' ');\n })\n .join('\\r\\n');\n }\n\n private mungeSDP(sdp: string) {\n let mungedSDP = this.prioritizeH264Profile(sdp, '42e01f');\n\n mungedSDP = mungedSDP.replace(\n /(a=fmtp:\\d+ .*level-asymmetry-allowed=.*)\\r\\n/gm,\n '$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\\r\\n',\n );\n\n // Set max bitrate to highest bitrate Opus supports\n let audioSDP = 'maxaveragebitrate=510000;';\n\n if (this.useMic) {\n // Set the max capture rate to 48khz (so we can send high-quality audio from mic)\n audioSDP += 'sprop-maxcapturerate=48000;';\n }\n\n // Force mono or stereo based on whether ?forceMono was passed or not\n audioSDP += this.forceMonoAudio ? 'stereo=0;' : 'stereo=1;';\n\n // Enable in-band forward error correction for opus audio\n audioSDP += 'useinbandfec=1';\n\n // We use the line 'useinbandfec=1' (which Opus uses) to set our Opus specific audio parameters.\n mungedSDP = mungedSDP?.replace('useinbandfec=1', audioSDP);\n\n return mungedSDP;\n }\n\n /**\n * Closes existing PeerConnection and DataChannel, resets negotiation state.\n */\n closePC() {\n if (this.pcClient) {\n Logger.warn('Closing existing PeerConnection');\n }\n this.pcClient?.close();\n this.pcClient = null;\n\n if (this.dcClient) {\n Logger.warn('Closing existing DataChannel');\n }\n this.dcClient?.close();\n this.dcClient = null;\n\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n }\n\n /**\n * Single source of truth for tearing down the remote connection: closes the\n * signaling WebSocket and then the PeerConnection/DataChannel.\n *\n * Called by the `destroyRemoteConnections$` effect and, as a\n * lifecycle-independent safeguard, by `UnrealSceneComponent.onDestroy` (the\n * route-scoped effects may already be torn down on navigation). Both close\n * steps are idempotent, so invoking this twice in one teardown is a harmless\n * no-op.\n */\n releaseRemoteConnections(reason: DisconnectReasonType) {\n this.signallingSrv.close({ code: WSCloseCode_FORCE_CIRRUS_CLOSE, reason });\n this.closePC();\n }\n\n canSend() {\n return this.dcClient && this.dcClient.readyState === 'open';\n }\n\n send(data: ArrayBuffer) {\n if (this.canSend()) {\n this.dcClient?.send(data);\n } else {\n Logger.colored(\n 'black',\n 'yellow',\n `DataChannel connection not prepared or in state: ${this.dcClient?.readyState}`,\n );\n\n // Trigger peer reconnection if DC is not open and we're not yet reconnecting\n this.tryReconnectOnSendFailure();\n }\n }\n\n /**\n * Attempts to reconnect the peer when send fails due to DataChannel not being open.\n * This handles cases where the DC connection is broken, but no error events are fired.\n */\n private tryReconnectOnSendFailure() {\n // Skip if already reconnecting or signaling is not connected\n if (this.isReconnecting()) {\n Logger.info(\n '[Reconnect] Already reconnecting, skipping duplicate attempt',\n );\n return;\n }\n\n if (!this.signallingSrv.isConnected()) {\n Logger.warn('[Reconnect] Cannot reconnect: Signaling not connected');\n return;\n }\n\n // Check if DC exists but is in a non-open state (closing, closed, or connecting stuck)\n const dcState = this.dcClient?.readyState;\n if (dcState && dcState !== 'open') {\n Logger.warn(\n `[Reconnect] DataChannel in \"${dcState}\" state during send, initiating peer reconnection`,\n );\n this.store.dispatch(\n reconnectPeer({\n attempt: 1,\n maxAttempts: RECONNECT_CONFIG.maxAttempts,\n delay: 0,\n }),\n );\n }\n }\n\n /**\n * Reconnects only the WebRTC peer connection without re-establishing signaling.\n * Closes the current PeerConnection and creates a new client-initiated offer\n * through the existing WebSocket connection.\n * @returns true if reconnection was initiated, false if signaling is not connected\n */\n reconnectPeer(): boolean {\n if (!this.signallingSrv.isConnected()) {\n Logger.error(\n '[Reconnect] Cannot reconnect peer: Signaling not connected',\n );\n return false;\n }\n\n if (!this.cfg || Object.keys(this.cfg).length === 0) {\n Logger.error('[Reconnect] Cannot reconnect peer: No config available');\n return false;\n }\n\n Logger.info('[Reconnect] Initiating peer reconnection');\n\n // Close only the PeerConnection, keep WebSocket alive\n this.closePC();\n\n // Create a new WebRTC offer using the stored config\n void this.createWebRtcOffer();\n\n return true;\n }\n\n /**\n * Adopt a fully-negotiated connection prefetched by `stream-prefetch.js`:\n * take ownership of its PeerConnection, DataChannel and media stream instead\n * of running the handshake. The head-script attached property-based handlers\n * (`pc.onicecandidate`, `dc.onmessage`, …) and buffered inbound DC messages;\n * here we detach those, wire our own (addEventListener-based) handlers, replay\n * the buffer in order, then drive `onDataChannelConnected` manually because the\n * DataChannel is already open (its `open` event won't fire again).\n */\n adopt(\n pc: RTCPeerConnection,\n dc: RTCDataChannel,\n stream: MediaStream,\n config: RTCConfiguration,\n dcBuffer: ArrayBuffer[],\n ) {\n // No prior pc/dc should exist on a fresh boot; closePC is idempotent.\n this.closePC();\n this.pcClient = pc;\n this.cfg = config ?? {};\n // Connection is fully negotiated — any late ICE goes straight in, not buffered.\n this.remoteDescriptionSet = true;\n\n // Detach the head-script's property handlers so events aren't processed\n // twice once our addEventListener-based handlers are attached below.\n pc.onicecandidate = null;\n pc.ondatachannel = null;\n pc.ontrack = null;\n\n this.handlePeerConnectionEvents(pc);\n // `setupPeerConnection` normally wires this; replicate for the adopted pc.\n this.disconnect$\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe(() => this.closePC());\n\n // Wire the already-open DataChannel. Nulling then re-listening is safe:\n // these statements run synchronously, so no `message` event can interleave\n // between detaching the script's handler and replaying the buffer.\n dc.onmessage = null;\n dc.onopen = null;\n dc.onclose = null;\n this.dcClient = this.setupDataChannelCallbacks(dc);\n for (const buffered of dcBuffer) {\n this.onDataChannelMessage$.next(buffered);\n }\n // DC is open already: balance the span `setupDataChannelCallbacks` opened\n // (its `open` handler won't fire) and announce the connection ourselves.\n this.commandTelemetryService.trackStopCommand('EXT-DataChannel Connection');\n this.onDataChannelConnected();\n\n // Attach the prefetched media to a fresh <video> (container is set by the\n // scene component before `initSignalling`, so `create()` has a DOM target).\n this.videoService.create();\n this.videoService.attachVideoStream(stream, pc);\n }\n\n private setConfig(parOptions = {} as ConfigMessage) {\n const urlParams = new URLSearchParams(window.location.search);\n\n //**********************\n //Config setup\n //**********************\n this.cfg = { ...parOptions.peerConnectionOptions };\n\n this.forceTURN = urlParams.has('ForceTURN');\n if (this.forceTURN) {\n Logger.info(\n 'Forcing TURN usage by setting ICE Transport Policy in peer connection config.',\n );\n this.cfg.iceTransportPolicy = 'relay';\n }\n\n this.cfg.bundlePolicy = urlParams.has('ForceMaxBundle')\n ? 'max-bundle'\n : 'balanced';\n\n this.cfg.iceCandidatePoolSize = 1;\n\n // When ?useMic check for SSL or localhost\n const isLocalhostConnection =\n location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const isHttpsConnection = location.protocol === 'https:';\n if (this.useMic && !isLocalhostConnection && !isHttpsConnection) {\n this.useMic = false;\n Logger.error(\n 'Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access.',\n );\n Logger.error(\n \"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'\",\n );\n }\n\n this.setupPeerConnection(this.cfg);\n }\n\n private handlePeerConnectionEvents(pcClient: RTCPeerConnection) {\n fromEvent(pcClient, 'signalingstatechange')\n .pipe(\n map(() => this.pcClient?.signalingState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Signaling state change] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Signaling state change',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'iceconnectionstatechange')\n .pipe(\n map(() => this.pcClient?.iceConnectionState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Browser ICE connection] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Browser ICE connection',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'icegatheringstatechange')\n .pipe(\n map(() => this.pcClient?.iceGatheringState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Browser ICE gathering] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Browser ICE gathering',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'connectionstatechange')\n .pipe(\n map(() => this.pcClient?.connectionState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[RTCPeerConnection state] |', state, '|');\n });\n\n fromEvent<RTCPeerConnectionIceEvent>(pcClient, 'icecandidate')\n .pipe(\n map((e: RTCPeerConnectionIceEvent) => e.candidate),\n filter(Truthy),\n tap((candidate: RTCIceCandidate) =>\n Logger.info(\n '[Browser ICE candidate]',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n ),\n ),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((candidate) =>\n this.signallingSrv.send({ type: 'iceCandidate', candidate }),\n );\n\n // When the server creates the DataChannel (server-offer flow),\n // we receive it here via the 'datachannel' event\n fromEvent<RTCDataChannelEvent>(pcClient, 'datachannel')\n .pipe(\n tap((e) =>\n Logger.info(\n `[DATACHANNEL] Received remote DC: label=\"${e.channel.label}\" id=${e.channel.id} protocol=\"${e.channel.protocol}\" ordered=${e.channel.ordered}`,\n ),\n ),\n map((e: RTCDataChannelEvent) => e.channel),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((datachannel) => {\n this.dcClient = this.setupDataChannelCallbacks(datachannel);\n });\n\n const onTrack$ = fromEvent<RTCTrackEvent>(pcClient, 'track').pipe(\n takeUntil(merge(this.disconnect$, this.destroy$)),\n filter((e) => !!e.track),\n tap((e) =>\n Logger.info(\n 'Got track - ' +\n e.track.kind +\n ' id=' +\n e.track.id +\n ' readyState=' +\n e.track.readyState,\n ),\n ),\n share(),\n );\n\n onTrack$\n .pipe(\n filter((e: RTCTrackEvent) => e.track.kind === 'audio'),\n map((e) => e.streams[0]),\n )\n .subscribe((stream) => this.videoService.attachAudioStream(stream));\n\n onTrack$\n .pipe(\n filter((e: RTCTrackEvent) => e.track.kind === 'video'),\n map((e) => e.streams[0]),\n tap(() => Logger.info('Set video source from video track ontrack.')),\n )\n .subscribe((stream) => {\n if (this.pcClient) {\n this.videoService.attachVideoStream(stream, this.pcClient);\n }\n });\n }\n\n private async setupTransceiversAsync(pc: RTCPeerConnection): Promise<void> {\n const hasTransceivers = pc.getTransceivers().length > 0;\n\n // Set up a transceiver for getting UE video\n pc.addTransceiver('video', { direction: 'recvonly' });\n\n // Set up a transceiver for sending mic audio to UE and receiving audio from UE\n if (!this.useMic) {\n pc.addTransceiver('audio', { direction: 'recvonly' });\n } else {\n const audioSendOptions = this.useMic\n ? {\n autoGainControl: false,\n channelCount: 1,\n echoCancellation: false,\n latency: 0,\n noiseSuppression: false,\n sampleRate: 48000,\n sampleSize: 16,\n volume: 1.0,\n }\n : false;\n\n // Note using mic on android chrome requires SSL or chrome://flags/ \"unsafely-treat-insecure-origin-as-secure\"\n const stream = await navigator.mediaDevices.getUserMedia({\n video: false,\n audio: audioSendOptions,\n });\n if (stream) {\n if (hasTransceivers) {\n for (const transceiver of pc.getTransceivers()) {\n if (\n transceiver &&\n transceiver.receiver &&\n transceiver.receiver.track &&\n transceiver.receiver.track.kind === 'audio'\n ) {\n for (const track of stream.getTracks()) {\n if (track.kind && track.kind === 'audio') {\n await transceiver.sender.replaceTrack(track);\n transceiver.direction = 'sendrecv';\n }\n }\n }\n }\n } else {\n for (const track of stream.getTracks()) {\n if (track.kind && track.kind === 'audio') {\n pc.addTransceiver(track, { direction: 'sendrecv' });\n }\n }\n }\n } else {\n pc.addTransceiver('audio', { direction: 'recvonly' });\n }\n }\n }\n\n private setupDataChannelCallbacks(\n datachannel: RTCDataChannel,\n ): RTCDataChannel | null {\n try {\n Logger.log(\n `[DATACHANNEL] Setting up datachannel \"${datachannel.label}\" callbacks...`,\n );\n this.commandTelemetryService.trackStartCommand(\n 'EXT-DataChannel Connection',\n );\n // Inform browser we would like binary data as an ArrayBuffer (FF chooses Blob by default!)\n datachannel.binaryType = 'arraybuffer';\n\n fromEvent(datachannel, 'close')\n .pipe(\n // Only dispatch disconnect if not already reconnecting to avoid infinite loops\n filter(() => !this.isReconnecting()),\n take(1),\n takeUntil(this.destroy$),\n )\n .subscribe((e) => {\n Logger.warn(\n `[DATACHANNEL] Data channel disconnected: ${datachannel.label}(${datachannel.id})`,\n e,\n );\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DataChannelClosed,\n message: 'DataChannelClosed',\n }),\n );\n });\n\n fromEvent(datachannel, 'error')\n .pipe(takeUntil(merge(this.disconnect$, this.destroy$)))\n .subscribe((e) => {\n const message = `[DATACHANNEL] Data channel \"${datachannel.label}\" error. id:${datachannel.id}`;\n Logger.error(message, e);\n });\n\n fromEvent(datachannel, 'open')\n .pipe(\n tap(() => {\n Logger.info(\n `[DATACHANNEL] Data channel \"${datachannel.label}\" connected. id:${datachannel.id}`,\n );\n }),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe(() => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-DataChannel Connection',\n );\n this.onDataChannelConnected();\n });\n\n fromEvent<MessageEvent>(datachannel, 'message')\n .pipe(\n /* tap((e: MessageEvent) => {\n const view = new Uint8Array(e.data);\n Logger.info(\n `[DATACHANNEL] Message received on \"${datachannel.label}\" id=${datachannel.id}, byteCode=${view[0]}, size=${view.byteLength}`,\n );\n }),*/\n map((e: MessageEvent) => e.data),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((data) => this.onDataChannelMessage$.next(data));\n\n return datachannel;\n } catch (e) {\n Logger.warn('[DATACHANNEL] Datachannel setup caused an exception: ', e);\n return null;\n }\n }\n\n private onDataChannelConnected() {\n let statusMessage = 'Session connected, video stream starting.';\n if (navigator.userAgent.includes('Firefox')) {\n statusMessage +=\n '\\n If you are experiencing connection problems please try Google Chrome';\n }\n this.store.dispatch(dataChannelConnected({ statusMessage }));\n }\n\n /**\n * Creates an SDP offer, applies SDP munging, sets it as a local description,\n * and sends it to the server via signaling.\n * Transceivers already configure media directions, so deprecated\n * offerToReceive* options are not used.\n */\n private async createOffer(pcClient: RTCPeerConnection): Promise<void> {\n try {\n const offer = await pcClient.createOffer();\n offer.sdp = this.mungeSDP(offer.sdp ?? '');\n await pcClient.setLocalDescription(offer);\n this.signallingSrv.send(offer);\n } catch {\n Logger.error(\"Couldn't create offer\");\n }\n }\n\n /**\n * Creates an SDP answer, applies SDP munging, sets it as a local description,\n * and sends it to the server via signaling.\n */\n private async createAnswer(pcClient: RTCPeerConnection): Promise<void> {\n try {\n const answer = await pcClient.createAnswer();\n answer.sdp = this.mungeSDP(answer.sdp ?? '');\n await pcClient.setLocalDescription(answer);\n this.signallingSrv.send(answer);\n // Observability signal for the signaling waterfall — the handshake\n // went \"answer sent\" between `offer received` and `datachannel_ready`.\n this.store.dispatch(answerSent());\n } catch (e) {\n Logger.error(\"Couldn't create answer\", e);\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { Observable, defer, of } from 'rxjs';\nimport { Logger } from '@3dsource/utils';\nimport { streamAdopted } from '../store/unreal/unreal.actions';\nimport { WS_OPEN_STATE } from '../constants';\n// Leaf imports (not the `../services` barrel) to keep the SubService extends\n// graph loading deterministically, matching the rest of the module.\nimport { SignallingService } from './signalling.service';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\n\n/**\n * Adopts a WebRTC connection prefetched by the `stream-prefetch.js` head-script\n * and parked on `window.__stream`, instead of running `connectToSignaling` from\n * scratch. Called from the same seam where signalling normally starts\n * (`connectToSignaling$` effect); if there is nothing ready to adopt it returns\n * `false` and the caller falls back to the normal connect — strictly additive.\n */\n@Injectable({ providedIn: 'root' })\nexport class StreamAdoptionService {\n private readonly store = inject(Store);\n private readonly signalling = inject(SignallingService);\n private readonly webRtc = inject(WebRtcPlayerService);\n\n /**\n * Decide adoption, WAITING for an in-flight prefetch instead of racing it.\n *\n * - nothing parked → emit `false` at once (caller connects normally).\n * - already settled (`ready`/`failed`/`adopted`) → adopt-if-ready at once.\n * - still `connecting` → wait for the script's `onSettled` callback and\n * adopt-if-ready the instant it fires (event-driven, zero polling latency).\n *\n * Deliberately NO time budget: for DIRECT orchestration the prefetch holds\n * the socket open while the orchestrator provisions a machine, which can take\n * minutes (150–200s+). A fixed deadline would make Angular give up and open a\n * second connection mid-provisioning — exactly the race/orphan this avoids.\n * The wait is bounded by liveness instead: the script flips the parked state\n * to `failed` on a dead socket (`ws.onclose`/`onerror`), and the caller wraps\n * this in `takeUntil(abortEstablishingConnection)`, so a route change / teardown\n * cancels it. Emits exactly once. Cancelling runs no adoption — which is what\n * stops a fast route-switch from starting overlapping connections.\n *\n * Wrapped in `defer` so the `tryAdopt()` side effect (which dispatches\n * `streamAdopted`) runs at SUBSCRIPTION time, not when the observable is\n * built. The effect prepends `startWith(setEstablishingConnection(true))`,\n * which starts the telemetry session and subscribes its phase catalog; that\n * must happen BEFORE `streamAdopted` → `regionTelemetryOnAdopt$` replays\n * `regionResolved`, or the region phase fires into a session that doesn't\n * exist yet and is lost. `defer` guarantees that ordering.\n */\n awaitAndAdopt$(): Observable<boolean> {\n return defer(() => {\n const parked = window.__stream;\n if (!parked) {\n return of(false);\n }\n if (parked.state !== 'connecting') {\n return of(this.tryAdopt());\n }\n Logger.info(\n '[Adoption] Prefetch in progress — waiting before connecting',\n );\n return this.awaitSettled$(parked);\n });\n }\n\n /**\n * Event-driven wait: the script fires `onSettled` the instant it parks\n * `ready`/`failed`, so we adopt with zero polling lag. Emits exactly once.\n *\n * No timer/budget by design: an indefinitely `connecting` stream is valid\n * (DIRECT orchestration holds the socket open for minutes while it\n * provisions), and every terminal state — including a dead socket — flips to\n * `ready`/`failed` and fires the hook. Teardown (route change → unsubscribe)\n * sets `done`, so a late callback after cancel can't trigger a stray adoption.\n */\n private awaitSettled$(\n parked: NonNullable<Window['__stream']>,\n ): Observable<boolean> {\n return new Observable<boolean>((subscriber) => {\n let done = false;\n parked.onSettled(() => {\n if (done) return;\n done = true;\n subscriber.next(this.tryAdopt());\n subscriber.complete();\n });\n return () => {\n done = true;\n };\n });\n }\n\n /**\n * @returns `true` if a ready parked stream was adopted (caller must NOT\n * start a fresh connection), `false` otherwise.\n */\n tryAdopt(): boolean {\n const parked = window.__stream;\n if (!parked || parked.state !== 'ready') {\n return false;\n }\n // A ready stream whose transport died before adoption is useless — fall back.\n if (\n !parked.ws ||\n parked.ws.readyState !== WS_OPEN_STATE ||\n !parked.pc ||\n !parked.dc ||\n !parked.stream\n ) {\n Logger.warn(\n '[Adoption] Parked stream is ready but transport is not live',\n );\n return false;\n }\n\n Logger.info('[Adoption] Adopting prefetched stream', parked.timings);\n\n // Clear the script's timers and mark the handoff complete.\n parked.adopt();\n\n // Flag cirrus connected (so a later `initSignalling` won't open a 2nd\n // connection), record the adopted machine, and hydrate the streamer info\n // (`ssData`) the prefetch captured from the `ssInfo` message. NOTE:\n // clientId/viewId are left untouched — the host app (metabox) already set\n // them authoritatively from its own data before `initSignalling`; the\n // script's ids are only used internally to establish the connection.\n this.store.dispatch(\n streamAdopted({\n machineId: parked.machineId ?? null,\n ssData: parked.ssData ?? null,\n timings: parked.timings ?? null,\n }),\n );\n\n // Hand the live socket over without re-sending `requestStream`, reusing the\n // script's correlationId (the one `requestStream` was already sent with).\n this.signalling.adoptSocket(parked.ws, parked.ids.correlationId);\n\n // Take ownership of pc/dc/media + replay buffered DC traffic. This drives\n // `dataChannelConnected`, which the `unrealReceiverReady$` effect turns into\n // `dataChannelReady` → app init (console commands, loopback, viewport).\n this.webRtc.adopt(\n parked.pc,\n parked.dc,\n parked.stream,\n parked.config ?? {},\n parked.dcBuffer,\n );\n\n return true;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { Actions, ofType } from '@ngrx/effects';\nimport { defer, of, take, timeout } from 'rxjs';\nimport { catchError, filter, map } from 'rxjs/operators';\nimport { generateUuid, tapLog, Truthy } from '@3dsource/utils';\nimport type {\n FCameraChangedCallback,\n FOnChangeSequenceChangedCallback,\n FOnFinishSequenceChangedCallback,\n FOnFocusObjectCallback,\n FOnObjectTransformChangedCallback,\n FOnSceneStateCallback,\n MetaBoxCallbackList,\n MetaBoxCommandList,\n} from '@3dsource/types-unreal';\nimport { unrealCommandCallback } from '../store';\n\n/**\n * `MetaBoxCommandList` / `MetaBoxCallbackList` are keyed by string-**enum**\n * members, which are nominal: a plain string literal like\n * `'loadProductCommandCallback'` is NOT assignable to the enum key\n * `MetaBoxCallback.FLoadProductCommandCallback`. So template-literal lookups\n * against `keyof MetaBoxCallbackList` always miss. We first re-key the callback\n * list by its plain string values, then bridge command→callback by string.\n */\ntype CallbackByString = {\n [C in keyof MetaBoxCallbackList as `${C & string}`]: MetaBoxCallbackList[C];\n};\n\n/**\n * Resolves a command key to its matching callback type via the\n * `F*Command` → `F*CommandCallback` naming convention\n * (e.g. command `'loadProduct'` → callback `'loadProductCommandCallback'`).\n */\ntype CommandCallbackFor<K extends keyof MetaBoxCommandList> =\n `${K & string}CommandCallback` extends keyof CallbackByString\n ? CallbackByString[`${K & string}CommandCallback`]\n : never;\n\n/** Every command keyed to its real callback type. */\ntype UnrealCommandCallbackMap = {\n [K in keyof MetaBoxCommandList]: CommandCallbackFor<K>;\n};\n\n/**\n * Custom Unreal callback events that are not part of MetaBoxCommandList.\n * These events are pushed from Unreal to the frontend via the data channel.\n * Keys are the runtime `command` values used for filtering.\n */\nexport interface UnrealCallbackEventMap {\n onSceneState: FOnSceneStateCallback;\n onFocusObject: FOnFocusObjectCallback;\n cameraChanged: FCameraChangedCallback;\n onObjectTransformChanged: FOnObjectTransformChangedCallback;\n onChangeSequence: FOnChangeSequenceChangedCallback;\n onFinishedSequence: FOnFinishSequenceChangedCallback;\n}\n\n/**\n * Combined map of all known callback types: every command mapped to its real\n * callback (`MetaBoxCallbackList`) + the custom event callbacks.\n */\nexport type UnrealCallbackDescriptor = UnrealCommandCallbackMap &\n UnrealCallbackEventMap;\n\n@Injectable({ providedIn: 'root' })\nexport class UnrealCallbackService {\n private readonly actions$ = inject(Actions);\n\n /**\n * Listens for unreal command callbacks matching a specific command or event type.\n *\n * Supports both MetaBoxCommand keys (e.g. `MetaBoxCommand.FLoadProductCommand`)\n * and custom Unreal callback events (e.g. `'cameraChanged'`, `'onSceneState'`).\n *\n * @param command - The command or event key to filter callbacks by\n * @returns Observable that emits matching callback payloads\n *\n * @example\n * ```ts\n * // Listen for a MetaBox command callback\n * this.unrealCallbackService\n * .fromUnrealCallback(MetaBoxCommand.FLoadProductCommand)\n * .subscribe(data => console.log(data));\n *\n * // Listen for a custom Unreal event\n * this.unrealCallbackService\n * .fromUnrealCallback('cameraChanged')\n * .subscribe(data => console.log(data));\n * ```\n */\n fromUnrealCallback<K extends keyof UnrealCallbackDescriptor>(command: K) {\n return this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json ? json.commandCallback : json,\n ),\n filter((json) => json.command === command),\n // Cast is required: after a `command`-based filter TS cannot narrow to a\n // type discriminated on `callback`. The unwrapped object IS the full callback.\n map((data) => data as UnrealCallbackDescriptor[K]),\n );\n }\n\n /**\n * Sends a command and observes the matching response by correlationId.\n * Replaces the old `observeCommandResponse` standalone function.\n *\n * @param data - The command data to send\n * @param sender - Function to send the command to Unreal\n * @param timeOut - Timeout in ms (default 60000)\n * @param dispatchOnTimeout - Whether to emit on timeout (default true)\n *\n * @example\n * ```ts\n * this.unrealCallbackService\n * .observeCommandResponse<FLoopBackCommand['command']>(\n * { command: MetaBoxCommand.FLoopBackCommand },\n * (data) => this.communicator.sendCommandToUnreal(data),\n * )\n * .subscribe();\n * ```\n */\n observeCommandResponse<\n K extends keyof MetaBoxCommandList,\n T extends MetaBoxCommandList[K] = MetaBoxCommandList[K],\n >(\n data: T,\n sender: (data: T) => void,\n timeOut = 60000,\n dispatchOnTimeout = true,\n ) {\n const correlationId = generateUuid();\n\n return defer(() => {\n const observable = this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json ? json.commandCallback : json,\n ),\n filter((json) => json.correlationId === correlationId),\n timeout(timeOut),\n catchError(() =>\n dispatchOnTimeout\n ? of({ command: 'timeout', correlationId: 'timeout' })\n : of(null),\n ),\n take(1),\n tapLog('Command Response Observer'),\n filter(Truthy),\n // Cast: response is matched by correlationId, so it is the callback for K.\n map((data) => data as CommandCallbackFor<K>),\n );\n\n setTimeout(() => sender({ ...data, correlationId }), 0);\n\n return observable;\n });\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { Subject, takeUntil, throttleTime } from 'rxjs';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport type { MessageTypeValues } from '../constants';\nimport { MessageType, UNREAL_CONFIG } from '../constants';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\nimport { COLOR_CODES, generateUuid, Logger } from '@3dsource/utils';\nimport {\n commandStarted,\n dataChannelConnected,\n resetAfk,\n unrealFeature,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class UnrealCommunicatorService extends SubService {\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private cirrusConnected = this.store.selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n private readonly afkIgnoredCommands = new Set(['executeConsoleCommand']);\n private skipAfkReset = false;\n // Throttle: input events fire 60-200x/sec, but AFK timeouts are measured in\n // seconds. Leading-edge throttle dispatches once, then suppresses for 1s.\n private readonly resetAfk$ = new Subject<void>();\n\n constructor() {\n super();\n this.resetAfk$\n .pipe(throttleTime(1000), takeUntil(this.destroy$))\n .subscribe(() => this.store.dispatch(resetAfk()));\n this.init();\n }\n\n protected init() {\n if (this.isPlaywrightMode()) {\n return;\n }\n this.emitUIInteraction = this.commandTelemetryService.decorate(\n this.emitUIInteraction.bind(this),\n );\n // Listen to the dataChannelConnected ACTION (point-in-time event) instead\n // of the store selector. The selector reads the current state and can fire on\n // stale `true` from a previous session when switching components (Angular\n // creates the new component before destroying the old one).\n this.actions$\n .pipe(ofType(dataChannelConnected), takeUntil(this.destroy$))\n .subscribe(() => {\n this.requestInitialSettings();\n this.requestQualityControl();\n });\n }\n\n sendCommandToUnreal(data: MetaBoxCommandPacket) {\n if (this.isPlaywrightMode()) {\n return;\n }\n if (this.webRtcPlayerService.canSend()) {\n const uniqId = data?.correlationId ?? generateUuid();\n const sendData: MetaBoxCommandPacket = { ...data, correlationId: uniqId };\n Logger.colored(...COLOR_CODES.TO_UNREAL, sendData);\n\n if (this.afkIgnoredCommands.has(data.command as string)) {\n this.skipAfkReset = true;\n }\n\n this.emitUIInteraction(sendData);\n this.skipAfkReset = false;\n\n this.store.dispatch(\n commandStarted({\n id: uniqId,\n command: data.command as string,\n timeStamp: Date.now(),\n }),\n );\n }\n }\n\n emitUIInteraction(descriptor: MetaBoxCommandPacket) {\n this.emitDescriptor(MessageType.UIInteraction, descriptor);\n }\n\n /**\n A build-in command can be sent to the UE4 client. The commands are defined by a\n JSON descriptor and will be executed automatically.\n The currently supported commands are:\n\n 1. A command to run any console command:\n \"{ ConsoleCommand: <string> }\"\n\n 2. A command to change the resolution to the given width and height.\n \"{ Resolution.Width: <value>, Resolution.Height: <value> }\"\n */\n emitCommand(descriptor: MetaBoxCommandPacket) {\n this.emitDescriptor(MessageType.Command, descriptor);\n }\n\n sendInputData(data: ArrayBuffer) {\n if (this.isPlaywrightMode()) {\n return;\n }\n try {\n if (!this.skipAfkReset) {\n this.resetAfk$.next();\n }\n this.webRtcPlayerService.send(data);\n } catch (error) {\n if (this.cirrusConnected()) {\n Logger.error(error);\n }\n }\n }\n\n isPlaywrightMode() {\n return !!this.unrealConfig?.playwright;\n }\n\n private emitDescriptor(\n messageType: MessageTypeValues,\n descriptor: MetaBoxCommandPacket,\n ) {\n // Convert the descriptor object into a JSON string.\n const descriptorAsString = JSON.stringify(descriptor);\n\n // Add the UTF-16 JSON string to the array byte buffer, going two bytes at\n // a time.\n const data = new DataView(\n new ArrayBuffer(1 + 2 + 2 * descriptorAsString.length),\n );\n let byteIdx = 0;\n data.setUint8(byteIdx, messageType);\n byteIdx++;\n data.setUint16(byteIdx, descriptorAsString.length, true);\n byteIdx += 2;\n\n for (let i = 0; i < descriptorAsString.length; i++) {\n data.setUint16(byteIdx, descriptorAsString.charCodeAt(i), true);\n byteIdx += 2;\n }\n\n this.sendInputData(data.buffer);\n }\n\n private requestInitialSettings() {\n this.sendInputData(\n new Uint8Array([MessageType.RequestInitialSettings]).buffer,\n );\n }\n\n private requestQualityControl() {\n this.sendInputData(\n new Uint8Array([MessageType.RequestQualityControl]).buffer,\n );\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-unreal-error-modal',\n templateUrl: './unreal-error-modal.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './unreal-error-modal.component.scss',\n imports: [SourceButtonComponent],\n})\nexport class UnrealErrorModalComponent {\n #dialogRef = inject(DialogRef);\n readonly dialogData = inject<{ content: string }>(DIALOG_DATA);\n\n close() {\n this.#dialogRef.close();\n }\n}\n","<div class=\"src-modal src-modal--small\">\n <header class=\"src-modal__header\">\n <div\n [attr.data-testid]=\"'unreal-error-header-title'\"\n class=\"src-modal__title\"\n >\n Warning\n </div>\n </header>\n <div class=\"src-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"src-modal__footer\">\n <src-button (onClick)=\"close()\">Ok</src-button>\n </div>\n</div>\n","import { inject, Injectable } from '@angular/core';\nimport { Actions, createEffect, ofType } from '@ngrx/effects';\nimport {\n concat,\n debounceTime,\n delay,\n EMPTY,\n ignoreElements,\n map,\n merge,\n mergeMap,\n of,\n skip,\n startWith,\n switchMap,\n take,\n timeout,\n timer,\n} from 'rxjs';\nimport { Store } from '@ngrx/store';\nimport {\n abortEstablishingConnection,\n commandCompleted,\n commandStarted,\n dataChannelConnected,\n dataChannelReady,\n destroyRemoteConnections,\n destroyUnrealScene,\n disconnectStream,\n dropConnection,\n initSignalling,\n reconnectPeer,\n reconnectPeerFailed,\n reconnectPeerSuccess,\n resetAfk,\n resetConfig,\n resetDataChannelForReconnect,\n resetWarnTimeout,\n setAwsInstance,\n setCirrusDisconnected,\n setConfig,\n setEstablishingConnection,\n setLoopBackCommandIsCompleted,\n setMaxFps,\n setOrchestrationParameters,\n setOrchestrationProgress,\n setStatusPercentSignallingServer,\n setUserInactivityTimeout,\n setViewportNotReady,\n setViewportReady,\n showUnrealErrorMessage,\n startStream,\n unrealCommandCallback,\n updateCirrusInfo,\n videoStreamInitialized,\n} from './unreal.actions';\nimport { unrealFeature } from './unreal.feature';\nimport {\n catchError,\n distinctUntilChanged,\n exhaustMap,\n filter,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators';\nimport { Falsy, Logger, tapLog, Truthy } from '@3dsource/utils';\nimport { getRtcErrorMessage } from '../../helpers';\nimport {\n DATA_CHANNEL_CONNECTION_TIMEOUT,\n DESTROY_DISCONNECT_REASONS,\n MINIMAL_FPS,\n RECONNECT_CONFIG,\n REGION_PING_BACKGROUND_REFRESH_DELAY_MS,\n SCREEN_LOCKER_CONTAINER_ID,\n UNREAL_CONFIG,\n} from '../../constants';\nimport { selectIsAutostart } from './unreal.selectors';\n// Avoid the `../../components` barrel — it transitively imports the\n// services module, producing a `SubService extends undefined` cycle when\n// `unreal.effects.ts` is loaded eagerly (e.g. through the `../store` barrel\n// during a spec compiler).\nimport { WebrtcErrorModalComponent } from '../../components/webrtc-error-modal/webrtc-error-modal.component';\n// Same cycle-break as the component import above: pull each service from\n// its own file rather than through the `../../services` barrel, which would\n// re-include `SubService` consumers and trigger\n// `Class extends value undefined` during eager-load spec compile.\nimport { CommandTelemetryService } from '../../services/command-telemetry.service';\nimport { DevModeService } from '../../services/dev-mode.service';\nimport { RegionsPingService } from '../../services/regions-ping.service';\nimport { SignallingService } from '../../services/signalling.service';\nimport { StreamAdoptionService } from '../../services/stream-adoption.service';\nimport { UnrealCallbackService } from '../../services/unreal-callback.service';\nimport { UnrealCommunicatorService } from '../../services/unreal-communicator.service';\nimport { VideoService } from '../../services/video.service';\nimport { WebRtcPlayerService } from '../../services/web-rtc-player.service';\nimport { Dialog } from '@angular/cdk/dialog';\nimport { HttpClient } from '@angular/common/http';\nimport { ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport type { AwsInstance } from '../../interfaces';\nimport { DisconnectReason } from '../../interfaces';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { MetaBoxCommand } from '@3dsource/types-unreal';\nimport { UnrealErrorModalComponent } from '../../components/unreal-error-modal/unreal-error-modal.component';\n\n@Injectable()\nexport class UnrealEffects {\n private readonly actions$ = inject(Actions);\n private readonly dialog = inject(Dialog);\n private readonly http = inject(HttpClient);\n private readonly store = inject(Store);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly scrollStrategy = inject(ScrollStrategyOptions).block();\n private readonly unrealInitialConfig = inject(UNREAL_CONFIG);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly regionsPingService = inject(RegionsPingService);\n private readonly signallingService = inject(SignallingService);\n private readonly streamAdoptionService = inject(StreamAdoptionService);\n private readonly videoService = inject(VideoService);\n private readonly unrealCallbackService = inject(UnrealCallbackService);\n private dataChannelConnectionTimeout =\n this.unrealInitialConfig?.dataChannelConnectionTimeout ??\n DATA_CHANNEL_CONNECTION_TIMEOUT;\n private connectionCompleted$ = this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(filter(Truthy));\n\n destroyConnections$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyUnrealScene),\n map(() => destroyRemoteConnections({ reason: DisconnectReason.Destroy })),\n );\n });\n\n // Stage 3 — accurate region re-ping in the background once the stream is up.\n // A few seconds after the data channel is ready (so it doesn't compete with\n // the connection handshake) we re-measure regions with the accurate\n // warm-up + median method and refresh the localStorage cache, improving the\n // pick for the NEXT connection. `switchMap` cancels a previous run if the\n // channel re-opens; `takeUntil(destroyUnrealScene)` tears it down on exit.\n // `dispatch: false` — it only writes the cache, no store change.\n refreshRegionCache$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(dataChannelReady),\n delay(REGION_PING_BACKGROUND_REFRESH_DELAY_MS),\n switchMap(() =>\n this.regionsPingService\n .refreshCacheInBackground()\n .pipe(takeUntil(this.actions$.pipe(ofType(destroyUnrealScene)))),\n ),\n );\n },\n { dispatch: false },\n );\n // Fan-in for \"cancel an in-flight signaling attempt\". One named action so\n // both `SignallingService.abort$` and `setDataChannelTimeoutCheck$.abort$`\n // subscribe to single intent (and it shows up as a distinct entry in the\n // Redux DevTools timeline).\n abortEstablishingConnection$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setCirrusDisconnected, dropConnection, destroyUnrealScene),\n map(() => abortEstablishingConnection()),\n );\n });\n resetAfk$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(\n setConfig,\n setUserInactivityTimeout,\n resetWarnTimeout,\n resetConfig,\n ),\n map(() => resetAfk()),\n );\n });\n iframeMessaging$ = createEffect(\n () => {\n const cirrusConnected$ = this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(skip(1));\n\n // On disconnect: immediately show 'Connection closed.', nullify after 2s\n const cirrusStatus$ = cirrusConnected$.pipe(\n switchMap((connected) =>\n connected\n ? of('Creating Socket...')\n : concat(of('Connection closed.'), of(null).pipe(delay(2000))),\n ),\n );\n\n // Skip initial false; emit null on every viewport state change\n const viewportReset$ = this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(\n skip(1),\n delay(500),\n map(() => null),\n );\n\n return merge(\n cirrusStatus$,\n this.store.select(unrealFeature.selectStatusMessage),\n viewportReset$,\n ).pipe(\n debounceTime(0),\n distinctUntilChanged(),\n tapLog('STATUS=>'),\n tap((status) => this.postToScreenLocker(status)),\n );\n },\n { dispatch: false },\n );\n setSignalingTo100$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setAwsInstance),\n map(() => setStatusPercentSignallingServer({ percent: 100 })),\n );\n });\n setOrchestrationParameters$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setOrchestrationParameters),\n map(({ eta }) => eta),\n filter((value) => value > 0),\n switchMap((total) => {\n // Emit every second: 0,1,2,...,total (inclusive)\n return timer(0, 1000).pipe(\n takeUntil(this.connectionCompleted$),\n take(total + 1),\n map((sec) => sec / total),\n distinctUntilChanged(),\n map((progressComplete) =>\n setOrchestrationProgress({ progressComplete }),\n ),\n );\n }),\n );\n });\n setDataChannelTimeoutCheck$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setAwsInstance),\n // require wsUrl present on the action payload\n filter((action) => !!action.wsUrl),\n // for each awsInstance action capture one ssData snapshot, then wait for dataChannelConnected\n switchMap((awsInstance: AwsInstance) => {\n return this.actions$.pipe(\n ofType(updateCirrusInfo),\n take(1),\n switchMap(({ ssData }) => {\n const abort$ = this.actions$.pipe(\n ofType(\n setCirrusDisconnected, // ← \"Cirrus closed\" action — direct,\n // no fan-in tick delay\n abortEstablishingConnection, // ← \"Manual abort\" fan-in for\n // dropConnection / destroy\n ),\n take(1),\n );\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n take(1),\n // 🚫 If Cirrus (or anything else) disconnects first, abort BEFORE timeout fires.\n takeUntil(abort$),\n // if it becomes true within timeout -> complete without dispatching any action\n timeout(this.dataChannelConnectionTimeout),\n // successfully connect → no action\n mergeMap(() => EMPTY),\n // ⏱️ Only actual timeout (or real upstream error) ends up here.\n catchError(() => {\n const error = `⏱️ DataChannel connection timeout ${this.dataChannelConnectionTimeout}ms, requesting new signaling.`;\n Logger.error(error);\n\n const body = {\n awsInstance,\n connectionId: ssData?.connectionId,\n href: location.href,\n userAgent: navigator.userAgent,\n error,\n };\n\n return this.http.post(awsInstance.pollingUrl || '', body).pipe(\n catchError((postError: unknown) => {\n Logger.error('Error sending timeout info:', postError);\n return of(null);\n }),\n // map response to the destroy action that ngrx will dispatch\n map(() =>\n disconnectStream({\n reason: DisconnectReason.DataChannelTimeout,\n message: 'Data Channel Timeout',\n }),\n ),\n );\n }),\n );\n }),\n );\n }),\n );\n });\n /**\n * Effect: `forceViewportNotReady$`\n *\n * Ensures the viewport is explicitly marked as *not ready* to prevent\n * a temporary black screen flash when disconnecting.\n *\n * ### Why\n * - The video stream is disconnected immediately.\n * - The DataChannel closes slightly later.\n * - Closing the DataChannel resets the Unreal scene,\n * which also sets `viewPortReady` to `false`.\n *\n * Without this effect, the order of these events may cause\n * a visible flicker (video flashing to black).\n */\n forceViewportNotReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n withLatestFrom(this.store.select(unrealFeature.selectViewportReady)),\n filter(([, viewportReady]) => viewportReady),\n map(() => setViewportNotReady()),\n );\n });\n resetCirrusOnDestroy$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n withLatestFrom(this.store.select(unrealFeature.selectCirrusConnected)),\n filter(([, cirrusConnected]) => cirrusConnected),\n map(() => setCirrusDisconnected()),\n );\n });\n destroyRemoteConnections$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n tap(({ reason }) => {\n this.webRtcPlayerService.releaseRemoteConnections(reason);\n }),\n filter(({ reason }) => reason === DisconnectReason.DropConnection),\n map(() => dropConnection()),\n );\n });\n destroyConnectionAndRestart$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setCirrusDisconnected),\n withLatestFrom(this.store.select(unrealFeature.selectDisconnectReason)),\n filter(([, reason]) => reason === DisconnectReason.DataChannelTimeout),\n map(() => initSignalling()),\n );\n });\n showUnrealError$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(showUnrealErrorMessage),\n map(({ code }) => getRtcErrorMessage(code)),\n distinctUntilChanged(),\n filter(Truthy),\n switchMap(\n (content: string) =>\n this.dialog.open(UnrealErrorModalComponent, {\n scrollStrategy: this.scrollStrategy,\n data: { content },\n }).closed,\n ),\n map(() => showUnrealErrorMessage({ code: null })),\n );\n });\n unrealReceiverReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n withLatestFrom(this.store.select(unrealFeature.selectIsReconnecting)),\n filter(([, isReconnecting]) => !isReconnecting),\n map(() => dataChannelReady()),\n );\n });\n initAppByDataChannelReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(dataChannelReady),\n tap(() => {\n this.commandsSender.sendCommandToUnreal({\n command: 'setFreezeFrameQuality',\n payload: { value: '95' },\n } as unknown as MetaBoxCommandPacket);\n this.commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FDebugModeCommand,\n payload: { value: this.isDevMode },\n });\n this.commandTelemetryService.trackStartCommand('EXT-SetViewportReady');\n }),\n switchMap(() =>\n // Wait for initial commands to be sent before sending the loopback.\n // commandStarted fires for each sent command; debounce ensures\n // we proceed only after no more commands are started for 50 ms.\n this.actions$.pipe(\n ofType(commandStarted),\n debounceTime(50),\n take(1),\n switchMap(() =>\n this.unrealCallbackService.observeCommandResponse<MetaBoxCommand.FLoopBackCommand>(\n { command: MetaBoxCommand.FLoopBackCommand },\n (data) => this.commandsSender.sendCommandToUnreal(data),\n ),\n ),\n switchMap(() => this.videoService.videoStats$),\n filter(\n ({ aggregatedStats: s }) =>\n !!s.framesPerSecond &&\n s.framesPerSecond > MINIMAL_FPS &&\n (s.framesDecoded ?? 0) > 15,\n ),\n take(1),\n map(() => setLoopBackCommandIsCompleted()),\n ),\n ),\n );\n });\n setViewportReadyBySetLoopBackCommandIsCompleted$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setLoopBackCommandIsCompleted, reconnectPeerSuccess),\n tap(() =>\n this.commandTelemetryService.trackStopCommand(\n 'EXT-SetViewportReady',\n false,\n { ready: true },\n ),\n ),\n map(() => setViewportReady()),\n );\n });\n startStream$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(startStream),\n map(() => initSignalling()),\n );\n });\n // When the video stream is initialized but autoplay didn't kick in\n // (browser blocked it; user gesture pending), the user may need extra\n // time before interacting. Refresh the AFK timer so it doesn't tick\n // toward an inactivity warning while we're waiting for permission.\n resetAfkOnPausedVideoInit$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(videoStreamInitialized),\n filter(() => !!this.videoService.video?.paused),\n map(() => resetAfk()),\n );\n });\n /**\n * Effect: `disconnectReasonHandling$`\n *\n * Translates every destroy-worthy `disconnectStream` into a\n * `destroyRemoteConnections` action so the cleanup chain (close signaling\n * + webrtc, mark cirrus disconnected, force viewport not-ready) runs once\n * per disconnect. The `disconnectReason` state is pinned by the\n * `disconnectStream` reducer's first-wins guard.\n *\n * Skip `DataChannelClosed` when peer reconnection can handle it — that\n * path is owned by `handleDataChannelClosed$` instead.\n */\n disconnectReasonHandling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(({ reason }) => {\n // Skip DataChannelClosed if peer reconnection will handle this case\n if (\n reason === DisconnectReason.DataChannelClosed &&\n this.canPeerReconnect()\n ) {\n Logger.info(\n '[Reconnect] Skipping destroy for DataChannelClosed - peer reconnection will handle',\n );\n return false;\n }\n return DESTROY_DISCONNECT_REASONS.includes(reason);\n }),\n map(({ reason }) => destroyRemoteConnections({ reason })),\n );\n });\n /**\n * Effect: `handleDataChannelClosed$`\n *\n * Triggers peer reconnection when DataChannel closes unexpectedly.\n * Only triggers if reconnection is enabled and the signaling WebSocket\n * is still connected.\n */\n handleDataChannelClosed$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(\n ({ reason }) =>\n reason === DisconnectReason.DataChannelClosed &&\n this.canPeerReconnect(),\n ),\n tap(() => {\n Logger.warn(\n '[Reconnect] DataChannel closed, initiating peer reconnection',\n );\n }),\n map(() =>\n reconnectPeer({\n attempt: 1,\n maxAttempts: RECONNECT_CONFIG.maxAttempts,\n delay: 0,\n }),\n ),\n );\n });\n webrtcErrorModalComponent$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(({ reason }) => reason === DisconnectReason.WebRTCError),\n debounceTime(400),\n switchMap(() =>\n this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(take(1), filter(Falsy)),\n ),\n tap(() => this.dialog.open(WebrtcErrorModalComponent)),\n );\n },\n { dispatch: false },\n );\n /**\n * Effect: `resetStateForPeerReconnect$`\n *\n * Resets the data channel state when peer reconnection starts.\n */\n resetStateForPeerReconnect$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeer),\n filter(() => RECONNECT_CONFIG.enabled),\n filter(({ attempt }) => attempt === 1), // Only reset on the first attempt\n map(() => resetDataChannelForReconnect()),\n );\n });\n /**\n * Effect: `executePeerReconnect$`\n *\n * Executes the actual peer reconnection attempt.\n * This only re-establishes the WebRTC connection, not the signaling.\n */\n executePeerReconnect$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeer),\n filter(() => RECONNECT_CONFIG.enabled),\n tap(({ attempt, maxAttempts }) => {\n Logger.info(\n `[Reconnect] Peer reconnection attempt ${attempt}/${maxAttempts} in ${RECONNECT_CONFIG.delayMs}ms`,\n );\n }),\n switchMap(({ attempt, maxAttempts, delay }) =>\n timer(delay ?? RECONNECT_CONFIG.delayMs).pipe(\n switchMap(() => {\n const success = this.webRtcPlayerService.reconnectPeer();\n if (!success) {\n Logger.error('[Reconnect] Failed to initiate peer reconnection');\n return of(\n this.scheduleRetryOrFail(\n attempt,\n maxAttempts,\n 'Signaling connection lost during peer reconnection',\n ),\n );\n }\n // Monitor for successful data channel connection\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n take(1),\n timeout(this.dataChannelConnectionTimeout),\n tap(() =>\n Logger.info('[Reconnect] Peer reconnection successful!'),\n ),\n map(() => reconnectPeerSuccess()),\n catchError(() => {\n if (attempt < maxAttempts) {\n Logger.warn(\n `[Reconnect] Peer reconnection attempt ${attempt} timed out, scheduling retry`,\n );\n } else {\n Logger.error(\n `[Reconnect] All ${maxAttempts} peer reconnection attempts exhausted`,\n );\n }\n return of(\n this.scheduleRetryOrFail(\n attempt,\n maxAttempts,\n `Peer reconnection failed after ${maxAttempts} attempts`,\n ),\n );\n }),\n );\n }),\n takeUntil(this.actions$.pipe(ofType(destroyUnrealScene), take(1))),\n ),\n ),\n );\n });\n /**\n * Effect: `handlePeerReconnectFailed$`\n *\n * Handles the case when all peer reconnection attempts have failed.\n * Falls back to full disconnection which may trigger full reconnection.\n */\n handlePeerReconnectFailed$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeerFailed),\n map(({ reason }) =>\n disconnectStream({\n reason: DisconnectReason.ReconnectFailed,\n message: reason,\n }),\n ),\n );\n });\n setMaxFps$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(setMaxFps),\n tap(({ maxFps }) => {\n this.commandsSender.sendCommandToUnreal({\n command: 'setMaxFPS',\n payload: { value: maxFps },\n } as unknown as MetaBoxCommandPacket);\n }),\n );\n },\n { dispatch: false },\n );\n sendStatisticsToUnreal$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(showUnrealErrorMessage),\n filter(({ code }) => code === 404),\n withLatestFrom(\n this.store.select(unrealFeature.selectAwsInstance),\n this.store.select(unrealFeature.selectStreamClientCompanyId),\n this.store.select(unrealFeature.selectStreamViewId),\n ),\n switchMap(([action, instance, companyId, viewId]) =>\n this.http\n .post(this.unrealInitialConfig?.customErrorsEndpoint || '', {\n client: instance.pollingUrl,\n session_uuid: companyId,\n session_uuid2: viewId,\n message: {\n type: 'front',\n error: 'pak_not_found',\n info: action?.error ?? '',\n },\n })\n .pipe(\n catchError(() => {\n Logger.error(\n `get error from ${this.unrealInitialConfig?.customErrorsEndpoint}`,\n );\n return EMPTY;\n }),\n ),\n ),\n );\n },\n { dispatch: false },\n );\n // Within an active signaling session, every unrealCommandCallback that\n // carries a correlationId resolves a previously started command.\n // Skip in Playwright mode (deterministic command IDs are issued directly).\n listenUnrealCallbackByInitSignalling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(initSignalling),\n filter(() => !this.unrealInitialConfig?.playwright),\n switchMap(() =>\n this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json\n ? json.commandCallback?.correlationId\n : json?.correlationId,\n ),\n filter(Truthy),\n map((id) => commandCompleted({ id, now: Date.now() })),\n ),\n ),\n );\n });\n connectToSignaling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(initSignalling),\n withLatestFrom(\n this.store.select(unrealFeature.selectMatchUrls),\n this.store.select(selectIsAutostart),\n this.store.select(unrealFeature.selectCirrusConnected),\n ),\n filter(([, , autoStart, cirrusConnected]) => {\n if (cirrusConnected) {\n Logger.warn(\n `SIGNALING REQUEST can't be called when cirrus connection is already established.`,\n );\n }\n return autoStart && !cirrusConnected;\n }),\n map(([, matchMakerUrls]) => [...matchMakerUrls].filter(Truthy)),\n filter((urls) => urls.length > 0),\n // Ensure a single in-flight request per attempt.\n exhaustMap((urls) =>\n // If a prefetched `window.__stream` is ready — or still connecting —\n // adopt it (waiting for it to finish) instead of racing a second\n // connection; otherwise fall back to a fresh signalling connection.\n // `takeUntil(abort)` cancels the wait on teardown / route change so a\n // fast switch can't leave overlapping connections.\n this.streamAdoptionService.awaitAndAdopt$().pipe(\n switchMap((adopted) =>\n adopted ? EMPTY : this.signallingService.connectToSignaling(urls),\n ),\n takeUntil(this.actions$.pipe(ofType(abortEstablishingConnection))),\n // The adopt/connect stream is side-effect-only (its values aren't\n // actions) — swallow them, and emit `setEstablishingConnection`\n // first so the reconnect/resume popup stays hidden during the\n // (possibly deferred) prefetch-adoption wait. Adoption otherwise\n // defers `connectToSignaling`, which is what normally sets this.\n ignoreElements(),\n startWith(setEstablishingConnection({ value: true })),\n ),\n ),\n );\n });\n\n private canPeerReconnect() {\n return RECONNECT_CONFIG.enabled && this.signallingService.isConnected();\n }\n\n /**\n * Either schedules the next peer-reconnect attempt or gives up with the\n * supplied reason. Used in two `executePeerReconnect$` branches that share\n * the same retry-or-fail decision.\n */\n private scheduleRetryOrFail(\n attempt: number,\n maxAttempts: number,\n exhaustedReason: string,\n ) {\n return attempt < maxAttempts\n ? reconnectPeer({ attempt: attempt + 1, maxAttempts })\n : reconnectPeerFailed({ reason: exhaustedReason });\n }\n\n private postToScreenLocker(text: string | null) {\n try {\n const el = document.getElementById(\n this.unrealInitialConfig?.screenLockerContainerId ??\n SCREEN_LOCKER_CONTAINER_ID,\n ) as HTMLIFrameElement | null;\n el?.contentWindow?.postMessage(text, '*');\n } catch {\n // Fails silently if cross-origin\n }\n }\n}\n","import { effect, inject, Injectable, untracked } from '@angular/core';\nimport {\n ControlScheme,\n DEFAULT_AFK_TIMEOUT_PERIOD,\n InputOptions,\n UNREAL_CONFIG,\n} from '../constants';\nimport { SubService } from './sub.service';\nimport { DisconnectReason } from '../interfaces';\nimport {\n disconnectStream,\n resetAfk,\n resetUserInactivityTimeout,\n selectWarnTimeout,\n setAfkTimerCountdown,\n setAfkTimerHide,\n setAfkTimerVisible,\n unrealFeature,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { merge, takeUntil } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class AFKService extends SubService {\n private active = false; // Whether the AFK system is currently looking for inactivity.\n private warnTimer: ReturnType<typeof setTimeout> | undefined;\n private countdown = 0;\n private countdownTimer: ReturnType<typeof setInterval> | undefined;\n private readonly warnTimeout = this.store.selectSignal(selectWarnTimeout);\n private readonly isAfkTimerVisible = this.store.selectSignal(\n unrealFeature.selectIsAfkTimerVisible,\n );\n private readonly isViewportReady = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n /** Ticks every time warnTimeout changes or resetAfk action fires */\n private readonly afkResetTrigger = toSignal(\n merge(\n this.store.select(selectWarnTimeout),\n this.actions$.pipe(ofType(resetAfk)),\n ),\n );\n\n constructor() {\n super();\n this.destroyRef.onDestroy(() => this.clearTimers());\n\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n // Reset AFK warning timer when warnTimeout changes or resetAfk action fires\n effect(() => {\n this.afkResetTrigger();\n untracked(() => {\n if (this.isViewportReady()) {\n this.resetAfkWarningTimer();\n }\n });\n });\n\n // Start AFK warning timer when viewport becomes ready\n effect(() => {\n const ready = this.isViewportReady();\n if (ready) {\n untracked(() => this.startAfkWarningTimer());\n }\n });\n\n // Stop the AFK timers when Cirrus drops the connection. `disconnect$`\n // emits void; the previous toSignal(disconnect$) approach never fired\n // (void → undefined → effect's `!== undefined` guard always false).\n this.disconnect$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.stop());\n\n this.actions$\n .pipe(ofType(resetUserInactivityTimeout), takeUntil(this.destroy$))\n .subscribe(() => this.reset());\n }\n\n private hideOverlay() {\n if (!this.isAfkTimerVisible()) {\n return;\n }\n this.store.dispatch(setAfkTimerHide());\n }\n\n /**\n * Start a timer which when elapsed will warn the user they are inactive.\n */\n private startAfkWarningTimer() {\n this.active = true;\n this.resetAfkWarningTimer();\n }\n\n /**\n * If the user interacts, then reset the warning timer.\n */\n private resetAfkWarningTimer() {\n if (this.active) {\n this.clearTimers();\n // `selectWarnTimeout` already falls back to DEFAULT_AFK_TIMEOUT when\n // config is missing, so warnTimeout() always returns a positive number.\n this.warnTimer = setTimeout(\n () => this.showAfkOverlay(),\n this.warnTimeout() * 1000,\n );\n }\n }\n\n /**\n * Update the count-down spans number for the overlay\n * @param countdown the count down number to be inserted into the span for updating\n */\n private updateCountDown(countdown: number) {\n this.store.dispatch(setAfkTimerCountdown({ countdown }));\n }\n\n private clearTimers() {\n clearInterval(this.countdownTimer);\n clearTimeout(this.warnTimer);\n }\n\n private stop() {\n this.clearTimers();\n this.hideOverlay();\n }\n\n reset() {\n this.hideOverlay();\n // startAfkWarningTimer → resetAfkWarningTimer → clearTimers() already\n // clears the countdown interval, no separate clearInterval needed.\n this.startAfkWarningTimer();\n }\n\n private showAfkOverlay() {\n if (!this.isViewportReady()) {\n return;\n }\n // Pause the timer while the user is looking at the inactivity warning overlay.\n this.active = false;\n this.countdown = DEFAULT_AFK_TIMEOUT_PERIOD;\n this.store.dispatch(setAfkTimerVisible());\n this.updateCountDown(this.countdown);\n\n if (InputOptions.controlScheme === ControlScheme.LockedMouse) {\n document.exitPointerLock();\n }\n\n this.countdownTimer = setInterval(() => {\n this.countdown--;\n if (this.countdown === 0) {\n // The user failed to click so disconnect them\n this.hideOverlay();\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.Afk,\n message: `AFK timeout:${this.warnTimeout()} seconds, popup timeout:${DEFAULT_AFK_TIMEOUT_PERIOD} seconds`,\n }),\n );\n clearInterval(this.countdownTimer);\n } else {\n this.updateCountDown(this.countdown);\n }\n }, 1000);\n }\n}\n","import { computed, inject, Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { of, scan, shareReplay, switchMap } from 'rxjs';\nimport { distinctUntilChanged } from 'rxjs/operators';\nimport { selectShowLoader, selectTotalProgress } from '../store';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { floatToPercents, floatToSmoothPercents } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class LoadingProgressService {\n readonly #store = inject(Store);\n\n readonly loaderVisible = this.#store.selectSignal(selectShowLoader);\n\n // Visibility-gated progress source.\n //\n // When the loader is visible, subscribe to `selectTotalProgress` and run\n // a `scan` that keeps the running max — progress should only advance\n // forward within a single loading session, never regress visually.\n //\n // When the loader is hidden, switch to a constant `of(0)`. This is what\n // makes percents drop to 0 on hide / destroy. A previous attempt used\n // `keepMaxUntilReset` here; that operator could not work because\n // `selectTotalProgress` is non-completing — it keeps re-emitting the\n // last (high) value after a reset, which immediately re-fills the max.\n // `switchMap` cancels the inner subscription on every visibility change\n // so stale emissions can't leak through.\n readonly #boundedProgress$ = toObservable(this.loaderVisible).pipe(\n switchMap((visible) =>\n visible\n ? this.#store\n .select(selectTotalProgress)\n .pipe(scan((max, val) => Math.max(max, val), 0))\n : of(0),\n ),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n readonly smoothPercents = toSignal(\n this.#boundedProgress$.pipe(\n floatToSmoothPercents(),\n distinctUntilChanged(),\n ),\n );\n readonly percents = toSignal(\n this.#boundedProgress$.pipe(floatToPercents(), distinctUntilChanged()),\n );\n readonly loadingStatusChanged = computed(() => ({\n percents: this.percents() ?? 0,\n loaderVisible: this.loaderVisible(),\n }));\n}\n","import { merge } from 'rxjs';\nimport { filter, takeUntil } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { SubService } from './sub.service';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport {\n setFreezeFrame,\n unrealFeature,\n videoStreamInitialized,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { UNREAL_CONFIG } from '../constants';\nimport { uint8ToBase64 } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class FreezeFrameService extends SubService {\n receiving = false;\n\n private size = 0;\n private jpeg: Uint8Array | undefined = undefined;\n private freezeFrameOverlay = new Image();\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n merge(\n this.store.select(unrealFeature.selectViewportReady).pipe(filter(Truthy)),\n this.actions$.pipe(ofType(videoStreamInitialized)),\n )\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.invalidate());\n }\n\n setData(view: Uint8Array) {\n view = view.slice(1 + 4);\n\n if (!this.jpeg) {\n return;\n }\n\n const jpeg = new Uint8Array(this.jpeg.length + view.length);\n jpeg.set(this.jpeg, 0);\n jpeg.set(view, this.jpeg.length);\n this.jpeg = jpeg;\n if (this.jpeg.length === this.size) {\n this.receiving = false;\n Logger.info(`FRAME: Received complete freeze frame ${this.size}`);\n this.showFreezeFrame();\n } else if (this.jpeg.length > this.size) {\n Logger.error(\n `FRAME: Received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`,\n );\n this.store.dispatch(setFreezeFrame({ dataUrl: null, progress: 0 }));\n this.jpeg = undefined;\n this.receiving = false;\n } else {\n this.dispatchInProgress();\n }\n }\n\n private dispatchInProgress() {\n this.store.dispatch(\n setFreezeFrame({\n dataUrl: null,\n progress: (this.jpeg?.length || 0) / this.size,\n }),\n );\n }\n\n start(view: Uint8Array) {\n this.size = new DataView(view.slice(1, 5).buffer).getInt32(0, true);\n this.jpeg = view.slice(1 + 4);\n if (this.jpeg.length < this.size) {\n this.dispatchInProgress();\n Logger.info(\n `FRAME: Received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,\n );\n this.receiving = true;\n } else {\n Logger.info(\n `FRAME: Received complete freeze frame: ${this.jpeg.length}/${this.size}`,\n );\n this.receiving = false;\n this.showFreezeFrame();\n }\n }\n\n invalidate() {\n if (!this.jpeg) {\n return;\n }\n this.store.dispatch(setFreezeFrame({ dataUrl: null, progress: null }));\n this.jpeg = undefined;\n this.receiving = false;\n }\n\n private showFreezeFrame() {\n if (!this.jpeg) {\n return;\n }\n const base64 = uint8ToBase64(this.jpeg);\n this.freezeFrameOverlay.src = 'data:image/jpeg;base64,' + base64;\n this.store.dispatch(\n setFreezeFrame({\n dataUrl: this.freezeFrameOverlay.src,\n progress: 1,\n }),\n );\n }\n}\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const deepEqual = (a: any, b: any) => {\n if (a === b) return true;\n\n // must both be objects (and not null)?\n if (\n typeof a === 'object' &&\n a !== null &&\n typeof b === 'object' &&\n b !== null\n ) {\n // arrays?\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // plain objects\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n // `b` must have key, and values must match\n if (!Object.prototype.hasOwnProperty.call(b, key)) {\n return false;\n }\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n return true;\n }\n\n // everything else (including mismatched types)\n return false;\n};\n","import { filter, takeUntil } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { SubService } from './sub.service';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport { unrealFeature } from '../store';\nimport { Subject } from 'rxjs';\nimport type { ReceivedMimeType } from '../interfaces/ReceivedMimeTypes';\nimport { UNREAL_CONFIG } from '../constants';\nimport { decodeData } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class FileReceiverService extends SubService {\n public fileComplete$ = new Subject<ReceivedFile>();\n\n private valid = false;\n private chunks = 0;\n private mimetype = '' as ReceivedMimeType;\n private receiving = false;\n private extension = '';\n private data: Uint8Array<ArrayBuffer>[] = [];\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe(() => this.reset());\n }\n\n public reset() {\n this.mimetype = '' as ReceivedMimeType;\n this.extension = '';\n this.receiving = false;\n this.valid = false;\n this.chunks = 0;\n this.data = [];\n }\n\n private resetOnStart() {\n this.reset();\n this.receiving = true;\n }\n\n /**\n * Processes a file extension when received over data channel\n * @param view - the file extension data\n */\n setExtensionFromBytes(view: Uint8Array) {\n // Reset this if we got a file message and we are not \"receiving\" it yet\n if (!this.receiving) {\n this.resetOnStart();\n }\n\n //Logger.info(extensionAsString);\n this.extension = decodeData(view.slice(1).buffer);\n }\n\n /**\n * Processes a file mime type when received over data channel\n * @param view - the file mime type data\n */\n setMimeTypeFromBytes(view: Uint8Array) {\n // Reset this if we got a file message and we are not \"receiving\" it yet\n if (!this.receiving) {\n this.resetOnStart();\n }\n\n const mimeAsString = decodeData(view.slice(1).buffer);\n // Logger.info(mimeAsString);\n this.mimetype = mimeAsString as ReceivedMimeType;\n }\n\n /*-------------------------------------------------------------------------------------------*/\n\n public setContentsFromBytes(view: Uint8Array) {\n // If we haven't received the initial setup instructions, return\n if (!this.receiving) return;\n\n const typeSize = 1;\n const intSize = 4;\n const maxMessageSize = 16 * 1024;\n const headerSize = typeSize + intSize;\n const maxPayloadSize = maxMessageSize - headerSize;\n\n // Calculate the total number of chunks from the total this size\n this.chunks = Math.ceil(\n new DataView(view.slice(typeSize, headerSize).buffer).getInt32(0, true) /\n maxPayloadSize,\n );\n\n // Get the file part of the payload\n const thisBytes = view.slice(headerSize);\n\n // Append to existing data that holds this\n this.data.push(thisBytes);\n\n // Uncomment for debug\n // Logger.info(`Received this chunk: ${this.data.length}/${this.chunks}`);\n\n if (this.data.length === this.chunks) {\n this.receiving = false;\n this.valid = true;\n /*Logger.info('Received complete file');\n const transferDuration = new Date().getTime() - this.timestampStart;\n const transferBitrate = Math.round(\n (this.chunks * maxMessageSize) / transferDuration,\n );\n Logger.info(\n `Average transfer bitrate: ${transferBitrate}kb/s over ${transferDuration / 1000} seconds`,\n );*/\n\n /**\n * Reconstruct the file\n * This code reconstructs the received data into the original this based on the mime type and extension provided\n */\n const blob = new Blob([...this.data], { type: this.mimetype });\n this.fileComplete$.next({\n blob,\n mimetype: this.mimetype,\n extension: this.extension,\n valid: this.valid,\n });\n this.reset();\n } else if (this.data.length > this.chunks) {\n Logger.error(\n `Received bigger this than advertised: ${this.data.length}/${this.chunks}`,\n );\n this.reset();\n }\n }\n}\nexport interface ReceivedFile {\n blob: Blob;\n mimetype: ReceivedMimeType;\n extension: string;\n valid: boolean;\n}\n","import { COLOR_CODES, Logger, Truthy, where } from '@3dsource/utils';\nimport { inject, Injectable } from '@angular/core';\nimport { merge } from 'rxjs';\nimport { distinctUntilChanged, filter, takeUntil } from 'rxjs/operators';\nimport {\n ControlScheme,\n InputOptions,\n SCREEN_LOCKER_CONTAINER_ID,\n ToClientMessage,\n UNREAL_CONFIG,\n} from '../constants';\nimport { FreezeFrameService } from './freeze-frame.service';\nimport { VideoService } from './video.service';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\nimport {\n selectStreamConfig,\n showUnrealErrorMessage,\n unrealCommandCallback,\n unrealFeature,\n} from '../store';\nimport { decodeData } from '../helpers';\nimport type { UnrealCommands } from '@3dsource/types-unreal';\nimport { deepEqual } from '../helpers/deepEqual';\nimport { SubService } from './sub.service';\nimport { FileReceiverService } from './file-receiver.service';\n\nconst filteredLogs = [\n {\n command: 'onChangeSequence',\n },\n];\n\n@Injectable({ providedIn: 'root' })\nexport class AggregatorService extends SubService {\n private readonly selectStreamConfig =\n this.store.selectSignal(selectStreamConfig);\n private readonly videoService = inject(VideoService);\n private readonly webrtcPlayer = inject(WebRtcPlayerService);\n private readonly freezeFrame = inject(FreezeFrameService);\n private readonly fileReceiver = inject(FileReceiverService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly responseEventListeners = new Map<\n string,\n (data: unknown) => void\n >();\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.listenWebRTC();\n this.initialize();\n }\n\n protected listenWebRTC() {\n this.webrtcPlayer.onDataChannelMessage$\n .pipe(takeUntil(this.destroy$))\n .subscribe((data) => this.dataChannelMessageHandler(data));\n }\n\n protected initialize() {\n this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(distinctUntilChanged(), takeUntil(this.destroy$))\n .subscribe((connected) => {\n this.resetResponseList();\n if (connected) {\n this.startListenCallbacks();\n }\n });\n\n const unlockViewport$ = this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy));\n\n merge(unlockViewport$, this.disconnect$)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.removeLoadScreen());\n\n if (\n !this.selectStreamConfig()?.autoStart ||\n location.protocol === 'http:'\n ) {\n this.removeLoadScreen();\n }\n\n InputOptions.controlScheme = ControlScheme.HoveringMouse;\n }\n\n private addResponseEventListener(\n name: string,\n listener: (data: unknown) => void,\n ) {\n this.responseEventListeners.set(name, listener);\n }\n\n private removeLoadScreen() {\n document\n .getElementById(\n this.unrealConfig?.screenLockerContainerId ||\n SCREEN_LOCKER_CONTAINER_ID,\n )\n ?.remove();\n }\n\n private startListenCallbacks() {\n Logger.info('Start Listen Unreal Callbacks');\n let previousJson: unknown = null;\n this.addResponseEventListener('unrealEvents', (data) => {\n try {\n if (typeof data !== 'string') {\n return;\n }\n const json = JSON.parse(data);\n\n if (!deepEqual(json, previousJson)) {\n if (json?.error) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL_ERROR,\n `${json.error}`,\n data,\n );\n this.store.dispatch(\n showUnrealErrorMessage({ code: json.code, error: json?.error }),\n );\n } else {\n this.showMessageFromUnreal(json);\n previousJson = json;\n\n this.store.dispatch(unrealCommandCallback({ json }));\n }\n } else {\n // Logger.warn('Duplicate message received');\n }\n } catch (e) {\n Logger.error(e);\n Logger.error('ERROR=>', data);\n }\n });\n }\n\n private showMessageFromUnreal<T extends UnrealCommands>(json: T) {\n if (filteredLogs.some(where({ command: json?.command }))) {\n return;\n }\n Logger.colored(...COLOR_CODES.FROM_UNREAL, json);\n }\n\n private resetResponseList() {\n this.responseEventListeners.clear();\n }\n\n private dataChannelMessageHandler(data: ArrayBuffer) {\n const view = new Uint8Array(data);\n const anyData = data.slice(1);\n\n if (this.freezeFrame.receiving) {\n this.freezeFrame.setData(view);\n return;\n }\n\n switch (view[0]) {\n case ToClientMessage.QualityControlOwnership: {\n const ownership = view[1] !== 0;\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Received quality controller message, will control quality: ' +\n ownership,\n );\n break;\n }\n case ToClientMessage.Response: {\n const response = decodeData(anyData);\n for (const listener of this.responseEventListeners.values()) {\n listener(response as never);\n }\n break;\n }\n case ToClientMessage.Command: {\n // The parsed command is only used for the dev log — skip the work in prod.\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n }\n case ToClientMessage.FileExtension:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileExtension');\n this.fileReceiver.setExtensionFromBytes(view);\n break;\n case ToClientMessage.FileMimeType:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileMimeType');\n this.fileReceiver.setMimeTypeFromBytes(view);\n break;\n case ToClientMessage.FileContents:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileContents');\n this.fileReceiver.setContentsFromBytes(view);\n break;\n case ToClientMessage.FreezeFrame:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'Freeze frame');\n this.freezeFrame.start(view);\n break;\n case ToClientMessage.UnfreezeFrame:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'Un-Freeze frame');\n this.freezeFrame.invalidate();\n break;\n case ToClientMessage.VideoEncoderAvgQP:\n this.videoService.setEncoder(anyData);\n break;\n case ToClientMessage.LatencyTest: {\n const latencyTimings = decodeData(anyData);\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Got latency timings :',\n latencyTimings,\n );\n Logger.colored(...COLOR_CODES.FROM_UNREAL, latencyTimings);\n this.videoService.setLatencyTimings(latencyTimings);\n break;\n }\n case ToClientMessage.InitialSettings:\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'InitialSettings message :',\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n case ToClientMessage.Protocol:\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Protocol message :',\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n case ToClientMessage.InputControlOwnership:\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'InputControlOwnership message :',\n anyData,\n );\n break;\n default:\n Logger.warn(`unrecognized data received, packet ID ${view[0]}`);\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport {\n disconnectStream,\n dropDC,\n dropPC,\n setConfig,\n setMaxFps,\n unrealFeature,\n} from '../store';\nimport { of, switchMap, take } from 'rxjs';\nimport { HttpClient } from '@angular/common/http';\nimport { Logger } from '@3dsource/utils';\nimport { catchError, filter } from 'rxjs/operators';\n// Direct file imports — see the comment in signalling.service.ts on cycle-break.\nimport { DevModeService } from './dev-mode.service';\nimport { SubService } from './sub.service';\nimport { UnrealCommunicatorService } from './unreal-communicator.service';\nimport { DisconnectReason } from '../interfaces';\nimport { MetaBoxCommand } from '@3dsource/types-unreal';\nimport { UNREAL_CONFIG } from '../constants';\n\ninterface CustomWindow extends Window {\n emitUIInteraction?: (data: unknown) => void;\n emitCommand?: (data: unknown) => void;\n dropConnection?: (data: unknown) => void;\n dropDC?: (data: unknown) => void;\n dropPC?: (data: unknown) => void;\n toggleBandwidth?: (data: unknown) => void;\n setMaxFps?: (data: number) => void;\n rebootInstance?: (data: unknown) => void;\n startShowcase?: (data: unknown) => void;\n restartApp?: (data: unknown) => void;\n unrealHelp?: (data: unknown) => void;\n setWarnTime?: (data: number) => void;\n setResolution?: (data: { w: number; h: number }) => void;\n}\n\ndeclare let window: CustomWindow;\n\n@Injectable({ providedIn: 'root' })\nexport class ConsoleExtensionsService extends SubService {\n readonly #httpClient = inject(HttpClient);\n readonly #commandsSender = inject(UnrealCommunicatorService);\n readonly #isDevMode = inject(DevModeService).isDevMode;\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n\n // Clean up window properties on destroyRef\n this.destroyRef.onDestroy(() => {\n if (!this.#isDevMode) {\n return;\n }\n window.dropConnection = undefined;\n window.dropDC = undefined;\n window.dropPC = undefined;\n window.setResolution = undefined;\n window.toggleBandwidth = undefined;\n window.setMaxFps = undefined;\n window.restartApp = undefined;\n window.unrealHelp = undefined;\n window.setWarnTime = undefined;\n });\n }\n\n protected init() {\n if (!this.#isDevMode || this.unrealConfig?.playwright) {\n return;\n }\n window.dropConnection = () => {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DropConnection,\n message: 'Manual Console Drop',\n }),\n );\n return true;\n };\n window.dropDC = () => {\n this.store.dispatch(dropDC());\n return true;\n };\n window.dropPC = () => {\n this.store.dispatch(dropPC());\n return true;\n };\n window.setResolution = ({ w, h }) => {\n const resolution = { x: w, y: h };\n this.#commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FChangeResolutionCommand,\n payload: { resolution },\n });\n return `Resolution set to ${resolution.x}x${resolution.y}`;\n };\n window.setMaxFps = (maxFps: number) => {\n this.store.dispatch(setMaxFps({ maxFps }));\n return `Max Fps Set to ${maxFps}`;\n };\n window.restartApp = () => {\n this.store\n .select(unrealFeature.selectAwsInstance)\n .pipe(\n take(1),\n filter((data) => !!data.instanceName),\n switchMap((data) =>\n this.#httpClient.get(`//${data.instanceName}/restartapp`),\n ),\n catchError(() => of(null)),\n )\n .subscribe();\n };\n window.unrealHelp = () => this.unrealHelp();\n window.setWarnTime = (time: number) => {\n this.store.dispatch(setConfig({ config: { warnTimeout: time } }));\n };\n }\n\n private unrealHelp() {\n Logger.info(\n 'dropConnection() => Closes Web Socket and abort communication.',\n );\n Logger.info('toggleBandwidth() => toggles speed.');\n Logger.info('restartApp() => force restart Unreal app.');\n Logger.info('rebootInstance() => force reboot instance.');\n Logger.info('startShowcase(time) => start Showcase.');\n Logger.info('setWarnTime() => set time to appear the AFK window.');\n Logger.info('emitCommand(command) => send command to Unreal Engine.');\n }\n}\n","import type { IKeyCode, IKeyName } from '@3dsource/utils';\nimport {\n InvertedKeyMap,\n KeyboardNumericCode,\n Logger,\n Truthy,\n} from '@3dsource/utils';\nimport type { InputProps } from '../interfaces';\nimport type { MessageTypeValues } from '../constants';\nimport {\n InputOptions,\n MessageType,\n MouseButton,\n MouseButtonsMask,\n SpecialKeyCodes,\n UNREAL_CONFIG,\n} from '../constants';\nimport type { Observable } from 'rxjs';\nimport { fromEvent, merge, NEVER, startWith, Subject, takeUntil } from 'rxjs';\nimport { debounceTime, filter, map } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { fromResizeObserver } from '../helpers';\nimport { UnrealCommunicatorService } from './unreal-communicator.service';\nimport { DevModeService } from './dev-mode.service';\nimport { SubService } from './sub.service';\nimport { VideoService } from './video.service';\nimport { unrealFeature, videoAdaptedToContainer } from '../store';\nimport { ofType } from '@ngrx/effects';\n\nconst INITIAL_FINGER_IDS = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] as const;\nconst UNSIGNED_RANGE = 65536;\nconst UNSIGNED_OUT_OF_RANGE = 65535;\nconst SIGNED_RANGE = 32767;\nconst WHEEL_DELTA_SCALE = -120;\nconst RESIZE_DEBOUNCE_MS = 300;\nconst FUNCTION_KEY_MIN = 112;\nconst FUNCTION_KEY_MAX = 123;\nconst TAB_KEY_CODE = 9;\n\n@Injectable({ providedIn: 'root' })\nexport class InputService extends SubService {\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n readonly defaultKeys = [\n KeyboardNumericCode.KeyW,\n KeyboardNumericCode.KeyS,\n KeyboardNumericCode.KeyA,\n KeyboardNumericCode.KeyD,\n KeyboardNumericCode.ArrowUp,\n KeyboardNumericCode.ArrowDown,\n KeyboardNumericCode.ArrowLeft,\n KeyboardNumericCode.ArrowRight,\n KeyboardNumericCode.NumpadAdd,\n KeyboardNumericCode.NumpadSubtract,\n KeyboardNumericCode.ControlRight,\n KeyboardNumericCode.Equal,\n KeyboardNumericCode.Minus,\n KeyboardNumericCode.NumpadDecimal,\n ];\n private availableKeys: IKeyCode[] = this.defaultKeys;\n private options: InputProps = InputOptions;\n private reInit$ = new Subject<void>();\n private deactivatedVideoTrigger$: Observable<unknown> = NEVER;\n\n private normalizeAndQuantizeUnsigned = (_x: number, _y: number) => ({\n inRange: false,\n x: UNSIGNED_OUT_OF_RANGE,\n y: UNSIGNED_OUT_OF_RANGE,\n });\n\n private normalizeAndQuantizeSigned = (_x: number, _y: number) => ({\n x: 0,\n y: 0,\n });\n\n private videoBoundingRect: DOMRect = new DOMRect(0, 0, 1, 1);\n private fingerIds = new Map<number, number>();\n private maxByteValue = 255;\n private fingers: number[] = [...INITIAL_FINGER_IDS];\n\n // Reusable wire buffers. Input events fire at up to ~60 Hz; the data channel\n // copies the bytes synchronously on sending (RTCDataChannel.send), so a single\n // buffer per message shape is safe and avoids per-event allocation/GC churn.\n private readonly mouseMoveView = new DataView(new ArrayBuffer(9));\n private readonly mouseButtonView = new DataView(new ArrayBuffer(6));\n private readonly mouseWheelView = new DataView(new ArrayBuffer(7));\n private readonly touchView = new DataView(new ArrayBuffer(9));\n private readonly keyPressView = new DataView(new ArrayBuffer(3));\n private readonly singleByteView = new DataView(new ArrayBuffer(1));\n private readonly keyDownBytes = new Uint8Array(3);\n private readonly keyUpBytes = new Uint8Array(2);\n\n private offsetParams: OffsetParams = {\n scaleX: 1,\n scaleY: 1,\n scaledHeight: 0,\n scaledWidth: 0,\n offsetByY: 0,\n offsetByX: 0,\n };\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n const visibilityHiddenTrigger$ = fromEvent(\n document,\n 'visibilitychange',\n ).pipe(\n map(() => document.visibilityState === 'hidden'),\n filter(Truthy),\n );\n const visibilityVisibleTrigger$ = fromEvent(\n document,\n 'visibilitychange',\n ).pipe(\n map(() => document.visibilityState === 'visible'),\n filter(Truthy),\n startWith(true),\n );\n\n this.deactivatedVideoTrigger$ = merge(\n this.disconnect$,\n this.reInit$,\n visibilityHiddenTrigger$,\n this.destroy$,\n );\n\n merge(\n visibilityVisibleTrigger$,\n this.store.select(unrealFeature.selectViewportReady).pipe(filter(Truthy)),\n )\n .pipe(\n filter(() => !!this.video),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.setup());\n }\n\n useKeyboardKeys(keys: IKeyCode[]) {\n this.availableKeys = keys;\n }\n\n get video() {\n return this.videoService.video;\n }\n\n private setup() {\n const video = this.video;\n if (!video) {\n return;\n }\n this.options = InputOptions;\n this.reInit$.next();\n\n // Reset touch state to prevent stale identifiers across sessions\n this.fingerIds.clear();\n this.fingers = [...INITIAL_FINGER_IDS];\n\n merge(\n fromResizeObserver(video),\n this.actions$.pipe(ofType(videoAdaptedToContainer)),\n )\n .pipe(\n debounceTime(RESIZE_DEBOUNCE_MS),\n takeUntil(this.deactivatedVideoTrigger$),\n )\n .subscribe(() => this.setupNormalizeAndQuantize(video));\n\n this.setupNormalizeAndQuantize(video);\n this.registerInputs(video);\n }\n\n /**\n * We use `object-fit: cover` on the video element. Since the video can have\n * a different aspect ratio from its container (and potentially be larger),\n * we need to calculate offsets and scale factors to map container (e.g., mouse)\n * coordinates back to the actual video coordinates.\n *\n * @param videoElement The video element whose scaling and positioning we need\n * @returns Object containing offset and scale info for coordinate normalization\n * @private\n */\n private getObjectFitOffset(videoElement: HTMLVideoElement) {\n const { width, height } = this.videoBoundingRect;\n const { videoWidth, videoHeight } = videoElement;\n\n Logger.log('Video Quantizing with => ', this.videoBoundingRect, {\n videoWidth,\n videoHeight,\n });\n\n const containerRatio = width / height;\n const videoRatio = videoWidth / videoHeight;\n\n const scale =\n videoRatio > containerRatio ? height / videoHeight : width / videoWidth;\n\n const scaledWidth = videoWidth * scale;\n const scaledHeight = videoHeight * scale;\n\n const offsetByX = (width - scaledWidth) / 2;\n const offsetByY = (height - scaledHeight) / 2;\n\n const scaleX = width / scaledWidth;\n const scaleY = height / scaledHeight;\n\n return {\n offsetByX,\n offsetByY,\n scaleX,\n scaleY,\n scaledWidth,\n scaledHeight,\n };\n }\n\n private setupNormalizeAndQuantize(videoElement: HTMLVideoElement) {\n this.videoBoundingRect = videoElement.getBoundingClientRect();\n this.offsetParams = this.getObjectFitOffset(videoElement);\n\n // Unsigned XY positions are the ratio (0.0..1.0) along a viewport axis,\n // quantized into a uint16 (0..65536).\n // Signed XY deltas are the ratio (-1.0..1.0) along a viewport axis,\n // quantized into an int16 (-32767..32767).\n // This allows the browser viewport and client viewport to have different sizes.\n // Hack: an out-of-range position becomes UNSIGNED_OUT_OF_RANGE because we\n // can't yet accurately detect mouse enter/leave precisely inside a video\n // with an aspect ratio that causes mattes.\n\n this.normalizeAndQuantizeUnsigned = (x, y) => {\n const normalizedX = x / videoElement.clientWidth;\n const normalizedY = y / videoElement.clientHeight;\n\n if (\n normalizedX < 0.0 ||\n normalizedX > 1.0 ||\n normalizedY < 0.0 ||\n normalizedY > 1.0\n ) {\n return {\n inRange: false,\n x: UNSIGNED_OUT_OF_RANGE,\n y: UNSIGNED_OUT_OF_RANGE,\n };\n }\n return {\n inRange: true,\n x: normalizedX * UNSIGNED_RANGE,\n y: normalizedY * UNSIGNED_RANGE,\n };\n };\n\n this.normalizeAndQuantizeSigned = (x, y) => {\n const normalizedX = x / (0.5 * videoElement.clientWidth);\n const normalizedY = y / (0.5 * videoElement.clientHeight);\n return {\n x: normalizedX * SIGNED_RANGE,\n y: normalizedY * SIGNED_RANGE,\n };\n };\n }\n\n private sendInputData(data: ArrayBuffer) {\n this.commandsSender.sendInputData(data);\n }\n\n private registerInputs(video: HTMLVideoElement) {\n fromEvent(window, 'blur')\n .pipe(\n filter(() => !!video),\n takeUntil(this.deactivatedVideoTrigger$),\n )\n .subscribe(() => this.releaseMouseButtons(255, 0, 0));\n\n this.registerMouseEnterAndLeaveEvents(video);\n this.registerHoveringMouseEvents(video);\n this.registerKeyboardEvents(this.availableKeys);\n this.registerTouchEvents(video);\n }\n\n private getTouchPositionWithOffset({ clientX, clientY }: Touch) {\n const { offsetByX, offsetByY, scaleX, scaleY } = this.offsetParams;\n\n return {\n x: (clientX - offsetByX - this.videoBoundingRect.left) * scaleX,\n y: (clientY - offsetByY - this.videoBoundingRect.top) * scaleY,\n };\n }\n\n private getMousePositionWithOffset({ offsetX, offsetY }: MouseEvent) {\n const { offsetByX, offsetByY, scaleX, scaleY } = this.offsetParams;\n\n return {\n x: (offsetX - offsetByX) * scaleX,\n y: (offsetY - offsetByY) * scaleY,\n };\n }\n\n private registerTouchEvents(htmlVideoElement: HTMLVideoElement) {\n const rememberTouch = (touch: Touch) => {\n const finger = this.fingers.pop();\n if (finger === undefined) {\n Logger.info('exhausted touch identifiers');\n return;\n }\n this.fingerIds.set(touch.identifier, finger);\n };\n\n const forgetTouch = (touch: Touch) => {\n const finger = this.fingerIds.get(touch.identifier);\n if (finger !== undefined) {\n this.fingers.push(finger);\n // Re-sort descending so the lowest available id is popped next.\n this.fingers.sort((a, b) => b - a);\n }\n this.fingerIds.delete(touch.identifier);\n };\n\n const emitTouchData = (type: MessageTypeValues, touches: TouchList) => {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n let byte = 2;\n const numTouches = 1;\n const touch = touches[t];\n const finger = this.fingerIds.get(touch.identifier);\n // Skip unknown identifiers (e.g., stale touch on a fast retap) — sending\n // 0 here would alias finger '0' and corrupt UE's touch state.\n if (finger === undefined) {\n continue;\n }\n const { x, y } = this.getTouchPositionWithOffset(touch);\n Logger.info(`F${finger}=(${x}, ${y})`);\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.touchView;\n\n data.setUint8(0, type);\n data.setUint8(1, numTouches);\n data.setUint16(byte, coord.x, true);\n byte += 2;\n data.setUint16(byte, coord.y, true);\n byte += 2;\n data.setUint8(byte, finger);\n byte += 1;\n // iOS bug: force is locked to 0.5 since forced touch is unused.\n data.setUint8(byte, this.maxByteValue * 0.5);\n byte += 1;\n data.setUint8(byte, coord.inRange ? 1 : 0);\n this.sendInputData(data.buffer);\n }\n };\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchstart')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.focusWindow();\n const touches: TouchList = e.changedTouches;\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n rememberTouch(touches[t]);\n }\n Logger.info('touch start');\n emitTouchData(MessageType.TouchStart, touches);\n e.preventDefault();\n });\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchend')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const touches: TouchList = e.changedTouches;\n Logger.info('touch end');\n\n emitTouchData(MessageType.TouchEnd, touches);\n\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n forgetTouch(touches[t]);\n }\n\n e.preventDefault();\n });\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchmove')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n emitTouchData(MessageType.TouchMove, e.touches);\n e.preventDefault();\n });\n }\n\n focusWindow() {\n window.focus();\n }\n\n emitMouseMove(x: number, y: number, deltaX: number, deltaY: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const delta = this.normalizeAndQuantizeSigned(deltaX, deltaY);\n const data = this.mouseMoveView;\n\n data.setUint8(0, MessageType.MouseMove);\n data.setUint16(1, coord.x, true);\n data.setUint16(3, coord.y, true);\n data.setInt16(5, delta.x, true);\n data.setInt16(7, delta.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseDown(button: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseButtonView;\n data.setUint8(0, MessageType.MouseDown);\n data.setUint8(1, button);\n data.setUint16(2, coord.x, true);\n data.setUint16(4, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseUp(button: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseButtonView;\n data.setUint8(0, MessageType.MouseUp);\n data.setUint8(1, button);\n data.setUint16(2, coord.x, true);\n data.setUint16(4, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseWheel(delta: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseWheelView;\n data.setUint8(0, MessageType.MouseWheel);\n data.setInt16(1, delta, true);\n data.setUint16(3, coord.x, true);\n data.setUint16(5, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n private releaseMouseButtons(buttons: number, x: number, y: number) {\n if (buttons & MouseButtonsMask.PrimaryButton) {\n this.emitMouseUp(MouseButton.MainButton, x, y);\n }\n if (buttons & MouseButtonsMask.SecondaryButton) {\n this.emitMouseUp(MouseButton.SecondaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.AuxiliaryButton) {\n this.emitMouseUp(MouseButton.AuxiliaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.FourthButton) {\n this.emitMouseUp(MouseButton.FourthButton, x, y);\n }\n if (buttons & MouseButtonsMask.FifthButton) {\n this.emitMouseUp(MouseButton.FifthButton, x, y);\n }\n }\n\n private pressMouseButtons(buttons: number, x: number, y: number) {\n if (buttons & MouseButtonsMask.PrimaryButton) {\n this.emitMouseDown(MouseButton.MainButton, x, y);\n }\n if (buttons & MouseButtonsMask.SecondaryButton) {\n this.emitMouseDown(MouseButton.SecondaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.AuxiliaryButton) {\n this.emitMouseDown(MouseButton.AuxiliaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.FourthButton) {\n this.emitMouseDown(MouseButton.FourthButton, x, y);\n }\n if (buttons & MouseButtonsMask.FifthButton) {\n this.emitMouseDown(MouseButton.FifthButton, x, y);\n }\n }\n\n private registerHoveringMouseEvents(htmlVideoElement: HTMLVideoElement) {\n fromEvent<MouseEvent>(htmlVideoElement, 'mousemove')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.emitMouseMove(x, y, e.movementX, e.movementY);\n e.preventDefault();\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mousedown')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.focusWindow();\n this.emitMouseDown(e.button, x, y);\n e.preventDefault();\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseup')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.emitMouseUp(e.button, x, y);\n e.preventDefault();\n });\n\n fromEvent<WheelEvent>(htmlVideoElement, 'wheel')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.emitMouseWheel(e.deltaY * WHEEL_DELTA_SCALE, e.offsetX, e.offsetY);\n e.preventDefault();\n });\n }\n\n private registerMouseEnterAndLeaveEvents(htmlVideoElement: HTMLVideoElement) {\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseenter')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.focusWindow();\n const data = this.singleByteView;\n data.setUint8(0, MessageType.MouseEnter);\n this.sendInputData(data.buffer);\n this.pressMouseButtons(e.buttons, e.offsetX, e.offsetY);\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseleave')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const data = this.singleByteView;\n data.setUint8(0, MessageType.MouseLeave);\n this.sendInputData(data.buffer);\n this.releaseMouseButtons(e.buttons, e.offsetX, e.offsetY);\n });\n }\n\n // Browser keys do not have a charCode so we only need to test keyCode.\n private isKeyCodeBrowserKey(keyCode: number): boolean {\n return (\n (keyCode >= FUNCTION_KEY_MIN && keyCode <= FUNCTION_KEY_MAX) ||\n keyCode === TAB_KEY_CODE\n );\n }\n\n private getKeyCode(e: KeyboardEvent): number {\n if (e.keyCode === SpecialKeyCodes.Shift && e.code === 'ShiftRight')\n return SpecialKeyCodes.RightShift;\n else if (e.keyCode === SpecialKeyCodes.Control && e.code === 'ControlRight')\n return SpecialKeyCodes.RightControl;\n else if (e.keyCode === SpecialKeyCodes.Alt && e.code === 'AltRight')\n return SpecialKeyCodes.RightAlt;\n else return e.keyCode;\n }\n\n private registerKeyboardEvents(availableKeys: IKeyCode[]) {\n const availableKeyNames = availableKeys.map(\n (value) => InvertedKeyMap[value],\n );\n\n const keyBlock = (event: KeyboardEvent) => {\n const code: IKeyName = event.code as IKeyName;\n const isInputFieldFocused =\n (event.target as HTMLElement)?.localName === 'input';\n const keyMatch = availableKeyNames.includes(code);\n\n if (this.isDevMode && !keyMatch) {\n Logger.warn(\n 'Code=>',\n code,\n 'Keyboard event is not filtered in DEV Mode. App may behave inappropriately!',\n );\n return isInputFieldFocused;\n }\n\n return isInputFieldFocused || !keyMatch;\n };\n this.startListenKeys(keyBlock);\n }\n\n private startListenKeys(_filter?: (event: KeyboardEvent) => boolean) {\n const filter = _filter ?? (() => false);\n\n fromEvent<KeyboardEvent>(document, 'keydown')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n\n const isCtrlOrCommand = e.ctrlKey || e.metaKey;\n\n const isPlusOrMinus =\n e.keyCode === KeyboardNumericCode.Equal ||\n e.keyCode === KeyboardNumericCode.Minus;\n if (isCtrlOrCommand && isPlusOrMinus) {\n return;\n }\n\n const keyDown = this.keyDownBytes;\n keyDown[0] = MessageType.KeyDown;\n keyDown[1] = this.getKeyCode(e);\n keyDown[2] = Number(e.repeat);\n this.sendInputData(keyDown.buffer);\n // Backspace isn't a keypress in JS, but UE4 text-entry fields need it\n // to delete characters.\n if (e.keyCode === SpecialKeyCodes.BackSpace) {\n const data = this.keyPressView;\n data.setUint8(0, MessageType.KeyPress);\n data.setUint16(1, SpecialKeyCodes.BackSpace, true);\n this.sendInputData(data.buffer);\n }\n if (\n this.options.suppressBrowserKeys &&\n this.isKeyCodeBrowserKey(e.keyCode)\n ) {\n e.preventDefault();\n }\n });\n\n fromEvent<KeyboardEvent>(document, 'keyup')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n const keyUp = this.keyUpBytes;\n keyUp[0] = MessageType.KeyUp;\n keyUp[1] = this.getKeyCode(e);\n this.sendInputData(keyUp.buffer);\n if (\n this.options.suppressBrowserKeys &&\n this.isKeyCodeBrowserKey(e.keyCode)\n ) {\n e.preventDefault();\n }\n });\n\n fromEvent<KeyboardEvent>(document, 'keypress')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n const data = this.keyPressView;\n data.setUint8(0, MessageType.KeyPress);\n data.setUint16(1, e.charCode, true);\n this.sendInputData(data.buffer);\n });\n }\n}\n\ninterface OffsetParams {\n scaleX: number;\n scaleY: number;\n scaledHeight: number;\n scaledWidth: number;\n offsetByY: number;\n offsetByX: number;\n}\n","import { ofType } from '@ngrx/effects';\nimport { inject, Injectable } from '@angular/core';\nimport { asyncScheduler, type Observable, takeUntil, throttleTime } from 'rxjs';\nimport {\n filter,\n map,\n startWith,\n switchMap,\n take,\n withLatestFrom,\n} from 'rxjs/operators';\nimport { initSignalling, trackMixpanelEvent, unrealFeature } from '../store';\nimport type { AggregatedStat, AwsInstance } from '../interfaces';\nimport { VideoService } from './video.service';\nimport { UNREAL_CONFIG } from '../constants';\nimport { SubService } from './sub.service';\n\ninterface MapEventDataParams {\n data: AggregatedStat;\n signalingServer: AwsInstance;\n startTimeUtc: string;\n signalingReadyTime: number | undefined;\n viewPortReadyTime: number | undefined;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class StreamStatusTelemetryService extends SubService {\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n // Start a telemetry session on every `initSignalling` dispatch.\n // switchMap cancels the previous session's inner pipeline on re-init.\n // throttleTime leading+trailing emits the first event immediately and\n // at most one event every 5s afterward.\n this.actions$\n .pipe(\n ofType(initSignalling),\n switchMap(() => {\n // Captured once per session — marks the UTC moment signaling started.\n const startedAt = Date.now();\n const startTimeUtc = new Date(startedAt).toISOString();\n const signalingReadyTime$ = this.readyTimeSince(\n this.store.select(unrealFeature.selectCirrusConnected),\n startedAt,\n );\n const viewPortReadyTime$ = this.readyTimeSince(\n this.store.select(unrealFeature.selectViewportReady),\n startedAt,\n );\n return this.videoService.videoStats$.pipe(\n throttleTime(5000, asyncScheduler, {\n leading: true,\n trailing: true,\n }),\n withLatestFrom(\n this.store.select(unrealFeature.selectAwsInstance),\n signalingReadyTime$,\n viewPortReadyTime$,\n ),\n map(\n ([\n data,\n signalingServer,\n signalingReadyTime,\n viewPortReadyTime,\n ]) =>\n this.mapEventData({\n data,\n signalingServer,\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n }),\n ),\n );\n }),\n takeUntil(this.destroy$),\n )\n .subscribe((data) =>\n this.store.dispatch(\n trackMixpanelEvent({ event: 'streamStatus', data }),\n ),\n );\n }\n\n /**\n * Emits `undefined` until `readyState$` first emits a truthy value,\n * then emits the ms elapsed since `startedAt` and completes.\n * Used with `withLatestFrom` so events carry a stable duration for the whole session.\n */\n private readyTimeSince(\n readyState$: Observable<boolean>,\n startedAt: number,\n ): Observable<number | undefined> {\n return readyState$.pipe(\n filter(Boolean),\n take(1),\n map(() => Date.now() - startedAt),\n startWith<number | undefined>(undefined),\n );\n }\n\n private mapEventData(params: MapEventDataParams) {\n const {\n data,\n signalingServer,\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n } = params;\n\n const {\n bitrate,\n VideoEncoderQP,\n framesPerSecond,\n frameWidth,\n frameHeight,\n jitter,\n packetsLost,\n currentRoundTripTime,\n runTime,\n } = data.aggregatedStats;\n\n return {\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n runTime,\n frameWidth,\n frameHeight,\n client: signalingServer.wsUrl,\n pixelRatio: window.devicePixelRatio,\n framesPerSecond,\n jitter,\n packetsLost,\n instanceName: signalingServer.instanceName,\n bitrate,\n rtt: currentRoundTripTime,\n VideoEncoderQP,\n };\n }\n}\n","import { Store } from '@ngrx/store';\nimport { Actions, ofType } from '@ngrx/effects';\nimport { DestroyRef, inject, Injectable } from '@angular/core';\nimport {\n bufferTime,\n filter,\n fromEvent,\n map,\n type Observable,\n scan,\n startWith,\n Subject,\n Subscription,\n switchMap,\n take,\n takeUntil,\n withLatestFrom,\n} from 'rxjs';\nimport {\n answerSent,\n commandCompleted,\n commandStarted,\n destroyUnrealScene,\n instanceReady,\n pollingEnded,\n pollingStarted,\n regionPingFetchEnd,\n regionPingFetchStart,\n regionResolved,\n setAwsInstance,\n setCirrusDisconnected,\n setEstablishingConnection,\n setMaxFps,\n setOrchestrationParameters,\n signalingRetryAttempted,\n streamAdopted,\n trackTelemetryData,\n unrealFeature,\n} from '../store';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { AggregatedStat } from '../interfaces';\nimport { DisconnectReason } from '../interfaces';\nimport { VideoService } from './video.service';\nimport { SignallingService } from './signalling.service';\nimport { REGION_PING_CACHE_KEY, UNREAL_CONFIG } from '../constants';\n\n/**\n * Pro-grade telemetry for the WebRTC stream lifecycle.\n *\n * Wire-level event taxonomy (intentionally small — all phase-specific\n * details ride inside `stream.phase_ended`'s payload):\n * - `stream.session_started` — once per session, when a real connection\n * attempt begins (`setEstablishingConnection(true)`)\n * - `stream.phase_ended` — once per closer in {@link phaseCatalog};\n * carries phaseNo / id / color /\n * milestones / params / overlays\n * - `stream.sample` — every 5s, window-aggregated (p. 50/p. 95/min/max)\n * - `stream.quality_degraded` — on QP entering `red` (>35)\n * - `stream.quality_recovered` — on QP leaving `red`\n * - `stream.fps_low` — when the window FPS p50 < 70% of the target\n * - `stream.session_ended` — once per session, on disconnect/pagehide/restart\n *\n * Every event carries `sessionId` + `userId`. Samples carry a monotonic\n * `seq` for server-side ordering & dedup. Durations use `performance.now()`\n * — immune to wall-clock jumps.\n *\n * NOTE: For `stream.session_ended` on the tab close to survive teardown,\n * the Mixpanel client must be configured with `api_transport: 'sendBeacon'`.\n */\ntype EndReason = 'disconnected' | 'pagehide' | 'restart' | 'destroy';\n\n/**\n * Statistical summary of a time-series metric (bitrate, fps, qp, jitter, rtt)\n * over a single aggregation window (default: 5 seconds, ~20 samples at 250ms).\n *\n * Each field answers a different question about the distribution within the\n * window. Together they describe the *shape* of the data, not just one number.\n *\n * ## Why aggregates instead of a single value\n *\n * The raw stream emits ~20 samples per 5s window. Reporting only the last\n * value (e.g. `throttleTime(5000)`) is fragile: one unlucky tick at the\n * window boundary can flip the signal. A single `mean` is also misleading\n * because one big outlier can drag it far from the typical value.\n * Percentiles and extremes give a stable, outlier-resistant view.\n *\n * ## Example\n *\n * Suppose the bitrate (bits/s) sampled over 5s is:\n * ```\n * [8M, 9M, 10M, 10M, 11M, 11M, 11M, 12M, 12M, 12M,\n * 12M, 12M, 13M, 13M, 13M, 13M, 13M, 14M, 14M, 20M]\n * ```\n * The resulting {@link WindowAggregate} is:\n * ```\n * { p50: 12_000_000, p95: 14_000_000, min: 8_000_000, max: 20_000_000 }\n * ```\n *\n * ## How to read each field\n *\n * | Field | Question it answers |\n * |-------|--------------------------------------------------------|\n * | p. 50 | \"What does the typical tick look like?\" |\n * | p. 95 | \"How bad is the bad tail that users notice?\" |\n * | min | \"Was there any catastrophic dip in this window?\" |\n * | max | \"Was there any peak / did we reach the target at all?\" |\n *\n * ## Why p. 50 instead of mean\n *\n * Mean is sensitive to outliers. Example FPS series `[60,60,60,60,60,60,60,60,60,5]`:\n * - mean ≈ 54.5 (looks fine)\n * - p. 50= 60 (truth: 9 of 10 ticks are perfect)\n * - min = 5 (but one tick collapsed)\n *\n * Mean smears the bad tick across the whole window. p50 reports the typical\n * case, `min` surfaces the worst, so together they describe reality.\n *\n * ## Why p95 instead of max\n *\n * `max` is a single tick — can be random noise (a 250ms glitch). `p95` is\n * \"the bad tail you consistently see\" and is what users actually perceive\n * as lag / freezes. For SLOs and alerting, use p95/p. 99 — not max.\n *\n * ## Dashboard / alerting hints\n *\n * - `bitrate.p50` → typical throughput over time\n * - `fps.p95 < 40` → 5% of the time the frame rate is poor (user-visible)\n * - `qp.max > 35` in a sliding window → quality spikes to investigate\n * - `fps.min` → the worst single tick, useful for freeze detection\n */\n/** One individual resource in the \"slowest N\" list of bootstrapInfo. */\ninterface SlowResource {\n /** Path only (origin + query stripped) — the file / endpoint. */\n name: string;\n /** Resource Timing initiatorType: 'script' | 'css' | 'img' | 'fetch' | … */\n type: string;\n /** responseEnd − startTime, ms. */\n durationMs: number;\n /** Bytes over the wire (0 = served from cache). */\n transferKb: number;\n /** Fetched after window.load (lazy route chunk) vs during page load. */\n lazy: boolean;\n}\n\n/** Trim a resource URL to its path: drop origin and query string so the\n * emitted name is short, stable, and not a PII-bearing query. */\nfunction shortResourceName(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return (url || '').split('?')[0];\n }\n}\n\ninterface WindowAggregate {\n /**\n * 50th percentile (median): value below which 50% of samples fall.\n * The \"typical\" value in the window — robust to outliers.\n * Use this as the primary signal on dashboards.\n */\n p50: number;\n\n /**\n * 95th percentile: value below which 95% of samples fall.\n * Describes the \"bad tail\" — the worst 5% of ticks. This is what\n * users perceive as lag / freezes. Preferred metric for SLOs and alerts.\n */\n p95: number;\n\n /**\n * Minimum sample in the window — the single worst tick observed.\n * Surfaces catastrophic dips (e.g., a single-frame freeze) that p50/p95\n * would smooth out. Noisy on its own; useful alongside p95.\n */\n min: number;\n\n /**\n * Maximum sample in the window — the single best tick observed.\n * Shows whether the system ever reached the target (e.g. \"did FPS ever\n * touch 60?\"). Like `min`, one-tick noisy; use it for ceiling / headroom checks.\n */\n max: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// Milestone catalog\n//\n// is The single declarative source for everything this service tracks\n// beyond the four lifecycle boundaries (session_started / signaling /\n// datachannel / viewport). Each entry binds a stable *id* + *phase*\n// to an Observable that fires when the milestone happens — pass an\n// NgRx action stream, a `SignallingService` Subject, or any custom\n// Observable you construct.\n//\n// Adding a new milestone = one entry in this array PLUS one row in the\n// viewer's vocabulary map (id → human label) — the wire carries only\n// stable kebab-case ids; all display text lives viewer-side.\n// ──────────────────────────────────────────────────────────────────\n\n/**\n * Every stable id this service can emit on the wire — phases,\n * milestones, overlays. The viewer's vocabulary maps each member to a\n * human label, so every id added here needs a paired vocabulary row\n * in the viewer (`telemetry-vocabulary.ts`).\n */\nexport type EventId =\n // Phases\n | 'region-resolving'\n | 'signaling-connection'\n | 'webrtc-negotiation'\n | 'unreal-communication'\n // Milestones\n | 'region-ping-fetch-start'\n | 'region-ping-fetch-end'\n | 'region-resolved'\n | 'polling-started'\n | 'polling-ended'\n | 'aws-instance-resolved'\n | 'signaling-ws-connected'\n | 'instance-reserved'\n | 'instance-ready'\n | 'config-received'\n | 'ssinfo-received'\n | 'offer-received'\n | 'answer-sent'\n | 'answer-received'\n | 'first-ice-candidate'\n | 'last-ice-candidate'\n | 'datachannel-connected'\n | 'first-command-started'\n | 'loopback-sent'\n | 'loopback-received'\n | 'viewport-ready'\n // Overlays\n | 'polling-to-instance'\n | 'signaling-handshake'\n | 'stabilization-warmup';\n\n/** Wire-format milestone — minimal by design. `id` is a stable\n * kebab-case identifier; the viewer maps it to a human label via its\n * vocabulary. */\nexport interface EmittedMilestone {\n readonly id: EventId;\n readonly time: number;\n}\n\n/**\n * Selected WebRTC ICE candidate pair, pulled off {@link AggregatedStat}.\n * The closer for the viewport phase flattens this to two `PhaseParam`\n * rows (`localCandidate`, `remoteCandidate`) before emission.\n */\nexport interface SelectedIceCandidatePair {\n local: { type: string; url: string };\n remote: { type: string; url: string };\n}\n\n/**\n * Wire-format display key/value pair — rendered verbatim in the viewer's\n * phase tooltip. Nested or structured values should be pre-formatted by\n * the catalog closer's `map(...)` (string/number/boolean only).\n */\nexport interface PhaseParam {\n readonly key: string;\n readonly value: string;\n}\n\n/** Resolved overlay region sent on the wire. `id` is a stable\n * kebab-case identifier mapped to a title by the viewer's vocabulary. */\nexport interface PhaseOverlay {\n readonly fromMs: number;\n readonly toMs: number;\n readonly id: EventId;\n}\n\n/**\n * A single milestone entry — the object identity serves as its key in\n * the in-session `times` map, so no separate `name` field is needed.\n */\ninterface CatalogEntry {\n /** Stable kebab-case id emitted on the wire alongside the firing\n * time. Display text lives in the viewer's vocabulary map. */\n readonly id: EventId;\n /**\n * Source of the milestone. Subscribed once per session; unsubscribed on\n * teardown. For closers, the emission value (when it's a plain object)\n * is spread into the lifecycle event's payload — use inline `map(...)`\n * to shape the extras.\n */\n readonly event: Observable<unknown>;\n /**\n * `'first'` (default) — record only the first emission per session.\n * `'last'` — keep overwriting, so the recorded time is the latest\n * emission. Ignored for closers (they take(1) anyway).\n */\n readonly mode?: 'first' | 'last';\n}\n\n/**\n * Declarative overlay recipe — resolved to `{fromMs, toMs, id}` at\n * emission time by looking up entries by object identity. Either\n * endpoint can be omitted to fall back to the phase bounds.\n */\ninterface OverlayRecipe {\n readonly from?: CatalogEntry;\n readonly to?: CatalogEntry;\n /** Stable kebab-case id; the viewer's vocabulary maps it to a title. */\n readonly id: EventId;\n}\n\n/**\n * Unified phase catalog entry. The *last* item in `milestones` is the\n * phase closer: when its observable fires, the service emits a single\n * generic `stream.phase_ended` wire event carrying `phaseNo`, `id`,\n * `color`, `duration`, `milestones[]`, `params[]`, `overlays[]`.\n *\n * Display text is NOT on the wire — the viewer's vocabulary map turns\n * every id (phase / milestone / overlay) back into a human label.\n * Adding a new phase here therefore requires one paired vocabulary row\n * in the viewer.\n */\ninterface CatalogPhase {\n /** Stable kebab-case phase id. The viewer maps it to the bar label\n * and derives boundary labels from neighboring phases. */\n readonly id: EventId;\n /** Viewer bar color (hex). */\n readonly color: string;\n readonly milestones: readonly CatalogEntry[];\n /** Optional diagonal-stripe recipes; resolved to ms at a closer time. */\n readonly overlays?: readonly OverlayRecipe[];\n}\n\ninterface SessionState {\n id: string;\n startedAt: number; // Date.now() — wall-clock for startTimeUtc\n startedAtPerf: number; // performance.now() at session start — kept for info\n /**\n * Anchor for all reported milestone timestamps.\n * - First session on this page: `0` (= `performance` navigation start).\n * Bootstrap measurements (`session_started.duration`, resource timings)\n * naturally fall out of `performance.now()` being \"ms since nav start\".\n * - Subsequent (Resume) sessions: `startedAtPerf`. The document is\n * already loaded, so \"bootstrap\" has no meaning — we suppress it by\n * anchoring at the session itself.\n * Milestone `*Ms` values emitted inside lifecycle events are relative\n * to this anchor — the viewer's scale starts at 0 at the same anchor.\n */\n anchorPerf: number;\n /**\n * Monotonic time (performance.now()) of the last fired lifecycle event.\n * Used to compute each next event's `duration` as the width of its own\n * phase (`now - lastMilestonePerf`) rather than an anchor-relative value.\n */\n lastMilestonePerf: number;\n seq: number;\n sub: Subscription;\n qpBad: boolean;\n fpsLow: boolean;\n maxFpsTarget: number; // 0 = unlimited → compare against UNLIMITED_REFERENCE_FPS\n /** Total number of ICE candidates the server sent during negotiation.\n * Shipped as a phase param on `datachannel_connected` — useful for\n * diagnosing restrictive networks (tiny candidate count = no relay). */\n iceCandidateCount: number;\n /** Which handshake flow was used (server-offer is our default today,\n * but the detector stays in place in case the flow ever switches).\n * `null` until one of the two answer-events fires. */\n handshakeFlow: 'server-offer' | 'client-offer' | null;\n /** Running count of commands sent to Unreal during the session.\n * Snapshot ted into the `viewport_ready` closer payload — helps\n * spot verbose scene-start flows where Unreal took a while to\n * settle because the client fired a lot of initial commands. */\n commandCount: number;\n /**\n * Recorded firing times for each catalog entry this session. Keyed by\n * the CatalogEntry object itself (stable identity across the service\n * lifetime) — no string names needed. `milestonesOfBucket` / overlay\n * resolution walk the catalog and read from this map directly.\n */\n times: Map<CatalogEntry, number>;\n}\n\nconst QP_RED_THRESHOLD = 35;\nconst FPS_LOW_RATIO = 0.7; // p50 fps below 70% of target\nconst UNLIMITED_REFERENCE_FPS = 60;\nconst SAMPLE_WINDOW_MS = 5000;\n/**\n * Catalog phase ids the prefetch establishes invisibly. For an adopted\n * connection their live closers are suppressed and the phases are emitted by\n * {@link StreamStatusTelemetryService2.emitAdoptedConnection} instead, timed\n * from the prefetch's own marks and anchored at the moment Angular reached the\n * connect call (session start) — so the waterfall shows the time the prefetch\n * actually SAVED, not the prefetch's page-load-parallel raw timeline.\n */\nconst PREFETCHED_PHASE_IDS: ReadonlySet<string> = new Set([\n 'region-resolving',\n 'signaling-connection',\n 'webrtc-negotiation',\n]);\n// Persistent per-browser identifier — survives page reloads. Used to group\n// multiple sessions of the same anonymous user for funnel / retention analysis.\nconst USER_ID_STORAGE_KEY = 'source3d.streamTelemetry.userId';\n\n@Injectable({ providedIn: 'root' })\nexport class StreamStatusTelemetryService2 {\n private readonly store = inject(Store);\n private readonly actions$ = inject(Actions);\n private readonly videoService = inject(VideoService);\n private readonly signallingService = inject(SignallingService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly destroy$ = new Subject<void>();\n\n /**\n * Per-browser anonymous user id. Read from `localStorage` on first access;\n * if missing, a new UUID is generated and persisted. Included as\n * `data.userId` on every emitted event — the server uses it to bucket\n * per-session files under `data/<userId>/<sessionId>.jsonl`.\n */\n private readonly userId = this.getOrCreateUserId();\n\n /**\n * Synchronous reads of the unreal store's disconnect state. Read at\n * `endSession` time for the granular `disconnectReason` /\n * `disconnectMessage` wire fields. Reducers update both fields\n * synchronously before action subscribers fire, so by the time the\n * action-stream end-trigger subscriptions below run, state already\n * reflects the originating cause.\n */\n private readonly disconnectReason$ = this.store.selectSignal(\n unrealFeature.selectDisconnectReason,\n );\n private readonly errorMessage$ = this.store.selectSignal(\n unrealFeature.selectErrorMessage,\n );\n private readonly viewPortReady$ = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n /**\n * Synchronous adoption flag. The `streamAdopted` reducer sets it BEFORE any\n * action subscriber runs, so the connection-phase closers (which fire inside\n * the same dispatch, e.g. `ssinfo-received` off the `ssData` state change)\n * can read it and defer to the prefetch-timed attribution emitted by\n * {@link emitAdoptedConnection} instead of recording the live wall-clock.\n */\n private readonly adopted$ = this.store.selectSignal(\n unrealFeature.selectAdopted,\n );\n /** Streamer identity for the adopted signaling phase params. */\n private readonly ssData$ = this.store.selectSignal(\n unrealFeature.selectSsData,\n );\n private readonly awsInstance$ = this.store.selectSignal(\n unrealFeature.selectAwsInstance,\n );\n\n private session: SessionState | null = null;\n\n /**\n * Whether a session has already started during the current page lifetime.\n * Used to distinguish a fresh page load (bootstrap measurement is\n * meaningful) from a Résumé/restart (the document is already loaded,\n * so \"bootstrap\" is a no-op). Only the first session gets the bootstrap\n * phase anchored at navigation start (perf.now() === 0).\n */\n private hasStartedBefore = false;\n\n /**\n * Rolling snapshot of the currently selected WebRTC ICE candidate pair\n * (local/remote type + url). Scanned over `videoStats$` so the stream\n * *keeps* the first non-null pair even if later stats emit null — WebRTC\n * doesn't unselect a pair mid-session, but the source is nullable. The\n * `startWith(null)` seed makes `withLatestFrom` on this stream safe even\n * before the first video stat arrives (common at data-channel-open).\n */\n private readonly selectedPair$: Observable<SelectedIceCandidatePair | null> =\n this.videoService.videoStats$.pipe(\n map((s) => s.aggregatedStats.selectedPair ?? null),\n scan<SelectedIceCandidatePair | null, SelectedIceCandidatePair | null>(\n (acc, curr) => curr ?? acc,\n null,\n ),\n startWith<SelectedIceCandidatePair | null>(null),\n );\n\n /**\n * Correlation-matched Observable: emits once when the first `loopBack`\n * command's corresponding `command completed` action fires. Built from\n * the two related actions — the command-started captures the correlation\n * id; the command-completed with that id emits.\n */\n private readonly loopbackReceived$: Observable<unknown> = this.actions$.pipe(\n ofType(commandStarted),\n filter(({ command }) => command === 'loopBack'),\n take(1),\n switchMap(({ id }) =>\n this.actions$.pipe(\n ofType(commandCompleted),\n filter((b) => b.id === id),\n take(1),\n ),\n ),\n );\n\n // Overlay-referenced milestones — hoisted as fields so both\n // `milestones: [...]` and `overlays: [...]` share the same object\n // identity (the in-session Map keys milestones by that identity).\n private readonly pollingStartedEntry: CatalogEntry = {\n id: 'polling-started',\n event: this.actions$.pipe(ofType(pollingStarted)),\n };\n private readonly awsInstanceResolvedEntry: CatalogEntry = {\n id: 'aws-instance-resolved',\n event: this.actions$.pipe(ofType(setAwsInstance)),\n };\n private readonly loopbackReceivedEntry: CatalogEntry = {\n id: 'loopback-received',\n event: this.loopbackReceived$,\n };\n private readonly signalingServerConnectedEntry: CatalogEntry = {\n id: 'signaling-ws-connected',\n event: this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(filter(Boolean), take(1)),\n };\n private readonly configReceivedEntry: CatalogEntry = {\n id: 'config-received',\n event: this.signallingService.onConfig$.pipe(filter(Boolean), take(1)),\n };\n\n /**\n * Unified phase catalog — the single source of truth for everything\n * this service tracks after `session_started`. Each entry is a phase;\n * its `milestones` array is ordered chronologically, and the *last*\n * entry is the phase closer. When that closer's observable fires, the\n * service emits one generic `stream.phase_ended` wire event with every\n * display field the viewer needs.\n *\n * `phaseNo` is the array index; `startPhase` chains from the previous\n * phase's `endPhase` — neither needs to be specified here.\n */\n private readonly phaseCatalog: readonly CatalogPhase[] = [\n {\n id: 'region-resolving',\n color: '#61afef',\n milestones: [\n {\n id: 'region-ping-fetch-start',\n event: this.actions$.pipe(ofType(regionPingFetchStart)),\n },\n {\n id: 'region-ping-fetch-end',\n event: this.actions$.pipe(ofType(regionPingFetchEnd)),\n },\n // CLOSER — the `regionResolved` action carries the raw ping\n // samples (one per probe) from `RegionsPingService`; the\n // catalog flattens them to a comma-separated string since\n // `toPhaseParams` only accepts primitives. Adopted connections never\n // run `getRegion`, but `UnrealEffects.regionTelemetryOnAdopt$` replays\n // the region waterfall (start → end → resolved) from the cached winner,\n // so this phase still appears with its ping samples.\n {\n id: 'region-resolved',\n event: this.actions$.pipe(\n ofType(regionResolved),\n take(1),\n map(({ region, pingsMs }) => ({\n region,\n pingsMs: pingsMs.length ? `${pingsMs.join(', ')} ms` : null,\n })),\n ),\n },\n ],\n },\n {\n id: 'signaling-connection',\n color: '#c678dd',\n overlays: [\n {\n from: this.pollingStartedEntry,\n to: this.awsInstanceResolvedEntry,\n id: 'polling-to-instance',\n },\n {\n from: this.signalingServerConnectedEntry,\n to: this.configReceivedEntry,\n id: 'signaling-handshake',\n },\n ],\n milestones: [\n this.pollingStartedEntry,\n {\n id: 'polling-ended',\n event: this.actions$.pipe(ofType(pollingEnded)),\n },\n this.awsInstanceResolvedEntry,\n this.signalingServerConnectedEntry,\n {\n id: 'instance-reserved',\n event: this.actions$.pipe(ofType(setOrchestrationParameters)),\n },\n {\n id: 'instance-ready',\n event: this.actions$.pipe(ofType(instanceReady)),\n },\n this.configReceivedEntry,\n {\n id: 'ssinfo-received',\n event: this.store.select(unrealFeature.selectSsData).pipe(\n filter(Boolean),\n take(1),\n withLatestFrom(this.store.select(unrealFeature.selectAwsInstance)),\n map(([ssData, aws]) => ({\n client: aws.wsUrl,\n instanceName: aws.instanceName,\n ...ssData,\n })),\n ),\n },\n ],\n },\n {\n id: 'webrtc-negotiation',\n color: '#e5c07b',\n milestones: [\n {\n id: 'offer-received',\n event: this.signallingService.onOffer$.pipe(filter(Boolean)),\n },\n {\n id: 'answer-sent',\n event: this.actions$.pipe(ofType(answerSent)),\n },\n {\n id: 'answer-received',\n event: this.signallingService.onWebRtcAnswer$.pipe(filter(Boolean)),\n },\n {\n id: 'first-ice-candidate',\n event: this.signallingService.onWebRtcIce$.pipe(filter(Boolean)),\n },\n {\n id: 'last-ice-candidate',\n event: this.signallingService.onWebRtcIce$.pipe(filter(Boolean)),\n mode: 'last',\n },\n // CLOSER — snaps negotiation diagnostics and the Cirrus\n // streamer identity (`ssData`, reliably populated by DC-open\n // time) into phase-3 params:\n // - `iceCandidateCount` (total ICE candidates from server — too\n // few hints at a restrictive network)\n // - `handshakeFlow` (server-offer vs. client-offer; we only use\n // server-offer today, but the detector stays in place)\n // - `instanceType` / `branchInfo` / version / path / app /\n // `connectionId` (streamer identity, from `ssInfo` message)\n {\n id: 'datachannel-connected',\n event: this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(\n filter(Boolean),\n take(1),\n map(() => ({\n iceCandidateCount: this.session?.iceCandidateCount ?? 0,\n handshakeFlow: this.session?.handshakeFlow ?? null,\n })),\n ),\n },\n ],\n },\n {\n id: 'unreal-communication',\n color: '#98c379',\n overlays: [\n {\n from: this.loopbackReceivedEntry,\n id: 'stabilization-warmup',\n },\n ],\n milestones: [\n {\n id: 'first-command-started',\n event: this.actions$.pipe(ofType(commandStarted)),\n },\n {\n id: 'loopback-sent',\n event: this.actions$.pipe(\n ofType(commandStarted),\n filter(({ command }) => command === 'loopBack'),\n ),\n },\n this.loopbackReceivedEntry,\n // CLOSER — flattens the selected ICE candidate pair into two\n // string params (local / remote), and snapshots the running\n // command counter, so phase 5 shows how many commands the client\n // fired at Unreal before the viewport was ready.\n {\n id: 'viewport-ready',\n event: this.store.select(unrealFeature.selectViewportReady).pipe(\n filter(Boolean),\n take(1),\n withLatestFrom(this.selectedPair$),\n map(([, selectedPair]) => ({\n localCandidate: fmtCandidate(selectedPair?.local),\n remoteCandidate: fmtCandidate(selectedPair?.remote),\n commandCount: this.session?.commandCount ?? 0,\n // `lastMilestonePerf` still points at the previous phase end\n // (data channel connected) — `emitPhaseEnded` advances it\n // only after this map() has run.\n msSinceDataChannel: this.session\n ? Math.round(performance.now() - this.session.lastMilestonePerf)\n : null,\n })),\n ),\n },\n ],\n },\n ];\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n // End any active session BEFORE completing destroy$, so the\n // session-scoped subscriptions in `this.session.sub` are released.\n this.endSession('destroy');\n this.destroy$.next();\n this.destroy$.complete();\n });\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.init();\n }\n\n private getOrCreateUserId(): string {\n try {\n const existing = localStorage.getItem(USER_ID_STORAGE_KEY);\n if (existing && existing.length > 0) return existing;\n const fresh = uuidv4();\n localStorage.setItem(USER_ID_STORAGE_KEY, fresh);\n return fresh;\n } catch {\n // localStorage disabled (private-mode restrictions, quota, etc.)\n // Fall back to a per-tab ephemeral id so telemetry keeps working.\n return uuidv4();\n }\n }\n\n private init() {\n // Start a new session when a real connection attempt BEGINS, not on\n // every `initSignalling` dispatch. `initSignalling` is fired multiple\n // times per page load (the unreal-scene effect, `startStream`, the\n // reconnect effect), but the connection layer collapses them into one\n // attempt via `connectToSignaling$` (`exhaustMap` + `!cirrusConnected`\n // filter). `setEstablishingConnection(true)` is dispatched exactly\n // once per real attempt from `SignallingService.startEstablishingConnection()`,\n // downstream of that guard — so binding here yields one session per\n // attempt instead of a burst of `restart` churn sessions. Genuine\n // reconnects (e.g. DataChannelTimeout) re-enter the same path and\n // correctly end the prior session as `restart` + start a new one.\n this.actions$\n .pipe(\n ofType(setEstablishingConnection),\n filter(({ value }) => value === true),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.startSession());\n\n // Action-stream end triggers (NOT a state-observable subscription).\n //\n // We can't observe the cirrus connection flag via `pairwise`\n // because the `destroyUnrealScene` reducer resets the entire\n // unreal state to `initialState` in one step — `cirrusConnected`\n // flips from `true` to `false` AND `disconnectReason` resets to\n // `None` simultaneously. A state-observable subscriber would fire\n // synchronously inside that reducer's emission, before the\n // follow-up effect (`destroyUnrealScene → destroyRemoteConnections({Destroy})`)\n // gets a chance to write `Destroy` back into state — so the\n // subscriber would see `None` and end as `'disconnected'`.\n //\n // Subscribing to the actions instead lets us pick the right\n // reason per dispatched action, and `endSession` is idempotent\n // (`if (!this.session) return`) so any cascading second trigger\n // is a no-op. Coverage:\n // - `destroyUnrealScene` → `'destroy'` (route change, removed from DOM)\n // - `setCirrusDisconnected` → `'disconnected'` (WS close, AFK,\n // manual drop, WebRTCError, etc. — granular cause + message\n // read from current state in `endSession`)\n this.actions$\n .pipe(ofType(destroyUnrealScene), takeUntil(this.destroy$))\n .subscribe(() => this.endSession('destroy'));\n\n this.actions$\n .pipe(ofType(setCirrusDisconnected), takeUntil(this.destroy$))\n .subscribe(() => this.endSession('disconnected'));\n\n // Close the session when the tab is hidden / being evicted from cache.\n // `pagehide` fires in more cases than `beforeunload` (covers iOS Safari, bfcache).\n fromEvent(window, 'pagehide')\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.endSession('pagehide'));\n }\n\n private startSession() {\n // If a previous session is still active, close it first.\n this.endSession('restart');\n\n const id = uuidv4();\n const startedAt = Date.now();\n const startedAtPerf = performance.now();\n const sub = new Subscription();\n\n // Anchor selection:\n // - First session on this page → anchor at navigation start (0).\n // `performance.now()` is already \"ms since navigation start\", so\n // `session_started.duration` becomes the full page-load + idle-time\n // leading up to the first stream start (i.e., the real bootstrap).\n // - Resume/restart sessions → anchor at the session's own start.\n // The document is already loaded — a \"bootstrap\" phase would either\n // balloon (to include all prior idle time) or be misleading, so we\n // suppress it by making the anchor == session_started.\n const isFirstSession = !this.hasStartedBefore;\n this.hasStartedBefore = true;\n const anchorPerf = isFirstSession ? 0 : startedAtPerf;\n\n const times = new Map<CatalogEntry, number>();\n\n this.session = {\n id,\n startedAt,\n startedAtPerf,\n anchorPerf,\n // Initial milestone anchor = anchorPerf. For the first session this is\n // navigation start (0), so `session_started.duration` becomes the full\n // page-load elapsed. For Resume sessions anchor == startedAtPerf, so\n // `session_started.duration` is 0 (no bootstrap phase).\n lastMilestonePerf: anchorPerf,\n seq: 0,\n sub,\n qpBad: false,\n fpsLow: false,\n maxFpsTarget: UNLIMITED_REFERENCE_FPS,\n iceCandidateCount: 0,\n handshakeFlow: null,\n commandCount: 0,\n times,\n };\n\n // Side-channel counters for WebRTC negotiation diagnostics — shown\n // as phase-3 params on the `datachannel_connected` closer. Kept\n // imperative (session-scoped) so no RxJS hot-stream plumbing is\n // needed to survive the subscribe-on-close timing.\n sub.add(\n this.signallingService.onWebRtcIce$\n .pipe(filter(Boolean))\n .subscribe(() => {\n if (this.session) this.session.iceCandidateCount++;\n }),\n );\n sub.add(\n this.actions$.pipe(ofType(answerSent), take(1)).subscribe(() => {\n if (this.session) this.session.handshakeFlow = 'server-offer';\n }),\n );\n sub.add(\n this.signallingService.onWebRtcAnswer$\n .pipe(filter(Boolean), take(1))\n .subscribe(() => {\n if (this.session) this.session.handshakeFlow = 'client-offer';\n }),\n );\n // Unreal-command counter — increments on every `commandStarted`\n // action. Snapshot ted into the `viewport_ready` closer payload as\n // phase-5's `commandCount`.\n sub.add(\n this.actions$.pipe(ofType(commandStarted)).subscribe(() => {\n if (this.session) this.session.commandCount++;\n }),\n );\n\n // Per-attempt observability for the signalling retry loops. Every\n // `retry({ delay })` callback in `SignallingService` (both the\n // outer connect retry and the inner orchestration retry) dispatches\n // `signalingRetryAttempted` with the attempt index, the underlying\n // error message, and which retry it was. Each one becomes a\n // `stream.signaling_retry` wire event the viewer surfaces in the\n // Anomalies table — see `SIGNALLING.md` for context.\n sub.add(\n this.actions$\n .pipe(ofType(signalingRetryAttempted))\n .subscribe(({ attempt, reason, kind }) => {\n if (!this.session) return;\n this.track('stream.signaling_retry', {\n sessionId: this.session.id,\n seq: this.session.seq,\n timestamp: new Date().toISOString(),\n attempt,\n reason,\n kind,\n });\n }),\n );\n\n // Unified catalog loop — one subscription per entry. Non-closers\n // record their emission time into the session map. The *last* entry\n // of each phase is the closer: its emission fires a single generic\n // `stream.phase_ended` event carrying every display field the viewer\n // needs. The viewer never inspects milestone names or phase kinds;\n // adding a new phase to `phaseCatalog` is enough — zero viewer work.\n this.phaseCatalog.forEach((bucket, bucketIdx) => {\n bucket.milestones.forEach((entry, idx) => {\n const isCloser = idx === bucket.milestones.length - 1;\n sub.add(\n entry.event.subscribe((value) => {\n if (!this.session) return;\n if (isCloser) {\n // Adopted connections receive the region / signaling / webrtc\n // phases from `emitAdoptedConnection` (timed from the prefetch's\n // own marks). Skip the live closer for those, so the whole\n // pre-adoption wait isn't dumped onto whichever connection closer\n // happens to fire first at the adoption instant.\n if (this.adopted$() && PREFETCHED_PHASE_IDS.has(bucket.id))\n return;\n this.emitPhaseEnded(bucket, bucketIdx, value);\n return;\n }\n const time = Math.round(\n performance.now() - this.session.anchorPerf,\n );\n if (entry.mode !== 'last' && this.session.times.has(entry)) return;\n this.session.times.set(entry, time);\n }),\n );\n });\n });\n\n // Adopted connection: emit the region / signaling / webrtc phases timed\n // from the prefetch marks, anchored at session start (see method doc). The\n // live closers for these phases are suppressed (PREFETCHED_PHASE_IDS).\n sub.add(\n this.actions$\n .pipe(ofType(streamAdopted))\n .subscribe(({ timings }) => this.emitAdoptedConnection(timings)),\n );\n\n const bootstrapInfo = this.collectBootstrapInfo();\n\n this.emitLifecycle(\n 'stream.session_started',\n {\n sessionId: id,\n startTimeUtc: new Date(startedAt).toISOString(),\n pixelRatio: window.devicePixelRatio,\n // Browser viewport size at session start (`window.innerWidth` /\n // `innerHeight`). Named `browserInnerSize` to distinguish from\n // the physical screen — what gates the rendered video resolution\n // is the container we started from, not the device hardware.\n browserInnerSize: {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n userAgent: navigator.userAgent,\n sampleWindowMs: SAMPLE_WINDOW_MS,\n // Full page URL — `location.href` is the only reliable way to get this.\n // The server-observed `Referer` header is truncated to origin for\n // cross-origin requests by default Referrer-Policy.\n pageUrl: window.location.href,\n // Navigation / page-load context for the \"app bootstrap → session_started\"\n // waterfall phase. Only useful for the first session (`bootstrap` phase\n // is suppressed on Resume), but `bootstrapInfo` describes the document,\n // not the session — harmless and cheap to send either way.\n ...(bootstrapInfo && { bootstrapInfo }),\n },\n // Pin the milestone to the captured `performance.now()` so `duration`\n // equals \"ms since navigation start\" precisely (for first sessions),\n // rather than being inflated by any synchronous setup done in between.\n startedAtPerf,\n );\n\n // Track current maxFps target to evaluate FPS-ratio anomalies.\n sub.add(\n this.actions$\n .pipe(ofType(setMaxFps))\n .subscribe(({ maxFps }) => this.updateMaxFpsTarget(maxFps)),\n );\n\n // Periodic aggregated sample — every 5s window.\n sub.add(\n this.videoService.videoStats$\n .pipe(\n bufferTime(SAMPLE_WINDOW_MS),\n filter((samples) => samples.length > 0),\n )\n .subscribe((samples) => this.handleWindow(samples)),\n );\n }\n\n private endSession(reason: EndReason) {\n if (!this.session) return;\n const { id, sub } = this.session;\n\n // Granular cause + message read from current store state. The\n // unreal reducer updates these synchronously when the originating\n // action (`disconnectStream` / `destroyRemoteConnections`) fires,\n // so by the time `endSession` runs they reflect the cause that\n // triggered this teardown. Both fields omitted when state is\n // clean (e.g. `pagehide` on an idle tab) — backward-compatible\n // with viewers that only know about the high-level `reason`.\n //\n // Message is only included when its `reason` matches the current\n // `disconnectReason` — `errorMessage` isn't reset on\n // `initSignalling`, so without this check a fresh session that\n // ends via a no-message path (e.g. route change → Destroy) would\n // surface the *previous* session's message.\n const granularReason = this.disconnectReason$();\n const errorMessage = this.errorMessage$();\n const granularMessage =\n errorMessage?.reason === granularReason\n ? errorMessage.message\n : undefined;\n const includeGranular =\n granularReason && granularReason !== DisconnectReason.None;\n\n this.emitLifecycle('stream.session_ended', {\n sessionId: id,\n reason,\n ...(includeGranular ? { disconnectReason: granularReason } : {}),\n ...(includeGranular && granularMessage\n ? { disconnectMessage: granularMessage }\n : {}),\n timestamp: new Date().toISOString(),\n });\n\n sub.unsubscribe();\n this.session = null;\n }\n\n /**\n * Emit a lifecycle event with a `duration` field — ms between the\n * previous lifecycle event and now (phase-local, NOT anchor-relative).\n * For `session_started` this equals the full page-load elapsed on the\n * first session, or 0 on Resume. Advances `lastMilestonePerf` so the\n * next event's duration is correctly rooted.\n */\n private emitLifecycle(\n event: string,\n extra: Record<string, unknown>,\n atPerf?: number,\n ) {\n if (!this.session) return;\n // `atPerf` lets callers pin the milestone to a specific `performance.now()`\n // value — useful for `session_started` where the wall-clock and perf-clock\n // anchors were already captured at the top of `startSession()`.\n const now = atPerf ?? performance.now();\n const duration = Math.round(now - this.session.lastMilestonePerf);\n this.track(event, { duration, ...extra });\n this.session.lastMilestonePerf = now;\n }\n\n /**\n * Emit the unified `stream.phase_ended` wire event for a closer —\n * phaseNo (derived from the catalog index), id, color, milestones,\n * params, overlays. No display text on the wire: the viewer's\n * vocabulary maps every id back to a human label, and boundary labels\n * are derived from neighbor phases.\n */\n private emitPhaseEnded(\n bucket: CatalogPhase,\n bucketIdx: number,\n extrasValue: unknown,\n ): void {\n if (!this.session) return;\n const now = performance.now();\n const phaseStartMs = Math.round(\n this.session.lastMilestonePerf - this.session.anchorPerf,\n );\n const phaseEndMs = Math.round(now - this.session.anchorPerf);\n const milestones = this.milestonesOfBucket(bucket);\n const params = toPhaseParams(extrasValue);\n const overlays = resolveOverlays(\n bucket.overlays,\n this.session.times,\n phaseStartMs,\n phaseEndMs,\n );\n this.emitLifecycle('stream.phase_ended', {\n sessionId: this.session.id,\n phaseNo: bucketIdx + 1,\n id: bucket.id,\n color: bucket.color,\n milestones,\n params,\n overlays,\n });\n }\n\n /**\n * Emit the region / signaling / webrtc phases for an ADOPTED connection.\n *\n * The prefetch script established the connection in PARALLEL with page load,\n * so the phases are positioned at their real (anchor-relative) spans — shifted\n * LEFT to overlap the HTML-loading / route-idle rows — rather than sequentially\n * after them. That's the whole point of the prefetch: the handshake already\n * happened while the page was loading. Each phase ships:\n * - `duration` — the real sub-step time the prefetch spent.\n * - `spanStartMs` — anchor-relative start, so the viewer left-shifts the bar.\n * - `adoptionAtMs` — where Angular took over (the next phase, Unreal\n * communication, resumes here on the sequential timeline).\n * - savings params: `prefetchConnectMs` (full handshake), `prefetchSavedMs`\n * (done before Angular was ready), `adoptionWaitMs` (real connect→adopted\n * wait), `adoptionOverheadMs` (prefetch-ready → adopted gap).\n */\n private emitAdoptedConnection(timings: Record<string, number> | null): void {\n const s = this.session;\n if (!s) return;\n\n const t = timings ?? {};\n const now = performance.now();\n // Everything in anchor-relative ms — the same scale the viewer renders on\n // (and the prefetch marks share the page `performance` clock).\n const toMs = (perf: number) => Math.round(perf - s.anchorPerf);\n const startMs = toMs(t['prefetch_start'] ?? s.startedAtPerf);\n const wsOpenMs = Math.max(\n startMs,\n toMs(t['ws_open'] ?? t['prefetch_start'] ?? s.startedAtPerf),\n );\n const readyMs = Math.max(\n wsOpenMs,\n toMs(t['ready'] ?? t['dc_open'] ?? t['ws_open'] ?? s.startedAtPerf),\n );\n const adoptionAtMs = toMs(now);\n const sessionStartMs = toMs(s.startedAtPerf);\n\n const sigDur = wsOpenMs - startMs;\n const webDur = readyMs - wsOpenMs;\n const connectMs = readyMs - startMs;\n\n // Savings, anchored at the moment Angular reached the connect call.\n const savings = {\n prefetched: true,\n prefetchConnectMs: connectMs,\n // How much of the handshake finished before Angular was ready (the win).\n prefetchSavedMs: Math.max(\n 0,\n Math.min(connectMs, sessionStartMs - startMs),\n ),\n // The real wait Angular experienced (connect call → adopted).\n adoptionWaitMs: Math.max(0, adoptionAtMs - sessionStartMs),\n // Gap between the prefetch being ready and Angular adopting it.\n adoptionOverheadMs: Math.max(0, adoptionAtMs - readyMs),\n };\n\n // Region (phaseNo 1) — served from the ping cache during prefetch (~0),\n // positioned at the prefetch start; ship the samples.\n const region = this.readRegionCache();\n this.emitAdoptedPhase(0, startMs, 0, adoptionAtMs, {\n region: region?.region_code ?? '',\n pingsMs: region?.result.length ? `${region.result.join(', ')} ms` : null,\n });\n // Signaling (phaseNo 2) — [prefetch_start → ws_open]; streamer identity +\n // savings; ws-connected marker sits at the phase's own end.\n this.emitAdoptedPhase(\n 1,\n startMs,\n sigDur,\n adoptionAtMs,\n {\n ...this.adoptedSignalingParams(),\n ...savings,\n prefetchSignalingMs: sigDur,\n },\n [{ id: 'signaling-ws-connected', time: wsOpenMs }],\n );\n // WebRTC negotiation (phaseNo 3) — [ws_open → ready].\n this.emitAdoptedPhase(2, wsOpenMs, webDur, adoptionAtMs, {\n iceCandidateCount: 0,\n prefetchWebrtcMs: webDur,\n });\n\n // Unreal communication chains from the adoption moment (real wall-clock).\n s.lastMilestonePerf = now;\n }\n\n /**\n * Emit one adopted phase positioned at its real `spanStartMs` (left-shifted\n * to overlap page load) with its real prefetch `duration`. `prefetched`,\n * `spanStartMs` and `adoptionAtMs` ride as top-level wire fields the viewer\n * uses to lay the bar out; the rest become display params.\n */\n private emitAdoptedPhase(\n bucketIdx: number,\n spanStartMs: number,\n durationMs: number,\n adoptionAtMs: number,\n extras: Record<string, unknown>,\n milestones: EmittedMilestone[] = [],\n ): void {\n const s = this.session;\n if (!s) return;\n const bucket = this.phaseCatalog[bucketIdx];\n this.track('stream.phase_ended', {\n sessionId: s.id,\n phaseNo: bucketIdx + 1,\n id: bucket.id,\n color: bucket.color,\n duration: durationMs,\n prefetched: true,\n spanStartMs,\n adoptionAtMs,\n milestones,\n params: toPhaseParams({ ...extras, prefetched: true }),\n overlays: [],\n });\n }\n\n /** Streamer identity params for the adopted signaling phase — mirrors the\n * `ssinfo-received` closer's shape (client / instanceName / …ssData). */\n private adoptedSignalingParams(): Record<string, unknown> {\n const aws = this.awsInstance$();\n const ssData = this.ssData$();\n return {\n client: aws?.wsUrl ?? null,\n instanceName: aws?.instanceName ?? null,\n ...(ssData ?? {}),\n };\n }\n\n /** Read the region-ping cache the prefetch reused (localStorage), so the\n * adopted region phase can still report the winning region + samples. */\n private readRegionCache(): { region_code: string; result: number[] } | null {\n try {\n const raw = localStorage.getItem(REGION_PING_CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as {\n region_code?: unknown;\n result?: unknown;\n };\n return {\n region_code:\n typeof parsed.region_code === 'string' ? parsed.region_code : '',\n result: Array.isArray(parsed.result)\n ? parsed.result.filter((n): n is number => typeof n === 'number')\n : [],\n };\n } catch {\n return null;\n }\n }\n\n private handleWindow(samples: AggregatedStat[]) {\n if (!this.session) return;\n const s = this.session;\n\n // Pull a metric off every sample, dropping anything that isn't a\n // real measurement. WebRTC reports `null` / `undefined` while the\n // metric is still warming up; some streamer libs emit `-1` as a\n // sentinel for \"not yet measurable\" (most notably for RTT). The\n // previous `?? 0` fallback masked both — the zero pad polluted\n // percentiles and the `-1` slipped through entirely.\n //\n // `nonNegative` is for metrics where a literal `0` is a legitimate\n // value (bitrate during stalls, jitter on a perfect link, QP at\n // lossless). `positive` is for metrics where `0` itself is\n // physically impossible (RTT, FPS).\n const nonNegative = (\n pick: (a: AggregatedStat['aggregatedStats']) => number | null | undefined,\n ): number[] =>\n samples\n .map((x) => pick(x.aggregatedStats))\n .filter(\n (v): v is number =>\n typeof v === 'number' && Number.isFinite(v) && v >= 0,\n );\n\n const positive = (\n pick: (a: AggregatedStat['aggregatedStats']) => number | null | undefined,\n ): number[] =>\n samples\n .map((x) => pick(x.aggregatedStats))\n .filter(\n (v): v is number =>\n typeof v === 'number' && Number.isFinite(v) && v > 0,\n );\n\n const bitrate = this.aggregate(nonNegative((a) => a.bitrate));\n const fps = this.aggregate(positive((a) => a.framesPerSecond));\n const qp = this.aggregate(nonNegative((a) => a.VideoEncoderQP));\n const jitter = this.aggregate(nonNegative((a) => a.jitter));\n const rtt = this.aggregate(positive((a) => a.currentRoundTripTime));\n const latest = samples[samples.length - 1]?.aggregatedStats;\n\n // Periodic sample event.\n this.track('stream.sample', {\n sessionId: s.id,\n seq: s.seq++,\n timestamp: new Date().toISOString(),\n sampleCount: samples.length,\n // Tab visibility state at emission time. Chrome does NOT throttle timers\n // for WebRTC-active tabs, so the handler runs on time even when hidden —\n // the point-in-time read is reliable in this specific context.\n visibilityState: document.visibilityState,\n bitrate,\n fps,\n qp,\n jitter,\n rtt,\n packetsLost: latest?.packetsLost,\n viewPort: {\n width: latest?.frameWidth,\n height: latest?.frameHeight,\n },\n });\n\n this.evaluateAnomalies(fps, qp);\n }\n\n private evaluateAnomalies(fps: WindowAggregate, qp: WindowAggregate) {\n if (!this.session) return;\n const s = this.session;\n\n // Quality (QP red) entry/exit.\n const qpBadNow = qp.p50 > QP_RED_THRESHOLD;\n if (qpBadNow !== s.qpBad) {\n s.qpBad = qpBadNow;\n this.track(\n qpBadNow ? 'stream.quality_degraded' : 'stream.quality_recovered',\n {\n sessionId: s.id,\n seq: s.seq,\n timestamp: new Date().toISOString(),\n qpP50: qp.p50,\n qpP95: qp.p95,\n },\n );\n }\n\n // FPS low vs. current target.\n const ref = s.maxFpsTarget > 0 ? s.maxFpsTarget : UNLIMITED_REFERENCE_FPS;\n const fpsLowNow = fps.p50 < ref * FPS_LOW_RATIO;\n if (fpsLowNow && !s.fpsLow) {\n this.track('stream.fps_low', {\n sessionId: s.id,\n seq: s.seq,\n timestamp: new Date().toISOString(),\n target: s.maxFpsTarget,\n referenceTarget: ref,\n fpsP50: fps.p50,\n fpsP95: fps.p95,\n });\n }\n s.fpsLow = fpsLowNow;\n }\n\n private updateMaxFpsTarget(maxFps: number) {\n if (this.session) this.session.maxFpsTarget = maxFps;\n }\n\n /**\n * Snapshot every milestone recorded in this session that belongs to\n * {@link phase}. Used to attach a phase's milestone array to the\n * lifecycle event that closes that phase.\n */\n /**\n * Collect wire-shape milestones that fired within a bucket. Walks the\n * catalog's own milestone list (minus the closer) and pulls each\n * entry's time from the in-session map via object identity.\n */\n private milestonesOfBucket(bucket: CatalogPhase): EmittedMilestone[] {\n if (!this.session) return [];\n const out: EmittedMilestone[] = [];\n const closerIdx = bucket.milestones.length - 1;\n for (let i = 0; i < closerIdx; i++) {\n const entry = bucket.milestones[i];\n const time = this.session.times.get(entry);\n if (time !== undefined) out.push({ id: entry.id, time });\n }\n return out;\n }\n\n /**\n * Capture browser navigation timings — useful to explain the\n * \"application bootstrap → session_started\" waterfall phase.\n * Values are ms from navigation start; null if the entry is unavailable\n * (old browsers, cross-origin iframes with limited perf access, etc.).\n */\n private collectBootstrapInfo(): Record<string, unknown> | null {\n try {\n const nav = performance.getEntriesByType('navigation')[0] as\n PerformanceNavigationTiming | undefined;\n if (!nav) return null;\n const split = this.collectResourceTotals(nav.loadEventEnd);\n return {\n type: nav.type, // 'navigate' | 'reload' | 'back_forward' | 'prerender'\n protocol: nav.nextHopProtocol || null, // 'h2' / 'h3' / 'http/1.1'\n firstByteMs: Math.round(nav.responseStart),\n domInteractiveMs: Math.round(nav.domInteractive),\n domContentLoadedMs: Math.round(nav.domContentLoadedEventEnd),\n loadEventMs: Math.round(nav.loadEventEnd),\n // Navigation-only size — the HTML document itself. Usually small;\n // the interesting number is `resources.transferSize` below.\n navigationTransferSize: nav.transferSize || null,\n navigationEncodedBodySize: nav.encodedBodySize || null,\n navigationDecodedBodySize: nav.decodedBodySize || null,\n // Resources are split into \"before window.load\" (page-weight) and\n // \"after window.load\" (typically lazy chunks for the route the\n // user navigated to before the streamer mounted). The viewer\n // attributes them to `HTML loading` and `Route idle` respectively.\n resources: split.resources,\n lazyResources: split.lazyResources,\n // Top-8 slowest individual resources (path + duration), so the viewer\n // can name the offending file / GraphQL endpoint.\n slowestResources: split.slowestResources,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Aggregate all resources the browser has loaded so far\n * (`performance.getEntriesByType('resource')`), grouped by `initiatorType`,\n * **split by `window.load`**:\n *\n * - `resources` — fetched before `loadEventEnd` (= part of the actual\n * page weight). What you'd traditionally call \"page load.\"\n * - `lazyResources` — fetched after `loadEventEnd` (= typically the\n * route's lazy-loaded chunks, JSON manifests etc. that download\n * when the user navigates to a sub-route the streamer lives on).\n *\n * When `loadEventEnd` is 0/unknown, everything goes into `resources`\n * and `lazyResources` is null — old behavior.\n *\n * `transferSize === 0 && decodedBodySize > 0` means the resource came from\n * the HTTP cache — counted separately so cached hits don't inflate\n * the \"bytes on the wire\" metric.\n */\n private collectResourceTotals(loadEventEnd: number): {\n resources: Record<string, unknown> | null;\n lazyResources: Record<string, unknown> | null;\n slowestResources: SlowResource[];\n } {\n try {\n const list = performance.getEntriesByType(\n 'resource',\n ) as PerformanceResourceTiming[];\n if (!list.length)\n return { resources: null, lazyResources: null, slowestResources: [] };\n\n interface Bucket {\n count: number;\n cachedCount: number;\n transferSize: number;\n encodedBodySize: number;\n decodedBodySize: number;\n // Timing (Resource Timing `duration` = responseEnd − startTime).\n // `durationMs` is the SUM across this type's resources; with `count`\n // it yields the average per request, and `maxDurationMs` the slowest.\n // For `fetch`/`xmlhttprequest` this is the GraphQL/data-call timing.\n durationMs: number;\n maxDurationMs: number;\n }\n const empty = (): Bucket => ({\n count: 0,\n cachedCount: 0,\n transferSize: 0,\n encodedBodySize: 0,\n decodedBodySize: 0,\n durationMs: 0,\n maxDurationMs: 0,\n });\n\n const splitEnabled = loadEventEnd > 0;\n\n const pageLoadTotals = empty();\n const pageLoadByType: Record<string, Bucket> = {};\n const lazyTotals = empty();\n const lazyByType: Record<string, Bucket> = {};\n const slow: SlowResource[] = []; // every timed resource; trimmed to top-N\n\n for (const r of list) {\n const type = r.initiatorType || 'other';\n const isLazy = splitEnabled && r.startTime > loadEventEnd;\n const totals = isLazy ? lazyTotals : pageLoadTotals;\n const byType = isLazy ? lazyByType : pageLoadByType;\n\n const b = (byType[type] ||= empty());\n const fromCache = r.transferSize === 0 && r.decodedBodySize > 0;\n const t = r.transferSize || 0;\n const enc = r.encodedBodySize || 0;\n const dec = r.decodedBodySize || 0;\n const dur = r.duration || 0; // responseEnd − startTime (ms)\n\n b.count++;\n if (fromCache) b.cachedCount++;\n b.transferSize += t;\n b.encodedBodySize += enc;\n b.decodedBodySize += dec;\n b.durationMs += dur;\n if (dur > b.maxDurationMs) b.maxDurationMs = dur;\n\n totals.count++;\n if (fromCache) totals.cachedCount++;\n totals.transferSize += t;\n totals.encodedBodySize += enc;\n totals.decodedBodySize += dec;\n totals.durationMs += dur;\n if (dur > totals.maxDurationMs) totals.maxDurationMs = dur;\n\n if (dur > 0) {\n slow.push({\n name: shortResourceName(r.name),\n type,\n durationMs: Math.round(dur),\n transferKb: Math.round((t / 1024) * 10) / 10,\n lazy: isLazy,\n });\n }\n }\n\n slow.sort((a, b) => b.durationMs - a.durationMs);\n\n return {\n resources:\n pageLoadTotals.count > 0\n ? { ...pageLoadTotals, byType: pageLoadByType }\n : null,\n lazyResources:\n lazyTotals.count > 0 ? { ...lazyTotals, byType: lazyByType } : null,\n // Top-8 slowest individual resources (path only, query stripped) so\n // the viewer can name the offending file / endpoint. GraphQL appears\n // here as its endpoint path (one entry per call) — Resource Timing\n // can't expose the operation name (it's in the POST body).\n slowestResources: slow.slice(0, 8),\n };\n } catch {\n return { resources: null, lazyResources: null, slowestResources: [] };\n }\n }\n\n private aggregate(values: number[]): WindowAggregate {\n if (values.length === 0) return { p50: 0, p95: 0, min: 0, max: 0 };\n const sorted = [...values].sort((a, b) => a - b);\n // Nearest-rank method: p-th percentile ≡ sorted[ceil(p/100 * n) - 1].\n // Using `floor` would make p95 collapse to `max` for n=20\n // (floor(0.95*20) = 19 = max index), hiding the max line behind p95\n // in charts. `ceil - 1` keeps them distinct: p. 95 = sorted[18], max = sorted[19].\n const pick = (p: number) => {\n const idx = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, Math.min(sorted.length - 1, idx))];\n };\n return {\n p50: pick(50),\n p95: pick(95),\n min: sorted[0],\n max: sorted[sorted.length - 1],\n };\n }\n\n private track(event: string, data: Record<string, unknown>) {\n // `userId` is attached to every event, so the server can bucket files\n // under `data/<userId>/<sessionId>.jsonl` without maintaining a\n // session→user index.\n this.store.dispatch(\n trackTelemetryData({\n event,\n data: { userId: this.userId, ...data },\n }),\n );\n }\n}\n\n// ──────────────────────────────────────────────────────────────────\n// Module-scope helpers — keep the class body focused on RxJS wiring.\n// ──────────────────────────────────────────────────────────────────\n\n/** Compact one side of an ICE candidate pair to `\"type (url)\"` or just\n * `type` (host candidates have no URL). */\nfunction fmtCandidate(c: { type: string; url: string } | undefined) {\n if (!c) {\n return null;\n }\n return c.url ? `${c.type} (${c.url})` : c.type;\n}\n\n/**\n * Flatten the closer's emitted extras object into display key/value\n * pairs. Null/undefined/empty are dropped; objects and arrays are\n * skipped — they should be pre-formatted by the closer's `map(...)`.\n */\nfunction toPhaseParams(value: unknown): PhaseParam[] {\n if (!value || typeof value !== 'object') return [];\n const out: PhaseParam[] = [];\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === null || v === undefined || v === '') continue;\n if (typeof v === 'object') continue;\n out.push({ key, value: String(v) });\n }\n return out;\n}\n\n/**\n * Resolve declarative overlay recipes to absolute ms spans. Endpoints\n * fall back to the phase's own start/end when unspecified; recipes\n * whose referenced entry never fired are quietly skipped.\n */\nfunction resolveOverlays(\n recipes: readonly OverlayRecipe[] | undefined,\n times: ReadonlyMap<CatalogEntry, number>,\n phaseStartMs: number,\n phaseEndMs: number,\n): PhaseOverlay[] {\n if (!recipes?.length) return [];\n const out: PhaseOverlay[] = [];\n for (const r of recipes) {\n const fromMs = r.from ? (times.get(r.from) ?? null) : phaseStartMs;\n const toMs = r.to ? (times.get(r.to) ?? null) : phaseEndMs;\n if (fromMs === null || toMs === null || toMs <= fromMs) continue;\n out.push({ fromMs, toMs, id: r.id });\n }\n return out;\n}\n","export const ReceivedMimeTypes = {\n ApplicationJson: 'application/json',\n} as const;\nexport type ReceivedMimeType =\n (typeof ReceivedMimeTypes)[keyof typeof ReceivedMimeTypes];\n","import { inject, Injectable } from '@angular/core';\nimport type { ReceivedFile } from './file-receiver.service';\nimport { FileReceiverService } from './file-receiver.service';\nimport { generateUuid, Logger, Truthy } from '@3dsource/utils';\nimport type { Observable } from 'rxjs';\nimport { defer, from, of, switchMap, take, timeout } from 'rxjs';\nimport { catchError, filter, map } from 'rxjs/operators';\nimport type { MetaBoxCommandList } from '@3dsource/types-unreal';\nimport type { ReceivedMimeType } from '../interfaces/ReceivedMimeTypes';\nimport { ReceivedMimeTypes } from '../interfaces/ReceivedMimeTypes';\n\ntype FileHandlers = Record<\n ReceivedMimeType,\n (data: ReceivedFile, correlationId: string) => Observable<unknown>\n>;\n\n@Injectable({ providedIn: 'root' })\nexport class FileHandlerService {\n private fileService = inject(FileReceiverService);\n private fileHandlers: FileHandlers = {\n [ReceivedMimeTypes.ApplicationJson]: this.handleJsonFile.bind(this),\n };\n\n private handleJsonFile(data: ReceivedFile, correlationId: string) {\n const { blob } = data;\n return from(blob.text()).pipe(\n map((text: string) => JSON.parse(text)),\n filter(({ commandCallback }) => {\n return commandCallback.correlationId === correlationId;\n }),\n );\n }\n\n observeFileResponse<\n K extends keyof MetaBoxCommandList,\n T extends MetaBoxCommandList[K] = MetaBoxCommandList[K],\n >(\n mimetype: ReceivedMimeType,\n data: T,\n sender: (data: T) => void,\n timeOut = 60000,\n ) {\n const correlationId = generateUuid();\n const out = { ...data, correlationId };\n\n return defer(() => {\n const observable = this.fileService.fileComplete$.pipe(\n switchMap((data) => {\n if (data.valid && this.fileHandlers[mimetype]) {\n return this.fileHandlers[mimetype](data, correlationId).pipe(\n filter(Truthy),\n );\n }\n return of(null);\n }),\n timeout(timeOut),\n catchError((e) => {\n Logger.error(e);\n return of(null);\n }),\n take(1),\n );\n setTimeout(() => sender(out), 0);\n return observable;\n });\n }\n}\n","import {\n filter,\n fromEvent,\n merge,\n Subject,\n takeUntil,\n throttleTime,\n} from 'rxjs';\nimport { Injectable } from '@angular/core';\nimport { distinctUntilChanged, tap } from 'rxjs/operators';\nimport { saveAnalyticsEvent, unrealFeature } from '../store';\nimport { Logger } from '@3dsource/utils';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class AnalyticsService extends SubService {\n #stopMouse$ = new Subject<void>();\n\n constructor() {\n super();\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(distinctUntilChanged(), takeUntil(this.destroy$))\n .subscribe((ready) => {\n this.#stopMouse$.next();\n if (ready) {\n this.monitorMouse();\n }\n });\n }\n\n private monitorMouse() {\n const stop$ = merge(this.#stopMouse$, this.destroy$);\n const element = document.getElementById('streamingVideo');\n\n if (!element) {\n return;\n }\n\n // Monitor mousewheel events\n const mousewheel$ = fromEvent<WheelEvent>(element, 'wheel').pipe(\n takeUntil(stop$),\n throttleTime(1000),\n );\n\n // Monitor mouse button states\n const mousedown$ = fromEvent<MouseEvent>(element, 'mousedown').pipe(\n takeUntil(stop$),\n );\n const touchStart$ = fromEvent<TouchEvent>(element, 'touchstart').pipe(\n takeUntil(stop$),\n );\n const touchMove$ = fromEvent<TouchEvent>(element, 'touchmove').pipe(\n takeUntil(stop$),\n throttleTime(200),\n );\n\n // Track mouse movement while the left or right button is pressed\n mousedown$\n .pipe(\n filter((event) => event.button === 0 || event.button === 2),\n tap((downEvent) => {\n this.sendEventToMixPanel('mouse_interaction', {\n viewX: downEvent.clientX / element.clientWidth,\n viewY: downEvent.clientY / element.clientHeight,\n action: downEvent.button === 0 ? 'spinning' : 'panning',\n });\n }),\n )\n .subscribe();\n\n // Track mouse movement while the left or right button is pressed\n touchStart$\n .pipe(\n tap((downEvent) => {\n const totalTouches = downEvent.touches.length;\n const touch = downEvent.touches[0];\n this.sendEventToMixPanel('touch_interaction', {\n viewX: touch.clientX / element.clientWidth,\n viewY: touch.clientY / element.clientHeight,\n action: totalTouches === 1 ? 'spinning' : 'panning',\n });\n }),\n )\n .subscribe();\n\n let initialTouchDistance = 0;\n // Subscribe to mousewheel events\n touchMove$.subscribe((event: TouchEvent) => {\n const totalTouches = event.touches.length;\n if (totalTouches < 2) {\n return;\n }\n\n // Calculate the current distance between two touches\n const touch1 = event.touches[0];\n const touch2 = event.touches[1];\n const currentDistance = Math.sqrt(\n Math.pow(touch2.clientX - touch1.clientX, 2) +\n Math.pow(touch2.clientY - touch1.clientY, 2),\n );\n\n // Determine if zooming in or out based on distance change\n const deltaDistance = currentDistance - initialTouchDistance;\n const isZoomingIn = deltaDistance > 0;\n\n // Only send event if there's a significant change (avoid noise)\n if (Math.abs(deltaDistance) > 10) {\n this.sendEventToMixPanel('touch_zoom_interaction', {\n delta: isZoomingIn ? 1 : -1,\n action: isZoomingIn ? 'zoomin' : 'zoomout',\n });\n\n // Update initial distance for next comparison\n initialTouchDistance = currentDistance;\n }\n });\n\n mousewheel$.subscribe((event: WheelEvent) => {\n this.sendEventToMixPanel('mouse_zoom_interaction', {\n delta: -(event.deltaY / Math.abs(event.deltaY)),\n action: event.deltaY < 0 ? 'zoomin' : 'zoomout',\n });\n });\n }\n\n private sendEventToMixPanel(\n name: string,\n params: Record<string, unknown> = {},\n ): void {\n Logger.log('Analytics Event:', name, params);\n this.store.dispatch(saveAnalyticsEvent({ event: { name, params } }));\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { filter, takeUntil, withLatestFrom } from 'rxjs/operators';\nimport { clampf, Logger } from '@3dsource/utils';\nimport { VideoService } from './video.service';\nimport { setMaxFps, unrealFeature } from '../store';\nimport { qpToQuality } from '../helpers';\nimport type { AggregatedStat } from '../interfaces';\nimport { merge, Subject } from 'rxjs';\nimport { UNREAL_CONFIG } from '../constants';\nimport { SubService } from './sub.service';\n\ntype Decision = 'decrease' | 'hold' | 'increase';\n\n/**\n * Adaptive FPS controller that monitors the incoming WebRTC video stream\n * quality and dynamically adjusts Unreal Engine's `t.MaxFPS` console variable.\n *\n * ## How it works\n *\n * The service subscribes to `VideoService.videoStats$` (emitted every 250 ms)\n * and collects samples of FPS, bitrate, and QP (Quantization Parameter).\n * Every {@link SAMPLE_WINDOW} ticks (~2 s) it averages the collected samples\n * and feeds them into a set of **fuzzy-logic membership functions** that\n * classify each metric into overlapping quality bands.\n *\n * ### Input signals\n *\n * **1. FPS ratio** = `actualFPS / currentTargetFPS` (0..1+)\n *\n * | Band | Range | Meaning |\n * |--------|---------------------|-----------------------------------------------|\n * | low | ratio < 0.7 → 1.0, linear ramp 0.7..0.9 → 0 | Stream cannot keep up with the target |\n * | okays | triangle 0.8..1.0, peak at 0.95 | Stream roughly matches the target |\n * | high | ratio 0.9..1.0 → ramp, >1.0 → 1.0 | Stream meets or exceeds the target |\n *\n * **2. Bitrate load** = `currentBitrate / MAX_BITRATE` (0..1+)\n *\n * `MAX_BITRATE` = 20 Mbit/s — the reference ceiling for the encoder.\n *\n * | Band | Range | Meaning |\n * |--------|-------------------------------------------------|-----------------------------------------------|\n * | high | load 0.5..0.8 → ramp, >0.8 → 1.0 | Encoder is using most of the available bandwidth |\n * | not high | load < 0.5 → 0.0 | Bandwidth headroom is available |\n *\n * **3. Quality** — mapped from QP via `mapQpToQuality()` (see {@link Quality}):\n *\n * | Quality | QP range | Meaning |\n * |----------|-----------|-------------------------------------------------|\n * | `lime` | QP <= 26 | Good — encoder has enough headroom |\n * | `orange` | QP 27..35 | Fair — encoder is under moderate pressure |\n * | `red` | QP > 35 | Poor — heavy compression, visible artifacts |\n *\n * ### Decision rules (evaluated in priority order, first match wins)\n *\n * | # | Condition | Decision |\n * |---|------------------------------------------------------------|--------------|\n * | 1 | FPS ratio is **low** (membership > 0.5) | **decrease** |\n * | 2 | FPS ratio is **ok** AND quality is `red` | **decrease** |\n * | 3 | FPS ratio is **ok** AND bitrate **high** AND quality is `orange` | **hold** |\n * | 4 | FPS ratio is **high** AND quality is `lime` AND bitrate **not high** | **increase** |\n * | — | Everything else | **hold** |\n *\n * ## Cooldown-based throttling\n *\n * The service continuously evaluates fuzzy rules in every sample window.\n * After each FPS step change it enforces a cooldown before the next\n * change can be applied. The cooldown duration depends on the\n * (previous decision → next decision) pair:\n *\n * | Previous | Next | Cooldown |\n * |-----------|-----------|-----------------------------------------------------|\n * | decrease | decrease | {@link COOLDOWN_DECREASE_AFTER_DECREASE_MS} (2 s) |\n * | decrease | increase | {@link COOLDOWN_INCREASE_AFTER_DECREASE_MS} (10 s) |\n * | increase | decrease | {@link COOLDOWN_AFTER_INCREASE_MS} (2 s) |\n * | increase | increase | {@link COOLDOWN_AFTER_INCREASE_MS} (2 s) |\n *\n * This means the system reacts quickly after an increase (2 s in any\n * direction) but is cautious about stepping back up after a decrease\n * (10 s), while still allowing consecutive decreases at 2 s intervals.\n *\n * ## FPS dispatch\n *\n * FPS changes are dispatched via the NgRx `setMaxFps` action, which triggers\n * the existing `UnrealEffects.setMaxFps$` effect that sends the\n * `t.MaxFPS <value>` console command to Unreal Engine.\n */\n@Injectable({ providedIn: 'root' })\nexport class FpsMonitorService extends SubService {\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n /** Discrete FPS targets the controller can switch between (ascending order). Last 0 is an unlimited framerate indicator*/\n private readonly FPS_STEPS = [30, 40, 50, 0] as const;\n\n /**\n * Reference FPS used to compute the FPS ratio when `currentFpsTarget` is 0\n * (unlimited). Keeps adaptive logic operational at the unlimited step:\n * if the stream drops well below this value, fuzzy rules can still fire.\n */\n private readonly UNLIMITED_REFERENCE_FPS = 60;\n\n /** Reference ceiling for bitrate (bits/sec) used to normalize a bitrate load to 0..1. */\n private readonly MAX_BITRATE = 20_000_000;\n\n /**\n * Cooldown (ms) for any decision (increase or decrease) following an increase.\n * After an increase, the system should react faster.\n */\n private readonly COOLDOWN_AFTER_INCREASE_MS = 2_000;\n\n /**\n * Cooldown (ms) for a decrease following a previous decrease.\n */\n private readonly COOLDOWN_DECREASE_AFTER_DECREASE_MS = 2_000;\n\n /**\n * Cooldown (ms) for an increase following a previous decrease.\n * The stream needs more time to stabilize before stepping back up.\n */\n private readonly COOLDOWN_INCREASE_AFTER_DECREASE_MS = 10_000;\n\n /**\n * Number of videoStats$ ticks to accumulate before evaluating.\n * At 250 ms per tick, this gives a ~2 s sliding evaluation window,\n * long enough to smooth out single-frame jitter.\n */\n private readonly SAMPLE_WINDOW = 8;\n\n /** Emits when the session ends, cancelling the current stats' subscription. */\n private session$ = new Subject<void>();\n\n /** Current FPS target; starts at max (60 FPS) and adapts downward/upward. */\n private currentFpsTarget: number = this.FPS_STEPS[this.FPS_STEPS.length - 1];\n private samples: { fps: number; bitrate: number; qp: number }[] = [];\n private lastDecisionTime = Date.now();\n private lastUpgrade: Decision = 'hold';\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright || !this.unrealConfig?.fpsMonitor) {\n return;\n }\n // Reset mutable state and re-subscribe when a new session starts\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Boolean), takeUntil(this.destroy$))\n .subscribe(() => this.startSession());\n\n // Reset mutable state when session ends\n this.disconnect$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.resetSession());\n }\n\n private startSession() {\n // Tear down previous stats subscription if any\n this.session$.next();\n this.resetMutableState();\n\n this.videoService.videoStats$\n .pipe(\n withLatestFrom(this.store.select(unrealFeature.selectViewportReady)),\n filter(([, viewportReady]) => viewportReady),\n takeUntil(merge(this.session$, this.destroy$)),\n )\n .subscribe(([stats]) => this.processTick(stats));\n }\n\n private resetSession() {\n this.session$.next();\n this.resetMutableState();\n }\n\n private resetMutableState() {\n this.currentFpsTarget = this.FPS_STEPS[this.FPS_STEPS.length - 1];\n this.samples = [];\n this.lastDecisionTime = Date.now();\n this.lastUpgrade = 'hold';\n }\n\n /**\n * Called on every videoStats$ emission (~250 ms).\n * Accumulates samples and evaluates once per SAMPLE_WINDOW.\n */\n private processTick(stats: AggregatedStat) {\n const { framesPerSecond, bitrate, VideoEncoderQP } = stats.aggregatedStats;\n\n this.samples.push({\n fps: framesPerSecond ?? 0,\n bitrate: bitrate ?? 0,\n qp: VideoEncoderQP ?? 0,\n });\n\n // Wait until we have enough samples for a reliable average.\n if (this.samples.length < this.SAMPLE_WINDOW) {\n return;\n }\n\n const avg = this.averageSamples();\n this.samples = [];\n\n this.handleMonitoring(avg, this.currentFpsTarget);\n }\n\n private handleMonitoring(\n avg: { fps: number; bitrate: number; qp: number },\n currentTarget: number,\n ) {\n const decision = this.evaluateDecision(avg, currentTarget);\n this.upgradeFps(decision, avg.qp);\n }\n\n /**\n * Combines fuzzy membership values into a single discrete decision.\n * Rules are evaluated in priority order — first match wins.\n *\n * Inputs:\n * - `fpsRatio` = avgFPS / currentTargetFPS (e.g., 45/60 = 0.75)\n * - `bitrateLoad` = avgBitrate / 20 Mbit/s (e.g., 12M/20M = 0.6)\n * - `quality` = mapQpToQuality(avgQP) → 'lime' | 'orange' | 'red'\n */\n private evaluateDecision(\n avg: { fps: number; bitrate: number; qp: number },\n currentTarget: number,\n ): Decision {\n const referenceTarget =\n currentTarget > 0 ? currentTarget : this.UNLIMITED_REFERENCE_FPS;\n const fpsRatio = avg.fps / referenceTarget;\n const bitrateLoad = avg.bitrate / this.MAX_BITRATE;\n\n const fpsLow = this.membershipFpsLow(fpsRatio);\n const fpsOk = this.membershipFpsOk(fpsRatio);\n const fpsHigh = this.membershipFpsHigh(fpsRatio);\n\n const bitrateHigh = this.membershipBitrateHigh(bitrateLoad);\n\n // Quality is derived from QP: lime (QP <= 26), orange (QP 27..35), red (QP > 35).\n const quality = qpToQuality(avg.qp);\n\n // Rule 1: FPS clearly below target (ratio roughly < 0.8) → step down immediately.\n if (fpsLow > 0.5) {\n return 'decrease';\n }\n\n // Rule 2: FPS looks acceptable numerically, but encoder quality is 'red'\n // (QP > 35 — heavy compression artifacts). Reducing target FPS frees\n // encoder headroom and improves visual quality.\n if (fpsOk > 0.4 && quality === 'red') {\n return 'decrease';\n }\n\n // Rule 3: FPS is ok, but the bitrate is above ~50-80% of 20 Mbit/s ceiling\n // and quality is 'orange' (QP 27..35). Near capacity — don't push higher.\n if (fpsOk > 0.4 && bitrateHigh > 0.5 && quality === 'orange') {\n return 'hold';\n }\n\n // Rule 4: FPS meets/exceeds the target (ratio >= ~0.95), quality is 'lime'\n // (QP <= 26), and bitrate is below 50% of ceiling — safe to step up.\n // Note: the last FPS_STEPS value (0) means \"no limit\", so compare by\n // position in FPS_STEPS rather than numerically.\n const currentIndex = this.FPS_STEPS.indexOf(\n this.currentFpsTarget as (typeof this.FPS_STEPS)[number],\n );\n if (\n fpsHigh > 0.5 &&\n quality === 'lime' &&\n bitrateHigh < 0.5 &&\n currentIndex !== -1 &&\n currentIndex < this.FPS_STEPS.length - 1\n ) {\n return 'increase';\n }\n\n return 'hold';\n }\n\n // ---------------------------------------------------------------------------\n // Fuzzy membership functions\n //\n // Each function maps a normalised input (0..1+) to a membership degree (0..1).\n // Overlapping trapezoid/triangle shapes let multiple categories be partially\n // active at the same time, which makes the rules less brittle than hard thresholds.\n // ---------------------------------------------------------------------------\n\n /**\n * FPS ratio membership \"low\".\n * Input: a ratio = actualFPS / targetFPS (e.g., 42/60 = 0.70).\n *\n * ratio < 0.7 → 1.0 (clearly failing, e.g., 40/60)\n * ratio 0.7..0.9 → linear ramp down (e.g., 0.8 → 0.5)\n * a ratio > 0.9 → 0.0 (keeping up)\n */\n private membershipFpsLow(ratio: number): number {\n if (ratio < 0.7) return 1.0;\n if (ratio > 0.9) return 0.0;\n return (0.9 - ratio) / 0.2;\n }\n\n /**\n * FPS ratio membership \"ok\" — triangle shape.\n * Input: ratio = actualFPS / targetFPS.\n *\n * ratio < 0.8 → 0.0\n * ratio 0.8..0.95 → ramp up, peak at 0.95 (e.g., 57/60)\n * ratio 0.95..1.0 → ramp down\n * a ratio > 1.0 → 0.0\n */\n private membershipFpsOk(ratio: number): number {\n if (ratio < 0.8) return 0.0;\n if (ratio < 0.95) return (ratio - 0.8) / 0.15;\n if (ratio <= 1.0) return (1.0 - ratio) / 0.05;\n return 0.0;\n }\n\n /**\n * FPS ratio membership \"high\".\n * Input: ratio = actualFPS / targetFPS.\n *\n * ratio < 0.9 → 0.0\n * ratio 0.9..1.0 → linear ramp up (e.g., 0.95 → 0.5)\n * a ratio >= 1.0 → 1.0 (meeting or exceeding target, e.g., 60/60)\n */\n private membershipFpsHigh(ratio: number): number {\n if (ratio < 0.9) return 0.0;\n if (ratio > 1.0) return 1.0;\n return (ratio - 0.9) / 0.1;\n }\n\n /**\n * Bitrate load membership \"high\".\n * Input: a load = currentBitrate / MAX_BITRATE (20 Mbit/s).\n *\n * load < 0.5 → 0.0 (below 10 Mbit/s — plenty of headroom)\n * load 0.5..0.8 → linear ramp (e.g., 13M/20M = 0.65 → 0.5)\n * load > 0.8 → 1.0 (above 16 Mbit/s — near capacity)\n */\n private membershipBitrateHigh(load: number): number {\n if (load < 0.5) return 0.0;\n if (load > 0.8) return 1.0;\n return (load - 0.5) / 0.3;\n }\n\n // ---------------------------------------------------------------------------\n // Step actions\n // ---------------------------------------------------------------------------\n\n private upgradeFps(decision: Decision, qp: number) {\n if (decision === 'hold') return;\n\n const now = Date.now();\n\n // Throttle: cooldown depends on (previous decision → current decision) pair.\n const isStepUp = decision === 'increase';\n const cooldown =\n this.lastUpgrade === 'decrease'\n ? isStepUp\n ? this.COOLDOWN_INCREASE_AFTER_DECREASE_MS\n : this.COOLDOWN_DECREASE_AFTER_DECREASE_MS\n : this.COOLDOWN_AFTER_INCREASE_MS;\n\n if (now - this.lastDecisionTime < cooldown) {\n return;\n }\n\n this.lastUpgrade = decision;\n\n const quality = qpToQuality(qp);\n const newTarget = this.getNextFpsTarget(this.currentFpsTarget, decision);\n\n Logger.info(\n `[FpsMonitor] Decision: ${decision} → FPS: ${newTarget}, Quality: ${quality}`,\n );\n\n if (newTarget !== this.currentFpsTarget) {\n this.currentFpsTarget = newTarget;\n this.store.dispatch(setMaxFps({ maxFps: newTarget }));\n }\n\n this.lastDecisionTime = now;\n this.samples = [];\n }\n\n /**\n * Get the next FPS target based on the current target and decision.\n * Clamps to the valid FPS_STEPS range.\n */\n private getNextFpsTarget(currentTarget: number, decision: Decision): number {\n const currentIndex = this.FPS_STEPS.indexOf(\n currentTarget as (typeof this.FPS_STEPS)[number],\n );\n\n // If current target is not in FPS_STEPS, find closest one\n const validIndex =\n currentIndex === -1\n ? this.findClosestFpsIndex(currentTarget)\n : currentIndex;\n\n const delta = decision === 'increase' ? 1 : -1;\n const newIndex = clampf(0, this.FPS_STEPS.length - 1, validIndex + delta);\n\n return this.FPS_STEPS[newIndex];\n }\n\n /**\n * Find the closest FPS step index for a given target value.\n */\n private findClosestFpsIndex(target: number): number {\n let closestIndex = 0;\n let closestDiff = Math.abs(this.FPS_STEPS[0] - target);\n\n for (let i = 1; i < this.FPS_STEPS.length; i++) {\n const diff = Math.abs(this.FPS_STEPS[i] - target);\n if (diff < closestDiff) {\n closestDiff = diff;\n closestIndex = i;\n }\n }\n\n return closestIndex;\n }\n\n /** Average all collected samples for the current evaluation window. */\n private averageSamples(): { fps: number; bitrate: number; qp: number } {\n const len = this.samples.length;\n if (len === 0) return { fps: 0, bitrate: 0, qp: 0 };\n\n let fps = 0;\n let bitrate = 0;\n let qp = 0;\n\n for (const s of this.samples) {\n fps += s.fps;\n bitrate += s.bitrate;\n qp += s.qp;\n }\n\n return { fps: fps / len, bitrate: bitrate / len, qp: qp / len };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n} from '@angular/core';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\nimport { AFKService } from '../../services';\nimport { Store } from '@ngrx/store';\nimport { unrealFeature } from '../../store';\n\n@Component({\n selector: 'app-afk-timeout-modal',\n templateUrl: './afk-timeout-modal.component.html',\n styleUrl: './afk-timeout-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class AfkTimeoutModalComponent {\n readonly #store = inject(Store);\n readonly #afkService = inject(AFKService);\n\n readonly isAfkTimerVisible = this.#store.selectSignal(\n unrealFeature.selectIsAfkTimerVisible,\n );\n readonly showAfkTimeoutPopup = this.#store.selectSignal(\n unrealFeature.selectShowAfkTimeoutPopup,\n );\n readonly afkCountdown = this.#store.selectSignal(\n unrealFeature.selectAfkCountdown,\n );\n readonly isShowAfkPopup = computed(\n () => this.isAfkTimerVisible() && this.showAfkTimeoutPopup(),\n );\n\n resetAfk() {\n this.#afkService.reset();\n }\n}\n","@if (isShowAfkPopup()) {\n <div\n (click)=\"resetAfk()\"\n (keydown.enter)=\"resetAfk()\"\n class=\"clickableState\"\n id=\"videoPlayOverlay\"\n role=\"button\"\n tabindex=\"0\"\n >\n <div class=\"resume-box\">\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <src-button\n [isFullWidth]=\"true\"\n [data-testid]=\"'continue-session'\"\n weight=\"primary\"\n size=\"lg\"\n >\n Continue\n </src-button>\n </div>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport {\n selectFreezeFrameCombinedDataUrl,\n selectFreezeFrameProgressMessageFromVideo,\n} from '../../store';\n\n@Component({\n selector: 'app-freeze-frame',\n templateUrl: './freeze-frame.component.html',\n styleUrl: './freeze-frame.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FreezeFrameComponent {\n readonly #store = inject(Store);\n\n readonly freezeFrameProgressMessageFromVideo = this.#store.selectSignal(\n selectFreezeFrameProgressMessageFromVideo,\n );\n readonly combinedFreeze = this.#store.selectSignal(\n selectFreezeFrameCombinedDataUrl,\n );\n}\n","@let image = combinedFreeze();\n@let progress = freezeFrameProgressMessageFromVideo();\n\n<div class=\"freeze-images\">\n @if (image) {\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\n }\n\n @if (progress) {\n <div class=\"progress-status\">\n {{ progress }}\n </div>\n }\n</div>\n","import type { PipeTransform } from '@angular/core';\nimport { inject, Pipe, SecurityContext } from '@angular/core';\nimport type {\n SafeHtml,\n SafeResourceUrl,\n SafeScript,\n SafeStyle,\n SafeUrl,\n} from '@angular/platform-browser';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Pipe({\n name: 'safe',\n})\nexport class SafePipe implements PipeTransform {\n private sanitizer = inject(DomSanitizer);\n\n transform(\n value: string,\n type: string,\n ): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {\n if (!value) {\n return value;\n }\n\n const context = (() => {\n switch (type) {\n case 'html':\n return SecurityContext.HTML;\n case 'style':\n return SecurityContext.STYLE;\n case 'script':\n return SecurityContext.SCRIPT;\n case 'url':\n return SecurityContext.URL;\n case 'resourceUrl':\n return SecurityContext.RESOURCE_URL;\n default:\n throw new Error(`Invalid safe type specified: ${type}`);\n }\n })();\n\n // Preserve the published return type while returning Angular-sanitized\n // content instead of disabling framework security checks.\n return (this.sanitizer.sanitize(context, value) ?? '') as SafeHtml;\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { DialogRef } from '@angular/cdk/dialog';\nimport { SafePipe } from '../../../../pipes';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-low-bandwidth-modal',\n templateUrl: './low-bandwidth-modal.component.html',\n styleUrl: './low-bandwidth-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SafePipe, SourceButtonComponent],\n})\nexport class LowBandwidthModalComponent {\n #dialogRef = inject(DialogRef);\n\n close(value?: boolean) {\n this.#dialogRef.close(value || false);\n }\n}\n","<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\n <header class=\"src-modal__header\">\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n Unstable Connection\n </h6>\n </header>\n <section class=\"src-modal__body\">\n <div\n [innerHtml]=\"\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\n | safe: 'html'\n \"\n class=\"src-modal__scroll-box\"\n ></div>\n </section>\n <footer class=\"src-modal__footer\">\n <div class=\"src-modal__buttons\">\n <src-button\n (onClick)=\"close(true)\"\n [data-testid]=\"'switch-to-interactive-mode'\"\n >\n Switch\n </src-button>\n\n <src-button\n (onClick)=\"close()\"\n [data-testid]=\"'close-lbm-modal'\"\n weight=\"primary\"\n >\n Ok\n </src-button>\n </div>\n </footer>\n</div>\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport {\n selectIsLoaderScreenVisible,\n setLoadingImageSrc,\n unrealFeature,\n} from '../../store';\nimport { Store } from '@ngrx/store';\nimport { NgOptimizedImage } from '@angular/common';\n\n@Component({\n selector: 'app-image-loading-src',\n templateUrl: './image-loading-src.component.html',\n styleUrl: './image-loading-src.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgOptimizedImage],\n})\nexport class ImageLoadingSrcComponent {\n #store = inject(Store);\n\n readonly isLoaderScreenVisible = this.#store.selectSignal(\n selectIsLoaderScreenVisible,\n );\n readonly imageLoadingSrc = this.#store.selectSignal(\n unrealFeature.selectImageLoadingSrc,\n );\n\n loadingImageError() {\n this.#store.dispatch(setLoadingImageSrc({ src: '' }));\n }\n}\n","@let image = imageLoadingSrc();\n@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (image) {\n <img\n (error)=\"loadingImageError()\"\n [ngSrc]=\"image\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n </div>\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n effect,\n ElementRef,\n HostListener,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n HEXtoRGB,\n HSVtoRGB,\n inverseLerp,\n RGBtoHEX,\n RGBtoHSV,\n} from '@3dsource/utils';\n\n@Component({\n selector: 'app-stat-graph',\n templateUrl: './stat-graph.component.html',\n styleUrl: './stat-graph.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class StatGraphComponent {\n readonly label = input.required<string>();\n readonly stat = input<{ value: number }>();\n readonly color = input('#417bc9');\n readonly tickStep = input(3);\n\n private el = inject(ElementRef);\n readonly graph = viewChild<ElementRef<HTMLCanvasElement>>('graph');\n\n private data: (number | null)[] = [];\n readonly max = signal(0);\n readonly min = signal(0);\n readonly current = signal(0);\n\n private canvas!: HTMLCanvasElement;\n private ctx!: CanvasRenderingContext2D;\n\n constructor() {\n effect(() => {\n const stat = this.stat();\n untracked(() => this.pushData(stat?.value ?? null));\n });\n afterNextRender({\n read: () => {\n const graph = this.graph();\n if (graph) {\n this.canvas = graph.nativeElement;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.ctx = this.canvas.getContext('2d')!;\n }\n },\n });\n }\n\n @HostListener('window:resize')\n resize() {\n this.draw();\n }\n\n private draw() {\n if (!this.canvas) {\n return;\n }\n\n const all = this.data.filter((r) => r !== null && !isNaN(r)) as number[];\n this.max.set(Math.max(...all));\n this.min.set(Math.min(...all));\n const scaleY = this.canvas.height / (this.max() || 1);\n this.current.set(all[all.length - 1] || 0);\n this.ctx.save();\n const bounds = this.el.nativeElement.getBoundingClientRect();\n this.canvas.width = bounds.width;\n this.canvas.height = bounds.height - 30; // -p height\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n [...this.data].reverse().forEach((val, index) => {\n const h = (val || 0) * scaleY;\n\n this.ctx.fillStyle = this.getColor(this.color(), h as number);\n this.ctx.fillRect(\n index * this.tickStep(),\n this.canvas.height - h,\n this.tickStep(),\n h,\n );\n });\n this.ctx.restore();\n }\n\n private getColor(fillStyle: string, value = 0) {\n const { r, g, b } = HEXtoRGB(fillStyle);\n const [h, s] = RGBtoHSV(r, g, b);\n const v = inverseLerp(0, this.canvas.height, value);\n {\n const [r, g, b] = HSVtoRGB(h, s, v);\n return '#' + RGBtoHEX(r, g, b);\n }\n }\n\n private pushData(stat: number | null) {\n this.data.push(stat);\n if (!this.canvas) {\n return;\n }\n if (this.data.length > this.canvas.width / this.tickStep()) {\n this.data.shift();\n }\n this.draw();\n }\n}\n","<div class=\"content\">\n <p>{{ label() }}: {{ current() }} | Min:{{ min() }} | Max:{{ max() }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n} from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { unrealFeature } from '../../store';\nimport { SourceLoadingComponent } from '@3dsource/source-ui-native';\nimport { LoadingProgressService } from '../../services';\n\n@Component({\n selector: 'app-unreal-status',\n templateUrl: './unreal-status.component.html',\n styleUrl: './unreal-status.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceLoadingComponent],\n})\nexport class UnrealStatusComponent {\n readonly #store = inject(Store);\n readonly #loadingProgress = inject(LoadingProgressService);\n\n readonly awsInstance = this.#store.selectSignal(\n unrealFeature.selectAwsInstance,\n );\n readonly smoothPercents = this.#loadingProgress.smoothPercents;\n readonly showLoader = this.#loadingProgress.loaderVisible;\n readonly showLoadingProgress = this.#store.selectSignal(\n unrealFeature.selectShowLoadingProgress,\n );\n readonly isShowLoadingPercentsPopup = computed(\n () => this.showLoader() && this.showLoadingProgress(),\n );\n}\n","@if (isShowLoadingPercentsPopup()) {\n @let _awsInstance = awsInstance();\n <div class=\"status-box\">\n @if (_awsInstance?.message) {\n <p>{{ _awsInstance?.message }}</p>\n } @else {\n <div class=\"status-box__message\">\n <src-loading\n [size]=\"30\"\n [backgroundStrokeColor]=\"'#E5E7EB'\"\n [progressStrokeColor]=\"'#1F2937'\"\n />\n {{ smoothPercents() }}%\n </div>\n }\n </div>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n type Signal,\n signal,\n} from '@angular/core';\nimport type { InboundVideoStats } from '../../interfaces';\nimport { selectSignalingParameters, unrealFeature } from '../../store';\nimport { StatGraphComponent } from '../stat-graph/stat-graph.component';\nimport { JsonPipe } from '@angular/common';\nimport { Store } from '@ngrx/store';\nimport { DevModeService, VideoService } from '../../services';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { SafePipe } from '../../pipes';\n\ninterface GraphListItem {\n key: string;\n color: string;\n stat: Signal<{ value: number }>;\n}\n\n@Component({\n selector: 'app-video-stats',\n templateUrl: './video-stats.component.html',\n styleUrl: './video-stats.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [StatGraphComponent, JsonPipe, SafePipe],\n})\nexport class VideoStatsComponent {\n readonly collapsed = signal(false);\n private readonly store = inject(Store);\n private readonly videoService = inject(VideoService);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n\n private readonly stats = toSignal(this.videoService.videoStats$);\n\n readonly viewportReady = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n readonly ssData = this.store.selectSignal(selectSignalingParameters);\n\n readonly fpsTick = computed(() => ({\n value: this.stats()?.aggregatedStats.framesPerSecond || 0,\n }));\n readonly bitrateTick = computed(() => ({\n value: this.stats()?.aggregatedStats.bitrate ?? 0,\n }));\n readonly videoQP = computed(() => ({\n value: this.stats()?.aggregatedStats.VideoEncoderQP ?? 0,\n }));\n\n readonly videoStatus = computed(() => {\n const event = this.stats();\n if (!this.isDevMode || !event) {\n return undefined;\n }\n const data = {\n ...event.aggregatedStats,\n quality: event.quality,\n } as InboundVideoStats;\n return this.fields\n .map((key) => ({ key, value: data[key as keyof InboundVideoStats] }))\n .filter((r) => !this.elementsToShow().includes(r.key));\n });\n\n readonly fields = [\n 'kalmanBitrate',\n 'bitrateDrop',\n 'runTime',\n 'pixelRatio',\n 'frameHeight',\n 'frameWidth',\n ':-------------',\n 'jitter',\n 'MBytesReceived',\n 'framesDecoded',\n 'framesDropped',\n 'framesReceived',\n 'keyFramesDecoded',\n 'currentRoundTripTime',\n 'packetsLost',\n ':-------------',\n 'quality',\n 'videoCodec',\n 'kind',\n 'type',\n 'codecs',\n 'selectedPair',\n ];\n\n private readonly elementsToShow = signal<string[]>([]);\n private readonly idKey = 'com.source3d.unreal.stat';\n\n private readonly graphListItems: GraphListItem[] = this.fields.map((key) => ({\n key,\n color:\n '#' +\n Math.floor(Math.random() * 16777216)\n .toString(16)\n .padStart(6, '0'),\n stat: computed(() => ({\n value: this.stats()?.aggregatedStats[\n key as keyof InboundVideoStats\n ] as number,\n })),\n }));\n\n readonly graphList = computed(() =>\n this.graphListItems.filter((r) => this.elementsToShow().includes(r.key)),\n );\n\n constructor() {\n this.restoreFromStorage();\n }\n\n toggle() {\n this.collapsed.update((collapsed) => !collapsed);\n this.writeFields();\n }\n\n toggleGraph($event: Event, el: string, value?: unknown) {\n $event.stopPropagation();\n if (\n (value && typeof value !== 'number') ||\n (typeof value === 'number' && isNaN(value))\n ) {\n return;\n }\n this.elementsToShow.update((current) =>\n current.includes(el)\n ? current.filter((item) => item !== el)\n : [...current, el],\n );\n this.writeFields();\n }\n\n private restoreFromStorage() {\n try {\n const { elements, collapsed } =\n JSON.parse(localStorage.getItem(this.idKey) as string) || {};\n this.elementsToShow.set(elements || []);\n this.collapsed.set(collapsed ?? false);\n } catch {\n this.elementsToShow.set([]);\n }\n }\n\n private writeFields() {\n localStorage.setItem(\n this.idKey,\n JSON.stringify({\n collapsed: this.collapsed(),\n elements: this.elementsToShow(),\n }),\n );\n }\n}\n","@if (videoStatus() && viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n [class.min]=\"collapsed()\"\n id=\"aggregatedStats\"\n role=\"button\"\n tabindex=\"0\"\n >\n <div class=\"forNerds\">\n <div\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n class=\"static\"\n role=\"group\"\n tabindex=\"0\"\n >\n <li>\n <app-stat-graph\n [stat]=\"fpsTick()!\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"videoQP()!\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"bitrateTick()!\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList(); track graph.key) {\n <li\n (click)=\"toggleGraph($event, graph.key, 0)\"\n (keydown.enter)=\"toggleGraph($event, graph.key, 0)\"\n class=\"graph\"\n role=\"button\"\n tabindex=\"0\"\n >\n <app-stat-graph\n [label]=\"graph.key\"\n [stat]=\"graph.stat()\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div\n (click)=\"toggleGraph($event, el.key, el.value)\"\n (keydown.enter)=\"toggleGraph($event, el.key, el.value)\"\n class=\"stat\"\n role=\"button\"\n tabindex=\"0\"\n >\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed()) {\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport {\n selectIsExistMatchUrls,\n selectIsLoaderScreenVisible,\n selectShowReconnectPopup,\n selectStreamConfig,\n startStream,\n unrealFeature,\n} from '../../store';\nimport { Store } from '@ngrx/store';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\nimport { DisconnectReason } from '../../interfaces';\n\n@Component({\n selector: 'app-resume-stream-button',\n templateUrl: './resume-stream-button.component.html',\n styleUrl: './resume-stream-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class ResumeStreamButtonComponent {\n readonly #store = inject(Store);\n\n readonly streamConfig = this.#store.selectSignal(selectStreamConfig);\n readonly isSecondStart = signal(\n this.streamConfig()?.autoStart && location.protocol === 'https:',\n );\n readonly isLoaderScreenVisible = this.#store.selectSignal(\n selectIsLoaderScreenVisible,\n );\n readonly showReconnectPopup = this.#store.selectSignal(\n selectShowReconnectPopup,\n );\n readonly isExistMatchUrls = this.#store.selectSignal(selectIsExistMatchUrls);\n readonly showResumeStreamPopup = this.#store.selectSignal(\n unrealFeature.selectShowResumeStreamPopup,\n );\n readonly isShowResumeButton = computed(\n () =>\n this.isLoaderScreenVisible() &&\n this.showReconnectPopup() &&\n this.isExistMatchUrls() &&\n this.showResumeStreamPopup(),\n );\n readonly disconnectReason = this.#store.selectSignal(\n unrealFeature.selectDisconnectReason,\n );\n readonly isAfkDisconnect = computed(() => {\n const disconnectReason = this.disconnectReason();\n return (\n disconnectReason === DisconnectReason.Afk ||\n disconnectReason === DisconnectReason.None\n );\n });\n\n private readonly cirrusConnected = this.#store.selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n\n constructor() {\n let wasConnected = this.cirrusConnected();\n effect(() => {\n const connected = this.cirrusConnected();\n if (!connected && wasConnected) {\n this.disconnect();\n }\n wasConnected = connected;\n });\n }\n\n connect() {\n this.#store.dispatch(startStream({ config: { autoStart: true } }));\n }\n\n disconnect() {\n this.isSecondStart.set(true);\n }\n}\n","@if (isShowResumeButton()) {\n <div class=\"resume-box\">\n @if (isSecondStart()) {\n <div class=\"resume-box__text\">\n Your stream {{ isAfkDisconnect() ? 'has been' : 'is' }} paused due to\n inactivity\n </div>\n }\n\n <src-button\n (onClick)=\"connect()\"\n [isFullWidth]=\"true\"\n [data-testid]=\"'connect-button'\"\n size=\"lg\"\n weight=\"primary\"\n class=\"connect-button\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </src-button>\n </div>\n}\n","import type { ElementRef } from '@angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { NgOptimizedImage } from '@angular/common';\nimport { resetIntroSrc, unrealFeature } from '../../store';\n\n@Component({\n selector: 'app-intro-src',\n templateUrl: './intro-src.component.html',\n styleUrl: './intro-src.component.scss',\n imports: [NgOptimizedImage],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IntroSrcComponent {\n #store = inject(Store);\n\n private readonly videoElement =\n viewChild<ElementRef<HTMLDivElement>>('videoPlayerCover');\n protected imageIntroSrc = this.#store.selectSignal(\n unrealFeature.selectImageIntroSrc,\n );\n protected videoIntroSrc = this.#store.selectSignal(\n unrealFeature.selectVideoIntroSrc,\n );\n private viewportReady = this.#store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n\n constructor() {\n effect(() => {\n const viewportReady = this.viewportReady();\n const videoIntroSrc = this.videoIntroSrc();\n const imageIntroSrc = this.imageIntroSrc();\n untracked(() => {\n if (viewportReady && (videoIntroSrc || imageIntroSrc)) {\n this.#store.dispatch(resetIntroSrc());\n }\n });\n });\n effect(() => {\n const videoElement = this.videoElement();\n const videoIntroSrc = this.videoIntroSrc();\n untracked(() => {\n if (videoElement && videoIntroSrc) {\n this.createVideo(videoIntroSrc, videoElement.nativeElement);\n }\n });\n });\n }\n\n loadingImageError() {\n this.#store.dispatch(resetIntroSrc());\n }\n\n private createVideo(src: string, videoContainer: HTMLDivElement) {\n if (typeof src !== 'string') {\n return;\n }\n const matchAbsolutePath = /.*\\.(mp4|WebM)(\\?.*)?$/i.test(src);\n videoContainer.innerHTML = ''; // This will remove all existing content within the layout\n const videoElement = document.createElement('video');\n videoElement.autoplay = true;\n videoElement.muted = true;\n videoElement.loop = true;\n if (!matchAbsolutePath) {\n videoElement.poster = `${src}/cover.webp`;\n }\n\n videoElement.style.position = 'absolute';\n videoElement.style.width = '100%';\n videoElement.style.height = '100%';\n videoElement.style.objectFit = 'cover';\n\n const sourceElement = document.createElement('source');\n if (matchAbsolutePath) {\n sourceElement.src = src;\n } else {\n sourceElement.src = `${src}/video.mp4`;\n }\n\n sourceElement.type = 'video/mp4';\n videoElement.appendChild(sourceElement);\n\n videoElement.addEventListener('error', () =>\n this.#store.dispatch(resetIntroSrc()),\n );\n sourceElement.addEventListener('error', () =>\n this.#store.dispatch(resetIntroSrc()),\n );\n\n videoContainer.appendChild(videoElement);\n }\n}\n","@let image = imageIntroSrc();\n@if (image) {\n <div class=\"backImage\">\n <img (error)=\"loadingImageError()\" [ngSrc]=\"image\" fill alt=\"imageSrc\" />\n </div>\n} @else if (videoIntroSrc()) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n","import type { ElementRef } from '@angular/core';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n HostListener,\n inject,\n input,\n output,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';\nimport {\n combineLatestWith,\n debounceTime,\n fromEvent,\n merge,\n of,\n switchMap,\n take,\n timer,\n} from 'rxjs';\nimport {\n DevModeService,\n UnrealCommunicatorService,\n VideoService,\n WebRtcPlayerService,\n} from '../../services';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport type { Size } from '@3dsource/utils';\nimport { fpIsASameAsB, Truthy } from '@3dsource/utils';\nimport { Store } from '@ngrx/store';\nimport {\n changeStreamResolutionAction,\n destroyUnrealScene,\n forceResizeViewport,\n initSignalling,\n selectIsExistMatchUrls,\n selectIsFreezeFrameLoading,\n unrealFeature,\n videoAdaptedToContainer,\n videoStreamInitialized,\n} from '../../store';\nimport {\n AUTO_HIGH_RESOLUTION_IDLE_MS,\n DEBOUNCE_TO_MANY_RESIZE_CALLS,\n FULL_HD_HEIGHT,\n FULL_HD_WIDTH,\n MIN_CONTAINER_SIZE,\n SAME_SIZE_THRESHOLD,\n UNREAL_CONFIG,\n} from '../../constants';\nimport {\n getResizeStudioValues,\n getResizeValuesUniversal,\n makeEven,\n} from '../../helpers';\nimport { DisconnectReason } from '../../interfaces';\nimport { AfkTimeoutModalComponent } from '../afk-timeout-modal/afk-timeout-modal.component';\nimport { UnrealStatusComponent } from '../unreal-status/unreal-status.component';\nimport { FreezeFrameComponent } from '../freeze-frame/freeze-frame.component';\nimport { VideoStatsComponent } from '../video-stats/video-stats.component';\nimport { ResumeStreamButtonComponent } from '../resume-stream-button/resume-stream-button.component';\nimport { ImageLoadingSrcComponent } from '../image-loading-src/image-loading-src.component';\nimport { IntroSrcComponent } from '../intro-src/intro-src.component';\nimport { EPayloadVersion, MetaBoxCommand } from '@3dsource/types-unreal';\nimport { Actions, ofType } from '@ngrx/effects';\n\n@Component({\n selector: 'app-unreal-scene',\n templateUrl: './unreal-scene.component.html',\n styleUrl: './unreal-scene.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n AfkTimeoutModalComponent,\n UnrealStatusComponent,\n FreezeFrameComponent,\n VideoStatsComponent,\n ResumeStreamButtonComponent,\n ImageLoadingSrcComponent,\n IntroSrcComponent,\n ],\n})\nexport class UnrealSceneComponent {\n readonly useContainerAsSizeProvider = input(true);\n readonly isStudio = input(false);\n readonly resolutionSize = input<{ width: number; height: number }>({\n width: FULL_HD_WIDTH,\n height: FULL_HD_HEIGHT,\n });\n\n readonly changeMouseOverScene = output<boolean>();\n\n readonly videoElement =\n viewChild<ElementRef<HTMLDivElement>>('videoContainer');\n\n private readonly resolutionValues$ = toObservable(this.resolutionSize);\n private width = FULL_HD_WIDTH;\n private height = FULL_HD_HEIGHT;\n private readonly actions$ = inject(Actions);\n readonly #store = inject(Store);\n private readonly isExistMatchUrls = this.#store.selectSignal(\n selectIsExistMatchUrls,\n );\n readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly isFreezeFrameLoading = this.#store.selectSignal(\n selectIsFreezeFrameLoading,\n );\n private readonly maxResolution = Truthy(\n new URLSearchParams(location.search).get('maxresolution'),\n );\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly videoService = inject(VideoService);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly unrealConfig = inject(UNREAL_CONFIG);\n private autoHighResolution = false;\n\n private get resizeValues() {\n if (this.isStudio()) {\n return this.getResizeStudioValues();\n }\n return this.getResizeValuesUniversal();\n }\n\n private get pixelRatio() {\n return window.devicePixelRatio;\n }\n\n @HostListener('mouseover')\n onMouseOver() {\n this.changeMouseOverScene.emit(true);\n }\n\n @HostListener('mouseout')\n onMouseOut() {\n this.changeMouseOverScene.emit(false);\n }\n\n @HostListener('contextmenu', ['$event'])\n onContextMenu(event: Event) {\n event.preventDefault();\n }\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n // Release the remote connection synchronously, independent of the\n // route-scoped UnrealEffects. provideUnrealModule (effects) is registered\n // per 3D route, so on navigation the route's environment injector — and\n // its UnrealEffects — may be torn down before the\n // `destroyUnrealScene → destroyRemoteConnections` effect chain closes the\n // WebSocket/PeerConnection, which would leak the stream session. We call\n // the same root-singleton method the effect uses, so the two can never\n // drift; it's idempotent, so whichever runs second is a harmless no-op.\n this.webRtcPlayerService.releaseRemoteConnections(\n DisconnectReason.Destroy,\n );\n // State cleanup is reducer-driven, not effect-driven: the\n // `destroyUnrealScene` reducer resets the whole UnrealState to\n // initialState (cirrusConnected/viewportReady/… → false). Reducers run in\n // the root store synchronously on every dispatch, so this is guaranteed\n // even if the route-scoped effects are already torn down — which is what\n // keeps the next 3D route's connect unblocked (connectToSignaling$ gates\n // on `!cirrusConnected`).\n this.#store.dispatch(destroyUnrealScene());\n });\n effect(() => {\n const videoElement = this.videoElement();\n const isExistMatchUrls = this.isExistMatchUrls();\n untracked(() => {\n if (videoElement && isExistMatchUrls) {\n // Set the container before signalling starts: if a prefetched stream\n // is adopted here, VideoService.create() needs the DOM target now\n // (the live flow only reaches create() later, at `config` time, by\n // which point afterNextRender has already set it).\n this.videoService.setContainer(videoElement.nativeElement);\n this.#store.dispatch(initSignalling());\n }\n });\n });\n\n afterNextRender({\n read: () => {\n const videoElement = this.videoElement();\n if (videoElement) {\n this.videoService.setContainer(videoElement.nativeElement);\n this.listenResizeValues();\n this.listenInteractivityForAutoHighResolution(\n videoElement.nativeElement,\n );\n }\n },\n });\n }\n\n private listenInteractivityForAutoHighResolution(target: HTMLElement) {\n if (!this.unrealConfig?.autoHighResolution) {\n return;\n }\n\n // Capture phase + sync dispatch: forceResizeViewport must reach the\n // data channel BEFORE InputService's target-phase listeners on <video>\n // emit any mouse/touch input for this same event.\n const opts = { passive: true, capture: true } as const;\n const interaction$ = merge(\n fromEvent(target, 'mousedown', opts),\n fromEvent(target, 'wheel', opts),\n fromEvent(target, 'touchstart', opts),\n fromEvent(target, 'touchmove', opts),\n );\n\n merge(of(null), interaction$)\n .pipe(\n tap((event) => {\n if (event && this.autoHighResolution) {\n this.autoHighResolution = false;\n this.#store.dispatch(forceResizeViewport());\n }\n }),\n switchMap(() => timer(AUTO_HIGH_RESOLUTION_IDLE_MS)),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(() => {\n if (this.autoHighResolution) {\n return;\n }\n this.autoHighResolution = true;\n this.#store.dispatch(forceResizeViewport());\n });\n }\n\n private listenResizeValues() {\n const customSizeInputChanged$ = this.resolutionValues$.pipe(\n filter(\n ({ width, height }) => this.width !== width || this.height !== height,\n ),\n tap(({ width, height }) => {\n this.width = width;\n this.height = height;\n }),\n );\n\n const resizeRequired$ = merge(\n this.actions$.pipe(ofType(videoStreamInitialized)),\n fromEvent(window, 'resize'),\n );\n\n const videoStreamSizeChanged$ = this.videoService.videoStats$.pipe(\n filter(() => !this.isFreezeFrameLoading()),\n map((stats) => ({\n w: stats.aggregatedStats.frameWidth || 0,\n h: stats.aggregatedStats.frameHeight || 0,\n })),\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD),\n ),\n );\n\n merge(customSizeInputChanged$, resizeRequired$, videoStreamSizeChanged$)\n .pipe(\n debounceTime(DEBOUNCE_TO_MANY_RESIZE_CALLS),\n switchMap(() => {\n const key = Math.random();\n // Poll 3 times to capture late-arriving DOM measurements after layout settles\n return timer(0, 300).pipe(\n take(3),\n map(() => key),\n );\n }),\n map((key) => ({ key, ...this.resizeValues })),\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD) &&\n previous.key === current.key,\n ),\n tap((size) => this.adaptVideo(size)),\n // Key excluded: only dispatch when actual pixel dimensions change\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD),\n ),\n // Holds dispatch until data channel is up; retains true after disconnect\n // so resizes still reach Unreal — cleanup is handled by destroyUnrealScene\n combineLatestWith(\n this.#store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(filter(Truthy)),\n ),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(([size]) => {\n this.#store.dispatch(\n changeStreamResolutionAction({ width: size.w, height: size.h }),\n );\n this.sendResize(size);\n });\n\n this.actions$\n .pipe(ofType(forceResizeViewport), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.sendResize(this.resizeValues));\n }\n\n private adaptVideo(size: Size) {\n const video = this.videoService.video;\n const areaSize = this.resizeValues;\n\n if (video?.style) {\n const pR = this.pixelRatio;\n video.width = makeEven(size.w / pR / areaSize.scale);\n video.height = makeEven(size.h / pR / areaSize.scale);\n\n if (!this.isStudio()) {\n video.style.overflow = 'hidden';\n video.style.objectFit = 'cover';\n video.style.width = `${video.width}px`;\n video.style.height = `${video.height}px`;\n }\n }\n\n this.#store.dispatch(videoAdaptedToContainer());\n }\n\n private getResizeValuesUniversal() {\n let containerWidth = window.innerWidth || MIN_CONTAINER_SIZE;\n let containerHeight = window.innerHeight || MIN_CONTAINER_SIZE;\n\n if (this.useContainerAsSizeProvider()) {\n containerWidth =\n this.videoElement()?.nativeElement.offsetWidth || MIN_CONTAINER_SIZE;\n containerHeight =\n this.videoElement()?.nativeElement.offsetHeight || MIN_CONTAINER_SIZE;\n }\n const pixelRatio = this.pixelRatio;\n\n return getResizeValuesUniversal({\n pixelRatio,\n containerWidth,\n containerHeight,\n maxResolution: this.maxResolution || this.autoHighResolution,\n });\n }\n\n private getResizeStudioValues() {\n const videoElement = this.videoElement()?.nativeElement;\n\n return getResizeStudioValues({\n pixelRatio: this.pixelRatio,\n containerWidth: videoElement?.offsetWidth || MIN_CONTAINER_SIZE,\n containerHeight: videoElement?.offsetHeight || MIN_CONTAINER_SIZE,\n studioWidth: this.width,\n studioHeight: this.height,\n maxResolution: this.maxResolution || this.autoHighResolution,\n });\n }\n\n private sendResize(size: Size) {\n const video = this.videoService.video;\n if (!video) {\n return;\n }\n this.commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FChangeResolutionCommand,\n payload: {\n resolution: { x: size.w, y: size.h },\n payloadVersion: this.isStudio()\n ? EPayloadVersion.disableFovRecalculation\n : undefined,\n },\n });\n }\n}\n","<div class=\"frame unreal-container\">\n <div #videoContainer id=\"player\"></div>\n\n <app-intro-src />\n <app-image-loading-src />\n <app-resume-stream-button />\n <app-unreal-status />\n <app-freeze-frame />\n <app-afk-timeout-modal />\n\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n\n @if (isDevMode) {\n <app-video-stats />\n }\n</div>\n","import type { OnInit } from '@angular/core';\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport type { FilterSettings } from '../../DataFlowConstants';\nimport { DefaultFilterModel, FilterModel } from '../../DataFlowConstants';\n\n@Component({\n selector: 'app-filter-settings',\n templateUrl: './filter-settings.component.html',\n styleUrl: './filter-settings.component.scss',\n imports: [FormsModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FilterSettingsComponent implements OnInit {\n private readonly storageKey = 'LBMFilterSettings';\n readonly defaultFilterModel = { ...DefaultFilterModel };\n settings = { ...DefaultFilterModel };\n\n ngOnInit() {\n const savedSettings = localStorage.getItem(this.storageKey);\n if (savedSettings) {\n this.dispatch(JSON.parse(savedSettings));\n }\n }\n\n togglePanel() {\n this.settings.panelOpen = !this.settings.panelOpen;\n this.saveSettings();\n }\n\n saveSettings() {\n const valid = Object.entries(this.settings).reduce((acc, [key, value]) => {\n return Truthy(value) ? { ...acc, [key]: value } : acc;\n }, {});\n this.dispatch({ ...DefaultFilterModel, ...valid });\n }\n\n dispatch(settings: FilterSettings) {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(settings));\n } catch (e) {\n Logger.error('Storage not available, Error saving filter settings:', e);\n }\n Object.assign(this.settings, settings);\n Object.assign(FilterModel, settings);\n }\n\n reset() {\n this.dispatch({\n ...DefaultFilterModel,\n panelOpen: this.settings.panelOpen,\n });\n }\n}\n","<div class=\"settings-container\">\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\n @if (settings.panelOpen) {\n <div class=\"settings-panel\">\n <h3>LBM Trigger Settings</h3>\n <h5>Data Flow Monitor</h5>\n <form>\n <label>\n Monitoring delay:\n <input\n [(ngModel)]=\"settings.monitoringDelayTime\"\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\n type=\"number\"\n name=\"monitoringDelayTime\"\n />\n </label>\n\n <label>\n Minimum Bitrate (kbit/s):\n <input\n [(ngModel)]=\"settings.minimumBitrate\"\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\n type=\"number\"\n name=\"minimumBitrate\"\n />\n </label>\n <label>\n Yellow Flag (%):\n <input\n [(ngModel)]=\"settings.yellowFlag\"\n [placeholder]=\"defaultFilterModel.yellowFlag\"\n type=\"number\"\n name=\"yellowFlag\"\n />\n </label>\n <label>\n Red Flag (%):\n <input\n [(ngModel)]=\"settings.redFlag\"\n [placeholder]=\"defaultFilterModel.redFlag\"\n type=\"number\"\n name=\"redFlag\"\n />\n </label>\n <label>\n Minimum FPS:\n <input\n [(ngModel)]=\"settings.minimumFps\"\n [placeholder]=\"defaultFilterModel.minimumFps\"\n type=\"number\"\n name=\"minimumFps\"\n />\n </label>\n <hr />\n <h5>Kalman Filter</h5>\n <label>\n Initial Bitrate Estimate (kbit/s):\n <input\n [(ngModel)]=\"settings.initialBitrateEstimate\"\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\n type=\"number\"\n name=\"initialBitrateEstimate\"\n />\n </label>\n <label>\n Initial Error Covariance:\n <input\n [(ngModel)]=\"settings.initialErrorCovariance\"\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\n type=\"number\"\n name=\"initialErrorCovariance\"\n />\n </label>\n <label>\n Process Noise (Q):\n <input\n [(ngModel)]=\"settings.processNoise\"\n [placeholder]=\"defaultFilterModel.processNoise\"\n type=\"number\"\n name=\"processNoise\"\n />\n </label>\n <label>\n Measurement Noise (R):\n <input\n [(ngModel)]=\"settings.measurementNoise\"\n [placeholder]=\"defaultFilterModel.measurementNoise\"\n type=\"number\"\n name=\"measurementNoise\"\n />\n </label>\n </form>\n <br />\n <br />\n <div class=\"apply-button-container\">\n <button (click)=\"reset()\">Reset</button>\n <button (click)=\"saveSettings()\">Apply</button>\n </div>\n </div>\n }\n</div>\n","import { Injectable, signal } from '@angular/core';\nimport { toObservable } from '@angular/core/rxjs-interop';\n\n@Injectable({ providedIn: 'root' })\nexport class LowBandwidthStateService {\n readonly #isLowBandwidth = signal(false);\n\n readonly isLowBandwidth = this.#isLowBandwidth.asReadonly();\n readonly isLowBandwidth$ = toObservable(this.isLowBandwidth);\n\n enterLowBandwidthMode() {\n this.#isLowBandwidth.set(true);\n }\n\n exitLowBandwidthMode() {\n this.#isLowBandwidth.set(false);\n }\n}\n","import type { OnInit } from '@angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n inject,\n signal,\n} from '@angular/core';\nimport { filter, tap } from 'rxjs/operators';\nimport { LowBandwidthModalComponent } from './components/low-bandwidth-modal/low-bandwidth-modal.component';\nimport { Store } from '@ngrx/store';\nimport { Falsy, Logger, Truthy } from '@3dsource/utils';\nimport {\n takeUntilDestroyed,\n toObservable,\n toSignal,\n} from '@angular/core/rxjs-interop';\nimport { unrealFeature } from '../../store';\nimport { Dialog } from '@angular/cdk/dialog';\nimport {\n combineLatestWith,\n concat,\n debounceTime,\n distinctUntilChanged,\n map,\n merge,\n of,\n share,\n skip,\n switchMap,\n take,\n takeUntil,\n timer,\n} from 'rxjs';\nimport { DevModeService, VideoService } from '../../services';\nimport type { Quality } from '../../interfaces';\nimport type { DataFlowCheckResult } from '../../helpers';\nimport { FilterSettingsComponent } from './components/filter-settings/filter-settings.component';\nimport { BITRATE_MONITOR, FilterModel } from './DataFlowConstants';\nimport { LowBandwidthStateService } from './low-bandwidth-state.service';\n\n@Component({\n selector: 'app-low-bandwidth-detector',\n templateUrl: './low-bandwidth-detector.component.html',\n styleUrl: './low-bandwidth-detector.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FilterSettingsComponent],\n})\nexport class LowBandwidthDetectorComponent implements OnInit {\n #store = inject(Store);\n private readonly dialog = inject(Dialog);\n private readonly destroyRef = inject(DestroyRef);\n private readonly videoService = inject(VideoService);\n private readonly lowBandwidthState = inject(LowBandwidthStateService);\n readonly isDevMode = inject(DevModeService).isDevMode;\n\n private readonly viewportReady$ = this.#store.select(\n unrealFeature.selectViewportReady,\n );\n private readonly isLowBandwidth$ = this.lowBandwidthState.isLowBandwidth$;\n private readonly lowBandwidthTrigger$ = this.isLowBandwidth$.pipe(\n distinctUntilChanged(),\n filter(Truthy),\n );\n private readonly highBandwidthTrigger$ = this.isLowBandwidth$.pipe(\n distinctUntilChanged(),\n filter(Falsy),\n );\n\n private readonly viewPortDestroyedTrigger$ = this.viewportReady$.pipe(\n distinctUntilChanged(),\n filter(Falsy),\n );\n\n private readonly aggregatedStats$ = this.videoService.videoStats$.pipe(\n map((data) => data.aggregatedStats),\n share(),\n );\n private readonly nativeQuality$ = this.videoService.videoStats$.pipe(\n map((data) => data.quality),\n );\n\n private readonly monitoringTrigger$ = this.viewportReady$\n .pipe(\n combineLatestWith(this.isLowBandwidth$),\n map(\n ([viewPortReady, isLowBandwidth]) => viewPortReady && !isLowBandwidth,\n ),\n )\n .pipe(share());\n\n private readonly reTrigger$ = this.monitoringTrigger$.pipe(\n map(() => ({ quality: 'lime' as Quality })),\n );\n\n private readonly canSwitchToLowBand$ = this.monitoringTrigger$.pipe(\n debounceTime(100),\n switchMap((canSwitch) =>\n concat(\n of(false),\n timer(FilterModel.monitoringDelayTime).pipe(map(() => canSwitch)),\n ).pipe(take(2), takeUntil(this.monitoringTrigger$)),\n ),\n distinctUntilChanged(),\n share(),\n );\n\n private readonly videoQuality$ = merge(\n this.nativeQuality$,\n this.reTrigger$,\n ).pipe(share(), takeUntil(this.viewPortDestroyedTrigger$));\n\n private readonly fps$ = this.aggregatedStats$.pipe(\n map((data) => data.framesPerSecond || 0),\n );\n\n private readonly bitrateDrop$ = this.aggregatedStats$.pipe(\n map((data) => data.dataFlowCheckResult),\n filter((br) => br.isDropDetected),\n takeUntil(merge(this.viewPortDestroyedTrigger$, this.reTrigger$)),\n );\n\n readonly fps = toSignal(this.fps$, { initialValue: 0 });\n readonly nativeQuality = toSignal(this.nativeQuality$);\n readonly isLowBandwidth = this.lowBandwidthState.isLowBandwidth;\n readonly aggregatedStats = toSignal(this.aggregatedStats$);\n readonly isReducedQuality = signal(false);\n readonly isIndicatorExpanded = signal(false);\n\n readonly isIndicatorExpandedTrigger$ = toObservable(\n this.isIndicatorExpanded,\n ).pipe(skip(1), distinctUntilChanged(), filter(Falsy));\n\n ngOnInit() {\n this.lowBandwidthTrigger$\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.toggleIndicator(true));\n\n merge(this.viewPortDestroyedTrigger$, this.highBandwidthTrigger$)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.isReducedQuality.set(false));\n\n this.canSwitchToLowBand$\n .pipe(\n filter(Truthy),\n tap(() => {\n BITRATE_MONITOR.reset();\n this.isReducedQuality.set(false);\n }),\n switchMap(() => this.bitrateDrop$),\n tap(this.trySetLowBandwidth.bind(this)),\n map((dataFlowResult) => dataFlowResult?.isDropDetected),\n distinctUntilChanged(),\n tap(() => {\n this.isReducedQuality.set(true);\n }),\n switchMap(() => this.videoQuality$),\n filter((quality) => quality === 'lime'),\n tap(() => this.isReducedQuality.set(false)),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe();\n }\n\n private trySetLowBandwidth(dataFlowResult: DataFlowCheckResult) {\n // Evaluate FPS and native quality\n const isFpsLow = this.fps() < FilterModel.minimumFps;\n const isNativeQualityRed = this.nativeQuality() === 'red';\n const shouldSwitch = isNativeQualityRed || isFpsLow;\n\n // Exit if conditions are not met or already in low bandwidth\n if (!shouldSwitch || this.isLowBandwidth()) return;\n\n const { quality, activeMedian } = dataFlowResult;\n const isQualityRed = quality === 'red';\n const isLowBitrate = activeMedian < FilterModel.minimumBitrate;\n\n // Final check for a red drop or low bitrate, or low FPS\n if (isQualityRed || isLowBitrate || isFpsLow) {\n let reason: string;\n\n if (isFpsLow) {\n reason = `FPS < ${FilterModel.minimumFps}`;\n } else if (quality === 'red') {\n reason = `Drop > ${FilterModel.redFlag}%`;\n } else {\n reason = `Speed < ${FilterModel.minimumBitrate}`;\n }\n\n Logger.info(\n `LBM DETECTED: ${reason}, switching to low bandwidth; `,\n dataFlowResult.message,\n {\n stats: {\n dataFlowResult,\n reason,\n triggerTime: this.aggregatedStats()?.runTime ?? 0,\n },\n },\n );\n this.lowBandwidthState.enterLowBandwidthMode();\n }\n }\n\n toggleIndicator(value: boolean) {\n this.isIndicatorExpanded.set(value);\n\n if (value) {\n this.hideIndicatorAfterDelay();\n }\n }\n\n hideIndicatorAfterDelay() {\n timer(3000)\n .pipe(take(1), takeUntil(this.isIndicatorExpandedTrigger$))\n .subscribe(() => this.toggleIndicator(false));\n }\n\n openLBMDialog() {\n this.dialog\n .open(LowBandwidthModalComponent)\n .closed.pipe(filter(Truthy))\n .subscribe(() => {\n this.lowBandwidthState.exitLowBandwidthMode();\n this.toggleIndicator(false);\n });\n }\n}\n","@if (isReducedQuality() || isLowBandwidth()) {\n <div\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\n class=\"lbm-indicator freeze-loader\"\n >\n <button (click)=\"toggleIndicator(true)\" class=\"lbm-icon\" type=\"button\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\n <path\n fill=\"#85888E\"\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n />\n <path\n fill=\"#fff\"\n fill-rule=\"evenodd\"\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n\n <div\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\n class=\"lbm-message\"\n >\n <p class=\"lbm-description\">\n Fluid Interactivity Modes were disabled due to an unstable connection.\n\n <button\n (click)=\"openLBMDialog()\"\n [attr.data-testid]=\"'learn-more-lbm'\"\n type=\"button\"\n class=\"lbm-learn-more\"\n >\n Learn more\n </button>\n </p>\n <button\n (click)=\"toggleIndicator(false)\"\n [attr.data-testid]=\"'close-lbm-indicator'\"\n type=\"button\"\n class=\"lbm-close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\n fill=\"white\"\n />\n </svg>\n </button>\n </div>\n </div>\n}\n\n@if (isDevMode) {\n <app-filter-settings />\n}\n","import { provideState } from '@ngrx/store';\nimport { provideEffects } from '@ngrx/effects';\nimport { UnrealEffects, unrealFeature } from '../store';\nimport {\n AFKService,\n AggregatorService,\n AnalyticsService,\n ConsoleExtensionsService,\n FpsMonitorService,\n FreezeFrameService,\n InputService,\n StreamStatusTelemetryService,\n StreamStatusTelemetryService2,\n} from '../services';\nimport {\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\n\n/**\n * Registers the Unreal NgRx feature state. Call this ONCE at the application\n * root.\n *\n * The streaming services are `providedIn: 'root'` singletons that hold\n * long-lived store subscriptions, so the feature state must live for the whole\n * app lifetime — registering it per-route would tear the slice down on\n * navigation and leave those singletons selecting from missing state.\n */\nexport function provideUnrealState() {\n return makeEnvironmentProviders([provideState(unrealFeature)]);\n}\n\n/**\n * Registers the Unreal effects and boots the streaming engine. Call this at\n * each lazy 3D route (configurator stream/manager, viewer, studio, …).\n *\n * The engine services are `providedIn: 'root'` singletons: navigating between\n * 3D routes reuses one live instance instead of re-instantiating WebRTC /\n * signalling / input listeners (which have no teardown). Their code is still\n * tree-shaken into the lazy route chunk because only these lazy routes import\n * it — so it stays out of the initial bundle.\n *\n * Requires {@link provideUnrealState} and the `UNREAL_CONFIG` value to be\n * provided at the app root.\n */\nexport function provideUnrealModule() {\n return makeEnvironmentProviders([\n provideEffects([UnrealEffects]),\n provideEnvironmentInitializer(() => {\n inject(AggregatorService);\n inject(InputService);\n inject(StreamStatusTelemetryService);\n inject(StreamStatusTelemetryService2);\n inject(ConsoleExtensionsService);\n inject(AFKService);\n inject(FreezeFrameService);\n inject(AnalyticsService);\n inject(FpsMonitorService);\n }),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["map","timeout","switchMap","takeUntil","tap","debounceTime","take","startWith","filter","withLatestFrom","uuidv4","distinctUntilChanged"],"mappings":"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"}
1
+ {"version":3,"file":"3dsource-angular-unreal-module.mjs","sources":["../../../../projects/3dsource/angular-unreal-module/src/lib/constants/buttons-codes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/control-scheme.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/message-type.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/to-client-message-types.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/initial-config.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/input-options.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/CustomCloseCodes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/disconnect-reasons.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/SignalingMessage.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/destroy-disconnect-reasons.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/constants/unreal.constant.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.actions.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.reducer.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.feature.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/sub.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/AnswerHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/ConfigHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/IceCandidateHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/InstanceReadyHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/InstanceReservedHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/PingHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/PlayerCountHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/SSInfoHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnCloseHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnErrorHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OnMessageHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/WsHandlers/OpenHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/keep-max-until-reset.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/data-decoder.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/data-flow-monitor.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/dispatch-resize.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/error-codes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/float-to-smooth-percents.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-image-from-video-stream.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-next-url.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/KalmanFilter1D.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/latency-timings.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/qp-to-quality.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/uint8-to-base64.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/resize-observer.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/make-even.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/get-resize-values.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.selectors.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/webrtc-error-modal/webrtc-error-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/webrtc-error-modal/webrtc-error-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/services/command-telemetry.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/dev-mode.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/regions-ping.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/StreamerListHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/OfferHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/http-to-ws-url.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/create-websocket.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/ForceDisconnect.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/FromStreamerHandlers/OrchestrationErrorHandler.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/signalling.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/DataFlowConstants.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/video.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/web-rtc-player.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-adoption.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/unreal-callback.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/unreal-communicator.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-error-modal/unreal-error-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-error-modal/unreal-error-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/store/unreal/unreal.effects.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/afk.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/loading-progress.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/freeze-frame.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/helpers/deepEqual.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/file-receiver.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/aggregator.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/console-extensions.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/input.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-status-telemetry.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/stream-status-telemetry2.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/interfaces/ReceivedMimeTypes.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/file-handler.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/analytics.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/services/fps-monitor.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/afk-timeout-modal/afk-timeout-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/afk-timeout-modal/afk-timeout-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/freeze-frame/freeze-frame.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/freeze-frame/freeze-frame.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/pipes/safe-html.pipe.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/low-bandwidth-modal/low-bandwidth-modal.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/low-bandwidth-modal/low-bandwidth-modal.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/image-loading-src/image-loading-src.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/image-loading-src/image-loading-src.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/stat-graph/stat-graph.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/stat-graph/stat-graph.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-status/unreal-status.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-status/unreal-status.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/video-stats/video-stats.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/video-stats/video-stats.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/resume-stream-button/resume-stream-button.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/resume-stream-button/resume-stream-button.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/intro-src/intro-src.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/intro-src/intro-src.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-scene/unreal-scene.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/unreal-scene/unreal-scene.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/filter-settings/filter-settings.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/components/filter-settings/filter-settings.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-state.service.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-detector.component.ts","../../../../projects/3dsource/angular-unreal-module/src/lib/components/low-bandwidth/low-bandwidth-detector.component.html","../../../../projects/3dsource/angular-unreal-module/src/lib/providers/index.ts","../../../../projects/3dsource/angular-unreal-module/src/3dsource-angular-unreal-module.ts"],"sourcesContent":["export const SpecialKeyCodes = {\n BackSpace: 8,\n Shift: 16,\n Control: 17,\n Alt: 18,\n RightShift: 253,\n RightControl: 254,\n RightAlt: 255,\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\nexport const MouseButton = {\n MainButton: 0, // Left button.\n AuxiliaryButton: 1, // Wheel button.\n SecondaryButton: 2, // Right button.\n FourthButton: 3, // Browser Back button.\n FifthButton: 4, // Browser Forward button.\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons\nexport const MouseButtonsMask = {\n PrimaryButton: 1, // Left button.\n SecondaryButton: 2, // Right button.\n AuxiliaryButton: 4, // Wheel button.\n FourthButton: 8, // Browser Back button.\n FifthButton: 16, // Browser Forward button.\n};\n","export const ControlScheme = {\n // A mouse can lock inside the WebRTC player, so the user can simply move the\n // mouse to control the orientation of the camera. The user presses the\n // Escape key to unlock the mouse.\n LockedMouse: 0,\n // A mouse can hover over the WebRTC player, so the user needs to click and\n // drag to control the orientation of the camera.\n HoveringMouse: 1,\n Default: 2,\n} as const;\n\nexport type ControlSchemeValues =\n (typeof ControlScheme)[keyof typeof ControlScheme];\n","// Must be kept in sync with PixelStreamingProtocol::EToUE4Msg C++ descriptors.\nexport const MessageType = {\n /*\n * Control Messages. Range = 0..49.\n */\n IFrameRequest: 0,\n RequestQualityControl: 1,\n MaxFpsRequest: 2,\n AverageBitrateRequest: 3,\n StartStreaming: 4,\n StopStreaming: 5,\n LatencyTest: 6,\n RequestInitialSettings: 7,\n\n /*\n * Input Messages. Range = 50..89.\n */\n\n // Generic Input Messages. Range = 50..59.\n UIInteraction: 50,\n Command: 51,\n\n // Keyboard Input Message. Range = 60..69.\n KeyDown: 60,\n KeyUp: 61,\n KeyPress: 62,\n\n // Mouse Input Messages. Range = 70..79.\n MouseEnter: 70,\n MouseLeave: 71,\n MouseDown: 72,\n MouseUp: 73,\n MouseMove: 74,\n MouseWheel: 75,\n\n // Touch Input Messages. Range = 80..89.\n TouchStart: 80,\n TouchEnd: 81,\n TouchMove: 82,\n} as const;\n\nexport type MessageTypeValues = (typeof MessageType)[keyof typeof MessageType];\n","export const ToClientMessage = {\n QualityControlOwnership: 0,\n Response: 1,\n Command: 2,\n FreezeFrame: 3,\n UnfreezeFrame: 4,\n VideoEncoderAvgQP: 5,\n LatencyTest: 6,\n InitialSettings: 7,\n FileExtension: 8,\n FileMimeType: 9,\n FileContents: 10,\n TestEcho: 11,\n InputControlOwnership: 12,\n GamepadResponse: 13,\n Protocol: 255,\n} as const;\n","import { InjectionToken } from '@angular/core';\nimport type { UnrealInitialConfig } from '../interfaces';\n\nexport const UNREAL_CONFIG = new InjectionToken<UnrealInitialConfig>(\n 'Unreal Initial Configuration',\n);\n","import { ControlScheme } from './control-scheme';\nimport type { InputProps } from '../interfaces';\n\nexport const InputOptions: InputProps = {\n controlScheme: ControlScheme.Default,\n suppressBrowserKeys: true,\n};\n","export const WSCloseCode_NORMAL_CLOSURE = 3000;\nexport const WSCloseCode_NORMAL_AFK_TIMEOUT = 3001;\nexport const WSCloseCode_NORMAL_MANUAL_DISCONNECT = 3002;\nexport const WSCloseCode_FORCE_CIRRUS_CLOSE = 3003;\n\nexport const WSCloseCode_UNKNOWN = 1000;\n\nexport const WSCloseCode_CIRRUS_PLAYER_DISCONNECTED = 1001;\nexport const WSCloseCode_CIRRUS_ABNORMAL_CLOSURE = 1006;\nexport const WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR = 1013;\nexport const WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER = 1011;\n\nexport const WSCloseCodes = [\n WSCloseCode_NORMAL_CLOSURE,\n WSCloseCode_NORMAL_AFK_TIMEOUT,\n WSCloseCode_NORMAL_MANUAL_DISCONNECT,\n WSCloseCode_FORCE_CIRRUS_CLOSE,\n WSCloseCode_UNKNOWN,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n] as const;\n\nexport type WSCloseCodesValues = (typeof WSCloseCodes)[number];\n","export const DisconnectReason = {\n Afk: 'Afk',\n None: 'None',\n Destroy: 'Destroy',\n DataChannelClosed: 'DataChannelClosed',\n DataChannelTimeout: 'DataChannelTimeout',\n WebRTCError: 'WebRTCError',\n WebSocketError: 'WebSocketError',\n WebSocketClose: 'WebSocketClose',\n DropConnection: 'DropConnection',\n OrchestrationPlayerDisconnected: 'OrchestrationPlayerDisconnected',\n OrchestrationStreamerDisconnected: 'OrchestrationStreamerDisconnected',\n IceConnectionFailed: 'IceConnectionFailed',\n ReconnectFailed: 'ReconnectFailed',\n NewConnectionAttempt: 'NewConnectionAttempt',\n AbortEstablishingConnection: 'AbortEstablishingConnection',\n} as const;\n\nexport type DisconnectReasonType =\n (typeof DisconnectReason)[keyof typeof DisconnectReason];\n\nexport interface ConnectionError {\n reason: DisconnectReasonType;\n message: string;\n}\n","/*\nexport interface RequestReservation extends InstanceMessageBase {\n type: 'requestReservation';\n}\n*/\n\nimport type { SignalingData } from './SignalingData';\n\nexport const OrchestrationMessageTypes = {\n ping: 'ping',\n error: 'error',\n offer: 'offer',\n answer: 'answer',\n ssInfo: 'ssInfo',\n config: 'config',\n playerCount: 'playerCount',\n iceCandidate: 'iceCandidate',\n streamerList: 'streamerList',\n requestStream: 'requestStream',\n listStreamers: 'listStreamers',\n instanceReady: 'instanceReady',\n p2pEstablished: 'p2pEstablished',\n instanceReserved: 'instanceReserved',\n playerDisconnected: 'playerDisconnected',\n streamPreparedForUserInteraction: 'streamPreparedForUserInteraction',\n streamerDisconnected: 'streamerDisconnected',\n interruptClientStream: 'interruptClientStream',\n} as const;\n\nexport interface InstanceReady extends InstanceMessageBase {\n type: 'instanceReady';\n}\n\nexport interface InstanceReserved extends InstanceMessageBase {\n type: 'instanceReserved';\n}\n\nexport interface OrchestrationErrorMessage {\n type: 'error';\n payload: { code: number; message: string };\n}\n\ninterface InstanceMessageBase extends MessageBase {\n correlationId: string;\n payload: {\n instanceId: string;\n streamRequestId: string;\n eta: number;\n };\n}\n\nexport interface MessageBase {\n type: OrchestrationMessageType;\n}\n\nexport interface SSInfo extends MessageBase {\n type: 'ssInfo';\n message: string;\n data: SignalingData;\n}\n\nexport interface PlayerCountMessage extends MessageBase {\n type: 'playerCount';\n playerCount: number;\n}\nexport interface StreamerListMessage extends MessageBase {\n type: 'streamerList';\n ids: string[];\n}\n\nexport interface ConfigMessage extends MessageBase, UnknownFields {\n type: 'config';\n peerConnectionOptions: RTCConfiguration;\n}\n\nexport interface CandidateMessage extends MessageBase {\n type: 'iceCandidate';\n candidate: RTCIceCandidate;\n}\n\nexport interface PingMessage extends MessageBase {\n type: 'ping';\n playerId: string;\n appConnectionCounter: number;\n}\n\nexport type UnknownFields = Record<string, unknown>;\n\nexport interface InterruptClientStream extends MessageBase {\n type: 'interruptClientStream';\n correlationId: string;\n payload: {\n environmentId: string;\n };\n}\n\nexport interface ForceClientDisconnect extends MessageBase {\n type: 'streamerDisconnected' | 'playerDisconnected';\n connectionId: string;\n}\n\nexport interface ListStreamersMessage extends MessageBase {\n type: 'listStreamers';\n correlationId: string;\n}\n\nexport interface P2PEstablishedMessage extends MessageBase {\n type: 'p2pEstablished';\n source: string;\n sessionId: string;\n}\n\nexport interface streamPreparedForUserInteractionMessage extends MessageBase {\n type: 'streamPreparedForUserInteraction';\n correlationId: string;\n}\n\nexport interface RequestStream extends MessageBase {\n type: 'requestStream';\n correlationId: string;\n payload: {\n environmentId: string;\n region?: string;\n /**\n * The context field is used for plugins of the external\n * applications for collecting additional statistics, etc.\n */\n context: StreamRequestContext;\n };\n}\n\ninterface MetaboxBasicConfiguratorContext {\n id: 'metaboxBasicConfigurator';\n data: {\n configuratorId: string;\n };\n}\n\ninterface MetaboxModularConfiguratorContext {\n id: 'metaboxModularConfigurator';\n data: {\n configuratorId: string;\n };\n}\n\ninterface MetaboxProductContext {\n id: 'metaboxProduct';\n data: {\n productId: string;\n };\n}\n\ninterface MetaboxEnvironmentContext {\n id: 'metaboxEnvironment';\n data: {\n environmentId: string;\n };\n}\ninterface MetaboxStudioContext {\n id: 'metaboxStudio';\n data: {\n userId: string;\n workspaceId: string;\n };\n}\ninterface CustomApplicationContext {\n id: 'customApplication';\n data: {\n clientId: string;\n applicationId: string;\n };\n}\n\ninterface MetaboxCustomApplicationContext {\n id: 'metaboxCustomApplication';\n data: {\n clientId: string;\n };\n}\n\nexport type StreamRequestContext =\n | MetaboxStudioContext\n | MetaboxProductContext\n | CustomApplicationContext\n | MetaboxCustomApplicationContext\n | MetaboxEnvironmentContext\n | MetaboxBasicConfiguratorContext\n | MetaboxModularConfiguratorContext;\n\nexport interface SignalingMessageMap {\n [OrchestrationMessageTypes.ping]: PingMessage;\n [OrchestrationMessageTypes.offer]: RTCSessionDescriptionInit;\n [OrchestrationMessageTypes.error]: OrchestrationErrorMessage;\n [OrchestrationMessageTypes.ssInfo]: SSInfo;\n [OrchestrationMessageTypes.config]: ConfigMessage;\n [OrchestrationMessageTypes.answer]: RTCSessionDescriptionInit;\n [OrchestrationMessageTypes.playerCount]: PlayerCountMessage;\n [OrchestrationMessageTypes.iceCandidate]: CandidateMessage;\n [OrchestrationMessageTypes.streamerList]: StreamerListMessage;\n [OrchestrationMessageTypes.instanceReady]: InstanceReady;\n [OrchestrationMessageTypes.requestStream]: RequestStream;\n [OrchestrationMessageTypes.listStreamers]: ListStreamersMessage;\n [OrchestrationMessageTypes.p2pEstablished]: P2PEstablishedMessage;\n [OrchestrationMessageTypes.instanceReserved]: InstanceReserved;\n [OrchestrationMessageTypes.playerDisconnected]: ForceClientDisconnect;\n [OrchestrationMessageTypes.streamPreparedForUserInteraction]: streamPreparedForUserInteractionMessage;\n [OrchestrationMessageTypes.streamerDisconnected]: ForceClientDisconnect;\n [OrchestrationMessageTypes.interruptClientStream]: InterruptClientStream;\n}\n\nexport type OrchestrationMessageType = keyof SignalingMessageMap;\n\n// New strict outbound union type (only valid signaling messages allowed)\nexport type AnySignalingMessage =\n SignalingMessageMap[OrchestrationMessageType] | string;\n\nexport type SignalingMessageHandler<T extends keyof SignalingMessageMap> = (\n msg: SignalingMessageMap[T],\n) => void;\n\nexport interface PollingOrchestrationMessage {\n mm_message?: string;\n signallingServer?: string;\n error?: string;\n info?: {\n age: number | null;\n left: number | null;\n percent: number | null;\n total: number | null;\n };\n}\n","import type { DisconnectReasonType } from '../interfaces';\nimport { DisconnectReason } from '../interfaces';\n\n/** Disconnect reasons that should trigger remote connection cleanup. */\nexport const DESTROY_DISCONNECT_REASONS: DisconnectReasonType[] = [\n DisconnectReason.Afk,\n DisconnectReason.DropConnection,\n DisconnectReason.WebRTCError,\n DisconnectReason.WebSocketError,\n DisconnectReason.WebSocketClose,\n DisconnectReason.ReconnectFailed,\n DisconnectReason.DataChannelClosed,\n DisconnectReason.DataChannelTimeout,\n DisconnectReason.OrchestrationPlayerDisconnected,\n DisconnectReason.OrchestrationStreamerDisconnected,\n];\n","export const DEBOUNCE_TO_MANY_RESIZE_CALLS = 100;\nexport const AUTO_HIGH_RESOLUTION_IDLE_MS = 5000;\nexport const SAME_SIZE_THRESHOLD = 1.01;\n// Minimum container dimension in px — prevents division by zero in resize calculations\nexport const MIN_CONTAINER_SIZE = 2;\nexport const MINIMAL_FPS = 6;\nexport const STREAMING_VIDEO_ID = 'streamingVideo';\nexport const STREAMING_AUDIO_ID = 'streamingAudio';\nexport const FULL_HD_WIDTH = 1920;\nexport const FULL_HD_HEIGHT = 1080;\n// Bound on a single WS upgrade attempt (`createWebSocket`). On cold\n// connections the TCP+TLS+WS handshake can legitimately take 3-5 s\n// (cold DNS, TLS session miss). 2 s was too aggressive — first\n// attempts kept timing out and the second attempt (with warm caches)\n// would connect in <500 ms. 10 s gives slow networks room without\n// letting a truly hung handshake hold up `connectToCirrus` forever.\nexport const WS_TIMEOUT = 6000;\nexport const POLLING_TIME = 4000;\n// Staged retry policy for `SignallingService.connectToSignaling`:\n// INNER_RETRY_LIMIT = max number of WS+orchestration attempts before\n// the pipeline gives up on the current region and bubbles the error\n// to the outer retry. URL rotation (`urlGen`) advances across these.\n// OUTER_RETRY_DELAY = backoff between region re-picks. Intentionally\n// longer than POLLING_TIME so region discovery is rare relative to\n// WS retries.\nexport const INNER_RETRY_LIMIT = 3;\nexport const OUTER_RETRY_DELAY = POLLING_TIME * 2;\n// Extra WS-only retries on the SAME wsUrl (cached AwsInstance) BEFORE\n// falling through to a URL-rotating retry that re-polls orchestration.\n// Why: a fresh `default` poll asks orchestrator to RESERVE a new\n// instance — the previous reservation is orphaned (server-side leak).\n// One quick same-wsUrl retry catches transient WS failures (network\n// blip, brief unavailability) without burning a second reservation.\n// Total WS attempts before URL rotation = 1 + WS_RETRY_PER_INSTANCE.\nexport const WS_RETRY_PER_INSTANCE = 1;\nexport const WS_OPEN_STATE = 1;\nexport const DEFAULT_AFK_TIMEOUT_PERIOD = 15;\nexport const DEFAULT_AFK_TIMEOUT = 300; // 5 minutes\nexport const DATA_CHANNEL_CONNECTION_TIMEOUT = 8000; //ms;\nexport const SIGNALLING_PERCENT_VALUE = 56;\nexport const SCREEN_LOCKER_CONTAINER_ID = '3dsource_start_screen';\n\n// Region-ping prefetch cache. A standalone script\n// (`src/js/region-ping-prefetch.js`) pings the regions the same way\n// `RegionsPingService` does and stores the winner here, so the service can\n// skip live pinging right before a connection. The script CANNOT import these\n// constants (it is framework-free, loaded straight into the host page), so it\n// hardcodes the same literals — keep all three in sync if you change them.\nexport const REGION_PING_CACHE_KEY = '3dsource:region-ping';\n// 1 month. Beyond this the cached winner is considered stale and the service\n// falls back to live pinging.\nexport const REGION_PING_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n// Accurate (background / prefetch) measurement: number of post-warm-up probes\n// per region. The winner is chosen by the MEDIAN of these (tie-break: min),\n// which is robust to jitter — unlike the fast `getFastest` race that just\n// takes the first region to finish.\nexport const REGION_PING_ACCURATE_SAMPLES = 3;\n// Upper bound on the parallel warm-up phase (DNS/TCP/TLS for every region at\n// once). Generous on purpose: warm-up runs OFF the connection critical path\n// (page-load prefetch + post-connection refresh), so accuracy beats speed —\n// a slow-cold-start region must finish warming before it is measured, else it\n// is unfairly penalised (e.g. a 737 ms cold start hiding a 34 ms real RTT).\nexport const REGION_PING_WARMUP_DEADLINE_MS = 1500;\n// Delay after the data channel is ready before the background accurate refresh\n// runs — lets the stream stabilise so the ping sweep does not compete with the\n// freshly-started media for bandwidth.\nexport const REGION_PING_BACKGROUND_REFRESH_DELAY_MS = 5000;\n\n// Reconnection defaults\nexport const RECONNECT_CONFIG = {\n enabled: true,\n maxAttempts: 3,\n delayMs: 1000,\n} as const;\n\nexport const UnrealStatusMessage = {\n CONNECTING_TO_SESSION: 'Connecting to session.',\n STARTING_YOUR_SESSION: 'Starting your session',\n} as const;\n","import { createAction, props } from '@ngrx/store';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport type {\n DisconnectReasonType,\n SignalingData,\n StreamConfig,\n StreamRequestContext,\n} from '../../interfaces';\n\nconst scoped = (templateString: TemplateStringsArray) =>\n `[UNREAL] ${templateString[0]}`;\n\n/**\n * Raw JSON from Unreal can either be wrapped in `commandCallback`\n * (e.g. `{ commandCallback: { command: '...', correlationId: '...' } }`)\n * or be a direct command/event object (e.g. `{ command: 'cameraChanged', payload: {...} }`).\n */\nexport interface UnrealCallbackJsonWrapped {\n commandCallback: MetaBoxCommandPacket;\n timeStamp?: unknown;\n}\n\nexport type UnrealCallbackJson =\n UnrealCallbackJsonWrapped | MetaBoxCommandPacket;\n\nexport const unrealCommandCallback = createAction(\n scoped`unreal command callback`,\n props<{ json: UnrealCallbackJson }>(),\n);\nexport const commandStarted = createAction(\n scoped`command started`,\n props<{ id: string; command: string; timeStamp: number }>(),\n);\nexport const commandCompleted = createAction(\n scoped`command completed`,\n props<{ id: string; now: number }>(),\n);\n\nexport const trackMixpanelEvent = createAction(\n scoped`track Mixpanel event`,\n props<{ event: string; data?: unknown }>(),\n);\nexport const trackTelemetryData = createAction(\n scoped`track telemetry data`,\n props<{ event: string; data?: unknown }>(),\n);\nexport const setMaxFps = createAction(\n scoped`change fps`,\n props<{ maxFps: number }>(),\n);\nexport const destroyRemoteConnections = createAction(\n scoped`destroyRemoteConnections`,\n props<{ reason: DisconnectReasonType }>(),\n);\nexport const destroyUnrealScene = createAction(scoped`destroyUnrealScene`);\nexport const setCirrusConnected = createAction(scoped`cirrusConnected`);\nexport const setCirrusDisconnected = createAction(scoped`cirrusDisconnected`);\nexport const changeStatusMainVideoOnScene = createAction(\n scoped`change status main video on scene`,\n props<{ isVideoPlaying: boolean }>(),\n);\nexport const setAwsInstance = createAction(\n scoped`set aws instance`,\n props<{\n wsUrl: string | null;\n pollingUrl: string | null;\n instanceName: string | null;\n }>(),\n);\nexport const setStatusMessage = createAction(\n scoped`set status message`,\n props<{ statusMessage: string | null }>(),\n);\nexport const setStatusPercentSignallingServer = createAction(\n scoped`change status percent signalling server`,\n props<{ percent: number | null }>(),\n);\nexport const setFreezeFrame = createAction(\n scoped`set freeze frame`,\n props<{\n dataUrl: string | null;\n progress: number | null;\n }>(),\n);\nexport const setStreamClientCompanyId = createAction(\n scoped`set stream client company id`,\n props<{ id: string }>(),\n);\nexport const setStreamViewId = createAction(\n scoped`set stream view id`,\n props<{ id: string }>(),\n);\nexport const setIntroImageSrc = createAction(\n scoped`set intro image src`,\n props<{ src: string }>(),\n);\n\nexport const setLoadingImageSrc = createAction(\n scoped`set loading image src`,\n props<{ src: string }>(),\n);\nexport const setIntroVideoSrc = createAction(\n scoped`set intro video src`,\n props<{ src: string }>(),\n);\nexport const resetIntroSrc = createAction(scoped`reset intro src`);\nexport const setFreezeFrameFromVideo = createAction(\n scoped`set freeze frame from video`,\n props<{\n dataUrl: string | null;\n progress: number | null;\n }>(),\n);\nexport const setEstablishingConnection = createAction(\n scoped`set establishing connection`,\n props<{ value: boolean }>(),\n);\nexport const dataChannelConnected = createAction(\n scoped`data channel connected`,\n props<{ statusMessage: string }>(),\n);\nexport const dataChannelReady = createAction(scoped`dataChannelReady`);\nexport const setConfig = createAction(\n scoped`set config`,\n props<{ config: Partial<StreamConfig> }>(),\n);\nexport const disconnectStream = createAction(\n scoped`disconnectStream`,\n props<{\n reason: DisconnectReasonType;\n message: string;\n }>(),\n);\nexport const dropConnection = createAction(scoped`dropConnection`);\nexport const setViewportReady = createAction(scoped`set viewport ready`);\nexport const setViewportNotReady = createAction(scoped`set viewport not ready`);\nexport const changeStreamResolutionAction = createAction(\n scoped`change stream resolution`,\n props<{\n width: number | null;\n height: number | null;\n }>(),\n);\nexport const setSignalingName = createAction(\n scoped`set aws instanceName`,\n props<{ instanceName: string }>(),\n);\nexport const setOrchestrationParameters = createAction(\n scoped`set orchestration parameters`,\n props<{ instanceName: string; streamRequestId: string; eta: number }>(),\n);\n/**\n * Dispatched when the orchestration server signals that the reserved\n * instance is ready to serve the stream (`instanceReady` WS message).\n * Emitted for observability only — no reducer state change.\n */\nexport const instanceReady = createAction(scoped`instance ready`);\n/**\n * Dispatched when `RegionsPingService.getFastest()` begins — right\n * before the region-list HTTP request goes out. Bookends the entire\n * region-discovery flow together with {@link regionResolved}.\n * Observability-only — no state change.\n */\nexport const regionPingFetchStart = createAction(\n scoped`region ping fetch start`,\n);\n/**\n * Dispatched once `RegionsPingService.getProviders()` returns the region\n * list — i.e., the fetch step is done and the actual per-region ping\n * sweep is about to start. Splits the region-discovery waterfall into\n * two legs: config fetch vs. ping sweep. Observability-only.\n */\nexport const regionPingFetchEnd = createAction(scoped`region ping fetch end`);\n/**\n * Dispatched once the closest region has been resolved by the\n * regions-ping service. Carries every sampled ping RTT to the winning\n * region (one entry per probe — `checkLatency` issues `ping_count`\n * sequential pings per region) so consumers can inspect variance /\n * jitter, not just the mean. Observability-only — no state change.\n */\nexport const regionResolved = createAction(\n scoped`region resolved`,\n props<{\n region: string;\n pingsMs: number[];\n }>(),\n);\n/**\n * Dispatched around the HTTP polling roundup inside `getAwsInstance`\n * (old orchestration flow). Only fires when polling is actually used\n * (i.e., signaling URL is not a direct `ws://` / `wss://` endpoint).\n * Observability-only — no state change.\n */\nexport const pollingStarted = createAction(scoped`polling started`);\nexport const pollingEnded = createAction(scoped`polling ended`);\n/**\n * Dispatched once for every `retry()` attempt inside the signalling\n * connect pipeline. Two kinds:\n *\n * - `'connect'` — outer retry around the whole connect pipeline\n * (region ping → AWS instance → WebSocket). Fires when the WS\n * errors (e.g. \"WebSocket closed before open\") and the entire\n * pipeline is re-subscribed. See `SIGNALLING.md` — every one of\n * these currently triggers a fresh region-ping storm.\n * - `'orchestration'` — inner retry inside `getAwsInstance`,\n * advancing `urlGen` to the next candidate signalling URL when\n * polling fails or returns an error payload.\n *\n * Observability-only — no state change. Surfaces in the viewer's\n * Anomalies table as `signaling_retry` rows so a session that\n * needed N tries shows N entries with their reasons.\n */\nexport const signalingRetryAttempted = createAction(\n scoped`signaling retry attempted`,\n props<{\n attempt: number;\n reason: string;\n // `ws-retry` — WS-only retry on the SAME wsUrl (cached AwsInstance);\n // does NOT re-poll orchestration → no orphaned reservation.\n // `connect` — full inner retry: urlGen rotates → new orchestration poll.\n // `orchestration` — legacy; kept for store-compat.\n // `region-cycle` — outer retry: `getRegion()` re-pinged.\n kind: 'ws-retry' | 'connect' | 'orchestration' | 'region-cycle';\n }>(),\n);\n/**\n * Dispatched when the client has just sent an SDP answer back to Cirrus\n * after receiving the server-initiated offer. Observability-only.\n */\nexport const answerSent = createAction(scoped`answer sent`);\nexport const setOrchestrationMessage = createAction(\n scoped`set orchestration message`,\n props<{ message: string }>(),\n);\nexport const setOrchestrationProgress = createAction(\n scoped`set orchestration progress`,\n props<{ progressComplete: number }>(),\n);\nexport const setOrchestrationContext = createAction(\n scoped`set orchestration params`,\n props<{\n urls: string[];\n environmentId: string;\n streamRequestContext: StreamRequestContext;\n }>(),\n);\nexport const updateCirrusInfo = createAction(\n scoped`set unrealInfo`,\n props<{ ssData: SignalingData }>(),\n);\nexport const setLoopBackCommandIsCompleted = createAction(\n scoped`set loopBack command is completed`,\n);\nexport const setAfkTimerVisible = createAction(scoped`set afk timer visible`);\nexport const setAfkTimerHide = createAction(scoped`set afk timer hide`);\nexport const setAfkTimerCountdown = createAction(\n scoped`set afk timer count down`,\n props<{ countdown: number }>(),\n);\nexport const showUnrealErrorMessage = createAction(\n scoped`show unreal error message`,\n props<{ code: number | null; error?: string }>(),\n);\nexport const initSignalling = createAction(scoped`init signalling`);\n/**\n * Dispatched when a prefetched connection parked on `window.__stream` by the\n * `stream-prefetch.js` head-script is adopted instead of opening a fresh\n * `connectToSignaling`. Marks cirrus connected and records the adopted machine\n * in one transaction; the data channel / app-init chain then proceeds via\n * `dataChannelConnected` dispatched from `WebRtcPlayerService`.\n *\n * Deliberately does NOT touch `streamClientCompanyId` / `streamViewId`: the host\n * app (e.g. metabox) sets those authoritatively from its own data before\n * `initSignalling`, and the prefetch script's ids are connection-internal only.\n */\nexport const streamAdopted = createAction(\n scoped`stream adopted`,\n props<{\n machineId: string | null;\n ssData: SignalingData | null;\n /**\n * `performance.now()` marks the prefetch script recorded while it\n * established the connection (`prefetch_start` / `ws_open` / `dc_open` /\n * `ready`), on the page navigation timeline. The telemetry service uses\n * them to attribute the signaling / webrtc phase durations to the time the\n * prefetch actually spent — instead of dumping the whole pre-adoption wait\n * onto whichever phase closer happens to fire first. `null` when adopting a\n * stream that carried no timings.\n */\n timings: Record<string, number> | null;\n }>(),\n);\nexport const startStream = createAction(\n scoped`startStream`,\n props<{ config: Partial<StreamConfig> }>(),\n);\nexport const resetConfig = createAction(scoped`reset config`);\nexport const resetAfk = createAction(scoped`reset afk action`);\nexport const resetWarnTimeout = createAction(scoped`reset config warn timeout`);\n/**\n * Fan-in for \"cancel an in-flight signalling attempt\". Dispatched by the\n * abortEstablishingConnection$ effect whenever any of these source actions\n * fire: `setCirrusDisconnected` (cirrus dropped), `dropConnection` (user\n * called drop), `destroyUnrealScene` (component teardown). Consumers\n * (`SignallingService.abort$`, `setDataChannelTimeoutCheck$.abort$`) listen\n * to this one action instead of the trio so the \"abort\" intent has a single\n * named entry in Redux DevTools and one subscription site to update.\n */\nexport const abortEstablishingConnection = createAction(\n scoped`abortEstablishingConnection`,\n);\nexport const setUnrealPlaywrightConfig = createAction(\n scoped`set unreal playwright config`,\n);\nexport const saveAnalyticsEvent = createAction(\n scoped`save analytics event`,\n props<{ event: { name: string; params: Record<string, unknown> } }>(),\n);\n/** Action to trigger WebRTC peer reconnection (keeps signaling connection) */\nexport const reconnectPeer = createAction(\n scoped`reconnect peer`,\n props<{ attempt: number; maxAttempts: number; delay?: number }>(),\n);\n/** Action to reset the data channel state before reconnection */\nexport const resetDataChannelForReconnect = createAction(\n scoped`reset data channel for reconnect`,\n);\n/** Action dispatched when peer reconnection succeeds */\nexport const reconnectPeerSuccess = createAction(\n scoped`reconnect peer success`,\n);\n/** Action dispatched when all peer reconnection attempts are exhausted */\nexport const reconnectPeerFailed = createAction(\n scoped`reconnect peer failed`,\n props<{ reason: string }>(),\n);\n/** Action dispatched when ICE connection state changes to failed/disconnected */\nexport const iceConnectionFailed = createAction(\n scoped`ice connection failed`,\n props<{ state: RTCIceConnectionState }>(),\n);\nexport const forceResizeViewport = createAction(scoped`force resize viewport`);\nexport const videoAdaptedToContainer = createAction(\n scoped`video adapted to container`,\n);\nexport const videoStreamInitialized = createAction(\n scoped`video stream initialized`,\n);\nexport const dropDC = createAction(scoped`drop data channel`);\nexport const dropPC = createAction(scoped`drop peer connection`);\nexport const showLoadingProgress = createAction(\n scoped`show loading progress`,\n props<{ visible: boolean }>(),\n);\nexport const showResumeStreamPopup = createAction(\n scoped`show resume stream popup`,\n props<{ visible: boolean }>(),\n);\nexport const showUserInactivityTimeoutPopup = createAction(\n scoped`show user inactivity timeout popup`,\n props<{ visible: boolean }>(),\n);\nexport const setUserInactivityTimeout = createAction(\n scoped`set user inactivity timeout`,\n props<{ timeout: number }>(),\n);\nexport const resetUserInactivityTimeout = createAction(\n scoped`reset user inactivity timeout`,\n);\n","import {\n changeStatusMainVideoOnScene,\n changeStreamResolutionAction,\n commandCompleted,\n commandStarted,\n dataChannelConnected,\n destroyUnrealScene,\n disconnectStream,\n dropConnection,\n initSignalling,\n reconnectPeerSuccess,\n resetConfig,\n resetDataChannelForReconnect,\n resetIntroSrc,\n resetWarnTimeout,\n saveAnalyticsEvent,\n setAfkTimerCountdown,\n setAfkTimerHide,\n setAfkTimerVisible,\n setAwsInstance,\n setCirrusConnected,\n setCirrusDisconnected,\n setConfig,\n setEstablishingConnection,\n setFreezeFrame,\n setFreezeFrameFromVideo,\n setIntroImageSrc,\n setIntroVideoSrc,\n setLoadingImageSrc,\n setLoopBackCommandIsCompleted,\n setOrchestrationContext,\n setOrchestrationMessage,\n setOrchestrationParameters,\n setOrchestrationProgress,\n setSignalingName,\n setStatusMessage,\n setStatusPercentSignallingServer,\n setStreamClientCompanyId,\n setStreamViewId,\n setUnrealPlaywrightConfig,\n setUserInactivityTimeout,\n setViewportNotReady,\n setViewportReady,\n showLoadingProgress,\n showResumeStreamPopup,\n showUserInactivityTimeoutPopup,\n startStream,\n streamAdopted,\n updateCirrusInfo,\n} from './unreal.actions';\nimport { createReducer, on } from '@ngrx/store';\nimport { whereNot } from '@3dsource/utils';\nimport type {\n AwsInstance,\n ConnectionError,\n DisconnectReasonType,\n FreezeFrameMessage,\n SignalingData,\n StreamConfig,\n StreamRequestContext,\n StreamResolutionProps,\n} from '../../interfaces';\nimport { DisconnectReason } from '../../interfaces';\nimport { DEFAULT_AFK_TIMEOUT } from '../../constants';\n\nconst COMMAND_EXILE_TIMEOUT_MS = 10_000;\n\nexport interface CommandInProgress {\n timeStamp: number;\n command: string;\n id: string;\n}\n\nfunction exileExpiredCommands(\n commandsInProgress: CommandInProgress[],\n idToRemove: string,\n now: number,\n): { commandsInProgress: CommandInProgress[]; exiled: number } {\n let remaining = commandsInProgress.filter(whereNot({ id: idToRemove }));\n const expired = remaining.filter(\n ({ timeStamp }) => now - timeStamp > COMMAND_EXILE_TIMEOUT_MS,\n );\n if (expired.length) {\n const expiredIds = new Set(expired.map(({ id }) => id));\n remaining = remaining.filter(({ id }) => !expiredIds.has(id));\n }\n return { commandsInProgress: remaining, exiled: expired.length };\n}\n\nexport interface UnrealState {\n streamConfig: StreamConfig;\n userInactivityTimeout: number;\n awsInstance: AwsInstance;\n isFirstSuccessLoad: boolean;\n isAfkTimerVisible: boolean;\n afkCountdown: number;\n cirrusConnected: boolean;\n /**\n * True once a prefetched connection has been adopted (`streamAdopted`).\n * Read synchronously by the telemetry service so the connection-phase\n * closers know to defer to the prefetch-timed attribution instead of the\n * live-event one. Reset on every fresh attempt / disconnect.\n */\n adopted: boolean;\n viewportReady: boolean;\n freezeFrameFromVideo: FreezeFrameMessage;\n freezeFrame: FreezeFrameMessage;\n statusMessage: string | null;\n ssData: SignalingData | null;\n statusPercentSignallingServer: number | null;\n errorMessage: ConnectionError | null;\n isReconnecting: boolean;\n dataChannelConnected: boolean;\n streamResolution: StreamResolutionProps;\n isVideoPlaying: boolean;\n establishingConnection: boolean;\n disconnectReason: DisconnectReasonType;\n matchUrls: string[];\n environmentId: string | null;\n streamClientCompanyId: string | null;\n streamViewId: string | null;\n videoIntroSrc: string | null;\n imageIntroSrc: string | null;\n imageLoadingSrc: string;\n streamRequestContext: StreamRequestContext | null;\n analyticsEvent: { name: string; params: Record<string, unknown> } | null;\n showLoadingProgress: boolean;\n showResumeStreamPopup: boolean;\n showAfkTimeoutPopup: boolean;\n // Command tracking — drives `selectCommandProgress` (% of loading bar).\n commandsInProgress: CommandInProgress[];\n totalCommandsStarted: number;\n totalCommandsCompleted: number;\n}\n\nconst initialState: UnrealState = {\n streamRequestContext: null,\n environmentId: null,\n isFirstSuccessLoad: false,\n isAfkTimerVisible: false,\n afkCountdown: 0,\n cirrusConnected: false,\n adopted: false,\n establishingConnection: false,\n isReconnecting: false,\n viewportReady: false,\n dataChannelConnected: false,\n isVideoPlaying: false,\n statusPercentSignallingServer: null,\n statusMessage: null,\n errorMessage: null,\n ssData: null,\n streamResolution: { width: null, height: null },\n freezeFrameFromVideo: { dataUrl: null, progress: null },\n freezeFrame: { dataUrl: null, progress: null },\n disconnectReason: DisconnectReason.None,\n awsInstance: {\n wsUrl: null,\n instanceName: null,\n pollingUrl: null,\n progressComplete: 0,\n },\n streamConfig: {\n autoStart: true,\n warnTimeout: DEFAULT_AFK_TIMEOUT,\n },\n userInactivityTimeout: DEFAULT_AFK_TIMEOUT,\n matchUrls: [],\n streamClientCompanyId: '',\n streamViewId: 'default',\n videoIntroSrc: null,\n imageIntroSrc: null,\n imageLoadingSrc: '',\n analyticsEvent: null,\n showLoadingProgress: true,\n showResumeStreamPopup: true,\n showAfkTimeoutPopup: true,\n commandsInProgress: [],\n totalCommandsStarted: 0,\n totalCommandsCompleted: 0,\n};\nexport const unrealReducer = createReducer(\n initialState,\n on(changeStatusMainVideoOnScene, (state, { isVideoPlaying }): UnrealState => {\n return { ...state, isVideoPlaying };\n }),\n on(\n setAwsInstance,\n (state, { instanceName, wsUrl, pollingUrl }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n instanceName,\n wsUrl,\n pollingUrl,\n progressComplete: 0,\n },\n };\n },\n ),\n on(setViewportReady, (state): UnrealState => {\n return {\n ...state,\n viewportReady: true,\n statusMessage: null,\n errorMessage: null,\n };\n }),\n on(setViewportNotReady, (state): UnrealState => {\n return { ...state, viewportReady: false };\n }),\n on(updateCirrusInfo, (state, { ssData }): UnrealState => {\n return { ...state, ssData: ssData };\n }),\n on(changeStreamResolutionAction, (state, { width, height }): UnrealState => {\n if (\n !width ||\n !height ||\n (state.streamResolution.width === width &&\n state.streamResolution.height === height)\n ) {\n return state;\n }\n return { ...state, streamResolution: { width, height } };\n }),\n on(setFreezeFrame, (state, freezeFrame): UnrealState => {\n return {\n ...state,\n freezeFrame: {\n dataUrl:\n freezeFrame.progress === 0 ||\n freezeFrame.progress === 1 ||\n freezeFrame.progress === null\n ? freezeFrame.dataUrl\n : state.freezeFrame.dataUrl,\n progress: freezeFrame.progress ?? null,\n },\n };\n }),\n on(disconnectStream, (state, errorMessage): UnrealState => {\n // Skip user-explicit destroy: the user already initiated cleanup, no\n // disconnect message should overwrite that intent.\n if (state.disconnectReason === DisconnectReason.Destroy) {\n return state;\n }\n // The first non-None reason wins, so the resume popup keeps showing the\n // original cause (e.g. 'Afk' isn't overwritten by 'DataChannelClosed'\n // when the AFK teardown closes the channel). Cleanup effects still run\n // on every disconnectStream dispatch — only the state stays pinned.\n const disconnectReason =\n state.disconnectReason === DisconnectReason.None\n ? errorMessage.reason\n : state.disconnectReason;\n return { ...state, errorMessage, statusMessage: null, disconnectReason };\n }),\n on(setFreezeFrameFromVideo, (state, freezeFrameFromVideo): UnrealState => {\n return {\n ...state,\n freezeFrameFromVideo: {\n dataUrl: freezeFrameFromVideo.dataUrl,\n progress: freezeFrameFromVideo.progress || null,\n },\n };\n }),\n on(setStatusMessage, (state, { statusMessage }): UnrealState => {\n return { ...state, statusMessage };\n }),\n on(setEstablishingConnection, (state, { value }): UnrealState => {\n return { ...state, establishingConnection: value };\n }),\n on(setStatusPercentSignallingServer, (state, { percent }): UnrealState => {\n return { ...state, statusPercentSignallingServer: percent };\n }),\n on(dataChannelConnected, (state, { statusMessage }): UnrealState => {\n return {\n ...state,\n statusMessage,\n dataChannelConnected: true,\n establishingConnection: false,\n };\n }),\n on(setConfig, startStream, (state, { config }): UnrealState => {\n return { ...state, streamConfig: { ...state.streamConfig, ...config } };\n }),\n on(resetWarnTimeout, (state): UnrealState => {\n return {\n ...state,\n streamConfig: {\n ...state.streamConfig,\n warnTimeout: state.userInactivityTimeout,\n },\n };\n }),\n on(resetConfig, (state): UnrealState => {\n return {\n ...state,\n streamConfig: {\n ...initialState.streamConfig,\n warnTimeout: state.userInactivityTimeout,\n },\n };\n }),\n on(initSignalling, (state): UnrealState => {\n return {\n ...state,\n adopted: false,\n disconnectReason: DisconnectReason.None,\n };\n }),\n on(reconnectPeerSuccess, (state): UnrealState => {\n return { ...state, isReconnecting: false };\n }),\n on(setSignalingName, (state, { instanceName }): UnrealState => {\n return { ...state, awsInstance: { ...state.awsInstance, instanceName } };\n }),\n on(\n setOrchestrationParameters,\n (state, { instanceName, streamRequestId, eta }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n message: undefined,\n instanceName,\n streamRequestId,\n eta,\n },\n };\n },\n ),\n on(setOrchestrationProgress, (state, { progressComplete }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n progressComplete,\n },\n };\n }),\n on(setOrchestrationMessage, (state, { message }): UnrealState => {\n return {\n ...state,\n awsInstance: {\n ...state.awsInstance,\n message,\n },\n };\n }),\n on(setLoopBackCommandIsCompleted, (state): UnrealState => {\n return { ...state, isFirstSuccessLoad: true };\n }),\n on(setAfkTimerCountdown, (state, { countdown }): UnrealState => {\n return { ...state, afkCountdown: countdown };\n }),\n on(setAfkTimerVisible, (state): UnrealState => {\n return { ...state, isAfkTimerVisible: true };\n }),\n on(setAfkTimerHide, (state): UnrealState => {\n return { ...state, isAfkTimerVisible: false, afkCountdown: 0 };\n }),\n on(\n setOrchestrationContext,\n (state, { urls, environmentId, streamRequestContext }): UnrealState => {\n return {\n ...state,\n matchUrls: urls,\n environmentId,\n streamRequestContext,\n };\n },\n ),\n on(setStreamClientCompanyId, (state, { id }): UnrealState => {\n return { ...state, streamClientCompanyId: id };\n }),\n on(setStreamViewId, (state, { id }): UnrealState => {\n return { ...state, streamViewId: id };\n }),\n on(setIntroImageSrc, (state, { src }): UnrealState => {\n return { ...state, imageIntroSrc: src };\n }),\n on(setLoadingImageSrc, (state, { src }): UnrealState => {\n return { ...state, imageLoadingSrc: src };\n }),\n on(setIntroVideoSrc, (state, { src }): UnrealState => {\n return { ...state, videoIntroSrc: src };\n }),\n on(resetIntroSrc, (state): UnrealState => {\n return { ...state, imageIntroSrc: '', videoIntroSrc: '' };\n }),\n on(saveAnalyticsEvent, (state, { event }): UnrealState => {\n return { ...state, analyticsEvent: event };\n }),\n on(setCirrusConnected, (state): UnrealState => {\n return { ...state, cirrusConnected: true };\n }),\n on(streamAdopted, (state, { machineId, ssData }): UnrealState => {\n return {\n ...state,\n cirrusConnected: true,\n adopted: true,\n ssData: ssData ?? state.ssData,\n awsInstance: {\n ...state.awsInstance,\n wsUrl: machineId,\n pollingUrl: null,\n instanceName: 'Adopted Connection',\n progressComplete: 0,\n },\n };\n }),\n on(showLoadingProgress, (state, { visible }): UnrealState => {\n return { ...state, showLoadingProgress: visible };\n }),\n on(showResumeStreamPopup, (state, { visible }): UnrealState => {\n return { ...state, showResumeStreamPopup: visible };\n }),\n on(showUserInactivityTimeoutPopup, (state, { visible }): UnrealState => {\n return { ...state, showAfkTimeoutPopup: visible };\n }),\n on(setUserInactivityTimeout, (state, { timeout }): UnrealState => {\n return {\n ...state,\n userInactivityTimeout: timeout,\n streamConfig: { ...state.streamConfig, warnTimeout: timeout },\n };\n }),\n on(setCirrusDisconnected, (state): UnrealState => {\n // Reset only the live connection / video pipeline fields. Anything not\n // listed here survives the drop (config, intro media, identifiers, etc.)\n // and is therefore implicitly safe when new state fields are added.\n // `errorMessage` and `disconnectReason` are explicitly kept so the UI\n // can render the reason after the connection drops.\n return {\n ...state,\n cirrusConnected: false,\n adopted: false,\n dataChannelConnected: false,\n viewportReady: false,\n isVideoPlaying: false,\n isReconnecting: false,\n isAfkTimerVisible: false,\n afkCountdown: 0,\n ssData: null,\n statusPercentSignallingServer: null,\n statusMessage: null,\n streamResolution: { width: null, height: null },\n freezeFrame: { dataUrl: null, progress: null },\n freezeFrameFromVideo: { dataUrl: null, progress: null },\n awsInstance: { ...initialState.awsInstance },\n commandsInProgress: [],\n totalCommandsStarted: 0,\n totalCommandsCompleted: 0,\n };\n }),\n on(dropConnection, (state): UnrealState => {\n return { ...state, establishingConnection: false };\n }),\n on(resetDataChannelForReconnect, (state): UnrealState => {\n return {\n ...state,\n isReconnecting: true,\n dataChannelConnected: false,\n viewportReady: false,\n statusMessage: 'Reconnecting...',\n };\n }),\n on(setUnrealPlaywrightConfig, (state): UnrealState => {\n return {\n ...state,\n cirrusConnected: true,\n viewportReady: true,\n dataChannelConnected: true,\n isVideoPlaying: true,\n };\n }),\n on(destroyUnrealScene, (): UnrealState => {\n // Pin `disconnectReason: Destroy` so any in-flight disconnectStream\n // actions are ignored by the sticky-Destroy guard above.\n return { ...initialState, disconnectReason: DisconnectReason.Destroy };\n }),\n on(commandStarted, (state, { id, command, timeStamp }): UnrealState => ({\n ...state,\n totalCommandsStarted: state.totalCommandsStarted + 1,\n commandsInProgress: [\n ...state.commandsInProgress,\n { id, command, timeStamp },\n ],\n })),\n on(commandCompleted, (state, { id, now }): UnrealState => {\n const { commandsInProgress, exiled } = exileExpiredCommands(\n state.commandsInProgress,\n id,\n now,\n );\n return {\n ...state,\n commandsInProgress,\n // +1 for the just-completed command, +exiled for stragglers we GC'd.\n totalCommandsCompleted: state.totalCommandsCompleted + 1 + exiled,\n };\n }),\n);\n","import { createFeature } from '@ngrx/store';\nimport { unrealReducer } from './unreal.reducer';\n\nexport const unrealFeature = createFeature({\n name: 'unrealFeature',\n reducer: unrealReducer,\n});\n","import { share, skip, Subject } from 'rxjs';\nimport { Store } from '@ngrx/store';\nimport { DestroyRef, inject } from '@angular/core';\n// Import from the leaf file rather than the `../store` barrel: the barrel\n// pulls in `unreal.effects.ts`, which depends on the services module, which\n// re-exports `SubService` — a circular load order that surfaces as\n// `Class extends value undefined` when test files trigger the chain.\nimport { unrealFeature } from '../store/unreal/unreal.feature';\nimport { filter } from 'rxjs/operators';\nimport { Falsy } from '@3dsource/utils';\nimport { Actions } from '@ngrx/effects';\n\nexport class SubService {\n protected readonly destroyRef = inject(DestroyRef);\n protected readonly destroy$ = new Subject<void>();\n protected readonly actions$ = inject(Actions);\n protected readonly store = inject(Store);\n\n disconnect$ = this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(skip(1), filter(Falsy), share());\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.destroy$.next();\n this.destroy$.complete();\n });\n }\n}\n","import type { SignallingService } from '../../services';\n\nexport function AnswerHandler(\n this: SignallingService,\n msg: RTCSessionDescriptionInit,\n) {\n this.onWebRtcAnswer$.next(msg);\n}\n","import type { SignallingService } from '../../services';\nimport type { ConfigMessage } from '../../interfaces';\n\nexport function ConfigHandler(this: SignallingService, msg: ConfigMessage) {\n this.onConfig$.next(msg);\n\n //DO NOT REMOVE. Possible required in future for SFU\n /*this.send({\n type: OrchestrationMessageTypes.listStreamers,\n correlationId: this.correlationId,\n });*/\n}\n","import type { SignallingService } from '../../services';\n\nexport function IceCandidateHandler(\n this: SignallingService,\n msg: { candidate: RTCIceCandidate },\n) {\n this.onWebRtcIce$.next(msg.candidate);\n}\n","import type { SignallingService } from '../../services';\nimport { instanceReady } from '../../store';\n\nexport function InstanceReadyHandler(this: SignallingService) {\n // No state change — emit the action purely so services that want to\n // observe orchestration progress (e.g. telemetry) have a hook.\n this.store.dispatch(instanceReady());\n}\n","import type { InstanceReserved } from '../../interfaces';\nimport type { SignallingService } from '../../services';\nimport { setOrchestrationParameters } from '../../store';\n\nexport function InstanceReservedHandler(\n this: SignallingService,\n msg: InstanceReserved,\n) {\n this.store.dispatch(\n setOrchestrationParameters({\n instanceName: msg.payload.instanceId,\n streamRequestId: msg.payload.streamRequestId,\n eta: msg.payload.eta ?? 150,\n }),\n );\n}\n","import type { SignallingService } from '../../services';\n\nexport function PingHandler(this: SignallingService) {\n this.send(\n JSON.stringify({\n type: 'pong',\n source: 'front',\n }),\n );\n}\n","import type { SignallingService } from '../..//services';\nimport type { PlayerCountMessage } from '../..//interfaces';\nimport { Logger } from '@3dsource/utils';\n\nexport function PlayerCountHandler(\n this: SignallingService,\n msg: PlayerCountMessage,\n) {\n Logger.log(msg);\n}\n","import type { SignallingService } from '../../services';\nimport type { SSInfo } from '../../interfaces';\nimport { updateCirrusInfo } from '../../store';\n\nexport function SSInfoHandler(this: SignallingService, msg: SSInfo) {\n this.store.dispatch(updateCirrusInfo({ ssData: msg.data }));\n return null;\n}\n","import type { SignallingService } from '../../services';\nimport { dropConnection, setCirrusDisconnected } from '../../store';\nimport { Logger } from '@3dsource/utils';\nimport {\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n WSCloseCode_UNKNOWN,\n} from '../../interfaces';\n\nconst dropCodes = [\n WSCloseCode_UNKNOWN,\n WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,\n WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,\n WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,\n WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,\n];\n\nexport function OnCloseHandler(this: SignallingService, e: CloseEvent) {\n const message = `WebSocket closed: ${JSON.stringify(e.code)} - ${e.reason}`;\n Logger.warn(message);\n this.store.dispatch(setCirrusDisconnected());\n\n if (dropCodes.includes(e.code)) {\n this.store.dispatch(dropConnection());\n }\n}\n","import type { SignallingService } from '../../services';\nimport { Logger } from '@3dsource/utils';\nimport { disconnectStream } from '../../store';\nimport { DisconnectReason } from '../../interfaces';\n\nexport function OnErrorHandler(this: SignallingService, e: Event) {\n Logger.warn(`WS error: ${JSON.stringify(e)}`);\n\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebSocketError,\n message: 'WebSocket Error',\n }),\n );\n}\n","import type { SignallingService } from '../../services';\nimport { Logger } from '@3dsource/utils';\n\nexport function OnMessageHandler(\n this: SignallingService,\n e: MessageEvent<string | Blob>,\n) {\n const handleData = (data: string) => {\n //Logger.colored(...COLOR_CODES.FROM_SIGNALING, data);\n const msg = JSON.parse(data);\n this.handleMessage(msg);\n };\n\n if (typeof e.data === 'string') {\n try {\n handleData(e.data);\n } catch (err) {\n Logger.warn('OnMessageHandler: failed to parse string message', err);\n }\n } else if (e.data instanceof Blob) {\n e.data\n .text()\n .then(handleData)\n .catch((err) =>\n Logger.warn('OnMessageHandler: failed to parse Blob message', err),\n );\n }\n}\n","import type { SignallingService } from '../../services';\nimport { setCirrusConnected } from '../../store';\n\nexport function OnOpenHandler(this: SignallingService) {\n this.store.dispatch(setCirrusConnected());\n this.sendRequestStream();\n}\n","import type { Observable, OperatorFunction } from 'rxjs';\nimport { map, merge, scan } from 'rxjs';\n\n/**\n * Keeps the max of numbers seen so far; resets to 0 whenever `reset$` emits.\n */\nexport const keepMaxUntilReset =\n (reset$: Observable<unknown>): OperatorFunction<number, number> =>\n (source$) =>\n merge(source$, reset$.pipe(map(() => null))).pipe(\n scan<number | null, number>(\n (max, value) => (value === null ? 0 : Math.max(max, value)),\n 0,\n ),\n );\n","// Reused across every inbound data-channel message — instantiating a\n// TextDecoder per call adds needless GC churn on a hot path.\nconst utf16Decoder = new TextDecoder('utf-16');\n\nexport function decodeData(anyData: ArrayBuffer) {\n try {\n return utf16Decoder.decode(anyData);\n } catch {\n return '';\n }\n}\n","import type { Quality } from '../interfaces';\nimport { calculateMedian, clampf } from '@3dsource/utils';\nimport type { FilterSettings } from '../components/low-bandwidth/DataFlowConstants';\n\nexport interface DataFlowCheckResult {\n isDropDetected: boolean;\n dropPercentage: number;\n activeMedian: number;\n quality: Quality;\n message: string;\n /** Optional diagnostic snapshot — only populated on demand to avoid a\n * per-tick array copy on this 4 Hz hot path. */\n dataHistory?: number[];\n config: {\n yellowFlagThresholdPercentage: number;\n redFlagThresholdPercentage: number;\n historyBufferLength: number;\n splitPoint: number;\n };\n}\n\nexport class DataFlowMonitor {\n protected dataHistory: number[] = [];\n\n /**\n * Initializes the DataFlowMonitor monitor.\n * @param yellowFlagThresholdPercentage - The percentage drop to trigger a YELLOW warning (default: 15%).\n * @param redFlagThresholdPercentage - The percentage drop to trigger a RED warning (default: 30%).\n * @param historyBufferLength - buffer length (default: 100).\n * @param splitPoint - The point at which to split the history buffer into two halves (default: 0.5).\n */\n constructor(\n protected yellowFlagThresholdPercentage = 15,\n protected redFlagThresholdPercentage = 30,\n protected historyBufferLength = 100,\n protected splitPoint = 0.5,\n ) {}\n\n reset() {\n this.dataHistory.length = 0;\n }\n\n config(data: FilterSettings) {\n this.reset();\n this.yellowFlagThresholdPercentage = data.yellowFlag;\n this.redFlagThresholdPercentage = data.redFlag;\n }\n\n /**\n * Adds a new bitrate measurement and checks for significant drops.\n * @param currentValue - The current bitrate in kbps.\n * @returns BitrateCheckResult indicating if a drop was detected.\n */\n addValue(currentValue: number): DataFlowCheckResult {\n if (isNaN(currentValue) || currentValue < 1) {\n return {} as DataFlowCheckResult;\n }\n const historyLength = this.dataHistory.length;\n\n if (historyLength > this.historyBufferLength) {\n this.dataHistory.shift();\n }\n this.dataHistory.push(currentValue);\n\n if (historyLength < this.historyBufferLength) {\n this.dataHistory.length = this.historyBufferLength;\n this.dataHistory.fill(currentValue, 0, this.historyBufferLength);\n }\n\n const splitIndex = Math.floor(historyLength * this.splitPoint);\n const firstHalf = this.dataHistory.slice(0, splitIndex);\n const secondHalf = this.dataHistory.slice(splitIndex);\n const firstHalfMedian = calculateMedian(firstHalf);\n const secondHalfMedian = calculateMedian(secondHalf);\n\n const dropPercentage = clampf(\n 0,\n 100,\n ((firstHalfMedian - secondHalfMedian) / firstHalfMedian) * 100,\n );\n\n const isRedFlag = dropPercentage >= this.redFlagThresholdPercentage;\n if (dropPercentage >= this.yellowFlagThresholdPercentage) {\n return {\n config: {\n yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,\n redFlagThresholdPercentage: this.redFlagThresholdPercentage,\n historyBufferLength: this.historyBufferLength,\n splitPoint: this.splitPoint,\n },\n isDropDetected: true,\n dropPercentage,\n activeMedian: secondHalfMedian,\n quality: isRedFlag ? 'red' : 'orange',\n message: `Significant flow drop detected: ${dropPercentage.toFixed(2)}% (from ${firstHalfMedian} to ${secondHalfMedian})`,\n };\n }\n\n return {\n config: {\n yellowFlagThresholdPercentage: this.yellowFlagThresholdPercentage,\n redFlagThresholdPercentage: this.redFlagThresholdPercentage,\n historyBufferLength: this.historyBufferLength,\n splitPoint: this.splitPoint,\n },\n isDropDetected: false,\n dropPercentage,\n activeMedian: secondHalfMedian,\n quality: 'lime',\n message: 'Stable flow',\n };\n }\n}\n","export const dispatchResize = () => {\n window.dispatchEvent(new Event('resize'));\n};\n","const errorCodes: Record<`code${number}`, string | undefined> = {\n code404:\n 'Your asset is being synced on Metabox servers and is not yet available in Metabox Studio or Metabox Configurator. Please check again later after syncing is complete. ',\n};\n\nexport function getRtcErrorMessage(code: number | null) {\n if (code === null) {\n return undefined;\n }\n\n return errorCodes[`code${code}`];\n}\n","import type { Observable, OperatorFunction } from 'rxjs';\nimport {\n animationFrameScheduler,\n concatMap,\n interval,\n of,\n pairwise,\n startWith,\n timestamp,\n} from 'rxjs';\nimport { distinctUntilChanged, map, takeWhile } from 'rxjs/operators';\nimport { clampf, lerp } from '@3dsource/utils';\n\nconst JUMP_THRESHOLD = 0.95;\nconst MAX_TRANSITION_DURATION_MS = 200;\n\n/**\n * Maps a 0..1 stream directly to a 0..100 integer percent stream.\n * No animation — emits whatever the source emits, rounded and clamped.\n */\nexport const floatToPercents =\n (): OperatorFunction<number, number> => (source) =>\n source.pipe(map((value) => clampf(0, 100, Math.round(value * 100))));\n\n/**\n * Maps a 0..1 progress stream to a smoothed 0..100 integer percent stream.\n * Animates between consecutive values over up to 200ms; jumps directly when\n * the delta exceeds 0.95 (treated as a reset, not a real progression).\n */\nexport const floatToSmoothPercents =\n (): OperatorFunction<number, number> => (source) =>\n source.pipe(\n timestamp(),\n startWith({ value: 0, timestamp: 0 }),\n pairwise(),\n concatMap(([prev, curr]) => {\n const isJump = Math.abs(curr.value - prev.value) > JUMP_THRESHOLD;\n const dt = prev.timestamp ? curr.timestamp - prev.timestamp : 0;\n if (isJump || dt === 0) {\n return of(curr.value);\n }\n return smoothTransition(\n prev.value,\n curr.value,\n Math.min(dt, MAX_TRANSITION_DURATION_MS),\n );\n }),\n floatToPercents(),\n );\n\n/**\n * Smoothly interpolates from `start` to `end` over `duration`ms using the\n * animation frame scheduler. Completes when the transition finishes.\n *\n * NOTE: duplicates `smoothTransition` from `@3dsource/utils`. The utils version\n * is missing `takeWhile(... < 1, true)` and never completes — which would\n * deadlock the `concatMap` above. Keep this local copy until utils is fixed.\n */\nexport const smoothTransition = (\n start: number,\n end: number,\n duration: number,\n): Observable<number> => {\n const startTime = animationFrameScheduler.now();\n return interval(0, animationFrameScheduler).pipe(\n map(() =>\n clampf(0, 1, (animationFrameScheduler.now() - startTime) / duration),\n ),\n distinctUntilChanged(),\n takeWhile((fraction) => fraction < 1, true),\n map((fraction) => lerp(start, end, fraction)),\n );\n};\n","import {\n FULL_HD_HEIGHT,\n FULL_HD_WIDTH,\n STREAMING_VIDEO_ID,\n} from '../constants';\nimport type { ImageOutputValues } from '@3dsource/utils';\nimport { getCanvasCached, getSnapshot } from '@3dsource/utils';\nimport type { StreamResolutionProps } from '../interfaces';\n\nexport const getImageFromVideoStream = (\n takeSizeFrom: 'video' | 'constant' = 'video',\n imageOutput?: ImageOutputValues,\n sizes?: StreamResolutionProps,\n) => {\n try {\n const video = document.getElementById(\n STREAMING_VIDEO_ID,\n ) as HTMLVideoElement;\n const { canvas, ctx } = getCanvasCached('video');\n\n canvas.width =\n takeSizeFrom === 'video'\n ? sizes?.width || video?.clientWidth || FULL_HD_WIDTH\n : FULL_HD_WIDTH;\n canvas.height =\n takeSizeFrom === 'video'\n ? sizes?.height || video?.clientHeight || FULL_HD_HEIGHT\n : FULL_HD_HEIGHT;\n\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n\n return getSnapshot(canvas, canvas.width, imageOutput) as string;\n } catch {\n return null;\n }\n};\n","/**\n * Generator that cycles through `urls` indefinitely. Each call to\n * `getActiveUrl(urls)` returns a fresh generator with its own counter,\n * so concurrent generators (e.g., overlapping reconnect attempts) do\n * not share state. The counter is initialized once per generator\n * instance — before any `yield` — so each `.next()` call advances\n * within that single generator.\n */\nexport function* getActiveUrl(urls: string[]) {\n let index = 0;\n while (true) {\n yield urls[index++ % urls.length];\n }\n}\n","import type { FilterSettings } from '../components/low-bandwidth/DataFlowConstants';\n\nexport class KalmanFilter1D {\n private estimate: number;\n private uncertainty: number;\n private processNoise: number;\n private measurementNoise: number;\n\n /**\n * @param initialEstimate Initial guess of the state.\n * @param initialUncertainty Initial uncertainty in the guess.\n * @param processNoise Process variance (Q) representing model uncertainty.\n * @param measurementNoise Measurement variance (R) representing noise in measurements.\n */\n constructor(\n initialEstimate: number,\n initialUncertainty: number,\n processNoise: number,\n measurementNoise: number,\n ) {\n this.estimate = initialEstimate;\n this.uncertainty = initialUncertainty;\n this.processNoise = processNoise;\n this.measurementNoise = measurementNoise;\n }\n\n /**\n * Incorporates a new measurement and returns the updated estimate.\n * @param measurement The new measurement value.\n */\n update(measurement: number): number {\n // === Prediction Step ===\n // For a constant model, the predicted state is the previous estimate.\n const predictedEstimate = this.estimate;\n // Increase the uncertainty by the process noise.\n const predictedUncertainty = this.uncertainty + this.processNoise;\n\n // === Update Step ===\n // Compute the innovation or measurement residual.\n const innovation = measurement - predictedEstimate;\n // Compute the innovation covariance.\n const innovationCovariance = predictedUncertainty + this.measurementNoise;\n // Compute the Kalman Gain.\n const kalmanGain = predictedUncertainty / innovationCovariance;\n\n // Update the estimate with the measurement, weighted by the Kalman Gain.\n this.estimate = predictedEstimate + kalmanGain * innovation;\n // Update the uncertainty.\n this.uncertainty = (1 - kalmanGain) * predictedUncertainty;\n\n return this.estimate;\n }\n\n config(data: FilterSettings) {\n const {\n initialBitrateEstimate,\n initialErrorCovariance,\n processNoise,\n measurementNoise,\n } = data;\n this.estimate = initialBitrateEstimate;\n this.uncertainty = initialErrorCovariance;\n this.processNoise = processNoise;\n this.measurementNoise = measurementNoise;\n }\n}\n","export class LatencyTimings {\n TestStartTimeMs: number | null = null;\n UEReceiptTimeMs: number | null = null;\n UEEncodeMs: number | null = null;\n UECaptureToSendMs: number | null = null;\n UETransmissionTimeMs: number | null = null;\n BrowserReceiptTimeMs: number | null = null;\n FrameDisplayDeltaTimeMs: number | null = null;\n\n Reset() {\n this.TestStartTimeMs = null;\n this.UEReceiptTimeMs = null;\n this.UEEncodeMs = null;\n this.UECaptureToSendMs = null;\n this.UETransmissionTimeMs = null;\n this.BrowserReceiptTimeMs = null;\n this.FrameDisplayDeltaTimeMs = null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n SetUETimings(UETimings: any) {\n this.UEReceiptTimeMs = UETimings.ReceiptTimeMs;\n this.UEEncodeMs = UETimings.EncodeMs;\n this.UECaptureToSendMs = UETimings.CaptureToSendMs;\n this.UETransmissionTimeMs = UETimings.TransmissionTimeMs;\n this.BrowserReceiptTimeMs = Date.now();\n }\n\n SetFrameDisplayDeltaTime(DeltaTimeMs: number) {\n if (this.FrameDisplayDeltaTimeMs == null) {\n this.FrameDisplayDeltaTimeMs = Math.round(DeltaTimeMs);\n }\n }\n}\n","import type { Quality } from '../interfaces';\n\nexport function qpToQuality(VideoEncoderQP: number) {\n const orangeQP = 26;\n const redQP = 35;\n\n let quality: Quality = 'lime';\n if (VideoEncoderQP > redQP) {\n quality = 'red';\n } else if (VideoEncoderQP > orangeQP) {\n quality = 'orange';\n }\n return quality;\n}\n","/**\n * Base64-encodes a byte array.\n *\n * Builds the intermediate binary string in fixed-size chunks instead of\n * concatenating one character at a time. The naive `bytes.reduce((s, b) => s +\n * String.fromCharCode(b), '')` is O(n²) (each `+` re-copies the growing string)\n * and stalls the main thread for a full-resolution frame; chunking keeps it\n * O(n). The chunk size stays under the argument-count limit of\n * `String.fromCharCode.apply`/spread.\n *\n * @param bytes - The raw bytes to encode.\n * @returns The Base64 representation of `bytes`.\n */\nexport function uint8ToBase64(bytes: Uint8Array): string {\n const CHUNK_SIZE = 0x8000;\n let binary = '';\n for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {\n binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK_SIZE));\n }\n return btoa(binary);\n}\n","import { Observable } from 'rxjs';\n\nexport function fromResizeObserver(\n elem: HTMLElement,\n): Observable<ResizeObserverEntry[]> {\n return new Observable((subscriber) => {\n const observer = new window.ResizeObserver((entries) =>\n subscriber.next(entries),\n );\n observer.observe(elem);\n\n return () => observer.unobserve(elem);\n });\n}\n","/*\n * Copyright (c) 2026.\n * 3DSource.com. Sergii Karanda steve@3dsource.com. All Rights Reserved.\n */\n\n/**\n * Rounds a number to the nearest even integer (rounding up for odd values).\n *\n * Video encoders (H.264/H.265) require even dimensions because chroma subsampling\n * operates on 2×2 pixel blocks. Odd dimensions cause encoding artifacts or failures.\n *\n * @param value - The number to round to the nearest even integer.\n * @returns The nearest even integer greater than or equal to the input.\n *\n * @example\n * makeEven(1079) // 1080\n * makeEven(1080) // 1080\n * makeEven(1081) // 1082\n */\nexport function makeEven(value: number): number {\n return Math.floor((value + 1) / 2) * 2;\n}\n","import type { Area } from '@3dsource/utils';\nimport { fitIntoRectangle } from '@3dsource/utils';\nimport { FULL_HD_HEIGHT, FULL_HD_WIDTH } from '../constants';\nimport { makeEven } from './make-even';\n\nconst FULL_HD_PIXELS = FULL_HD_WIDTH * FULL_HD_HEIGHT;\nconst UHD_PIXELS = FULL_HD_WIDTH * 2 * (FULL_HD_HEIGHT * 2);\n\n/**\n * Calculates the optimal stream resolution for studio mode.\n *\n * Fits the studio aspect ratio into the container (scaled by pixelRatio), then\n * caps the total pixel count to a budget (Full HD or 4K) to avoid overloading\n * the GPU/encoder while maximizing visual quality.\n *\n * The pixel budget approach (instead of per-dimension caps) ensures that\n * non-standard aspect ratios (portrait, ultra-wide, square) utilize available\n * pixels efficiently — e.g. a tall 1080×1920 stream uses the same pixel budget\n * as a wide 1920×1080 stream.\n *\n * Resolution is always capped at the studio dimensions — never upscaled beyond\n * what the Unreal scene was designed for.\n *\n * @param params.pixelRatio - Device pixel ratio (`window.devicePixelRatio`).\n * @param params.containerWidth - CSS width of the video container in pixels.\n * @param params.containerHeight - CSS height of the video container in pixels.\n * @param params.studioWidth - Target width of the MetaBox Studio scene.\n * @param params.studioHeight - Target height of the MetaBox Studio scene.\n * @param params.maxResolution - When `true`, uses 4K pixel budget (3840×2160);\n * otherwise Full HD (1920×1080). Controlled by `?maxresolution` query param.\n * @returns An {@link Area} with the calculated `w`, `h`, position (`x`, `y`),\n * and `scale` factor relative to the container's device-pixel size.\n */\nexport function getResizeStudioValues(params: {\n pixelRatio: number;\n containerWidth: number;\n containerHeight: number;\n studioWidth: number;\n studioHeight: number;\n maxResolution: boolean;\n}): Area {\n const {\n pixelRatio,\n containerWidth,\n containerHeight,\n studioWidth,\n studioHeight,\n maxResolution,\n } = params;\n\n const maxSpace = {\n w: containerWidth * pixelRatio,\n h: containerHeight * pixelRatio,\n };\n const maxPixels = maxResolution ? UHD_PIXELS : FULL_HD_PIXELS;\n\n const videoSizePixelPerfect = fitIntoRectangle(\n { x: 0, y: 0, w: studioWidth, h: studioHeight },\n { x: 0, y: 0, ...maxSpace },\n );\n\n let w = videoSizePixelPerfect.w;\n let h = videoSizePixelPerfect.h;\n\n if (w * h > maxPixels) {\n // Derive uniform scale factor `s` from: (w*s) * (h*s) = maxPixels\n // → w * h * s² = maxPixels → s = √(maxPixels / (w * h)).\n // Applying the same `s` to both dimensions preserves the aspect ratio.\n const scaleFactor = Math.sqrt(maxPixels / (w * h));\n w = w * scaleFactor;\n h = h * scaleFactor;\n }\n\n const out = fitIntoRectangle(videoSizePixelPerfect, {\n x: videoSizePixelPerfect.x,\n y: videoSizePixelPerfect.y,\n w,\n h,\n });\n\n out.w = makeEven(out.w);\n out.h = makeEven(out.h);\n return out;\n}\n\n/**\n * Calculates the optimal stream resolution for configurator (non-studio) mode.\n *\n * Uses the full container area (scaled by pixelRatio) as the stream resolution,\n * then caps total pixel count to a budget (Full HD or 4K) to prevent excessive\n * GPU/encoder load while preserving the container's aspect ratio.\n *\n * Unlike {@link getResizeStudioValues}, there is no fixed studio resolution to\n * fit into — the container itself defines the aspect ratio, and the stream fills\n * it entirely (no letterboxing).\n *\n * @param params.pixelRatio - Device pixel ratio (`window.devicePixelRatio`).\n * @param params.containerWidth - CSS width of the video container in pixels.\n * @param params.containerHeight - CSS height of the video container in pixels.\n * @param params.maxResolution - When `true`, uses 4K pixel budget (3840×2160);\n * otherwise Full HD (1920×1080). Controlled by `?maxresolution` query param.\n * @returns An {@link Area} with the calculated `w`, `h`, position (`x`, `y`),\n * and `scale` factor (1 when no downscale needed, <1 when capped).\n */\nexport function getResizeValuesUniversal(params: {\n pixelRatio: number;\n containerWidth: number;\n containerHeight: number;\n maxResolution: boolean;\n}): Area {\n const { pixelRatio, containerWidth, containerHeight, maxResolution } = params;\n\n const maxSpace = {\n w: containerWidth * pixelRatio,\n h: containerHeight * pixelRatio,\n };\n const maxPixels = maxResolution ? UHD_PIXELS : FULL_HD_PIXELS;\n\n let w = maxSpace.w;\n let h = maxSpace.h;\n\n if (w * h > maxPixels) {\n // Derive uniform scale factor `s` from: (w*s) * (h*s) = maxPixels\n // → w * h * s² = maxPixels → s = √(maxPixels / (w * h)).\n // Applying the same `s` to both dimensions preserves the aspect ratio.\n const scaleFactor = Math.sqrt(maxPixels / (w * h));\n w = w * scaleFactor;\n h = h * scaleFactor;\n }\n\n return { w: makeEven(w), h: makeEven(h), x: 0, y: 0, scale: w / maxSpace.w };\n}\n","import { createSelector } from '@ngrx/store';\nimport { unrealFeature } from './unreal.feature';\nimport { DEFAULT_AFK_TIMEOUT, SIGNALLING_PERCENT_VALUE } from '../../constants';\nimport { clampf, lerp } from '@3dsource/utils';\n\n/**\n * Fraction of commands completed (0–1). Drives the second half of the\n * loading bar, after signaling reaches `SIGNALLING_PERCENT_VALUE`.\n */\nexport const selectCommandProgress = createSelector(\n unrealFeature.selectTotalCommandsStarted,\n unrealFeature.selectTotalCommandsCompleted,\n (started, completed) => (started ? completed / started : 0),\n);\n\nexport const selectFreezeFrameDataUrlFromVideo = createSelector(\n unrealFeature.selectFreezeFrameFromVideo,\n (freezeFrameFromVideo) => freezeFrameFromVideo?.dataUrl || null,\n);\nexport const selectFreezeFrameProgressMessageFromVideo = createSelector(\n unrealFeature.selectFreezeFrameFromVideo,\n (freezeFrameFromVideo) => freezeFrameFromVideo?.progress || null,\n);\nexport const selectFreezeFrameDataUrl = createSelector(\n unrealFeature.selectFreezeFrame,\n (freezeFrame) => (freezeFrame?.dataUrl ? freezeFrame?.dataUrl : null),\n);\nexport const selectIsFreezeFrameLoading = createSelector(\n unrealFeature.selectFreezeFrame,\n (freezeFrame) =>\n freezeFrame?.progress\n ? freezeFrame.progress > 0 && freezeFrame.progress < 1\n : false,\n);\nexport const selectFreezeFrameCombinedDataUrl = createSelector(\n selectFreezeFrameDataUrlFromVideo,\n selectFreezeFrameDataUrl,\n (dataUrlFromVideo, remoteDataUrl) =>\n dataUrlFromVideo || remoteDataUrl || null,\n);\nexport const selectStreamConfig = createSelector(\n unrealFeature.selectStreamConfig,\n (config) => config,\n);\nexport const selectWarnTimeout = createSelector(\n selectStreamConfig,\n (config) => config?.warnTimeout || DEFAULT_AFK_TIMEOUT,\n);\nexport const selectIsExistMatchUrls = createSelector(\n unrealFeature.selectMatchUrls,\n (urls) => urls?.length > 0,\n);\nexport const selectIsAutostart = createSelector(\n selectStreamConfig,\n (config) => config?.autoStart,\n);\nexport const selectShowReconnectPopup = createSelector(\n unrealFeature.selectCirrusConnected,\n unrealFeature.selectEstablishingConnection,\n (cirrusConnected, establishingConnection) =>\n !cirrusConnected && !establishingConnection,\n);\nexport const selectShowLoader = createSelector(\n selectShowReconnectPopup,\n unrealFeature.selectViewportReady,\n (showPopup, viewportReady) => !showPopup && !viewportReady,\n);\nexport const selectSignalingParameters = createSelector(\n unrealFeature.selectSsData,\n unrealFeature.selectAwsInstance,\n (data, instance) => {\n const info: string[] = [];\n if (data) {\n info.push(\n `${data.cirrusVersion}, ${data.branchInfo}, ${data.instanceType}`,\n );\n info.push(`Unreal App Version: ${data.streamerVersion}`);\n info.push(`APP: ${data.streamPath}${data.streamApp}`);\n }\n info.push(`Polling: ${instance.pollingUrl}`);\n info.push(`WS: ${instance.wsUrl}`);\n return info.join('<br>');\n },\n);\nexport const selectClientAndViewIds = createSelector(\n unrealFeature.selectStreamClientCompanyId,\n unrealFeature.selectStreamViewId,\n (clientId, viewId) => ({ clientId, viewId }),\n);\nexport const selectIsFullyConnected = createSelector(\n unrealFeature.selectViewportReady,\n unrealFeature.selectDataChannelConnected,\n unrealFeature.selectCirrusConnected,\n (viewportReady, dataChannelConnected, cirrusConnected) =>\n viewportReady && dataChannelConnected && cirrusConnected,\n);\nexport const selectIsLoaderScreenVisible = createSelector(\n selectIsFullyConnected,\n (fullyConnected) => !fullyConnected,\n);\n/**\n * Returns Scene load progress as a float value between 0 and 1.\n *\n * Progress is split into two phases:\n * 1. **Signaling** (0 → ~56%): connection polling or orchestration progress.\n * Starts at 0.1%, so the bar is never visually empty while connecting.\n * 2. **Commands** (~56% → 100%): Unreal command progress after the data channel connects.\n *\n * The split point bumps by +1% once the WebSocket URL is known,\n * producing a small visual step that indicates the WS handshake succeeded.\n */\nexport const selectTotalProgress = createSelector(\n unrealFeature.selectStatusPercentSignallingServer,\n selectCommandProgress,\n unrealFeature.selectAwsInstance,\n unrealFeature.selectDataChannelConnected,\n (\n statusPercentSignallingServer,\n commandProgress,\n awsInstance,\n dataChannelConnected,\n ) => {\n const SIGNALLING_MAX = SIGNALLING_PERCENT_VALUE / 100;\n const ORCHESTRATION_WS_PATTERN = /^wss:\\/\\/orchestration-websocket/i;\n\n const isNewOrchestration = ORCHESTRATION_WS_PATTERN.test(\n awsInstance?.wsUrl ?? '',\n );\n\n // Once the data channel is connected, signaling is fully complete (1.0) —\n // regardless of orchestration type. This is what makes an ADOPTED stream\n // (whose wsUrl is the machine host, not the orchestration-websocket URL,\n // and which never set `statusPercentSignallingServer`) correctly show the\n // whole first phase done instead of stalling near the command-only value.\n // Otherwise: new orchestration reports 0–1 progress; legacy uses the\n // polling percent.\n const signalingProgress = dataChannelConnected\n ? 1\n : isNewOrchestration\n ? (awsInstance?.progressComplete ?? 0)\n : (statusPercentSignallingServer ?? 0) / 100;\n\n // +1% bump once WS URL is known (visual step for WS handshake)\n const splitPoint = awsInstance?.wsUrl\n ? SIGNALLING_MAX + 0.01\n : SIGNALLING_MAX;\n\n // 0.001 minimum so the bar is never completely empty while loading\n const progressSignaling = lerp(0.001, splitPoint, signalingProgress);\n const progressRest = lerp(0, 1 - splitPoint, commandProgress);\n\n return clampf(0, 1, progressSignaling + progressRest);\n },\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectCirrusConnectionId = createSelector(\n unrealFeature.selectSsData,\n (data) => data?.connectionId,\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectUserInactivityDetected = createSelector(\n unrealFeature.selectAfkCountdown,\n unrealFeature.selectIsAfkTimerVisible,\n (remainingSecondsToDisconnect, countdownVisible) => ({\n remainingSecondsToDisconnect,\n countdownVisible,\n }),\n);\n/** Used by external consumers (e.g., metabox). Do not remove. */\nexport const selectIsVideoPlayingAndDataChannelConnected = createSelector(\n unrealFeature.selectIsVideoPlaying,\n unrealFeature.selectDataChannelConnected,\n (isVideoPlaying, isDataChannelConnected) =>\n isVideoPlaying && isDataChannelConnected,\n);\n","import { DialogRef } from '@angular/cdk/dialog';\nimport { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { disconnectStream, unrealFeature } from '../../store';\nimport { DisconnectReason } from '../../interfaces';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-webrtc-error-modal',\n templateUrl: './webrtc-error-modal.component.html',\n styleUrl: './webrtc-error-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class WebrtcErrorModalComponent {\n #dialogRef = inject(DialogRef);\n #store = inject(Store);\n readonly isCirrusConnected = inject(Store).selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n\n closeModalWithCirrusDisconnect() {\n if (!this.isCirrusConnected()) {\n this.#store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DropConnection,\n message: 'Modal Drop Connection',\n }),\n );\n }\n this.close();\n }\n\n private close() {\n this.#dialogRef.close();\n }\n}\n","<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"src-modal\">\n <header class=\"src-modal__header\"></header>\n <section class=\"src-modal__body\">\n <div [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n WebRTC error\n </div>\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"src-modal__footer\">\n <src-button\n (onClick)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n weight=\"primary\"\n >\n Ok\n </src-button>\n </footer>\n</div>\n","import { inject, Injectable } from '@angular/core';\nimport { catchError, filter, takeUntil } from 'rxjs/operators';\nimport type { TelemetryType } from '../interfaces';\nimport { of, take, timer } from 'rxjs';\nimport { generateUuid, Truthy } from '@3dsource/utils';\nimport { HttpClient } from '@angular/common/http';\nimport { UNREAL_CONFIG } from '../constants';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { ofType } from '@ngrx/effects';\nimport { unrealCommandCallback } from '../store';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class CommandTelemetryService extends SubService {\n private readonly appId: string = 'metabox-telemetry';\n private commandsSent: Record<string, CommandToSend> = {};\n private exileTimeout = 60000;\n private pollingTime = 5000;\n private commandSequenceNumber = 0;\n\n /**\n * The time the telemetry service was started.\n * Initialized at a moment when connectToSignaling() was called.\n * @private\n */\n private startTime!: number;\n private lastTime!: number;\n private uuid!: string;\n private viewId!: string;\n private sessionId!: string;\n private userId!: string;\n private payloads: Payload[] = [];\n\n private readonly httpClient = inject(HttpClient);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (\n !this.unrealConfig?.commandTelemetryReceiver ||\n this.unrealConfig?.playwright\n ) {\n return;\n }\n\n this.reset();\n this.sessionId = sessionStorage.getItem(this.appId) || this.uuid;\n this.userId = localStorage.getItem(this.appId) || this.uuid;\n sessionStorage.setItem(this.appId, this.sessionId);\n localStorage.setItem(this.appId, this.userId);\n timer(0, this.pollingTime)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n this.send(this.payloads);\n });\n }\n\n private get timeNow() {\n return Date.now();\n }\n\n private get sessionTime() {\n return this.timeNow - this.startTime;\n }\n\n private get canSkipSending() {\n return !(this.timeNow - this.lastTime > this.pollingTime * 2);\n }\n\n decorate(funcToDecorate: ToBeDecorated) {\n this.listenCallbacks();\n return this.wrapper.bind(this, funcToDecorate);\n }\n\n trackStartCommand(trackingId: string) {\n const out = {\n command: trackingId,\n trackingId,\n };\n const timers = {\n sessionElapsedTime: this.sessionTime,\n } as ComputedTimers;\n this.pushStatToBuffer('commandSent', out, timers);\n this.trackTime(out);\n }\n\n trackStopCommand(\n trackingId: string,\n multi = false,\n response: { multi?: boolean } & Record<string, unknown> = {},\n timeStampsRaw?: TimeStampsRaw,\n ) {\n const commandResponse = this.commandsSent[trackingId];\n if (!commandResponse) {\n return;\n }\n const totalRoundTripTime = this.timeNow - commandResponse.timeStampJs;\n\n /**\n * Time between telemetry was reset and a command was sent.\n */\n const commandSentJsTime = commandResponse.timeStampJs - this.startTime;\n let unrealTimers = {};\n\n const t = timeStampsRaw?.timeStampCommand;\n if (t) {\n unrealTimers = {\n unrealRoundTripTime:\n t.onCompleteCommand.timestamp - t.onRequestCommand.timestamp,\n\n unrealExecutionDuration:\n t.onCompleteCommand.timestamp - t.onStartCommand.timestamp,\n\n timeDiffRequest:\n t.onRequestCommand.timestamp - commandResponse.timeStampJs,\n\n timeDiffCallBack: this.timeNow - t.onCompleteCommand.timestamp,\n };\n }\n\n const timers = {\n sessionElapsedTime: this.sessionTime,\n commandSentJsTime,\n totalRoundTripTime,\n ...unrealTimers,\n } as ComputedTimers;\n\n this.pushStatToBuffer(\n 'commandStop',\n { ...commandResponse.command, response },\n timers,\n timeStampsRaw,\n );\n if (!multi) {\n delete this.commandsSent[trackingId];\n }\n }\n\n reset() {\n this.uuid = generateUuid();\n this.commandSequenceNumber = 0;\n this.viewId = this.uuid;\n this.startTime = this.timeNow;\n this.payloads.length = 0;\n this.commandsSent = {};\n }\n\n private pushStatToBuffer(\n type: TelemetryType,\n commandContent: Record<string, unknown>,\n computedTimers: ComputedTimers,\n timeStampsRaw?: TimeStampsRaw,\n ) {\n this.pushData({\n type,\n commandSequenceNumber: this.commandSequenceNumber++,\n commandContent,\n timeStampsRaw,\n computedTimers,\n });\n }\n\n private trackTime(command: { trackingId: string }) {\n this.commandsSent[command.trackingId] = {\n timeStampJs: this.timeNow,\n command,\n };\n }\n\n private send(payload: Payload[]) {\n if (payload.length === 0 || (this.canSkipSending && payload.length < 10)) {\n return;\n }\n this.lastTime = this.timeNow;\n const out: TelemetryBatch = {\n appId: this.appId,\n sessionId: this.sessionId,\n viewId: this.viewId,\n userId: this.userId,\n ua: navigator.userAgent,\n timeStamp: new Date(this.timeNow).toString(),\n href: location.href,\n resolution: {\n width: window.screen.width,\n height: window.screen.height,\n pixelRatio: window.devicePixelRatio,\n },\n payload,\n };\n const lastIndex = payload[payload.length - 1].commandSequenceNumber;\n this.httpClient\n .post(this.unrealConfig?.commandTelemetryReceiver || '', out)\n .pipe(\n catchError(() => of(null)),\n take(1),\n )\n .subscribe(() => {\n this.payloads = this.payloads.filter(\n (p) => p.commandSequenceNumber > lastIndex,\n );\n });\n }\n\n /**\n * Listens for Unreal Engine callbacks.\n * Subscribes to the Unreal Engine event loop back and filters out events that do not have a tracking ID.\n * When a callback with a tracking ID is received,\n * it stops tracking the time for that command and filters out commands\n * that have exceeded the timeout limit.\n */\n protected listenCallbacks() {\n this.actions$\n .pipe(\n ofType(unrealCommandCallback),\n filter(({ json }) => {\n const callback =\n 'commandCallback' in json ? json.commandCallback : json;\n return Truthy(callback?.trackingId);\n }),\n takeUntil(this.destroy$),\n )\n .subscribe(({ json }) => {\n const callback =\n 'commandCallback' in json ? json.commandCallback : json;\n const timeStampsRaw =\n 'timeStamp' in json ? (json?.timeStamp as TimeStampsRaw) : undefined;\n const trackingId = callback?.trackingId || '';\n\n this.trackStopCommand(trackingId, false, {}, timeStampsRaw);\n this.removeExileCommands();\n });\n }\n\n private pushData(payload: Payload) {\n this.payloads.push(payload);\n }\n\n /**\n * Removes commands that have exceeded the timeout limit.\n * Iterates over all the commands sent and checks if the difference between the current time\n * and the time the command was sent is greater than the timeout limit.\n * If it is, the command is marked for deletion.\n * After checking all commands, those marked for deletion are removed from the commands sent.\n * This method is used to ensure that commands that are not responded to within a certain time frame\n * do not remain in the commandsSent object indefinitely, which could lead to memory leaks over time.\n */\n private removeExileCommands() {\n const time: number = new Date().getTime();\n const markForDelete: string[] = [];\n Object.entries<CommandToSend>(this.commandsSent).forEach(\n ([trackingId, { timeStampJs }]) => {\n if (time - timeStampJs > this.exileTimeout) {\n markForDelete.push(trackingId);\n }\n },\n );\n\n markForDelete.forEach((trackingId) => {\n delete this.commandsSent[trackingId];\n });\n }\n\n /**\n * Wraps the provided function with telemetry tracking.\n * Generates a unique tracking ID and adds it to the data object.\n * Pushes the command sent to the payloads with the tracking ID.\n * Starts tracking the time for the command.\n * Finally, calls the provided function with the modified data object.\n *\n * @param {ToBeDecorated} funcToDecorate - The function to be decorated with telemetry tracking.\n * @param {MetaBoxCommandPacket} data - The data object to be passed to the function. It will be augmented with a unique tracking ID.\n */\n private wrapper(funcToDecorate: ToBeDecorated, data: MetaBoxCommandPacket) {\n const out = { ...data, trackingId: generateUuid() };\n const timers = {\n sessionElapsedTime: this.sessionTime,\n } as ComputedTimers;\n this.pushStatToBuffer(\n 'commandSent',\n {\n ...out,\n trackingId: `${out.trackingId}`,\n },\n timers,\n );\n this.trackTime(out);\n funcToDecorate(out);\n }\n}\n\ntype ToBeDecorated = (data: MetaBoxCommandPacket) => void;\n\ninterface TelemetryBatch {\n appId: string;\n sessionId: string;\n viewId: string;\n userId: string;\n ua: string;\n timeStamp: string;\n href: string;\n payload: Payload[];\n resolution: {\n width: number;\n height: number;\n pixelRatio: number;\n };\n}\n\ninterface Payload {\n type: TelemetryType;\n commandSequenceNumber: number;\n commandContent: Record<string, unknown>;\n timeStampsRaw?: TimeStampsRaw;\n computedTimers: ComputedTimers;\n}\n\ninterface TimeStampsRaw {\n timeStampPak: TimeStampPakCollection;\n timeStampCommand: TimeStampCommandCollection;\n}\n\ninterface TimeStampPakCollection {\n onLoadPak: TimeStampMemory;\n onRenderPak: TimeStampMemory;\n onSequencePak: TimeStampMemory;\n onSpawnPak: TimeStampMemory;\n}\n\ninterface TimeStampMemory {\n timestamp: number;\n ram: number;\n vRam: number;\n}\n\ninterface TimeStampCommandCollection {\n onRequestCommand: TimeStampMemory;\n onStartCommand: TimeStampMemory;\n onCompleteCommand: TimeStampMemory;\n}\n\ninterface ComputedTimers {\n unrealRoundTripTime: number;\n totalRoundTripTime: number;\n unrealExecutionDuration: number;\n sessionElapsedTime: number;\n timeDiffRequest: number;\n timeDiffCallBack: number;\n commandSentJsTime: number;\n}\n\ninterface CommandToSend {\n timeStampJs: number;\n command: { trackingId: string };\n}\n","import { Injectable } from '@angular/core';\nimport { Truthy } from '@3dsource/utils';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class DevModeService {\n get isDevMode() {\n return Truthy(localStorage.getItem('devMode'));\n }\n /**\n * Called from the browser console to toggle dev mode at runtime.\n * @preserve\n */\n setDevMode(value: boolean) {\n if (value) {\n localStorage.setItem('devMode', value.toString());\n } else {\n localStorage.removeItem('devMode');\n }\n }\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Store } from '@ngrx/store';\nimport { defer, from, of, switchMap } from 'rxjs';\nimport { catchError, map, tap } from 'rxjs/operators';\nimport { Semaphore, tapLog } from '@3dsource/utils';\nimport {\n REGION_PING_ACCURATE_SAMPLES,\n REGION_PING_CACHE_KEY,\n REGION_PING_CACHE_TTL_MS,\n REGION_PING_WARMUP_DEADLINE_MS,\n UNREAL_CONFIG,\n} from '../constants';\nimport {\n regionPingFetchEnd,\n regionPingFetchStart,\n regionResolved,\n} from '../store';\n\n@Injectable({ providedIn: 'root' })\nexport class RegionsPingService {\n private httpClient = inject(HttpClient);\n private store = inject(Store);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n // Aborted when the injector is destroyed. Forwarded into every\n // `startPinging` call's winnerController so in-flight fetches cancel\n // immediately on route exit instead of running to natural completion.\n private readonly destroyController = new AbortController();\n\n public config = {\n ping_count: 2,\n ping_timeout: 2000,\n max_parallel_requests: 10,\n bust_cache: true,\n };\n\n constructor() {\n this.destroyRef.onDestroy(() => this.destroyController.abort());\n }\n\n public getFastest(regionListUrl = this.unrealConfig?.regionsPingUrl || '') {\n // Self-announce every lifecycle waypoint of the region-discovery\n // flow (start / providers-fetched / resolved). The final\n // `regionResolved` forwards the winner's full ping-sample array\n // straight from `PingResult.result` — no aggregation.\n return defer(() => {\n this.store.dispatch(regionPingFetchStart());\n\n // Cache hit: a standalone prefetch script\n // (`src/js/region-ping-prefetch.js`) may already have pinged the\n // regions and stored the winner. If that entry is still fresh, skip\n // the HTTP fetch + live ping sweep entirely — this is the whole point\n // of the prefetch: keep the ping cost off the connection critical path.\n const cached = this.readCachedWinner();\n if (cached) {\n // Bookend the waterfall the same way the live path does so observers\n // see start → end → resolved even though discovery was instant.\n // Dispatches are split across operators (not fired back-to-back) to\n // keep the same shape as the live pipe below.\n return of(cached).pipe(\n tap(() => this.store.dispatch(regionPingFetchEnd())),\n tap((data) =>\n this.store.dispatch(\n regionResolved({\n region: data.region_code,\n pingsMs: data.result,\n }),\n ),\n ),\n map((data) => data.region_code),\n );\n }\n\n return this.getProviders(regionListUrl).pipe(\n tap(() => this.store.dispatch(regionPingFetchEnd())),\n switchMap((providers: ProvidersData) => this.getPingResult(providers)),\n catchError(() => of(null)),\n tapLog('PingResult'),\n // Warm the cache with the live result so the next connection (and any\n // reload within the TTL) can skip pinging even if the prefetch script\n // never ran.\n tap((data) => {\n if (data?.region_code) {\n this.writeCachedWinner(data.region_code, data.result);\n }\n }),\n tap((data) =>\n this.store.dispatch(\n regionResolved({\n region: data?.region_code ?? '',\n pingsMs: data?.result ?? [],\n }),\n ),\n ),\n map((data) => data?.region_code),\n );\n });\n }\n\n /**\n * Read the prefetched winner from `localStorage`, returning it only if the\n * entry is well-formed and still within {@link REGION_PING_CACHE_TTL_MS}.\n * All access is guarded — `localStorage` can throw (private mode, disabled\n * storage) or be absent (non-browser).\n *\n * Public so adopted connections (which skip `getFastest`) can replay the\n * region-resolving telemetry phase from the same cached winner — see\n * `UnrealEffects.regionTelemetryOnAdopt$`.\n */\n readCachedWinner(): { region_code: string; result: number[] } | null {\n try {\n if (typeof localStorage === 'undefined') return null;\n const raw = localStorage.getItem(REGION_PING_CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as {\n region_code?: unknown;\n result?: unknown;\n ts?: unknown;\n };\n if (\n typeof parsed?.region_code !== 'string' ||\n !Array.isArray(parsed.result) ||\n typeof parsed.ts !== 'number' ||\n Date.now() - parsed.ts >= REGION_PING_CACHE_TTL_MS\n ) {\n return null;\n }\n return { region_code: parsed.region_code, result: parsed.result };\n } catch {\n return null;\n }\n }\n\n private writeCachedWinner(regionCode: string, result: number[] = []) {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(\n REGION_PING_CACHE_KEY,\n JSON.stringify({ region_code: regionCode, result, ts: Date.now() }),\n );\n } catch {\n // Storage unavailable — cache stays cold, live ping still works.\n }\n }\n\n /**\n * Accurate, OFF-critical-path refresh of the region cache. Mirrors the\n * prefetch script: warm up every region in parallel (barrier), then measure\n * {@link REGION_PING_ACCURATE_SAMPLES} probes each and pick the lowest\n * MEDIAN RTT (tie-break: min). Writes the winner to `localStorage` ONLY — it\n * does NOT dispatch `regionResolved` or touch current-session state, since\n * the connection is already established on a region; this just improves the\n * pick for the NEXT connection.\n *\n * Invoked from an effect a few seconds after the data channel is ready (see\n * `REGION_PING_BACKGROUND_REFRESH_DELAY_MS`), so it never competes with the\n * connection handshake. Aborts with the injector via `destroyController`.\n */\n public refreshCacheInBackground(\n regionListUrl = this.unrealConfig?.regionsPingUrl || '',\n ) {\n return defer(() => this.getProviders(regionListUrl)).pipe(\n switchMap((providers: ProvidersData) =>\n from(\n this.measureAccurate(\n providers.regions,\n providers.timeout ?? this.config.ping_timeout,\n ),\n ),\n ),\n tap((winner) => {\n if (winner) {\n this.writeCachedWinner(winner.region_code, winner.result);\n }\n }),\n catchError(() => of(null)),\n );\n }\n\n private async measureAccurate(endpoints: Region[], defaultTimeout: number) {\n const signal = this.destroyController.signal;\n await this.warmUpAll(endpoints, defaultTimeout, signal);\n if (signal.aborted) return null;\n\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n const tasks = endpoints.map(async ({ region_code, url, timeout }) => {\n await semaphore.acquire();\n try {\n const result = await this.checkLatency(\n url,\n timeout ?? defaultTimeout,\n signal,\n REGION_PING_ACCURATE_SAMPLES,\n );\n return result.length >= 2 ? { region_code, result } : null;\n } catch {\n return null;\n } finally {\n semaphore.release();\n }\n });\n\n const results = (await Promise.all(tasks)).filter(\n (r): r is { region_code: string; result: number[] } => r !== null,\n );\n return this.pickByMedian(results);\n }\n\n /**\n * Phase 1 of the accurate measure: one throwaway probe to every region in\n * parallel to pay the DNS/TCP/TLS cold-start. Resolves once all settle OR\n * the warm-up deadline elapses, whichever is first.\n */\n private async warmUpAll(\n endpoints: Region[],\n defaultTimeout: number,\n signal: AbortSignal,\n ) {\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n const warmups = endpoints.map(async ({ url, timeout }) => {\n await semaphore.acquire();\n try {\n await this.checkLatency(url, timeout ?? defaultTimeout, signal, 1);\n } finally {\n semaphore.release();\n }\n });\n await Promise.race([\n Promise.allSettled(warmups),\n new Promise((resolve) =>\n setTimeout(resolve, REGION_PING_WARMUP_DEADLINE_MS),\n ),\n ]);\n }\n\n private pickByMedian(\n results: { region_code: string; result: number[] }[],\n ): { region_code: string; result: number[] } | null {\n let best: { region_code: string; result: number[] } | null = null;\n let bestMedian = Infinity;\n let bestMin = Infinity;\n for (const r of results) {\n const med = this.median(r.result);\n const min = Math.min(...r.result);\n if (med < bestMedian || (med === bestMedian && min < bestMin)) {\n bestMedian = med;\n bestMin = min;\n best = r;\n }\n }\n return best;\n }\n\n private median(samples: number[]) {\n const sorted = [...samples].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2\n ? sorted[mid]\n : (sorted[mid - 1] + sorted[mid]) / 2;\n }\n\n public getPingResult(providers: ProvidersData) {\n const defaultTimeout = providers.timeout ?? this.config.ping_timeout;\n return from(this.startPinging(providers.regions, defaultTimeout));\n }\n\n public getProviders(regionListUrl = this.unrealConfig?.regionsPingUrl || '') {\n return this.httpClient.get<ProvidersData>(regionListUrl);\n }\n\n private async startPinging(endpoints: Region[], defaultTimeout: number) {\n const semaphore = new Semaphore(this.config.max_parallel_requests);\n // Shared \"stop\" signal. Aborted when EITHER:\n // - one region finishes successfully (winner found → cancel losers); OR\n // - the service's injector is destroyed (route exit → cancel everything).\n // Without this, losing regions keep pinging to their own `ping_timeout`,\n // generating up to `(endpoints.length - 1) × ping_count` wasted requests\n // every time `getFastest` runs, and in-flight fetches outlive the route.\n const winnerController = new AbortController();\n const destroySignal = this.destroyController.signal;\n let onDestroyAbort: (() => void) | undefined;\n if (destroySignal.aborted) {\n // Service already destroyed — bail every task synchronously.\n winnerController.abort(destroySignal.reason);\n } else {\n onDestroyAbort = () => winnerController.abort(destroySignal.reason);\n destroySignal.addEventListener('abort', onDestroyAbort, { once: true });\n }\n\n const tasks = endpoints.map(async ({ region_code, url, timeout }) => {\n await semaphore.acquire();\n try {\n const result = await this.checkLatency(\n url,\n timeout ?? defaultTimeout,\n winnerController.signal,\n );\n if (result.length < 2) throw new Error('insufficient pings');\n return { region_code, result };\n } finally {\n semaphore.release();\n }\n });\n\n try {\n return await Promise.any(tasks);\n } catch {\n return null;\n } finally {\n // Cancel losing in-flight pings. Safe to call on success (we already\n // captured the winner) AND on all-failed (no-op, all tasks settled).\n winnerController.abort();\n // Detach the destroy listener so it doesn't linger on the long-lived\n // destroyController.signal across multiple `getFastest` invocations.\n if (onDestroyAbort) {\n destroySignal.removeEventListener('abort', onDestroyAbort);\n }\n }\n }\n\n private async checkLatency(\n endpoint: string,\n timeout: number,\n abortSignal?: AbortSignal,\n count = this.config.ping_count,\n ) {\n const pingResults: number[] = [];\n const sep = endpoint.includes('?') ? '&' : '?';\n\n for (let i = 0; i < count; i++) {\n // Bail out as soon as another region's task has won — no point\n // burning further `ping_timeout` budget here.\n if (abortSignal?.aborted) {\n break;\n }\n\n const startTime = performance.now();\n try {\n await this.fetchWithTimeout(\n this.config.bust_cache\n ? `${endpoint}${sep}cache_buster=${performance.now()}`\n : endpoint,\n {\n method: 'GET',\n mode: 'no-cors',\n headers: {\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n Pragma: 'no-cache',\n Expires: '0',\n },\n credentials: 'omit',\n },\n timeout,\n abortSignal,\n );\n } catch {\n // intentional: finally pushes the elapsed time as the latency sample\n } finally {\n const latency = Math.round(performance.now() - startTime);\n pingResults.push(latency);\n }\n }\n return pingResults;\n }\n\n private async fetchWithTimeout(\n url: string,\n options: RequestInit = {},\n timeout: number,\n abortSignal?: AbortSignal,\n ) {\n const controller = new AbortController();\n options.signal = controller.signal;\n\n // Forward an external abort into our local controller so a winner-found signal cancels the in-flight `fetch` immediately. If the\n // external signal is already aborted, abort synchronously before\n // even starting the fetch.\n let onExternalAbort: (() => void) | undefined;\n if (abortSignal) {\n if (abortSignal.aborted) {\n controller.abort(abortSignal.reason);\n } else {\n onExternalAbort = () => controller.abort(abortSignal.reason);\n abortSignal.addEventListener('abort', onExternalAbort, { once: true });\n }\n }\n\n const timeoutId = setTimeout(\n () =>\n controller.abort(new DOMException('Request timed out', 'TimeoutError')),\n timeout,\n );\n\n try {\n return await fetch(url, options);\n } finally {\n clearTimeout(timeoutId);\n if (abortSignal && onExternalAbort) {\n abortSignal.removeEventListener('abort', onExternalAbort);\n }\n }\n }\n}\n\ninterface ProvidersData {\n timeout?: number;\n regions: Region[];\n}\n\ninterface Region {\n region_code: string;\n url: string;\n timeout?: number;\n}\n","import type { SignallingService } from '../../services';\nimport type { StreamerListMessage } from '../../interfaces';\n\nexport function StreamerListHandler(\n this: SignallingService,\n msg: StreamerListMessage,\n) {\n this.send(\n JSON.stringify({\n type: 'subscribe',\n streamerId: msg.ids[0],\n }),\n );\n}\n","import type { SignallingService } from '../../services';\n\nexport function OfferHandler(\n this: SignallingService,\n msg: RTCSessionDescriptionInit,\n) {\n this.onOffer$.next(msg);\n}\n","export function httpUrlToWs(url: string) {\n return url.replace('http://', 'ws://').replace('https://', 'wss://');\n}\n","import { defer, Observable, throwError } from 'rxjs';\nimport { timeout } from 'rxjs/operators';\nimport { Logger } from '@3dsource/utils';\nimport { WS_TIMEOUT } from '../constants';\n\n/**\n * Factory that creates a WebSocket connection and wraps it in an RxJS Observable.\n *\n * Returns a **single-value Observable**: it emits the open `WebSocket` instance\n * once the connection is established, then completes. This design allows\n * downstream operators (e.g. `tap` in `connectToCirrus`) to attach their own\n * event handlers before any messages arrive.\n *\n * ## Ownership model\n *\n * The factory **transfers ownership** of the WebSocket to the consumer upon\n * emission. Once `observer.next(ws)` fires, the consumer is responsible for\n * the socket's lifecycle (attaching handlers, closing when done). The teardown\n * logic will **never** close a socket that has been successfully delivered.\n *\n * ## Timeout\n *\n * The observable is piped through `timeout({ first: WS_TIMEOUT })`. If the\n * WebSocket `open` event does not fire within `WS_TIMEOUT` milliseconds, the\n * stream errors with a timeout message and the teardown disposes the socket.\n *\n * ## Teardown & leak prevention\n *\n * When the observable is unsubscribed (timeout, manual unsubscribe, or error),\n * the teardown function runs and handles two cases:\n *\n * 1. **Socket was emitted (`emitted === true`):** The consumer owns the socket.\n * Teardown only removes the internal event listeners — it does NOT close\n * the socket. Closing it here would break downstream consumers like\n * `connectToCirrus` that rely on the connection staying alive.\n *\n * 2. **Socket was NOT emitted (`emitted === false`):** The socket is orphaned\n * (nobody has a reference to it). Teardown must close it to prevent a leak.\n * However, calling `ws.close()` on a `CONNECTING` socket does not reliably\n * abort the underlying HTTP upgrade request in all browsers — the TCP\n * handshake may still complete asynchronously. To handle this edge case,\n * teardown replaces the `open` listener with a one-shot handler that calls\n * `ws.close()` if the connection succeeds after teardown has already run.\n * This ensures the orphaned socket is closed regardless of timing:\n *\n * - If `close()` aborts the connection immediately — done.\n * - If the browser lets the handshake complete anyway — the `open` handler\n * fires and closes the now-connected socket, so it doesn't linger in\n * the browser's network tab as a \"Pending\" request.\n *\n * ## Why `defer`?\n *\n * The outer `defer()` ensures a **new WebSocket** is created on each\n * subscription. Without it, retry operators would reuse the same (possibly\n * closed) socket instance. With `defer`, each retry gets a fresh connection.\n *\n * ## SSR guard\n *\n * If `window` or `WebSocket` is not available (server-side rendering),\n * the function returns an error observable immediately without attempting\n * a connection.\n *\n * ## Lifecycle flags\n *\n * - `opened` — set to `true` when the `open` event fires. Guards the `close`\n * handler so it only errors the observable if the socket was closed *before*\n * the connection was established (e.g. server rejected the upgrade).\n *\n * - `emitted` — set to `true` right before `observer.next(ws)`. Tells the\n * teardown function whether the socket was delivered to the consumer.\n * This is the flag that controls whether teardown closes the socket or\n * leaves it for the consumer.\n *\n * ## Abort\n *\n * The factory does **not** accept an abort signal — cancellation is handled\n * by the caller via standard RxJS unsubscription. When the caller's\n * `takeUntil` (or manual `unsubscribe`) fires, the observable tears down\n * and the orphaned socket is closed. For retry loops, place `takeUntil`\n * at two levels:\n *\n * 1. **Inside the per-attempt chain** (e.g. in `connectToCirrus`) — cancels\n * the current in-flight WebSocket attempt and triggers teardown.\n * 2. **Outside `retry`** (e.g. in `connectToSignaling`) — kills the entire\n * retry loop so no further re-subscriptions occur.\n *\n * ## Usage\n *\n * ```typescript\n * // In connectToCirrus — takeUntil cancels the current attempt:\n * createWebSocket(wsUrl).pipe(\n * takeUntil(abort$),\n * tap(ws => addWsHandlers(ws)),\n * );\n *\n * // In connectToSignaling — takeUntil outside retry kills the loop:\n * defer(() => innerChain$).pipe(\n * retry({ delay: ... }),\n * takeUntil(abort$),\n * );\n * ```\n *\n * @param wsUrl - The `ws://` or `wss://` URL to connect to.\n * @returns Observable that emits a single open WebSocket, then completes.\n * Errors if the connection fails, times out, or the environment\n * does not support WebSocket.\n */\nexport function createWebSocket(\n wsUrl: string,\n timeoutMs: number = WS_TIMEOUT,\n): Observable<WebSocket> {\n // --- SSR guard: bail immediately if WebSocket API is unavailable ---\n if (typeof window === 'undefined' || !('WebSocket' in window)) {\n return throwError(\n () => new Error(\"Your browser doesn't support WebSocket\"),\n );\n }\n\n Logger.info('Creating socket', wsUrl);\n\n return defer(\n () =>\n new Observable<WebSocket>((observer) => {\n const ws = new WebSocket(wsUrl);\n\n // Lifecycle flags — see JSDoc above for detailed explanation.\n let opened = false;\n let emitted = false;\n\n // --- Event handlers (attached during connection, removed in teardown) ---\n\n const onOpen = () => {\n opened = true;\n emitted = true;\n observer.next(ws);\n observer.complete();\n };\n\n const onError = (ev: Event) => {\n const err =\n ev && 'error' in ev && ev?.error instanceof Error\n ? ev.error\n : new Error('WebSocket failed to connect');\n observer.error(err);\n };\n\n const onClose = (ev: CloseEvent) => {\n if (!opened) {\n observer.error(\n new Error(`WebSocket closed before open (code ${ev.code})`),\n );\n }\n };\n\n ws.addEventListener('open', onOpen);\n ws.addEventListener('error', onError);\n ws.addEventListener('close', onClose);\n\n // --- Teardown: runs on unsubscribe, timeout, error, or complete ---\n return () => {\n ws.removeEventListener('error', onError);\n ws.removeEventListener('close', onClose);\n\n if (\n !emitted &&\n (ws.readyState === WebSocket.CONNECTING ||\n ws.readyState === WebSocket.OPEN)\n ) {\n // Socket was never delivered — it's orphaned. Must close it.\n // Replace the open listener with a cleanup handler: if the\n // browser completes the handshake after this teardown, the\n // handler will close the orphaned socket immediately.\n ws.removeEventListener('open', onOpen);\n ws.addEventListener('open', () => ws.close());\n\n // Some strict implementations (including `ws`) emit an `error`\n // when a CONNECTING socket is closed. The observable is already\n // torn down, so consume that expected lifecycle error and remove\n // the temporary handlers once the socket closes.\n const onOrphanError = () => undefined;\n const onOrphanClose = () => {\n ws.removeEventListener('error', onOrphanError);\n ws.removeEventListener('close', onOrphanClose);\n };\n ws.addEventListener('error', onOrphanError);\n ws.addEventListener('close', onOrphanClose);\n ws.close();\n } else {\n // Socket was delivered to consumer — they own it now.\n // Just remove our internal listener; don't touch the socket.\n ws.removeEventListener('open', onOpen);\n }\n };\n }),\n ).pipe(\n timeout({\n first: timeoutMs,\n with: () =>\n throwError(\n () =>\n new Error(`WebSocket connection timed out after ${timeoutMs}ms`),\n ),\n }),\n );\n}\n","import { disconnectStream } from '../../store';\nimport type { SignallingService } from '../../services';\nimport { DisconnectReason } from '../../interfaces';\n\nexport function PlayerDisconnectHandler(this: SignallingService) {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.OrchestrationPlayerDisconnected,\n message: 'Orchestration: PlayerDisconnectHandler',\n }),\n );\n}\nexport function StreamerDisconnectHandler(this: SignallingService) {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.OrchestrationStreamerDisconnected,\n message: 'Orchestration: StreamerDisconnectHandler',\n }),\n );\n}\n","import type { SignallingService } from '../../services';\nimport type { OrchestrationErrorMessage } from '../../interfaces';\nimport { POLLING_TIME } from '../../constants';\nimport { setOrchestrationMessage } from '../../store';\nimport { timer } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n// Structured constants holding code + description\nexport const ORCHESTRATION_ERROR_CODES = {\n NO_AVAILABLE_INSTANCES: {\n code: 4001,\n description: 'There are no instances to run for the requested environment.',\n },\n LIMIT_REACHED: {\n code: 4002,\n description:\n 'The limit of instances for the requested environment is reached.',\n },\n DIFFERENT_ORIGIN: {\n code: 4003,\n description:\n 'Origin instance and client are on different connection servers on instance.',\n },\n} as const;\n\n// Set for codes that should trigger a retry\nconst RETRY_CODES = new Set<number>([\n ORCHESTRATION_ERROR_CODES.NO_AVAILABLE_INSTANCES.code,\n ORCHESTRATION_ERROR_CODES.LIMIT_REACHED.code,\n]);\n\nexport function OrchestrationErrorHandler(\n this: SignallingService,\n msg: OrchestrationErrorMessage,\n) {\n if (RETRY_CODES.has(msg.payload.code)) {\n const errorInfo = Object.values(ORCHESTRATION_ERROR_CODES).find(\n ({ code }) => code === msg.payload.code,\n );\n this.store.dispatch(\n setOrchestrationMessage({ message: errorInfo?.description as string }),\n );\n this.orchestrationRetrySub?.unsubscribe();\n this.orchestrationRetrySub = timer(POLLING_TIME)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.sendRequestStream());\n }\n}\n","import { inject, Injectable, signal } from '@angular/core';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport type { Observable, Subscription } from 'rxjs';\nimport {\n defer,\n EMPTY,\n repeat,\n retry,\n Subject,\n switchMap,\n take,\n throwError,\n timeout,\n timer,\n} from 'rxjs';\nimport {\n catchError,\n filter,\n finalize,\n first,\n map,\n takeUntil,\n tap,\n} from 'rxjs/operators';\nimport {\n abortEstablishingConnection,\n dataChannelConnected,\n dataChannelReady,\n pollingEnded,\n pollingStarted,\n selectClientAndViewIds,\n setAwsInstance,\n setEstablishingConnection,\n setStatusMessage,\n setStatusPercentSignallingServer,\n setUnrealPlaywrightConfig,\n signalingRetryAttempted,\n unrealFeature,\n} from '../store';\nimport { HttpClient } from '@angular/common/http';\nimport { SubService } from './sub.service';\nimport {\n INNER_RETRY_LIMIT,\n OUTER_RETRY_DELAY,\n POLLING_TIME,\n UNREAL_CONFIG,\n UnrealStatusMessage,\n WS_OPEN_STATE,\n WS_RETRY_PER_INSTANCE,\n} from '../constants';\nimport type {\n AnySignalingMessage,\n AwsInstance,\n CloseReason,\n ConfigMessage,\n MessageBase,\n PollingOrchestrationMessage,\n SignalingMessageHandler,\n SignalingMessageMap,\n} from '../interfaces';\nimport { DisconnectReason, OrchestrationMessageTypes } from '../interfaces';\nimport {\n COLOR_CODES,\n generateUuid,\n Logger,\n tapLog,\n Truthy,\n} from '@3dsource/utils';\nimport {\n AnswerHandler,\n ConfigHandler,\n getActiveUrl,\n IceCandidateHandler,\n InstanceReadyHandler,\n InstanceReservedHandler,\n OnCloseHandler,\n OnErrorHandler,\n OnMessageHandler,\n OnOpenHandler,\n PingHandler,\n PlayerCountHandler,\n SSInfoHandler,\n} from '../helpers';\n// Direct file import (not the barrel) so the `extends SubService` graph\n// loads in a deterministic order during spec compile.\nimport { RegionsPingService } from './regions-ping.service';\nimport { StreamerListHandler } from '../helpers/FromStreamerHandlers/StreamerListHandler';\nimport { OfferHandler } from '../helpers/FromStreamerHandlers/OfferHandler';\nimport { ofType } from '@ngrx/effects';\nimport { httpUrlToWs } from '../helpers/http-to-ws-url';\nimport { createWebSocket } from '../helpers/create-websocket';\nimport {\n PlayerDisconnectHandler,\n StreamerDisconnectHandler,\n} from '../helpers/FromStreamerHandlers/ForceDisconnect';\nimport { OrchestrationErrorHandler } from '../helpers/FromStreamerHandlers/OrchestrationErrorHandler';\n\n@Injectable({ providedIn: 'root' })\nexport class SignallingService extends SubService {\n private readonly httpClient = inject(HttpClient);\n private readonly regionsPingService = inject(RegionsPingService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n readonly region = signal('');\n\n readonly selectClientAndViewIds = this.store.selectSignal(\n selectClientAndViewIds,\n );\n readonly environmentId = this.store.selectSignal(\n unrealFeature.selectEnvironmentId,\n );\n readonly streamRequestContext = this.store.selectSignal(\n unrealFeature.selectStreamRequestContext,\n );\n\n onOffer$ = new Subject<RTCSessionDescriptionInit>();\n onConfig$ = new Subject<ConfigMessage>();\n onWebRtcIce$ = new Subject<RTCIceCandidate>();\n onWebRtcAnswer$ = new Subject<RTCSessionDescriptionInit | null>();\n // Pure signal — no side-effects. The `close()` is wired ONCE in init()\n // below so a single abort event triggers exactly one close, regardless\n // of how many pipelines have `takeUntil(this.abort$)` attached.\n abort$ = this.actions$.pipe(ofType(abortEstablishingConnection));\n\n private ws: WebSocket | null = null;\n orchestrationRetrySub?: Subscription;\n\n private wsMsgHandlers: Partial<{\n [K in keyof SignalingMessageMap]: SignalingMessageHandler<K>;\n }> = {};\n\n protected correlationId!: string;\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.setHandlersFromStream();\n\n // Single owner of the \"close on abort\" side-effect. Previously this\n // lived as a `tap` inside `abort$` itself, which made every\n // `takeUntil(this.abort$)` subscriber fire its own close().\n this.abort$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.close({\n code: 1000,\n reason: DisconnectReason.AbortEstablishingConnection,\n });\n });\n\n // `dataChannelReady` is a per-session event. Bind ONLY to destroy$, not\n // to abort$ — `abort$` fires on every destroyUnrealScene (route swap),\n // and `init()` runs once in the constructor. If these subs were torn\n // down by abort$, a second in-injector session (e.g. navigating between\n // two routes that both host <app-unreal-scene>) would never send\n // `p2pEstablished` / `streamPreparedForUserInteraction`. `send()` is\n // already a no-op on a closed WS, so there's no risk of stray messages.\n this.actions$\n .pipe(ofType(dataChannelReady), takeUntil(this.destroy$))\n .subscribe(() => {\n this.send({\n type: 'p2pEstablished',\n source: 'front',\n sessionId: generateUuid(),\n });\n });\n\n this.actions$\n .pipe(\n ofType(dataChannelReady),\n switchMap(() =>\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy), take(1)),\n ),\n takeUntil(this.destroy$),\n )\n .subscribe(() => {\n this.send({\n type: 'streamPreparedForUserInteraction',\n correlationId: generateUuid(),\n });\n });\n }\n\n connectToSignaling(urlList: string[]) {\n if (this.unrealConfig?.playwright) {\n this.store.dispatch(setUnrealPlaywrightConfig());\n this.store.dispatch(\n dataChannelConnected({\n statusMessage: 'Playwright set data channel connected',\n }),\n );\n return EMPTY;\n }\n\n Logger.log('CONNECT TO SIGNALLING');\n\n // Side-effects that belong to one logical `connectToSignaling`\n // invocation (NOT one retry attempt). Wrapping them in a `defer`\n // makes them fire on subscribe (lazy), but only ONCE — the retry\n // below sits INSIDE this defer's projection so re-subscribing the\n // inner pipeline does not re-trigger these.\n return defer(() => {\n this.correlationId = generateUuid();\n this.commandTelemetryService.reset();\n this.startEstablishingConnection();\n\n // Staged retry:\n // * `getRegion()` is pulled in front of the retry — region\n // discovery happens once per outer cycle.\n // * `connectAttempt(urls)` owns inner retry + URL rotation +\n // WS connect. WS/orch failures stay inside it (capped at\n // `INNER_RETRY_LIMIT`).\n // * If the inner retry exhausts, the error propagates to the\n // OUTER retry below which re-runs `getRegion()` (rare, real\n // \"region down\" case). Outer delay > inner so escalation is\n // bounded.\n const connectCycle$ = this.getRegion().pipe(\n tap((region) => this.region.set(region ?? '')),\n map((region) => this.adaptUrlsToRegion(urlList, region)),\n switchMap((urls) => this.connectAttempt(urls)),\n takeUntil(this.abort$),\n );\n\n return connectCycle$.pipe(\n retry({\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'region-cycle',\n }),\n );\n Logger.info(\n `Outer retry (region re-pick) in ${OUTER_RETRY_DELAY}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(OUTER_RETRY_DELAY);\n },\n }),\n );\n }).pipe(takeUntil(this.abort$));\n }\n\n /**\n * One inner cycle: rotate `urlGen` over the pool, resolve via\n * {@link getAwsInstance}, open WS via {@link connectToCirrus},\n * retry up to {@link INNER_RETRY_LIMIT} on any hard failure. The\n * urlGen lives in this closure so retries advance through the\n * pool. Exhaustion bubbles to {@link connectToSignaling}'s outer\n * retry which re-pings the region.\n */\n private connectAttempt(urls: string[]): Observable<WebSocket> {\n const urlGen = getActiveUrl(urls);\n\n return defer(() => this.getAwsInstance(`${urlGen.next().value}`)).pipe(\n tap((awsInstance) => this.store.dispatch(setAwsInstance(awsInstance))),\n switchMap(({ wsUrl }) =>\n // ── WS-only retry tier ─────────────────────────────────────────────\n // Tries the SAME `wsUrl` up to `WS_RETRY_PER_INSTANCE` extra times\n // before letting the error bubble up to the outer (URL-rotating)\n // retry. This is important because the outer retry calls\n // `getAwsInstance(url)` again, which polls orchestration again,\n // which causes orchestrator to RESERVE A NEW instance — the\n // previous reservation is orphaned (server-side leak).\n //\n // The same-wsUrl retry catches transient WS failures (network\n // blip, brief region unavailability, slow cold handshake) without\n // burning a second reservation. If WS still fails after these\n // extra attempts, the instance is genuinely unusable and we\n // accept the cost of rotating.\n this.connectToCirrus(wsUrl ?? '').pipe(\n filter(Truthy),\n take(1),\n retry({\n count: WS_RETRY_PER_INSTANCE,\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'ws-retry',\n }),\n );\n this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);\n Logger.info(\n `WS-only retry on SAME url in ${POLLING_TIME}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(POLLING_TIME);\n },\n }),\n ),\n ),\n // ── URL-rotating retry tier ─────────────────────────────────────────\n // Triggers only when the WS-only retries above are exhausted. Each\n // attempt advances `urlGen` → new `getAwsInstance(url)` → new\n // orchestration poll → new AwsInstance reservation.\n retry({\n count: INNER_RETRY_LIMIT,\n delay: (err, attempt) => {\n this.store.dispatch(\n signalingRetryAttempted({\n attempt,\n reason: err?.message ?? 'unknown',\n kind: 'connect',\n }),\n );\n this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);\n Logger.info(\n `Inner retry (WS+orch) in ${POLLING_TIME}ms. Attempt# ${attempt}.`,\n err?.message,\n );\n return timer(POLLING_TIME);\n },\n }),\n );\n }\n\n protected startEstablishingConnection() {\n this.showStatusMessage(UnrealStatusMessage.STARTING_YOUR_SESSION);\n this.store.dispatch(setEstablishingConnection({ value: true }));\n }\n\n private adaptUrlsToRegion(urlList: string[], region?: string) {\n return urlList.map((url) => {\n if (region && !url.includes(':region')) {\n return url.replace(\n /signallingserver/gi,\n `signallingserver/region:${region}`,\n );\n }\n return url;\n });\n }\n\n /**\n * Resolve one URL to an `AwsInstance`. Dispatches to\n * {@link directWsInstance} for `ws://` / `wss://` URLs, otherwise\n * to {@link pollOrchestration}.\n */\n private getAwsInstance(url: string): Observable<AwsInstance> {\n return url.match(/^ws(s?):\\/\\//i)\n ? this.directWsInstance(url)\n : this.pollOrchestration(url);\n }\n\n /**\n * Direct `ws://` / `wss://` short-circuit — no HTTP orchestration.\n * Waits for `clientId` and `viewId` to be truthy in the store, then\n * emits a `Direct Connection` `AwsInstance` and completes.\n */\n private directWsInstance(url: string): Observable<AwsInstance> {\n return this.store.select(selectClientAndViewIds).pipe(\n filter(({ clientId, viewId }) => !!clientId && !!viewId),\n take(1),\n map(\n () =>\n ({\n wsUrl: url,\n pollingUrl: null,\n instanceName: 'Direct Connection',\n }) as AwsInstance,\n ),\n );\n }\n\n /**\n * HTTP-orchestration path. Brackets {@link pollLoop} with the\n * `pollingStarted`/`pollingEnded` actions and the `EXT-getSignaling`\n * telemetry span (start in `defer`, stop in `finalize` with the\n * last response captured in the closure). Maps the final ready\n * response to an `AwsInstance`.\n */\n private pollOrchestration(url: string): Observable<AwsInstance> {\n return defer(() => {\n let lastResp: PollingOrchestrationMessage | undefined;\n this.store.dispatch(pollingStarted());\n this.commandTelemetryService.trackStartCommand('EXT-getSignaling');\n\n return this.store.select(selectClientAndViewIds).pipe(\n tap(({ clientId, viewId }) => {\n if (!clientId || !viewId) {\n Logger.error('Client ID or View ID is not set');\n }\n }),\n filter(({ clientId, viewId }) => !!clientId && !!viewId),\n take(1),\n switchMap(({ clientId, viewId }) =>\n this.pollLoop(`${url}${clientId}/${viewId}`).pipe(\n tap((data) => {\n lastResp = data;\n }),\n ),\n ),\n map((data): AwsInstance => ({\n wsUrl: httpUrlToWs(`${location.protocol}//${data.signallingServer}`),\n pollingUrl: url,\n instanceName: data.signallingServer ?? '',\n })),\n finalize(() => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-getSignaling',\n true,\n { ...(lastResp ?? {}), multi: true } as never,\n );\n this.store.dispatch(pollingEnded());\n }),\n );\n });\n }\n\n /**\n * Poll the SAME `url` until ready, or until HTTP 4xx says the URL\n * is dead.\n *\n * | Response | Class | Action |\n * | ---------------------------------------- | ---------- | ---------------------------- |\n * | 200 `{ signallingServer: 'cirrus', ... }`| ✅ Ready | `first()` emits, loop ends |\n * | 200 empty `signallingServer` (any error/info/mm_message) | ⏳ Progress | Dispatch status+percent, re-poll same URL |\n * | HTTP 4xx (except 429) | ❌ Hard | Re-throw → caller rotates URL |\n * | HTTP 5xx / 429 / timeout / network | ⚠️ Soft | `EMPTY` → `repeat` same URL |\n *\n * `data.error` is NOT treated as fatal — the backend reuses it for\n * progress strings like `\"Ready in ~2m 23s\"`. The only fatal exits\n * are HTTP 4xx and `abort$` upstream.\n */\n private pollLoop(url: string): Observable<PollingOrchestrationMessage> {\n return defer(() =>\n this.httpClient.get<PollingOrchestrationMessage>(url),\n ).pipe(\n timeout(POLLING_TIME),\n catchError((err) => {\n // HTTP 4xx (except 429) = the URL itself is dead → rotate.\n const status = (err as { status?: number } | null)?.status;\n if (\n typeof status === 'number' &&\n status >= 400 &&\n status < 500 &&\n status !== 429\n ) {\n Logger.warn(\n `Polling HARD error on ${url} (HTTP ${status}); rotating URL`,\n );\n return throwError(() => err);\n }\n // Everything else = soft → re-poll same URL.\n Logger.warn(\n `Polling soft error on ${url} (${err?.message ?? err}); re-polling same URL`,\n );\n return EMPTY;\n }),\n tap((data: PollingOrchestrationMessage) => {\n // Ready response is handled by `first()` below — nothing to\n // dispatch here. Empty `signallingServer` = progress.\n if (data.signallingServer) return;\n\n this.showStatusMessage(data?.mm_message || 'Server not found');\n if (data?.info) {\n this.store.dispatch(\n setStatusPercentSignallingServer({\n percent: data.info.percent,\n }),\n );\n }\n }),\n // Re-subscribe (= poll again) after each completed response OR\n // after `catchError` swallowed a transient failure.\n repeat({ delay: () => timer(POLLING_TIME) }),\n // Stop the poll loop as soon as we get a ready response.\n first((data: PollingOrchestrationMessage) => !!data.signallingServer),\n );\n }\n\n private connectToCirrus(wsUrl: string) {\n // Wrapped in `defer` so each subscription (including ws-retry\n // re-subscriptions from `connectAttempt`) starts a FRESH WS attempt:\n // the previous socket is closed and a new one is created. Without\n // this, the WS-only retry would just re-subscribe the SAME WS\n // observable, which in production-defer'd `createWebSocket` would\n // still create a new socket, but in tests would re-emit the same\n // (already-errored) mock observable.\n return defer(() => {\n this.close({ code: 1000, reason: DisconnectReason.NewConnectionAttempt });\n return createWebSocket(wsUrl);\n }).pipe(\n takeUntil(this.abort$),\n tapLog('WS CREATED'),\n tap((ws) => {\n this.commandTelemetryService.trackStartCommand('EXT-iceCandidate');\n this.addWsHandlers(ws);\n }),\n );\n }\n\n private addWsHandlers(ws: WebSocket) {\n ws.onmessage = OnMessageHandler.bind(this);\n ws.onclose = OnCloseHandler.bind(this);\n ws.onerror = OnErrorHandler.bind(this);\n this.ws = ws;\n Logger.log('WS HANDLERS ADDED');\n OnOpenHandler.call(this);\n }\n\n /**\n * Adopt a live signalling socket opened by the `stream-prefetch.js`\n * head-script. The socket is already OPEN and `requestStream` was already\n * sent, so — unlike {@link addWsHandlers} — we attach message/close/error\n * handlers but deliberately skip {@link OnOpenHandler} (which would\n * `setCirrusConnected` + re-`sendRequestStream`). Reuses the head-script's\n * `correlationId` so subsequent correlated messages line up.\n */\n adoptSocket(ws: WebSocket, correlationId: string) {\n this.correlationId = correlationId;\n ws.onmessage = OnMessageHandler.bind(this);\n ws.onclose = OnCloseHandler.bind(this);\n ws.onerror = OnErrorHandler.bind(this);\n this.ws = ws;\n Logger.log(\n 'WS ADOPTED (handshake already done, requestStream already sent)',\n );\n }\n\n private showStatusMessage(statusMessage: string | null) {\n this.store.dispatch(setStatusMessage({ statusMessage }));\n }\n\n /**\n * Close the connection with the signaling server\n * @param data\n */\n close(data: CloseReason) {\n const { code, reason } = data;\n this.onWebRtcAnswer$.next(null);\n this.orchestrationRetrySub?.unsubscribe();\n\n if (this.ws) {\n Logger.warn('Closing existing WebSocket connection');\n const ws = this.ws;\n ws.onmessage = () => null;\n ws.onerror = () => null;\n ws.onclose = () => null;\n ws.onopen = () => null;\n this.ws = null;\n\n if (\n ws.readyState === WebSocket.CONNECTING ||\n ws.readyState === WebSocket.OPEN\n ) {\n ws.addEventListener('open', () => ws.close(code, reason), {\n once: true,\n });\n ws.close(code, reason);\n }\n }\n }\n\n send(data: AnySignalingMessage) {\n let dataString = data;\n if (typeof dataString !== 'string') {\n dataString = JSON.stringify(data);\n }\n if (this.ws && this.ws.readyState === WS_OPEN_STATE) {\n // Only parse-for-display when the logger would actually print — avoids a\n // JSON.parse on every outbound message in production (logger is a no-op).\n if (Logger.isDevMode) {\n Logger.colored(...COLOR_CODES.TO_CIRRUS, JSON.parse(dataString));\n }\n try {\n this.ws.send(dataString);\n } catch {\n Logger.error('No Websocket');\n }\n }\n }\n\n protected handleMessage(msg: MessageBase) {\n try {\n Logger.colored(...COLOR_CODES.FROM_CIRRUS, msg);\n this.wsMsgHandlers?.[msg.type]?.(msg as never);\n } catch {\n Logger.colored(\n ...COLOR_CODES.FROM_CIRRUS_ERROR,\n `Invalid CIRRUS message type: ${msg.type}`,\n );\n }\n }\n\n private setHandlersFromStream() {\n this.wsMsgHandlers.ping = PingHandler.bind(this);\n this.wsMsgHandlers.error = OrchestrationErrorHandler.bind(this);\n this.wsMsgHandlers.config = ConfigHandler.bind(this);\n this.wsMsgHandlers.answer = AnswerHandler.bind(this);\n this.wsMsgHandlers.ssInfo = SSInfoHandler.bind(this);\n this.wsMsgHandlers.playerCount = PlayerCountHandler.bind(this);\n this.wsMsgHandlers.streamerList = StreamerListHandler.bind(this);\n this.wsMsgHandlers.iceCandidate = IceCandidateHandler.bind(this);\n this.wsMsgHandlers.instanceReady = InstanceReadyHandler.bind(this);\n this.wsMsgHandlers.instanceReserved = InstanceReservedHandler.bind(this);\n this.wsMsgHandlers.playerDisconnected = PlayerDisconnectHandler.bind(this);\n this.wsMsgHandlers.streamerDisconnected =\n StreamerDisconnectHandler.bind(this);\n this.wsMsgHandlers.offer = OfferHandler.bind(this);\n }\n\n protected sendRequestStream() {\n const context = this.streamRequestContext();\n const environmentId = this.environmentId();\n if (!context || !environmentId) {\n return;\n }\n\n this.send({\n type: OrchestrationMessageTypes.requestStream,\n correlationId: this.correlationId,\n payload: {\n region: this.region(),\n environmentId,\n context,\n },\n });\n }\n\n /**\n * Check if the WebSocket connection is open and ready.\n */\n isConnected() {\n return !!(this.ws && this.ws.readyState === WS_OPEN_STATE);\n }\n\n private getRegion() {\n Logger.log('Start Getting Region');\n return this.regionsPingService.getFastest().pipe(take(1));\n }\n}\n","import { DataFlowMonitor } from '../../helpers/data-flow-monitor';\n\nexport interface FilterSettings {\n /**\n * Minimum number of kilobits per second to trigger low bandwidth\n */\n minimumBitrate: number;\n /**\n * Amount of a percentage drop to trigger a yellow warning\n */\n yellowFlag: number;\n /**\n * Amount of a percentage drop to trigger a red warning\n */\n redFlag: number;\n /**\n * Minimum number of frames per second to trigger low bandwidth\n */\n minimumFps: number;\n /**\n * Time to wait before checking if we can switch to low bandwidth\n */\n monitoringDelayTime: number;\n // initial guess in kbps\n initialBitrateEstimate: number;\n // initial error covariance\n initialErrorCovariance: number;\n // Q: how much we expect the bitrate to change between measurements\n processNoise: number;\n // R: variance of measurement noise\n measurementNoise: number;\n panelOpen: boolean;\n}\n\n/**\n * Default LBM Filter Parameters\n */\nexport const DefaultFilterModel: FilterSettings = {\n minimumBitrate: 1600,\n yellowFlag: 30,\n redFlag: 50,\n minimumFps: 5,\n monitoringDelayTime: 5000,\n initialBitrateEstimate: 1600,\n initialErrorCovariance: 1,\n processNoise: 3,\n measurementNoise: 500,\n panelOpen: false,\n} as const;\n\n/**\n * Global LBM Filter Parameters\n */\nexport const FilterModel = { ...DefaultFilterModel };\n\n/**\n * Bitrate Monitor Static Class\n */\nexport const BITRATE_MONITOR = new DataFlowMonitor(\n FilterModel.yellowFlag,\n FilterModel.redFlag,\n 20,\n);\n","import {\n BehaviorSubject,\n from,\n fromEvent,\n interval,\n map,\n merge,\n of,\n share,\n take,\n takeUntil,\n} from 'rxjs';\nimport { SubService } from './sub.service';\nimport { Injectable } from '@angular/core';\nimport { type AggregatedStat, type InboundVideoStats } from '../interfaces';\nimport { filter, switchMap } from 'rxjs/operators';\nimport {\n decodeData,\n dispatchResize,\n KalmanFilter1D,\n LatencyTimings,\n qpToQuality,\n} from '../helpers';\nimport {\n changeStatusMainVideoOnScene,\n unrealFeature,\n videoStreamInitialized,\n} from '../store';\nimport { STREAMING_AUDIO_ID, STREAMING_VIDEO_ID } from '../constants';\nimport { Logger, tapLog, Truthy } from '@3dsource/utils';\nimport {\n BITRATE_MONITOR,\n FilterModel,\n} from '../components/low-bandwidth/DataFlowConstants';\n\n@Injectable({ providedIn: 'root' })\nexport class VideoService extends SubService {\n private readonly isVideoPlaying = this.store.selectSignal(\n unrealFeature.selectIsVideoPlaying,\n );\n video: HTMLVideoElement | null = null;\n audio: HTMLAudioElement | null = null;\n\n private container: HTMLDivElement | null = null;\n private latencyTestTimings = new LatencyTimings();\n\n // BehaviorSubject (not Subject) so a late subscriber to `videoStats$` still\n // gets the current track. Adoption (`WebRtcPlayerService.adopt`) calls\n // `attachVideoStream` synchronously/early — before the resize and app-init\n // (`initAppByDataChannelReady$`) subscribers attach — and a plain Subject\n // would drop that emission, so the stats interval (and `setViewportReady`,\n // gated on `framesPerSecond`) would never start.\n private videoTrack$ = new BehaviorSubject<{\n stream: MediaStream;\n pcClient: RTCPeerConnection;\n } | null>(null);\n\n private VideoEncoderQP = 0;\n private aggregatedStats = {} as InboundVideoStats;\n kalmanFilter1D = new KalmanFilter1D(\n FilterModel.initialBitrateEstimate,\n FilterModel.initialErrorCovariance,\n FilterModel.processNoise,\n FilterModel.measurementNoise,\n );\n\n /**\n * Aggregate video stats and emit it as videoStats$\n */\n videoStats$ = this.videoTrack$.pipe(\n // If videoTrack$ emits null, switch to EMPTY → the current interval is canceled.\n switchMap((track) =>\n track\n ? // IMPORTANT! DO NOT CHANGE THOSE NUMBERS, LBM Stats are based on those values\n interval(250).pipe(\n map(() => track.pcClient),\n switchMap((pcClient) => from(this.getStats(pcClient))),\n filter(Truthy),\n )\n : of(null),\n ),\n filter(Truthy),\n share(),\n );\n\n private destroyAbort = new AbortController();\n\n constructor() {\n super();\n this.destroyRef.onDestroy(() => this.destroy());\n }\n\n setContainer(container: HTMLDivElement | null = null) {\n this.container = container;\n }\n\n setLatencyTimings(latencyTimings: string) {\n this.latencyTestTimings.SetUETimings(latencyTimings);\n }\n\n setEncoder(data: ArrayBuffer) {\n this.VideoEncoderQP = Number(decodeData(data));\n }\n\n create() {\n if (!this.container) {\n Logger.warn(\n 'VideoService.create(): no container set; <video> will be built but never attached to the DOM, which suppresses autoplay.',\n );\n }\n this.disconnect$\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe(() => this.destroy());\n this.destroy();\n this.createWebRtcVideo();\n this.createWebRtcAudio();\n }\n\n attachVideoStream(stream: MediaStream, pcClient: RTCPeerConnection) {\n if (!this.video) {\n Logger.error('Video element is not defined.');\n return;\n }\n // Safari refuses muted-autoplay for MediaStreams that carry unmuted\n // audio tracks, even when the <video> is muted. Route video tracks to\n // the video element and audio tracks (if any) to the audio element.\n this.video.srcObject = new MediaStream(stream.getVideoTracks());\n const audioTracks = stream.getAudioTracks();\n if (audioTracks.length && this.audio) {\n this.audio.srcObject = new MediaStream(audioTracks);\n this.playAudio(this.audio);\n }\n this.videoTrack$.next({ stream, pcClient });\n // Safari does not reliably honor the autoplay attribute when srcObject\n // is bound post-creation for a WebRTC MediaStream; trigger play()\n // explicitly and let safePlay() fall back if Safari refuses.\n void this.safePlay(this.video);\n }\n\n attachAudioStream(stream: MediaStream) {\n if (!this.audio) {\n return;\n }\n const audioTracks = stream.getAudioTracks();\n if (!audioTracks.length) {\n return;\n }\n this.audio.srcObject = new MediaStream(audioTracks);\n this.playAudio(this.audio);\n }\n\n play() {\n void this.safePlay(this.video);\n }\n\n async safePlay(video: HTMLVideoElement | null) {\n if (!video) {\n return;\n }\n\n try {\n await video.play();\n return;\n } catch (error: unknown) {\n if (\n error &&\n typeof error === 'object' &&\n 'name' in error &&\n error?.name !== 'NotAllowedError'\n ) {\n Logger.warn('safePlay() rejected with non-autoplay error:', error);\n return;\n }\n\n // Try silent inline autoplay\n video.muted = true;\n video.setAttribute('playsinline', '');\n try {\n await video.play();\n return;\n } catch {\n /* fall through */\n }\n\n // Last resort: wait for the next real user gesture and play with/without sound\n const resume = async () => {\n try {\n // choose whether to unmute here\n // video.muted = false;\n await video.play();\n } catch {\n /* ignore, maybe another gesture needed */\n } finally {\n window.removeEventListener('pointerdown', resume, true);\n window.removeEventListener('keydown', resume, true);\n }\n };\n\n window.addEventListener('pointerdown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n window.addEventListener('keydown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n }\n }\n\n private async getStats(\n pcClient: RTCPeerConnection | null,\n ): Promise<AggregatedStat | null> {\n if (!pcClient || pcClient.connectionState === 'closed') {\n return null;\n }\n\n try {\n const stats = await pcClient.getStats(null);\n // The service may have been destroyed while pcClient.getStats() was\n // pending; bail before writing back to this.aggregatedStats.\n if (!this.video) {\n return null;\n }\n return this.generateAggregatedStatsFunction(stats);\n } catch (err) {\n // Handle InvalidStateError or any transient WebRTC errors gracefully\n if (err instanceof DOMException && err.name === 'InvalidStateError') {\n Logger.warn('Peer connection is closed or unusable, skipping stats.');\n return null;\n }\n throw err;\n }\n }\n\n private generateAggregatedStatsFunction(\n stats: RTCStatsReport,\n ): AggregatedStat {\n const newStat: InboundVideoStats = {} as InboundVideoStats;\n\n // store each type of codec we can get stats on\n newStat.codecs = {};\n newStat.currentRoundTripTime = -1;\n\n stats.forEach((report) => {\n // Get the inbound-rtp for video\n if (report.type === 'inbound-rtp' && report.kind === 'video') {\n Object.assign(newStat, report);\n\n newStat.bytesReceivedStart =\n this.aggregatedStats && this.aggregatedStats.bytesReceivedStart\n ? this.aggregatedStats.bytesReceivedStart\n : report.bytesReceived;\n\n newStat.framesDecodedStart =\n this.aggregatedStats && this.aggregatedStats.framesDecodedStart\n ? this.aggregatedStats.framesDecodedStart\n : report.framesDecoded;\n\n newStat.timestampStart =\n this.aggregatedStats && this.aggregatedStats.timestampStart\n ? this.aggregatedStats.timestampStart\n : report.timestamp;\n\n if (this.aggregatedStats && this.aggregatedStats.timestamp) {\n // Get the mimetype of the video codec being used\n if (\n report.codecId &&\n this.aggregatedStats.codecs &&\n Object.hasOwn(this.aggregatedStats.codecs, report.codecId)\n ) {\n newStat.videoCodec = this.aggregatedStats.codecs[report.codecId];\n }\n\n if (this.aggregatedStats.bytesReceived) {\n // bitrate = bits received since last time / number of ms since last time\n // This is automatically in kbits (where k=1000) since time is in ms and stat we want is in seconds (so a '* 1000' then a '/ 1000' would negate each other)\n newStat.bitrate = Math.floor(\n (8 *\n ((newStat.bytesReceived || 0) -\n this.aggregatedStats.bytesReceived)) /\n (newStat.timestamp - this.aggregatedStats.timestamp),\n );\n }\n\n if (this.aggregatedStats.bytesReceivedStart) {\n newStat.avgBitrate = Math.floor(\n (8 *\n ((newStat.bytesReceived || 0) -\n this.aggregatedStats.bytesReceivedStart)) /\n (newStat.timestamp - this.aggregatedStats.timestampStart),\n );\n }\n\n if (this.aggregatedStats.framesDecodedStart) {\n newStat.avgFrameRate = Math.floor(\n ((newStat.framesDecoded || 0) -\n this.aggregatedStats.framesDecodedStart) /\n ((newStat.timestamp - this.aggregatedStats.timestampStart) /\n 1000),\n );\n }\n }\n }\n\n // Only read RTT from the *nominated* ICE candidate pair. The\n // stats report contains multiple `candidate-pair` entries (one\n // per host/srflx/relay combination tried during ICE); only the\n // nominated pair carries a meaningful `currentRoundTripTime`,\n // the rest typically report 0 or stale values. Without the\n // `nominated` filter, browser-specific iteration order decides\n // who \"wins\" the assignment — Chrome happens to put the\n // nominated pair last and gets the real number, Firefox puts it\n // first and the loop overwrites it with 0 from a non-selected\n // pair, so RTT in the viewer is always 0 in Firefox.\n if (\n report.type === 'candidate-pair' &&\n report.nominated === true &&\n Object.hasOwn(report, 'currentRoundTripTime')\n ) {\n newStat.currentRoundTripTime = report.currentRoundTripTime ?? 0;\n }\n\n if (\n report.type === 'transport' &&\n Object.hasOwn(report, 'selectedCandidatePairId')\n ) {\n const selectedPair = stats.get(report.selectedCandidatePairId);\n if (selectedPair) {\n const local = stats.get(selectedPair.localCandidateId);\n const remote = stats.get(selectedPair.remoteCandidateId);\n newStat.selectedPair = {\n local: { type: local?.candidateType, url: local?.url },\n remote: { type: remote?.candidateType, url: remote?.url },\n };\n }\n }\n\n // Store mimetype of each codec\n if (\n Object.hasOwn(newStat, 'codecs') &&\n report.type === 'codec' &&\n report.mimeType &&\n report.id\n ) {\n const codecId = report.id;\n newStat.codecs[codecId] = report.mimeType\n .replace('video/', '')\n .replace('audio/', '');\n }\n });\n\n newStat.pixelRatio = +window.devicePixelRatio.toFixed(2);\n if (this.aggregatedStats.receiveToCompositeMs) {\n newStat.receiveToCompositeMs = this.aggregatedStats.receiveToCompositeMs;\n this.latencyTestTimings.SetFrameDisplayDeltaTime(\n this.aggregatedStats.receiveToCompositeMs,\n );\n }\n\n // Calculate duration of run\n newStat.runTime = Math.floor(\n (newStat.timestamp - newStat.timestampStart) / 1000,\n );\n newStat.kalmanBitrate = Math.floor(\n this.kalmanFilter1D.update(\n newStat.bitrate || FilterModel.initialBitrateEstimate,\n ),\n );\n\n newStat.dataFlowCheckResult = BITRATE_MONITOR.addValue(\n newStat.kalmanBitrate,\n );\n\n newStat.bitrateDrop = Math.floor(\n newStat.dataFlowCheckResult.dropPercentage,\n );\n this.aggregatedStats = newStat;\n return this.onAggregatedStats(newStat);\n }\n\n private onAggregatedStats(aggregatedStats: InboundVideoStats) {\n return {\n quality: qpToQuality(this.VideoEncoderQP),\n aggregatedStats: {\n ...aggregatedStats,\n VideoEncoderQP: this.VideoEncoderQP,\n },\n };\n }\n\n private destroy() {\n if (!this.video) {\n return;\n }\n this.changeStatusMainVideoOnScene(false);\n // Cancel any gesture listeners armed by safePlay/playAudio in this\n // session, then arm a fresh controller for the next one. Without this,\n // listeners survive mid-session disconnect$ → destroy() cycles.\n this.destroyAbort.abort();\n this.destroyAbort = new AbortController();\n // Pause and detach streams before nulling — Safari can otherwise hold\n // on to the RTCRtpReceiver until GC eventually clears srcObject.\n this.video.pause();\n this.video.srcObject = null;\n if (this.audio) {\n this.audio.pause();\n this.audio.srcObject = null;\n }\n this.video = null;\n this.audio = null;\n this.videoTrack$.next(null);\n\n // Reset stat state to prevent stale deltas on next session\n this.aggregatedStats = {} as InboundVideoStats;\n this.VideoEncoderQP = 0;\n this.kalmanFilter1D = new KalmanFilter1D(\n FilterModel.initialBitrateEstimate,\n FilterModel.initialErrorCovariance,\n FilterModel.processNoise,\n FilterModel.measurementNoise,\n );\n BITRATE_MONITOR.reset();\n\n while (this.container?.firstChild) {\n this.container.removeChild(this.container.firstChild);\n }\n }\n\n private changeStatusMainVideoOnScene(isVideoPlaying: boolean) {\n if (this.isVideoPlaying() === isVideoPlaying) {\n return;\n }\n this.store.dispatch(changeStatusMainVideoOnScene({ isVideoPlaying }));\n }\n\n private createWebRtcVideo() {\n dispatchResize();\n const video = document.createElement('video');\n video.id = STREAMING_VIDEO_ID;\n video.playsInline = true;\n video.muted = true;\n // Safari occasionally resets `muted` when srcObject is rebound; the\n // `defaultMuted` reflection makes the muted state sticky and keeps the\n // muted-autoplay policy intact.\n video.defaultMuted = true;\n // No `autoplay` attribute on purpose: attachVideoStream() always calls\n // safePlay() explicitly, and the attribute would create a second\n // browser-internal play() Promise that we can't catch — which surfaces\n // as an unhandled rejection when destroy() pauses the element.\n video.preload = 'auto';\n video.disablePictureInPicture = true;\n\n this.video = video;\n this.container?.appendChild(this.video);\n\n fromEvent(this.video, 'play')\n .pipe(takeUntil(merge(this.disconnect$, this.destroy$)))\n .subscribe(() => this.changeStatusMainVideoOnScene(true));\n\n fromEvent(this.video, 'loadedmetadata')\n .pipe(\n take(1),\n filter((data) => this.video === data.target),\n tapLog('VideoService loadedmetadata:'),\n filter(() => !!this.video),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.store.dispatch(videoStreamInitialized()));\n }\n\n private createWebRtcAudio() {\n const audio = new Audio();\n audio.id = STREAMING_AUDIO_ID;\n this.audio = audio;\n }\n\n private async playAudio(audio: HTMLAudioElement) {\n try {\n await audio.play();\n return;\n } catch {\n // Wait for the next real user gesture and retry.\n const resume = async () => {\n try {\n await audio.play();\n } catch {\n /* ignore — caller may need another gesture */\n } finally {\n window.removeEventListener('pointerdown', resume, true);\n window.removeEventListener('keydown', resume, true);\n }\n };\n\n window.addEventListener('pointerdown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n window.addEventListener('keydown', resume, {\n once: true,\n capture: true,\n signal: this.destroyAbort.signal,\n });\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { fromEvent, merge, share, Subject, take, tap } from 'rxjs';\nimport { filter, map, takeUntil } from 'rxjs/operators';\nimport {\n answerSent,\n dataChannelConnected,\n disconnectStream,\n dropDC,\n dropPC,\n reconnectPeer,\n unrealFeature,\n} from '../store';\nimport { SubService } from './sub.service';\nimport { RECONNECT_CONFIG } from '../constants';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport type { ConfigMessage, DisconnectReasonType } from '../interfaces';\nimport {\n DisconnectReason,\n WSCloseCode_FORCE_CIRRUS_CLOSE,\n} from '../interfaces';\nimport { SignallingService } from './signalling.service';\nimport { VideoService } from './video.service';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport { ofType } from '@ngrx/effects';\n\n@Injectable({ providedIn: 'root' })\nexport class WebRtcPlayerService extends SubService {\n onDataChannelMessage$ = new Subject<ArrayBuffer>();\n\n private pcClient: RTCPeerConnection | null = null;\n private dcClient: RTCDataChannel | null = null;\n private readonly signallingSrv = inject(SignallingService);\n private readonly videoService = inject(VideoService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private cfg: RTCConfiguration = {};\n private useMic = false;\n private forceTURN = false;\n private forceMonoAudio = false;\n\n /** Whether the remote SDP has been applied to the current peer connection */\n private remoteDescriptionSet = false;\n /** ICE candidates received before the remote description was set */\n private iceCandidateBuffer: RTCIceCandidate[] = [];\n\n private isReconnecting = this.store.selectSignal(\n unrealFeature.selectIsReconnecting,\n );\n\n constructor() {\n super();\n this.init();\n this.actions$\n .pipe(ofType(dropDC), takeUntil(this.destroy$))\n .subscribe(() => this.dcClient?.close());\n this.actions$\n .pipe(ofType(dropPC), takeUntil(this.destroy$))\n .subscribe(() => this.pcClient?.close());\n this.destroyRef.onDestroy(() => this.closePC());\n }\n\n protected init() {\n this.signallingSrv.onConfig$\n .pipe(takeUntil(this.destroy$))\n .subscribe((config: ConfigMessage) => {\n this.videoService.create();\n this.setConfig(config);\n });\n\n // Server-initiated offer: set remote description and respond with answer\n this.signallingSrv.onOffer$\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe((offer) => {\n void this.handleServerOffer(offer);\n });\n\n // Answer to a client-initiated offer\n this.signallingSrv.onWebRtcAnswer$\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe((answer) => {\n void this.handleServerAnswer(answer);\n });\n\n // ICE candidates — buffered until remote description is set\n this.signallingSrv.onWebRtcIce$\n .pipe(takeUntil(this.destroy$))\n .subscribe((candidate) => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-iceCandidate',\n true,\n { multi: true },\n );\n\n if (this.remoteDescriptionSet) {\n this.handleCandidateFromServer(candidate);\n } else {\n this.iceCandidateBuffer.push(candidate);\n }\n });\n }\n\n /**\n * Handles an SDP offer received from the server.\n * Creates a new peer connection, applies the remote offer,\n * then responds with an SDP answer.\n *\n * The DataChannel is NOT created here — the server creates it,\n * and we receive it via the `datachannel` event on the peer connection.\n */\n private async handleServerOffer(\n offer: RTCSessionDescriptionInit,\n ): Promise<void> {\n Logger.info('Received offer from server, creating answer');\n try {\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n\n if (!this.pcClient) {\n this.setupPeerConnection(this.cfg);\n }\n\n const pc = this.pcClient;\n if (!pc) {\n return;\n }\n\n // Offer already defines media transceivers — don't add extras\n await pc.setRemoteDescription(offer);\n this.remoteDescriptionSet = true;\n this.flushIceCandidateBuffer();\n\n await this.createAnswer(pc);\n } catch (e) {\n Logger.error('Failed to handle server offer', e);\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebRTCError,\n message: 'WebRTCError: Failed to handle server offer',\n }),\n );\n }\n }\n\n /**\n * Handles an SDP answer received from the server in response to our offer.\n * Applies the remote description and flushes any buffered ICE candidates.\n */\n private async handleServerAnswer(\n answer: RTCSessionDescriptionInit,\n ): Promise<void> {\n Logger.info('Received answer from server');\n try {\n await this.pcClient?.setRemoteDescription(answer);\n this.remoteDescriptionSet = true;\n this.flushIceCandidateBuffer();\n } catch (e) {\n Logger.error('Failed to set remote description from answer', e);\n }\n }\n\n /** Drains buffered ICE candidates after the remote description has been set */\n private flushIceCandidateBuffer() {\n for (const candidate of this.iceCandidateBuffer) {\n this.handleCandidateFromServer(candidate);\n }\n this.iceCandidateBuffer.length = 0;\n }\n\n /**\n * Creates a client-initiated WebRTC offer and sends it to the server.\n * When the client offers, it also creates the DataChannel.\n * Used for peer reconnection through the existing signaling connection.\n */\n private async createWebRtcOffer(): Promise<void> {\n Logger.info('Creating client-initiated offer');\n try {\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n\n if (!this.pcClient) {\n this.setupPeerConnection(this.cfg);\n }\n\n const pc = this.pcClient;\n if (!pc) {\n return;\n }\n\n // Client offers: transceivers first, then DC, then offer\n await this.setupTransceiversAsync(pc);\n\n this.dcClient = this.createDataChannel(pc, 'UnrealDcConnection', {\n ordered: true,\n });\n\n await this.createOffer(pc);\n } catch (e) {\n Logger.error('Failed to create WebRTC offer', e);\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.WebRTCError,\n message: 'WebRTCError: Offer Error',\n }),\n );\n }\n }\n\n /**\n * Initializes a new RTCPeerConnection with event handlers.\n * Transceivers are NOT added here — the caller is responsible for adding\n * them at the correct point depending on the negotiation flow.\n */\n private setupPeerConnection(config: RTCConfiguration) {\n this.closePC();\n Logger.log('Creating new RTCPeerConnection with config');\n this.pcClient = new RTCPeerConnection(config);\n\n this.commandTelemetryService.trackStartCommand('EXT-Browser ICE gathering');\n this.commandTelemetryService.trackStartCommand(\n 'EXT-Browser ICE connection',\n );\n this.commandTelemetryService.trackStartCommand(\n 'EXT-Signaling state change',\n );\n\n this.handlePeerConnectionEvents(this.pcClient);\n\n this.disconnect$.pipe(take(1), takeUntil(this.destroy$)).subscribe(() => {\n this.closePC();\n });\n }\n\n private createDataChannel(\n pc: RTCPeerConnection,\n label: string,\n options: RTCDataChannelInit,\n ) {\n const datachannel = pc.createDataChannel(label, options);\n return this.setupDataChannelCallbacks(datachannel);\n }\n\n private handleCandidateFromServer(iceCandidate: RTCIceCandidate) {\n try {\n const candidate = new RTCIceCandidate(iceCandidate);\n Logger.info(\n '[Unreal ICE candidate]',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n );\n\n // If forcing TURN, reject any candidates not relay\n if (this.forceTURN) {\n if (candidate.candidate.indexOf('relay') < 0) {\n Logger.warn(\n 'Dropping candidate because it was not TURN relay.',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n );\n return;\n }\n }\n this.pcClient?.addIceCandidate(candidate).catch((e) => {\n Logger.warn('Failed to add ICE candidate', e);\n });\n } catch (e) {\n Logger.error('Error handleCandidateFromServer', e);\n }\n }\n\n /**\n * Reorders the `m=video` line in the SDP so that payload types matching\n * the given H.264 `profile-level-id` appear first, making the browser\n * prefer that profile during codec negotiation.\n *\n * A `profile-level-id` is a 3-byte hex string (`XXYYZZ`) defined in\n * RFC 6184 that encodes three H.264 parameters:\n * - **Profile IDC** (`XX`) — the H.264 profile.\n * - **Profile IOP** (`YY`) — constraint flags that further narrow the profile.\n * - **Level IDC** (`ZZ`) — the level which caps resolution/framerate/bitrate.\n *\n * ### H.264 profiles relevant to Unreal Engine Pixel Streaming\n *\n * | profile-level-id | Profile | Level | Notes |\n * |------------------|----------------------------|-------|----------------------------------------------|\n * | `42001f` | Baseline | 3.1 | No B-frames, low latency; legacy devices |\n * | `42e01f` | Constrained Baseline | 3.1 | Widest HW decode support; **recommended** |\n * | `4d001f` | Main | 3.1 | B-frames + CABAC; better compression |\n * | `4d4028` | Main | 4.0 | Up to 1080p60; common desktop target |\n * | `640028` | High | 4.0 | Best quality/compression; most GPUs support |\n * | `64002a` | High | 4.2 | Up to 1080p120 or 4K30 |\n * | `640033` | High | 5.1 | Up to 4K60; requires modern HW |\n * | `640034` | High | 5.2 | Up to 4K120; high-end HW only |\n * | `6e001f` | High 10 | 3.1 | 10-bit color; limited browser support |\n * | `f4001f` | High 4:4:4 Predictive | 3.1 | Lossless capable; rare in browsers |\n *\n * UE Pixel Streaming defaults to Constrained Baseline (`42e01f`) or High (`6400xx`)\n * depending on the engine version and `WebRTC.H264Profile` CVar.\n *\n * We prioritize `42e01f` because it guarantees hardware decoding on\n * virtually all client devices (desktop, mobile, embedded), avoiding\n * fallback to software decoding or negotiation of a higher profile\n * that the client GPU may not speed up.\n */\n private prioritizeH264Profile(sdp: string, profileLevelId: string): string {\n const lines = sdp.split('\\r\\n');\n const targetPts: string[] = [];\n\n for (const line of lines) {\n if (\n line.startsWith('a=fmtp:') &&\n line.toLowerCase().includes(`profile-level-id=${profileLevelId}`)\n ) {\n const pt = line.split(':')[1]?.split(' ')[0];\n if (pt) targetPts.push(pt);\n }\n }\n\n if (targetPts.length === 0) return sdp;\n\n return lines\n .map((line) => {\n if (!line.startsWith('m=video')) return line;\n const parts = line.split(' ');\n // parts: m=video <port> <proto> <pt1> <pt2> ...\n const header = parts.slice(0, 3);\n const pts = parts.slice(3);\n const prioritized = [\n ...targetPts.filter((pt) => pts.includes(pt)),\n ...pts.filter((pt) => !targetPts.includes(pt)),\n ];\n return [...header, ...prioritized].join(' ');\n })\n .join('\\r\\n');\n }\n\n private mungeSDP(sdp: string) {\n let mungedSDP = this.prioritizeH264Profile(sdp, '42e01f');\n\n mungedSDP = mungedSDP.replace(\n /(a=fmtp:\\d+ .*level-asymmetry-allowed=.*)\\r\\n/gm,\n '$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\\r\\n',\n );\n\n // Set max bitrate to highest bitrate Opus supports\n let audioSDP = 'maxaveragebitrate=510000;';\n\n if (this.useMic) {\n // Set the max capture rate to 48khz (so we can send high-quality audio from mic)\n audioSDP += 'sprop-maxcapturerate=48000;';\n }\n\n // Force mono or stereo based on whether ?forceMono was passed or not\n audioSDP += this.forceMonoAudio ? 'stereo=0;' : 'stereo=1;';\n\n // Enable in-band forward error correction for opus audio\n audioSDP += 'useinbandfec=1';\n\n // We use the line 'useinbandfec=1' (which Opus uses) to set our Opus specific audio parameters.\n mungedSDP = mungedSDP?.replace('useinbandfec=1', audioSDP);\n\n return mungedSDP;\n }\n\n /**\n * Closes existing PeerConnection and DataChannel, resets negotiation state.\n */\n closePC() {\n if (this.pcClient) {\n Logger.warn('Closing existing PeerConnection');\n }\n this.pcClient?.close();\n this.pcClient = null;\n\n if (this.dcClient) {\n Logger.warn('Closing existing DataChannel');\n }\n this.dcClient?.close();\n this.dcClient = null;\n\n this.remoteDescriptionSet = false;\n this.iceCandidateBuffer.length = 0;\n }\n\n /**\n * Single source of truth for tearing down the remote connection: closes the\n * signaling WebSocket and then the PeerConnection/DataChannel.\n *\n * Called by the `destroyRemoteConnections$` effect and, as a\n * lifecycle-independent safeguard, by `UnrealSceneComponent.onDestroy` (the\n * route-scoped effects may already be torn down on navigation). Both close\n * steps are idempotent, so invoking this twice in one teardown is a harmless\n * no-op.\n */\n releaseRemoteConnections(reason: DisconnectReasonType) {\n this.signallingSrv.close({ code: WSCloseCode_FORCE_CIRRUS_CLOSE, reason });\n this.closePC();\n }\n\n canSend() {\n return this.dcClient && this.dcClient.readyState === 'open';\n }\n\n send(data: ArrayBuffer) {\n if (this.canSend()) {\n this.dcClient?.send(data);\n } else {\n Logger.colored(\n 'black',\n 'yellow',\n `DataChannel connection not prepared or in state: ${this.dcClient?.readyState}`,\n );\n\n // Trigger peer reconnection if DC is not open and we're not yet reconnecting\n this.tryReconnectOnSendFailure();\n }\n }\n\n /**\n * Attempts to reconnect the peer when send fails due to DataChannel not being open.\n * This handles cases where the DC connection is broken, but no error events are fired.\n */\n private tryReconnectOnSendFailure() {\n // Skip if already reconnecting or signaling is not connected\n if (this.isReconnecting()) {\n Logger.info(\n '[Reconnect] Already reconnecting, skipping duplicate attempt',\n );\n return;\n }\n\n if (!this.signallingSrv.isConnected()) {\n Logger.warn('[Reconnect] Cannot reconnect: Signaling not connected');\n return;\n }\n\n // Check if DC exists but is in a non-open state (closing, closed, or connecting stuck)\n const dcState = this.dcClient?.readyState;\n if (dcState && dcState !== 'open') {\n Logger.warn(\n `[Reconnect] DataChannel in \"${dcState}\" state during send, initiating peer reconnection`,\n );\n this.store.dispatch(\n reconnectPeer({\n attempt: 1,\n maxAttempts: RECONNECT_CONFIG.maxAttempts,\n delay: 0,\n }),\n );\n }\n }\n\n /**\n * Reconnects only the WebRTC peer connection without re-establishing signaling.\n * Closes the current PeerConnection and creates a new client-initiated offer\n * through the existing WebSocket connection.\n * @returns true if reconnection was initiated, false if signaling is not connected\n */\n reconnectPeer(): boolean {\n if (!this.signallingSrv.isConnected()) {\n Logger.error(\n '[Reconnect] Cannot reconnect peer: Signaling not connected',\n );\n return false;\n }\n\n if (!this.cfg || Object.keys(this.cfg).length === 0) {\n Logger.error('[Reconnect] Cannot reconnect peer: No config available');\n return false;\n }\n\n Logger.info('[Reconnect] Initiating peer reconnection');\n\n // Close only the PeerConnection, keep WebSocket alive\n this.closePC();\n\n // Create a new WebRTC offer using the stored config\n void this.createWebRtcOffer();\n\n return true;\n }\n\n /**\n * Adopt a fully-negotiated connection prefetched by `stream-prefetch.js`:\n * take ownership of its PeerConnection, DataChannel and media stream instead\n * of running the handshake. The head-script attached property-based handlers\n * (`pc.onicecandidate`, `dc.onmessage`, …) and buffered inbound DC messages;\n * here we detach those, wire our own (addEventListener-based) handlers, replay\n * the buffer in order, then drive `onDataChannelConnected` manually because the\n * DataChannel is already open. A native `open` event may still be queued, so the\n * adopted channel deliberately does not subscribe to it.\n */\n adopt(\n pc: RTCPeerConnection,\n dc: RTCDataChannel,\n stream: MediaStream,\n config: RTCConfiguration,\n dcBuffer: ArrayBuffer[],\n ) {\n // No prior pc/dc should exist on a fresh boot; closePC is idempotent.\n this.closePC();\n this.pcClient = pc;\n this.cfg = config ?? {};\n // Connection is fully negotiated — any late ICE goes straight in, not buffered.\n this.remoteDescriptionSet = true;\n\n // Detach the head-script's property handlers so events aren't processed\n // twice once our addEventListener-based handlers are attached below.\n pc.onicecandidate = null;\n pc.ondatachannel = null;\n pc.ontrack = null;\n\n this.handlePeerConnectionEvents(pc);\n // `setupPeerConnection` normally wires this; replicate for the adopted pc.\n this.disconnect$\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe(() => this.closePC());\n\n // Wire the already-open DataChannel. Nulling then re-listening is safe:\n // these statements run synchronously, so no `message` event can interleave\n // between detaching the script's handler and replaying the buffer.\n dc.onmessage = null;\n dc.onopen = null;\n dc.onclose = null;\n // Adoption announces the already-open channel manually below. Do not\n // subscribe to a native `open` event that may still be queued.\n this.dcClient = this.setupDataChannelCallbacks(dc, false);\n for (const buffered of dcBuffer) {\n this.onDataChannelMessage$.next(buffered);\n }\n // DC is open already: balance the span `setupDataChannelCallbacks` opened\n // (its `open` handler won't fire) and announce the connection ourselves.\n this.commandTelemetryService.trackStopCommand('EXT-DataChannel Connection');\n this.onDataChannelConnected();\n\n // Attach the prefetched media to a fresh <video> (container is set by the\n // scene component before `initSignalling`, so `create()` has a DOM target).\n this.videoService.create();\n this.videoService.attachVideoStream(stream, pc);\n }\n\n private setConfig(parOptions = {} as ConfigMessage) {\n const urlParams = new URLSearchParams(window.location.search);\n\n //**********************\n //Config setup\n //**********************\n this.cfg = { ...parOptions.peerConnectionOptions };\n\n this.forceTURN = urlParams.has('ForceTURN');\n if (this.forceTURN) {\n Logger.info(\n 'Forcing TURN usage by setting ICE Transport Policy in peer connection config.',\n );\n this.cfg.iceTransportPolicy = 'relay';\n }\n\n this.cfg.bundlePolicy = urlParams.has('ForceMaxBundle')\n ? 'max-bundle'\n : 'balanced';\n\n this.cfg.iceCandidatePoolSize = 1;\n\n // When ?useMic check for SSL or localhost\n const isLocalhostConnection =\n location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const isHttpsConnection = location.protocol === 'https:';\n if (this.useMic && !isLocalhostConnection && !isHttpsConnection) {\n this.useMic = false;\n Logger.error(\n 'Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access.',\n );\n Logger.error(\n \"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'\",\n );\n }\n\n this.setupPeerConnection(this.cfg);\n }\n\n private handlePeerConnectionEvents(pcClient: RTCPeerConnection) {\n fromEvent(pcClient, 'signalingstatechange')\n .pipe(\n map(() => this.pcClient?.signalingState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Signaling state change] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Signaling state change',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'iceconnectionstatechange')\n .pipe(\n map(() => this.pcClient?.iceConnectionState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Browser ICE connection] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Browser ICE connection',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'icegatheringstatechange')\n .pipe(\n map(() => this.pcClient?.iceGatheringState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[Browser ICE gathering] |', state, '|');\n this.commandTelemetryService.trackStopCommand(\n 'EXT-Browser ICE gathering',\n true,\n { state, multi: true },\n );\n });\n\n fromEvent(pcClient, 'connectionstatechange')\n .pipe(\n map(() => this.pcClient?.connectionState),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((state) => {\n Logger.info('[RTCPeerConnection state] |', state, '|');\n });\n\n fromEvent<RTCPeerConnectionIceEvent>(pcClient, 'icecandidate')\n .pipe(\n map((e: RTCPeerConnectionIceEvent) => e.candidate),\n filter(Truthy),\n tap((candidate: RTCIceCandidate) =>\n Logger.info(\n '[Browser ICE candidate]',\n '| Type=',\n candidate.type,\n '| Protocol=',\n candidate.protocol,\n '| Address=',\n candidate.address,\n '| Port=',\n candidate.port,\n '|',\n ),\n ),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((candidate) =>\n this.signallingSrv.send({ type: 'iceCandidate', candidate }),\n );\n\n // When the server creates the DataChannel (server-offer flow),\n // we receive it here via the 'datachannel' event\n fromEvent<RTCDataChannelEvent>(pcClient, 'datachannel')\n .pipe(\n tap((e) =>\n Logger.info(\n `[DATACHANNEL] Received remote DC: label=\"${e.channel.label}\" id=${e.channel.id} protocol=\"${e.channel.protocol}\" ordered=${e.channel.ordered}`,\n ),\n ),\n map((e: RTCDataChannelEvent) => e.channel),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((datachannel) => {\n this.dcClient = this.setupDataChannelCallbacks(datachannel);\n });\n\n const onTrack$ = fromEvent<RTCTrackEvent>(pcClient, 'track').pipe(\n takeUntil(merge(this.disconnect$, this.destroy$)),\n filter((e) => !!e.track),\n tap((e) =>\n Logger.info(\n 'Got track - ' +\n e.track.kind +\n ' id=' +\n e.track.id +\n ' readyState=' +\n e.track.readyState,\n ),\n ),\n share(),\n );\n\n onTrack$\n .pipe(\n filter((e: RTCTrackEvent) => e.track.kind === 'audio'),\n map((e) => e.streams[0]),\n )\n .subscribe((stream) => this.videoService.attachAudioStream(stream));\n\n onTrack$\n .pipe(\n filter((e: RTCTrackEvent) => e.track.kind === 'video'),\n map((e) => e.streams[0]),\n tap(() => Logger.info('Set video source from video track ontrack.')),\n )\n .subscribe((stream) => {\n if (this.pcClient) {\n this.videoService.attachVideoStream(stream, this.pcClient);\n }\n });\n }\n\n private async setupTransceiversAsync(pc: RTCPeerConnection): Promise<void> {\n const hasTransceivers = pc.getTransceivers().length > 0;\n\n // Set up a transceiver for getting UE video\n pc.addTransceiver('video', { direction: 'recvonly' });\n\n // Set up a transceiver for sending mic audio to UE and receiving audio from UE\n if (!this.useMic) {\n pc.addTransceiver('audio', { direction: 'recvonly' });\n } else {\n const audioSendOptions = this.useMic\n ? {\n autoGainControl: false,\n channelCount: 1,\n echoCancellation: false,\n latency: 0,\n noiseSuppression: false,\n sampleRate: 48000,\n sampleSize: 16,\n volume: 1.0,\n }\n : false;\n\n // Note using mic on android chrome requires SSL or chrome://flags/ \"unsafely-treat-insecure-origin-as-secure\"\n const stream = await navigator.mediaDevices.getUserMedia({\n video: false,\n audio: audioSendOptions,\n });\n if (stream) {\n if (hasTransceivers) {\n for (const transceiver of pc.getTransceivers()) {\n if (\n transceiver &&\n transceiver.receiver &&\n transceiver.receiver.track &&\n transceiver.receiver.track.kind === 'audio'\n ) {\n for (const track of stream.getTracks()) {\n if (track.kind && track.kind === 'audio') {\n await transceiver.sender.replaceTrack(track);\n transceiver.direction = 'sendrecv';\n }\n }\n }\n }\n } else {\n for (const track of stream.getTracks()) {\n if (track.kind && track.kind === 'audio') {\n pc.addTransceiver(track, { direction: 'sendrecv' });\n }\n }\n }\n } else {\n pc.addTransceiver('audio', { direction: 'recvonly' });\n }\n }\n }\n\n private setupDataChannelCallbacks(\n datachannel: RTCDataChannel,\n subscribeToOpen = true,\n ): RTCDataChannel | null {\n try {\n Logger.log(\n `[DATACHANNEL] Setting up datachannel \"${datachannel.label}\" callbacks...`,\n );\n this.commandTelemetryService.trackStartCommand(\n 'EXT-DataChannel Connection',\n );\n // Inform browser we would like binary data as an ArrayBuffer (FF chooses Blob by default!)\n datachannel.binaryType = 'arraybuffer';\n\n fromEvent(datachannel, 'close')\n .pipe(\n // Only dispatch disconnect if not already reconnecting to avoid infinite loops\n filter(() => !this.isReconnecting()),\n take(1),\n takeUntil(this.destroy$),\n )\n .subscribe((e) => {\n Logger.warn(\n `[DATACHANNEL] Data channel disconnected: ${datachannel.label}(${datachannel.id})`,\n e,\n );\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DataChannelClosed,\n message: 'DataChannelClosed',\n }),\n );\n });\n\n fromEvent(datachannel, 'error')\n .pipe(takeUntil(merge(this.disconnect$, this.destroy$)))\n .subscribe((e) => {\n const message = `[DATACHANNEL] Data channel \"${datachannel.label}\" error. id:${datachannel.id}`;\n Logger.error(message, e);\n });\n\n if (subscribeToOpen) {\n fromEvent(datachannel, 'open')\n .pipe(\n tap(() => {\n Logger.info(\n `[DATACHANNEL] Data channel \"${datachannel.label}\" connected. id:${datachannel.id}`,\n );\n }),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe(() => {\n this.commandTelemetryService.trackStopCommand(\n 'EXT-DataChannel Connection',\n );\n this.onDataChannelConnected();\n });\n }\n\n fromEvent<MessageEvent>(datachannel, 'message')\n .pipe(\n /* tap((e: MessageEvent) => {\n const view = new Uint8Array(e.data);\n Logger.info(\n `[DATACHANNEL] Message received on \"${datachannel.label}\" id=${datachannel.id}, byteCode=${view[0]}, size=${view.byteLength}`,\n );\n }),*/\n map((e: MessageEvent) => e.data),\n takeUntil(merge(this.disconnect$, this.destroy$)),\n )\n .subscribe((data) => this.onDataChannelMessage$.next(data));\n\n return datachannel;\n } catch (e) {\n Logger.warn('[DATACHANNEL] Datachannel setup caused an exception: ', e);\n return null;\n }\n }\n\n private onDataChannelConnected() {\n let statusMessage = 'Session connected, video stream starting.';\n if (navigator.userAgent.includes('Firefox')) {\n statusMessage +=\n '\\n If you are experiencing connection problems please try Google Chrome';\n }\n this.store.dispatch(dataChannelConnected({ statusMessage }));\n }\n\n /**\n * Creates an SDP offer, applies SDP munging, sets it as a local description,\n * and sends it to the server via signaling.\n * Transceivers already configure media directions, so deprecated\n * offerToReceive* options are not used.\n */\n private async createOffer(pcClient: RTCPeerConnection): Promise<void> {\n try {\n const offer = await pcClient.createOffer();\n offer.sdp = this.mungeSDP(offer.sdp ?? '');\n await pcClient.setLocalDescription(offer);\n this.signallingSrv.send(offer);\n } catch {\n Logger.error(\"Couldn't create offer\");\n }\n }\n\n /**\n * Creates an SDP answer, applies SDP munging, sets it as a local description,\n * and sends it to the server via signaling.\n */\n private async createAnswer(pcClient: RTCPeerConnection): Promise<void> {\n try {\n const answer = await pcClient.createAnswer();\n answer.sdp = this.mungeSDP(answer.sdp ?? '');\n await pcClient.setLocalDescription(answer);\n this.signallingSrv.send(answer);\n // Observability signal for the signaling waterfall — the handshake\n // went \"answer sent\" between `offer received` and `datachannel_ready`.\n this.store.dispatch(answerSent());\n } catch (e) {\n Logger.error(\"Couldn't create answer\", e);\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { Observable, defer, of } from 'rxjs';\nimport { Logger } from '@3dsource/utils';\nimport { streamAdopted } from '../store/unreal/unreal.actions';\nimport { WS_OPEN_STATE } from '../constants';\n// Leaf imports (not the `../services` barrel) to keep the SubService extends\n// graph loading deterministically, matching the rest of the module.\nimport { SignallingService } from './signalling.service';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\n\n/**\n * Adopts a WebRTC connection prefetched by the `stream-prefetch.js` head-script\n * and parked on `window.__stream`, instead of running `connectToSignaling` from\n * scratch. Called from the same seam where signalling normally starts\n * (`connectToSignaling$` effect); if there is nothing ready to adopt it returns\n * `false` and the caller falls back to the normal connect — strictly additive.\n */\n@Injectable({ providedIn: 'root' })\nexport class StreamAdoptionService {\n private readonly store = inject(Store);\n private readonly signalling = inject(SignallingService);\n private readonly webRtc = inject(WebRtcPlayerService);\n\n /**\n * Decide adoption, WAITING for an in-flight prefetch instead of racing it.\n *\n * - nothing parked → emit `false` at once (caller connects normally).\n * - already settled (`ready`/`failed`/`adopted`) → adopt-if-ready at once.\n * - still `connecting` → wait for the script's `onSettled` callback and\n * adopt-if-ready the instant it fires (event-driven, zero polling latency).\n *\n * Deliberately NO time budget: for DIRECT orchestration the prefetch holds\n * the socket open while the orchestrator provisions a machine, which can take\n * minutes (150–200s+). A fixed deadline would make Angular give up and open a\n * second connection mid-provisioning — exactly the race/orphan this avoids.\n * The wait is bounded by liveness instead: the script flips the parked state\n * to `failed` on a dead socket (`ws.onclose`/`onerror`), and the caller wraps\n * this in `takeUntil(abortEstablishingConnection)`, so a route change / teardown\n * cancels it. Emits exactly once. Cancelling runs no adoption — which is what\n * stops a fast route-switch from starting overlapping connections.\n *\n * Wrapped in `defer` so the `tryAdopt()` side effect (which dispatches\n * `streamAdopted`) runs at SUBSCRIPTION time, not when the observable is\n * built. The effect prepends `startWith(setEstablishingConnection(true))`,\n * which starts the telemetry session and subscribes its phase catalog; that\n * must happen BEFORE `streamAdopted` → `regionTelemetryOnAdopt$` replays\n * `regionResolved`, or the region phase fires into a session that doesn't\n * exist yet and is lost. `defer` guarantees that ordering.\n */\n awaitAndAdopt$(): Observable<boolean> {\n return defer(() => {\n const parked = window.__stream;\n if (!parked) {\n return of(false);\n }\n if (parked.state !== 'connecting') {\n return of(this.tryAdopt());\n }\n Logger.info(\n '[Adoption] Prefetch in progress — waiting before connecting',\n );\n return this.awaitSettled$(parked);\n });\n }\n\n /**\n * Event-driven wait: the script fires `onSettled` the instant it parks\n * `ready`/`failed`, so we adopt with zero polling lag. Emits exactly once.\n *\n * No timer/budget by design: an indefinitely `connecting` stream is valid\n * (DIRECT orchestration holds the socket open for minutes while it\n * provisions), and every terminal state — including a dead socket — flips to\n * `ready`/`failed` and fires the hook. Teardown (route change → unsubscribe)\n * sets `done`, so a late callback after cancel can't trigger a stray adoption.\n */\n private awaitSettled$(\n parked: NonNullable<Window['__stream']>,\n ): Observable<boolean> {\n return new Observable<boolean>((subscriber) => {\n let done = false;\n parked.onSettled(() => {\n if (done) return;\n done = true;\n subscriber.next(this.tryAdopt());\n subscriber.complete();\n });\n return () => {\n done = true;\n };\n });\n }\n\n /**\n * @returns `true` if a ready parked stream was adopted (caller must NOT\n * start a fresh connection), `false` otherwise.\n */\n tryAdopt(): boolean {\n const parked = window.__stream;\n if (!parked || parked.state !== 'ready') {\n return false;\n }\n // A ready stream whose transport died before adoption is useless — fall back.\n if (\n !parked.ws ||\n parked.ws.readyState !== WS_OPEN_STATE ||\n !parked.pc ||\n !parked.dc ||\n !parked.stream\n ) {\n Logger.warn(\n '[Adoption] Parked stream is ready but transport is not live',\n );\n return false;\n }\n\n Logger.info('[Adoption] Adopting prefetched stream', parked.timings);\n\n // Clear the script's timers and mark the handoff complete.\n parked.adopt();\n\n // Flag cirrus connected (so a later `initSignalling` won't open a 2nd\n // connection), record the adopted machine, and hydrate the streamer info\n // (`ssData`) the prefetch captured from the `ssInfo` message. NOTE:\n // clientId/viewId are left untouched — the host app (metabox) already set\n // them authoritatively from its own data before `initSignalling`; the\n // script's ids are only used internally to establish the connection.\n this.store.dispatch(\n streamAdopted({\n machineId: parked.machineId ?? null,\n ssData: parked.ssData ?? null,\n timings: parked.timings ?? null,\n }),\n );\n\n // Hand the live socket over without re-sending `requestStream`, reusing the\n // script's correlationId (the one `requestStream` was already sent with).\n this.signalling.adoptSocket(parked.ws, parked.ids.correlationId);\n\n // Take ownership of pc/dc/media + replay buffered DC traffic. This drives\n // `dataChannelConnected`, which the `unrealReceiverReady$` effect turns into\n // `dataChannelReady` → app init (console commands, loopback, viewport).\n this.webRtc.adopt(\n parked.pc,\n parked.dc,\n parked.stream,\n parked.config ?? {},\n parked.dcBuffer,\n );\n\n return true;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { Actions, ofType } from '@ngrx/effects';\nimport { defer, of, take, timeout } from 'rxjs';\nimport { catchError, filter, map } from 'rxjs/operators';\nimport { generateUuid, tapLog, Truthy } from '@3dsource/utils';\nimport type {\n FCameraChangedCallback,\n FOnChangeSequenceChangedCallback,\n FOnFinishSequenceChangedCallback,\n FOnFocusObjectCallback,\n FOnObjectTransformChangedCallback,\n FOnSceneStateCallback,\n MetaBoxCallbackList,\n MetaBoxCommandList,\n} from '@3dsource/types-unreal';\nimport { unrealCommandCallback } from '../store';\n\n/**\n * `MetaBoxCommandList` / `MetaBoxCallbackList` are keyed by string-**enum**\n * members, which are nominal: a plain string literal like\n * `'loadProductCommandCallback'` is NOT assignable to the enum key\n * `MetaBoxCallback.FLoadProductCommandCallback`. So template-literal lookups\n * against `keyof MetaBoxCallbackList` always miss. We first re-key the callback\n * list by its plain string values, then bridge command→callback by string.\n */\ntype CallbackByString = {\n [C in keyof MetaBoxCallbackList as `${C & string}`]: MetaBoxCallbackList[C];\n};\n\n/**\n * Resolves a command key to its matching callback type via the\n * `F*Command` → `F*CommandCallback` naming convention\n * (e.g. command `'loadProduct'` → callback `'loadProductCommandCallback'`).\n */\ntype CommandCallbackFor<K extends keyof MetaBoxCommandList> =\n `${K & string}CommandCallback` extends keyof CallbackByString\n ? CallbackByString[`${K & string}CommandCallback`]\n : never;\n\n/** Every command keyed to its real callback type. */\ntype UnrealCommandCallbackMap = {\n [K in keyof MetaBoxCommandList]: CommandCallbackFor<K>;\n};\n\n/**\n * Custom Unreal callback events that are not part of MetaBoxCommandList.\n * These events are pushed from Unreal to the frontend via the data channel.\n * Keys are the runtime `command` values used for filtering.\n */\nexport interface UnrealCallbackEventMap {\n onSceneState: FOnSceneStateCallback;\n onFocusObject: FOnFocusObjectCallback;\n cameraChanged: FCameraChangedCallback;\n onObjectTransformChanged: FOnObjectTransformChangedCallback;\n onChangeSequence: FOnChangeSequenceChangedCallback;\n onFinishedSequence: FOnFinishSequenceChangedCallback;\n}\n\n/**\n * Combined map of all known callback types: every command mapped to its real\n * callback (`MetaBoxCallbackList`) + the custom event callbacks.\n */\nexport type UnrealCallbackDescriptor = UnrealCommandCallbackMap &\n UnrealCallbackEventMap;\n\n@Injectable({ providedIn: 'root' })\nexport class UnrealCallbackService {\n private readonly actions$ = inject(Actions);\n\n /**\n * Listens for unreal command callbacks matching a specific command or event type.\n *\n * Supports both MetaBoxCommand keys (e.g. `MetaBoxCommand.FLoadProductCommand`)\n * and custom Unreal callback events (e.g. `'cameraChanged'`, `'onSceneState'`).\n *\n * @param command - The command or event key to filter callbacks by\n * @returns Observable that emits matching callback payloads\n *\n * @example\n * ```ts\n * // Listen for a MetaBox command callback\n * this.unrealCallbackService\n * .fromUnrealCallback(MetaBoxCommand.FLoadProductCommand)\n * .subscribe(data => console.log(data));\n *\n * // Listen for a custom Unreal event\n * this.unrealCallbackService\n * .fromUnrealCallback('cameraChanged')\n * .subscribe(data => console.log(data));\n * ```\n */\n fromUnrealCallback<K extends keyof UnrealCallbackDescriptor>(command: K) {\n return this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json ? json.commandCallback : json,\n ),\n filter((json) => json.command === command),\n // Cast is required: after a `command`-based filter TS cannot narrow to a\n // type discriminated on `callback`. The unwrapped object IS the full callback.\n map((data) => data as UnrealCallbackDescriptor[K]),\n );\n }\n\n /**\n * Sends a command and observes the matching response by correlationId.\n * Replaces the old `observeCommandResponse` standalone function.\n *\n * @param data - The command data to send\n * @param sender - Function to send the command to Unreal\n * @param timeOut - Timeout in ms (default 60000)\n * @param dispatchOnTimeout - Whether to emit on timeout (default true)\n *\n * @example\n * ```ts\n * this.unrealCallbackService\n * .observeCommandResponse<FLoopBackCommand['command']>(\n * { command: MetaBoxCommand.FLoopBackCommand },\n * (data) => this.communicator.sendCommandToUnreal(data),\n * )\n * .subscribe();\n * ```\n */\n observeCommandResponse<\n K extends keyof MetaBoxCommandList,\n T extends MetaBoxCommandList[K] = MetaBoxCommandList[K],\n >(\n data: T,\n sender: (data: T) => void,\n timeOut = 60000,\n dispatchOnTimeout = true,\n ) {\n const correlationId = generateUuid();\n\n return defer(() => {\n const observable = this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json ? json.commandCallback : json,\n ),\n filter((json) => json.correlationId === correlationId),\n timeout(timeOut),\n catchError(() =>\n dispatchOnTimeout\n ? of({ command: 'timeout', correlationId: 'timeout' })\n : of(null),\n ),\n take(1),\n tapLog('Command Response Observer'),\n filter(Truthy),\n // Cast: response is matched by correlationId, so it is the callback for K.\n map((data) => data as CommandCallbackFor<K>),\n );\n\n setTimeout(() => sender({ ...data, correlationId }), 0);\n\n return observable;\n });\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { Subject, takeUntil, throttleTime } from 'rxjs';\nimport { CommandTelemetryService } from './command-telemetry.service';\nimport type { MessageTypeValues } from '../constants';\nimport { MessageType, UNREAL_CONFIG } from '../constants';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\nimport { COLOR_CODES, generateUuid, Logger } from '@3dsource/utils';\nimport {\n commandStarted,\n dataChannelConnected,\n resetAfk,\n unrealFeature,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class UnrealCommunicatorService extends SubService {\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private cirrusConnected = this.store.selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n private readonly afkIgnoredCommands = new Set(['executeConsoleCommand']);\n private skipAfkReset = false;\n // Throttle: input events fire 60-200x/sec, but AFK timeouts are measured in\n // seconds. Leading-edge throttle dispatches once, then suppresses for 1s.\n private readonly resetAfk$ = new Subject<void>();\n\n constructor() {\n super();\n this.resetAfk$\n .pipe(throttleTime(1000), takeUntil(this.destroy$))\n .subscribe(() => this.store.dispatch(resetAfk()));\n this.init();\n }\n\n protected init() {\n if (this.isPlaywrightMode()) {\n return;\n }\n this.emitUIInteraction = this.commandTelemetryService.decorate(\n this.emitUIInteraction.bind(this),\n );\n // Listen to the dataChannelConnected ACTION (point-in-time event) instead\n // of the store selector. The selector reads the current state and can fire on\n // stale `true` from a previous session when switching components (Angular\n // creates the new component before destroying the old one).\n this.actions$\n .pipe(ofType(dataChannelConnected), takeUntil(this.destroy$))\n .subscribe(() => {\n this.requestInitialSettings();\n this.requestQualityControl();\n });\n }\n\n sendCommandToUnreal(data: MetaBoxCommandPacket) {\n if (this.isPlaywrightMode()) {\n return;\n }\n if (this.webRtcPlayerService.canSend()) {\n const uniqId = data?.correlationId ?? generateUuid();\n const sendData: MetaBoxCommandPacket = { ...data, correlationId: uniqId };\n Logger.colored(...COLOR_CODES.TO_UNREAL, sendData);\n\n if (this.afkIgnoredCommands.has(data.command as string)) {\n this.skipAfkReset = true;\n }\n\n this.emitUIInteraction(sendData);\n this.skipAfkReset = false;\n\n this.store.dispatch(\n commandStarted({\n id: uniqId,\n command: data.command as string,\n timeStamp: Date.now(),\n }),\n );\n }\n }\n\n emitUIInteraction(descriptor: MetaBoxCommandPacket) {\n this.emitDescriptor(MessageType.UIInteraction, descriptor);\n }\n\n /**\n A build-in command can be sent to the UE4 client. The commands are defined by a\n JSON descriptor and will be executed automatically.\n The currently supported commands are:\n\n 1. A command to run any console command:\n \"{ ConsoleCommand: <string> }\"\n\n 2. A command to change the resolution to the given width and height.\n \"{ Resolution.Width: <value>, Resolution.Height: <value> }\"\n */\n emitCommand(descriptor: MetaBoxCommandPacket) {\n this.emitDescriptor(MessageType.Command, descriptor);\n }\n\n sendInputData(data: ArrayBuffer) {\n if (this.isPlaywrightMode()) {\n return;\n }\n try {\n if (!this.skipAfkReset) {\n this.resetAfk$.next();\n }\n this.webRtcPlayerService.send(data);\n } catch (error) {\n if (this.cirrusConnected()) {\n Logger.error(error);\n }\n }\n }\n\n isPlaywrightMode() {\n return !!this.unrealConfig?.playwright;\n }\n\n private emitDescriptor(\n messageType: MessageTypeValues,\n descriptor: MetaBoxCommandPacket,\n ) {\n // Convert the descriptor object into a JSON string.\n const descriptorAsString = JSON.stringify(descriptor);\n\n // Add the UTF-16 JSON string to the array byte buffer, going two bytes at\n // a time.\n const data = new DataView(\n new ArrayBuffer(1 + 2 + 2 * descriptorAsString.length),\n );\n let byteIdx = 0;\n data.setUint8(byteIdx, messageType);\n byteIdx++;\n data.setUint16(byteIdx, descriptorAsString.length, true);\n byteIdx += 2;\n\n for (let i = 0; i < descriptorAsString.length; i++) {\n data.setUint16(byteIdx, descriptorAsString.charCodeAt(i), true);\n byteIdx += 2;\n }\n\n this.sendInputData(data.buffer);\n }\n\n private requestInitialSettings() {\n this.sendInputData(\n new Uint8Array([MessageType.RequestInitialSettings]).buffer,\n );\n }\n\n private requestQualityControl() {\n this.sendInputData(\n new Uint8Array([MessageType.RequestQualityControl]).buffer,\n );\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-unreal-error-modal',\n templateUrl: './unreal-error-modal.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './unreal-error-modal.component.scss',\n imports: [SourceButtonComponent],\n})\nexport class UnrealErrorModalComponent {\n #dialogRef = inject(DialogRef);\n readonly dialogData = inject<{ content: string }>(DIALOG_DATA);\n\n close() {\n this.#dialogRef.close();\n }\n}\n","<div class=\"src-modal src-modal--small\">\n <header class=\"src-modal__header\">\n <div\n [attr.data-testid]=\"'unreal-error-header-title'\"\n class=\"src-modal__title\"\n >\n Warning\n </div>\n </header>\n <div class=\"src-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"src-modal__footer\">\n <src-button (onClick)=\"close()\">Ok</src-button>\n </div>\n</div>\n","import { inject, Injectable } from '@angular/core';\nimport { Actions, createEffect, ofType } from '@ngrx/effects';\nimport {\n concat,\n debounceTime,\n delay,\n EMPTY,\n ignoreElements,\n map,\n merge,\n mergeMap,\n of,\n skip,\n startWith,\n switchMap,\n take,\n timeout,\n timer,\n} from 'rxjs';\nimport { Store } from '@ngrx/store';\nimport {\n abortEstablishingConnection,\n commandCompleted,\n commandStarted,\n dataChannelConnected,\n dataChannelReady,\n destroyRemoteConnections,\n destroyUnrealScene,\n disconnectStream,\n dropConnection,\n initSignalling,\n reconnectPeer,\n reconnectPeerFailed,\n reconnectPeerSuccess,\n resetAfk,\n resetConfig,\n resetDataChannelForReconnect,\n resetWarnTimeout,\n setAwsInstance,\n setCirrusDisconnected,\n setConfig,\n setEstablishingConnection,\n setLoopBackCommandIsCompleted,\n setMaxFps,\n setOrchestrationParameters,\n setOrchestrationProgress,\n setStatusPercentSignallingServer,\n setUserInactivityTimeout,\n setViewportNotReady,\n setViewportReady,\n showUnrealErrorMessage,\n startStream,\n unrealCommandCallback,\n updateCirrusInfo,\n videoStreamInitialized,\n} from './unreal.actions';\nimport { unrealFeature } from './unreal.feature';\nimport {\n catchError,\n distinctUntilChanged,\n exhaustMap,\n filter,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators';\nimport { Falsy, Logger, tapLog, Truthy } from '@3dsource/utils';\nimport { getRtcErrorMessage } from '../../helpers';\nimport {\n DATA_CHANNEL_CONNECTION_TIMEOUT,\n DESTROY_DISCONNECT_REASONS,\n MINIMAL_FPS,\n RECONNECT_CONFIG,\n REGION_PING_BACKGROUND_REFRESH_DELAY_MS,\n SCREEN_LOCKER_CONTAINER_ID,\n UNREAL_CONFIG,\n} from '../../constants';\nimport { selectIsAutostart } from './unreal.selectors';\n// Avoid the `../../components` barrel — it transitively imports the\n// services module, producing a `SubService extends undefined` cycle when\n// `unreal.effects.ts` is loaded eagerly (e.g. through the `../store` barrel\n// during a spec compiler).\nimport { WebrtcErrorModalComponent } from '../../components/webrtc-error-modal/webrtc-error-modal.component';\n// Same cycle-break as the component import above: pull each service from\n// its own file rather than through the `../../services` barrel, which would\n// re-include `SubService` consumers and trigger\n// `Class extends value undefined` during eager-load spec compile.\nimport { CommandTelemetryService } from '../../services/command-telemetry.service';\nimport { DevModeService } from '../../services/dev-mode.service';\nimport { RegionsPingService } from '../../services/regions-ping.service';\nimport { SignallingService } from '../../services/signalling.service';\nimport { StreamAdoptionService } from '../../services/stream-adoption.service';\nimport { UnrealCallbackService } from '../../services/unreal-callback.service';\nimport { UnrealCommunicatorService } from '../../services/unreal-communicator.service';\nimport { VideoService } from '../../services/video.service';\nimport { WebRtcPlayerService } from '../../services/web-rtc-player.service';\nimport { Dialog } from '@angular/cdk/dialog';\nimport { HttpClient } from '@angular/common/http';\nimport { ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport type { AwsInstance } from '../../interfaces';\nimport { DisconnectReason } from '../../interfaces';\nimport type { MetaBoxCommandPacket } from '@3dsource/types-unreal';\nimport { MetaBoxCommand } from '@3dsource/types-unreal';\nimport { UnrealErrorModalComponent } from '../../components/unreal-error-modal/unreal-error-modal.component';\n\n@Injectable()\nexport class UnrealEffects {\n private readonly actions$ = inject(Actions);\n private readonly dialog = inject(Dialog);\n private readonly http = inject(HttpClient);\n private readonly store = inject(Store);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly scrollStrategy = inject(ScrollStrategyOptions).block();\n private readonly unrealInitialConfig = inject(UNREAL_CONFIG);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly commandTelemetryService = inject(CommandTelemetryService);\n private readonly regionsPingService = inject(RegionsPingService);\n private readonly signallingService = inject(SignallingService);\n private readonly streamAdoptionService = inject(StreamAdoptionService);\n private readonly videoService = inject(VideoService);\n private readonly unrealCallbackService = inject(UnrealCallbackService);\n private dataChannelConnectionTimeout =\n this.unrealInitialConfig?.dataChannelConnectionTimeout ??\n DATA_CHANNEL_CONNECTION_TIMEOUT;\n private connectionCompleted$ = this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(filter(Truthy));\n\n destroyConnections$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyUnrealScene),\n map(() => destroyRemoteConnections({ reason: DisconnectReason.Destroy })),\n );\n });\n\n // Stage 3 — accurate region re-ping in the background once the stream is up.\n // A few seconds after the data channel is ready (so it doesn't compete with\n // the connection handshake) we re-measure regions with the accurate\n // warm-up + median method and refresh the localStorage cache, improving the\n // pick for the NEXT connection. `switchMap` cancels a previous run if the\n // channel re-opens; `takeUntil(destroyUnrealScene)` tears it down on exit.\n // `dispatch: false` — it only writes the cache, no store change.\n refreshRegionCache$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(dataChannelReady),\n delay(REGION_PING_BACKGROUND_REFRESH_DELAY_MS),\n switchMap(() =>\n this.regionsPingService\n .refreshCacheInBackground()\n .pipe(takeUntil(this.actions$.pipe(ofType(destroyUnrealScene)))),\n ),\n );\n },\n { dispatch: false },\n );\n // Fan-in for \"cancel an in-flight signaling attempt\". One named action so\n // both `SignallingService.abort$` and `setDataChannelTimeoutCheck$.abort$`\n // subscribe to single intent (and it shows up as a distinct entry in the\n // Redux DevTools timeline).\n abortEstablishingConnection$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setCirrusDisconnected, dropConnection, destroyUnrealScene),\n map(() => abortEstablishingConnection()),\n );\n });\n resetAfk$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(\n setConfig,\n setUserInactivityTimeout,\n resetWarnTimeout,\n resetConfig,\n ),\n map(() => resetAfk()),\n );\n });\n iframeMessaging$ = createEffect(\n () => {\n const cirrusConnected$ = this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(skip(1));\n\n // On disconnect: immediately show 'Connection closed.', nullify after 2s\n const cirrusStatus$ = cirrusConnected$.pipe(\n switchMap((connected) =>\n connected\n ? of('Creating Socket...')\n : concat(of('Connection closed.'), of(null).pipe(delay(2000))),\n ),\n );\n\n // Skip initial false; emit null on every viewport state change\n const viewportReset$ = this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(\n skip(1),\n delay(500),\n map(() => null),\n );\n\n return merge(\n cirrusStatus$,\n this.store.select(unrealFeature.selectStatusMessage),\n viewportReset$,\n ).pipe(\n debounceTime(0),\n distinctUntilChanged(),\n tapLog('STATUS=>'),\n tap((status) => this.postToScreenLocker(status)),\n );\n },\n { dispatch: false },\n );\n setSignalingTo100$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setAwsInstance),\n map(() => setStatusPercentSignallingServer({ percent: 100 })),\n );\n });\n setOrchestrationParameters$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setOrchestrationParameters),\n map(({ eta }) => eta),\n filter((value) => value > 0),\n switchMap((total) => {\n // Emit every second: 0,1,2,...,total (inclusive)\n return timer(0, 1000).pipe(\n takeUntil(this.connectionCompleted$),\n take(total + 1),\n map((sec) => sec / total),\n distinctUntilChanged(),\n map((progressComplete) =>\n setOrchestrationProgress({ progressComplete }),\n ),\n );\n }),\n );\n });\n setDataChannelTimeoutCheck$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setAwsInstance),\n // require wsUrl present on the action payload\n filter((action) => !!action.wsUrl),\n // for each awsInstance action capture one ssData snapshot, then wait for dataChannelConnected\n switchMap((awsInstance: AwsInstance) => {\n return this.actions$.pipe(\n ofType(updateCirrusInfo),\n take(1),\n switchMap(({ ssData }) => {\n const abort$ = this.actions$.pipe(\n ofType(\n setCirrusDisconnected, // ← \"Cirrus closed\" action — direct,\n // no fan-in tick delay\n abortEstablishingConnection, // ← \"Manual abort\" fan-in for\n // dropConnection / destroy\n ),\n take(1),\n );\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n take(1),\n // 🚫 If Cirrus (or anything else) disconnects first, abort BEFORE timeout fires.\n takeUntil(abort$),\n // if it becomes true within timeout -> complete without dispatching any action\n timeout(this.dataChannelConnectionTimeout),\n // successfully connect → no action\n mergeMap(() => EMPTY),\n // ⏱️ Only actual timeout (or real upstream error) ends up here.\n catchError(() => {\n const error = `⏱️ DataChannel connection timeout ${this.dataChannelConnectionTimeout}ms, requesting new signaling.`;\n Logger.error(error);\n\n const body = {\n awsInstance,\n connectionId: ssData?.connectionId,\n href: location.href,\n userAgent: navigator.userAgent,\n error,\n };\n\n return this.http.post(awsInstance.pollingUrl || '', body).pipe(\n catchError((postError: unknown) => {\n Logger.error('Error sending timeout info:', postError);\n return of(null);\n }),\n // map response to the destroy action that ngrx will dispatch\n map(() =>\n disconnectStream({\n reason: DisconnectReason.DataChannelTimeout,\n message: 'Data Channel Timeout',\n }),\n ),\n );\n }),\n );\n }),\n );\n }),\n );\n });\n /**\n * Effect: `forceViewportNotReady$`\n *\n * Ensures the viewport is explicitly marked as *not ready* to prevent\n * a temporary black screen flash when disconnecting.\n *\n * ### Why\n * - The video stream is disconnected immediately.\n * - The DataChannel closes slightly later.\n * - Closing the DataChannel resets the Unreal scene,\n * which also sets `viewPortReady` to `false`.\n *\n * Without this effect, the order of these events may cause\n * a visible flicker (video flashing to black).\n */\n forceViewportNotReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n withLatestFrom(this.store.select(unrealFeature.selectViewportReady)),\n filter(([, viewportReady]) => viewportReady),\n map(() => setViewportNotReady()),\n );\n });\n resetCirrusOnDestroy$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n withLatestFrom(this.store.select(unrealFeature.selectCirrusConnected)),\n filter(([, cirrusConnected]) => cirrusConnected),\n map(() => setCirrusDisconnected()),\n );\n });\n destroyRemoteConnections$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(destroyRemoteConnections),\n tap(({ reason }) => {\n this.webRtcPlayerService.releaseRemoteConnections(reason);\n }),\n filter(({ reason }) => reason === DisconnectReason.DropConnection),\n map(() => dropConnection()),\n );\n });\n destroyConnectionAndRestart$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setCirrusDisconnected),\n withLatestFrom(this.store.select(unrealFeature.selectDisconnectReason)),\n filter(([, reason]) => reason === DisconnectReason.DataChannelTimeout),\n map(() => initSignalling()),\n );\n });\n showUnrealError$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(showUnrealErrorMessage),\n map(({ code }) => getRtcErrorMessage(code)),\n distinctUntilChanged(),\n filter(Truthy),\n switchMap(\n (content: string) =>\n this.dialog.open(UnrealErrorModalComponent, {\n scrollStrategy: this.scrollStrategy,\n data: { content },\n }).closed,\n ),\n map(() => showUnrealErrorMessage({ code: null })),\n );\n });\n unrealReceiverReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n withLatestFrom(this.store.select(unrealFeature.selectIsReconnecting)),\n filter(([, isReconnecting]) => !isReconnecting),\n map(() => dataChannelReady()),\n );\n });\n initAppByDataChannelReady$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(dataChannelReady),\n tap(() => {\n this.commandsSender.sendCommandToUnreal({\n command: 'setFreezeFrameQuality',\n payload: { value: '95' },\n } as unknown as MetaBoxCommandPacket);\n this.commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FDebugModeCommand,\n payload: { value: this.isDevMode },\n });\n this.commandTelemetryService.trackStartCommand('EXT-SetViewportReady');\n }),\n switchMap(() =>\n // Wait for initial commands to be sent before sending the loopback.\n // commandStarted fires for each sent command; debounce ensures\n // we proceed only after no more commands are started for 50 ms.\n this.actions$.pipe(\n ofType(commandStarted),\n debounceTime(50),\n take(1),\n switchMap(() =>\n this.unrealCallbackService.observeCommandResponse<MetaBoxCommand.FLoopBackCommand>(\n { command: MetaBoxCommand.FLoopBackCommand },\n (data) => this.commandsSender.sendCommandToUnreal(data),\n ),\n ),\n switchMap(() => this.videoService.videoStats$),\n filter(\n ({ aggregatedStats: s }) =>\n !!s.framesPerSecond &&\n s.framesPerSecond > MINIMAL_FPS &&\n (s.framesDecoded ?? 0) > 15,\n ),\n take(1),\n map(() => setLoopBackCommandIsCompleted()),\n ),\n ),\n );\n });\n setViewportReadyBySetLoopBackCommandIsCompleted$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(setLoopBackCommandIsCompleted, reconnectPeerSuccess),\n tap(() =>\n this.commandTelemetryService.trackStopCommand(\n 'EXT-SetViewportReady',\n false,\n { ready: true },\n ),\n ),\n map(() => setViewportReady()),\n );\n });\n startStream$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(startStream),\n map(() => initSignalling()),\n );\n });\n // When the video stream is initialized but autoplay didn't kick in\n // (browser blocked it; user gesture pending), the user may need extra\n // time before interacting. Refresh the AFK timer so it doesn't tick\n // toward an inactivity warning while we're waiting for permission.\n resetAfkOnPausedVideoInit$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(videoStreamInitialized),\n filter(() => !!this.videoService.video?.paused),\n map(() => resetAfk()),\n );\n });\n /**\n * Effect: `disconnectReasonHandling$`\n *\n * Translates every destroy-worthy `disconnectStream` into a\n * `destroyRemoteConnections` action so the cleanup chain (close signaling\n * + webrtc, mark cirrus disconnected, force viewport not-ready) runs once\n * per disconnect. The `disconnectReason` state is pinned by the\n * `disconnectStream` reducer's first-wins guard.\n *\n * Skip `DataChannelClosed` when peer reconnection can handle it — that\n * path is owned by `handleDataChannelClosed$` instead.\n */\n disconnectReasonHandling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(({ reason }) => {\n // Skip DataChannelClosed if peer reconnection will handle this case\n if (\n reason === DisconnectReason.DataChannelClosed &&\n this.canPeerReconnect()\n ) {\n Logger.info(\n '[Reconnect] Skipping destroy for DataChannelClosed - peer reconnection will handle',\n );\n return false;\n }\n return DESTROY_DISCONNECT_REASONS.includes(reason);\n }),\n map(({ reason }) => destroyRemoteConnections({ reason })),\n );\n });\n /**\n * Effect: `handleDataChannelClosed$`\n *\n * Triggers peer reconnection when DataChannel closes unexpectedly.\n * Only triggers if reconnection is enabled and the signaling WebSocket\n * is still connected.\n */\n handleDataChannelClosed$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(\n ({ reason }) =>\n reason === DisconnectReason.DataChannelClosed &&\n this.canPeerReconnect(),\n ),\n tap(() => {\n Logger.warn(\n '[Reconnect] DataChannel closed, initiating peer reconnection',\n );\n }),\n map(() =>\n reconnectPeer({\n attempt: 1,\n maxAttempts: RECONNECT_CONFIG.maxAttempts,\n delay: 0,\n }),\n ),\n );\n });\n webrtcErrorModalComponent$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(disconnectStream),\n filter(({ reason }) => reason === DisconnectReason.WebRTCError),\n debounceTime(400),\n switchMap(() =>\n this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(take(1), filter(Falsy)),\n ),\n tap(() => this.dialog.open(WebrtcErrorModalComponent)),\n );\n },\n { dispatch: false },\n );\n /**\n * Effect: `resetStateForPeerReconnect$`\n *\n * Resets the data channel state when peer reconnection starts.\n */\n resetStateForPeerReconnect$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeer),\n filter(() => RECONNECT_CONFIG.enabled),\n filter(({ attempt }) => attempt === 1), // Only reset on the first attempt\n map(() => resetDataChannelForReconnect()),\n );\n });\n /**\n * Effect: `executePeerReconnect$`\n *\n * Executes the actual peer reconnection attempt.\n * This only re-establishes the WebRTC connection, not the signaling.\n */\n executePeerReconnect$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeer),\n filter(() => RECONNECT_CONFIG.enabled),\n tap(({ attempt, maxAttempts }) => {\n Logger.info(\n `[Reconnect] Peer reconnection attempt ${attempt}/${maxAttempts} in ${RECONNECT_CONFIG.delayMs}ms`,\n );\n }),\n switchMap(({ attempt, maxAttempts, delay }) =>\n timer(delay ?? RECONNECT_CONFIG.delayMs).pipe(\n switchMap(() => {\n const success = this.webRtcPlayerService.reconnectPeer();\n if (!success) {\n Logger.error('[Reconnect] Failed to initiate peer reconnection');\n return of(\n this.scheduleRetryOrFail(\n attempt,\n maxAttempts,\n 'Signaling connection lost during peer reconnection',\n ),\n );\n }\n // Monitor for successful data channel connection\n return this.actions$.pipe(\n ofType(dataChannelConnected),\n take(1),\n timeout(this.dataChannelConnectionTimeout),\n tap(() =>\n Logger.info('[Reconnect] Peer reconnection successful!'),\n ),\n map(() => reconnectPeerSuccess()),\n catchError(() => {\n if (attempt < maxAttempts) {\n Logger.warn(\n `[Reconnect] Peer reconnection attempt ${attempt} timed out, scheduling retry`,\n );\n } else {\n Logger.error(\n `[Reconnect] All ${maxAttempts} peer reconnection attempts exhausted`,\n );\n }\n return of(\n this.scheduleRetryOrFail(\n attempt,\n maxAttempts,\n `Peer reconnection failed after ${maxAttempts} attempts`,\n ),\n );\n }),\n );\n }),\n takeUntil(this.actions$.pipe(ofType(destroyUnrealScene), take(1))),\n ),\n ),\n );\n });\n /**\n * Effect: `handlePeerReconnectFailed$`\n *\n * Handles the case when all peer reconnection attempts have failed.\n * Falls back to full disconnection which may trigger full reconnection.\n */\n handlePeerReconnectFailed$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(reconnectPeerFailed),\n map(({ reason }) =>\n disconnectStream({\n reason: DisconnectReason.ReconnectFailed,\n message: reason,\n }),\n ),\n );\n });\n setMaxFps$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(setMaxFps),\n tap(({ maxFps }) => {\n this.commandsSender.sendCommandToUnreal({\n command: 'setMaxFPS',\n payload: { value: maxFps },\n } as unknown as MetaBoxCommandPacket);\n }),\n );\n },\n { dispatch: false },\n );\n sendStatisticsToUnreal$ = createEffect(\n () => {\n return this.actions$.pipe(\n ofType(showUnrealErrorMessage),\n filter(({ code }) => code === 404),\n withLatestFrom(\n this.store.select(unrealFeature.selectAwsInstance),\n this.store.select(unrealFeature.selectStreamClientCompanyId),\n this.store.select(unrealFeature.selectStreamViewId),\n ),\n switchMap(([action, instance, companyId, viewId]) =>\n this.http\n .post(this.unrealInitialConfig?.customErrorsEndpoint || '', {\n client: instance.pollingUrl,\n session_uuid: companyId,\n session_uuid2: viewId,\n message: {\n type: 'front',\n error: 'pak_not_found',\n info: action?.error ?? '',\n },\n })\n .pipe(\n catchError(() => {\n Logger.error(\n `get error from ${this.unrealInitialConfig?.customErrorsEndpoint}`,\n );\n return EMPTY;\n }),\n ),\n ),\n );\n },\n { dispatch: false },\n );\n // Within an active signaling session, every unrealCommandCallback that\n // carries a correlationId resolves a previously started command.\n // Skip in Playwright mode (deterministic command IDs are issued directly).\n listenUnrealCallbackByInitSignalling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(initSignalling),\n filter(() => !this.unrealInitialConfig?.playwright),\n switchMap(() =>\n this.actions$.pipe(\n ofType(unrealCommandCallback),\n map(({ json }) =>\n 'commandCallback' in json\n ? json.commandCallback?.correlationId\n : json?.correlationId,\n ),\n filter(Truthy),\n map((id) => commandCompleted({ id, now: Date.now() })),\n ),\n ),\n );\n });\n connectToSignaling$ = createEffect(() => {\n return this.actions$.pipe(\n ofType(initSignalling),\n withLatestFrom(\n this.store.select(unrealFeature.selectMatchUrls),\n this.store.select(selectIsAutostart),\n this.store.select(unrealFeature.selectCirrusConnected),\n ),\n filter(([, , autoStart, cirrusConnected]) => {\n if (cirrusConnected) {\n Logger.warn(\n `SIGNALING REQUEST can't be called when cirrus connection is already established.`,\n );\n }\n return autoStart && !cirrusConnected;\n }),\n map(([, matchMakerUrls]) => [...matchMakerUrls].filter(Truthy)),\n filter((urls) => urls.length > 0),\n // Ensure a single in-flight request per attempt.\n exhaustMap((urls) =>\n // If a prefetched `window.__stream` is ready — or still connecting —\n // adopt it (waiting for it to finish) instead of racing a second\n // connection; otherwise fall back to a fresh signalling connection.\n // `takeUntil(abort)` cancels the wait on teardown / route change so a\n // fast switch can't leave overlapping connections.\n this.streamAdoptionService.awaitAndAdopt$().pipe(\n switchMap((adopted) =>\n adopted ? EMPTY : this.signallingService.connectToSignaling(urls),\n ),\n takeUntil(this.actions$.pipe(ofType(abortEstablishingConnection))),\n // The adopt/connect stream is side-effect-only (its values aren't\n // actions) — swallow them, and emit `setEstablishingConnection`\n // first so the reconnect/resume popup stays hidden during the\n // (possibly deferred) prefetch-adoption wait. Adoption otherwise\n // defers `connectToSignaling`, which is what normally sets this.\n ignoreElements(),\n startWith(setEstablishingConnection({ value: true })),\n ),\n ),\n );\n });\n\n private canPeerReconnect() {\n return RECONNECT_CONFIG.enabled && this.signallingService.isConnected();\n }\n\n /**\n * Either schedules the next peer-reconnect attempt or gives up with the\n * supplied reason. Used in two `executePeerReconnect$` branches that share\n * the same retry-or-fail decision.\n */\n private scheduleRetryOrFail(\n attempt: number,\n maxAttempts: number,\n exhaustedReason: string,\n ) {\n return attempt < maxAttempts\n ? reconnectPeer({ attempt: attempt + 1, maxAttempts })\n : reconnectPeerFailed({ reason: exhaustedReason });\n }\n\n private postToScreenLocker(text: string | null) {\n try {\n const el = document.getElementById(\n this.unrealInitialConfig?.screenLockerContainerId ??\n SCREEN_LOCKER_CONTAINER_ID,\n ) as HTMLIFrameElement | null;\n el?.contentWindow?.postMessage(text, '*');\n } catch {\n // Fails silently if cross-origin\n }\n }\n}\n","import { effect, inject, Injectable, untracked } from '@angular/core';\nimport {\n ControlScheme,\n DEFAULT_AFK_TIMEOUT_PERIOD,\n InputOptions,\n UNREAL_CONFIG,\n} from '../constants';\nimport { SubService } from './sub.service';\nimport { DisconnectReason } from '../interfaces';\nimport {\n disconnectStream,\n resetAfk,\n resetUserInactivityTimeout,\n selectWarnTimeout,\n setAfkTimerCountdown,\n setAfkTimerHide,\n setAfkTimerVisible,\n unrealFeature,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { merge, takeUntil } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class AFKService extends SubService {\n private active = false; // Whether the AFK system is currently looking for inactivity.\n private warnTimer: ReturnType<typeof setTimeout> | undefined;\n private countdown = 0;\n private countdownTimer: ReturnType<typeof setInterval> | undefined;\n private readonly warnTimeout = this.store.selectSignal(selectWarnTimeout);\n private readonly isAfkTimerVisible = this.store.selectSignal(\n unrealFeature.selectIsAfkTimerVisible,\n );\n private readonly isViewportReady = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n /** Ticks every time warnTimeout changes or resetAfk action fires */\n private readonly afkResetTrigger = toSignal(\n merge(\n this.store.select(selectWarnTimeout),\n this.actions$.pipe(ofType(resetAfk)),\n ),\n );\n\n constructor() {\n super();\n this.destroyRef.onDestroy(() => this.clearTimers());\n\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n // Reset AFK warning timer when warnTimeout changes or resetAfk action fires\n effect(() => {\n this.afkResetTrigger();\n untracked(() => {\n if (this.isViewportReady()) {\n this.resetAfkWarningTimer();\n }\n });\n });\n\n // Start AFK warning timer when viewport becomes ready\n effect(() => {\n const ready = this.isViewportReady();\n if (ready) {\n untracked(() => this.startAfkWarningTimer());\n }\n });\n\n // Stop the AFK timers when Cirrus drops the connection. `disconnect$`\n // emits void; the previous toSignal(disconnect$) approach never fired\n // (void → undefined → effect's `!== undefined` guard always false).\n this.disconnect$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.stop());\n\n this.actions$\n .pipe(ofType(resetUserInactivityTimeout), takeUntil(this.destroy$))\n .subscribe(() => this.reset());\n }\n\n private hideOverlay() {\n if (!this.isAfkTimerVisible()) {\n return;\n }\n this.store.dispatch(setAfkTimerHide());\n }\n\n /**\n * Start a timer which when elapsed will warn the user they are inactive.\n */\n private startAfkWarningTimer() {\n this.active = true;\n this.resetAfkWarningTimer();\n }\n\n /**\n * If the user interacts, then reset the warning timer.\n */\n private resetAfkWarningTimer() {\n if (this.active) {\n this.clearTimers();\n // `selectWarnTimeout` already falls back to DEFAULT_AFK_TIMEOUT when\n // config is missing, so warnTimeout() always returns a positive number.\n this.warnTimer = setTimeout(\n () => this.showAfkOverlay(),\n this.warnTimeout() * 1000,\n );\n }\n }\n\n /**\n * Update the count-down spans number for the overlay\n * @param countdown the count down number to be inserted into the span for updating\n */\n private updateCountDown(countdown: number) {\n this.store.dispatch(setAfkTimerCountdown({ countdown }));\n }\n\n private clearTimers() {\n clearInterval(this.countdownTimer);\n clearTimeout(this.warnTimer);\n }\n\n private stop() {\n this.clearTimers();\n this.hideOverlay();\n }\n\n reset() {\n this.hideOverlay();\n // startAfkWarningTimer → resetAfkWarningTimer → clearTimers() already\n // clears the countdown interval, no separate clearInterval needed.\n this.startAfkWarningTimer();\n }\n\n private showAfkOverlay() {\n if (!this.isViewportReady()) {\n return;\n }\n // Pause the timer while the user is looking at the inactivity warning overlay.\n this.active = false;\n this.countdown = DEFAULT_AFK_TIMEOUT_PERIOD;\n this.store.dispatch(setAfkTimerVisible());\n this.updateCountDown(this.countdown);\n\n if (InputOptions.controlScheme === ControlScheme.LockedMouse) {\n document.exitPointerLock();\n }\n\n this.countdownTimer = setInterval(() => {\n this.countdown--;\n if (this.countdown === 0) {\n // The user failed to click so disconnect them\n this.hideOverlay();\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.Afk,\n message: `AFK timeout:${this.warnTimeout()} seconds, popup timeout:${DEFAULT_AFK_TIMEOUT_PERIOD} seconds`,\n }),\n );\n clearInterval(this.countdownTimer);\n } else {\n this.updateCountDown(this.countdown);\n }\n }, 1000);\n }\n}\n","import { computed, inject, Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { of, scan, shareReplay, switchMap } from 'rxjs';\nimport { distinctUntilChanged } from 'rxjs/operators';\nimport { selectShowLoader, selectTotalProgress } from '../store';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { floatToPercents, floatToSmoothPercents } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class LoadingProgressService {\n readonly #store = inject(Store);\n\n readonly loaderVisible = this.#store.selectSignal(selectShowLoader);\n\n // Visibility-gated progress source.\n //\n // When the loader is visible, subscribe to `selectTotalProgress` and run\n // a `scan` that keeps the running max — progress should only advance\n // forward within a single loading session, never regress visually.\n //\n // When the loader is hidden, switch to a constant `of(0)`. This is what\n // makes percents drop to 0 on hide / destroy. A previous attempt used\n // `keepMaxUntilReset` here; that operator could not work because\n // `selectTotalProgress` is non-completing — it keeps re-emitting the\n // last (high) value after a reset, which immediately re-fills the max.\n // `switchMap` cancels the inner subscription on every visibility change\n // so stale emissions can't leak through.\n readonly #boundedProgress$ = toObservable(this.loaderVisible).pipe(\n switchMap((visible) =>\n visible\n ? this.#store\n .select(selectTotalProgress)\n .pipe(scan((max, val) => Math.max(max, val), 0))\n : of(0),\n ),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n readonly smoothPercents = toSignal(\n this.#boundedProgress$.pipe(\n floatToSmoothPercents(),\n distinctUntilChanged(),\n ),\n );\n readonly percents = toSignal(\n this.#boundedProgress$.pipe(floatToPercents(), distinctUntilChanged()),\n );\n readonly loadingStatusChanged = computed(() => ({\n percents: this.percents() ?? 0,\n loaderVisible: this.loaderVisible(),\n }));\n}\n","import { merge } from 'rxjs';\nimport { filter, takeUntil } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { SubService } from './sub.service';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport {\n setFreezeFrame,\n unrealFeature,\n videoStreamInitialized,\n} from '../store';\nimport { ofType } from '@ngrx/effects';\nimport { UNREAL_CONFIG } from '../constants';\nimport { uint8ToBase64 } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class FreezeFrameService extends SubService {\n receiving = false;\n\n private size = 0;\n private jpeg: Uint8Array | undefined = undefined;\n private freezeFrameOverlay = new Image();\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n merge(\n this.store.select(unrealFeature.selectViewportReady).pipe(filter(Truthy)),\n this.actions$.pipe(ofType(videoStreamInitialized)),\n )\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.invalidate());\n }\n\n setData(view: Uint8Array) {\n view = view.slice(1 + 4);\n\n if (!this.jpeg) {\n return;\n }\n\n const jpeg = new Uint8Array(this.jpeg.length + view.length);\n jpeg.set(this.jpeg, 0);\n jpeg.set(view, this.jpeg.length);\n this.jpeg = jpeg;\n if (this.jpeg.length === this.size) {\n this.receiving = false;\n Logger.info(`FRAME: Received complete freeze frame ${this.size}`);\n this.showFreezeFrame();\n } else if (this.jpeg.length > this.size) {\n Logger.error(\n `FRAME: Received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`,\n );\n this.store.dispatch(setFreezeFrame({ dataUrl: null, progress: 0 }));\n this.jpeg = undefined;\n this.receiving = false;\n } else {\n this.dispatchInProgress();\n }\n }\n\n private dispatchInProgress() {\n this.store.dispatch(\n setFreezeFrame({\n dataUrl: null,\n progress: (this.jpeg?.length || 0) / this.size,\n }),\n );\n }\n\n start(view: Uint8Array) {\n this.size = new DataView(view.slice(1, 5).buffer).getInt32(0, true);\n this.jpeg = view.slice(1 + 4);\n if (this.jpeg.length < this.size) {\n this.dispatchInProgress();\n Logger.info(\n `FRAME: Received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,\n );\n this.receiving = true;\n } else {\n Logger.info(\n `FRAME: Received complete freeze frame: ${this.jpeg.length}/${this.size}`,\n );\n this.receiving = false;\n this.showFreezeFrame();\n }\n }\n\n invalidate() {\n if (!this.jpeg) {\n return;\n }\n this.store.dispatch(setFreezeFrame({ dataUrl: null, progress: null }));\n this.jpeg = undefined;\n this.receiving = false;\n }\n\n private showFreezeFrame() {\n if (!this.jpeg) {\n return;\n }\n const base64 = uint8ToBase64(this.jpeg);\n this.freezeFrameOverlay.src = 'data:image/jpeg;base64,' + base64;\n this.store.dispatch(\n setFreezeFrame({\n dataUrl: this.freezeFrameOverlay.src,\n progress: 1,\n }),\n );\n }\n}\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const deepEqual = (a: any, b: any) => {\n if (a === b) return true;\n\n // must both be objects (and not null)?\n if (\n typeof a === 'object' &&\n a !== null &&\n typeof b === 'object' &&\n b !== null\n ) {\n // arrays?\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // plain objects\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n // `b` must have key, and values must match\n if (!Object.prototype.hasOwnProperty.call(b, key)) {\n return false;\n }\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n return true;\n }\n\n // everything else (including mismatched types)\n return false;\n};\n","import { filter, takeUntil } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { SubService } from './sub.service';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport { unrealFeature } from '../store';\nimport { Subject } from 'rxjs';\nimport type { ReceivedMimeType } from '../interfaces/ReceivedMimeTypes';\nimport { UNREAL_CONFIG } from '../constants';\nimport { decodeData } from '../helpers';\n\n@Injectable({ providedIn: 'root' })\nexport class FileReceiverService extends SubService {\n public fileComplete$ = new Subject<ReceivedFile>();\n\n private valid = false;\n private chunks = 0;\n private mimetype = '' as ReceivedMimeType;\n private receiving = false;\n private extension = '';\n private data: Uint8Array<ArrayBuffer>[] = [];\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy), takeUntil(this.destroy$))\n .subscribe(() => this.reset());\n }\n\n public reset() {\n this.mimetype = '' as ReceivedMimeType;\n this.extension = '';\n this.receiving = false;\n this.valid = false;\n this.chunks = 0;\n this.data = [];\n }\n\n private resetOnStart() {\n this.reset();\n this.receiving = true;\n }\n\n /**\n * Processes a file extension when received over data channel\n * @param view - the file extension data\n */\n setExtensionFromBytes(view: Uint8Array) {\n // Reset this if we got a file message and we are not \"receiving\" it yet\n if (!this.receiving) {\n this.resetOnStart();\n }\n\n //Logger.info(extensionAsString);\n this.extension = decodeData(view.slice(1).buffer);\n }\n\n /**\n * Processes a file mime type when received over data channel\n * @param view - the file mime type data\n */\n setMimeTypeFromBytes(view: Uint8Array) {\n // Reset this if we got a file message and we are not \"receiving\" it yet\n if (!this.receiving) {\n this.resetOnStart();\n }\n\n const mimeAsString = decodeData(view.slice(1).buffer);\n // Logger.info(mimeAsString);\n this.mimetype = mimeAsString as ReceivedMimeType;\n }\n\n /*-------------------------------------------------------------------------------------------*/\n\n public setContentsFromBytes(view: Uint8Array) {\n // If we haven't received the initial setup instructions, return\n if (!this.receiving) return;\n\n const typeSize = 1;\n const intSize = 4;\n const maxMessageSize = 16 * 1024;\n const headerSize = typeSize + intSize;\n const maxPayloadSize = maxMessageSize - headerSize;\n\n // Calculate the total number of chunks from the total this size\n this.chunks = Math.ceil(\n new DataView(view.slice(typeSize, headerSize).buffer).getInt32(0, true) /\n maxPayloadSize,\n );\n\n // Get the file part of the payload\n const thisBytes = view.slice(headerSize);\n\n // Append to existing data that holds this\n this.data.push(thisBytes);\n\n // Uncomment for debug\n // Logger.info(`Received this chunk: ${this.data.length}/${this.chunks}`);\n\n if (this.data.length === this.chunks) {\n this.receiving = false;\n this.valid = true;\n /*Logger.info('Received complete file');\n const transferDuration = new Date().getTime() - this.timestampStart;\n const transferBitrate = Math.round(\n (this.chunks * maxMessageSize) / transferDuration,\n );\n Logger.info(\n `Average transfer bitrate: ${transferBitrate}kb/s over ${transferDuration / 1000} seconds`,\n );*/\n\n /**\n * Reconstruct the file\n * This code reconstructs the received data into the original this based on the mime type and extension provided\n */\n const blob = new Blob([...this.data], { type: this.mimetype });\n this.fileComplete$.next({\n blob,\n mimetype: this.mimetype,\n extension: this.extension,\n valid: this.valid,\n });\n this.reset();\n } else if (this.data.length > this.chunks) {\n Logger.error(\n `Received bigger this than advertised: ${this.data.length}/${this.chunks}`,\n );\n this.reset();\n }\n }\n}\nexport interface ReceivedFile {\n blob: Blob;\n mimetype: ReceivedMimeType;\n extension: string;\n valid: boolean;\n}\n","import { COLOR_CODES, Logger, Truthy, where } from '@3dsource/utils';\nimport { inject, Injectable } from '@angular/core';\nimport { merge } from 'rxjs';\nimport { distinctUntilChanged, filter, takeUntil } from 'rxjs/operators';\nimport {\n ControlScheme,\n InputOptions,\n SCREEN_LOCKER_CONTAINER_ID,\n ToClientMessage,\n UNREAL_CONFIG,\n} from '../constants';\nimport { FreezeFrameService } from './freeze-frame.service';\nimport { VideoService } from './video.service';\nimport { WebRtcPlayerService } from './web-rtc-player.service';\nimport {\n selectStreamConfig,\n showUnrealErrorMessage,\n unrealCommandCallback,\n unrealFeature,\n} from '../store';\nimport { decodeData } from '../helpers';\nimport type { UnrealCommands } from '@3dsource/types-unreal';\nimport { deepEqual } from '../helpers/deepEqual';\nimport { SubService } from './sub.service';\nimport { FileReceiverService } from './file-receiver.service';\n\nconst filteredLogs = [\n {\n command: 'onChangeSequence',\n },\n];\n\n@Injectable({ providedIn: 'root' })\nexport class AggregatorService extends SubService {\n private readonly selectStreamConfig =\n this.store.selectSignal(selectStreamConfig);\n private readonly videoService = inject(VideoService);\n private readonly webrtcPlayer = inject(WebRtcPlayerService);\n private readonly freezeFrame = inject(FreezeFrameService);\n private readonly fileReceiver = inject(FileReceiverService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly responseEventListeners = new Map<\n string,\n (data: unknown) => void\n >();\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.listenWebRTC();\n this.initialize();\n }\n\n protected listenWebRTC() {\n this.webrtcPlayer.onDataChannelMessage$\n .pipe(takeUntil(this.destroy$))\n .subscribe((data) => this.dataChannelMessageHandler(data));\n }\n\n protected initialize() {\n this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(distinctUntilChanged(), takeUntil(this.destroy$))\n .subscribe((connected) => {\n this.resetResponseList();\n if (connected) {\n this.startListenCallbacks();\n }\n });\n\n const unlockViewport$ = this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Truthy));\n\n merge(unlockViewport$, this.disconnect$)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.removeLoadScreen());\n\n if (\n !this.selectStreamConfig()?.autoStart ||\n location.protocol === 'http:'\n ) {\n this.removeLoadScreen();\n }\n\n InputOptions.controlScheme = ControlScheme.HoveringMouse;\n }\n\n private addResponseEventListener(\n name: string,\n listener: (data: unknown) => void,\n ) {\n this.responseEventListeners.set(name, listener);\n }\n\n private removeLoadScreen() {\n document\n .getElementById(\n this.unrealConfig?.screenLockerContainerId ||\n SCREEN_LOCKER_CONTAINER_ID,\n )\n ?.remove();\n }\n\n private startListenCallbacks() {\n Logger.info('Start Listen Unreal Callbacks');\n let previousJson: unknown = null;\n this.addResponseEventListener('unrealEvents', (data) => {\n try {\n if (typeof data !== 'string') {\n return;\n }\n const json = JSON.parse(data);\n\n if (!deepEqual(json, previousJson)) {\n if (json?.error) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL_ERROR,\n `${json.error}`,\n data,\n );\n this.store.dispatch(\n showUnrealErrorMessage({ code: json.code, error: json?.error }),\n );\n } else {\n this.showMessageFromUnreal(json);\n previousJson = json;\n\n this.store.dispatch(unrealCommandCallback({ json }));\n }\n } else {\n // Logger.warn('Duplicate message received');\n }\n } catch (e) {\n Logger.error(e);\n Logger.error('ERROR=>', data);\n }\n });\n }\n\n private showMessageFromUnreal<T extends UnrealCommands>(json: T) {\n if (filteredLogs.some(where({ command: json?.command }))) {\n return;\n }\n Logger.colored(...COLOR_CODES.FROM_UNREAL, json);\n }\n\n private resetResponseList() {\n this.responseEventListeners.clear();\n }\n\n private dataChannelMessageHandler(data: ArrayBuffer) {\n const view = new Uint8Array(data);\n const anyData = data.slice(1);\n\n if (this.freezeFrame.receiving) {\n this.freezeFrame.setData(view);\n return;\n }\n\n switch (view[0]) {\n case ToClientMessage.QualityControlOwnership: {\n const ownership = view[1] !== 0;\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Received quality controller message, will control quality: ' +\n ownership,\n );\n break;\n }\n case ToClientMessage.Response: {\n const response = decodeData(anyData);\n for (const listener of this.responseEventListeners.values()) {\n listener(response as never);\n }\n break;\n }\n case ToClientMessage.Command: {\n // The parsed command is only used for the dev log — skip the work in prod.\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n }\n case ToClientMessage.FileExtension:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileExtension');\n this.fileReceiver.setExtensionFromBytes(view);\n break;\n case ToClientMessage.FileMimeType:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileMimeType');\n this.fileReceiver.setMimeTypeFromBytes(view);\n break;\n case ToClientMessage.FileContents:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'FileContents');\n this.fileReceiver.setContentsFromBytes(view);\n break;\n case ToClientMessage.FreezeFrame:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'Freeze frame');\n this.freezeFrame.start(view);\n break;\n case ToClientMessage.UnfreezeFrame:\n Logger.colored(...COLOR_CODES.FROM_UNREAL, 'Un-Freeze frame');\n this.freezeFrame.invalidate();\n break;\n case ToClientMessage.VideoEncoderAvgQP:\n this.videoService.setEncoder(anyData);\n break;\n case ToClientMessage.LatencyTest: {\n const latencyTimings = decodeData(anyData);\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Got latency timings :',\n latencyTimings,\n );\n Logger.colored(...COLOR_CODES.FROM_UNREAL, latencyTimings);\n this.videoService.setLatencyTimings(latencyTimings);\n break;\n }\n case ToClientMessage.InitialSettings:\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'InitialSettings message :',\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n case ToClientMessage.Protocol:\n if (Logger.isDevMode) {\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'Protocol message :',\n JSON.parse(decodeData(anyData)),\n );\n }\n break;\n case ToClientMessage.InputControlOwnership:\n Logger.colored(\n ...COLOR_CODES.FROM_UNREAL,\n 'InputControlOwnership message :',\n anyData,\n );\n break;\n default:\n Logger.warn(`unrecognized data received, packet ID ${view[0]}`);\n }\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport {\n disconnectStream,\n dropDC,\n dropPC,\n setConfig,\n setMaxFps,\n unrealFeature,\n} from '../store';\nimport { of, switchMap, take } from 'rxjs';\nimport { HttpClient } from '@angular/common/http';\nimport { Logger } from '@3dsource/utils';\nimport { catchError, filter } from 'rxjs/operators';\n// Direct file imports — see the comment in signalling.service.ts on cycle-break.\nimport { DevModeService } from './dev-mode.service';\nimport { SubService } from './sub.service';\nimport { UnrealCommunicatorService } from './unreal-communicator.service';\nimport { DisconnectReason } from '../interfaces';\nimport { MetaBoxCommand } from '@3dsource/types-unreal';\nimport { UNREAL_CONFIG } from '../constants';\n\ninterface CustomWindow extends Window {\n emitUIInteraction?: (data: unknown) => void;\n emitCommand?: (data: unknown) => void;\n dropConnection?: (data: unknown) => void;\n dropDC?: (data: unknown) => void;\n dropPC?: (data: unknown) => void;\n toggleBandwidth?: (data: unknown) => void;\n setMaxFps?: (data: number) => void;\n rebootInstance?: (data: unknown) => void;\n startShowcase?: (data: unknown) => void;\n restartApp?: (data: unknown) => void;\n unrealHelp?: (data: unknown) => void;\n setWarnTime?: (data: number) => void;\n setResolution?: (data: { w: number; h: number }) => void;\n}\n\ndeclare let window: CustomWindow;\n\n@Injectable({ providedIn: 'root' })\nexport class ConsoleExtensionsService extends SubService {\n readonly #httpClient = inject(HttpClient);\n readonly #commandsSender = inject(UnrealCommunicatorService);\n readonly #isDevMode = inject(DevModeService).isDevMode;\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n\n // Clean up window properties on destroyRef\n this.destroyRef.onDestroy(() => {\n if (!this.#isDevMode) {\n return;\n }\n window.dropConnection = undefined;\n window.dropDC = undefined;\n window.dropPC = undefined;\n window.setResolution = undefined;\n window.toggleBandwidth = undefined;\n window.setMaxFps = undefined;\n window.restartApp = undefined;\n window.unrealHelp = undefined;\n window.setWarnTime = undefined;\n });\n }\n\n protected init() {\n if (!this.#isDevMode || this.unrealConfig?.playwright) {\n return;\n }\n window.dropConnection = () => {\n this.store.dispatch(\n disconnectStream({\n reason: DisconnectReason.DropConnection,\n message: 'Manual Console Drop',\n }),\n );\n return true;\n };\n window.dropDC = () => {\n this.store.dispatch(dropDC());\n return true;\n };\n window.dropPC = () => {\n this.store.dispatch(dropPC());\n return true;\n };\n window.setResolution = ({ w, h }) => {\n const resolution = { x: w, y: h };\n this.#commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FChangeResolutionCommand,\n payload: { resolution },\n });\n return `Resolution set to ${resolution.x}x${resolution.y}`;\n };\n window.setMaxFps = (maxFps: number) => {\n this.store.dispatch(setMaxFps({ maxFps }));\n return `Max Fps Set to ${maxFps}`;\n };\n window.restartApp = () => {\n this.store\n .select(unrealFeature.selectAwsInstance)\n .pipe(\n take(1),\n filter((data) => !!data.instanceName),\n switchMap((data) =>\n this.#httpClient.get(`//${data.instanceName}/restartapp`),\n ),\n catchError(() => of(null)),\n )\n .subscribe();\n };\n window.unrealHelp = () => this.unrealHelp();\n window.setWarnTime = (time: number) => {\n this.store.dispatch(setConfig({ config: { warnTimeout: time } }));\n };\n }\n\n private unrealHelp() {\n Logger.info(\n 'dropConnection() => Closes Web Socket and abort communication.',\n );\n Logger.info('toggleBandwidth() => toggles speed.');\n Logger.info('restartApp() => force restart Unreal app.');\n Logger.info('rebootInstance() => force reboot instance.');\n Logger.info('startShowcase(time) => start Showcase.');\n Logger.info('setWarnTime() => set time to appear the AFK window.');\n Logger.info('emitCommand(command) => send command to Unreal Engine.');\n }\n}\n","import type { IKeyCode, IKeyName } from '@3dsource/utils';\nimport {\n InvertedKeyMap,\n KeyboardNumericCode,\n Logger,\n Truthy,\n} from '@3dsource/utils';\nimport type { InputProps } from '../interfaces';\nimport type { MessageTypeValues } from '../constants';\nimport {\n InputOptions,\n MessageType,\n MouseButton,\n MouseButtonsMask,\n SpecialKeyCodes,\n UNREAL_CONFIG,\n} from '../constants';\nimport type { Observable } from 'rxjs';\nimport { fromEvent, merge, NEVER, startWith, Subject, takeUntil } from 'rxjs';\nimport { debounceTime, filter, map } from 'rxjs/operators';\nimport { inject, Injectable } from '@angular/core';\nimport { fromResizeObserver } from '../helpers';\nimport { UnrealCommunicatorService } from './unreal-communicator.service';\nimport { DevModeService } from './dev-mode.service';\nimport { SubService } from './sub.service';\nimport { VideoService } from './video.service';\nimport { unrealFeature, videoAdaptedToContainer } from '../store';\nimport { ofType } from '@ngrx/effects';\n\nconst INITIAL_FINGER_IDS = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] as const;\nconst UNSIGNED_RANGE = 65536;\nconst UNSIGNED_OUT_OF_RANGE = 65535;\nconst SIGNED_RANGE = 32767;\nconst WHEEL_DELTA_SCALE = -120;\nconst RESIZE_DEBOUNCE_MS = 300;\nconst FUNCTION_KEY_MIN = 112;\nconst FUNCTION_KEY_MAX = 123;\nconst TAB_KEY_CODE = 9;\n\n@Injectable({ providedIn: 'root' })\nexport class InputService extends SubService {\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n readonly defaultKeys = [\n KeyboardNumericCode.KeyW,\n KeyboardNumericCode.KeyS,\n KeyboardNumericCode.KeyA,\n KeyboardNumericCode.KeyD,\n KeyboardNumericCode.ArrowUp,\n KeyboardNumericCode.ArrowDown,\n KeyboardNumericCode.ArrowLeft,\n KeyboardNumericCode.ArrowRight,\n KeyboardNumericCode.NumpadAdd,\n KeyboardNumericCode.NumpadSubtract,\n KeyboardNumericCode.ControlRight,\n KeyboardNumericCode.Equal,\n KeyboardNumericCode.Minus,\n KeyboardNumericCode.NumpadDecimal,\n ];\n private availableKeys: IKeyCode[] = this.defaultKeys;\n private options: InputProps = InputOptions;\n private reInit$ = new Subject<void>();\n private deactivatedVideoTrigger$: Observable<unknown> = NEVER;\n\n private normalizeAndQuantizeUnsigned = (_x: number, _y: number) => ({\n inRange: false,\n x: UNSIGNED_OUT_OF_RANGE,\n y: UNSIGNED_OUT_OF_RANGE,\n });\n\n private normalizeAndQuantizeSigned = (_x: number, _y: number) => ({\n x: 0,\n y: 0,\n });\n\n private videoBoundingRect: DOMRect = new DOMRect(0, 0, 1, 1);\n private fingerIds = new Map<number, number>();\n private maxByteValue = 255;\n private fingers: number[] = [...INITIAL_FINGER_IDS];\n\n // Reusable wire buffers. Input events fire at up to ~60 Hz; the data channel\n // copies the bytes synchronously on sending (RTCDataChannel.send), so a single\n // buffer per message shape is safe and avoids per-event allocation/GC churn.\n private readonly mouseMoveView = new DataView(new ArrayBuffer(9));\n private readonly mouseButtonView = new DataView(new ArrayBuffer(6));\n private readonly mouseWheelView = new DataView(new ArrayBuffer(7));\n private readonly touchView = new DataView(new ArrayBuffer(9));\n private readonly keyPressView = new DataView(new ArrayBuffer(3));\n private readonly singleByteView = new DataView(new ArrayBuffer(1));\n private readonly keyDownBytes = new Uint8Array(3);\n private readonly keyUpBytes = new Uint8Array(2);\n\n private offsetParams: OffsetParams = {\n scaleX: 1,\n scaleY: 1,\n scaledHeight: 0,\n scaledWidth: 0,\n offsetByY: 0,\n offsetByX: 0,\n };\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n const visibilityHiddenTrigger$ = fromEvent(\n document,\n 'visibilitychange',\n ).pipe(\n map(() => document.visibilityState === 'hidden'),\n filter(Truthy),\n );\n const visibilityVisibleTrigger$ = fromEvent(\n document,\n 'visibilitychange',\n ).pipe(\n map(() => document.visibilityState === 'visible'),\n filter(Truthy),\n startWith(true),\n );\n\n this.deactivatedVideoTrigger$ = merge(\n this.disconnect$,\n this.reInit$,\n visibilityHiddenTrigger$,\n this.destroy$,\n );\n\n merge(\n visibilityVisibleTrigger$,\n this.store.select(unrealFeature.selectViewportReady).pipe(filter(Truthy)),\n )\n .pipe(\n filter(() => !!this.video),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.setup());\n }\n\n useKeyboardKeys(keys: IKeyCode[]) {\n this.availableKeys = keys;\n }\n\n get video() {\n return this.videoService.video;\n }\n\n private setup() {\n const video = this.video;\n if (!video) {\n return;\n }\n this.options = InputOptions;\n this.reInit$.next();\n\n // Reset touch state to prevent stale identifiers across sessions\n this.fingerIds.clear();\n this.fingers = [...INITIAL_FINGER_IDS];\n\n merge(\n fromResizeObserver(video),\n this.actions$.pipe(ofType(videoAdaptedToContainer)),\n )\n .pipe(\n debounceTime(RESIZE_DEBOUNCE_MS),\n takeUntil(this.deactivatedVideoTrigger$),\n )\n .subscribe(() => this.setupNormalizeAndQuantize(video));\n\n this.setupNormalizeAndQuantize(video);\n this.registerInputs(video);\n }\n\n /**\n * We use `object-fit: cover` on the video element. Since the video can have\n * a different aspect ratio from its container (and potentially be larger),\n * we need to calculate offsets and scale factors to map container (e.g., mouse)\n * coordinates back to the actual video coordinates.\n *\n * @param videoElement The video element whose scaling and positioning we need\n * @returns Object containing offset and scale info for coordinate normalization\n * @private\n */\n private getObjectFitOffset(videoElement: HTMLVideoElement) {\n const { width, height } = this.videoBoundingRect;\n const { videoWidth, videoHeight } = videoElement;\n\n Logger.log('Video Quantizing with => ', this.videoBoundingRect, {\n videoWidth,\n videoHeight,\n });\n\n const containerRatio = width / height;\n const videoRatio = videoWidth / videoHeight;\n\n const scale =\n videoRatio > containerRatio ? height / videoHeight : width / videoWidth;\n\n const scaledWidth = videoWidth * scale;\n const scaledHeight = videoHeight * scale;\n\n const offsetByX = (width - scaledWidth) / 2;\n const offsetByY = (height - scaledHeight) / 2;\n\n const scaleX = width / scaledWidth;\n const scaleY = height / scaledHeight;\n\n return {\n offsetByX,\n offsetByY,\n scaleX,\n scaleY,\n scaledWidth,\n scaledHeight,\n };\n }\n\n private setupNormalizeAndQuantize(videoElement: HTMLVideoElement) {\n this.videoBoundingRect = videoElement.getBoundingClientRect();\n this.offsetParams = this.getObjectFitOffset(videoElement);\n\n // Unsigned XY positions are the ratio (0.0..1.0) along a viewport axis,\n // quantized into a uint16 (0..65536).\n // Signed XY deltas are the ratio (-1.0..1.0) along a viewport axis,\n // quantized into an int16 (-32767..32767).\n // This allows the browser viewport and client viewport to have different sizes.\n // Hack: an out-of-range position becomes UNSIGNED_OUT_OF_RANGE because we\n // can't yet accurately detect mouse enter/leave precisely inside a video\n // with an aspect ratio that causes mattes.\n\n this.normalizeAndQuantizeUnsigned = (x, y) => {\n const normalizedX = x / videoElement.clientWidth;\n const normalizedY = y / videoElement.clientHeight;\n\n if (\n normalizedX < 0.0 ||\n normalizedX > 1.0 ||\n normalizedY < 0.0 ||\n normalizedY > 1.0\n ) {\n return {\n inRange: false,\n x: UNSIGNED_OUT_OF_RANGE,\n y: UNSIGNED_OUT_OF_RANGE,\n };\n }\n return {\n inRange: true,\n x: normalizedX * UNSIGNED_RANGE,\n y: normalizedY * UNSIGNED_RANGE,\n };\n };\n\n this.normalizeAndQuantizeSigned = (x, y) => {\n const normalizedX = x / (0.5 * videoElement.clientWidth);\n const normalizedY = y / (0.5 * videoElement.clientHeight);\n return {\n x: normalizedX * SIGNED_RANGE,\n y: normalizedY * SIGNED_RANGE,\n };\n };\n }\n\n private sendInputData(data: ArrayBuffer) {\n this.commandsSender.sendInputData(data);\n }\n\n private registerInputs(video: HTMLVideoElement) {\n fromEvent(window, 'blur')\n .pipe(\n filter(() => !!video),\n takeUntil(this.deactivatedVideoTrigger$),\n )\n .subscribe(() => this.releaseMouseButtons(255, 0, 0));\n\n this.registerMouseEnterAndLeaveEvents(video);\n this.registerHoveringMouseEvents(video);\n this.registerKeyboardEvents(this.availableKeys);\n this.registerTouchEvents(video);\n }\n\n private getTouchPositionWithOffset({ clientX, clientY }: Touch) {\n const { offsetByX, offsetByY, scaleX, scaleY } = this.offsetParams;\n\n return {\n x: (clientX - offsetByX - this.videoBoundingRect.left) * scaleX,\n y: (clientY - offsetByY - this.videoBoundingRect.top) * scaleY,\n };\n }\n\n private getMousePositionWithOffset({ offsetX, offsetY }: MouseEvent) {\n const { offsetByX, offsetByY, scaleX, scaleY } = this.offsetParams;\n\n return {\n x: (offsetX - offsetByX) * scaleX,\n y: (offsetY - offsetByY) * scaleY,\n };\n }\n\n private registerTouchEvents(htmlVideoElement: HTMLVideoElement) {\n const rememberTouch = (touch: Touch) => {\n const finger = this.fingers.pop();\n if (finger === undefined) {\n Logger.info('exhausted touch identifiers');\n return;\n }\n this.fingerIds.set(touch.identifier, finger);\n };\n\n const forgetTouch = (touch: Touch) => {\n const finger = this.fingerIds.get(touch.identifier);\n if (finger !== undefined) {\n this.fingers.push(finger);\n // Re-sort descending so the lowest available id is popped next.\n this.fingers.sort((a, b) => b - a);\n }\n this.fingerIds.delete(touch.identifier);\n };\n\n const emitTouchData = (type: MessageTypeValues, touches: TouchList) => {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n let byte = 2;\n const numTouches = 1;\n const touch = touches[t];\n const finger = this.fingerIds.get(touch.identifier);\n // Skip unknown identifiers (e.g., stale touch on a fast retap) — sending\n // 0 here would alias finger '0' and corrupt UE's touch state.\n if (finger === undefined) {\n continue;\n }\n const { x, y } = this.getTouchPositionWithOffset(touch);\n Logger.info(`F${finger}=(${x}, ${y})`);\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.touchView;\n\n data.setUint8(0, type);\n data.setUint8(1, numTouches);\n data.setUint16(byte, coord.x, true);\n byte += 2;\n data.setUint16(byte, coord.y, true);\n byte += 2;\n data.setUint8(byte, finger);\n byte += 1;\n // iOS bug: force is locked to 0.5 since forced touch is unused.\n data.setUint8(byte, this.maxByteValue * 0.5);\n byte += 1;\n data.setUint8(byte, coord.inRange ? 1 : 0);\n this.sendInputData(data.buffer);\n }\n };\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchstart')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.focusWindow();\n const touches: TouchList = e.changedTouches;\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n rememberTouch(touches[t]);\n }\n Logger.info('touch start');\n emitTouchData(MessageType.TouchStart, touches);\n e.preventDefault();\n });\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchend')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const touches: TouchList = e.changedTouches;\n Logger.info('touch end');\n\n emitTouchData(MessageType.TouchEnd, touches);\n\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let t = 0; t < touches.length; t++) {\n forgetTouch(touches[t]);\n }\n\n e.preventDefault();\n });\n\n fromEvent<TouchEvent>(htmlVideoElement, 'touchmove')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n emitTouchData(MessageType.TouchMove, e.touches);\n e.preventDefault();\n });\n }\n\n focusWindow() {\n window.focus();\n }\n\n emitMouseMove(x: number, y: number, deltaX: number, deltaY: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const delta = this.normalizeAndQuantizeSigned(deltaX, deltaY);\n const data = this.mouseMoveView;\n\n data.setUint8(0, MessageType.MouseMove);\n data.setUint16(1, coord.x, true);\n data.setUint16(3, coord.y, true);\n data.setInt16(5, delta.x, true);\n data.setInt16(7, delta.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseDown(button: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseButtonView;\n data.setUint8(0, MessageType.MouseDown);\n data.setUint8(1, button);\n data.setUint16(2, coord.x, true);\n data.setUint16(4, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseUp(button: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseButtonView;\n data.setUint8(0, MessageType.MouseUp);\n data.setUint8(1, button);\n data.setUint16(2, coord.x, true);\n data.setUint16(4, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n emitMouseWheel(delta: number, x: number, y: number) {\n const coord = this.normalizeAndQuantizeUnsigned(x, y);\n const data = this.mouseWheelView;\n data.setUint8(0, MessageType.MouseWheel);\n data.setInt16(1, delta, true);\n data.setUint16(3, coord.x, true);\n data.setUint16(5, coord.y, true);\n this.sendInputData(data.buffer);\n }\n\n private releaseMouseButtons(buttons: number, x: number, y: number) {\n if (buttons & MouseButtonsMask.PrimaryButton) {\n this.emitMouseUp(MouseButton.MainButton, x, y);\n }\n if (buttons & MouseButtonsMask.SecondaryButton) {\n this.emitMouseUp(MouseButton.SecondaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.AuxiliaryButton) {\n this.emitMouseUp(MouseButton.AuxiliaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.FourthButton) {\n this.emitMouseUp(MouseButton.FourthButton, x, y);\n }\n if (buttons & MouseButtonsMask.FifthButton) {\n this.emitMouseUp(MouseButton.FifthButton, x, y);\n }\n }\n\n private pressMouseButtons(buttons: number, x: number, y: number) {\n if (buttons & MouseButtonsMask.PrimaryButton) {\n this.emitMouseDown(MouseButton.MainButton, x, y);\n }\n if (buttons & MouseButtonsMask.SecondaryButton) {\n this.emitMouseDown(MouseButton.SecondaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.AuxiliaryButton) {\n this.emitMouseDown(MouseButton.AuxiliaryButton, x, y);\n }\n if (buttons & MouseButtonsMask.FourthButton) {\n this.emitMouseDown(MouseButton.FourthButton, x, y);\n }\n if (buttons & MouseButtonsMask.FifthButton) {\n this.emitMouseDown(MouseButton.FifthButton, x, y);\n }\n }\n\n private registerHoveringMouseEvents(htmlVideoElement: HTMLVideoElement) {\n fromEvent<MouseEvent>(htmlVideoElement, 'mousemove')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.emitMouseMove(x, y, e.movementX, e.movementY);\n e.preventDefault();\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mousedown')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.focusWindow();\n this.emitMouseDown(e.button, x, y);\n e.preventDefault();\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseup')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const { x, y } = this.getMousePositionWithOffset(e);\n this.emitMouseUp(e.button, x, y);\n e.preventDefault();\n });\n\n fromEvent<WheelEvent>(htmlVideoElement, 'wheel')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.emitMouseWheel(e.deltaY * WHEEL_DELTA_SCALE, e.offsetX, e.offsetY);\n e.preventDefault();\n });\n }\n\n private registerMouseEnterAndLeaveEvents(htmlVideoElement: HTMLVideoElement) {\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseenter')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n this.focusWindow();\n const data = this.singleByteView;\n data.setUint8(0, MessageType.MouseEnter);\n this.sendInputData(data.buffer);\n this.pressMouseButtons(e.buttons, e.offsetX, e.offsetY);\n });\n\n fromEvent<MouseEvent>(htmlVideoElement, 'mouseleave')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n const data = this.singleByteView;\n data.setUint8(0, MessageType.MouseLeave);\n this.sendInputData(data.buffer);\n this.releaseMouseButtons(e.buttons, e.offsetX, e.offsetY);\n });\n }\n\n // Browser keys do not have a charCode so we only need to test keyCode.\n private isKeyCodeBrowserKey(keyCode: number): boolean {\n return (\n (keyCode >= FUNCTION_KEY_MIN && keyCode <= FUNCTION_KEY_MAX) ||\n keyCode === TAB_KEY_CODE\n );\n }\n\n private getKeyCode(e: KeyboardEvent): number {\n if (e.keyCode === SpecialKeyCodes.Shift && e.code === 'ShiftRight')\n return SpecialKeyCodes.RightShift;\n else if (e.keyCode === SpecialKeyCodes.Control && e.code === 'ControlRight')\n return SpecialKeyCodes.RightControl;\n else if (e.keyCode === SpecialKeyCodes.Alt && e.code === 'AltRight')\n return SpecialKeyCodes.RightAlt;\n else return e.keyCode;\n }\n\n private registerKeyboardEvents(availableKeys: IKeyCode[]) {\n const availableKeyNames = availableKeys.map(\n (value) => InvertedKeyMap[value],\n );\n\n const keyBlock = (event: KeyboardEvent) => {\n const code: IKeyName = event.code as IKeyName;\n const isInputFieldFocused =\n (event.target as HTMLElement)?.localName === 'input';\n const keyMatch = availableKeyNames.includes(code);\n\n if (this.isDevMode && !keyMatch) {\n Logger.warn(\n 'Code=>',\n code,\n 'Keyboard event is not filtered in DEV Mode. App may behave inappropriately!',\n );\n return isInputFieldFocused;\n }\n\n return isInputFieldFocused || !keyMatch;\n };\n this.startListenKeys(keyBlock);\n }\n\n private startListenKeys(_filter?: (event: KeyboardEvent) => boolean) {\n const filter = _filter ?? (() => false);\n\n fromEvent<KeyboardEvent>(document, 'keydown')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n\n const isCtrlOrCommand = e.ctrlKey || e.metaKey;\n\n const isPlusOrMinus =\n e.keyCode === KeyboardNumericCode.Equal ||\n e.keyCode === KeyboardNumericCode.Minus;\n if (isCtrlOrCommand && isPlusOrMinus) {\n return;\n }\n\n const keyDown = this.keyDownBytes;\n keyDown[0] = MessageType.KeyDown;\n keyDown[1] = this.getKeyCode(e);\n keyDown[2] = Number(e.repeat);\n this.sendInputData(keyDown.buffer);\n // Backspace isn't a keypress in JS, but UE4 text-entry fields need it\n // to delete characters.\n if (e.keyCode === SpecialKeyCodes.BackSpace) {\n const data = this.keyPressView;\n data.setUint8(0, MessageType.KeyPress);\n data.setUint16(1, SpecialKeyCodes.BackSpace, true);\n this.sendInputData(data.buffer);\n }\n if (\n this.options.suppressBrowserKeys &&\n this.isKeyCodeBrowserKey(e.keyCode)\n ) {\n e.preventDefault();\n }\n });\n\n fromEvent<KeyboardEvent>(document, 'keyup')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n const keyUp = this.keyUpBytes;\n keyUp[0] = MessageType.KeyUp;\n keyUp[1] = this.getKeyCode(e);\n this.sendInputData(keyUp.buffer);\n if (\n this.options.suppressBrowserKeys &&\n this.isKeyCodeBrowserKey(e.keyCode)\n ) {\n e.preventDefault();\n }\n });\n\n fromEvent<KeyboardEvent>(document, 'keypress')\n .pipe(takeUntil(this.deactivatedVideoTrigger$))\n .subscribe((e) => {\n if (filter(e)) {\n return;\n }\n const data = this.keyPressView;\n data.setUint8(0, MessageType.KeyPress);\n data.setUint16(1, e.charCode, true);\n this.sendInputData(data.buffer);\n });\n }\n}\n\ninterface OffsetParams {\n scaleX: number;\n scaleY: number;\n scaledHeight: number;\n scaledWidth: number;\n offsetByY: number;\n offsetByX: number;\n}\n","import { ofType } from '@ngrx/effects';\nimport { inject, Injectable } from '@angular/core';\nimport { asyncScheduler, type Observable, takeUntil, throttleTime } from 'rxjs';\nimport {\n filter,\n map,\n startWith,\n switchMap,\n take,\n withLatestFrom,\n} from 'rxjs/operators';\nimport { initSignalling, trackMixpanelEvent, unrealFeature } from '../store';\nimport type { AggregatedStat, AwsInstance } from '../interfaces';\nimport { VideoService } from './video.service';\nimport { UNREAL_CONFIG } from '../constants';\nimport { SubService } from './sub.service';\n\ninterface MapEventDataParams {\n data: AggregatedStat;\n signalingServer: AwsInstance;\n startTimeUtc: string;\n signalingReadyTime: number | undefined;\n viewPortReadyTime: number | undefined;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class StreamStatusTelemetryService extends SubService {\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright) {\n return;\n }\n\n // Start a telemetry session on every `initSignalling` dispatch.\n // switchMap cancels the previous session's inner pipeline on re-init.\n // throttleTime leading+trailing emits the first event immediately and\n // at most one event every 5s afterward.\n this.actions$\n .pipe(\n ofType(initSignalling),\n switchMap(() => {\n // Captured once per session — marks the UTC moment signaling started.\n const startedAt = Date.now();\n const startTimeUtc = new Date(startedAt).toISOString();\n const signalingReadyTime$ = this.readyTimeSince(\n this.store.select(unrealFeature.selectCirrusConnected),\n startedAt,\n );\n const viewPortReadyTime$ = this.readyTimeSince(\n this.store.select(unrealFeature.selectViewportReady),\n startedAt,\n );\n return this.videoService.videoStats$.pipe(\n throttleTime(5000, asyncScheduler, {\n leading: true,\n trailing: true,\n }),\n withLatestFrom(\n this.store.select(unrealFeature.selectAwsInstance),\n signalingReadyTime$,\n viewPortReadyTime$,\n ),\n map(\n ([\n data,\n signalingServer,\n signalingReadyTime,\n viewPortReadyTime,\n ]) =>\n this.mapEventData({\n data,\n signalingServer,\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n }),\n ),\n );\n }),\n takeUntil(this.destroy$),\n )\n .subscribe((data) =>\n this.store.dispatch(\n trackMixpanelEvent({ event: 'streamStatus', data }),\n ),\n );\n }\n\n /**\n * Emits `undefined` until `readyState$` first emits a truthy value,\n * then emits the ms elapsed since `startedAt` and completes.\n * Used with `withLatestFrom` so events carry a stable duration for the whole session.\n */\n private readyTimeSince(\n readyState$: Observable<boolean>,\n startedAt: number,\n ): Observable<number | undefined> {\n return readyState$.pipe(\n filter(Boolean),\n take(1),\n map(() => Date.now() - startedAt),\n startWith<number | undefined>(undefined),\n );\n }\n\n private mapEventData(params: MapEventDataParams) {\n const {\n data,\n signalingServer,\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n } = params;\n\n const {\n bitrate,\n VideoEncoderQP,\n framesPerSecond,\n frameWidth,\n frameHeight,\n jitter,\n packetsLost,\n currentRoundTripTime,\n runTime,\n } = data.aggregatedStats;\n\n return {\n startTimeUtc,\n signalingReadyTime,\n viewPortReadyTime,\n runTime,\n frameWidth,\n frameHeight,\n client: signalingServer.wsUrl,\n pixelRatio: window.devicePixelRatio,\n framesPerSecond,\n jitter,\n packetsLost,\n instanceName: signalingServer.instanceName,\n bitrate,\n rtt: currentRoundTripTime,\n VideoEncoderQP,\n };\n }\n}\n","import { Store } from '@ngrx/store';\nimport { Actions, ofType } from '@ngrx/effects';\nimport { DestroyRef, inject, Injectable } from '@angular/core';\nimport {\n bufferTime,\n filter,\n fromEvent,\n map,\n type Observable,\n scan,\n startWith,\n Subject,\n Subscription,\n switchMap,\n take,\n takeUntil,\n withLatestFrom,\n} from 'rxjs';\nimport {\n answerSent,\n commandCompleted,\n commandStarted,\n destroyUnrealScene,\n instanceReady,\n pollingEnded,\n pollingStarted,\n regionPingFetchEnd,\n regionPingFetchStart,\n regionResolved,\n setAwsInstance,\n setCirrusDisconnected,\n setEstablishingConnection,\n setMaxFps,\n setOrchestrationParameters,\n signalingRetryAttempted,\n streamAdopted,\n trackTelemetryData,\n unrealFeature,\n} from '../store';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { AggregatedStat } from '../interfaces';\nimport { DisconnectReason } from '../interfaces';\nimport { VideoService } from './video.service';\nimport { SignallingService } from './signalling.service';\nimport { REGION_PING_CACHE_KEY, UNREAL_CONFIG } from '../constants';\n\n/**\n * Pro-grade telemetry for the WebRTC stream lifecycle.\n *\n * Wire-level event taxonomy (intentionally small — all phase-specific\n * details ride inside `stream.phase_ended`'s payload):\n * - `stream.session_started` — once per session, when a real connection\n * attempt begins (`setEstablishingConnection(true)`)\n * - `stream.phase_ended` — once per closer in {@link phaseCatalog};\n * carries phaseNo / id / color /\n * milestones / params / overlays\n * - `stream.sample` — every 5s, window-aggregated (p. 50/p. 95/min/max)\n * - `stream.quality_degraded` — on QP entering `red` (>35)\n * - `stream.quality_recovered` — on QP leaving `red`\n * - `stream.fps_low` — when the window FPS p50 < 70% of the target\n * - `stream.session_ended` — once per session, on disconnect/pagehide/restart\n *\n * Every event carries `sessionId` + `userId`. Samples carry a monotonic\n * `seq` for server-side ordering & dedup. Durations use `performance.now()`\n * — immune to wall-clock jumps.\n *\n * NOTE: For `stream.session_ended` on the tab close to survive teardown,\n * the Mixpanel client must be configured with `api_transport: 'sendBeacon'`.\n */\ntype EndReason = 'disconnected' | 'pagehide' | 'restart' | 'destroy';\n\n/**\n * Statistical summary of a time-series metric (bitrate, fps, qp, jitter, rtt)\n * over a single aggregation window (default: 5 seconds, ~20 samples at 250ms).\n *\n * Each field answers a different question about the distribution within the\n * window. Together they describe the *shape* of the data, not just one number.\n *\n * ## Why aggregates instead of a single value\n *\n * The raw stream emits ~20 samples per 5s window. Reporting only the last\n * value (e.g. `throttleTime(5000)`) is fragile: one unlucky tick at the\n * window boundary can flip the signal. A single `mean` is also misleading\n * because one big outlier can drag it far from the typical value.\n * Percentiles and extremes give a stable, outlier-resistant view.\n *\n * ## Example\n *\n * Suppose the bitrate (bits/s) sampled over 5s is:\n * ```\n * [8M, 9M, 10M, 10M, 11M, 11M, 11M, 12M, 12M, 12M,\n * 12M, 12M, 13M, 13M, 13M, 13M, 13M, 14M, 14M, 20M]\n * ```\n * The resulting {@link WindowAggregate} is:\n * ```\n * { p50: 12_000_000, p95: 14_000_000, min: 8_000_000, max: 20_000_000 }\n * ```\n *\n * ## How to read each field\n *\n * | Field | Question it answers |\n * |-------|--------------------------------------------------------|\n * | p. 50 | \"What does the typical tick look like?\" |\n * | p. 95 | \"How bad is the bad tail that users notice?\" |\n * | min | \"Was there any catastrophic dip in this window?\" |\n * | max | \"Was there any peak / did we reach the target at all?\" |\n *\n * ## Why p. 50 instead of mean\n *\n * Mean is sensitive to outliers. Example FPS series `[60,60,60,60,60,60,60,60,60,5]`:\n * - mean ≈ 54.5 (looks fine)\n * - p. 50= 60 (truth: 9 of 10 ticks are perfect)\n * - min = 5 (but one tick collapsed)\n *\n * Mean smears the bad tick across the whole window. p50 reports the typical\n * case, `min` surfaces the worst, so together they describe reality.\n *\n * ## Why p95 instead of max\n *\n * `max` is a single tick — can be random noise (a 250ms glitch). `p95` is\n * \"the bad tail you consistently see\" and is what users actually perceive\n * as lag / freezes. For SLOs and alerting, use p95/p. 99 — not max.\n *\n * ## Dashboard / alerting hints\n *\n * - `bitrate.p50` → typical throughput over time\n * - `fps.p95 < 40` → 5% of the time the frame rate is poor (user-visible)\n * - `qp.max > 35` in a sliding window → quality spikes to investigate\n * - `fps.min` → the worst single tick, useful for freeze detection\n */\n/** One individual resource in the \"slowest N\" list of bootstrapInfo. */\ninterface SlowResource {\n /** Path only (origin + query stripped) — the file / endpoint. */\n name: string;\n /** Resource Timing initiatorType: 'script' | 'css' | 'img' | 'fetch' | … */\n type: string;\n /** responseEnd − startTime, ms. */\n durationMs: number;\n /** Bytes over the wire (0 = served from cache). */\n transferKb: number;\n /** Fetched after window.load (lazy route chunk) vs during page load. */\n lazy: boolean;\n}\n\n/** Trim a resource URL to its path: drop origin and query string so the\n * emitted name is short, stable, and not a PII-bearing query. */\nfunction shortResourceName(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return (url || '').split('?')[0];\n }\n}\n\ninterface WindowAggregate {\n /**\n * 50th percentile (median): value below which 50% of samples fall.\n * The \"typical\" value in the window — robust to outliers.\n * Use this as the primary signal on dashboards.\n */\n p50: number;\n\n /**\n * 95th percentile: value below which 95% of samples fall.\n * Describes the \"bad tail\" — the worst 5% of ticks. This is what\n * users perceive as lag / freezes. Preferred metric for SLOs and alerts.\n */\n p95: number;\n\n /**\n * Minimum sample in the window — the single worst tick observed.\n * Surfaces catastrophic dips (e.g., a single-frame freeze) that p50/p95\n * would smooth out. Noisy on its own; useful alongside p95.\n */\n min: number;\n\n /**\n * Maximum sample in the window — the single best tick observed.\n * Shows whether the system ever reached the target (e.g. \"did FPS ever\n * touch 60?\"). Like `min`, one-tick noisy; use it for ceiling / headroom checks.\n */\n max: number;\n}\n\n// ──────────────────────────────────────────────────────────────────\n// Milestone catalog\n//\n// is The single declarative source for everything this service tracks\n// beyond the four lifecycle boundaries (session_started / signaling /\n// datachannel / viewport). Each entry binds a stable *id* + *phase*\n// to an Observable that fires when the milestone happens — pass an\n// NgRx action stream, a `SignallingService` Subject, or any custom\n// Observable you construct.\n//\n// Adding a new milestone = one entry in this array PLUS one row in the\n// viewer's vocabulary map (id → human label) — the wire carries only\n// stable kebab-case ids; all display text lives viewer-side.\n// ──────────────────────────────────────────────────────────────────\n\n/**\n * Every stable id this service can emit on the wire — phases,\n * milestones, overlays. The viewer's vocabulary maps each member to a\n * human label, so every id added here needs a paired vocabulary row\n * in the viewer (`telemetry-vocabulary.ts`).\n */\nexport type EventId =\n // Phases\n | 'region-resolving'\n | 'signaling-connection'\n | 'webrtc-negotiation'\n | 'unreal-communication'\n // Milestones\n | 'region-ping-fetch-start'\n | 'region-ping-fetch-end'\n | 'region-resolved'\n | 'polling-started'\n | 'polling-ended'\n | 'aws-instance-resolved'\n | 'signaling-ws-connected'\n | 'instance-reserved'\n | 'instance-ready'\n | 'config-received'\n | 'ssinfo-received'\n | 'offer-received'\n | 'answer-sent'\n | 'answer-received'\n | 'first-ice-candidate'\n | 'last-ice-candidate'\n | 'datachannel-connected'\n | 'first-command-started'\n | 'loopback-sent'\n | 'loopback-received'\n | 'viewport-ready'\n // Overlays\n | 'polling-to-instance'\n | 'signaling-handshake'\n | 'stabilization-warmup';\n\n/** Wire-format milestone — minimal by design. `id` is a stable\n * kebab-case identifier; the viewer maps it to a human label via its\n * vocabulary. */\nexport interface EmittedMilestone {\n readonly id: EventId;\n readonly time: number;\n}\n\n/**\n * Selected WebRTC ICE candidate pair, pulled off {@link AggregatedStat}.\n * The closer for the viewport phase flattens this to two `PhaseParam`\n * rows (`localCandidate`, `remoteCandidate`) before emission.\n */\nexport interface SelectedIceCandidatePair {\n local: { type: string; url: string };\n remote: { type: string; url: string };\n}\n\n/**\n * Wire-format display key/value pair — rendered verbatim in the viewer's\n * phase tooltip. Nested or structured values should be pre-formatted by\n * the catalog closer's `map(...)` (string/number/boolean only).\n */\nexport interface PhaseParam {\n readonly key: string;\n readonly value: string;\n}\n\n/** Resolved overlay region sent on the wire. `id` is a stable\n * kebab-case identifier mapped to a title by the viewer's vocabulary. */\nexport interface PhaseOverlay {\n readonly fromMs: number;\n readonly toMs: number;\n readonly id: EventId;\n}\n\n/**\n * A single milestone entry — the object identity serves as its key in\n * the in-session `times` map, so no separate `name` field is needed.\n */\ninterface CatalogEntry {\n /** Stable kebab-case id emitted on the wire alongside the firing\n * time. Display text lives in the viewer's vocabulary map. */\n readonly id: EventId;\n /**\n * Source of the milestone. Subscribed once per session; unsubscribed on\n * teardown. For closers, the emission value (when it's a plain object)\n * is spread into the lifecycle event's payload — use inline `map(...)`\n * to shape the extras.\n */\n readonly event: Observable<unknown>;\n /**\n * `'first'` (default) — record only the first emission per session.\n * `'last'` — keep overwriting, so the recorded time is the latest\n * emission. Ignored for closers (they take(1) anyway).\n */\n readonly mode?: 'first' | 'last';\n}\n\n/**\n * Declarative overlay recipe — resolved to `{fromMs, toMs, id}` at\n * emission time by looking up entries by object identity. Either\n * endpoint can be omitted to fall back to the phase bounds.\n */\ninterface OverlayRecipe {\n readonly from?: CatalogEntry;\n readonly to?: CatalogEntry;\n /** Stable kebab-case id; the viewer's vocabulary maps it to a title. */\n readonly id: EventId;\n}\n\n/**\n * Unified phase catalog entry. The *last* item in `milestones` is the\n * phase closer: when its observable fires, the service emits a single\n * generic `stream.phase_ended` wire event carrying `phaseNo`, `id`,\n * `color`, `duration`, `milestones[]`, `params[]`, `overlays[]`.\n *\n * Display text is NOT on the wire — the viewer's vocabulary map turns\n * every id (phase / milestone / overlay) back into a human label.\n * Adding a new phase here therefore requires one paired vocabulary row\n * in the viewer.\n */\ninterface CatalogPhase {\n /** Stable kebab-case phase id. The viewer maps it to the bar label\n * and derives boundary labels from neighboring phases. */\n readonly id: EventId;\n /** Viewer bar color (hex). */\n readonly color: string;\n readonly milestones: readonly CatalogEntry[];\n /** Optional diagonal-stripe recipes; resolved to ms at a closer time. */\n readonly overlays?: readonly OverlayRecipe[];\n}\n\ninterface SessionState {\n id: string;\n startedAt: number; // Date.now() — wall-clock for startTimeUtc\n startedAtPerf: number; // performance.now() at session start — kept for info\n /**\n * Anchor for all reported milestone timestamps.\n * - First session on this page: `0` (= `performance` navigation start).\n * Bootstrap measurements (`session_started.duration`, resource timings)\n * naturally fall out of `performance.now()` being \"ms since nav start\".\n * - Subsequent (Resume) sessions: `startedAtPerf`. The document is\n * already loaded, so \"bootstrap\" has no meaning — we suppress it by\n * anchoring at the session itself.\n * Milestone `*Ms` values emitted inside lifecycle events are relative\n * to this anchor — the viewer's scale starts at 0 at the same anchor.\n */\n anchorPerf: number;\n /**\n * Monotonic time (performance.now()) of the last fired lifecycle event.\n * Used to compute each next event's `duration` as the width of its own\n * phase (`now - lastMilestonePerf`) rather than an anchor-relative value.\n */\n lastMilestonePerf: number;\n seq: number;\n sub: Subscription;\n qpBad: boolean;\n fpsLow: boolean;\n maxFpsTarget: number; // 0 = unlimited → compare against UNLIMITED_REFERENCE_FPS\n /** Total number of ICE candidates the server sent during negotiation.\n * Shipped as a phase param on `datachannel_connected` — useful for\n * diagnosing restrictive networks (tiny candidate count = no relay). */\n iceCandidateCount: number;\n /** Which handshake flow was used (server-offer is our default today,\n * but the detector stays in place in case the flow ever switches).\n * `null` until one of the two answer-events fires. */\n handshakeFlow: 'server-offer' | 'client-offer' | null;\n /** Running count of commands sent to Unreal during the session.\n * Snapshot ted into the `viewport_ready` closer payload — helps\n * spot verbose scene-start flows where Unreal took a while to\n * settle because the client fired a lot of initial commands. */\n commandCount: number;\n /**\n * Recorded firing times for each catalog entry this session. Keyed by\n * the CatalogEntry object itself (stable identity across the service\n * lifetime) — no string names needed. `milestonesOfBucket` / overlay\n * resolution walk the catalog and read from this map directly.\n */\n times: Map<CatalogEntry, number>;\n}\n\nconst QP_RED_THRESHOLD = 35;\nconst FPS_LOW_RATIO = 0.7; // p50 fps below 70% of target\nconst UNLIMITED_REFERENCE_FPS = 60;\nconst SAMPLE_WINDOW_MS = 5000;\n/**\n * Catalog phase ids the prefetch establishes invisibly. For an adopted\n * connection their live closers are suppressed and the phases are emitted by\n * {@link StreamStatusTelemetryService2.emitAdoptedConnection} instead, timed\n * from the prefetch's own marks and anchored at the moment Angular reached the\n * connect call (session start) — so the waterfall shows the time the prefetch\n * actually SAVED, not the prefetch's page-load-parallel raw timeline.\n */\nconst PREFETCHED_PHASE_IDS: ReadonlySet<string> = new Set([\n 'region-resolving',\n 'signaling-connection',\n 'webrtc-negotiation',\n]);\n// Persistent per-browser identifier — survives page reloads. Used to group\n// multiple sessions of the same anonymous user for funnel / retention analysis.\nconst USER_ID_STORAGE_KEY = 'source3d.streamTelemetry.userId';\n\n@Injectable({ providedIn: 'root' })\nexport class StreamStatusTelemetryService2 {\n private readonly store = inject(Store);\n private readonly actions$ = inject(Actions);\n private readonly videoService = inject(VideoService);\n private readonly signallingService = inject(SignallingService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly destroy$ = new Subject<void>();\n\n /**\n * Per-browser anonymous user id. Read from `localStorage` on first access;\n * if missing, a new UUID is generated and persisted. Included as\n * `data.userId` on every emitted event — the server uses it to bucket\n * per-session files under `data/<userId>/<sessionId>.jsonl`.\n */\n private readonly userId = this.getOrCreateUserId();\n\n /**\n * Synchronous reads of the unreal store's disconnect state. Read at\n * `endSession` time for the granular `disconnectReason` /\n * `disconnectMessage` wire fields. Reducers update both fields\n * synchronously before action subscribers fire, so by the time the\n * action-stream end-trigger subscriptions below run, state already\n * reflects the originating cause.\n */\n private readonly disconnectReason$ = this.store.selectSignal(\n unrealFeature.selectDisconnectReason,\n );\n private readonly errorMessage$ = this.store.selectSignal(\n unrealFeature.selectErrorMessage,\n );\n private readonly viewPortReady$ = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n /**\n * Synchronous adoption flag. The `streamAdopted` reducer sets it BEFORE any\n * action subscriber runs, so the connection-phase closers (which fire inside\n * the same dispatch, e.g. `ssinfo-received` off the `ssData` state change)\n * can read it and defer to the prefetch-timed attribution emitted by\n * {@link emitAdoptedConnection} instead of recording the live wall-clock.\n */\n private readonly adopted$ = this.store.selectSignal(\n unrealFeature.selectAdopted,\n );\n /** Streamer identity for the adopted signaling phase params. */\n private readonly ssData$ = this.store.selectSignal(\n unrealFeature.selectSsData,\n );\n private readonly awsInstance$ = this.store.selectSignal(\n unrealFeature.selectAwsInstance,\n );\n\n private session: SessionState | null = null;\n\n /**\n * Whether a session has already started during the current page lifetime.\n * Used to distinguish a fresh page load (bootstrap measurement is\n * meaningful) from a Résumé/restart (the document is already loaded,\n * so \"bootstrap\" is a no-op). Only the first session gets the bootstrap\n * phase anchored at navigation start (perf.now() === 0).\n */\n private hasStartedBefore = false;\n\n /**\n * Rolling snapshot of the currently selected WebRTC ICE candidate pair\n * (local/remote type + url). Scanned over `videoStats$` so the stream\n * *keeps* the first non-null pair even if later stats emit null — WebRTC\n * doesn't unselect a pair mid-session, but the source is nullable. The\n * `startWith(null)` seed makes `withLatestFrom` on this stream safe even\n * before the first video stat arrives (common at data-channel-open).\n */\n private readonly selectedPair$: Observable<SelectedIceCandidatePair | null> =\n this.videoService.videoStats$.pipe(\n map((s) => s.aggregatedStats.selectedPair ?? null),\n scan<SelectedIceCandidatePair | null, SelectedIceCandidatePair | null>(\n (acc, curr) => curr ?? acc,\n null,\n ),\n startWith<SelectedIceCandidatePair | null>(null),\n );\n\n /**\n * Correlation-matched Observable: emits once when the first `loopBack`\n * command's corresponding `command completed` action fires. Built from\n * the two related actions — the command-started captures the correlation\n * id; the command-completed with that id emits.\n */\n private readonly loopbackReceived$: Observable<unknown> = this.actions$.pipe(\n ofType(commandStarted),\n filter(({ command }) => command === 'loopBack'),\n take(1),\n switchMap(({ id }) =>\n this.actions$.pipe(\n ofType(commandCompleted),\n filter((b) => b.id === id),\n take(1),\n ),\n ),\n );\n\n // Overlay-referenced milestones — hoisted as fields so both\n // `milestones: [...]` and `overlays: [...]` share the same object\n // identity (the in-session Map keys milestones by that identity).\n private readonly pollingStartedEntry: CatalogEntry = {\n id: 'polling-started',\n event: this.actions$.pipe(ofType(pollingStarted)),\n };\n private readonly awsInstanceResolvedEntry: CatalogEntry = {\n id: 'aws-instance-resolved',\n event: this.actions$.pipe(ofType(setAwsInstance)),\n };\n private readonly loopbackReceivedEntry: CatalogEntry = {\n id: 'loopback-received',\n event: this.loopbackReceived$,\n };\n private readonly signalingServerConnectedEntry: CatalogEntry = {\n id: 'signaling-ws-connected',\n event: this.store\n .select(unrealFeature.selectCirrusConnected)\n .pipe(filter(Boolean), take(1)),\n };\n private readonly configReceivedEntry: CatalogEntry = {\n id: 'config-received',\n event: this.signallingService.onConfig$.pipe(filter(Boolean), take(1)),\n };\n\n /**\n * Unified phase catalog — the single source of truth for everything\n * this service tracks after `session_started`. Each entry is a phase;\n * its `milestones` array is ordered chronologically, and the *last*\n * entry is the phase closer. When that closer's observable fires, the\n * service emits one generic `stream.phase_ended` wire event with every\n * display field the viewer needs.\n *\n * `phaseNo` is the array index; `startPhase` chains from the previous\n * phase's `endPhase` — neither needs to be specified here.\n */\n private readonly phaseCatalog: readonly CatalogPhase[] = [\n {\n id: 'region-resolving',\n color: '#61afef',\n milestones: [\n {\n id: 'region-ping-fetch-start',\n event: this.actions$.pipe(ofType(regionPingFetchStart)),\n },\n {\n id: 'region-ping-fetch-end',\n event: this.actions$.pipe(ofType(regionPingFetchEnd)),\n },\n // CLOSER — the `regionResolved` action carries the raw ping\n // samples (one per probe) from `RegionsPingService`; the\n // catalog flattens them to a comma-separated string since\n // `toPhaseParams` only accepts primitives. Adopted connections never\n // run `getRegion`, but `UnrealEffects.regionTelemetryOnAdopt$` replays\n // the region waterfall (start → end → resolved) from the cached winner,\n // so this phase still appears with its ping samples.\n {\n id: 'region-resolved',\n event: this.actions$.pipe(\n ofType(regionResolved),\n take(1),\n map(({ region, pingsMs }) => ({\n region,\n pingsMs: pingsMs.length ? `${pingsMs.join(', ')} ms` : null,\n })),\n ),\n },\n ],\n },\n {\n id: 'signaling-connection',\n color: '#c678dd',\n overlays: [\n {\n from: this.pollingStartedEntry,\n to: this.awsInstanceResolvedEntry,\n id: 'polling-to-instance',\n },\n {\n from: this.signalingServerConnectedEntry,\n to: this.configReceivedEntry,\n id: 'signaling-handshake',\n },\n ],\n milestones: [\n this.pollingStartedEntry,\n {\n id: 'polling-ended',\n event: this.actions$.pipe(ofType(pollingEnded)),\n },\n this.awsInstanceResolvedEntry,\n this.signalingServerConnectedEntry,\n {\n id: 'instance-reserved',\n event: this.actions$.pipe(ofType(setOrchestrationParameters)),\n },\n {\n id: 'instance-ready',\n event: this.actions$.pipe(ofType(instanceReady)),\n },\n this.configReceivedEntry,\n {\n id: 'ssinfo-received',\n event: this.store.select(unrealFeature.selectSsData).pipe(\n filter(Boolean),\n take(1),\n withLatestFrom(this.store.select(unrealFeature.selectAwsInstance)),\n map(([ssData, aws]) => ({\n client: aws.wsUrl,\n instanceName: aws.instanceName,\n ...ssData,\n })),\n ),\n },\n ],\n },\n {\n id: 'webrtc-negotiation',\n color: '#e5c07b',\n milestones: [\n {\n id: 'offer-received',\n event: this.signallingService.onOffer$.pipe(filter(Boolean)),\n },\n {\n id: 'answer-sent',\n event: this.actions$.pipe(ofType(answerSent)),\n },\n {\n id: 'answer-received',\n event: this.signallingService.onWebRtcAnswer$.pipe(filter(Boolean)),\n },\n {\n id: 'first-ice-candidate',\n event: this.signallingService.onWebRtcIce$.pipe(filter(Boolean)),\n },\n {\n id: 'last-ice-candidate',\n event: this.signallingService.onWebRtcIce$.pipe(filter(Boolean)),\n mode: 'last',\n },\n // CLOSER — snaps negotiation diagnostics and the Cirrus\n // streamer identity (`ssData`, reliably populated by DC-open\n // time) into phase-3 params:\n // - `iceCandidateCount` (total ICE candidates from server — too\n // few hints at a restrictive network)\n // - `handshakeFlow` (server-offer vs. client-offer; we only use\n // server-offer today, but the detector stays in place)\n // - `instanceType` / `branchInfo` / version / path / app /\n // `connectionId` (streamer identity, from `ssInfo` message)\n {\n id: 'datachannel-connected',\n event: this.store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(\n filter(Boolean),\n take(1),\n map(() => ({\n iceCandidateCount: this.session?.iceCandidateCount ?? 0,\n handshakeFlow: this.session?.handshakeFlow ?? null,\n })),\n ),\n },\n ],\n },\n {\n id: 'unreal-communication',\n color: '#98c379',\n overlays: [\n {\n from: this.loopbackReceivedEntry,\n id: 'stabilization-warmup',\n },\n ],\n milestones: [\n {\n id: 'first-command-started',\n event: this.actions$.pipe(ofType(commandStarted)),\n },\n {\n id: 'loopback-sent',\n event: this.actions$.pipe(\n ofType(commandStarted),\n filter(({ command }) => command === 'loopBack'),\n ),\n },\n this.loopbackReceivedEntry,\n // CLOSER — flattens the selected ICE candidate pair into two\n // string params (local / remote), and snapshots the running\n // command counter, so phase 5 shows how many commands the client\n // fired at Unreal before the viewport was ready.\n {\n id: 'viewport-ready',\n event: this.store.select(unrealFeature.selectViewportReady).pipe(\n filter(Boolean),\n take(1),\n withLatestFrom(this.selectedPair$),\n map(([, selectedPair]) => ({\n localCandidate: fmtCandidate(selectedPair?.local),\n remoteCandidate: fmtCandidate(selectedPair?.remote),\n commandCount: this.session?.commandCount ?? 0,\n // `lastMilestonePerf` still points at the previous phase end\n // (data channel connected) — `emitPhaseEnded` advances it\n // only after this map() has run.\n msSinceDataChannel: this.session\n ? Math.round(performance.now() - this.session.lastMilestonePerf)\n : null,\n })),\n ),\n },\n ],\n },\n ];\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n // End any active session BEFORE completing destroy$, so the\n // session-scoped subscriptions in `this.session.sub` are released.\n this.endSession('destroy');\n this.destroy$.next();\n this.destroy$.complete();\n });\n if (this.unrealConfig?.playwright) {\n return;\n }\n this.init();\n }\n\n private getOrCreateUserId(): string {\n try {\n const existing = localStorage.getItem(USER_ID_STORAGE_KEY);\n if (existing && existing.length > 0) return existing;\n const fresh = uuidv4();\n localStorage.setItem(USER_ID_STORAGE_KEY, fresh);\n return fresh;\n } catch {\n // localStorage disabled (private-mode restrictions, quota, etc.)\n // Fall back to a per-tab ephemeral id so telemetry keeps working.\n return uuidv4();\n }\n }\n\n private init() {\n // Start a new session when a real connection attempt BEGINS, not on\n // every `initSignalling` dispatch. `initSignalling` is fired multiple\n // times per page load (the unreal-scene effect, `startStream`, the\n // reconnect effect), but the connection layer collapses them into one\n // attempt via `connectToSignaling$` (`exhaustMap` + `!cirrusConnected`\n // filter). `setEstablishingConnection(true)` is dispatched exactly\n // once per real attempt from `SignallingService.startEstablishingConnection()`,\n // downstream of that guard — so binding here yields one session per\n // attempt instead of a burst of `restart` churn sessions. Genuine\n // reconnects (e.g. DataChannelTimeout) re-enter the same path and\n // correctly end the prior session as `restart` + start a new one.\n this.actions$\n .pipe(\n ofType(setEstablishingConnection),\n filter(({ value }) => value === true),\n takeUntil(this.destroy$),\n )\n .subscribe(() => this.startSession());\n\n // Action-stream end triggers (NOT a state-observable subscription).\n //\n // We can't observe the cirrus connection flag via `pairwise`\n // because the `destroyUnrealScene` reducer resets the entire\n // unreal state to `initialState` in one step — `cirrusConnected`\n // flips from `true` to `false` AND `disconnectReason` resets to\n // `None` simultaneously. A state-observable subscriber would fire\n // synchronously inside that reducer's emission, before the\n // follow-up effect (`destroyUnrealScene → destroyRemoteConnections({Destroy})`)\n // gets a chance to write `Destroy` back into state — so the\n // subscriber would see `None` and end as `'disconnected'`.\n //\n // Subscribing to the actions instead lets us pick the right\n // reason per dispatched action, and `endSession` is idempotent\n // (`if (!this.session) return`) so any cascading second trigger\n // is a no-op. Coverage:\n // - `destroyUnrealScene` → `'destroy'` (route change, removed from DOM)\n // - `setCirrusDisconnected` → `'disconnected'` (WS close, AFK,\n // manual drop, WebRTCError, etc. — granular cause + message\n // read from current state in `endSession`)\n this.actions$\n .pipe(ofType(destroyUnrealScene), takeUntil(this.destroy$))\n .subscribe(() => this.endSession('destroy'));\n\n this.actions$\n .pipe(ofType(setCirrusDisconnected), takeUntil(this.destroy$))\n .subscribe(() => this.endSession('disconnected'));\n\n // Close the session when the tab is hidden / being evicted from cache.\n // `pagehide` fires in more cases than `beforeunload` (covers iOS Safari, bfcache).\n fromEvent(window, 'pagehide')\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.endSession('pagehide'));\n }\n\n private startSession() {\n // If a previous session is still active, close it first.\n this.endSession('restart');\n\n const id = uuidv4();\n const startedAt = Date.now();\n const startedAtPerf = performance.now();\n const sub = new Subscription();\n\n // Anchor selection:\n // - First session on this page → anchor at navigation start (0).\n // `performance.now()` is already \"ms since navigation start\", so\n // `session_started.duration` becomes the full page-load + idle-time\n // leading up to the first stream start (i.e., the real bootstrap).\n // - Resume/restart sessions → anchor at the session's own start.\n // The document is already loaded — a \"bootstrap\" phase would either\n // balloon (to include all prior idle time) or be misleading, so we\n // suppress it by making the anchor == session_started.\n const isFirstSession = !this.hasStartedBefore;\n this.hasStartedBefore = true;\n const anchorPerf = isFirstSession ? 0 : startedAtPerf;\n\n const times = new Map<CatalogEntry, number>();\n\n this.session = {\n id,\n startedAt,\n startedAtPerf,\n anchorPerf,\n // Initial milestone anchor = anchorPerf. For the first session this is\n // navigation start (0), so `session_started.duration` becomes the full\n // page-load elapsed. For Resume sessions anchor == startedAtPerf, so\n // `session_started.duration` is 0 (no bootstrap phase).\n lastMilestonePerf: anchorPerf,\n seq: 0,\n sub,\n qpBad: false,\n fpsLow: false,\n maxFpsTarget: UNLIMITED_REFERENCE_FPS,\n iceCandidateCount: 0,\n handshakeFlow: null,\n commandCount: 0,\n times,\n };\n\n // Side-channel counters for WebRTC negotiation diagnostics — shown\n // as phase-3 params on the `datachannel_connected` closer. Kept\n // imperative (session-scoped) so no RxJS hot-stream plumbing is\n // needed to survive the subscribe-on-close timing.\n sub.add(\n this.signallingService.onWebRtcIce$\n .pipe(filter(Boolean))\n .subscribe(() => {\n if (this.session) this.session.iceCandidateCount++;\n }),\n );\n sub.add(\n this.actions$.pipe(ofType(answerSent), take(1)).subscribe(() => {\n if (this.session) this.session.handshakeFlow = 'server-offer';\n }),\n );\n sub.add(\n this.signallingService.onWebRtcAnswer$\n .pipe(filter(Boolean), take(1))\n .subscribe(() => {\n if (this.session) this.session.handshakeFlow = 'client-offer';\n }),\n );\n // Unreal-command counter — increments on every `commandStarted`\n // action. Snapshot ted into the `viewport_ready` closer payload as\n // phase-5's `commandCount`.\n sub.add(\n this.actions$.pipe(ofType(commandStarted)).subscribe(() => {\n if (this.session) this.session.commandCount++;\n }),\n );\n\n // Per-attempt observability for the signalling retry loops. Every\n // `retry({ delay })` callback in `SignallingService` (both the\n // outer connect retry and the inner orchestration retry) dispatches\n // `signalingRetryAttempted` with the attempt index, the underlying\n // error message, and which retry it was. Each one becomes a\n // `stream.signaling_retry` wire event the viewer surfaces in the\n // Anomalies table — see `SIGNALLING.md` for context.\n sub.add(\n this.actions$\n .pipe(ofType(signalingRetryAttempted))\n .subscribe(({ attempt, reason, kind }) => {\n if (!this.session) return;\n this.track('stream.signaling_retry', {\n sessionId: this.session.id,\n seq: this.session.seq,\n timestamp: new Date().toISOString(),\n attempt,\n reason,\n kind,\n });\n }),\n );\n\n // Unified catalog loop — one subscription per entry. Non-closers\n // record their emission time into the session map. The *last* entry\n // of each phase is the closer: its emission fires a single generic\n // `stream.phase_ended` event carrying every display field the viewer\n // needs. The viewer never inspects milestone names or phase kinds;\n // adding a new phase to `phaseCatalog` is enough — zero viewer work.\n this.phaseCatalog.forEach((bucket, bucketIdx) => {\n bucket.milestones.forEach((entry, idx) => {\n const isCloser = idx === bucket.milestones.length - 1;\n sub.add(\n entry.event.subscribe((value) => {\n if (!this.session) return;\n if (isCloser) {\n // Adopted connections receive the region / signaling / webrtc\n // phases from `emitAdoptedConnection` (timed from the prefetch's\n // own marks). Skip the live closer for those, so the whole\n // pre-adoption wait isn't dumped onto whichever connection closer\n // happens to fire first at the adoption instant.\n if (this.adopted$() && PREFETCHED_PHASE_IDS.has(bucket.id))\n return;\n this.emitPhaseEnded(bucket, bucketIdx, value);\n return;\n }\n const time = Math.round(\n performance.now() - this.session.anchorPerf,\n );\n if (entry.mode !== 'last' && this.session.times.has(entry)) return;\n this.session.times.set(entry, time);\n }),\n );\n });\n });\n\n // Adopted connection: emit the region / signaling / webrtc phases timed\n // from the prefetch marks, anchored at session start (see method doc). The\n // live closers for these phases are suppressed (PREFETCHED_PHASE_IDS).\n sub.add(\n this.actions$\n .pipe(ofType(streamAdopted))\n .subscribe(({ timings }) => this.emitAdoptedConnection(timings)),\n );\n\n const bootstrapInfo = this.collectBootstrapInfo();\n\n this.emitLifecycle(\n 'stream.session_started',\n {\n sessionId: id,\n startTimeUtc: new Date(startedAt).toISOString(),\n pixelRatio: window.devicePixelRatio,\n // Browser viewport size at session start (`window.innerWidth` /\n // `innerHeight`). Named `browserInnerSize` to distinguish from\n // the physical screen — what gates the rendered video resolution\n // is the container we started from, not the device hardware.\n browserInnerSize: {\n width: window.innerWidth,\n height: window.innerHeight,\n },\n userAgent: navigator.userAgent,\n sampleWindowMs: SAMPLE_WINDOW_MS,\n // Full page URL — `location.href` is the only reliable way to get this.\n // The server-observed `Referer` header is truncated to origin for\n // cross-origin requests by default Referrer-Policy.\n pageUrl: window.location.href,\n // Navigation / page-load context for the \"app bootstrap → session_started\"\n // waterfall phase. Only useful for the first session (`bootstrap` phase\n // is suppressed on Resume), but `bootstrapInfo` describes the document,\n // not the session — harmless and cheap to send either way.\n ...(bootstrapInfo && { bootstrapInfo }),\n },\n // Pin the milestone to the captured `performance.now()` so `duration`\n // equals \"ms since navigation start\" precisely (for first sessions),\n // rather than being inflated by any synchronous setup done in between.\n startedAtPerf,\n );\n\n // Track current maxFps target to evaluate FPS-ratio anomalies.\n sub.add(\n this.actions$\n .pipe(ofType(setMaxFps))\n .subscribe(({ maxFps }) => this.updateMaxFpsTarget(maxFps)),\n );\n\n // Periodic aggregated sample — every 5s window.\n sub.add(\n this.videoService.videoStats$\n .pipe(\n bufferTime(SAMPLE_WINDOW_MS),\n filter((samples) => samples.length > 0),\n )\n .subscribe((samples) => this.handleWindow(samples)),\n );\n }\n\n private endSession(reason: EndReason) {\n if (!this.session) return;\n const { id, sub } = this.session;\n\n // Granular cause + message read from current store state. The\n // unreal reducer updates these synchronously when the originating\n // action (`disconnectStream` / `destroyRemoteConnections`) fires,\n // so by the time `endSession` runs they reflect the cause that\n // triggered this teardown. Both fields omitted when state is\n // clean (e.g. `pagehide` on an idle tab) — backward-compatible\n // with viewers that only know about the high-level `reason`.\n //\n // Message is only included when its `reason` matches the current\n // `disconnectReason` — `errorMessage` isn't reset on\n // `initSignalling`, so without this check a fresh session that\n // ends via a no-message path (e.g. route change → Destroy) would\n // surface the *previous* session's message.\n const granularReason = this.disconnectReason$();\n const errorMessage = this.errorMessage$();\n const granularMessage =\n errorMessage?.reason === granularReason\n ? errorMessage.message\n : undefined;\n const includeGranular =\n granularReason && granularReason !== DisconnectReason.None;\n\n this.emitLifecycle('stream.session_ended', {\n sessionId: id,\n reason,\n ...(includeGranular ? { disconnectReason: granularReason } : {}),\n ...(includeGranular && granularMessage\n ? { disconnectMessage: granularMessage }\n : {}),\n timestamp: new Date().toISOString(),\n });\n\n sub.unsubscribe();\n this.session = null;\n }\n\n /**\n * Emit a lifecycle event with a `duration` field — ms between the\n * previous lifecycle event and now (phase-local, NOT anchor-relative).\n * For `session_started` this equals the full page-load elapsed on the\n * first session, or 0 on Resume. Advances `lastMilestonePerf` so the\n * next event's duration is correctly rooted.\n */\n private emitLifecycle(\n event: string,\n extra: Record<string, unknown>,\n atPerf?: number,\n ) {\n if (!this.session) return;\n // `atPerf` lets callers pin the milestone to a specific `performance.now()`\n // value — useful for `session_started` where the wall-clock and perf-clock\n // anchors were already captured at the top of `startSession()`.\n const now = atPerf ?? performance.now();\n const duration = Math.round(now - this.session.lastMilestonePerf);\n this.track(event, { duration, ...extra });\n this.session.lastMilestonePerf = now;\n }\n\n /**\n * Emit the unified `stream.phase_ended` wire event for a closer —\n * phaseNo (derived from the catalog index), id, color, milestones,\n * params, overlays. No display text on the wire: the viewer's\n * vocabulary maps every id back to a human label, and boundary labels\n * are derived from neighbor phases.\n */\n private emitPhaseEnded(\n bucket: CatalogPhase,\n bucketIdx: number,\n extrasValue: unknown,\n ): void {\n if (!this.session) return;\n const now = performance.now();\n const phaseStartMs = Math.round(\n this.session.lastMilestonePerf - this.session.anchorPerf,\n );\n const phaseEndMs = Math.round(now - this.session.anchorPerf);\n const milestones = this.milestonesOfBucket(bucket);\n const params = toPhaseParams(extrasValue);\n const overlays = resolveOverlays(\n bucket.overlays,\n this.session.times,\n phaseStartMs,\n phaseEndMs,\n );\n this.emitLifecycle('stream.phase_ended', {\n sessionId: this.session.id,\n phaseNo: bucketIdx + 1,\n id: bucket.id,\n color: bucket.color,\n milestones,\n params,\n overlays,\n });\n }\n\n /**\n * Emit the region / signaling / webrtc phases for an ADOPTED connection.\n *\n * The prefetch script established the connection in PARALLEL with page load,\n * so the phases are positioned at their real (anchor-relative) spans — shifted\n * LEFT to overlap the HTML-loading / route-idle rows — rather than sequentially\n * after them. That's the whole point of the prefetch: the handshake already\n * happened while the page was loading. Each phase ships:\n * - `duration` — the real sub-step time the prefetch spent.\n * - `spanStartMs` — anchor-relative start, so the viewer left-shifts the bar.\n * - `adoptionAtMs` — where Angular took over (the next phase, Unreal\n * communication, resumes here on the sequential timeline).\n * - savings params: `prefetchConnectMs` (full handshake), `prefetchSavedMs`\n * (done before Angular was ready), `adoptionWaitMs` (real connect→adopted\n * wait), `adoptionOverheadMs` (prefetch-ready → adopted gap).\n */\n private emitAdoptedConnection(timings: Record<string, number> | null): void {\n const s = this.session;\n if (!s) return;\n\n const t = timings ?? {};\n const now = performance.now();\n // Everything in anchor-relative ms — the same scale the viewer renders on\n // (and the prefetch marks share the page `performance` clock).\n const toMs = (perf: number) => Math.round(perf - s.anchorPerf);\n const startMs = toMs(t['prefetch_start'] ?? s.startedAtPerf);\n const wsOpenMs = Math.max(\n startMs,\n toMs(t['ws_open'] ?? t['prefetch_start'] ?? s.startedAtPerf),\n );\n const readyMs = Math.max(\n wsOpenMs,\n toMs(t['ready'] ?? t['dc_open'] ?? t['ws_open'] ?? s.startedAtPerf),\n );\n const adoptionAtMs = toMs(now);\n const sessionStartMs = toMs(s.startedAtPerf);\n\n const sigDur = wsOpenMs - startMs;\n const webDur = readyMs - wsOpenMs;\n const connectMs = readyMs - startMs;\n\n // Savings, anchored at the moment Angular reached the connect call.\n const savings = {\n prefetched: true,\n prefetchConnectMs: connectMs,\n // How much of the handshake finished before Angular was ready (the win).\n prefetchSavedMs: Math.max(\n 0,\n Math.min(connectMs, sessionStartMs - startMs),\n ),\n // The real wait Angular experienced (connect call → adopted).\n adoptionWaitMs: Math.max(0, adoptionAtMs - sessionStartMs),\n // Gap between the prefetch being ready and Angular adopting it.\n adoptionOverheadMs: Math.max(0, adoptionAtMs - readyMs),\n };\n\n // Region (phaseNo 1) — served from the ping cache during prefetch (~0),\n // positioned at the prefetch start; ship the samples.\n const region = this.readRegionCache();\n this.emitAdoptedPhase(0, startMs, 0, adoptionAtMs, {\n region: region?.region_code ?? '',\n pingsMs: region?.result.length ? `${region.result.join(', ')} ms` : null,\n });\n // Signaling (phaseNo 2) — [prefetch_start → ws_open]; streamer identity +\n // savings; ws-connected marker sits at the phase's own end.\n this.emitAdoptedPhase(\n 1,\n startMs,\n sigDur,\n adoptionAtMs,\n {\n ...this.adoptedSignalingParams(),\n ...savings,\n prefetchSignalingMs: sigDur,\n },\n [{ id: 'signaling-ws-connected', time: wsOpenMs }],\n );\n // WebRTC negotiation (phaseNo 3) — [ws_open → ready].\n this.emitAdoptedPhase(2, wsOpenMs, webDur, adoptionAtMs, {\n iceCandidateCount: 0,\n prefetchWebrtcMs: webDur,\n });\n\n // Unreal communication chains from the adoption moment (real wall-clock).\n s.lastMilestonePerf = now;\n }\n\n /**\n * Emit one adopted phase positioned at its real `spanStartMs` (left-shifted\n * to overlap page load) with its real prefetch `duration`. `prefetched`,\n * `spanStartMs` and `adoptionAtMs` ride as top-level wire fields the viewer\n * uses to lay the bar out; the rest become display params.\n */\n private emitAdoptedPhase(\n bucketIdx: number,\n spanStartMs: number,\n durationMs: number,\n adoptionAtMs: number,\n extras: Record<string, unknown>,\n milestones: EmittedMilestone[] = [],\n ): void {\n const s = this.session;\n if (!s) return;\n const bucket = this.phaseCatalog[bucketIdx];\n this.track('stream.phase_ended', {\n sessionId: s.id,\n phaseNo: bucketIdx + 1,\n id: bucket.id,\n color: bucket.color,\n duration: durationMs,\n prefetched: true,\n spanStartMs,\n adoptionAtMs,\n milestones,\n params: toPhaseParams({ ...extras, prefetched: true }),\n overlays: [],\n });\n }\n\n /** Streamer identity params for the adopted signaling phase — mirrors the\n * `ssinfo-received` closer's shape (client / instanceName / …ssData). */\n private adoptedSignalingParams(): Record<string, unknown> {\n const aws = this.awsInstance$();\n const ssData = this.ssData$();\n return {\n client: aws?.wsUrl ?? null,\n instanceName: aws?.instanceName ?? null,\n ...(ssData ?? {}),\n };\n }\n\n /** Read the region-ping cache the prefetch reused (localStorage), so the\n * adopted region phase can still report the winning region + samples. */\n private readRegionCache(): { region_code: string; result: number[] } | null {\n try {\n const raw = localStorage.getItem(REGION_PING_CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as {\n region_code?: unknown;\n result?: unknown;\n };\n return {\n region_code:\n typeof parsed.region_code === 'string' ? parsed.region_code : '',\n result: Array.isArray(parsed.result)\n ? parsed.result.filter((n): n is number => typeof n === 'number')\n : [],\n };\n } catch {\n return null;\n }\n }\n\n private handleWindow(samples: AggregatedStat[]) {\n if (!this.session) return;\n const s = this.session;\n\n // Pull a metric off every sample, dropping anything that isn't a\n // real measurement. WebRTC reports `null` / `undefined` while the\n // metric is still warming up; some streamer libs emit `-1` as a\n // sentinel for \"not yet measurable\" (most notably for RTT). The\n // previous `?? 0` fallback masked both — the zero pad polluted\n // percentiles and the `-1` slipped through entirely.\n //\n // `nonNegative` is for metrics where a literal `0` is a legitimate\n // value (bitrate during stalls, jitter on a perfect link, QP at\n // lossless). `positive` is for metrics where `0` itself is\n // physically impossible (RTT, FPS).\n const nonNegative = (\n pick: (a: AggregatedStat['aggregatedStats']) => number | null | undefined,\n ): number[] =>\n samples\n .map((x) => pick(x.aggregatedStats))\n .filter(\n (v): v is number =>\n typeof v === 'number' && Number.isFinite(v) && v >= 0,\n );\n\n const positive = (\n pick: (a: AggregatedStat['aggregatedStats']) => number | null | undefined,\n ): number[] =>\n samples\n .map((x) => pick(x.aggregatedStats))\n .filter(\n (v): v is number =>\n typeof v === 'number' && Number.isFinite(v) && v > 0,\n );\n\n const bitrate = this.aggregate(nonNegative((a) => a.bitrate));\n const fps = this.aggregate(positive((a) => a.framesPerSecond));\n const qp = this.aggregate(nonNegative((a) => a.VideoEncoderQP));\n const jitter = this.aggregate(nonNegative((a) => a.jitter));\n const rtt = this.aggregate(positive((a) => a.currentRoundTripTime));\n const latest = samples[samples.length - 1]?.aggregatedStats;\n\n // Periodic sample event.\n this.track('stream.sample', {\n sessionId: s.id,\n seq: s.seq++,\n timestamp: new Date().toISOString(),\n sampleCount: samples.length,\n // Tab visibility state at emission time. Chrome does NOT throttle timers\n // for WebRTC-active tabs, so the handler runs on time even when hidden —\n // the point-in-time read is reliable in this specific context.\n visibilityState: document.visibilityState,\n bitrate,\n fps,\n qp,\n jitter,\n rtt,\n packetsLost: latest?.packetsLost,\n viewPort: {\n width: latest?.frameWidth,\n height: latest?.frameHeight,\n },\n });\n\n this.evaluateAnomalies(fps, qp);\n }\n\n private evaluateAnomalies(fps: WindowAggregate, qp: WindowAggregate) {\n if (!this.session) return;\n const s = this.session;\n\n // Quality (QP red) entry/exit.\n const qpBadNow = qp.p50 > QP_RED_THRESHOLD;\n if (qpBadNow !== s.qpBad) {\n s.qpBad = qpBadNow;\n this.track(\n qpBadNow ? 'stream.quality_degraded' : 'stream.quality_recovered',\n {\n sessionId: s.id,\n seq: s.seq,\n timestamp: new Date().toISOString(),\n qpP50: qp.p50,\n qpP95: qp.p95,\n },\n );\n }\n\n // FPS low vs. current target.\n const ref = s.maxFpsTarget > 0 ? s.maxFpsTarget : UNLIMITED_REFERENCE_FPS;\n const fpsLowNow = fps.p50 < ref * FPS_LOW_RATIO;\n if (fpsLowNow && !s.fpsLow) {\n this.track('stream.fps_low', {\n sessionId: s.id,\n seq: s.seq,\n timestamp: new Date().toISOString(),\n target: s.maxFpsTarget,\n referenceTarget: ref,\n fpsP50: fps.p50,\n fpsP95: fps.p95,\n });\n }\n s.fpsLow = fpsLowNow;\n }\n\n private updateMaxFpsTarget(maxFps: number) {\n if (this.session) this.session.maxFpsTarget = maxFps;\n }\n\n /**\n * Snapshot every milestone recorded in this session that belongs to\n * {@link phase}. Used to attach a phase's milestone array to the\n * lifecycle event that closes that phase.\n */\n /**\n * Collect wire-shape milestones that fired within a bucket. Walks the\n * catalog's own milestone list (minus the closer) and pulls each\n * entry's time from the in-session map via object identity.\n */\n private milestonesOfBucket(bucket: CatalogPhase): EmittedMilestone[] {\n if (!this.session) return [];\n const out: EmittedMilestone[] = [];\n const closerIdx = bucket.milestones.length - 1;\n for (let i = 0; i < closerIdx; i++) {\n const entry = bucket.milestones[i];\n const time = this.session.times.get(entry);\n if (time !== undefined) out.push({ id: entry.id, time });\n }\n return out;\n }\n\n /**\n * Capture browser navigation timings — useful to explain the\n * \"application bootstrap → session_started\" waterfall phase.\n * Values are ms from navigation start; null if the entry is unavailable\n * (old browsers, cross-origin iframes with limited perf access, etc.).\n */\n private collectBootstrapInfo(): Record<string, unknown> | null {\n try {\n const nav = performance.getEntriesByType('navigation')[0] as\n PerformanceNavigationTiming | undefined;\n if (!nav) return null;\n const split = this.collectResourceTotals(nav.loadEventEnd);\n return {\n type: nav.type, // 'navigate' | 'reload' | 'back_forward' | 'prerender'\n protocol: nav.nextHopProtocol || null, // 'h2' / 'h3' / 'http/1.1'\n firstByteMs: Math.round(nav.responseStart),\n domInteractiveMs: Math.round(nav.domInteractive),\n domContentLoadedMs: Math.round(nav.domContentLoadedEventEnd),\n loadEventMs: Math.round(nav.loadEventEnd),\n // Navigation-only size — the HTML document itself. Usually small;\n // the interesting number is `resources.transferSize` below.\n navigationTransferSize: nav.transferSize || null,\n navigationEncodedBodySize: nav.encodedBodySize || null,\n navigationDecodedBodySize: nav.decodedBodySize || null,\n // Resources are split into \"before window.load\" (page-weight) and\n // \"after window.load\" (typically lazy chunks for the route the\n // user navigated to before the streamer mounted). The viewer\n // attributes them to `HTML loading` and `Route idle` respectively.\n resources: split.resources,\n lazyResources: split.lazyResources,\n // Top-8 slowest individual resources (path + duration), so the viewer\n // can name the offending file / GraphQL endpoint.\n slowestResources: split.slowestResources,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Aggregate all resources the browser has loaded so far\n * (`performance.getEntriesByType('resource')`), grouped by `initiatorType`,\n * **split by `window.load`**:\n *\n * - `resources` — fetched before `loadEventEnd` (= part of the actual\n * page weight). What you'd traditionally call \"page load.\"\n * - `lazyResources` — fetched after `loadEventEnd` (= typically the\n * route's lazy-loaded chunks, JSON manifests etc. that download\n * when the user navigates to a sub-route the streamer lives on).\n *\n * When `loadEventEnd` is 0/unknown, everything goes into `resources`\n * and `lazyResources` is null — old behavior.\n *\n * `transferSize === 0 && decodedBodySize > 0` means the resource came from\n * the HTTP cache — counted separately so cached hits don't inflate\n * the \"bytes on the wire\" metric.\n */\n private collectResourceTotals(loadEventEnd: number): {\n resources: Record<string, unknown> | null;\n lazyResources: Record<string, unknown> | null;\n slowestResources: SlowResource[];\n } {\n try {\n const list = performance.getEntriesByType(\n 'resource',\n ) as PerformanceResourceTiming[];\n if (!list.length)\n return { resources: null, lazyResources: null, slowestResources: [] };\n\n interface Bucket {\n count: number;\n cachedCount: number;\n transferSize: number;\n encodedBodySize: number;\n decodedBodySize: number;\n // Timing (Resource Timing `duration` = responseEnd − startTime).\n // `durationMs` is the SUM across this type's resources; with `count`\n // it yields the average per request, and `maxDurationMs` the slowest.\n // For `fetch`/`xmlhttprequest` this is the GraphQL/data-call timing.\n durationMs: number;\n maxDurationMs: number;\n }\n const empty = (): Bucket => ({\n count: 0,\n cachedCount: 0,\n transferSize: 0,\n encodedBodySize: 0,\n decodedBodySize: 0,\n durationMs: 0,\n maxDurationMs: 0,\n });\n\n const splitEnabled = loadEventEnd > 0;\n\n const pageLoadTotals = empty();\n const pageLoadByType: Record<string, Bucket> = {};\n const lazyTotals = empty();\n const lazyByType: Record<string, Bucket> = {};\n const slow: SlowResource[] = []; // every timed resource; trimmed to top-N\n\n for (const r of list) {\n const type = r.initiatorType || 'other';\n const isLazy = splitEnabled && r.startTime > loadEventEnd;\n const totals = isLazy ? lazyTotals : pageLoadTotals;\n const byType = isLazy ? lazyByType : pageLoadByType;\n\n const b = (byType[type] ||= empty());\n const fromCache = r.transferSize === 0 && r.decodedBodySize > 0;\n const t = r.transferSize || 0;\n const enc = r.encodedBodySize || 0;\n const dec = r.decodedBodySize || 0;\n const dur = r.duration || 0; // responseEnd − startTime (ms)\n\n b.count++;\n if (fromCache) b.cachedCount++;\n b.transferSize += t;\n b.encodedBodySize += enc;\n b.decodedBodySize += dec;\n b.durationMs += dur;\n if (dur > b.maxDurationMs) b.maxDurationMs = dur;\n\n totals.count++;\n if (fromCache) totals.cachedCount++;\n totals.transferSize += t;\n totals.encodedBodySize += enc;\n totals.decodedBodySize += dec;\n totals.durationMs += dur;\n if (dur > totals.maxDurationMs) totals.maxDurationMs = dur;\n\n if (dur > 0) {\n slow.push({\n name: shortResourceName(r.name),\n type,\n durationMs: Math.round(dur),\n transferKb: Math.round((t / 1024) * 10) / 10,\n lazy: isLazy,\n });\n }\n }\n\n slow.sort((a, b) => b.durationMs - a.durationMs);\n\n return {\n resources:\n pageLoadTotals.count > 0\n ? { ...pageLoadTotals, byType: pageLoadByType }\n : null,\n lazyResources:\n lazyTotals.count > 0 ? { ...lazyTotals, byType: lazyByType } : null,\n // Top-8 slowest individual resources (path only, query stripped) so\n // the viewer can name the offending file / endpoint. GraphQL appears\n // here as its endpoint path (one entry per call) — Resource Timing\n // can't expose the operation name (it's in the POST body).\n slowestResources: slow.slice(0, 8),\n };\n } catch {\n return { resources: null, lazyResources: null, slowestResources: [] };\n }\n }\n\n private aggregate(values: number[]): WindowAggregate {\n if (values.length === 0) return { p50: 0, p95: 0, min: 0, max: 0 };\n const sorted = [...values].sort((a, b) => a - b);\n // Nearest-rank method: p-th percentile ≡ sorted[ceil(p/100 * n) - 1].\n // Using `floor` would make p95 collapse to `max` for n=20\n // (floor(0.95*20) = 19 = max index), hiding the max line behind p95\n // in charts. `ceil - 1` keeps them distinct: p. 95 = sorted[18], max = sorted[19].\n const pick = (p: number) => {\n const idx = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, Math.min(sorted.length - 1, idx))];\n };\n return {\n p50: pick(50),\n p95: pick(95),\n min: sorted[0],\n max: sorted[sorted.length - 1],\n };\n }\n\n private track(event: string, data: Record<string, unknown>) {\n // `userId` is attached to every event, so the server can bucket files\n // under `data/<userId>/<sessionId>.jsonl` without maintaining a\n // session→user index.\n this.store.dispatch(\n trackTelemetryData({\n event,\n data: { userId: this.userId, ...data },\n }),\n );\n }\n}\n\n// ──────────────────────────────────────────────────────────────────\n// Module-scope helpers — keep the class body focused on RxJS wiring.\n// ──────────────────────────────────────────────────────────────────\n\n/** Compact one side of an ICE candidate pair to `\"type (url)\"` or just\n * `type` (host candidates have no URL). */\nfunction fmtCandidate(c: { type: string; url: string } | undefined) {\n if (!c) {\n return null;\n }\n return c.url ? `${c.type} (${c.url})` : c.type;\n}\n\n/**\n * Flatten the closer's emitted extras object into display key/value\n * pairs. Null/undefined/empty are dropped; objects and arrays are\n * skipped — they should be pre-formatted by the closer's `map(...)`.\n */\nfunction toPhaseParams(value: unknown): PhaseParam[] {\n if (!value || typeof value !== 'object') return [];\n const out: PhaseParam[] = [];\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === null || v === undefined || v === '') continue;\n if (typeof v === 'object') continue;\n out.push({ key, value: String(v) });\n }\n return out;\n}\n\n/**\n * Resolve declarative overlay recipes to absolute ms spans. Endpoints\n * fall back to the phase's own start/end when unspecified; recipes\n * whose referenced entry never fired are quietly skipped.\n */\nfunction resolveOverlays(\n recipes: readonly OverlayRecipe[] | undefined,\n times: ReadonlyMap<CatalogEntry, number>,\n phaseStartMs: number,\n phaseEndMs: number,\n): PhaseOverlay[] {\n if (!recipes?.length) return [];\n const out: PhaseOverlay[] = [];\n for (const r of recipes) {\n const fromMs = r.from ? (times.get(r.from) ?? null) : phaseStartMs;\n const toMs = r.to ? (times.get(r.to) ?? null) : phaseEndMs;\n if (fromMs === null || toMs === null || toMs <= fromMs) continue;\n out.push({ fromMs, toMs, id: r.id });\n }\n return out;\n}\n","export const ReceivedMimeTypes = {\n ApplicationJson: 'application/json',\n} as const;\nexport type ReceivedMimeType =\n (typeof ReceivedMimeTypes)[keyof typeof ReceivedMimeTypes];\n","import { inject, Injectable } from '@angular/core';\nimport type { ReceivedFile } from './file-receiver.service';\nimport { FileReceiverService } from './file-receiver.service';\nimport { generateUuid, Logger, Truthy } from '@3dsource/utils';\nimport type { Observable } from 'rxjs';\nimport { defer, from, of, switchMap, take, timeout } from 'rxjs';\nimport { catchError, filter, map } from 'rxjs/operators';\nimport type { MetaBoxCommandList } from '@3dsource/types-unreal';\nimport type { ReceivedMimeType } from '../interfaces/ReceivedMimeTypes';\nimport { ReceivedMimeTypes } from '../interfaces/ReceivedMimeTypes';\n\ntype FileHandlers = Record<\n ReceivedMimeType,\n (data: ReceivedFile, correlationId: string) => Observable<unknown>\n>;\n\n@Injectable({ providedIn: 'root' })\nexport class FileHandlerService {\n private fileService = inject(FileReceiverService);\n private fileHandlers: FileHandlers = {\n [ReceivedMimeTypes.ApplicationJson]: this.handleJsonFile.bind(this),\n };\n\n private handleJsonFile(data: ReceivedFile, correlationId: string) {\n const { blob } = data;\n return from(blob.text()).pipe(\n map((text: string) => JSON.parse(text)),\n filter(({ commandCallback }) => {\n return commandCallback.correlationId === correlationId;\n }),\n );\n }\n\n observeFileResponse<\n K extends keyof MetaBoxCommandList,\n T extends MetaBoxCommandList[K] = MetaBoxCommandList[K],\n >(\n mimetype: ReceivedMimeType,\n data: T,\n sender: (data: T) => void,\n timeOut = 60000,\n ) {\n const correlationId = generateUuid();\n const out = { ...data, correlationId };\n\n return defer(() => {\n const observable = this.fileService.fileComplete$.pipe(\n switchMap((data) => {\n if (data.valid && this.fileHandlers[mimetype]) {\n return this.fileHandlers[mimetype](data, correlationId).pipe(\n filter(Truthy),\n );\n }\n return of(null);\n }),\n timeout(timeOut),\n catchError((e) => {\n Logger.error(e);\n return of(null);\n }),\n take(1),\n );\n setTimeout(() => sender(out), 0);\n return observable;\n });\n }\n}\n","import {\n filter,\n fromEvent,\n merge,\n Subject,\n takeUntil,\n throttleTime,\n} from 'rxjs';\nimport { Injectable } from '@angular/core';\nimport { distinctUntilChanged, tap } from 'rxjs/operators';\nimport { saveAnalyticsEvent, unrealFeature } from '../store';\nimport { Logger } from '@3dsource/utils';\nimport { SubService } from './sub.service';\n\n@Injectable({ providedIn: 'root' })\nexport class AnalyticsService extends SubService {\n #stopMouse$ = new Subject<void>();\n\n constructor() {\n super();\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(distinctUntilChanged(), takeUntil(this.destroy$))\n .subscribe((ready) => {\n this.#stopMouse$.next();\n if (ready) {\n this.monitorMouse();\n }\n });\n }\n\n private monitorMouse() {\n const stop$ = merge(this.#stopMouse$, this.destroy$);\n const element = document.getElementById('streamingVideo');\n\n if (!element) {\n return;\n }\n\n // Monitor mousewheel events\n const mousewheel$ = fromEvent<WheelEvent>(element, 'wheel').pipe(\n takeUntil(stop$),\n throttleTime(1000),\n );\n\n // Monitor mouse button states\n const mousedown$ = fromEvent<MouseEvent>(element, 'mousedown').pipe(\n takeUntil(stop$),\n );\n const touchStart$ = fromEvent<TouchEvent>(element, 'touchstart').pipe(\n takeUntil(stop$),\n );\n const touchMove$ = fromEvent<TouchEvent>(element, 'touchmove').pipe(\n takeUntil(stop$),\n throttleTime(200),\n );\n\n // Track mouse movement while the left or right button is pressed\n mousedown$\n .pipe(\n filter((event) => event.button === 0 || event.button === 2),\n tap((downEvent) => {\n this.sendEventToMixPanel('mouse_interaction', {\n viewX: downEvent.clientX / element.clientWidth,\n viewY: downEvent.clientY / element.clientHeight,\n action: downEvent.button === 0 ? 'spinning' : 'panning',\n });\n }),\n )\n .subscribe();\n\n // Track mouse movement while the left or right button is pressed\n touchStart$\n .pipe(\n tap((downEvent) => {\n const totalTouches = downEvent.touches.length;\n const touch = downEvent.touches[0];\n this.sendEventToMixPanel('touch_interaction', {\n viewX: touch.clientX / element.clientWidth,\n viewY: touch.clientY / element.clientHeight,\n action: totalTouches === 1 ? 'spinning' : 'panning',\n });\n }),\n )\n .subscribe();\n\n let initialTouchDistance = 0;\n // Subscribe to mousewheel events\n touchMove$.subscribe((event: TouchEvent) => {\n const totalTouches = event.touches.length;\n if (totalTouches < 2) {\n return;\n }\n\n // Calculate the current distance between two touches\n const touch1 = event.touches[0];\n const touch2 = event.touches[1];\n const currentDistance = Math.sqrt(\n Math.pow(touch2.clientX - touch1.clientX, 2) +\n Math.pow(touch2.clientY - touch1.clientY, 2),\n );\n\n // Determine if zooming in or out based on distance change\n const deltaDistance = currentDistance - initialTouchDistance;\n const isZoomingIn = deltaDistance > 0;\n\n // Only send event if there's a significant change (avoid noise)\n if (Math.abs(deltaDistance) > 10) {\n this.sendEventToMixPanel('touch_zoom_interaction', {\n delta: isZoomingIn ? 1 : -1,\n action: isZoomingIn ? 'zoomin' : 'zoomout',\n });\n\n // Update initial distance for next comparison\n initialTouchDistance = currentDistance;\n }\n });\n\n mousewheel$.subscribe((event: WheelEvent) => {\n this.sendEventToMixPanel('mouse_zoom_interaction', {\n delta: -(event.deltaY / Math.abs(event.deltaY)),\n action: event.deltaY < 0 ? 'zoomin' : 'zoomout',\n });\n });\n }\n\n private sendEventToMixPanel(\n name: string,\n params: Record<string, unknown> = {},\n ): void {\n Logger.log('Analytics Event:', name, params);\n this.store.dispatch(saveAnalyticsEvent({ event: { name, params } }));\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { filter, takeUntil, withLatestFrom } from 'rxjs/operators';\nimport { clampf, Logger } from '@3dsource/utils';\nimport { VideoService } from './video.service';\nimport { setMaxFps, unrealFeature } from '../store';\nimport { qpToQuality } from '../helpers';\nimport type { AggregatedStat } from '../interfaces';\nimport { merge, Subject } from 'rxjs';\nimport { UNREAL_CONFIG } from '../constants';\nimport { SubService } from './sub.service';\n\ntype Decision = 'decrease' | 'hold' | 'increase';\n\n/**\n * Adaptive FPS controller that monitors the incoming WebRTC video stream\n * quality and dynamically adjusts Unreal Engine's `t.MaxFPS` console variable.\n *\n * ## How it works\n *\n * The service subscribes to `VideoService.videoStats$` (emitted every 250 ms)\n * and collects samples of FPS, bitrate, and QP (Quantization Parameter).\n * Every {@link SAMPLE_WINDOW} ticks (~2 s) it averages the collected samples\n * and feeds them into a set of **fuzzy-logic membership functions** that\n * classify each metric into overlapping quality bands.\n *\n * ### Input signals\n *\n * **1. FPS ratio** = `actualFPS / currentTargetFPS` (0..1+)\n *\n * | Band | Range | Meaning |\n * |--------|---------------------|-----------------------------------------------|\n * | low | ratio < 0.7 → 1.0, linear ramp 0.7..0.9 → 0 | Stream cannot keep up with the target |\n * | okays | triangle 0.8..1.0, peak at 0.95 | Stream roughly matches the target |\n * | high | ratio 0.9..1.0 → ramp, >1.0 → 1.0 | Stream meets or exceeds the target |\n *\n * **2. Bitrate load** = `currentBitrate / MAX_BITRATE` (0..1+)\n *\n * `MAX_BITRATE` = 20 Mbit/s — the reference ceiling for the encoder.\n *\n * | Band | Range | Meaning |\n * |--------|-------------------------------------------------|-----------------------------------------------|\n * | high | load 0.5..0.8 → ramp, >0.8 → 1.0 | Encoder is using most of the available bandwidth |\n * | not high | load < 0.5 → 0.0 | Bandwidth headroom is available |\n *\n * **3. Quality** — mapped from QP via `mapQpToQuality()` (see {@link Quality}):\n *\n * | Quality | QP range | Meaning |\n * |----------|-----------|-------------------------------------------------|\n * | `lime` | QP <= 26 | Good — encoder has enough headroom |\n * | `orange` | QP 27..35 | Fair — encoder is under moderate pressure |\n * | `red` | QP > 35 | Poor — heavy compression, visible artifacts |\n *\n * ### Decision rules (evaluated in priority order, first match wins)\n *\n * | # | Condition | Decision |\n * |---|------------------------------------------------------------|--------------|\n * | 1 | FPS ratio is **low** (membership > 0.5) | **decrease** |\n * | 2 | FPS ratio is **ok** AND quality is `red` | **decrease** |\n * | 3 | FPS ratio is **ok** AND bitrate **high** AND quality is `orange` | **hold** |\n * | 4 | FPS ratio is **high** AND quality is `lime` AND bitrate **not high** | **increase** |\n * | — | Everything else | **hold** |\n *\n * ## Cooldown-based throttling\n *\n * The service continuously evaluates fuzzy rules in every sample window.\n * After each FPS step change it enforces a cooldown before the next\n * change can be applied. The cooldown duration depends on the\n * (previous decision → next decision) pair:\n *\n * | Previous | Next | Cooldown |\n * |-----------|-----------|-----------------------------------------------------|\n * | decrease | decrease | {@link COOLDOWN_DECREASE_AFTER_DECREASE_MS} (2 s) |\n * | decrease | increase | {@link COOLDOWN_INCREASE_AFTER_DECREASE_MS} (10 s) |\n * | increase | decrease | {@link COOLDOWN_AFTER_INCREASE_MS} (2 s) |\n * | increase | increase | {@link COOLDOWN_AFTER_INCREASE_MS} (2 s) |\n *\n * This means the system reacts quickly after an increase (2 s in any\n * direction) but is cautious about stepping back up after a decrease\n * (10 s), while still allowing consecutive decreases at 2 s intervals.\n *\n * ## FPS dispatch\n *\n * FPS changes are dispatched via the NgRx `setMaxFps` action, which triggers\n * the existing `UnrealEffects.setMaxFps$` effect that sends the\n * `t.MaxFPS <value>` console command to Unreal Engine.\n */\n@Injectable({ providedIn: 'root' })\nexport class FpsMonitorService extends SubService {\n private readonly videoService = inject(VideoService);\n private readonly unrealConfig = inject(UNREAL_CONFIG, { optional: true });\n\n /** Discrete FPS targets the controller can switch between (ascending order). Last 0 is an unlimited framerate indicator*/\n private readonly FPS_STEPS = [30, 40, 50, 0] as const;\n\n /**\n * Reference FPS used to compute the FPS ratio when `currentFpsTarget` is 0\n * (unlimited). Keeps adaptive logic operational at the unlimited step:\n * if the stream drops well below this value, fuzzy rules can still fire.\n */\n private readonly UNLIMITED_REFERENCE_FPS = 60;\n\n /** Reference ceiling for bitrate (bits/sec) used to normalize a bitrate load to 0..1. */\n private readonly MAX_BITRATE = 20_000_000;\n\n /**\n * Cooldown (ms) for any decision (increase or decrease) following an increase.\n * After an increase, the system should react faster.\n */\n private readonly COOLDOWN_AFTER_INCREASE_MS = 2_000;\n\n /**\n * Cooldown (ms) for a decrease following a previous decrease.\n */\n private readonly COOLDOWN_DECREASE_AFTER_DECREASE_MS = 2_000;\n\n /**\n * Cooldown (ms) for an increase following a previous decrease.\n * The stream needs more time to stabilize before stepping back up.\n */\n private readonly COOLDOWN_INCREASE_AFTER_DECREASE_MS = 10_000;\n\n /**\n * Number of videoStats$ ticks to accumulate before evaluating.\n * At 250 ms per tick, this gives a ~2 s sliding evaluation window,\n * long enough to smooth out single-frame jitter.\n */\n private readonly SAMPLE_WINDOW = 8;\n\n /** Emits when the session ends, cancelling the current stats' subscription. */\n private session$ = new Subject<void>();\n\n /** Current FPS target; starts at max (60 FPS) and adapts downward/upward. */\n private currentFpsTarget: number = this.FPS_STEPS[this.FPS_STEPS.length - 1];\n private samples: { fps: number; bitrate: number; qp: number }[] = [];\n private lastDecisionTime = Date.now();\n private lastUpgrade: Decision = 'hold';\n\n constructor() {\n super();\n this.init();\n }\n\n protected init() {\n if (this.unrealConfig?.playwright || !this.unrealConfig?.fpsMonitor) {\n return;\n }\n // Reset mutable state and re-subscribe when a new session starts\n this.store\n .select(unrealFeature.selectViewportReady)\n .pipe(filter(Boolean), takeUntil(this.destroy$))\n .subscribe(() => this.startSession());\n\n // Reset mutable state when session ends\n this.disconnect$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.resetSession());\n }\n\n private startSession() {\n // Tear down previous stats subscription if any\n this.session$.next();\n this.resetMutableState();\n\n this.videoService.videoStats$\n .pipe(\n withLatestFrom(this.store.select(unrealFeature.selectViewportReady)),\n filter(([, viewportReady]) => viewportReady),\n takeUntil(merge(this.session$, this.destroy$)),\n )\n .subscribe(([stats]) => this.processTick(stats));\n }\n\n private resetSession() {\n this.session$.next();\n this.resetMutableState();\n }\n\n private resetMutableState() {\n this.currentFpsTarget = this.FPS_STEPS[this.FPS_STEPS.length - 1];\n this.samples = [];\n this.lastDecisionTime = Date.now();\n this.lastUpgrade = 'hold';\n }\n\n /**\n * Called on every videoStats$ emission (~250 ms).\n * Accumulates samples and evaluates once per SAMPLE_WINDOW.\n */\n private processTick(stats: AggregatedStat) {\n const { framesPerSecond, bitrate, VideoEncoderQP } = stats.aggregatedStats;\n\n this.samples.push({\n fps: framesPerSecond ?? 0,\n bitrate: bitrate ?? 0,\n qp: VideoEncoderQP ?? 0,\n });\n\n // Wait until we have enough samples for a reliable average.\n if (this.samples.length < this.SAMPLE_WINDOW) {\n return;\n }\n\n const avg = this.averageSamples();\n this.samples = [];\n\n this.handleMonitoring(avg, this.currentFpsTarget);\n }\n\n private handleMonitoring(\n avg: { fps: number; bitrate: number; qp: number },\n currentTarget: number,\n ) {\n const decision = this.evaluateDecision(avg, currentTarget);\n this.upgradeFps(decision, avg.qp);\n }\n\n /**\n * Combines fuzzy membership values into a single discrete decision.\n * Rules are evaluated in priority order — first match wins.\n *\n * Inputs:\n * - `fpsRatio` = avgFPS / currentTargetFPS (e.g., 45/60 = 0.75)\n * - `bitrateLoad` = avgBitrate / 20 Mbit/s (e.g., 12M/20M = 0.6)\n * - `quality` = mapQpToQuality(avgQP) → 'lime' | 'orange' | 'red'\n */\n private evaluateDecision(\n avg: { fps: number; bitrate: number; qp: number },\n currentTarget: number,\n ): Decision {\n const referenceTarget =\n currentTarget > 0 ? currentTarget : this.UNLIMITED_REFERENCE_FPS;\n const fpsRatio = avg.fps / referenceTarget;\n const bitrateLoad = avg.bitrate / this.MAX_BITRATE;\n\n const fpsLow = this.membershipFpsLow(fpsRatio);\n const fpsOk = this.membershipFpsOk(fpsRatio);\n const fpsHigh = this.membershipFpsHigh(fpsRatio);\n\n const bitrateHigh = this.membershipBitrateHigh(bitrateLoad);\n\n // Quality is derived from QP: lime (QP <= 26), orange (QP 27..35), red (QP > 35).\n const quality = qpToQuality(avg.qp);\n\n // Rule 1: FPS clearly below target (ratio roughly < 0.8) → step down immediately.\n if (fpsLow > 0.5) {\n return 'decrease';\n }\n\n // Rule 2: FPS looks acceptable numerically, but encoder quality is 'red'\n // (QP > 35 — heavy compression artifacts). Reducing target FPS frees\n // encoder headroom and improves visual quality.\n if (fpsOk > 0.4 && quality === 'red') {\n return 'decrease';\n }\n\n // Rule 3: FPS is ok, but the bitrate is above ~50-80% of 20 Mbit/s ceiling\n // and quality is 'orange' (QP 27..35). Near capacity — don't push higher.\n if (fpsOk > 0.4 && bitrateHigh > 0.5 && quality === 'orange') {\n return 'hold';\n }\n\n // Rule 4: FPS meets/exceeds the target (ratio >= ~0.95), quality is 'lime'\n // (QP <= 26), and bitrate is below 50% of ceiling — safe to step up.\n // Note: the last FPS_STEPS value (0) means \"no limit\", so compare by\n // position in FPS_STEPS rather than numerically.\n const currentIndex = this.FPS_STEPS.indexOf(\n this.currentFpsTarget as (typeof this.FPS_STEPS)[number],\n );\n if (\n fpsHigh > 0.5 &&\n quality === 'lime' &&\n bitrateHigh < 0.5 &&\n currentIndex !== -1 &&\n currentIndex < this.FPS_STEPS.length - 1\n ) {\n return 'increase';\n }\n\n return 'hold';\n }\n\n // ---------------------------------------------------------------------------\n // Fuzzy membership functions\n //\n // Each function maps a normalised input (0..1+) to a membership degree (0..1).\n // Overlapping trapezoid/triangle shapes let multiple categories be partially\n // active at the same time, which makes the rules less brittle than hard thresholds.\n // ---------------------------------------------------------------------------\n\n /**\n * FPS ratio membership \"low\".\n * Input: a ratio = actualFPS / targetFPS (e.g., 42/60 = 0.70).\n *\n * ratio < 0.7 → 1.0 (clearly failing, e.g., 40/60)\n * ratio 0.7..0.9 → linear ramp down (e.g., 0.8 → 0.5)\n * a ratio > 0.9 → 0.0 (keeping up)\n */\n private membershipFpsLow(ratio: number): number {\n if (ratio < 0.7) return 1.0;\n if (ratio > 0.9) return 0.0;\n return (0.9 - ratio) / 0.2;\n }\n\n /**\n * FPS ratio membership \"ok\" — triangle shape.\n * Input: ratio = actualFPS / targetFPS.\n *\n * ratio < 0.8 → 0.0\n * ratio 0.8..0.95 → ramp up, peak at 0.95 (e.g., 57/60)\n * ratio 0.95..1.0 → ramp down\n * a ratio > 1.0 → 0.0\n */\n private membershipFpsOk(ratio: number): number {\n if (ratio < 0.8) return 0.0;\n if (ratio < 0.95) return (ratio - 0.8) / 0.15;\n if (ratio <= 1.0) return (1.0 - ratio) / 0.05;\n return 0.0;\n }\n\n /**\n * FPS ratio membership \"high\".\n * Input: ratio = actualFPS / targetFPS.\n *\n * ratio < 0.9 → 0.0\n * ratio 0.9..1.0 → linear ramp up (e.g., 0.95 → 0.5)\n * a ratio >= 1.0 → 1.0 (meeting or exceeding target, e.g., 60/60)\n */\n private membershipFpsHigh(ratio: number): number {\n if (ratio < 0.9) return 0.0;\n if (ratio > 1.0) return 1.0;\n return (ratio - 0.9) / 0.1;\n }\n\n /**\n * Bitrate load membership \"high\".\n * Input: a load = currentBitrate / MAX_BITRATE (20 Mbit/s).\n *\n * load < 0.5 → 0.0 (below 10 Mbit/s — plenty of headroom)\n * load 0.5..0.8 → linear ramp (e.g., 13M/20M = 0.65 → 0.5)\n * load > 0.8 → 1.0 (above 16 Mbit/s — near capacity)\n */\n private membershipBitrateHigh(load: number): number {\n if (load < 0.5) return 0.0;\n if (load > 0.8) return 1.0;\n return (load - 0.5) / 0.3;\n }\n\n // ---------------------------------------------------------------------------\n // Step actions\n // ---------------------------------------------------------------------------\n\n private upgradeFps(decision: Decision, qp: number) {\n if (decision === 'hold') return;\n\n const now = Date.now();\n\n // Throttle: cooldown depends on (previous decision → current decision) pair.\n const isStepUp = decision === 'increase';\n const cooldown =\n this.lastUpgrade === 'decrease'\n ? isStepUp\n ? this.COOLDOWN_INCREASE_AFTER_DECREASE_MS\n : this.COOLDOWN_DECREASE_AFTER_DECREASE_MS\n : this.COOLDOWN_AFTER_INCREASE_MS;\n\n if (now - this.lastDecisionTime < cooldown) {\n return;\n }\n\n this.lastUpgrade = decision;\n\n const quality = qpToQuality(qp);\n const newTarget = this.getNextFpsTarget(this.currentFpsTarget, decision);\n\n Logger.info(\n `[FpsMonitor] Decision: ${decision} → FPS: ${newTarget}, Quality: ${quality}`,\n );\n\n if (newTarget !== this.currentFpsTarget) {\n this.currentFpsTarget = newTarget;\n this.store.dispatch(setMaxFps({ maxFps: newTarget }));\n }\n\n this.lastDecisionTime = now;\n this.samples = [];\n }\n\n /**\n * Get the next FPS target based on the current target and decision.\n * Clamps to the valid FPS_STEPS range.\n */\n private getNextFpsTarget(currentTarget: number, decision: Decision): number {\n const currentIndex = this.FPS_STEPS.indexOf(\n currentTarget as (typeof this.FPS_STEPS)[number],\n );\n\n // If current target is not in FPS_STEPS, find closest one\n const validIndex =\n currentIndex === -1\n ? this.findClosestFpsIndex(currentTarget)\n : currentIndex;\n\n const delta = decision === 'increase' ? 1 : -1;\n const newIndex = clampf(0, this.FPS_STEPS.length - 1, validIndex + delta);\n\n return this.FPS_STEPS[newIndex];\n }\n\n /**\n * Find the closest FPS step index for a given target value.\n */\n private findClosestFpsIndex(target: number): number {\n let closestIndex = 0;\n let closestDiff = Math.abs(this.FPS_STEPS[0] - target);\n\n for (let i = 1; i < this.FPS_STEPS.length; i++) {\n const diff = Math.abs(this.FPS_STEPS[i] - target);\n if (diff < closestDiff) {\n closestDiff = diff;\n closestIndex = i;\n }\n }\n\n return closestIndex;\n }\n\n /** Average all collected samples for the current evaluation window. */\n private averageSamples(): { fps: number; bitrate: number; qp: number } {\n const len = this.samples.length;\n if (len === 0) return { fps: 0, bitrate: 0, qp: 0 };\n\n let fps = 0;\n let bitrate = 0;\n let qp = 0;\n\n for (const s of this.samples) {\n fps += s.fps;\n bitrate += s.bitrate;\n qp += s.qp;\n }\n\n return { fps: fps / len, bitrate: bitrate / len, qp: qp / len };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n} from '@angular/core';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\nimport { AFKService } from '../../services';\nimport { Store } from '@ngrx/store';\nimport { unrealFeature } from '../../store';\n\n@Component({\n selector: 'app-afk-timeout-modal',\n templateUrl: './afk-timeout-modal.component.html',\n styleUrl: './afk-timeout-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class AfkTimeoutModalComponent {\n readonly #store = inject(Store);\n readonly #afkService = inject(AFKService);\n\n readonly isAfkTimerVisible = this.#store.selectSignal(\n unrealFeature.selectIsAfkTimerVisible,\n );\n readonly showAfkTimeoutPopup = this.#store.selectSignal(\n unrealFeature.selectShowAfkTimeoutPopup,\n );\n readonly afkCountdown = this.#store.selectSignal(\n unrealFeature.selectAfkCountdown,\n );\n readonly isShowAfkPopup = computed(\n () => this.isAfkTimerVisible() && this.showAfkTimeoutPopup(),\n );\n\n resetAfk() {\n this.#afkService.reset();\n }\n}\n","@if (isShowAfkPopup()) {\n <div\n (click)=\"resetAfk()\"\n (keydown.enter)=\"resetAfk()\"\n class=\"clickableState\"\n id=\"videoPlayOverlay\"\n role=\"button\"\n tabindex=\"0\"\n >\n <div class=\"resume-box\">\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"afkCountdown()\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <src-button\n [isFullWidth]=\"true\"\n [data-testid]=\"'continue-session'\"\n weight=\"primary\"\n size=\"lg\"\n >\n Continue\n </src-button>\n </div>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport {\n selectFreezeFrameCombinedDataUrl,\n selectFreezeFrameProgressMessageFromVideo,\n} from '../../store';\n\n@Component({\n selector: 'app-freeze-frame',\n templateUrl: './freeze-frame.component.html',\n styleUrl: './freeze-frame.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FreezeFrameComponent {\n readonly #store = inject(Store);\n\n readonly freezeFrameProgressMessageFromVideo = this.#store.selectSignal(\n selectFreezeFrameProgressMessageFromVideo,\n );\n readonly combinedFreeze = this.#store.selectSignal(\n selectFreezeFrameCombinedDataUrl,\n );\n}\n","@let image = combinedFreeze();\n@let progress = freezeFrameProgressMessageFromVideo();\n\n<div class=\"freeze-images\">\n @if (image) {\n <img [src]=\"image\" class=\"videoStillImage\" alt=\"freezeFrameImage\" />\n }\n\n @if (progress) {\n <div class=\"progress-status\">\n {{ progress }}\n </div>\n }\n</div>\n","import type { PipeTransform } from '@angular/core';\nimport { inject, Pipe, SecurityContext } from '@angular/core';\nimport type {\n SafeHtml,\n SafeResourceUrl,\n SafeScript,\n SafeStyle,\n SafeUrl,\n} from '@angular/platform-browser';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Pipe({\n name: 'safe',\n})\nexport class SafePipe implements PipeTransform {\n private sanitizer = inject(DomSanitizer);\n\n transform(\n value: string,\n type: string,\n ): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {\n if (!value) {\n return value;\n }\n\n const context = (() => {\n switch (type) {\n case 'html':\n return SecurityContext.HTML;\n case 'style':\n return SecurityContext.STYLE;\n case 'script':\n return SecurityContext.SCRIPT;\n case 'url':\n return SecurityContext.URL;\n case 'resourceUrl':\n return SecurityContext.RESOURCE_URL;\n default:\n throw new Error(`Invalid safe type specified: ${type}`);\n }\n })();\n\n // Preserve the published return type while returning Angular-sanitized\n // content instead of disabling framework security checks.\n return (this.sanitizer.sanitize(context, value) ?? '') as SafeHtml;\n }\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { DialogRef } from '@angular/cdk/dialog';\nimport { SafePipe } from '../../../../pipes';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\n\n@Component({\n selector: 'app-low-bandwidth-modal',\n templateUrl: './low-bandwidth-modal.component.html',\n styleUrl: './low-bandwidth-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SafePipe, SourceButtonComponent],\n})\nexport class LowBandwidthModalComponent {\n #dialogRef = inject(DialogRef);\n\n close(value?: boolean) {\n this.#dialogRef.close(value || false);\n }\n}\n","<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\n <header class=\"src-modal__header\">\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n Unstable Connection\n </h6>\n </header>\n <section class=\"src-modal__body\">\n <div\n [innerHtml]=\"\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\n | safe: 'html'\n \"\n class=\"src-modal__scroll-box\"\n ></div>\n </section>\n <footer class=\"src-modal__footer\">\n <div class=\"src-modal__buttons\">\n <src-button\n (onClick)=\"close(true)\"\n [data-testid]=\"'switch-to-interactive-mode'\"\n >\n Switch\n </src-button>\n\n <src-button\n (onClick)=\"close()\"\n [data-testid]=\"'close-lbm-modal'\"\n weight=\"primary\"\n >\n Ok\n </src-button>\n </div>\n </footer>\n</div>\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport {\n selectIsLoaderScreenVisible,\n setLoadingImageSrc,\n unrealFeature,\n} from '../../store';\nimport { Store } from '@ngrx/store';\nimport { NgOptimizedImage } from '@angular/common';\n\n@Component({\n selector: 'app-image-loading-src',\n templateUrl: './image-loading-src.component.html',\n styleUrl: './image-loading-src.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgOptimizedImage],\n})\nexport class ImageLoadingSrcComponent {\n #store = inject(Store);\n\n readonly isLoaderScreenVisible = this.#store.selectSignal(\n selectIsLoaderScreenVisible,\n );\n readonly imageLoadingSrc = this.#store.selectSignal(\n unrealFeature.selectImageLoadingSrc,\n );\n\n loadingImageError() {\n this.#store.dispatch(setLoadingImageSrc({ src: '' }));\n }\n}\n","@let image = imageLoadingSrc();\n@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (image) {\n <img\n (error)=\"loadingImageError()\"\n [ngSrc]=\"image\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n </div>\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n effect,\n ElementRef,\n HostListener,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n HEXtoRGB,\n HSVtoRGB,\n inverseLerp,\n RGBtoHEX,\n RGBtoHSV,\n} from '@3dsource/utils';\n\n@Component({\n selector: 'app-stat-graph',\n templateUrl: './stat-graph.component.html',\n styleUrl: './stat-graph.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class StatGraphComponent {\n readonly label = input.required<string>();\n readonly stat = input<{ value: number }>();\n readonly color = input('#417bc9');\n readonly tickStep = input(3);\n\n private el = inject(ElementRef);\n readonly graph = viewChild<ElementRef<HTMLCanvasElement>>('graph');\n\n private data: (number | null)[] = [];\n readonly max = signal(0);\n readonly min = signal(0);\n readonly current = signal(0);\n\n private canvas!: HTMLCanvasElement;\n private ctx!: CanvasRenderingContext2D;\n\n constructor() {\n effect(() => {\n const stat = this.stat();\n untracked(() => this.pushData(stat?.value ?? null));\n });\n afterNextRender({\n read: () => {\n const graph = this.graph();\n if (graph) {\n this.canvas = graph.nativeElement;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.ctx = this.canvas.getContext('2d')!;\n }\n },\n });\n }\n\n @HostListener('window:resize')\n resize() {\n this.draw();\n }\n\n private draw() {\n if (!this.canvas) {\n return;\n }\n\n const all = this.data.filter((r) => r !== null && !isNaN(r)) as number[];\n this.max.set(Math.max(...all));\n this.min.set(Math.min(...all));\n const scaleY = this.canvas.height / (this.max() || 1);\n this.current.set(all[all.length - 1] || 0);\n this.ctx.save();\n const bounds = this.el.nativeElement.getBoundingClientRect();\n this.canvas.width = bounds.width;\n this.canvas.height = bounds.height - 30; // -p height\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n [...this.data].reverse().forEach((val, index) => {\n const h = (val || 0) * scaleY;\n\n this.ctx.fillStyle = this.getColor(this.color(), h as number);\n this.ctx.fillRect(\n index * this.tickStep(),\n this.canvas.height - h,\n this.tickStep(),\n h,\n );\n });\n this.ctx.restore();\n }\n\n private getColor(fillStyle: string, value = 0) {\n const { r, g, b } = HEXtoRGB(fillStyle);\n const [h, s] = RGBtoHSV(r, g, b);\n const v = inverseLerp(0, this.canvas.height, value);\n {\n const [r, g, b] = HSVtoRGB(h, s, v);\n return '#' + RGBtoHEX(r, g, b);\n }\n }\n\n private pushData(stat: number | null) {\n this.data.push(stat);\n if (!this.canvas) {\n return;\n }\n if (this.data.length > this.canvas.width / this.tickStep()) {\n this.data.shift();\n }\n this.draw();\n }\n}\n","<div class=\"content\">\n <p>{{ label() }}: {{ current() }} | Min:{{ min() }} | Max:{{ max() }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n} from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { unrealFeature } from '../../store';\nimport { SourceLoadingComponent } from '@3dsource/source-ui-native';\nimport { LoadingProgressService } from '../../services';\n\n@Component({\n selector: 'app-unreal-status',\n templateUrl: './unreal-status.component.html',\n styleUrl: './unreal-status.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceLoadingComponent],\n})\nexport class UnrealStatusComponent {\n readonly #store = inject(Store);\n readonly #loadingProgress = inject(LoadingProgressService);\n\n readonly awsInstance = this.#store.selectSignal(\n unrealFeature.selectAwsInstance,\n );\n readonly smoothPercents = this.#loadingProgress.smoothPercents;\n readonly showLoader = this.#loadingProgress.loaderVisible;\n readonly showLoadingProgress = this.#store.selectSignal(\n unrealFeature.selectShowLoadingProgress,\n );\n readonly isShowLoadingPercentsPopup = computed(\n () => this.showLoader() && this.showLoadingProgress(),\n );\n}\n","@if (isShowLoadingPercentsPopup()) {\n @let _awsInstance = awsInstance();\n <div class=\"status-box\">\n @if (_awsInstance?.message) {\n <p>{{ _awsInstance?.message }}</p>\n } @else {\n <div class=\"status-box__message\">\n <src-loading\n [size]=\"30\"\n [backgroundStrokeColor]=\"'#E5E7EB'\"\n [progressStrokeColor]=\"'#1F2937'\"\n />\n {{ smoothPercents() }}%\n </div>\n }\n </div>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n type Signal,\n signal,\n} from '@angular/core';\nimport type { InboundVideoStats } from '../../interfaces';\nimport { selectSignalingParameters, unrealFeature } from '../../store';\nimport { StatGraphComponent } from '../stat-graph/stat-graph.component';\nimport { JsonPipe } from '@angular/common';\nimport { Store } from '@ngrx/store';\nimport { DevModeService, VideoService } from '../../services';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { SafePipe } from '../../pipes';\n\ninterface GraphListItem {\n key: string;\n color: string;\n stat: Signal<{ value: number }>;\n}\n\n@Component({\n selector: 'app-video-stats',\n templateUrl: './video-stats.component.html',\n styleUrl: './video-stats.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [StatGraphComponent, JsonPipe, SafePipe],\n})\nexport class VideoStatsComponent {\n readonly collapsed = signal(false);\n private readonly store = inject(Store);\n private readonly videoService = inject(VideoService);\n private readonly isDevMode = inject(DevModeService).isDevMode;\n\n private readonly stats = toSignal(this.videoService.videoStats$);\n\n readonly viewportReady = this.store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n readonly ssData = this.store.selectSignal(selectSignalingParameters);\n\n readonly fpsTick = computed(() => ({\n value: this.stats()?.aggregatedStats.framesPerSecond || 0,\n }));\n readonly bitrateTick = computed(() => ({\n value: this.stats()?.aggregatedStats.bitrate ?? 0,\n }));\n readonly videoQP = computed(() => ({\n value: this.stats()?.aggregatedStats.VideoEncoderQP ?? 0,\n }));\n\n readonly videoStatus = computed(() => {\n const event = this.stats();\n if (!this.isDevMode || !event) {\n return undefined;\n }\n const data = {\n ...event.aggregatedStats,\n quality: event.quality,\n } as InboundVideoStats;\n return this.fields\n .map((key) => ({ key, value: data[key as keyof InboundVideoStats] }))\n .filter((r) => !this.elementsToShow().includes(r.key));\n });\n\n readonly fields = [\n 'kalmanBitrate',\n 'bitrateDrop',\n 'runTime',\n 'pixelRatio',\n 'frameHeight',\n 'frameWidth',\n ':-------------',\n 'jitter',\n 'MBytesReceived',\n 'framesDecoded',\n 'framesDropped',\n 'framesReceived',\n 'keyFramesDecoded',\n 'currentRoundTripTime',\n 'packetsLost',\n ':-------------',\n 'quality',\n 'videoCodec',\n 'kind',\n 'type',\n 'codecs',\n 'selectedPair',\n ];\n\n private readonly elementsToShow = signal<string[]>([]);\n private readonly idKey = 'com.source3d.unreal.stat';\n\n private readonly graphListItems: GraphListItem[] = this.fields.map((key) => ({\n key,\n color:\n '#' +\n Math.floor(Math.random() * 16777216)\n .toString(16)\n .padStart(6, '0'),\n stat: computed(() => ({\n value: this.stats()?.aggregatedStats[\n key as keyof InboundVideoStats\n ] as number,\n })),\n }));\n\n readonly graphList = computed(() =>\n this.graphListItems.filter((r) => this.elementsToShow().includes(r.key)),\n );\n\n constructor() {\n this.restoreFromStorage();\n }\n\n toggle() {\n this.collapsed.update((collapsed) => !collapsed);\n this.writeFields();\n }\n\n toggleGraph($event: Event, el: string, value?: unknown) {\n $event.stopPropagation();\n if (\n (value && typeof value !== 'number') ||\n (typeof value === 'number' && isNaN(value))\n ) {\n return;\n }\n this.elementsToShow.update((current) =>\n current.includes(el)\n ? current.filter((item) => item !== el)\n : [...current, el],\n );\n this.writeFields();\n }\n\n private restoreFromStorage() {\n try {\n const { elements, collapsed } =\n JSON.parse(localStorage.getItem(this.idKey) as string) || {};\n this.elementsToShow.set(elements || []);\n this.collapsed.set(collapsed ?? false);\n } catch {\n this.elementsToShow.set([]);\n }\n }\n\n private writeFields() {\n localStorage.setItem(\n this.idKey,\n JSON.stringify({\n collapsed: this.collapsed(),\n elements: this.elementsToShow(),\n }),\n );\n }\n}\n","@if (videoStatus() && viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n [class.min]=\"collapsed()\"\n id=\"aggregatedStats\"\n role=\"button\"\n tabindex=\"0\"\n >\n <div class=\"forNerds\">\n <div\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n class=\"static\"\n role=\"group\"\n tabindex=\"0\"\n >\n <li>\n <app-stat-graph\n [stat]=\"fpsTick()!\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"videoQP()!\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [stat]=\"bitrateTick()!\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList(); track graph.key) {\n <li\n (click)=\"toggleGraph($event, graph.key, 0)\"\n (keydown.enter)=\"toggleGraph($event, graph.key, 0)\"\n class=\"graph\"\n role=\"button\"\n tabindex=\"0\"\n >\n <app-stat-graph\n [label]=\"graph.key\"\n [stat]=\"graph.stat()\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div\n (click)=\"toggleGraph($event, el.key, el.value)\"\n (keydown.enter)=\"toggleGraph($event, el.key, el.value)\"\n class=\"stat\"\n role=\"button\"\n tabindex=\"0\"\n >\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed()) {\n <div [innerHTML]=\"ssData() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport {\n selectIsExistMatchUrls,\n selectIsLoaderScreenVisible,\n selectShowReconnectPopup,\n selectStreamConfig,\n startStream,\n unrealFeature,\n} from '../../store';\nimport { Store } from '@ngrx/store';\nimport { SourceButtonComponent } from '@3dsource/source-ui-native';\nimport { DisconnectReason } from '../../interfaces';\n\n@Component({\n selector: 'app-resume-stream-button',\n templateUrl: './resume-stream-button.component.html',\n styleUrl: './resume-stream-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SourceButtonComponent],\n})\nexport class ResumeStreamButtonComponent {\n readonly #store = inject(Store);\n\n readonly streamConfig = this.#store.selectSignal(selectStreamConfig);\n readonly isSecondStart = signal(\n this.streamConfig()?.autoStart && location.protocol === 'https:',\n );\n readonly isLoaderScreenVisible = this.#store.selectSignal(\n selectIsLoaderScreenVisible,\n );\n readonly showReconnectPopup = this.#store.selectSignal(\n selectShowReconnectPopup,\n );\n readonly isExistMatchUrls = this.#store.selectSignal(selectIsExistMatchUrls);\n readonly showResumeStreamPopup = this.#store.selectSignal(\n unrealFeature.selectShowResumeStreamPopup,\n );\n readonly isShowResumeButton = computed(\n () =>\n this.isLoaderScreenVisible() &&\n this.showReconnectPopup() &&\n this.isExistMatchUrls() &&\n this.showResumeStreamPopup(),\n );\n readonly disconnectReason = this.#store.selectSignal(\n unrealFeature.selectDisconnectReason,\n );\n readonly isAfkDisconnect = computed(() => {\n const disconnectReason = this.disconnectReason();\n return (\n disconnectReason === DisconnectReason.Afk ||\n disconnectReason === DisconnectReason.None\n );\n });\n\n private readonly cirrusConnected = this.#store.selectSignal(\n unrealFeature.selectCirrusConnected,\n );\n\n constructor() {\n let wasConnected = this.cirrusConnected();\n effect(() => {\n const connected = this.cirrusConnected();\n if (!connected && wasConnected) {\n this.disconnect();\n }\n wasConnected = connected;\n });\n }\n\n connect() {\n this.#store.dispatch(startStream({ config: { autoStart: true } }));\n }\n\n disconnect() {\n this.isSecondStart.set(true);\n }\n}\n","@if (isShowResumeButton()) {\n <div class=\"resume-box\">\n @if (isSecondStart()) {\n <div class=\"resume-box__text\">\n Your stream {{ isAfkDisconnect() ? 'has been' : 'is' }} paused due to\n inactivity\n </div>\n }\n\n <src-button\n (onClick)=\"connect()\"\n [isFullWidth]=\"true\"\n [data-testid]=\"'connect-button'\"\n size=\"lg\"\n weight=\"primary\"\n class=\"connect-button\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </src-button>\n </div>\n}\n","import type { ElementRef } from '@angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { NgOptimizedImage } from '@angular/common';\nimport { resetIntroSrc, unrealFeature } from '../../store';\n\n@Component({\n selector: 'app-intro-src',\n templateUrl: './intro-src.component.html',\n styleUrl: './intro-src.component.scss',\n imports: [NgOptimizedImage],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IntroSrcComponent {\n #store = inject(Store);\n\n private readonly videoElement =\n viewChild<ElementRef<HTMLDivElement>>('videoPlayerCover');\n protected imageIntroSrc = this.#store.selectSignal(\n unrealFeature.selectImageIntroSrc,\n );\n protected videoIntroSrc = this.#store.selectSignal(\n unrealFeature.selectVideoIntroSrc,\n );\n private viewportReady = this.#store.selectSignal(\n unrealFeature.selectViewportReady,\n );\n\n constructor() {\n effect(() => {\n const viewportReady = this.viewportReady();\n const videoIntroSrc = this.videoIntroSrc();\n const imageIntroSrc = this.imageIntroSrc();\n untracked(() => {\n if (viewportReady && (videoIntroSrc || imageIntroSrc)) {\n this.#store.dispatch(resetIntroSrc());\n }\n });\n });\n effect(() => {\n const videoElement = this.videoElement();\n const videoIntroSrc = this.videoIntroSrc();\n untracked(() => {\n if (videoElement && videoIntroSrc) {\n this.createVideo(videoIntroSrc, videoElement.nativeElement);\n }\n });\n });\n }\n\n loadingImageError() {\n this.#store.dispatch(resetIntroSrc());\n }\n\n private createVideo(src: string, videoContainer: HTMLDivElement) {\n if (typeof src !== 'string') {\n return;\n }\n const matchAbsolutePath = /.*\\.(mp4|WebM)(\\?.*)?$/i.test(src);\n videoContainer.innerHTML = ''; // This will remove all existing content within the layout\n const videoElement = document.createElement('video');\n videoElement.autoplay = true;\n videoElement.muted = true;\n videoElement.loop = true;\n if (!matchAbsolutePath) {\n videoElement.poster = `${src}/cover.webp`;\n }\n\n videoElement.style.position = 'absolute';\n videoElement.style.width = '100%';\n videoElement.style.height = '100%';\n videoElement.style.objectFit = 'cover';\n\n const sourceElement = document.createElement('source');\n if (matchAbsolutePath) {\n sourceElement.src = src;\n } else {\n sourceElement.src = `${src}/video.mp4`;\n }\n\n sourceElement.type = 'video/mp4';\n videoElement.appendChild(sourceElement);\n\n videoElement.addEventListener('error', () =>\n this.#store.dispatch(resetIntroSrc()),\n );\n sourceElement.addEventListener('error', () =>\n this.#store.dispatch(resetIntroSrc()),\n );\n\n videoContainer.appendChild(videoElement);\n }\n}\n","@let image = imageIntroSrc();\n@if (image) {\n <div class=\"backImage\">\n <img (error)=\"loadingImageError()\" [ngSrc]=\"image\" fill alt=\"imageSrc\" />\n </div>\n} @else if (videoIntroSrc()) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n","import type { ElementRef } from '@angular/core';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n HostListener,\n inject,\n input,\n output,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';\nimport {\n combineLatestWith,\n debounceTime,\n fromEvent,\n merge,\n of,\n switchMap,\n take,\n timer,\n} from 'rxjs';\nimport {\n DevModeService,\n UnrealCommunicatorService,\n VideoService,\n WebRtcPlayerService,\n} from '../../services';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport type { Size } from '@3dsource/utils';\nimport { fpIsASameAsB, Truthy } from '@3dsource/utils';\nimport { Store } from '@ngrx/store';\nimport {\n changeStreamResolutionAction,\n destroyUnrealScene,\n forceResizeViewport,\n initSignalling,\n selectIsExistMatchUrls,\n selectIsFreezeFrameLoading,\n unrealFeature,\n videoAdaptedToContainer,\n videoStreamInitialized,\n} from '../../store';\nimport {\n AUTO_HIGH_RESOLUTION_IDLE_MS,\n DEBOUNCE_TO_MANY_RESIZE_CALLS,\n FULL_HD_HEIGHT,\n FULL_HD_WIDTH,\n MIN_CONTAINER_SIZE,\n SAME_SIZE_THRESHOLD,\n UNREAL_CONFIG,\n} from '../../constants';\nimport {\n getResizeStudioValues,\n getResizeValuesUniversal,\n makeEven,\n} from '../../helpers';\nimport { DisconnectReason } from '../../interfaces';\nimport { AfkTimeoutModalComponent } from '../afk-timeout-modal/afk-timeout-modal.component';\nimport { UnrealStatusComponent } from '../unreal-status/unreal-status.component';\nimport { FreezeFrameComponent } from '../freeze-frame/freeze-frame.component';\nimport { VideoStatsComponent } from '../video-stats/video-stats.component';\nimport { ResumeStreamButtonComponent } from '../resume-stream-button/resume-stream-button.component';\nimport { ImageLoadingSrcComponent } from '../image-loading-src/image-loading-src.component';\nimport { IntroSrcComponent } from '../intro-src/intro-src.component';\nimport { EPayloadVersion, MetaBoxCommand } from '@3dsource/types-unreal';\nimport { Actions, ofType } from '@ngrx/effects';\n\n@Component({\n selector: 'app-unreal-scene',\n templateUrl: './unreal-scene.component.html',\n styleUrl: './unreal-scene.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n AfkTimeoutModalComponent,\n UnrealStatusComponent,\n FreezeFrameComponent,\n VideoStatsComponent,\n ResumeStreamButtonComponent,\n ImageLoadingSrcComponent,\n IntroSrcComponent,\n ],\n})\nexport class UnrealSceneComponent {\n readonly useContainerAsSizeProvider = input(true);\n readonly isStudio = input(false);\n readonly resolutionSize = input<{ width: number; height: number }>({\n width: FULL_HD_WIDTH,\n height: FULL_HD_HEIGHT,\n });\n\n readonly changeMouseOverScene = output<boolean>();\n\n readonly videoElement =\n viewChild<ElementRef<HTMLDivElement>>('videoContainer');\n\n private readonly resolutionValues$ = toObservable(this.resolutionSize);\n private width = FULL_HD_WIDTH;\n private height = FULL_HD_HEIGHT;\n private readonly actions$ = inject(Actions);\n readonly #store = inject(Store);\n private readonly isExistMatchUrls = this.#store.selectSignal(\n selectIsExistMatchUrls,\n );\n readonly isDevMode = inject(DevModeService).isDevMode;\n private readonly isFreezeFrameLoading = this.#store.selectSignal(\n selectIsFreezeFrameLoading,\n );\n private readonly maxResolution = Truthy(\n new URLSearchParams(location.search).get('maxresolution'),\n );\n private readonly commandsSender = inject(UnrealCommunicatorService);\n private readonly videoService = inject(VideoService);\n private readonly webRtcPlayerService = inject(WebRtcPlayerService);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly unrealConfig = inject(UNREAL_CONFIG);\n private autoHighResolution = false;\n\n private get resizeValues() {\n if (this.isStudio()) {\n return this.getResizeStudioValues();\n }\n return this.getResizeValuesUniversal();\n }\n\n private get pixelRatio() {\n return window.devicePixelRatio;\n }\n\n @HostListener('mouseover')\n onMouseOver() {\n this.changeMouseOverScene.emit(true);\n }\n\n @HostListener('mouseout')\n onMouseOut() {\n this.changeMouseOverScene.emit(false);\n }\n\n @HostListener('contextmenu', ['$event'])\n onContextMenu(event: Event) {\n event.preventDefault();\n }\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n // Release the remote connection synchronously, independent of the\n // route-scoped UnrealEffects. provideUnrealModule (effects) is registered\n // per 3D route, so on navigation the route's environment injector — and\n // its UnrealEffects — may be torn down before the\n // `destroyUnrealScene → destroyRemoteConnections` effect chain closes the\n // WebSocket/PeerConnection, which would leak the stream session. We call\n // the same root-singleton method the effect uses, so the two can never\n // drift; it's idempotent, so whichever runs second is a harmless no-op.\n this.webRtcPlayerService.releaseRemoteConnections(\n DisconnectReason.Destroy,\n );\n // State cleanup is reducer-driven, not effect-driven: the\n // `destroyUnrealScene` reducer resets the whole UnrealState to\n // initialState (cirrusConnected/viewportReady/… → false). Reducers run in\n // the root store synchronously on every dispatch, so this is guaranteed\n // even if the route-scoped effects are already torn down — which is what\n // keeps the next 3D route's connect unblocked (connectToSignaling$ gates\n // on `!cirrusConnected`).\n this.#store.dispatch(destroyUnrealScene());\n });\n effect(() => {\n const videoElement = this.videoElement();\n const isExistMatchUrls = this.isExistMatchUrls();\n untracked(() => {\n if (videoElement && isExistMatchUrls) {\n // Set the container before signalling starts: if a prefetched stream\n // is adopted here, VideoService.create() needs the DOM target now\n // (the live flow only reaches create() later, at `config` time, by\n // which point afterNextRender has already set it).\n this.videoService.setContainer(videoElement.nativeElement);\n this.#store.dispatch(initSignalling());\n }\n });\n });\n\n afterNextRender({\n read: () => {\n const videoElement = this.videoElement();\n if (videoElement) {\n this.videoService.setContainer(videoElement.nativeElement);\n this.listenResizeValues();\n this.listenInteractivityForAutoHighResolution(\n videoElement.nativeElement,\n );\n }\n },\n });\n }\n\n private listenInteractivityForAutoHighResolution(target: HTMLElement) {\n if (!this.unrealConfig?.autoHighResolution) {\n return;\n }\n\n // Capture phase + sync dispatch: forceResizeViewport must reach the\n // data channel BEFORE InputService's target-phase listeners on <video>\n // emit any mouse/touch input for this same event.\n const opts = { passive: true, capture: true } as const;\n const interaction$ = merge(\n fromEvent(target, 'mousedown', opts),\n fromEvent(target, 'wheel', opts),\n fromEvent(target, 'touchstart', opts),\n fromEvent(target, 'touchmove', opts),\n );\n\n merge(of(null), interaction$)\n .pipe(\n tap((event) => {\n if (event && this.autoHighResolution) {\n this.autoHighResolution = false;\n this.#store.dispatch(forceResizeViewport());\n }\n }),\n switchMap(() => timer(AUTO_HIGH_RESOLUTION_IDLE_MS)),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(() => {\n if (this.autoHighResolution) {\n return;\n }\n this.autoHighResolution = true;\n this.#store.dispatch(forceResizeViewport());\n });\n }\n\n private listenResizeValues() {\n const customSizeInputChanged$ = this.resolutionValues$.pipe(\n filter(\n ({ width, height }) => this.width !== width || this.height !== height,\n ),\n tap(({ width, height }) => {\n this.width = width;\n this.height = height;\n }),\n );\n\n const resizeRequired$ = merge(\n this.actions$.pipe(ofType(videoStreamInitialized)),\n fromEvent(window, 'resize'),\n );\n\n const videoStreamSizeChanged$ = this.videoService.videoStats$.pipe(\n filter(() => !this.isFreezeFrameLoading()),\n map((stats) => ({\n w: stats.aggregatedStats.frameWidth || 0,\n h: stats.aggregatedStats.frameHeight || 0,\n })),\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD),\n ),\n );\n\n merge(customSizeInputChanged$, resizeRequired$, videoStreamSizeChanged$)\n .pipe(\n debounceTime(DEBOUNCE_TO_MANY_RESIZE_CALLS),\n switchMap(() => {\n const key = Math.random();\n // Poll 3 times to capture late-arriving DOM measurements after layout settles\n return timer(0, 300).pipe(\n take(3),\n map(() => key),\n );\n }),\n map((key) => ({ key, ...this.resizeValues })),\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD) &&\n previous.key === current.key,\n ),\n tap((size) => this.adaptVideo(size)),\n // Key excluded: only dispatch when actual pixel dimensions change\n distinctUntilChanged(\n (previous, current) =>\n fpIsASameAsB(previous.w, current.w, SAME_SIZE_THRESHOLD) &&\n fpIsASameAsB(previous.h, current.h, SAME_SIZE_THRESHOLD),\n ),\n // Holds dispatch until data channel is up; retains true after disconnect\n // so resizes still reach Unreal — cleanup is handled by destroyUnrealScene\n combineLatestWith(\n this.#store\n .select(unrealFeature.selectDataChannelConnected)\n .pipe(filter(Truthy)),\n ),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe(([size]) => {\n this.#store.dispatch(\n changeStreamResolutionAction({ width: size.w, height: size.h }),\n );\n this.sendResize(size);\n });\n\n this.actions$\n .pipe(ofType(forceResizeViewport), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.sendResize(this.resizeValues));\n }\n\n private adaptVideo(size: Size) {\n const video = this.videoService.video;\n const areaSize = this.resizeValues;\n\n if (video?.style) {\n const pR = this.pixelRatio;\n video.width = makeEven(size.w / pR / areaSize.scale);\n video.height = makeEven(size.h / pR / areaSize.scale);\n\n if (!this.isStudio()) {\n video.style.overflow = 'hidden';\n video.style.objectFit = 'cover';\n video.style.width = `${video.width}px`;\n video.style.height = `${video.height}px`;\n }\n }\n\n this.#store.dispatch(videoAdaptedToContainer());\n }\n\n private getResizeValuesUniversal() {\n let containerWidth = window.innerWidth || MIN_CONTAINER_SIZE;\n let containerHeight = window.innerHeight || MIN_CONTAINER_SIZE;\n\n if (this.useContainerAsSizeProvider()) {\n containerWidth =\n this.videoElement()?.nativeElement.offsetWidth || MIN_CONTAINER_SIZE;\n containerHeight =\n this.videoElement()?.nativeElement.offsetHeight || MIN_CONTAINER_SIZE;\n }\n const pixelRatio = this.pixelRatio;\n\n return getResizeValuesUniversal({\n pixelRatio,\n containerWidth,\n containerHeight,\n maxResolution: this.maxResolution || this.autoHighResolution,\n });\n }\n\n private getResizeStudioValues() {\n const videoElement = this.videoElement()?.nativeElement;\n\n return getResizeStudioValues({\n pixelRatio: this.pixelRatio,\n containerWidth: videoElement?.offsetWidth || MIN_CONTAINER_SIZE,\n containerHeight: videoElement?.offsetHeight || MIN_CONTAINER_SIZE,\n studioWidth: this.width,\n studioHeight: this.height,\n maxResolution: this.maxResolution || this.autoHighResolution,\n });\n }\n\n private sendResize(size: Size) {\n const video = this.videoService.video;\n if (!video) {\n return;\n }\n this.commandsSender.sendCommandToUnreal({\n command: MetaBoxCommand.FChangeResolutionCommand,\n payload: {\n resolution: { x: size.w, y: size.h },\n payloadVersion: this.isStudio()\n ? EPayloadVersion.disableFovRecalculation\n : undefined,\n },\n });\n }\n}\n","<div class=\"frame unreal-container\">\n <div #videoContainer id=\"player\"></div>\n\n <app-intro-src />\n <app-image-loading-src />\n <app-resume-stream-button />\n <app-unreal-status />\n <app-freeze-frame />\n <app-afk-timeout-modal />\n\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n\n @if (isDevMode) {\n <app-video-stats />\n }\n</div>\n","import type { OnInit } from '@angular/core';\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Logger, Truthy } from '@3dsource/utils';\nimport type { FilterSettings } from '../../DataFlowConstants';\nimport { DefaultFilterModel, FilterModel } from '../../DataFlowConstants';\n\n@Component({\n selector: 'app-filter-settings',\n templateUrl: './filter-settings.component.html',\n styleUrl: './filter-settings.component.scss',\n imports: [FormsModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FilterSettingsComponent implements OnInit {\n private readonly storageKey = 'LBMFilterSettings';\n readonly defaultFilterModel = { ...DefaultFilterModel };\n settings = { ...DefaultFilterModel };\n\n ngOnInit() {\n const savedSettings = localStorage.getItem(this.storageKey);\n if (savedSettings) {\n this.dispatch(JSON.parse(savedSettings));\n }\n }\n\n togglePanel() {\n this.settings.panelOpen = !this.settings.panelOpen;\n this.saveSettings();\n }\n\n saveSettings() {\n const valid = Object.entries(this.settings).reduce((acc, [key, value]) => {\n return Truthy(value) ? { ...acc, [key]: value } : acc;\n }, {});\n this.dispatch({ ...DefaultFilterModel, ...valid });\n }\n\n dispatch(settings: FilterSettings) {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(settings));\n } catch (e) {\n Logger.error('Storage not available, Error saving filter settings:', e);\n }\n Object.assign(this.settings, settings);\n Object.assign(FilterModel, settings);\n }\n\n reset() {\n this.dispatch({\n ...DefaultFilterModel,\n panelOpen: this.settings.panelOpen,\n });\n }\n}\n","<div class=\"settings-container\">\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\n @if (settings.panelOpen) {\n <div class=\"settings-panel\">\n <h3>LBM Trigger Settings</h3>\n <h5>Data Flow Monitor</h5>\n <form>\n <label>\n Monitoring delay:\n <input\n [(ngModel)]=\"settings.monitoringDelayTime\"\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\n type=\"number\"\n name=\"monitoringDelayTime\"\n />\n </label>\n\n <label>\n Minimum Bitrate (kbit/s):\n <input\n [(ngModel)]=\"settings.minimumBitrate\"\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\n type=\"number\"\n name=\"minimumBitrate\"\n />\n </label>\n <label>\n Yellow Flag (%):\n <input\n [(ngModel)]=\"settings.yellowFlag\"\n [placeholder]=\"defaultFilterModel.yellowFlag\"\n type=\"number\"\n name=\"yellowFlag\"\n />\n </label>\n <label>\n Red Flag (%):\n <input\n [(ngModel)]=\"settings.redFlag\"\n [placeholder]=\"defaultFilterModel.redFlag\"\n type=\"number\"\n name=\"redFlag\"\n />\n </label>\n <label>\n Minimum FPS:\n <input\n [(ngModel)]=\"settings.minimumFps\"\n [placeholder]=\"defaultFilterModel.minimumFps\"\n type=\"number\"\n name=\"minimumFps\"\n />\n </label>\n <hr />\n <h5>Kalman Filter</h5>\n <label>\n Initial Bitrate Estimate (kbit/s):\n <input\n [(ngModel)]=\"settings.initialBitrateEstimate\"\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\n type=\"number\"\n name=\"initialBitrateEstimate\"\n />\n </label>\n <label>\n Initial Error Covariance:\n <input\n [(ngModel)]=\"settings.initialErrorCovariance\"\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\n type=\"number\"\n name=\"initialErrorCovariance\"\n />\n </label>\n <label>\n Process Noise (Q):\n <input\n [(ngModel)]=\"settings.processNoise\"\n [placeholder]=\"defaultFilterModel.processNoise\"\n type=\"number\"\n name=\"processNoise\"\n />\n </label>\n <label>\n Measurement Noise (R):\n <input\n [(ngModel)]=\"settings.measurementNoise\"\n [placeholder]=\"defaultFilterModel.measurementNoise\"\n type=\"number\"\n name=\"measurementNoise\"\n />\n </label>\n </form>\n <br />\n <br />\n <div class=\"apply-button-container\">\n <button (click)=\"reset()\">Reset</button>\n <button (click)=\"saveSettings()\">Apply</button>\n </div>\n </div>\n }\n</div>\n","import { Injectable, signal } from '@angular/core';\nimport { toObservable } from '@angular/core/rxjs-interop';\n\n@Injectable({ providedIn: 'root' })\nexport class LowBandwidthStateService {\n readonly #isLowBandwidth = signal(false);\n\n readonly isLowBandwidth = this.#isLowBandwidth.asReadonly();\n readonly isLowBandwidth$ = toObservable(this.isLowBandwidth);\n\n enterLowBandwidthMode() {\n this.#isLowBandwidth.set(true);\n }\n\n exitLowBandwidthMode() {\n this.#isLowBandwidth.set(false);\n }\n}\n","import type { OnInit } from '@angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n inject,\n signal,\n} from '@angular/core';\nimport { filter, tap } from 'rxjs/operators';\nimport { LowBandwidthModalComponent } from './components/low-bandwidth-modal/low-bandwidth-modal.component';\nimport { Store } from '@ngrx/store';\nimport { Falsy, Logger, Truthy } from '@3dsource/utils';\nimport {\n takeUntilDestroyed,\n toObservable,\n toSignal,\n} from '@angular/core/rxjs-interop';\nimport { unrealFeature } from '../../store';\nimport { Dialog } from '@angular/cdk/dialog';\nimport {\n combineLatestWith,\n concat,\n debounceTime,\n distinctUntilChanged,\n map,\n merge,\n of,\n share,\n skip,\n switchMap,\n take,\n takeUntil,\n timer,\n} from 'rxjs';\nimport { DevModeService, VideoService } from '../../services';\nimport type { Quality } from '../../interfaces';\nimport type { DataFlowCheckResult } from '../../helpers';\nimport { FilterSettingsComponent } from './components/filter-settings/filter-settings.component';\nimport { BITRATE_MONITOR, FilterModel } from './DataFlowConstants';\nimport { LowBandwidthStateService } from './low-bandwidth-state.service';\n\n@Component({\n selector: 'app-low-bandwidth-detector',\n templateUrl: './low-bandwidth-detector.component.html',\n styleUrl: './low-bandwidth-detector.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FilterSettingsComponent],\n})\nexport class LowBandwidthDetectorComponent implements OnInit {\n #store = inject(Store);\n private readonly dialog = inject(Dialog);\n private readonly destroyRef = inject(DestroyRef);\n private readonly videoService = inject(VideoService);\n private readonly lowBandwidthState = inject(LowBandwidthStateService);\n readonly isDevMode = inject(DevModeService).isDevMode;\n\n private readonly viewportReady$ = this.#store.select(\n unrealFeature.selectViewportReady,\n );\n private readonly isLowBandwidth$ = this.lowBandwidthState.isLowBandwidth$;\n private readonly lowBandwidthTrigger$ = this.isLowBandwidth$.pipe(\n distinctUntilChanged(),\n filter(Truthy),\n );\n private readonly highBandwidthTrigger$ = this.isLowBandwidth$.pipe(\n distinctUntilChanged(),\n filter(Falsy),\n );\n\n private readonly viewPortDestroyedTrigger$ = this.viewportReady$.pipe(\n distinctUntilChanged(),\n filter(Falsy),\n );\n\n private readonly aggregatedStats$ = this.videoService.videoStats$.pipe(\n map((data) => data.aggregatedStats),\n share(),\n );\n private readonly nativeQuality$ = this.videoService.videoStats$.pipe(\n map((data) => data.quality),\n );\n\n private readonly monitoringTrigger$ = this.viewportReady$\n .pipe(\n combineLatestWith(this.isLowBandwidth$),\n map(\n ([viewPortReady, isLowBandwidth]) => viewPortReady && !isLowBandwidth,\n ),\n )\n .pipe(share());\n\n private readonly reTrigger$ = this.monitoringTrigger$.pipe(\n map(() => ({ quality: 'lime' as Quality })),\n );\n\n private readonly canSwitchToLowBand$ = this.monitoringTrigger$.pipe(\n debounceTime(100),\n switchMap((canSwitch) =>\n concat(\n of(false),\n timer(FilterModel.monitoringDelayTime).pipe(map(() => canSwitch)),\n ).pipe(take(2), takeUntil(this.monitoringTrigger$)),\n ),\n distinctUntilChanged(),\n share(),\n );\n\n private readonly videoQuality$ = merge(\n this.nativeQuality$,\n this.reTrigger$,\n ).pipe(share(), takeUntil(this.viewPortDestroyedTrigger$));\n\n private readonly fps$ = this.aggregatedStats$.pipe(\n map((data) => data.framesPerSecond || 0),\n );\n\n private readonly bitrateDrop$ = this.aggregatedStats$.pipe(\n map((data) => data.dataFlowCheckResult),\n filter((br) => br.isDropDetected),\n takeUntil(merge(this.viewPortDestroyedTrigger$, this.reTrigger$)),\n );\n\n readonly fps = toSignal(this.fps$, { initialValue: 0 });\n readonly nativeQuality = toSignal(this.nativeQuality$);\n readonly isLowBandwidth = this.lowBandwidthState.isLowBandwidth;\n readonly aggregatedStats = toSignal(this.aggregatedStats$);\n readonly isReducedQuality = signal(false);\n readonly isIndicatorExpanded = signal(false);\n\n readonly isIndicatorExpandedTrigger$ = toObservable(\n this.isIndicatorExpanded,\n ).pipe(skip(1), distinctUntilChanged(), filter(Falsy));\n\n ngOnInit() {\n this.lowBandwidthTrigger$\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.toggleIndicator(true));\n\n merge(this.viewPortDestroyedTrigger$, this.highBandwidthTrigger$)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.isReducedQuality.set(false));\n\n this.canSwitchToLowBand$\n .pipe(\n filter(Truthy),\n tap(() => {\n BITRATE_MONITOR.reset();\n this.isReducedQuality.set(false);\n }),\n switchMap(() => this.bitrateDrop$),\n tap(this.trySetLowBandwidth.bind(this)),\n map((dataFlowResult) => dataFlowResult?.isDropDetected),\n distinctUntilChanged(),\n tap(() => {\n this.isReducedQuality.set(true);\n }),\n switchMap(() => this.videoQuality$),\n filter((quality) => quality === 'lime'),\n tap(() => this.isReducedQuality.set(false)),\n takeUntilDestroyed(this.destroyRef),\n )\n .subscribe();\n }\n\n private trySetLowBandwidth(dataFlowResult: DataFlowCheckResult) {\n // Evaluate FPS and native quality\n const isFpsLow = this.fps() < FilterModel.minimumFps;\n const isNativeQualityRed = this.nativeQuality() === 'red';\n const shouldSwitch = isNativeQualityRed || isFpsLow;\n\n // Exit if conditions are not met or already in low bandwidth\n if (!shouldSwitch || this.isLowBandwidth()) return;\n\n const { quality, activeMedian } = dataFlowResult;\n const isQualityRed = quality === 'red';\n const isLowBitrate = activeMedian < FilterModel.minimumBitrate;\n\n // Final check for a red drop or low bitrate, or low FPS\n if (isQualityRed || isLowBitrate || isFpsLow) {\n let reason: string;\n\n if (isFpsLow) {\n reason = `FPS < ${FilterModel.minimumFps}`;\n } else if (quality === 'red') {\n reason = `Drop > ${FilterModel.redFlag}%`;\n } else {\n reason = `Speed < ${FilterModel.minimumBitrate}`;\n }\n\n Logger.info(\n `LBM DETECTED: ${reason}, switching to low bandwidth; `,\n dataFlowResult.message,\n {\n stats: {\n dataFlowResult,\n reason,\n triggerTime: this.aggregatedStats()?.runTime ?? 0,\n },\n },\n );\n this.lowBandwidthState.enterLowBandwidthMode();\n }\n }\n\n toggleIndicator(value: boolean) {\n this.isIndicatorExpanded.set(value);\n\n if (value) {\n this.hideIndicatorAfterDelay();\n }\n }\n\n hideIndicatorAfterDelay() {\n timer(3000)\n .pipe(take(1), takeUntil(this.isIndicatorExpandedTrigger$))\n .subscribe(() => this.toggleIndicator(false));\n }\n\n openLBMDialog() {\n this.dialog\n .open(LowBandwidthModalComponent)\n .closed.pipe(filter(Truthy))\n .subscribe(() => {\n this.lowBandwidthState.exitLowBandwidthMode();\n this.toggleIndicator(false);\n });\n }\n}\n","@if (isReducedQuality() || isLowBandwidth()) {\n <div\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\n class=\"lbm-indicator freeze-loader\"\n >\n <button (click)=\"toggleIndicator(true)\" class=\"lbm-icon\" type=\"button\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\n <path\n fill=\"#85888E\"\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n />\n <path\n fill=\"#fff\"\n fill-rule=\"evenodd\"\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n\n <div\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\n class=\"lbm-message\"\n >\n <p class=\"lbm-description\">\n Fluid Interactivity Modes were disabled due to an unstable connection.\n\n <button\n (click)=\"openLBMDialog()\"\n [attr.data-testid]=\"'learn-more-lbm'\"\n type=\"button\"\n class=\"lbm-learn-more\"\n >\n Learn more\n </button>\n </p>\n <button\n (click)=\"toggleIndicator(false)\"\n [attr.data-testid]=\"'close-lbm-indicator'\"\n type=\"button\"\n class=\"lbm-close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\n fill=\"white\"\n />\n </svg>\n </button>\n </div>\n </div>\n}\n\n@if (isDevMode) {\n <app-filter-settings />\n}\n","import { provideState } from '@ngrx/store';\nimport { provideEffects } from '@ngrx/effects';\nimport { UnrealEffects, unrealFeature } from '../store';\nimport {\n AFKService,\n AggregatorService,\n AnalyticsService,\n ConsoleExtensionsService,\n FpsMonitorService,\n FreezeFrameService,\n InputService,\n StreamStatusTelemetryService,\n StreamStatusTelemetryService2,\n} from '../services';\nimport {\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\n\n/**\n * Registers the Unreal NgRx feature state. Call this ONCE at the application\n * root.\n *\n * The streaming services are `providedIn: 'root'` singletons that hold\n * long-lived store subscriptions, so the feature state must live for the whole\n * app lifetime — registering it per-route would tear the slice down on\n * navigation and leave those singletons selecting from missing state.\n */\nexport function provideUnrealState() {\n return makeEnvironmentProviders([provideState(unrealFeature)]);\n}\n\n/**\n * Registers the Unreal effects and boots the streaming engine. Call this at\n * each lazy 3D route (configurator stream/manager, viewer, studio, …).\n *\n * The engine services are `providedIn: 'root'` singletons: navigating between\n * 3D routes reuses one live instance instead of re-instantiating WebRTC /\n * signalling / input listeners (which have no teardown). Their code is still\n * tree-shaken into the lazy route chunk because only these lazy routes import\n * it — so it stays out of the initial bundle.\n *\n * Requires {@link provideUnrealState} and the `UNREAL_CONFIG` value to be\n * provided at the app root.\n */\nexport function provideUnrealModule() {\n return makeEnvironmentProviders([\n provideEffects([UnrealEffects]),\n provideEnvironmentInitializer(() => {\n inject(AggregatorService);\n inject(InputService);\n inject(StreamStatusTelemetryService);\n inject(StreamStatusTelemetryService2);\n inject(ConsoleExtensionsService);\n inject(AFKService);\n inject(FreezeFrameService);\n inject(AnalyticsService);\n inject(FpsMonitorService);\n }),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["map","timeout","switchMap","takeUntil","tap","debounceTime","take","startWith","filter","withLatestFrom","uuidv4","distinctUntilChanged"],"mappings":";;;;;;;;;;;;;;;;;;;AAAO,MAAM,eAAe,GAAG;AAC7B,IAAA,SAAS,EAAE,CAAC;AACZ,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,GAAG,EAAE,EAAE;AACP,IAAA,UAAU,EAAE,GAAG;AACf,IAAA,YAAY,EAAE,GAAG;AACjB,IAAA,QAAQ,EAAE,GAAG;;AAGf;AACO,MAAM,WAAW,GAAG;IACzB,UAAU,EAAE,CAAC;IACb,eAAe,EAAE,CAAC;IAClB,eAAe,EAAE,CAAC;IAClB,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,CAAC;;AAGhB;AACO,MAAM,gBAAgB,GAAG;IAC9B,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,CAAC;IAClB,eAAe,EAAE,CAAC;IAClB,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,EAAE;;;ACzBV,MAAM,aAAa,GAAG;;;;AAI3B,IAAA,WAAW,EAAE,CAAC;;;AAGd,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,OAAO,EAAE,CAAC;;;ACRZ;AACO,MAAM,WAAW,GAAG;AACzB;;AAEG;AACH,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,qBAAqB,EAAE,CAAC;AACxB,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,qBAAqB,EAAE,CAAC;AACxB,IAAA,cAAc,EAAE,CAAC;AACjB,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,WAAW,EAAE,CAAC;AACd,IAAA,sBAAsB,EAAE,CAAC;AAEzB;;AAEG;;AAGH,IAAA,aAAa,EAAE,EAAE;AACjB,IAAA,OAAO,EAAE,EAAE;;AAGX,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,QAAQ,EAAE,EAAE;;AAGZ,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,SAAS,EAAE,EAAE;AACb,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,SAAS,EAAE,EAAE;AACb,IAAA,UAAU,EAAE,EAAE;;AAGd,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,SAAS,EAAE,EAAE;;;ACtCR,MAAM,eAAe,GAAG;AAC7B,IAAA,uBAAuB,EAAE,CAAC;AAC1B,IAAA,QAAQ,EAAE,CAAC;AACX,IAAA,OAAO,EAAE,CAAC;AACV,IAAA,WAAW,EAAE,CAAC;AACd,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,iBAAiB,EAAE,CAAC;AACpB,IAAA,WAAW,EAAE,CAAC;AACd,IAAA,eAAe,EAAE,CAAC;AAClB,IAAA,aAAa,EAAE,CAAC;AAChB,IAAA,YAAY,EAAE,CAAC;AACf,IAAA,YAAY,EAAE,EAAE;AAChB,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,qBAAqB,EAAE,EAAE;AACzB,IAAA,eAAe,EAAE,EAAE;AACnB,IAAA,QAAQ,EAAE,GAAG;;;MCZF,aAAa,GAAG,IAAI,cAAc,CAC7C,8BAA8B;;ACDzB,MAAM,YAAY,GAAe;IACtC,aAAa,EAAE,aAAa,CAAC,OAAO;AACpC,IAAA,mBAAmB,EAAE,IAAI;;;ACLpB,MAAM,0BAA0B,GAAG;AACnC,MAAM,8BAA8B,GAAG;AACvC,MAAM,oCAAoC,GAAG;AAC7C,MAAM,8BAA8B,GAAG;AAEvC,MAAM,mBAAmB,GAAG;AAE5B,MAAM,sCAAsC,GAAG;AAC/C,MAAM,mCAAmC,GAAG;AAC5C,MAAM,oCAAoC,GAAG;AAC7C,MAAM,wCAAwC,GAAG;AAEjD,MAAM,YAAY,GAAG;IAC1B,0BAA0B;IAC1B,8BAA8B;IAC9B,oCAAoC;IACpC,8BAA8B;IAC9B,mBAAmB;IACnB,sCAAsC;IACtC,mCAAmC;IACnC,oCAAoC;IACpC,wCAAwC;;;ACrBnC,MAAM,gBAAgB,GAAG;AAC9B,IAAA,GAAG,EAAE,KAAK;AACV,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,OAAO,EAAE,SAAS;AAClB,IAAA,iBAAiB,EAAE,mBAAmB;AACtC,IAAA,kBAAkB,EAAE,oBAAoB;AACxC,IAAA,WAAW,EAAE,aAAa;AAC1B,IAAA,cAAc,EAAE,gBAAgB;AAChC,IAAA,cAAc,EAAE,gBAAgB;AAChC,IAAA,cAAc,EAAE,gBAAgB;AAChC,IAAA,+BAA+B,EAAE,iCAAiC;AAClE,IAAA,iCAAiC,EAAE,mCAAmC;AACtE,IAAA,mBAAmB,EAAE,qBAAqB;AAC1C,IAAA,eAAe,EAAE,iBAAiB;AAClC,IAAA,oBAAoB,EAAE,sBAAsB;AAC5C,IAAA,2BAA2B,EAAE,6BAA6B;;;ACf5D;;;;AAIE;AAIK,MAAM,yBAAyB,GAAG;AACvC,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,KAAK,EAAE,OAAO;AACd,IAAA,KAAK,EAAE,OAAO;AACd,IAAA,MAAM,EAAE,QAAQ;AAChB,IAAA,MAAM,EAAE,QAAQ;AAChB,IAAA,MAAM,EAAE,QAAQ;AAChB,IAAA,WAAW,EAAE,aAAa;AAC1B,IAAA,YAAY,EAAE,cAAc;AAC5B,IAAA,YAAY,EAAE,cAAc;AAC5B,IAAA,aAAa,EAAE,eAAe;AAC9B,IAAA,aAAa,EAAE,eAAe;AAC9B,IAAA,aAAa,EAAE,eAAe;AAC9B,IAAA,cAAc,EAAE,gBAAgB;AAChC,IAAA,gBAAgB,EAAE,kBAAkB;AACpC,IAAA,kBAAkB,EAAE,oBAAoB;AACxC,IAAA,gCAAgC,EAAE,kCAAkC;AACpE,IAAA,oBAAoB,EAAE,sBAAsB;AAC5C,IAAA,qBAAqB,EAAE,uBAAuB;;;ACvBhD;AACO,MAAM,0BAA0B,GAA2B;AAChE,IAAA,gBAAgB,CAAC,GAAG;AACpB,IAAA,gBAAgB,CAAC,cAAc;AAC/B,IAAA,gBAAgB,CAAC,WAAW;AAC5B,IAAA,gBAAgB,CAAC,cAAc;AAC/B,IAAA,gBAAgB,CAAC,cAAc;AAC/B,IAAA,gBAAgB,CAAC,eAAe;AAChC,IAAA,gBAAgB,CAAC,iBAAiB;AAClC,IAAA,gBAAgB,CAAC,kBAAkB;AACnC,IAAA,gBAAgB,CAAC,+BAA+B;AAChD,IAAA,gBAAgB,CAAC,iCAAiC;;;ACd7C,MAAM,6BAA6B,GAAG;AACtC,MAAM,4BAA4B,GAAG;AACrC,MAAM,mBAAmB,GAAG;AACnC;AACO,MAAM,kBAAkB,GAAG;AAC3B,MAAM,WAAW,GAAG;AACpB,MAAM,kBAAkB,GAAG;AAC3B,MAAM,kBAAkB,GAAG;AAC3B,MAAM,aAAa,GAAG;AACtB,MAAM,cAAc,GAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,UAAU,GAAG;AACnB,MAAM,YAAY,GAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,iBAAiB,GAAG;AAC1B,MAAM,iBAAiB,GAAG,YAAY,GAAG;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,qBAAqB,GAAG;AAC9B,MAAM,aAAa,GAAG;AACtB,MAAM,0BAA0B,GAAG;AACnC,MAAM,mBAAmB,GAAG,IAAI;AAChC,MAAM,+BAA+B,GAAG,KAAK;AAC7C,MAAM,wBAAwB,GAAG;AACjC,MAAM,0BAA0B,GAAG;AAE1C;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,qBAAqB,GAAG;AACrC;AACA;AACO,MAAM,wBAAwB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;AAC5D;AACA;AACA;AACA;AACO,MAAM,4BAA4B,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACO,MAAM,8BAA8B,GAAG;AAC9C;AACA;AACA;AACO,MAAM,uCAAuC,GAAG;AAEvD;AACO,MAAM,gBAAgB,GAAG;AAC9B,IAAA,OAAO,EAAE,IAAI;AACb,IAAA,WAAW,EAAE,CAAC;AACd,IAAA,OAAO,EAAE,IAAI;;AAGR,MAAM,mBAAmB,GAAG;AACjC,IAAA,qBAAqB,EAAE,wBAAwB;AAC/C,IAAA,qBAAqB,EAAE,uBAAuB;;;ACpEhD,MAAM,MAAM,GAAG,CAAC,cAAoC,KAClD,CAAA,SAAA,EAAY,cAAc,CAAC,CAAC,CAAC,EAAE;AAe1B,MAAM,qBAAqB,GAAG,YAAY,CAC/C,MAAM,CAAA,CAAA,uBAAA,CAAyB,EAC/B,KAAK,EAAgC;AAEhC,MAAM,cAAc,GAAG,YAAY,CACxC,MAAM,CAAA,CAAA,eAAA,CAAiB,EACvB,KAAK,EAAsD;AAEtD,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,iBAAA,CAAmB,EACzB,KAAK,EAA+B;AAG/B,MAAM,kBAAkB,GAAG,YAAY,CAC5C,MAAM,CAAA,CAAA,oBAAA,CAAsB,EAC5B,KAAK,EAAqC;AAErC,MAAM,kBAAkB,GAAG,YAAY,CAC5C,MAAM,CAAA,CAAA,oBAAA,CAAsB,EAC5B,KAAK,EAAqC;AAErC,MAAM,SAAS,GAAG,YAAY,CACnC,MAAM,CAAA,CAAA,UAAA,CAAY,EAClB,KAAK,EAAsB;AAEtB,MAAM,wBAAwB,GAAG,YAAY,CAClD,MAAM,CAAA,CAAA,wBAAA,CAA0B,EAChC,KAAK,EAAoC;AAEpC,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,kBAAA,CAAoB;AAClE,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,eAAA,CAAiB;AAC/D,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,kBAAA,CAAoB;AACrE,MAAM,4BAA4B,GAAG,YAAY,CACtD,MAAM,CAAA,CAAA,iCAAA,CAAmC,EACzC,KAAK,EAA+B;AAE/B,MAAM,cAAc,GAAG,YAAY,CACxC,MAAM,CAAA,CAAA,gBAAA,CAAkB,EACxB,KAAK,EAID;AAEC,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,kBAAA,CAAoB,EAC1B,KAAK,EAAoC;AAEpC,MAAM,gCAAgC,GAAG,YAAY,CAC1D,MAAM,CAAA,CAAA,uCAAA,CAAyC,EAC/C,KAAK,EAA8B;AAE9B,MAAM,cAAc,GAAG,YAAY,CACxC,MAAM,CAAA,CAAA,gBAAA,CAAkB,EACxB,KAAK,EAGD;AAEC,MAAM,wBAAwB,GAAG,YAAY,CAClD,MAAM,CAAA,CAAA,4BAAA,CAA8B,EACpC,KAAK,EAAkB;AAElB,MAAM,eAAe,GAAG,YAAY,CACzC,MAAM,CAAA,CAAA,kBAAA,CAAoB,EAC1B,KAAK,EAAkB;AAElB,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,mBAAA,CAAqB,EAC3B,KAAK,EAAmB;AAGnB,MAAM,kBAAkB,GAAG,YAAY,CAC5C,MAAM,CAAA,CAAA,qBAAA,CAAuB,EAC7B,KAAK,EAAmB;AAEnB,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,mBAAA,CAAqB,EAC3B,KAAK,EAAmB;AAEnB,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,eAAA,CAAiB;AAC1D,MAAM,uBAAuB,GAAG,YAAY,CACjD,MAAM,CAAA,CAAA,2BAAA,CAA6B,EACnC,KAAK,EAGD;AAEC,MAAM,yBAAyB,GAAG,YAAY,CACnD,MAAM,CAAA,CAAA,2BAAA,CAA6B,EACnC,KAAK,EAAsB;AAEtB,MAAM,oBAAoB,GAAG,YAAY,CAC9C,MAAM,CAAA,CAAA,sBAAA,CAAwB,EAC9B,KAAK,EAA6B;AAE7B,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,gBAAA,CAAkB;AAC9D,MAAM,SAAS,GAAG,YAAY,CACnC,MAAM,CAAA,CAAA,UAAA,CAAY,EAClB,KAAK,EAAqC;AAErC,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,gBAAA,CAAkB,EACxB,KAAK,EAGD;AAEC,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,cAAA,CAAgB;AAC1D,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,kBAAA,CAAoB;AAChE,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,sBAAA,CAAwB;AACvE,MAAM,4BAA4B,GAAG,YAAY,CACtD,MAAM,CAAA,CAAA,wBAAA,CAA0B,EAChC,KAAK,EAGD;AAEC,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,oBAAA,CAAsB,EAC5B,KAAK,EAA4B;AAE5B,MAAM,0BAA0B,GAAG,YAAY,CACpD,MAAM,CAAA,CAAA,4BAAA,CAA8B,EACpC,KAAK,EAAkE;AAEzE;;;;AAIG;AACI,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,cAAA,CAAgB;AAChE;;;;;AAKG;AACI,MAAM,oBAAoB,GAAG,YAAY,CAC9C,MAAM,CAAA,CAAA,uBAAA,CAAyB;AAEjC;;;;;AAKG;AACI,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,qBAAA,CAAuB;AAC5E;;;;;;AAMG;AACI,MAAM,cAAc,GAAG,YAAY,CACxC,MAAM,CAAA,CAAA,eAAA,CAAiB,EACvB,KAAK,EAGD;AAEN;;;;;AAKG;AACI,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,eAAA,CAAiB;AAC3D,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,aAAA,CAAe;AAC9D;;;;;;;;;;;;;;;;AAgBG;AACI,MAAM,uBAAuB,GAAG,YAAY,CACjD,MAAM,CAAA,CAAA,yBAAA,CAA2B,EACjC,KAAK,EASD;AAEN;;;AAGG;AACI,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,WAAA,CAAa;AACnD,MAAM,uBAAuB,GAAG,YAAY,CACjD,MAAM,CAAA,CAAA,yBAAA,CAA2B,EACjC,KAAK,EAAuB;AAEvB,MAAM,wBAAwB,GAAG,YAAY,CAClD,MAAM,CAAA,CAAA,0BAAA,CAA4B,EAClC,KAAK,EAAgC;AAEhC,MAAM,uBAAuB,GAAG,YAAY,CACjD,MAAM,CAAA,CAAA,wBAAA,CAA0B,EAChC,KAAK,EAID;AAEC,MAAM,gBAAgB,GAAG,YAAY,CAC1C,MAAM,CAAA,CAAA,cAAA,CAAgB,EACtB,KAAK,EAA6B;AAE7B,MAAM,6BAA6B,GAAG,YAAY,CACvD,MAAM,CAAA,CAAA,iCAAA,CAAmC;AAEpC,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,qBAAA,CAAuB;AACrE,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,kBAAA,CAAoB;AAC/D,MAAM,oBAAoB,GAAG,YAAY,CAC9C,MAAM,CAAA,CAAA,wBAAA,CAA0B,EAChC,KAAK,EAAyB;AAEzB,MAAM,sBAAsB,GAAG,YAAY,CAChD,MAAM,CAAA,CAAA,yBAAA,CAA2B,EACjC,KAAK,EAA2C;AAE3C,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,eAAA,CAAiB;AAClE;;;;;;;;;;AAUG;AACI,MAAM,aAAa,GAAG,YAAY,CACvC,MAAM,CAAA,CAAA,cAAA,CAAgB,EACtB,KAAK,EAaD;AAEC,MAAM,WAAW,GAAG,YAAY,CACrC,MAAM,CAAA,CAAA,WAAA,CAAa,EACnB,KAAK,EAAqC;AAErC,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,YAAA,CAAc;AACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,gBAAA,CAAkB;AACtD,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,yBAAA,CAA2B;AAC9E;;;;;;;;AAQG;AACI,MAAM,2BAA2B,GAAG,YAAY,CACrD,MAAM,CAAA,CAAA,2BAAA,CAA6B;AAE9B,MAAM,yBAAyB,GAAG,YAAY,CACnD,MAAM,CAAA,CAAA,4BAAA,CAA8B;AAE/B,MAAM,kBAAkB,GAAG,YAAY,CAC5C,MAAM,CAAA,CAAA,oBAAA,CAAsB,EAC5B,KAAK,EAAgE;AAEvE;AACO,MAAM,aAAa,GAAG,YAAY,CACvC,MAAM,CAAA,CAAA,cAAA,CAAgB,EACtB,KAAK,EAA4D;AAEnE;AACO,MAAM,4BAA4B,GAAG,YAAY,CACtD,MAAM,CAAA,CAAA,gCAAA,CAAkC;AAE1C;AACO,MAAM,oBAAoB,GAAG,YAAY,CAC9C,MAAM,CAAA,CAAA,sBAAA,CAAwB;AAEhC;AACO,MAAM,mBAAmB,GAAG,YAAY,CAC7C,MAAM,CAAA,CAAA,qBAAA,CAAuB,EAC7B,KAAK,EAAsB;AAE7B;AACO,MAAM,mBAAmB,GAAG,YAAY,CAC7C,MAAM,CAAA,CAAA,qBAAA,CAAuB,EAC7B,KAAK,EAAoC;AAEpC,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,qBAAA,CAAuB;AACtE,MAAM,uBAAuB,GAAG,YAAY,CACjD,MAAM,CAAA,CAAA,0BAAA,CAA4B;AAE7B,MAAM,sBAAsB,GAAG,YAAY,CAChD,MAAM,CAAA,CAAA,wBAAA,CAA0B;AAE3B,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,iBAAA,CAAmB;AACrD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAA,CAAA,oBAAA,CAAsB;AACxD,MAAM,mBAAmB,GAAG,YAAY,CAC7C,MAAM,CAAA,CAAA,qBAAA,CAAuB,EAC7B,KAAK,EAAwB;AAExB,MAAM,qBAAqB,GAAG,YAAY,CAC/C,MAAM,CAAA,CAAA,wBAAA,CAA0B,EAChC,KAAK,EAAwB;AAExB,MAAM,8BAA8B,GAAG,YAAY,CACxD,MAAM,CAAA,CAAA,kCAAA,CAAoC,EAC1C,KAAK,EAAwB;AAExB,MAAM,wBAAwB,GAAG,YAAY,CAClD,MAAM,CAAA,CAAA,2BAAA,CAA6B,EACnC,KAAK,EAAuB;AAEvB,MAAM,0BAA0B,GAAG,YAAY,CACpD,MAAM,CAAA,CAAA,6BAAA,CAA+B;;AC9SvC,MAAM,wBAAwB,GAAG,MAAM;AAQvC,SAAS,oBAAoB,CAC3B,kBAAuC,EACvC,UAAkB,EAClB,GAAW,EAAA;AAEX,IAAA,IAAI,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACvE,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAC9B,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,GAAG,SAAS,GAAG,wBAAwB,CAC9D;AACD,IAAA,IAAI,OAAO,CAAC,MAAM,EAAE;AAClB,QAAA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/D;IACA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;AAClE;AAgDA,MAAM,YAAY,GAAgB;AAChC,IAAA,oBAAoB,EAAE,IAAI;AAC1B,IAAA,aAAa,EAAE,IAAI;AACnB,IAAA,kBAAkB,EAAE,KAAK;AACzB,IAAA,iBAAiB,EAAE,KAAK;AACxB,IAAA,YAAY,EAAE,CAAC;AACf,IAAA,eAAe,EAAE,KAAK;AACtB,IAAA,OAAO,EAAE,KAAK;AACd,IAAA,sBAAsB,EAAE,KAAK;AAC7B,IAAA,cAAc,EAAE,KAAK;AACrB,IAAA,aAAa,EAAE,KAAK;AACpB,IAAA,oBAAoB,EAAE,KAAK;AAC3B,IAAA,cAAc,EAAE,KAAK;AACrB,IAAA,6BAA6B,EAAE,IAAI;AACnC,IAAA,aAAa,EAAE,IAAI;AACnB,IAAA,YAAY,EAAE,IAAI;AAClB,IAAA,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAC/C,oBAAoB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvD,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9C,gBAAgB,EAAE,gBAAgB,CAAC,IAAI;AACvC,IAAA,WAAW,EAAE;AACX,QAAA,KAAK,EAAE,IAAI;AACX,QAAA,YAAY,EAAE,IAAI;AAClB,QAAA,UAAU,EAAE,IAAI;AAChB,QAAA,gBAAgB,EAAE,CAAC;AACpB,KAAA;AACD,IAAA,YAAY,EAAE;AACZ,QAAA,SAAS,EAAE,IAAI;AACf,QAAA,WAAW,EAAE,mBAAmB;AACjC,KAAA;AACD,IAAA,qBAAqB,EAAE,mBAAmB;AAC1C,IAAA,SAAS,EAAE,EAAE;AACb,IAAA,qBAAqB,EAAE,EAAE;AACzB,IAAA,YAAY,EAAE,SAAS;AACvB,IAAA,aAAa,EAAE,IAAI;AACnB,IAAA,aAAa,EAAE,IAAI;AACnB,IAAA,eAAe,EAAE,EAAE;AACnB,IAAA,cAAc,EAAE,IAAI;AACpB,IAAA,mBAAmB,EAAE,IAAI;AACzB,IAAA,qBAAqB,EAAE,IAAI;AAC3B,IAAA,mBAAmB,EAAE,IAAI;AACzB,IAAA,kBAAkB,EAAE,EAAE;AACtB,IAAA,oBAAoB,EAAE,CAAC;AACvB,IAAA,sBAAsB,EAAE,CAAC;CAC1B;AACM,MAAM,aAAa,GAAG,aAAa,CACxC,YAAY,EACZ,EAAE,CAAC,4BAA4B,EAAE,CAAC,KAAK,EAAE,EAAE,cAAc,EAAE,KAAiB;AAC1E,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE;AACrC,CAAC,CAAC,EACF,EAAE,CACA,cAAc,EACd,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,KAAiB;IAC1D,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,WAAW,EAAE;YACX,GAAG,KAAK,CAAC,WAAW;YACpB,YAAY;YACZ,KAAK;YACL,UAAU;AACV,YAAA,gBAAgB,EAAE,CAAC;AACpB,SAAA;KACF;AACH,CAAC,CACF,EACD,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,KAAiB;IAC1C,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,YAAY,EAAE,IAAI;KACnB;AACH,CAAC,CAAC,EACF,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,KAAiB;IAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;AAC3C,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAiB;IACtD,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;AACrC,CAAC,CAAC,EACF,EAAE,CAAC,4BAA4B,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAiB;AACzE,IAAA,IACE,CAAC,KAAK;AACN,QAAA,CAAC,MAAM;AACP,SAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,KAAK,KAAK;YACrC,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,MAAM,CAAC,EAC3C;AACA,QAAA,OAAO,KAAK;IACd;AACA,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;AAC1D,CAAC,CAAC,EACF,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,KAAiB;IACrD,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,WAAW,EAAE;AACX,YAAA,OAAO,EACL,WAAW,CAAC,QAAQ,KAAK,CAAC;gBAC1B,WAAW,CAAC,QAAQ,KAAK,CAAC;gBAC1B,WAAW,CAAC,QAAQ,KAAK;kBACrB,WAAW,CAAC;AACd,kBAAE,KAAK,CAAC,WAAW,CAAC,OAAO;AAC/B,YAAA,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,IAAI;AACvC,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAiB;;;IAGxD,IAAI,KAAK,CAAC,gBAAgB,KAAK,gBAAgB,CAAC,OAAO,EAAE;AACvD,QAAA,OAAO,KAAK;IACd;;;;;IAKA,MAAM,gBAAgB,GACpB,KAAK,CAAC,gBAAgB,KAAK,gBAAgB,CAAC;UACxC,YAAY,CAAC;AACf,UAAE,KAAK,CAAC,gBAAgB;AAC5B,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE;AAC1E,CAAC,CAAC,EACF,EAAE,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAiB;IACvE,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,oBAAoB,EAAE;YACpB,OAAO,EAAE,oBAAoB,CAAC,OAAO;AACrC,YAAA,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,IAAI,IAAI;AAChD,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,KAAiB;AAC7D,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE;AACpC,CAAC,CAAC,EACF,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAiB;IAC9D,OAAO,EAAE,GAAG,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE;AACpD,CAAC,CAAC,EACF,EAAE,CAAC,gCAAgC,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IACvE,OAAO,EAAE,GAAG,KAAK,EAAE,6BAA6B,EAAE,OAAO,EAAE;AAC7D,CAAC,CAAC,EACF,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,KAAiB;IACjE,OAAO;AACL,QAAA,GAAG,KAAK;QACR,aAAa;AACb,QAAA,oBAAoB,EAAE,IAAI;AAC1B,QAAA,sBAAsB,EAAE,KAAK;KAC9B;AACH,CAAC,CAAC,EACF,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAiB;AAC5D,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,GAAG,MAAM,EAAE,EAAE;AACzE,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,KAAiB;IAC1C,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,YAAY,EAAE;YACZ,GAAG,KAAK,CAAC,YAAY;YACrB,WAAW,EAAE,KAAK,CAAC,qBAAqB;AACzC,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,KAAiB;IACrC,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,YAAY,EAAE;YACZ,GAAG,YAAY,CAAC,YAAY;YAC5B,WAAW,EAAE,KAAK,CAAC,qBAAqB;AACzC,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,KAAiB;IACxC,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,OAAO,EAAE,KAAK;QACd,gBAAgB,EAAE,gBAAgB,CAAC,IAAI;KACxC;AACH,CAAC,CAAC,EACF,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,KAAiB;IAC9C,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE;AAC5C,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAiB;AAC5D,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,YAAY,EAAE,EAAE;AAC1E,CAAC,CAAC,EACF,EAAE,CACA,0BAA0B,EAC1B,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,EAAE,KAAiB;IAC7D,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,WAAW,EAAE;YACX,GAAG,KAAK,CAAC,WAAW;AACpB,YAAA,OAAO,EAAE,SAAS;YAClB,YAAY;YACZ,eAAe;YACf,GAAG;AACJ,SAAA;KACF;AACH,CAAC,CACF,EACD,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,EAAE,gBAAgB,EAAE,KAAiB;IACxE,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,WAAW,EAAE;YACX,GAAG,KAAK,CAAC,WAAW;YACpB,gBAAgB;AACjB,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IAC9D,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,WAAW,EAAE;YACX,GAAG,KAAK,CAAC,WAAW;YACpB,OAAO;AACR,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,6BAA6B,EAAE,CAAC,KAAK,KAAiB;IACvD,OAAO,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE;AAC/C,CAAC,CAAC,EACF,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,KAAiB;IAC7D,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE;AAC9C,CAAC,CAAC,EACF,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAK,KAAiB;IAC5C,OAAO,EAAE,GAAG,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE;AAC9C,CAAC,CAAC,EACF,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,KAAiB;AACzC,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;AAChE,CAAC,CAAC,EACF,EAAE,CACA,uBAAuB,EACvB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,oBAAoB,EAAE,KAAiB;IACpE,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,SAAS,EAAE,IAAI;QACf,aAAa;QACb,oBAAoB;KACrB;AACH,CAAC,CACF,EACD,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,KAAiB;IAC1D,OAAO,EAAE,GAAG,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE;AAChD,CAAC,CAAC,EACF,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,KAAiB;IACjD,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE;AACvC,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAiB;IACnD,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE;AACzC,CAAC,CAAC,EACF,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAiB;IACrD,OAAO,EAAE,GAAG,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE;AAC3C,CAAC,CAAC,EACF,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAiB;IACnD,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE;AACzC,CAAC,CAAC,EACF,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,KAAiB;AACvC,IAAA,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;AAC3D,CAAC,CAAC,EACF,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAiB;IACvD,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE;AAC5C,CAAC,CAAC,EACF,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAK,KAAiB;IAC5C,OAAO,EAAE,GAAG,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;AAC5C,CAAC,CAAC,EACF,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAiB;IAC9D,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,OAAO,EAAE,IAAI;AACb,QAAA,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM;AAC9B,QAAA,WAAW,EAAE;YACX,GAAG,KAAK,CAAC,WAAW;AACpB,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,YAAY,EAAE,oBAAoB;AAClC,YAAA,gBAAgB,EAAE,CAAC;AACpB,SAAA;KACF;AACH,CAAC,CAAC,EACF,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IAC1D,OAAO,EAAE,GAAG,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE;AACnD,CAAC,CAAC,EACF,EAAE,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IAC5D,OAAO,EAAE,GAAG,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE;AACrD,CAAC,CAAC,EACF,EAAE,CAAC,8BAA8B,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IACrE,OAAO,EAAE,GAAG,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE;AACnD,CAAC,CAAC,EACF,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAiB;IAC/D,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,qBAAqB,EAAE,OAAO;QAC9B,YAAY,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE;KAC9D;AACH,CAAC,CAAC,EACF,EAAE,CAAC,qBAAqB,EAAE,CAAC,KAAK,KAAiB;;;;;;IAM/C,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,eAAe,EAAE,KAAK;AACtB,QAAA,OAAO,EAAE,KAAK;AACd,QAAA,oBAAoB,EAAE,KAAK;AAC3B,QAAA,aAAa,EAAE,KAAK;AACpB,QAAA,cAAc,EAAE,KAAK;AACrB,QAAA,cAAc,EAAE,KAAK;AACrB,QAAA,iBAAiB,EAAE,KAAK;AACxB,QAAA,YAAY,EAAE,CAAC;AACf,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,6BAA6B,EAAE,IAAI;AACnC,QAAA,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAC/C,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC9C,oBAAoB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;AACvD,QAAA,WAAW,EAAE,EAAE,GAAG,YAAY,CAAC,WAAW,EAAE;AAC5C,QAAA,kBAAkB,EAAE,EAAE;AACtB,QAAA,oBAAoB,EAAE,CAAC;AACvB,QAAA,sBAAsB,EAAE,CAAC;KAC1B;AACH,CAAC,CAAC,EACF,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,KAAiB;IACxC,OAAO,EAAE,GAAG,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE;AACpD,CAAC,CAAC,EACF,EAAE,CAAC,4BAA4B,EAAE,CAAC,KAAK,KAAiB;IACtD,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,cAAc,EAAE,IAAI;AACpB,QAAA,oBAAoB,EAAE,KAAK;AAC3B,QAAA,aAAa,EAAE,KAAK;AACpB,QAAA,aAAa,EAAE,iBAAiB;KACjC;AACH,CAAC,CAAC,EACF,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAK,KAAiB;IACnD,OAAO;AACL,QAAA,GAAG,KAAK;AACR,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,oBAAoB,EAAE,IAAI;AAC1B,QAAA,cAAc,EAAE,IAAI;KACrB;AACH,CAAC,CAAC,EACF,EAAE,CAAC,kBAAkB,EAAE,MAAkB;;;IAGvC,OAAO,EAAE,GAAG,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,EAAE;AACxE,CAAC,CAAC,EACF,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,MAAmB;AACtE,IAAA,GAAG,KAAK;AACR,IAAA,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,GAAG,CAAC;AACpD,IAAA,kBAAkB,EAAE;QAClB,GAAG,KAAK,CAAC,kBAAkB;AAC3B,QAAA,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;AAC3B,KAAA;AACF,CAAA,CAAC,CAAC,EACH,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAiB;AACvD,IAAA,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,GAAG,oBAAoB,CACzD,KAAK,CAAC,kBAAkB,EACxB,EAAE,EACF,GAAG,CACJ;IACD,OAAO;AACL,QAAA,GAAG,KAAK;QACR,kBAAkB;;AAElB,QAAA,sBAAsB,EAAE,KAAK,CAAC,sBAAsB,GAAG,CAAC,GAAG,MAAM;KAClE;AACH,CAAC,CAAC;;AClfG,MAAM,aAAa,GAAG,aAAa,CAAC;AACzC,IAAA,IAAI,EAAE,eAAe;AACrB,IAAA,OAAO,EAAE,aAAa;AACvB,CAAA;;MCMY,UAAU,CAAA;AAUrB,IAAA,WAAA,GAAA;AATmB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ;AAC9B,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;AAC1B,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAExC,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC;AAChB,aAAA,MAAM,CAAC,aAAa,CAAC,qBAAqB;AAC1C,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;AAGtC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AAC7B,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;AACpB,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAC1B,QAAA,CAAC,CAAC;IACJ;AACD;;AC1BK,SAAU,aAAa,CAE3B,GAA8B,EAAA;AAE9B,IAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;AAChC;;ACJM,SAAU,aAAa,CAA0B,GAAkB,EAAA;AACvE,IAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;;AAGxB;;;AAGK;AACP;;ACTM,SAAU,mBAAmB,CAEjC,GAAmC,EAAA;IAEnC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AACvC;;SCJgB,oBAAoB,GAAA;;;IAGlC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;AACtC;;ACHM,SAAU,uBAAuB,CAErC,GAAqB,EAAA;AAErB,IAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,0BAA0B,CAAC;AACzB,QAAA,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU;AACpC,QAAA,eAAe,EAAE,GAAG,CAAC,OAAO,CAAC,eAAe;AAC5C,QAAA,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG;AAC5B,KAAA,CAAC,CACH;AACH;;SCbgB,WAAW,GAAA;AACzB,IAAA,IAAI,CAAC,IAAI,CACP,IAAI,CAAC,SAAS,CAAC;AACb,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,MAAM,EAAE,OAAO;AAChB,KAAA,CAAC,CACH;AACH;;ACLM,SAAU,kBAAkB,CAEhC,GAAuB,EAAA;AAEvB,IAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AACjB;;ACLM,SAAU,aAAa,CAA0B,GAAW,EAAA;AAChE,IAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,IAAA,OAAO,IAAI;AACb;;ACIA,MAAM,SAAS,GAAG;IAChB,mBAAmB;IACnB,sCAAsC;IACtC,mCAAmC;IACnC,wCAAwC;IACxC,oCAAoC;CACrC;AAEK,SAAU,cAAc,CAA0B,CAAa,EAAA;AACnE,IAAA,MAAM,OAAO,GAAG,CAAA,kBAAA,EAAqB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA,GAAA,EAAM,CAAC,CAAC,MAAM,EAAE;AAC3E,IAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IACpB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;IAE5C,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;QAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IACvC;AACF;;ACtBM,SAAU,cAAc,CAA0B,CAAQ,EAAA;AAC9D,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,UAAA,EAAa,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA,CAAE,CAAC;AAE7C,IAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;QACf,MAAM,EAAE,gBAAgB,CAAC,cAAc;AACvC,QAAA,OAAO,EAAE,iBAAiB;AAC3B,KAAA,CAAC,CACH;AACH;;ACXM,SAAU,gBAAgB,CAE9B,CAA8B,EAAA;AAE9B,IAAA,MAAM,UAAU,GAAG,CAAC,IAAY,KAAI;;QAElC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AAC5B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;AACzB,IAAA,CAAC;AAED,IAAA,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE;AAC9B,QAAA,IAAI;AACF,YAAA,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QACpB;QAAE,OAAO,GAAG,EAAE;AACZ,YAAA,MAAM,CAAC,IAAI,CAAC,kDAAkD,EAAE,GAAG,CAAC;QACtE;IACF;AAAO,SAAA,IAAI,CAAC,CAAC,IAAI,YAAY,IAAI,EAAE;AACjC,QAAA,CAAC,CAAC;AACC,aAAA,IAAI;aACJ,IAAI,CAAC,UAAU;AACf,aAAA,KAAK,CAAC,CAAC,GAAG,KACT,MAAM,CAAC,IAAI,CAAC,gDAAgD,EAAE,GAAG,CAAC,CACnE;IACL;AACF;;SCxBgB,aAAa,GAAA;IAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;IACzC,IAAI,CAAC,iBAAiB,EAAE;AAC1B;;ACHA;;AAEG;AACI,MAAM,iBAAiB,GAC5B,CAAC,MAA2B,KAC5B,CAAC,OAAO,KACN,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAC/C,IAAI,CACF,CAAC,GAAG,EAAE,KAAK,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAC3D,CAAC,CACF;;ACbP;AACA;AACA,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC;AAExC,SAAU,UAAU,CAAC,OAAoB,EAAA;AAC7C,IAAA,IAAI;AACF,QAAA,OAAO,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;IACrC;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,EAAE;IACX;AACF;;MCWa,eAAe,CAAA;AAG1B;;;;;;AAMG;IACH,WAAA,CACY,6BAAA,GAAgC,EAAE,EAClC,0BAAA,GAA6B,EAAE,EAC/B,mBAAA,GAAsB,GAAG,EACzB,UAAA,GAAa,GAAG,EAAA;QAHhB,IAAA,CAAA,6BAA6B,GAA7B,6BAA6B;QAC7B,IAAA,CAAA,0BAA0B,GAA1B,0BAA0B;QAC1B,IAAA,CAAA,mBAAmB,GAAnB,mBAAmB;QACnB,IAAA,CAAA,UAAU,GAAV,UAAU;QAbZ,IAAA,CAAA,WAAW,GAAa,EAAE;IAcjC;IAEH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;IAC7B;AAEA,IAAA,MAAM,CAAC,IAAoB,EAAA;QACzB,IAAI,CAAC,KAAK,EAAE;AACZ,QAAA,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,UAAU;AACpD,QAAA,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,OAAO;IAChD;AAEA;;;;AAIG;AACH,IAAA,QAAQ,CAAC,YAAoB,EAAA;QAC3B,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,EAAE;AAC3C,YAAA,OAAO,EAAyB;QAClC;AACA,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM;AAE7C,QAAA,IAAI,aAAa,GAAG,IAAI,CAAC,mBAAmB,EAAE;AAC5C,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;QAC1B;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC;AAEnC,QAAA,IAAI,aAAa,GAAG,IAAI,CAAC,mBAAmB,EAAE;YAC5C,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,mBAAmB;AAClD,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;QAClE;AAEA,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC;AAC9D,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;AACrD,QAAA,MAAM,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC;AAClD,QAAA,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC;QAEpD,MAAM,cAAc,GAAG,MAAM,CAC3B,CAAC,EACD,GAAG,EACH,CAAC,CAAC,eAAe,GAAG,gBAAgB,IAAI,eAAe,IAAI,GAAG,CAC/D;AAED,QAAA,MAAM,SAAS,GAAG,cAAc,IAAI,IAAI,CAAC,0BAA0B;AACnE,QAAA,IAAI,cAAc,IAAI,IAAI,CAAC,6BAA6B,EAAE;YACxD,OAAO;AACL,gBAAA,MAAM,EAAE;oBACN,6BAA6B,EAAE,IAAI,CAAC,6BAA6B;oBACjE,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;oBAC3D,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;oBAC7C,UAAU,EAAE,IAAI,CAAC,UAAU;AAC5B,iBAAA;AACD,gBAAA,cAAc,EAAE,IAAI;gBACpB,cAAc;AACd,gBAAA,YAAY,EAAE,gBAAgB;gBAC9B,OAAO,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ;AACrC,gBAAA,OAAO,EAAE,CAAA,gCAAA,EAAmC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,QAAA,EAAW,eAAe,CAAA,IAAA,EAAO,gBAAgB,CAAA,CAAA,CAAG;aAC1H;QACH;QAEA,OAAO;AACL,YAAA,MAAM,EAAE;gBACN,6BAA6B,EAAE,IAAI,CAAC,6BAA6B;gBACjE,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;gBAC3D,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;gBAC7C,UAAU,EAAE,IAAI,CAAC,UAAU;AAC5B,aAAA;AACD,YAAA,cAAc,EAAE,KAAK;YACrB,cAAc;AACd,YAAA,YAAY,EAAE,gBAAgB;AAC9B,YAAA,OAAO,EAAE,MAAM;AACf,YAAA,OAAO,EAAE,aAAa;SACvB;IACH;AACD;;AChHM,MAAM,cAAc,GAAG,MAAK;IACjC,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC3C;;ACFA,MAAM,UAAU,GAAgD;AAC9D,IAAA,OAAO,EACL,wKAAwK;CAC3K;AAEK,SAAU,kBAAkB,CAAC,IAAmB,EAAA;AACpD,IAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,UAAU,CAAC,CAAA,IAAA,EAAO,IAAI,CAAA,CAAE,CAAC;AAClC;;ACEA,MAAM,cAAc,GAAG,IAAI;AAC3B,MAAM,0BAA0B,GAAG,GAAG;AAEtC;;;AAGG;AACI,MAAM,eAAe,GAC1B,MAAwC,CAAC,MAAM,KAC7C,MAAM,CAAC,IAAI,CAACA,KAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;AAEvE;;;;AAIG;MACU,qBAAqB,GAChC,MAAwC,CAAC,MAAM,KAC7C,MAAM,CAAC,IAAI,CACT,SAAS,EAAE,EACX,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EACrC,QAAQ,EAAE,EACV,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAI;AACzB,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc;AACjE,IAAA,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC;AAC/D,IAAA,IAAI,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE;AACtB,QAAA,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;IACvB;AACA,IAAA,OAAO,gBAAgB,CACrB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,0BAA0B,CAAC,CACzC;AACH,CAAC,CAAC,EACF,eAAe,EAAE;AAGvB;;;;;;;AAOG;AACI,MAAM,gBAAgB,GAAG,CAC9B,KAAa,EACb,GAAW,EACX,QAAgB,KACM;AACtB,IAAA,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,EAAE;AAC/C,IAAA,OAAO,QAAQ,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAC9CA,KAAG,CAAC,MACF,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,QAAQ,CAAC,CACrE,EACD,oBAAoB,EAAE,EACtB,SAAS,CAAC,CAAC,QAAQ,KAAK,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,EAC3CA,KAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAC9C;AACH;;AC/DO,MAAM,uBAAuB,GAAG,CACrC,YAAA,GAAqC,OAAO,EAC5C,WAA+B,EAC/B,KAA6B,KAC3B;AACF,IAAA,IAAI;QACF,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CACnC,kBAAkB,CACC;QACrB,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC;AAEhD,QAAA,MAAM,CAAC,KAAK;AACV,YAAA,YAAY,KAAK;kBACb,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,WAAW,IAAI;kBACtC,aAAa;AACnB,QAAA,MAAM,CAAC,MAAM;AACX,YAAA,YAAY,KAAK;kBACb,KAAK,EAAE,MAAM,IAAI,KAAK,EAAE,YAAY,IAAI;kBACxC,cAAc;AAEpB,QAAA,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QAEvD,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,WAAW,CAAW;IACjE;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;;ACnCA;;;;;;;AAOG;AACG,UAAW,YAAY,CAAC,IAAc,EAAA;IAC1C,IAAI,KAAK,GAAG,CAAC;IACb,OAAO,IAAI,EAAE;QACX,MAAM,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC;AACF;;MCXa,cAAc,CAAA;AAMzB;;;;;AAKG;AACH,IAAA,WAAA,CACE,eAAuB,EACvB,kBAA0B,EAC1B,YAAoB,EACpB,gBAAwB,EAAA;AAExB,QAAA,IAAI,CAAC,QAAQ,GAAG,eAAe;AAC/B,QAAA,IAAI,CAAC,WAAW,GAAG,kBAAkB;AACrC,QAAA,IAAI,CAAC,YAAY,GAAG,YAAY;AAChC,QAAA,IAAI,CAAC,gBAAgB,GAAG,gBAAgB;IAC1C;AAEA;;;AAGG;AACH,IAAA,MAAM,CAAC,WAAmB,EAAA;;;AAGxB,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ;;QAEvC,MAAM,oBAAoB,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY;;;AAIjE,QAAA,MAAM,UAAU,GAAG,WAAW,GAAG,iBAAiB;;AAElD,QAAA,MAAM,oBAAoB,GAAG,oBAAoB,GAAG,IAAI,CAAC,gBAAgB;;AAEzE,QAAA,MAAM,UAAU,GAAG,oBAAoB,GAAG,oBAAoB;;QAG9D,IAAI,CAAC,QAAQ,GAAG,iBAAiB,GAAG,UAAU,GAAG,UAAU;;QAE3D,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,UAAU,IAAI,oBAAoB;QAE1D,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA,IAAA,MAAM,CAAC,IAAoB,EAAA;QACzB,MAAM,EACJ,sBAAsB,EACtB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,GACjB,GAAG,IAAI;AACR,QAAA,IAAI,CAAC,QAAQ,GAAG,sBAAsB;AACtC,QAAA,IAAI,CAAC,WAAW,GAAG,sBAAsB;AACzC,QAAA,IAAI,CAAC,YAAY,GAAG,YAAY;AAChC,QAAA,IAAI,CAAC,gBAAgB,GAAG,gBAAgB;IAC1C;AACD;;MCjEY,cAAc,CAAA;AAA3B,IAAA,WAAA,GAAA;QACE,IAAA,CAAA,eAAe,GAAkB,IAAI;QACrC,IAAA,CAAA,eAAe,GAAkB,IAAI;QACrC,IAAA,CAAA,UAAU,GAAkB,IAAI;QAChC,IAAA,CAAA,iBAAiB,GAAkB,IAAI;QACvC,IAAA,CAAA,oBAAoB,GAAkB,IAAI;QAC1C,IAAA,CAAA,oBAAoB,GAAkB,IAAI;QAC1C,IAAA,CAAA,uBAAuB,GAAkB,IAAI;IA0B/C;IAxBE,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI;AAC3B,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI;AAC3B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC7B,QAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;AAChC,QAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;AAChC,QAAA,IAAI,CAAC,uBAAuB,GAAG,IAAI;IACrC;;AAGA,IAAA,YAAY,CAAC,SAAc,EAAA;AACzB,QAAA,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,aAAa;AAC9C,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,QAAQ;AACpC,QAAA,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,eAAe;AAClD,QAAA,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,kBAAkB;AACxD,QAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE;IACxC;AAEA,IAAA,wBAAwB,CAAC,WAAmB,EAAA;AAC1C,QAAA,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,EAAE;YACxC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;QACxD;IACF;AACD;;AC/BK,SAAU,WAAW,CAAC,cAAsB,EAAA;IAChD,MAAM,QAAQ,GAAG,EAAE;IACnB,MAAM,KAAK,GAAG,EAAE;IAEhB,IAAI,OAAO,GAAY,MAAM;AAC7B,IAAA,IAAI,cAAc,GAAG,KAAK,EAAE;QAC1B,OAAO,GAAG,KAAK;IACjB;AAAO,SAAA,IAAI,cAAc,GAAG,QAAQ,EAAE;QACpC,OAAO,GAAG,QAAQ;IACpB;AACA,IAAA,OAAO,OAAO;AAChB;;ACbA;;;;;;;;;;;;AAYG;AACG,SAAU,aAAa,CAAC,KAAiB,EAAA;IAC7C,MAAM,UAAU,GAAG,MAAM;IACzB,IAAI,MAAM,GAAG,EAAE;AACf,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,UAAU,EAAE;AACjD,QAAA,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC;IACrE;AACA,IAAA,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB;;AClBM,SAAU,kBAAkB,CAChC,IAAiB,EAAA;AAEjB,IAAA,OAAO,IAAI,UAAU,CAAC,CAAC,UAAU,KAAI;AACnC,QAAA,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,KACjD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CACzB;AACD,QAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;QAEtB,OAAO,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;AACvC,IAAA,CAAC,CAAC;AACJ;;ACbA;;;AAGG;AAEH;;;;;;;;;;;;;AAaG;AACG,SAAU,QAAQ,CAAC,KAAa,EAAA;AACpC,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;AACxC;;AChBA,MAAM,cAAc,GAAG,aAAa,GAAG,cAAc;AACrD,MAAM,UAAU,GAAG,aAAa,GAAG,CAAC,IAAI,cAAc,GAAG,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACG,SAAU,qBAAqB,CAAC,MAOrC,EAAA;AACC,IAAA,MAAM,EACJ,UAAU,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,GACd,GAAG,MAAM;AAEV,IAAA,MAAM,QAAQ,GAAG;QACf,CAAC,EAAE,cAAc,GAAG,UAAU;QAC9B,CAAC,EAAE,eAAe,GAAG,UAAU;KAChC;IACD,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc;AAE7D,IAAA,MAAM,qBAAqB,GAAG,gBAAgB,CAC5C,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,EAC/C,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAE,CAC5B;AAED,IAAA,IAAI,CAAC,GAAG,qBAAqB,CAAC,CAAC;AAC/B,IAAA,IAAI,CAAC,GAAG,qBAAqB,CAAC,CAAC;AAE/B,IAAA,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE;;;;AAIrB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,QAAA,CAAC,GAAG,CAAC,GAAG,WAAW;AACnB,QAAA,CAAC,GAAG,CAAC,GAAG,WAAW;IACrB;AAEA,IAAA,MAAM,GAAG,GAAG,gBAAgB,CAAC,qBAAqB,EAAE;QAClD,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC1B,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC1B,CAAC;QACD,CAAC;AACF,KAAA,CAAC;IAEF,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACvB,IAAA,OAAO,GAAG;AACZ;AAEA;;;;;;;;;;;;;;;;;;AAkBG;AACG,SAAU,wBAAwB,CAAC,MAKxC,EAAA;IACC,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,MAAM;AAE7E,IAAA,MAAM,QAAQ,GAAG;QACf,CAAC,EAAE,cAAc,GAAG,UAAU;QAC9B,CAAC,EAAE,eAAe,GAAG,UAAU;KAChC;IACD,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc;AAE7D,IAAA,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;AAClB,IAAA,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;AAElB,IAAA,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE;;;;AAIrB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,QAAA,CAAC,GAAG,CAAC,GAAG,WAAW;AACnB,QAAA,CAAC,GAAG,CAAC,GAAG,WAAW;IACrB;AAEA,IAAA,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE;AAC9E;;AC9HA;;;AAGG;AACI,MAAM,qBAAqB,GAAG,cAAc,CACjD,aAAa,CAAC,0BAA0B,EACxC,aAAa,CAAC,4BAA4B,EAC1C,CAAC,OAAO,EAAE,SAAS,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC;MAGhD,iCAAiC,GAAG,cAAc,CAC7D,aAAa,CAAC,0BAA0B,EACxC,CAAC,oBAAoB,KAAK,oBAAoB,EAAE,OAAO,IAAI,IAAI;MAEpD,yCAAyC,GAAG,cAAc,CACrE,aAAa,CAAC,0BAA0B,EACxC,CAAC,oBAAoB,KAAK,oBAAoB,EAAE,QAAQ,IAAI,IAAI;AAE3D,MAAM,wBAAwB,GAAG,cAAc,CACpD,aAAa,CAAC,iBAAiB,EAC/B,CAAC,WAAW,MAAM,WAAW,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;AAEhE,MAAM,0BAA0B,GAAG,cAAc,CACtD,aAAa,CAAC,iBAAiB,EAC/B,CAAC,WAAW,KACV,WAAW,EAAE;MACT,WAAW,CAAC,QAAQ,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,GAAG;MACnD,KAAK;MAEA,gCAAgC,GAAG,cAAc,CAC5D,iCAAiC,EACjC,wBAAwB,EACxB,CAAC,gBAAgB,EAAE,aAAa,KAC9B,gBAAgB,IAAI,aAAa,IAAI,IAAI;AAEtC,MAAM,kBAAkB,GAAG,cAAc,CAC9C,aAAa,CAAC,kBAAkB,EAChC,CAAC,MAAM,KAAK,MAAM;AAEb,MAAM,iBAAiB,GAAG,cAAc,CAC7C,kBAAkB,EAClB,CAAC,MAAM,KAAK,MAAM,EAAE,WAAW,IAAI,mBAAmB;MAE3C,sBAAsB,GAAG,cAAc,CAClD,aAAa,CAAC,eAAe,EAC7B,CAAC,IAAI,KAAK,IAAI,EAAE,MAAM,GAAG,CAAC;AAErB,MAAM,iBAAiB,GAAG,cAAc,CAC7C,kBAAkB,EAClB,CAAC,MAAM,KAAK,MAAM,EAAE,SAAS;AAExB,MAAM,wBAAwB,GAAG,cAAc,CACpD,aAAa,CAAC,qBAAqB,EACnC,aAAa,CAAC,4BAA4B,EAC1C,CAAC,eAAe,EAAE,sBAAsB,KACtC,CAAC,eAAe,IAAI,CAAC,sBAAsB;AAExC,MAAM,gBAAgB,GAAG,cAAc,CAC5C,wBAAwB,EACxB,aAAa,CAAC,mBAAmB,EACjC,CAAC,SAAS,EAAE,aAAa,KAAK,CAAC,SAAS,IAAI,CAAC,aAAa;AAErD,MAAM,yBAAyB,GAAG,cAAc,CACrD,aAAa,CAAC,YAAY,EAC1B,aAAa,CAAC,iBAAiB,EAC/B,CAAC,IAAI,EAAE,QAAQ,KAAI;IACjB,MAAM,IAAI,GAAa,EAAE;IACzB,IAAI,IAAI,EAAE;AACR,QAAA,IAAI,CAAC,IAAI,CACP,CAAA,EAAG,IAAI,CAAC,aAAa,CAAA,EAAA,EAAK,IAAI,CAAC,UAAU,CAAA,EAAA,EAAK,IAAI,CAAC,YAAY,CAAA,CAAE,CAClE;QACD,IAAI,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,IAAI,CAAC,eAAe,CAAA,CAAE,CAAC;AACxD,QAAA,IAAI,CAAC,IAAI,CAAC,CAAA,KAAA,EAAQ,IAAI,CAAC,UAAU,CAAA,EAAG,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;IACvD;IACA,IAAI,CAAC,IAAI,CAAC,CAAA,SAAA,EAAY,QAAQ,CAAC,UAAU,CAAA,CAAE,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,CAAA,IAAA,EAAO,QAAQ,CAAC,KAAK,CAAA,CAAE,CAAC;AAClC,IAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,CAAC;AAEI,MAAM,sBAAsB,GAAG,cAAc,CAClD,aAAa,CAAC,2BAA2B,EACzC,aAAa,CAAC,kBAAkB,EAChC,CAAC,QAAQ,EAAE,MAAM,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAEvC,MAAM,sBAAsB,GAAG,cAAc,CAClD,aAAa,CAAC,mBAAmB,EACjC,aAAa,CAAC,0BAA0B,EACxC,aAAa,CAAC,qBAAqB,EACnC,CAAC,aAAa,EAAE,oBAAoB,EAAE,eAAe,KACnD,aAAa,IAAI,oBAAoB,IAAI,eAAe;AAErD,MAAM,2BAA2B,GAAG,cAAc,CACvD,sBAAsB,EACtB,CAAC,cAAc,KAAK,CAAC,cAAc;AAErC;;;;;;;;;;AAUG;AACI,MAAM,mBAAmB,GAAG,cAAc,CAC/C,aAAa,CAAC,mCAAmC,EACjD,qBAAqB,EACrB,aAAa,CAAC,iBAAiB,EAC/B,aAAa,CAAC,0BAA0B,EACxC,CACE,6BAA6B,EAC7B,eAAe,EACf,WAAW,EACX,oBAAoB,KAClB;AACF,IAAA,MAAM,cAAc,GAAG,wBAAwB,GAAG,GAAG;IACrD,MAAM,wBAAwB,GAAG,mCAAmC;AAEpE,IAAA,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,IAAI,CACtD,WAAW,EAAE,KAAK,IAAI,EAAE,CACzB;;;;;;;;IASD,MAAM,iBAAiB,GAAG;AACxB,UAAE;AACF,UAAE;AACA,eAAG,WAAW,EAAE,gBAAgB,IAAI,CAAC;cACnC,CAAC,6BAA6B,IAAI,CAAC,IAAI,GAAG;;AAGhD,IAAA,MAAM,UAAU,GAAG,WAAW,EAAE;UAC5B,cAAc,GAAG;UACjB,cAAc;;IAGlB,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,iBAAiB,CAAC;AACpE,IAAA,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,eAAe,CAAC;IAE7D,OAAO,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC;AACvD,CAAC;AAEH;AACO,MAAM,wBAAwB,GAAG,cAAc,CACpD,aAAa,CAAC,YAAY,EAC1B,CAAC,IAAI,KAAK,IAAI,EAAE,YAAY;AAE9B;MACa,4BAA4B,GAAG,cAAc,CACxD,aAAa,CAAC,kBAAkB,EAChC,aAAa,CAAC,uBAAuB,EACrC,CAAC,4BAA4B,EAAE,gBAAgB,MAAM;IACnD,4BAA4B;IAC5B,gBAAgB;AACjB,CAAA,CAAC;AAEJ;AACO,MAAM,2CAA2C,GAAG,cAAc,CACvE,aAAa,CAAC,oBAAoB,EAClC,aAAa,CAAC,0BAA0B,EACxC,CAAC,cAAc,EAAE,sBAAsB,KACrC,cAAc,IAAI,sBAAsB;;MC/J/B,yBAAyB,CAAA;AAPtC,IAAA,WAAA,GAAA;AAQE,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;AAC9B,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AACb,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CACrD,aAAa,CAAC,qBAAqB,CACpC;AAiBF,IAAA;AArBC,IAAA,UAAU;AACV,IAAA,MAAM;IAKN,8BAA8B,GAAA;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE;AAC7B,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAClB,gBAAgB,CAAC;gBACf,MAAM,EAAE,gBAAgB,CAAC,cAAc;AACvC,gBAAA,OAAO,EAAE,uBAAuB;AACjC,aAAA,CAAC,CACH;QACH;QACA,IAAI,CAAC,KAAK,EAAE;IACd;IAEQ,KAAK,GAAA;AACX,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;IACzB;8GArBW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECdtC,64CAiCA,EAAA,MAAA,EAAA,CAAA,oXAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDrBY,qBAAqB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,WAAA,EAAA,YAAA,EAAA,WAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEpB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAPrC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,mBAGjB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,qBAAqB,CAAC,EAAA,QAAA,EAAA,64CAAA,EAAA,MAAA,EAAA,CAAA,oXAAA,CAAA,EAAA;;;AEC5B,MAAO,uBAAwB,SAAQ,UAAU,CAAA;AAuBrD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QAvBQ,IAAA,CAAA,KAAK,GAAW,mBAAmB;QAC5C,IAAA,CAAA,YAAY,GAAkC,EAAE;QAChD,IAAA,CAAA,YAAY,GAAG,KAAK;QACpB,IAAA,CAAA,WAAW,GAAG,IAAI;QAClB,IAAA,CAAA,qBAAqB,GAAG,CAAC;QAazB,IAAA,CAAA,QAAQ,GAAc,EAAE;AAEf,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAC/B,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAIvE,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IACE,CAAC,IAAI,CAAC,YAAY,EAAE,wBAAwB;AAC5C,YAAA,IAAI,CAAC,YAAY,EAAE,UAAU,EAC7B;YACA;QACF;QAEA,IAAI,CAAC,KAAK,EAAE;AACZ,QAAA,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI;AAChE,QAAA,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI;QAC3D,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;QAClD,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;AAC7C,QAAA,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW;AACtB,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC1B,QAAA,CAAC,CAAC;IACN;AAEA,IAAA,IAAY,OAAO,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,GAAG,EAAE;IACnB;AAEA,IAAA,IAAY,WAAW,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS;IACtC;AAEA,IAAA,IAAY,cAAc,GAAA;AACxB,QAAA,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IAC/D;AAEA,IAAA,QAAQ,CAAC,cAA6B,EAAA;QACpC,IAAI,CAAC,eAAe,EAAE;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;IAChD;AAEA,IAAA,iBAAiB,CAAC,UAAkB,EAAA;AAClC,QAAA,MAAM,GAAG,GAAG;AACV,YAAA,OAAO,EAAE,UAAU;YACnB,UAAU;SACX;AACD,QAAA,MAAM,MAAM,GAAG;YACb,kBAAkB,EAAE,IAAI,CAAC,WAAW;SACnB;QACnB,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC;AACjD,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;IACrB;IAEA,gBAAgB,CACd,UAAkB,EAClB,KAAK,GAAG,KAAK,EACb,QAAA,GAA0D,EAAE,EAC5D,aAA6B,EAAA;QAE7B,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;QACrD,IAAI,CAAC,eAAe,EAAE;YACpB;QACF;QACA,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC,WAAW;AAErE;;AAEG;QACH,MAAM,iBAAiB,GAAG,eAAe,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS;QACtE,IAAI,YAAY,GAAG,EAAE;AAErB,QAAA,MAAM,CAAC,GAAG,aAAa,EAAE,gBAAgB;QACzC,IAAI,CAAC,EAAE;AACL,YAAA,YAAY,GAAG;gBACb,mBAAmB,EACjB,CAAC,CAAC,iBAAiB,CAAC,SAAS,GAAG,CAAC,CAAC,gBAAgB,CAAC,SAAS;gBAE9D,uBAAuB,EACrB,CAAC,CAAC,iBAAiB,CAAC,SAAS,GAAG,CAAC,CAAC,cAAc,CAAC,SAAS;gBAE5D,eAAe,EACb,CAAC,CAAC,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,WAAW;gBAE5D,gBAAgB,EAAE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,iBAAiB,CAAC,SAAS;aAC/D;QACH;AAEA,QAAA,MAAM,MAAM,GAAG;YACb,kBAAkB,EAAE,IAAI,CAAC,WAAW;YACpC,iBAAiB;YACjB,kBAAkB;AAClB,YAAA,GAAG,YAAY;SACE;AAEnB,QAAA,IAAI,CAAC,gBAAgB,CACnB,aAAa,EACb,EAAE,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,EACxC,MAAM,EACN,aAAa,CACd;QACD,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;QACtC;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,IAAI,GAAG,YAAY,EAAE;AAC1B,QAAA,IAAI,CAAC,qBAAqB,GAAG,CAAC;AAC9B,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;AACxB,QAAA,IAAI,CAAC,YAAY,GAAG,EAAE;IACxB;AAEQ,IAAA,gBAAgB,CACtB,IAAmB,EACnB,cAAuC,EACvC,cAA8B,EAC9B,aAA6B,EAAA;QAE7B,IAAI,CAAC,QAAQ,CAAC;YACZ,IAAI;AACJ,YAAA,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,EAAE;YACnD,cAAc;YACd,aAAa;YACb,cAAc;AACf,SAAA,CAAC;IACJ;AAEQ,IAAA,SAAS,CAAC,OAA+B,EAAA;AAC/C,QAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG;YACtC,WAAW,EAAE,IAAI,CAAC,OAAO;YACzB,OAAO;SACR;IACH;AAEQ,IAAA,IAAI,CAAC,OAAkB,EAAA;AAC7B,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,KAAK,IAAI,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE;YACxE;QACF;AACA,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO;AAC5B,QAAA,MAAM,GAAG,GAAmB;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,EAAE,EAAE,SAAS,CAAC,SAAS;YACvB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE;YAC5C,IAAI,EAAE,QAAQ,CAAC,IAAI;AACnB,YAAA,UAAU,EAAE;AACV,gBAAA,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;AAC1B,gBAAA,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAC5B,UAAU,EAAE,MAAM,CAAC,gBAAgB;AACpC,aAAA;YACD,OAAO;SACR;AACD,QAAA,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,qBAAqB;AACnE,QAAA,IAAI,CAAC;aACF,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,wBAAwB,IAAI,EAAE,EAAE,GAAG;AAC3D,aAAA,IAAI,CACH,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,EAC1B,IAAI,CAAC,CAAC,CAAC;aAER,SAAS,CAAC,MAAK;YACd,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAClC,CAAC,CAAC,KAAK,CAAC,CAAC,qBAAqB,GAAG,SAAS,CAC3C;AACH,QAAA,CAAC,CAAC;IACN;AAEA;;;;;;AAMG;IACO,eAAe,GAAA;AACvB,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CACH,MAAM,CAAC,qBAAqB,CAAC,EAC7B,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAI;AAClB,YAAA,MAAM,QAAQ,GACZ,iBAAiB,IAAI,IAAI,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI;AACzD,YAAA,OAAO,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;QACrC,CAAC,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAEzB,aAAA,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,KAAI;AACtB,YAAA,MAAM,QAAQ,GACZ,iBAAiB,IAAI,IAAI,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI;AACzD,YAAA,MAAM,aAAa,GACjB,WAAW,IAAI,IAAI,GAAI,IAAI,EAAE,SAA2B,GAAG,SAAS;AACtE,YAAA,MAAM,UAAU,GAAG,QAAQ,EAAE,UAAU,IAAI,EAAE;YAE7C,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,CAAC;YAC3D,IAAI,CAAC,mBAAmB,EAAE;AAC5B,QAAA,CAAC,CAAC;IACN;AAEQ,IAAA,QAAQ,CAAC,OAAgB,EAAA;AAC/B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B;AAEA;;;;;;;;AAQG;IACK,mBAAmB,GAAA;QACzB,MAAM,IAAI,GAAW,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;QACzC,MAAM,aAAa,GAAa,EAAE;AAClC,QAAA,MAAM,CAAC,OAAO,CAAgB,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CACtD,CAAC,CAAC,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,KAAI;YAChC,IAAI,IAAI,GAAG,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE;AAC1C,gBAAA,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC;AACF,QAAA,CAAC,CACF;AAED,QAAA,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,KAAI;AACnC,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;AACtC,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;;;;AASG;IACK,OAAO,CAAC,cAA6B,EAAE,IAA0B,EAAA;QACvE,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE;AACnD,QAAA,MAAM,MAAM,GAAG;YACb,kBAAkB,EAAE,IAAI,CAAC,WAAW;SACnB;AACnB,QAAA,IAAI,CAAC,gBAAgB,CACnB,aAAa,EACb;AACE,YAAA,GAAG,GAAG;AACN,YAAA,UAAU,EAAE,CAAA,EAAG,GAAG,CAAC,UAAU,CAAA,CAAE;SAChC,EACD,MAAM,CACP;AACD,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QACnB,cAAc,CAAC,GAAG,CAAC;IACrB;8GAtRW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cADV,MAAM,EAAA,CAAA,CAAA;;2FACnB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCNrB,cAAc,CAAA;AACzB,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChD;AACA;;;AAGG;AACH,IAAA,UAAU,CAAC,KAAc,EAAA;QACvB,IAAI,KAAK,EAAE;YACT,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnD;aAAO;AACL,YAAA,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC;QACpC;IACF;8GAdW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAd,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cAFb,MAAM,EAAA,CAAA,CAAA;;2FAEP,cAAc,EAAA,UAAA,EAAA,CAAA;kBAH1B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCeY,kBAAkB,CAAA;AAiB7B,IAAA,WAAA,GAAA;AAhBQ,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACZ,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;;;AAI/B,QAAA,IAAA,CAAA,iBAAiB,GAAG,IAAI,eAAe,EAAE;AAEnD,QAAA,IAAA,CAAA,MAAM,GAAG;AACd,YAAA,UAAU,EAAE,CAAC;AACb,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,qBAAqB,EAAE,EAAE;AACzB,YAAA,UAAU,EAAE,IAAI;SACjB;AAGC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACjE;IAEO,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,IAAI,EAAE,EAAA;;;;;QAKvE,OAAO,KAAK,CAAC,MAAK;YAChB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;;;;;;AAO3C,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE;YACtC,IAAI,MAAM,EAAE;;;;;AAKV,gBAAA,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CACpB,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC,EACpD,GAAG,CAAC,CAAC,IAAI,KACP,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,cAAc,CAAC;oBACb,MAAM,EAAE,IAAI,CAAC,WAAW;oBACxB,OAAO,EAAE,IAAI,CAAC,MAAM;AACrB,iBAAA,CAAC,CACH,CACF,EACDA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,CAChC;YACH;YAEA,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,IAAI,CAC1C,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC,EACpD,SAAS,CAAC,CAAC,SAAwB,KAAK,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,EACtE,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,EAC1B,MAAM,CAAC,YAAY,CAAC;;;;AAIpB,YAAA,GAAG,CAAC,CAAC,IAAI,KAAI;AACX,gBAAA,IAAI,IAAI,EAAE,WAAW,EAAE;oBACrB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC;gBACvD;AACF,YAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,IAAI,KACP,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,cAAc,CAAC;AACb,gBAAA,MAAM,EAAE,IAAI,EAAE,WAAW,IAAI,EAAE;AAC/B,gBAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AAC5B,aAAA,CAAC,CACH,CACF,EACDA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,WAAW,CAAC,CACjC;AACH,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;;;;AASG;IACH,gBAAgB,GAAA;AACd,QAAA,IAAI;YACF,IAAI,OAAO,YAAY,KAAK,WAAW;AAAE,gBAAA,OAAO,IAAI;YACpD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,qBAAqB,CAAC;AACvD,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,IAAI;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAI5B;AACD,YAAA,IACE,OAAO,MAAM,EAAE,WAAW,KAAK,QAAQ;AACvC,gBAAA,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7B,gBAAA,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ;gBAC7B,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,wBAAwB,EAClD;AACA,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QACnE;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;AAEQ,IAAA,iBAAiB,CAAC,UAAkB,EAAE,MAAA,GAAmB,EAAE,EAAA;AACjE,QAAA,IAAI;YACF,IAAI,OAAO,YAAY,KAAK,WAAW;gBAAE;YACzC,YAAY,CAAC,OAAO,CAClB,qBAAqB,EACrB,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CACpE;QACH;AAAE,QAAA,MAAM;;QAER;IACF;AAEA;;;;;;;;;;;;AAYG;IACI,wBAAwB,CAC7B,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,IAAI,EAAE,EAAA;QAEvD,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CACvD,SAAS,CAAC,CAAC,SAAwB,KACjC,IAAI,CACF,IAAI,CAAC,eAAe,CAClB,SAAS,CAAC,OAAO,EACjB,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAC9C,CACF,CACF,EACD,GAAG,CAAC,CAAC,MAAM,KAAI;YACb,IAAI,MAAM,EAAE;gBACV,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC;YAC3D;AACF,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAC3B;IACH;AAEQ,IAAA,MAAM,eAAe,CAAC,SAAmB,EAAE,cAAsB,EAAA;AACvE,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM;QAC5C,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,CAAC;QACvD,IAAI,MAAM,CAAC,OAAO;AAAE,YAAA,OAAO,IAAI;QAE/B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC;AAClE,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,KAAI;AAClE,YAAA,MAAM,SAAS,CAAC,OAAO,EAAE;AACzB,YAAA,IAAI;AACF,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CACpC,GAAG,EACH,OAAO,IAAI,cAAc,EACzB,MAAM,EACN,4BAA4B,CAC7B;AACD,gBAAA,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI;YAC5D;AAAE,YAAA,MAAM;AACN,gBAAA,OAAO,IAAI;YACb;oBAAU;gBACR,SAAS,CAAC,OAAO,EAAE;YACrB;AACF,QAAA,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAC/C,CAAC,CAAC,KAAqD,CAAC,KAAK,IAAI,CAClE;AACD,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;IACnC;AAEA;;;;AAIG;AACK,IAAA,MAAM,SAAS,CACrB,SAAmB,EACnB,cAAsB,EACtB,MAAmB,EAAA;QAEnB,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC;AAClE,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAI;AACvD,YAAA,MAAM,SAAS,CAAC,OAAO,EAAE;AACzB,YAAA,IAAI;AACF,gBAAA,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE;oBAAU;gBACR,SAAS,CAAC,OAAO,EAAE;YACrB;AACF,QAAA,CAAC,CAAC;QACF,MAAM,OAAO,CAAC,IAAI,CAAC;AACjB,YAAA,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;AAC3B,YAAA,IAAI,OAAO,CAAC,CAAC,OAAO,KAClB,UAAU,CAAC,OAAO,EAAE,8BAA8B,CAAC,CACpD;AACF,SAAA,CAAC;IACJ;AAEQ,IAAA,YAAY,CAClB,OAAoD,EAAA;QAEpD,IAAI,IAAI,GAAqD,IAAI;QACjE,IAAI,UAAU,GAAG,QAAQ;QACzB,IAAI,OAAO,GAAG,QAAQ;AACtB,QAAA,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;YACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AACjC,YAAA,IAAI,GAAG,GAAG,UAAU,KAAK,GAAG,KAAK,UAAU,IAAI,GAAG,GAAG,OAAO,CAAC,EAAE;gBAC7D,UAAU,GAAG,GAAG;gBAChB,OAAO,GAAG,GAAG;gBACb,IAAI,GAAG,CAAC;YACV;QACF;AACA,QAAA,OAAO,IAAI;IACb;AAEQ,IAAA,MAAM,CAAC,OAAiB,EAAA;QAC9B,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACjD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AACzC,QAAA,OAAO,MAAM,CAAC,MAAM,GAAG;AACrB,cAAE,MAAM,CAAC,GAAG;AACZ,cAAE,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;IACzC;AAEO,IAAA,aAAa,CAAC,SAAwB,EAAA;QAC3C,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY;AACpE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACnE;IAEO,YAAY,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,IAAI,EAAE,EAAA;QACzE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAgB,aAAa,CAAC;IAC1D;AAEQ,IAAA,MAAM,YAAY,CAAC,SAAmB,EAAE,cAAsB,EAAA;QACpE,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC;;;;;;;AAOlE,QAAA,MAAM,gBAAgB,GAAG,IAAI,eAAe,EAAE;AAC9C,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM;AACnD,QAAA,IAAI,cAAwC;AAC5C,QAAA,IAAI,aAAa,CAAC,OAAO,EAAE;;AAEzB,YAAA,gBAAgB,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;QAC9C;aAAO;AACL,YAAA,cAAc,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;AACnE,YAAA,aAAa,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACzE;AAEA,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,KAAI;AAClE,YAAA,MAAM,SAAS,CAAC,OAAO,EAAE;AACzB,YAAA,IAAI;AACF,gBAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CACpC,GAAG,EACH,OAAO,IAAI,cAAc,EACzB,gBAAgB,CAAC,MAAM,CACxB;AACD,gBAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC;AAC5D,gBAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE;YAChC;oBAAU;gBACR,SAAS,CAAC,OAAO,EAAE;YACrB;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACjC;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;gBAAU;;;YAGR,gBAAgB,CAAC,KAAK,EAAE;;;YAGxB,IAAI,cAAc,EAAE;AAClB,gBAAA,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC;YAC5D;QACF;IACF;AAEQ,IAAA,MAAM,YAAY,CACxB,QAAgB,EAChB,OAAe,EACf,WAAyB,EACzB,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAA;QAE9B,MAAM,WAAW,GAAa,EAAE;AAChC,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG;AAE9C,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;;;AAG9B,YAAA,IAAI,WAAW,EAAE,OAAO,EAAE;gBACxB;YACF;AAEA,YAAA,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;AACnC,YAAA,IAAI;gBACF,MAAM,IAAI,CAAC,gBAAgB,CACzB,IAAI,CAAC,MAAM,CAAC;sBACR,CAAA,EAAG,QAAQ,CAAA,EAAG,GAAG,gBAAgB,WAAW,CAAC,GAAG,EAAE,CAAA;sBAClD,QAAQ,EACZ;AACE,oBAAA,MAAM,EAAE,KAAK;AACb,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,OAAO,EAAE;AACP,wBAAA,eAAe,EAAE,qCAAqC;AACtD,wBAAA,MAAM,EAAE,UAAU;AAClB,wBAAA,OAAO,EAAE,GAAG;AACb,qBAAA;AACD,oBAAA,WAAW,EAAE,MAAM;AACpB,iBAAA,EACD,OAAO,EACP,WAAW,CACZ;YACH;AAAE,YAAA,MAAM;;YAER;oBAAU;AACR,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;AACzD,gBAAA,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3B;QACF;AACA,QAAA,OAAO,WAAW;IACpB;IAEQ,MAAM,gBAAgB,CAC5B,GAAW,EACX,UAAuB,EAAE,EACzB,OAAe,EACf,WAAyB,EAAA;AAEzB,QAAA,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE;AACxC,QAAA,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;;;;AAKlC,QAAA,IAAI,eAAyC;QAC7C,IAAI,WAAW,EAAE;AACf,YAAA,IAAI,WAAW,CAAC,OAAO,EAAE;AACvB,gBAAA,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;YACtC;iBAAO;AACL,gBAAA,eAAe,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;AAC5D,gBAAA,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACxE;QACF;QAEA,MAAM,SAAS,GAAG,UAAU,CAC1B,MACE,UAAU,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC,EACzE,OAAO,CACR;AAED,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC;QAClC;gBAAU;YACR,YAAY,CAAC,SAAS,CAAC;AACvB,YAAA,IAAI,WAAW,IAAI,eAAe,EAAE;AAClC,gBAAA,WAAW,CAAC,mBAAmB,CAAC,OAAO,EAAE,eAAe,CAAC;YAC3D;QACF;IACF;8GA9XW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cADL,MAAM,EAAA,CAAA,CAAA;;2FACnB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AChB5B,SAAU,mBAAmB,CAEjC,GAAwB,EAAA;AAExB,IAAA,IAAI,CAAC,IAAI,CACP,IAAI,CAAC,SAAS,CAAC;AACb,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACvB,KAAA,CAAC,CACH;AACH;;ACXM,SAAU,YAAY,CAE1B,GAA8B,EAAA;AAE9B,IAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;AACzB;;ACPM,SAAU,WAAW,CAAC,GAAW,EAAA;AACrC,IAAA,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;AACtE;;ACGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGG;SACa,eAAe,CAC7B,KAAa,EACb,YAAoB,UAAU,EAAA;;AAG9B,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,EAAE,WAAW,IAAI,MAAM,CAAC,EAAE;QAC7D,OAAO,UAAU,CACf,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAC1D;IACH;AAEA,IAAA,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAErC,OAAO,KAAK,CACV,MACE,IAAI,UAAU,CAAY,CAAC,QAAQ,KAAI;AACrC,QAAA,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC;;QAG/B,IAAI,MAAM,GAAG,KAAK;QAClB,IAAI,OAAO,GAAG,KAAK;;QAInB,MAAM,MAAM,GAAG,MAAK;YAClB,MAAM,GAAG,IAAI;YACb,OAAO,GAAG,IAAI;AACd,YAAA,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,QAAQ,CAAC,QAAQ,EAAE;AACrB,QAAA,CAAC;AAED,QAAA,MAAM,OAAO,GAAG,CAAC,EAAS,KAAI;AAC5B,YAAA,MAAM,GAAG,GACP,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,YAAY;kBACxC,EAAE,CAAC;AACL,kBAAE,IAAI,KAAK,CAAC,6BAA6B,CAAC;AAC9C,YAAA,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;AACrB,QAAA,CAAC;AAED,QAAA,MAAM,OAAO,GAAG,CAAC,EAAc,KAAI;YACjC,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,QAAQ,CAAC,KAAK,CACZ,IAAI,KAAK,CAAC,CAAA,mCAAA,EAAsC,EAAE,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC,CAC5D;YACH;AACF,QAAA,CAAC;AAED,QAAA,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC;AACnC,QAAA,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC;AACrC,QAAA,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC;;AAGrC,QAAA,OAAO,MAAK;AACV,YAAA,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AACxC,YAAA,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AAExC,YAAA,IACE,CAAC,OAAO;AACR,iBAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;oBACrC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,CAAC,EACnC;;;;;AAKA,gBAAA,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC;AACtC,gBAAA,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;;;;;AAM7C,gBAAA,MAAM,aAAa,GAAG,MAAM,SAAS;gBACrC,MAAM,aAAa,GAAG,MAAK;AACzB,oBAAA,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC;AAC9C,oBAAA,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC;AAChD,gBAAA,CAAC;AACD,gBAAA,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC;AAC3C,gBAAA,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC;gBAC3C,EAAE,CAAC,KAAK,EAAE;YACZ;iBAAO;;;AAGL,gBAAA,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC;YACxC;AACF,QAAA,CAAC;AACH,IAAA,CAAC,CAAC,CACL,CAAC,IAAI,CACJ,OAAO,CAAC;AACN,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,IAAI,EAAE,MACJ,UAAU,CACR,MACE,IAAI,KAAK,CAAC,CAAA,qCAAA,EAAwC,SAAS,CAAA,EAAA,CAAI,CAAC,CACnE;AACJ,KAAA,CAAC,CACH;AACH;;SCxMgB,uBAAuB,GAAA;AACrC,IAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;QACf,MAAM,EAAE,gBAAgB,CAAC,+BAA+B;AACxD,QAAA,OAAO,EAAE,wCAAwC;AAClD,KAAA,CAAC,CACH;AACH;SACgB,yBAAyB,GAAA;AACvC,IAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;QACf,MAAM,EAAE,gBAAgB,CAAC,iCAAiC;AAC1D,QAAA,OAAO,EAAE,0CAA0C;AACpD,KAAA,CAAC,CACH;AACH;;ACZA;AACO,MAAM,yBAAyB,GAAG;AACvC,IAAA,sBAAsB,EAAE;AACtB,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,WAAW,EAAE,8DAA8D;AAC5E,KAAA;AACD,IAAA,aAAa,EAAE;AACb,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,WAAW,EACT,kEAAkE;AACrE,KAAA;AACD,IAAA,gBAAgB,EAAE;AAChB,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,WAAW,EACT,6EAA6E;AAChF,KAAA;CACO;AAEV;AACA,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAClC,yBAAyB,CAAC,sBAAsB,CAAC,IAAI;IACrD,yBAAyB,CAAC,aAAa,CAAC,IAAI;AAC7C,CAAA,CAAC;AAEI,SAAU,yBAAyB,CAEvC,GAA8B,EAAA;IAE9B,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAC7D,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,CACxC;AACD,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,uBAAuB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,WAAqB,EAAE,CAAC,CACvE;AACD,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AACzC,QAAA,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC,YAAY;AAC5C,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC9C;AACF;;ACmDM,MAAO,iBAAkB,SAAQ,UAAU,CAAA;AAoC/C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AApCQ,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAC/C,QAAA,IAAA,CAAA,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;QACzD,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAEhE,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,EAAE;mFAAC;QAEnB,IAAA,CAAA,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACvD,sBAAsB,CACvB;QACQ,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC9C,aAAa,CAAC,mBAAmB,CAClC;QACQ,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACrD,aAAa,CAAC,0BAA0B,CACzC;AAED,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAA6B;AACnD,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,OAAO,EAAiB;AACxC,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,OAAO,EAAmB;AAC7C,QAAA,IAAA,CAAA,eAAe,GAAG,IAAI,OAAO,EAAoC;;;;AAIjE,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC;QAExD,IAAA,CAAA,EAAE,GAAqB,IAAI;QAG3B,IAAA,CAAA,aAAa,GAEhB,EAAE;QAML,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;QACA,IAAI,CAAC,qBAAqB,EAAE;;;;AAK5B,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;YACxD,IAAI,CAAC,KAAK,CAAC;AACT,gBAAA,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,gBAAgB,CAAC,2BAA2B;AACrD,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;;;;;;;;AASF,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aACvD,SAAS,CAAC,MAAK;YACd,IAAI,CAAC,IAAI,CAAC;AACR,gBAAA,IAAI,EAAE,gBAAgB;AACtB,gBAAA,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE,YAAY,EAAE;AAC1B,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;AAEJ,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CACH,MAAM,CAAC,gBAAgB,CAAC,EACxB,SAAS,CAAC,MACR,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;AACxC,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CACjC,EACD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAEzB,SAAS,CAAC,MAAK;YACd,IAAI,CAAC,IAAI,CAAC;AACR,gBAAA,IAAI,EAAE,kCAAkC;gBACxC,aAAa,EAAE,YAAY,EAAE;AAC9B,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACN;AAEA,IAAA,kBAAkB,CAAC,OAAiB,EAAA;AAClC,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC;AAChD,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,oBAAoB,CAAC;AACnB,gBAAA,aAAa,EAAE,uCAAuC;AACvD,aAAA,CAAC,CACH;AACD,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC;;;;;;QAOnC,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,IAAI,CAAC,aAAa,GAAG,YAAY,EAAE;AACnC,YAAA,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE;YACpC,IAAI,CAAC,2BAA2B,EAAE;;;;;;;;;;;AAYlC,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CACzC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,EAC9CA,KAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,EACxD,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAC9C,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CACvB;AAED,YAAA,OAAO,aAAa,CAAC,IAAI,CACvB,KAAK,CAAC;AACJ,gBAAA,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAI;AACtB,oBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,uBAAuB,CAAC;wBACtB,OAAO;AACP,wBAAA,MAAM,EAAE,GAAG,EAAE,OAAO,IAAI,SAAS;AACjC,wBAAA,IAAI,EAAE,cAAc;AACrB,qBAAA,CAAC,CACH;AACD,oBAAA,MAAM,CAAC,IAAI,CACT,CAAA,gCAAA,EAAmC,iBAAiB,CAAA,aAAA,EAAgB,OAAO,CAAA,CAAA,CAAG,EAC9E,GAAG,EAAE,OAAO,CACb;AACD,oBAAA,OAAO,KAAK,CAAC,iBAAiB,CAAC;gBACjC,CAAC;AACF,aAAA,CAAC,CACH;QACH,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC;AAEA;;;;;;;AAOG;AACK,IAAA,cAAc,CAAC,IAAc,EAAA;AACnC,QAAA,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC;QAEjC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,CAAA,EAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAA,CAAE,CAAC,CAAC,CAAC,IAAI,CACpE,GAAG,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,EACtE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE;;;;;;;;;;;;;;QAclB,IAAI,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CACpC,MAAM,CAAC,MAAM,CAAC,EACd,IAAI,CAAC,CAAC,CAAC,EACP,KAAK,CAAC;AACJ,YAAA,KAAK,EAAE,qBAAqB;AAC5B,YAAA,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAI;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,uBAAuB,CAAC;oBACtB,OAAO;AACP,oBAAA,MAAM,EAAE,GAAG,EAAE,OAAO,IAAI,SAAS;AACjC,oBAAA,IAAI,EAAE,UAAU;AACjB,iBAAA,CAAC,CACH;AACD,gBAAA,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,qBAAqB,CAAC;AACjE,gBAAA,MAAM,CAAC,IAAI,CACT,CAAA,6BAAA,EAAgC,YAAY,CAAA,aAAA,EAAgB,OAAO,CAAA,CAAA,CAAG,EACtE,GAAG,EAAE,OAAO,CACb;AACD,gBAAA,OAAO,KAAK,CAAC,YAAY,CAAC;YAC5B,CAAC;AACF,SAAA,CAAC,CACH,CACF;;;;;AAKD,QAAA,KAAK,CAAC;AACJ,YAAA,KAAK,EAAE,iBAAiB;AACxB,YAAA,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAI;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,uBAAuB,CAAC;oBACtB,OAAO;AACP,oBAAA,MAAM,EAAE,GAAG,EAAE,OAAO,IAAI,SAAS;AACjC,oBAAA,IAAI,EAAE,SAAS;AAChB,iBAAA,CAAC,CACH;AACD,gBAAA,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,qBAAqB,CAAC;AACjE,gBAAA,MAAM,CAAC,IAAI,CACT,CAAA,yBAAA,EAA4B,YAAY,CAAA,aAAA,EAAgB,OAAO,CAAA,CAAA,CAAG,EAClE,GAAG,EAAE,OAAO,CACb;AACD,gBAAA,OAAO,KAAK,CAAC,YAAY,CAAC;YAC5B,CAAC;AACF,SAAA,CAAC,CACH;IACH;IAEU,2BAA2B,GAAA;AACnC,QAAA,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,qBAAqB,CAAC;AACjE,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE;IAEQ,iBAAiB,CAAC,OAAiB,EAAE,MAAe,EAAA;AAC1D,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,KAAI;YACzB,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;gBACtC,OAAO,GAAG,CAAC,OAAO,CAChB,oBAAoB,EACpB,CAAA,wBAAA,EAA2B,MAAM,CAAA,CAAE,CACpC;YACH;AACA,YAAA,OAAO,GAAG;AACZ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;AAIG;AACK,IAAA,cAAc,CAAC,GAAW,EAAA;AAChC,QAAA,OAAO,GAAG,CAAC,KAAK,CAAC,eAAe;AAC9B,cAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG;AAC3B,cAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;IACjC;AAEA;;;;AAIG;AACK,IAAA,gBAAgB,CAAC,GAAW,EAAA;AAClC,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,EACxD,IAAI,CAAC,CAAC,CAAC,EACPA,KAAG,CACD,OACG;AACC,YAAA,KAAK,EAAE,GAAG;AACV,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,YAAY,EAAE,mBAAmB;SAClC,CAAgB,CACpB,CACF;IACH;AAEA;;;;;;AAMG;AACK,IAAA,iBAAiB,CAAC,GAAW,EAAA;QACnC,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,IAAI,QAAiD;YACrD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;AACrC,YAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,kBAAkB,CAAC;YAElE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CACnD,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAI;AAC3B,gBAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE;AACxB,oBAAA,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC;gBACjD;YACF,CAAC,CAAC,EACF,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,EACxD,IAAI,CAAC,CAAC,CAAC,EACP,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAC7B,IAAI,CAAC,QAAQ,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAC,CAAC,IAAI,CAC/C,GAAG,CAAC,CAAC,IAAI,KAAI;gBACX,QAAQ,GAAG,IAAI;YACjB,CAAC,CAAC,CACH,CACF,EACDA,KAAG,CAAC,CAAC,IAAI,MAAmB;AAC1B,gBAAA,KAAK,EAAE,WAAW,CAAC,CAAA,EAAG,QAAQ,CAAC,QAAQ,CAAA,EAAA,EAAK,IAAI,CAAC,gBAAgB,CAAA,CAAE,CAAC;AACpE,gBAAA,UAAU,EAAE,GAAG;AACf,gBAAA,YAAY,EAAE,IAAI,CAAC,gBAAgB,IAAI,EAAE;AAC1C,aAAA,CAAC,CAAC,EACH,QAAQ,CAAC,MAAK;gBACZ,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,kBAAkB,EAClB,IAAI,EACJ,EAAE,IAAI,QAAQ,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAW,CAC9C;gBACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;YACrC,CAAC,CAAC,CACH;AACH,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;;;;;;;;;AAcG;AACK,IAAA,QAAQ,CAAC,GAAW,EAAA;QAC1B,OAAO,KAAK,CAAC,MACX,IAAI,CAAC,UAAU,CAAC,GAAG,CAA8B,GAAG,CAAC,CACtD,CAAC,IAAI,CACJC,SAAO,CAAC,YAAY,CAAC,EACrB,UAAU,CAAC,CAAC,GAAG,KAAI;;AAEjB,YAAA,MAAM,MAAM,GAAI,GAAkC,EAAE,MAAM;YAC1D,IACE,OAAO,MAAM,KAAK,QAAQ;AAC1B,gBAAA,MAAM,IAAI,GAAG;AACb,gBAAA,MAAM,GAAG,GAAG;gBACZ,MAAM,KAAK,GAAG,EACd;gBACA,MAAM,CAAC,IAAI,CACT,CAAA,sBAAA,EAAyB,GAAG,CAAA,OAAA,EAAU,MAAM,CAAA,eAAA,CAAiB,CAC9D;AACD,gBAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;YAC9B;;AAEA,YAAA,MAAM,CAAC,IAAI,CACT,CAAA,sBAAA,EAAyB,GAAG,CAAA,EAAA,EAAK,GAAG,EAAE,OAAO,IAAI,GAAG,CAAA,sBAAA,CAAwB,CAC7E;AACD,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,IAAiC,KAAI;;;YAGxC,IAAI,IAAI,CAAC,gBAAgB;gBAAE;YAE3B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,IAAI,kBAAkB,CAAC;AAC9D,YAAA,IAAI,IAAI,EAAE,IAAI,EAAE;AACd,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gCAAgC,CAAC;AAC/B,oBAAA,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;AAC3B,iBAAA,CAAC,CACH;YACH;AACF,QAAA,CAAC,CAAC;;;AAGF,QAAA,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;;AAE5C,QAAA,KAAK,CAAC,CAAC,IAAiC,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CACtE;IACH;AAEQ,IAAA,eAAe,CAAC,KAAa,EAAA;;;;;;;;QAQnC,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;AACzE,YAAA,OAAO,eAAe,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,CAAC,IAAI,CACL,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EACtB,MAAM,CAAC,YAAY,CAAC,EACpB,GAAG,CAAC,CAAC,EAAE,KAAI;AACT,YAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,kBAAkB,CAAC;AAClE,YAAA,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QACxB,CAAC,CAAC,CACH;IACH;AAEQ,IAAA,aAAa,CAAC,EAAa,EAAA;QACjC,EAAE,CAAC,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1C,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,QAAA,IAAI,CAAC,EAAE,GAAG,EAAE;AACZ,QAAA,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC/B,QAAA,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B;AAEA;;;;;;;AAOG;IACH,WAAW,CAAC,EAAa,EAAE,aAAqB,EAAA;AAC9C,QAAA,IAAI,CAAC,aAAa,GAAG,aAAa;QAClC,EAAE,CAAC,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1C,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,QAAA,IAAI,CAAC,EAAE,GAAG,EAAE;AACZ,QAAA,MAAM,CAAC,GAAG,CACR,iEAAiE,CAClE;IACH;AAEQ,IAAA,iBAAiB,CAAC,aAA4B,EAAA;AACpD,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;IAC1D;AAEA;;;AAGG;AACH,IAAA,KAAK,CAAC,IAAiB,EAAA;AACrB,QAAA,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;AAC7B,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;AAC/B,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AAEzC,QAAA,IAAI,IAAI,CAAC,EAAE,EAAE;AACX,YAAA,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC;AACpD,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;AAClB,YAAA,EAAE,CAAC,SAAS,GAAG,MAAM,IAAI;AACzB,YAAA,EAAE,CAAC,OAAO,GAAG,MAAM,IAAI;AACvB,YAAA,EAAE,CAAC,OAAO,GAAG,MAAM,IAAI;AACvB,YAAA,EAAE,CAAC,MAAM,GAAG,MAAM,IAAI;AACtB,YAAA,IAAI,CAAC,EAAE,GAAG,IAAI;AAEd,YAAA,IACE,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;AACtC,gBAAA,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAChC;AACA,gBAAA,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACxD,oBAAA,IAAI,EAAE,IAAI;AACX,iBAAA,CAAC;AACF,gBAAA,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;YACxB;QACF;IACF;AAEA,IAAA,IAAI,CAAC,IAAyB,EAAA;QAC5B,IAAI,UAAU,GAAG,IAAI;AACrB,QAAA,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;AAClC,YAAA,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QACnC;AACA,QAAA,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,aAAa,EAAE;;;AAGnD,YAAA,IAAI,MAAM,CAAC,SAAS,EAAE;AACpB,gBAAA,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClE;AACA,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC;YAC1B;AAAE,YAAA,MAAM;AACN,gBAAA,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;YAC9B;QACF;IACF;AAEU,IAAA,aAAa,CAAC,GAAgB,EAAA;AACtC,QAAA,IAAI;YACF,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC;AAC/C,YAAA,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAY,CAAC;QAChD;AAAE,QAAA,MAAM;AACN,YAAA,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,iBAAiB,EAChC,CAAA,6BAAA,EAAgC,GAAG,CAAC,IAAI,CAAA,CAAE,CAC3C;QACH;IACF;IAEQ,qBAAqB,GAAA;QAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAChD,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/D,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9D,IAAI,CAAC,aAAa,CAAC,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAChE,IAAI,CAAC,aAAa,CAAC,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAChE,IAAI,CAAC,aAAa,CAAC,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;QAClE,IAAI,CAAC,aAAa,CAAC,gBAAgB,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;QACxE,IAAI,CAAC,aAAa,CAAC,kBAAkB,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1E,IAAI,CAAC,aAAa,CAAC,oBAAoB;AACrC,YAAA,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;IACpD;IAEU,iBAAiB,GAAA;AACzB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,EAAE;AAC3C,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;AAC1C,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,EAAE;YAC9B;QACF;QAEA,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,yBAAyB,CAAC,aAAa;YAC7C,aAAa,EAAE,IAAI,CAAC,aAAa;AACjC,YAAA,OAAO,EAAE;AACP,gBAAA,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;gBACrB,aAAa;gBACb,OAAO;AACR,aAAA;AACF,SAAA,CAAC;IACJ;AAEA;;AAEG;IACH,WAAW,GAAA;AACT,QAAA,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,aAAa,CAAC;IAC5D;IAEQ,SAAS,GAAA;AACf,QAAA,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC;AAClC,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3D;8GA9hBW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cADJ,MAAM,EAAA,CAAA,CAAA;;2FACnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AC/DlC;;AAEG;AACI,MAAM,kBAAkB,GAAmB;AAChD,IAAA,cAAc,EAAE,IAAI;AACpB,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,mBAAmB,EAAE,IAAI;AACzB,IAAA,sBAAsB,EAAE,IAAI;AAC5B,IAAA,sBAAsB,EAAE,CAAC;AACzB,IAAA,YAAY,EAAE,CAAC;AACf,IAAA,gBAAgB,EAAE,GAAG;AACrB,IAAA,SAAS,EAAE,KAAK;CACR;AAEV;;AAEG;AACI,MAAM,WAAW,GAAG,EAAE,GAAG,kBAAkB,EAAE;AAEpD;;AAEG;AACI,MAAM,eAAe,GAAG,IAAI,eAAe,CAChD,WAAW,CAAC,UAAU,EACtB,WAAW,CAAC,OAAO,EACnB,EAAE,CACH;;AC1BK,MAAO,YAAa,SAAQ,UAAU,CAAA;AAmD1C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QAnDQ,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACvD,aAAa,CAAC,oBAAoB,CACnC;QACD,IAAA,CAAA,KAAK,GAA4B,IAAI;QACrC,IAAA,CAAA,KAAK,GAA4B,IAAI;QAE7B,IAAA,CAAA,SAAS,GAA0B,IAAI;AACvC,QAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,cAAc,EAAE;;;;;;;AAQzC,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,eAAe,CAG/B,IAAI,CAAC;QAEP,IAAA,CAAA,cAAc,GAAG,CAAC;QAClB,IAAA,CAAA,eAAe,GAAG,EAAuB;QACjD,IAAA,CAAA,cAAc,GAAG,IAAI,cAAc,CACjC,WAAW,CAAC,sBAAsB,EAClC,WAAW,CAAC,sBAAsB,EAClC,WAAW,CAAC,YAAY,EACxB,WAAW,CAAC,gBAAgB,CAC7B;AAED;;AAEG;AACH,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI;;AAEjC,QAAAC,WAAS,CAAC,CAAC,KAAK,KACd;AACE;AACE,gBAAA,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAChB,GAAG,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,EACzBA,WAAS,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EACtD,MAAM,CAAC,MAAM,CAAC;AAElB,cAAE,EAAE,CAAC,IAAI,CAAC,CACb,EACD,MAAM,CAAC,MAAM,CAAC,EACd,KAAK,EAAE,CACR;AAEO,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,eAAe,EAAE;AAI1C,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACjD;IAEA,YAAY,CAAC,YAAmC,IAAI,EAAA;AAClD,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;IAC5B;AAEA,IAAA,iBAAiB,CAAC,cAAsB,EAAA;AACtC,QAAA,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,cAAc,CAAC;IACtD;AAEA,IAAA,UAAU,CAAC,IAAiB,EAAA;QAC1B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAChD;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AACnB,YAAA,MAAM,CAAC,IAAI,CACT,0HAA0H,CAC3H;QACH;AACA,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAEC,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,EAAE;QACd,IAAI,CAAC,iBAAiB,EAAE;QACxB,IAAI,CAAC,iBAAiB,EAAE;IAC1B;IAEA,iBAAiB,CAAC,MAAmB,EAAE,QAA2B,EAAA;AAChE,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC;YAC7C;QACF;;;;AAIA,QAAA,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;AAC/D,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE;QAC3C,IAAI,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE;YACpC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC;AACnD,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5B;QACA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;;;;QAI3C,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAChC;AAEA,IAAA,iBAAiB,CAAC,MAAmB,EAAA;AACnC,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YACf;QACF;AACA,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE;AAC3C,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;YACvB;QACF;QACA,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC;AACnD,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;IAC5B;IAEA,IAAI,GAAA;QACF,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAChC;IAEA,MAAM,QAAQ,CAAC,KAA8B,EAAA;QAC3C,IAAI,CAAC,KAAK,EAAE;YACV;QACF;AAEA,QAAA,IAAI;AACF,YAAA,MAAM,KAAK,CAAC,IAAI,EAAE;YAClB;QACF;QAAE,OAAO,KAAc,EAAE;AACvB,YAAA,IACE,KAAK;gBACL,OAAO,KAAK,KAAK,QAAQ;AACzB,gBAAA,MAAM,IAAI,KAAK;AACf,gBAAA,KAAK,EAAE,IAAI,KAAK,iBAAiB,EACjC;AACA,gBAAA,MAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE,KAAK,CAAC;gBAClE;YACF;;AAGA,YAAA,KAAK,CAAC,KAAK,GAAG,IAAI;AAClB,YAAA,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC;AACrC,YAAA,IAAI;AACF,gBAAA,MAAM,KAAK,CAAC,IAAI,EAAE;gBAClB;YACF;AAAE,YAAA,MAAM;;YAER;;AAGA,YAAA,MAAM,MAAM,GAAG,YAAW;AACxB,gBAAA,IAAI;;;AAGF,oBAAA,MAAM,KAAK,CAAC,IAAI,EAAE;gBACpB;AAAE,gBAAA,MAAM;;gBAER;wBAAU;oBACR,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC;oBACvD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC;gBACrD;AACF,YAAA,CAAC;AAED,YAAA,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE;AAC7C,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;AACjC,aAAA,CAAC;AACF,YAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE;AACzC,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;AACjC,aAAA,CAAC;QACJ;IACF;IAEQ,MAAM,QAAQ,CACpB,QAAkC,EAAA;QAElC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,eAAe,KAAK,QAAQ,EAAE;AACtD,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;;;AAG3C,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,OAAO,IAAI,CAAC,+BAA+B,CAAC,KAAK,CAAC;QACpD;QAAE,OAAO,GAAG,EAAE;;YAEZ,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE;AACnE,gBAAA,MAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC;AACrE,gBAAA,OAAO,IAAI;YACb;AACA,YAAA,MAAM,GAAG;QACX;IACF;AAEQ,IAAA,+BAA+B,CACrC,KAAqB,EAAA;QAErB,MAAM,OAAO,GAAsB,EAAuB;;AAG1D,QAAA,OAAO,CAAC,MAAM,GAAG,EAAE;AACnB,QAAA,OAAO,CAAC,oBAAoB,GAAG,CAAC,CAAC;AAEjC,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;;AAEvB,YAAA,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE;AAC5D,gBAAA,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;AAE9B,gBAAA,OAAO,CAAC,kBAAkB;AACxB,oBAAA,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;AAC3C,0BAAE,IAAI,CAAC,eAAe,CAAC;AACvB,0BAAE,MAAM,CAAC,aAAa;AAE1B,gBAAA,OAAO,CAAC,kBAAkB;AACxB,oBAAA,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;AAC3C,0BAAE,IAAI,CAAC,eAAe,CAAC;AACvB,0BAAE,MAAM,CAAC,aAAa;AAE1B,gBAAA,OAAO,CAAC,cAAc;AACpB,oBAAA,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;AAC3C,0BAAE,IAAI,CAAC,eAAe,CAAC;AACvB,0BAAE,MAAM,CAAC,SAAS;gBAEtB,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE;;oBAE1D,IACE,MAAM,CAAC,OAAO;wBACd,IAAI,CAAC,eAAe,CAAC,MAAM;AAC3B,wBAAA,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,EAC1D;AACA,wBAAA,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;oBAClE;AAEA,oBAAA,IAAI,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE;;;wBAGtC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAC1B,CAAC,CAAC;AACA,6BAAC,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC;AAC1B,gCAAA,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;6BACpC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CACvD;oBACH;AAEA,oBAAA,IAAI,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE;wBAC3C,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAC7B,CAAC,CAAC;AACA,6BAAC,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC;AAC1B,gCAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;6BACzC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAC5D;oBACH;AAEA,oBAAA,IAAI,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE;AAC3C,wBAAA,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAC/B,CAAC,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC;AAC1B,4BAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB;6BACtC,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc;gCACvD,IAAI,CAAC,CACV;oBACH;gBACF;YACF;;;;;;;;;;;AAYA,YAAA,IACE,MAAM,CAAC,IAAI,KAAK,gBAAgB;gBAChC,MAAM,CAAC,SAAS,KAAK,IAAI;gBACzB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C;gBACA,OAAO,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,CAAC;YACjE;AAEA,YAAA,IACE,MAAM,CAAC,IAAI,KAAK,WAAW;gBAC3B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,EAChD;gBACA,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,CAAC;gBAC9D,IAAI,YAAY,EAAE;oBAChB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC;oBACtD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC;oBACxD,OAAO,CAAC,YAAY,GAAG;AACrB,wBAAA,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;AACtD,wBAAA,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;qBAC1D;gBACH;YACF;;AAGA,YAAA,IACE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC;gBAChC,MAAM,CAAC,IAAI,KAAK,OAAO;AACvB,gBAAA,MAAM,CAAC,QAAQ;gBACf,MAAM,CAAC,EAAE,EACT;AACA,gBAAA,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE;gBACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAC9B,qBAAA,OAAO,CAAC,QAAQ,EAAE,EAAE;AACpB,qBAAA,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC1B;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,CAAC,UAAU,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AACxD,QAAA,IAAI,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE;YAC7C,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,oBAAoB;YACxE,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,CAC9C,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAC1C;QACH;;AAGA,QAAA,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAC1B,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CACpD;QACD,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAChC,IAAI,CAAC,cAAc,CAAC,MAAM,CACxB,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,sBAAsB,CACtD,CACF;QAED,OAAO,CAAC,mBAAmB,GAAG,eAAe,CAAC,QAAQ,CACpD,OAAO,CAAC,aAAa,CACtB;AAED,QAAA,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAC9B,OAAO,CAAC,mBAAmB,CAAC,cAAc,CAC3C;AACD,QAAA,IAAI,CAAC,eAAe,GAAG,OAAO;AAC9B,QAAA,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;IACxC;AAEQ,IAAA,iBAAiB,CAAC,eAAkC,EAAA;QAC1D,OAAO;AACL,YAAA,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC;AACzC,YAAA,eAAe,EAAE;AACf,gBAAA,GAAG,eAAe;gBAClB,cAAc,EAAE,IAAI,CAAC,cAAc;AACpC,aAAA;SACF;IACH;IAEQ,OAAO,GAAA;AACb,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YACf;QACF;AACA,QAAA,IAAI,CAAC,4BAA4B,CAAC,KAAK,CAAC;;;;AAIxC,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AACzB,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,eAAe,EAAE;;;AAGzC,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AAClB,QAAA,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;AAC3B,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AAClB,YAAA,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI;QAC7B;AACA,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;;AAG3B,QAAA,IAAI,CAAC,eAAe,GAAG,EAAuB;AAC9C,QAAA,IAAI,CAAC,cAAc,GAAG,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CACtC,WAAW,CAAC,sBAAsB,EAClC,WAAW,CAAC,sBAAsB,EAClC,WAAW,CAAC,YAAY,EACxB,WAAW,CAAC,gBAAgB,CAC7B;QACD,eAAe,CAAC,KAAK,EAAE;AAEvB,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;QACvD;IACF;AAEQ,IAAA,4BAA4B,CAAC,cAAuB,EAAA;AAC1D,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,cAAc,EAAE;YAC5C;QACF;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;IACvE;IAEQ,iBAAiB,GAAA;AACvB,QAAA,cAAc,EAAE;QAChB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,QAAA,KAAK,CAAC,EAAE,GAAG,kBAAkB;AAC7B,QAAA,KAAK,CAAC,WAAW,GAAG,IAAI;AACxB,QAAA,KAAK,CAAC,KAAK,GAAG,IAAI;;;;AAIlB,QAAA,KAAK,CAAC,YAAY,GAAG,IAAI;;;;;AAKzB,QAAA,KAAK,CAAC,OAAO,GAAG,MAAM;AACtB,QAAA,KAAK,CAAC,uBAAuB,GAAG,IAAI;AAEpC,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;QAClB,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;AAEvC,QAAA,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM;AACzB,aAAA,IAAI,CAACA,WAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;aACtD,SAAS,CAAC,MAAM,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC;AAE3D,QAAA,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,gBAAgB;aACnC,IAAI,CACH,IAAI,CAAC,CAAC,CAAC,EACP,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,EAC5C,MAAM,CAAC,8BAA8B,CAAC,EACtC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAC1BA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAEzB,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACnE;IAEQ,iBAAiB,GAAA;AACvB,QAAA,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE;AACzB,QAAA,KAAK,CAAC,EAAE,GAAG,kBAAkB;AAC7B,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;IACpB;IAEQ,MAAM,SAAS,CAAC,KAAuB,EAAA;AAC7C,QAAA,IAAI;AACF,YAAA,MAAM,KAAK,CAAC,IAAI,EAAE;YAClB;QACF;AAAE,QAAA,MAAM;;AAEN,YAAA,MAAM,MAAM,GAAG,YAAW;AACxB,gBAAA,IAAI;AACF,oBAAA,MAAM,KAAK,CAAC,IAAI,EAAE;gBACpB;AAAE,gBAAA,MAAM;;gBAER;wBAAU;oBACR,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC;oBACvD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC;gBACrD;AACF,YAAA,CAAC;AAED,YAAA,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE;AAC7C,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;AACjC,aAAA,CAAC;AACF,YAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE;AACzC,gBAAA,IAAI,EAAE,IAAI;AACV,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;AACjC,aAAA,CAAC;QACJ;IACF;8GAtdW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAZ,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cADC,MAAM,EAAA,CAAA,CAAA;;2FACnB,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACT5B,MAAO,mBAAoB,SAAQ,UAAU,CAAA;AAsBjD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAtBT,QAAA,IAAA,CAAA,qBAAqB,GAAG,IAAI,OAAO,EAAe;QAE1C,IAAA,CAAA,QAAQ,GAA6B,IAAI;QACzC,IAAA,CAAA,QAAQ,GAA0B,IAAI;AAC7B,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,iBAAiB,CAAC;AACzC,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;QAClE,IAAA,CAAA,GAAG,GAAqB,EAAE;QAC1B,IAAA,CAAA,MAAM,GAAG,KAAK;QACd,IAAA,CAAA,SAAS,GAAG,KAAK;QACjB,IAAA,CAAA,cAAc,GAAG,KAAK;;QAGtB,IAAA,CAAA,oBAAoB,GAAG,KAAK;;QAE5B,IAAA,CAAA,kBAAkB,GAAsB,EAAE;QAE1C,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC9C,aAAa,CAAC,oBAAoB,CACnC;QAIC,IAAI,CAAC,IAAI,EAAE;AACX,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7C,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC1C,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7C,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC1C,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACjD;IAEU,IAAI,GAAA;QACZ,IAAI,CAAC,aAAa,CAAC;AAChB,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7B,aAAA,SAAS,CAAC,CAAC,MAAqB,KAAI;AACnC,YAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AACxB,QAAA,CAAC,CAAC;;QAGJ,IAAI,CAAC,aAAa,CAAC;AAChB,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,KAAK,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;AACpC,QAAA,CAAC,CAAC;;QAGJ,IAAI,CAAC,aAAa,CAAC;AAChB,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AACpB,YAAA,KAAK,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;AACtC,QAAA,CAAC,CAAC;;QAGJ,IAAI,CAAC,aAAa,CAAC;AAChB,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7B,aAAA,SAAS,CAAC,CAAC,SAAS,KAAI;AACvB,YAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,kBAAkB,EAClB,IAAI,EACJ,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB;AAED,YAAA,IAAI,IAAI,CAAC,oBAAoB,EAAE;AAC7B,gBAAA,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC;YAC3C;iBAAO;AACL,gBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC;YACzC;AACF,QAAA,CAAC,CAAC;IACN;AAEA;;;;;;;AAOG;IACK,MAAM,iBAAiB,CAC7B,KAAgC,EAAA;AAEhC,QAAA,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC;AAC1D,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,oBAAoB,GAAG,KAAK;AACjC,YAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;AAElC,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAClB,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;YACpC;AAEA,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ;YACxB,IAAI,CAAC,EAAE,EAAE;gBACP;YACF;;AAGA,YAAA,MAAM,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC;AACpC,YAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;YAChC,IAAI,CAAC,uBAAuB,EAAE;AAE9B,YAAA,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC;AAChD,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;gBACf,MAAM,EAAE,gBAAgB,CAAC,WAAW;AACpC,gBAAA,OAAO,EAAE,4CAA4C;AACtD,aAAA,CAAC,CACH;QACH;IACF;AAEA;;;AAGG;IACK,MAAM,kBAAkB,CAC9B,MAAiC,EAAA;AAEjC,QAAA,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC;AAC1C,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC;AACjD,YAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;YAChC,IAAI,CAAC,uBAAuB,EAAE;QAChC;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,CAAC;QACjE;IACF;;IAGQ,uBAAuB,GAAA;AAC7B,QAAA,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,kBAAkB,EAAE;AAC/C,YAAA,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC;QAC3C;AACA,QAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;IACpC;AAEA;;;;AAIG;AACK,IAAA,MAAM,iBAAiB,GAAA;AAC7B,QAAA,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC;AAC9C,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,oBAAoB,GAAG,KAAK;AACjC,YAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;AAElC,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAClB,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;YACpC;AAEA,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ;YACxB,IAAI,CAAC,EAAE,EAAE;gBACP;YACF;;AAGA,YAAA,MAAM,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAErC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,oBAAoB,EAAE;AAC/D,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA,CAAC;AAEF,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC;AAChD,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;gBACf,MAAM,EAAE,gBAAgB,CAAC,WAAW;AACpC,gBAAA,OAAO,EAAE,0BAA0B;AACpC,aAAA,CAAC,CACH;QACH;IACF;AAEA;;;;AAIG;AACK,IAAA,mBAAmB,CAAC,MAAwB,EAAA;QAClD,IAAI,CAAC,OAAO,EAAE;AACd,QAAA,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC;QACxD,IAAI,CAAC,QAAQ,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC;AAE7C,QAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,2BAA2B,CAAC;AAC3E,QAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAC5C,4BAA4B,CAC7B;AACD,QAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAC5C,4BAA4B,CAC7B;AAED,QAAA,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC;QAE9C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;YACtE,IAAI,CAAC,OAAO,EAAE;AAChB,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,iBAAiB,CACvB,EAAqB,EACrB,KAAa,EACb,OAA2B,EAAA;QAE3B,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC;AACxD,QAAA,OAAO,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC;IACpD;AAEQ,IAAA,yBAAyB,CAAC,YAA6B,EAAA;AAC7D,QAAA,IAAI;AACF,YAAA,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC;AACnD,YAAA,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,SAAS,EACT,SAAS,CAAC,IAAI,EACd,aAAa,EACb,SAAS,CAAC,QAAQ,EAClB,YAAY,EACZ,SAAS,CAAC,OAAO,EACjB,SAAS,EACT,SAAS,CAAC,IAAI,EACd,GAAG,CACJ;;AAGD,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AAC5C,oBAAA,MAAM,CAAC,IAAI,CACT,mDAAmD,EACnD,SAAS,EACT,SAAS,CAAC,IAAI,EACd,aAAa,EACb,SAAS,CAAC,QAAQ,EAClB,YAAY,EACZ,SAAS,CAAC,OAAO,EACjB,SAAS,EACT,SAAS,CAAC,IAAI,EACd,GAAG,CACJ;oBACD;gBACF;YACF;AACA,YAAA,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAI;AACpD,gBAAA,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,CAAC,CAAC;AAC/C,YAAA,CAAC,CAAC;QACJ;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC;QACpD;IACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCG;IACK,qBAAqB,CAAC,GAAW,EAAE,cAAsB,EAAA;QAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QAC/B,MAAM,SAAS,GAAa,EAAE;AAE9B,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,YAAA,IACE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC1B,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAA,iBAAA,EAAoB,cAAc,CAAA,CAAE,CAAC,EACjE;AACA,gBAAA,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5C,gBAAA,IAAI,EAAE;AAAE,oBAAA,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B;QACF;AAEA,QAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,GAAG;AAEtC,QAAA,OAAO;AACJ,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;AACZ,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;AAAE,gBAAA,OAAO,IAAI;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;;YAE7B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAChC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,YAAA,MAAM,WAAW,GAAG;AAClB,gBAAA,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7C,gBAAA,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aAC/C;AACD,YAAA,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;AAC9C,QAAA,CAAC;aACA,IAAI,CAAC,MAAM,CAAC;IACjB;AAEQ,IAAA,QAAQ,CAAC,GAAW,EAAA;QAC1B,IAAI,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;QAEzD,SAAS,GAAG,SAAS,CAAC,OAAO,CAC3B,iDAAiD,EACjD,iEAAiE,CAClE;;QAGD,IAAI,QAAQ,GAAG,2BAA2B;AAE1C,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;;YAEf,QAAQ,IAAI,6BAA6B;QAC3C;;AAGA,QAAA,QAAQ,IAAI,IAAI,CAAC,cAAc,GAAG,WAAW,GAAG,WAAW;;QAG3D,QAAQ,IAAI,gBAAgB;;QAG5B,SAAS,GAAG,SAAS,EAAE,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AAE1D,QAAA,OAAO,SAAS;IAClB;AAEA;;AAEG;IACH,OAAO,GAAA;AACL,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC;QAChD;AACA,QAAA,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE;AACtB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AAEpB,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC;QAC7C;AACA,QAAA,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE;AACtB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AAEpB,QAAA,IAAI,CAAC,oBAAoB,GAAG,KAAK;AACjC,QAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;IACpC;AAEA;;;;;;;;;AASG;AACH,IAAA,wBAAwB,CAAC,MAA4B,EAAA;AACnD,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,8BAA8B,EAAE,MAAM,EAAE,CAAC;QAC1E,IAAI,CAAC,OAAO,EAAE;IAChB;IAEA,OAAO,GAAA;QACL,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,KAAK,MAAM;IAC7D;AAEA,IAAA,IAAI,CAAC,IAAiB,EAAA;AACpB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;AAClB,YAAA,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC;QAC3B;aAAO;AACL,YAAA,MAAM,CAAC,OAAO,CACZ,OAAO,EACP,QAAQ,EACR,CAAA,iDAAA,EAAoD,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAA,CAAE,CAChF;;YAGD,IAAI,CAAC,yBAAyB,EAAE;QAClC;IACF;AAEA;;;AAGG;IACK,yBAAyB,GAAA;;AAE/B,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE;AACzB,YAAA,MAAM,CAAC,IAAI,CACT,8DAA8D,CAC/D;YACD;QACF;QAEA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE;AACrC,YAAA,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC;YACpE;QACF;;AAGA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU;AACzC,QAAA,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE;AACjC,YAAA,MAAM,CAAC,IAAI,CACT,+BAA+B,OAAO,CAAA,iDAAA,CAAmD,CAC1F;AACD,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,aAAa,CAAC;AACZ,gBAAA,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,gBAAgB,CAAC,WAAW;AACzC,gBAAA,KAAK,EAAE,CAAC;AACT,aAAA,CAAC,CACH;QACH;IACF;AAEA;;;;;AAKG;IACH,aAAa,GAAA;QACX,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE;AACrC,YAAA,MAAM,CAAC,KAAK,CACV,4DAA4D,CAC7D;AACD,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;AACnD,YAAA,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC;AACtE,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC;;QAGvD,IAAI,CAAC,OAAO,EAAE;;AAGd,QAAA,KAAK,IAAI,CAAC,iBAAiB,EAAE;AAE7B,QAAA,OAAO,IAAI;IACb;AAEA;;;;;;;;;AASG;IACH,KAAK,CACH,EAAqB,EACrB,EAAkB,EAClB,MAAmB,EACnB,MAAwB,EACxB,QAAuB,EAAA;;QAGvB,IAAI,CAAC,OAAO,EAAE;AACd,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;AAClB,QAAA,IAAI,CAAC,GAAG,GAAG,MAAM,IAAI,EAAE;;AAEvB,QAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;;;AAIhC,QAAA,EAAE,CAAC,cAAc,GAAG,IAAI;AACxB,QAAA,EAAE,CAAC,aAAa,GAAG,IAAI;AACvB,QAAA,EAAE,CAAC,OAAO,GAAG,IAAI;AAEjB,QAAA,IAAI,CAAC,0BAA0B,CAAC,EAAE,CAAC;;AAEnC,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;;;;AAKlC,QAAA,EAAE,CAAC,SAAS,GAAG,IAAI;AACnB,QAAA,EAAE,CAAC,MAAM,GAAG,IAAI;AAChB,QAAA,EAAE,CAAC,OAAO,GAAG,IAAI;;;QAGjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,yBAAyB,CAAC,EAAE,EAAE,KAAK,CAAC;AACzD,QAAA,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE;AAC/B,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC3C;;;AAGA,QAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,4BAA4B,CAAC;QAC3E,IAAI,CAAC,sBAAsB,EAAE;;;AAI7B,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;QAC1B,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;IACjD;IAEQ,SAAS,CAAC,aAAa,EAAmB,EAAA;QAChD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;;;;QAK7D,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,UAAU,CAAC,qBAAqB,EAAE;QAElD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC;AAC3C,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,MAAM,CAAC,IAAI,CACT,+EAA+E,CAChF;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,OAAO;QACvC;QAEA,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,gBAAgB;AACpD,cAAE;cACA,UAAU;AAEd,QAAA,IAAI,CAAC,GAAG,CAAC,oBAAoB,GAAG,CAAC;;AAGjC,QAAA,MAAM,qBAAqB,GACzB,QAAQ,CAAC,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW;AACxE,QAAA,MAAM,iBAAiB,GAAG,QAAQ,CAAC,QAAQ,KAAK,QAAQ;QACxD,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,qBAAqB,IAAI,CAAC,iBAAiB,EAAE;AAC/D,YAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,YAAA,MAAM,CAAC,KAAK,CACV,4GAA4G,CAC7G;AACD,YAAA,MAAM,CAAC,KAAK,CACV,8IAA8I,CAC/I;QACH;AAEA,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;IACpC;AAEQ,IAAA,0BAA0B,CAAC,QAA2B,EAAA;AAC5D,QAAA,SAAS,CAAC,QAAQ,EAAE,sBAAsB;aACvC,IAAI,CACHH,KAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,EACxC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;YACnB,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,EAAE,GAAG,CAAC;AACrD,YAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,4BAA4B,EAC5B,IAAI,EACJ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CACvB;AACH,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAC,QAAQ,EAAE,0BAA0B;aAC3C,IAAI,CACHA,KAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAC5C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;YACnB,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,EAAE,GAAG,CAAC;AACrD,YAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,4BAA4B,EAC5B,IAAI,EACJ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CACvB;AACH,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAC,QAAQ,EAAE,yBAAyB;aAC1C,IAAI,CACHA,KAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,EAC3C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;YACnB,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAG,CAAC;AACpD,YAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,2BAA2B,EAC3B,IAAI,EACJ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CACvB;AACH,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAC,QAAQ,EAAE,uBAAuB;aACxC,IAAI,CACHA,KAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EACzC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;YACnB,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,KAAK,EAAE,GAAG,CAAC;AACxD,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAA4B,QAAQ,EAAE,cAAc;AAC1D,aAAA,IAAI,CACHA,KAAG,CAAC,CAAC,CAA4B,KAAK,CAAC,CAAC,SAAS,CAAC,EAClD,MAAM,CAAC,MAAM,CAAC,EACdI,KAAG,CAAC,CAAC,SAA0B,KAC7B,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,SAAS,EACT,SAAS,CAAC,IAAI,EACd,aAAa,EACb,SAAS,CAAC,QAAQ,EAClB,YAAY,EACZ,SAAS,CAAC,OAAO,EACjB,SAAS,EACT,SAAS,CAAC,IAAI,EACd,GAAG,CACJ,CACF,EACD,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;aAElD,SAAS,CAAC,CAAC,SAAS,KACnB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAC7D;;;AAIH,QAAA,SAAS,CAAsB,QAAQ,EAAE,aAAa;AACnD,aAAA,IAAI,CACHA,KAAG,CAAC,CAAC,CAAC,KACJ,MAAM,CAAC,IAAI,CACT,4CAA4C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAA,KAAA,EAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAA,WAAA,EAAc,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAA,UAAA,EAAa,CAAC,CAAC,OAAO,CAAC,OAAO,CAAA,CAAE,CAChJ,CACF,EACDJ,KAAG,CAAC,CAAC,CAAsB,KAAK,CAAC,CAAC,OAAO,CAAC,EAC1C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,aAAA,SAAS,CAAC,CAAC,WAAW,KAAI;YACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC;AAC7D,QAAA,CAAC,CAAC;QAEJ,MAAM,QAAQ,GAAG,SAAS,CAAgB,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAC/D,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EACjD,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EACxBI,KAAG,CAAC,CAAC,CAAC,KACJ,MAAM,CAAC,IAAI,CACT,cAAc;YACZ,CAAC,CAAC,KAAK,CAAC,IAAI;YACZ,MAAM;YACN,CAAC,CAAC,KAAK,CAAC,EAAE;YACV,cAAc;YACd,CAAC,CAAC,KAAK,CAAC,UAAU,CACrB,CACF,EACD,KAAK,EAAE,CACR;QAED;AACG,aAAA,IAAI,CACH,MAAM,CAAC,CAAC,CAAgB,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EACtDJ,KAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEzB,aAAA,SAAS,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAErE;aACG,IAAI,CACH,MAAM,CAAC,CAAC,CAAgB,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EACtDA,KAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EACxBI,KAAG,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;AAErE,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AACpB,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACjB,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC5D;AACF,QAAA,CAAC,CAAC;IACN;IAEQ,MAAM,sBAAsB,CAAC,EAAqB,EAAA;QACxD,MAAM,eAAe,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,GAAG,CAAC;;QAGvD,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;;AAGrD,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;QACvD;aAAO;AACL,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC5B,kBAAE;AACE,oBAAA,eAAe,EAAE,KAAK;AACtB,oBAAA,YAAY,EAAE,CAAC;AACf,oBAAA,gBAAgB,EAAE,KAAK;AACvB,oBAAA,OAAO,EAAE,CAAC;AACV,oBAAA,gBAAgB,EAAE,KAAK;AACvB,oBAAA,UAAU,EAAE,KAAK;AACjB,oBAAA,UAAU,EAAE,EAAE;AACd,oBAAA,MAAM,EAAE,GAAG;AACZ;kBACD,KAAK;;YAGT,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;AACvD,gBAAA,KAAK,EAAE,KAAK;AACZ,gBAAA,KAAK,EAAE,gBAAgB;AACxB,aAAA,CAAC;YACF,IAAI,MAAM,EAAE;gBACV,IAAI,eAAe,EAAE;oBACnB,KAAK,MAAM,WAAW,IAAI,EAAE,CAAC,eAAe,EAAE,EAAE;AAC9C,wBAAA,IACE,WAAW;AACX,4BAAA,WAAW,CAAC,QAAQ;4BACpB,WAAW,CAAC,QAAQ,CAAC,KAAK;4BAC1B,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,EAC3C;4BACA,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE;gCACtC,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;oCACxC,MAAM,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;AAC5C,oCAAA,WAAW,CAAC,SAAS,GAAG,UAAU;gCACpC;4BACF;wBACF;oBACF;gBACF;qBAAO;oBACL,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE;wBACtC,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;4BACxC,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;wBACrD;oBACF;gBACF;YACF;iBAAO;gBACL,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;YACvD;QACF;IACF;AAEQ,IAAA,yBAAyB,CAC/B,WAA2B,EAC3B,eAAe,GAAG,IAAI,EAAA;AAEtB,QAAA,IAAI;YACF,MAAM,CAAC,GAAG,CACR,CAAA,sCAAA,EAAyC,WAAW,CAAC,KAAK,CAAA,cAAA,CAAgB,CAC3E;AACD,YAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAC5C,4BAA4B,CAC7B;;AAED,YAAA,WAAW,CAAC,UAAU,GAAG,aAAa;AAEtC,YAAA,SAAS,CAAC,WAAW,EAAE,OAAO;iBAC3B,IAAI;;YAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EACpC,IAAI,CAAC,CAAC,CAAC,EACP,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAEzB,iBAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,gBAAA,MAAM,CAAC,IAAI,CACT,CAAA,yCAAA,EAA4C,WAAW,CAAC,KAAK,CAAA,CAAA,EAAI,WAAW,CAAC,EAAE,CAAA,CAAA,CAAG,EAClF,CAAC,CACF;AACD,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;oBACf,MAAM,EAAE,gBAAgB,CAAC,iBAAiB;AAC1C,oBAAA,OAAO,EAAE,mBAAmB;AAC7B,iBAAA,CAAC,CACH;AACH,YAAA,CAAC,CAAC;AAEJ,YAAA,SAAS,CAAC,WAAW,EAAE,OAAO;AAC3B,iBAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AACtD,iBAAA,SAAS,CAAC,CAAC,CAAC,KAAI;gBACf,MAAM,OAAO,GAAG,CAAA,4BAAA,EAA+B,WAAW,CAAC,KAAK,CAAA,YAAA,EAAe,WAAW,CAAC,EAAE,CAAA,CAAE;AAC/F,gBAAA,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AAC1B,YAAA,CAAC,CAAC;YAEJ,IAAI,eAAe,EAAE;AACnB,gBAAA,SAAS,CAAC,WAAW,EAAE,MAAM;AAC1B,qBAAA,IAAI,CACHA,KAAG,CAAC,MAAK;AACP,oBAAA,MAAM,CAAC,IAAI,CACT,CAAA,4BAAA,EAA+B,WAAW,CAAC,KAAK,CAAA,gBAAA,EAAmB,WAAW,CAAC,EAAE,CAAA,CAAE,CACpF;AACH,gBAAA,CAAC,CAAC,EACF,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;qBAElD,SAAS,CAAC,MAAK;AACd,oBAAA,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,4BAA4B,CAC7B;oBACD,IAAI,CAAC,sBAAsB,EAAE;AAC/B,gBAAA,CAAC,CAAC;YACN;AAEA,YAAA,SAAS,CAAe,WAAW,EAAE,SAAS;iBAC3C,IAAI;AACH;;;;;AAKK;YACLJ,KAAG,CAAC,CAAC,CAAe,KAAK,CAAC,CAAC,IAAI,CAAC,EAChC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAElD,iBAAA,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE7D,YAAA,OAAO,WAAW;QACpB;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,IAAI,CAAC,uDAAuD,EAAE,CAAC,CAAC;AACvE,YAAA,OAAO,IAAI;QACb;IACF;IAEQ,sBAAsB,GAAA;QAC5B,IAAI,aAAa,GAAG,2CAA2C;QAC/D,IAAI,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;YAC3C,aAAa;AACX,gBAAA,yEAAyE;QAC7E;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;IAC9D;AAEA;;;;;AAKG;IACK,MAAM,WAAW,CAAC,QAA2B,EAAA;AACnD,QAAA,IAAI;AACF,YAAA,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE;AAC1C,YAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;AAC1C,YAAA,MAAM,QAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC;AACzC,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC;AAAE,QAAA,MAAM;AACN,YAAA,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC;QACvC;IACF;AAEA;;;AAGG;IACK,MAAM,YAAY,CAAC,QAA2B,EAAA;AACpD,QAAA,IAAI;AACF,YAAA,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE;AAC5C,YAAA,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;AAC5C,YAAA,MAAM,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC;AAC1C,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;;;YAG/B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACnC;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC,CAAC;QAC3C;IACF;8GAz2BW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cADN,MAAM,EAAA,CAAA,CAAA;;2FACnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACdlC;;;;;;AAMG;MAEU,qBAAqB,CAAA;AADlC,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;AACtC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAkItD,IAAA;AAhIC;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;IACH,cAAc,GAAA;QACZ,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ;YAC9B,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,OAAO,EAAE,CAAC,KAAK,CAAC;YAClB;AACA,YAAA,IAAI,MAAM,CAAC,KAAK,KAAK,YAAY,EAAE;AACjC,gBAAA,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B;AACA,YAAA,MAAM,CAAC,IAAI,CACT,6DAA6D,CAC9D;AACD,YAAA,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;AACnC,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;;;;AASG;AACK,IAAA,aAAa,CACnB,MAAuC,EAAA;AAEvC,QAAA,OAAO,IAAI,UAAU,CAAU,CAAC,UAAU,KAAI;YAC5C,IAAI,IAAI,GAAG,KAAK;AAChB,YAAA,MAAM,CAAC,SAAS,CAAC,MAAK;AACpB,gBAAA,IAAI,IAAI;oBAAE;gBACV,IAAI,GAAG,IAAI;gBACX,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChC,UAAU,CAAC,QAAQ,EAAE;AACvB,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,MAAK;gBACV,IAAI,GAAG,IAAI;AACb,YAAA,CAAC;AACH,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;IACH,QAAQ,GAAA;AACN,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ;QAC9B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,OAAO,EAAE;AACvC,YAAA,OAAO,KAAK;QACd;;QAEA,IACE,CAAC,MAAM,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,EAAE,CAAC,UAAU,KAAK,aAAa;YACtC,CAAC,MAAM,CAAC,EAAE;YACV,CAAC,MAAM,CAAC,EAAE;AACV,YAAA,CAAC,MAAM,CAAC,MAAM,EACd;AACA,YAAA,MAAM,CAAC,IAAI,CACT,6DAA6D,CAC9D;AACD,YAAA,OAAO,KAAK;QACd;QAEA,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,MAAM,CAAC,OAAO,CAAC;;QAGpE,MAAM,CAAC,KAAK,EAAE;;;;;;;AAQd,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,aAAa,CAAC;AACZ,YAAA,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;AACnC,YAAA,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI;AAC7B,YAAA,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;AAChC,SAAA,CAAC,CACH;;;AAID,QAAA,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC;;;;QAKhE,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,MAAM,IAAI,EAAE,EACnB,MAAM,CAAC,QAAQ,CAChB;AAED,QAAA,OAAO,IAAI;IACb;8GApIW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cADR,MAAM,EAAA,CAAA,CAAA;;2FACnB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBADjC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCgDrB,qBAAqB,CAAA;AADlC,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;AA4F5C,IAAA;AA1FC;;;;;;;;;;;;;;;;;;;;;AAqBG;AACH,IAAA,kBAAkB,CAA2C,OAAU,EAAA;QACrE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,qBAAqB,CAAC,EAC7BA,KAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KACX,iBAAiB,IAAI,IAAI,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CACxD,EACD,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC;;;QAG1CA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAmC,CAAC,CACnD;IACH;AAEA;;;;;;;;;;;;;;;;;;AAkBG;IACH,sBAAsB,CAIpB,IAAO,EACP,MAAyB,EACzB,OAAO,GAAG,KAAK,EACf,iBAAiB,GAAG,IAAI,EAAA;AAExB,QAAA,MAAM,aAAa,GAAG,YAAY,EAAE;QAEpC,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CACnC,MAAM,CAAC,qBAAqB,CAAC,EAC7BA,KAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KACX,iBAAiB,IAAI,IAAI,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CACxD,EACD,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,KAAK,aAAa,CAAC,EACtDC,SAAO,CAAC,OAAO,CAAC,EAChB,UAAU,CAAC,MACT;AACE,kBAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE;kBACnD,EAAE,CAAC,IAAI,CAAC,CACb,EACD,IAAI,CAAC,CAAC,CAAC,EACP,MAAM,CAAC,2BAA2B,CAAC,EACnC,MAAM,CAAC,MAAM,CAAC;;YAEdD,KAAG,CAAC,CAAC,IAAI,KAAK,IAA6B,CAAC,CAC7C;AAED,YAAA,UAAU,CAAC,MAAM,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;AAEvD,YAAA,OAAO,UAAU;AACnB,QAAA,CAAC,CAAC;IACJ;8GA5FW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cADR,MAAM,EAAA,CAAA,CAAA;;2FACnB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBADjC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AC/C5B,MAAO,yBAA0B,SAAQ,UAAU,CAAA;AAavD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAbQ,QAAA,IAAA,CAAA,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;AACzD,QAAA,IAAA,CAAA,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC;QACjD,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACjE,IAAA,CAAA,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC/C,aAAa,CAAC,qBAAqB,CACpC;QACgB,IAAA,CAAA,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAChE,IAAA,CAAA,YAAY,GAAG,KAAK;;;AAGX,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,OAAO,EAAQ;AAI9C,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAEG,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AACjD,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;YAC3B;QACF;AACA,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAC5D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAClC;;;;;AAKD,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAEA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC3D,SAAS,CAAC,MAAK;YACd,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,qBAAqB,EAAE;AAC9B,QAAA,CAAC,CAAC;IACN;AAEA,IAAA,mBAAmB,CAAC,IAA0B,EAAA;AAC5C,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;YAC3B;QACF;AACA,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE;YACtC,MAAM,MAAM,GAAG,IAAI,EAAE,aAAa,IAAI,YAAY,EAAE;YACpD,MAAM,QAAQ,GAAyB,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE;YACzE,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC;YAElD,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAiB,CAAC,EAAE;AACvD,gBAAA,IAAI,CAAC,YAAY,GAAG,IAAI;YAC1B;AAEA,YAAA,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;AAChC,YAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AAEzB,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,cAAc,CAAC;AACb,gBAAA,EAAE,EAAE,MAAM;gBACV,OAAO,EAAE,IAAI,CAAC,OAAiB;AAC/B,gBAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;AACtB,aAAA,CAAC,CACH;QACH;IACF;AAEA,IAAA,iBAAiB,CAAC,UAAgC,EAAA;QAChD,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,aAAa,EAAE,UAAU,CAAC;IAC5D;AAEA;;;;;;;;;;AAUG;AACH,IAAA,WAAW,CAAC,UAAgC,EAAA;QAC1C,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC;IACtD;AAEA,IAAA,aAAa,CAAC,IAAiB,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;YAC3B;QACF;AACA,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AACtB,gBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;YACvB;AACA,YAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QACrC;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;AAC1B,gBAAA,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YACrB;QACF;IACF;IAEA,gBAAgB,GAAA;AACd,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU;IACxC;IAEQ,cAAc,CACpB,WAA8B,EAC9B,UAAgC,EAAA;;QAGhC,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;;;AAIrD,QAAA,MAAM,IAAI,GAAG,IAAI,QAAQ,CACvB,IAAI,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CACvD;QACD,IAAI,OAAO,GAAG,CAAC;AACf,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;AACnC,QAAA,OAAO,EAAE;QACT,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC;QACxD,OAAO,IAAI,CAAC;AAEZ,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAClD,YAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd;AAEA,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACjC;IAEQ,sBAAsB,GAAA;AAC5B,QAAA,IAAI,CAAC,aAAa,CAChB,IAAI,UAAU,CAAC,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC,MAAM,CAC5D;IACH;IAEQ,qBAAqB,GAAA;AAC3B,QAAA,IAAI,CAAC,aAAa,CAChB,IAAI,UAAU,CAAC,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAC,MAAM,CAC3D;IACH;8GA7IW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAzB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,yBAAyB,cADZ,MAAM,EAAA,CAAA,CAAA;;2FACnB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBADrC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCNrB,yBAAyB,CAAA;AAPtC,IAAA,WAAA,GAAA;AAQE,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;AACrB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAsB,WAAW,CAAC;AAK/D,IAAA;AANC,IAAA,UAAU;IAGV,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;IACzB;8GANW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECXtC,+aAgBA,EAAA,MAAA,EAAA,CAAA,2CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDPY,qBAAqB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,WAAA,EAAA,YAAA,EAAA,WAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEpB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAPrC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,mBAEjB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EAEtC,CAAC,qBAAqB,CAAC,EAAA,QAAA,EAAA,+aAAA,EAAA,MAAA,EAAA,CAAA,2CAAA,CAAA,EAAA;;;MEiGrB,aAAa,CAAA;AAD1B,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;AAC1B,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;AACzB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;QAC5C,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE;AACtD,QAAA,IAAA,CAAA,mBAAmB,GAAG,MAAM,CAAC,aAAa,CAAC;AAC3C,QAAA,IAAA,CAAA,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC;AACjD,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAClD,QAAA,IAAA,CAAA,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;AACzD,QAAA,IAAA,CAAA,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAC/C,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC7C,QAAA,IAAA,CAAA,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC;AACrD,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAC9D,QAAA,IAAA,CAAA,4BAA4B,GAClC,IAAI,CAAC,mBAAmB,EAAE,4BAA4B;AACtD,YAAA,+BAA+B;QACzB,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC;AACjC,aAAA,MAAM,CAAC,aAAa,CAAC,0BAA0B;AAC/C,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAEvB,QAAA,IAAA,CAAA,mBAAmB,GAAG,YAAY,CAAC,MAAK;AACtC,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,kBAAkB,CAAC,EAC1B,GAAG,CAAC,MAAM,wBAAwB,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAC1E;AACH,QAAA,CAAC,CAAC;;;;;;;;AASF,QAAA,IAAA,CAAA,mBAAmB,GAAG,YAAY,CAChC,MAAK;YACH,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,KAAK,CAAC,uCAAuC,CAAC,EAC9C,SAAS,CAAC,MACR,IAAI,CAAC;AACF,iBAAA,wBAAwB;AACxB,iBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CACnE,CACF;AACH,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB;;;;;AAKD,QAAA,IAAA,CAAA,4BAA4B,GAAG,YAAY,CAAC,MAAK;YAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,kBAAkB,CAAC,EACjE,GAAG,CAAC,MAAM,2BAA2B,EAAE,CAAC,CACzC;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,SAAS,GAAG,YAAY,CAAC,MAAK;YAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CACJ,SAAS,EACT,wBAAwB,EACxB,gBAAgB,EAChB,WAAW,CACZ,EACD,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,CACtB;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,gBAAgB,GAAG,YAAY,CAC7B,MAAK;AACH,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC3B,iBAAA,MAAM,CAAC,aAAa,CAAC,qBAAqB;AAC1C,iBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;AAGhB,YAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CACzC,SAAS,CAAC,CAAC,SAAS,KAClB;AACE,kBAAE,EAAE,CAAC,oBAAoB;kBACvB,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACjE,CACF;;AAGD,YAAA,MAAM,cAAc,GAAG,IAAI,CAAC;AACzB,iBAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;AACxC,iBAAA,IAAI,CACH,IAAI,CAAC,CAAC,CAAC,EACP,KAAK,CAAC,GAAG,CAAC,EACV,GAAG,CAAC,MAAM,IAAI,CAAC,CAChB;YAEH,OAAO,KAAK,CACV,aAAa,EACb,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,EACpD,cAAc,CACf,CAAC,IAAI,CACJ,YAAY,CAAC,CAAC,CAAC,EACf,oBAAoB,EAAE,EACtB,MAAM,CAAC,UAAU,CAAC,EAClB,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CACjD;AACH,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB;AACD,QAAA,IAAA,CAAA,kBAAkB,GAAG,YAAY,CAAC,MAAK;YACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC,EACtB,GAAG,CAAC,MAAM,gCAAgC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAC9D;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,2BAA2B,GAAG,YAAY,CAAC,MAAK;AAC9C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,0BAA0B,CAAC,EAClC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EACrB,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC,CAAC,EAC5B,SAAS,CAAC,CAAC,KAAK,KAAI;;gBAElB,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CACxB,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,EACpC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EACf,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,GAAG,KAAK,CAAC,EACzB,oBAAoB,EAAE,EACtB,GAAG,CAAC,CAAC,gBAAgB,KACnB,wBAAwB,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAC/C,CACF;YACH,CAAC,CAAC,CACH;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,2BAA2B,GAAG,YAAY,CAAC,MAAK;YAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC;;YAEtB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;;AAElC,YAAA,SAAS,CAAC,CAAC,WAAwB,KAAI;gBACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,IAAI,CAAC,CAAC,CAAC,EACP,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,KAAI;AACvB,oBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAC/B,MAAM,CACJ,qBAAqB;;AAErB,oBAAA,2BAA2B,CAE5B,EACD,IAAI,CAAC,CAAC,CAAC,CACR;AACD,oBAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,oBAAoB,CAAC,EAC5B,IAAI,CAAC,CAAC,CAAC;;oBAEP,SAAS,CAAC,MAAM,CAAC;;AAEjB,oBAAAF,SAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC;;AAE1C,oBAAA,QAAQ,CAAC,MAAM,KAAK,CAAC;;oBAErB,UAAU,CAAC,MAAK;AACd,wBAAA,MAAM,KAAK,GAAG,CAAA,kCAAA,EAAqC,IAAI,CAAC,4BAA4B,+BAA+B;AACnH,wBAAA,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;AAEnB,wBAAA,MAAM,IAAI,GAAG;4BACX,WAAW;4BACX,YAAY,EAAE,MAAM,EAAE,YAAY;4BAClC,IAAI,EAAE,QAAQ,CAAC,IAAI;4BACnB,SAAS,EAAE,SAAS,CAAC,SAAS;4BAC9B,KAAK;yBACN;wBAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAC5D,UAAU,CAAC,CAAC,SAAkB,KAAI;AAChC,4BAAA,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,SAAS,CAAC;AACtD,4BAAA,OAAO,EAAE,CAAC,IAAI,CAAC;AACjB,wBAAA,CAAC,CAAC;;AAEF,wBAAA,GAAG,CAAC,MACF,gBAAgB,CAAC;4BACf,MAAM,EAAE,gBAAgB,CAAC,kBAAkB;AAC3C,4BAAA,OAAO,EAAE,sBAAsB;yBAChC,CAAC,CACH,CACF;oBACH,CAAC,CAAC,CACH;gBACH,CAAC,CAAC,CACH;YACH,CAAC,CAAC,CACH;AACH,QAAA,CAAC,CAAC;AACF;;;;;;;;;;;;;;AAcG;AACH,QAAA,IAAA,CAAA,sBAAsB,GAAG,YAAY,CAAC,MAAK;YACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,wBAAwB,CAAC,EAChC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,EACpE,MAAM,CAAC,CAAC,GAAG,aAAa,CAAC,KAAK,aAAa,CAAC,EAC5C,GAAG,CAAC,MAAM,mBAAmB,EAAE,CAAC,CACjC;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,qBAAqB,GAAG,YAAY,CAAC,MAAK;YACxC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,wBAAwB,CAAC,EAChC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC,EACtE,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC,KAAK,eAAe,CAAC,EAChD,GAAG,CAAC,MAAM,qBAAqB,EAAE,CAAC,CACnC;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,yBAAyB,GAAG,YAAY,CAAC,MAAK;AAC5C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,wBAAwB,CAAC,EAChC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAI;AACjB,gBAAA,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,CAAC,MAAM,CAAC;YAC3D,CAAC,CAAC,EACF,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM,KAAK,gBAAgB,CAAC,cAAc,CAAC,EAClE,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC,CAC5B;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,4BAA4B,GAAG,YAAY,CAAC,MAAK;YAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,qBAAqB,CAAC,EAC7B,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,EACvE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,MAAM,KAAK,gBAAgB,CAAC,kBAAkB,CAAC,EACtE,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC,CAC5B;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,gBAAgB,GAAG,YAAY,CAAC,MAAK;YACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,sBAAsB,CAAC,EAC9B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAC3C,oBAAoB,EAAE,EACtB,MAAM,CAAC,MAAM,CAAC,EACd,SAAS,CACP,CAAC,OAAe,KACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;gBAC1C,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,IAAI,EAAE,EAAE,OAAO,EAAE;AAClB,aAAA,CAAC,CAAC,MAAM,CACZ,EACD,GAAG,CAAC,MAAM,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAClD;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,oBAAoB,GAAG,YAAY,CAAC,MAAK;YACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,oBAAoB,CAAC,EAC5B,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC,EACrE,MAAM,CAAC,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,EAC/C,GAAG,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAC9B;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,0BAA0B,GAAG,YAAY,CAAC,MAAK;AAC7C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,GAAG,CAAC,MAAK;AACP,gBAAA,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC;AACtC,oBAAA,OAAO,EAAE,uBAAuB;AAChC,oBAAA,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;AACU,iBAAA,CAAC;AACrC,gBAAA,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC;oBACtC,OAAO,EAAE,cAAc,CAAC,iBAAiB;AACzC,oBAAA,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;AACnC,iBAAA,CAAC;AACF,gBAAA,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,sBAAsB,CAAC;AACxE,YAAA,CAAC,CAAC,EACF,SAAS,CAAC;;;;AAIR,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,MAAM,CAAC,cAAc,CAAC,EACtB,YAAY,CAAC,EAAE,CAAC,EAChB,IAAI,CAAC,CAAC,CAAC,EACP,SAAS,CAAC,MACR,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,CAC/C,EAAE,OAAO,EAAE,cAAc,CAAC,gBAAgB,EAAE,EAC5C,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,IAAI,CAAC,CACxD,CACF,EACD,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAC9C,MAAM,CACJ,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,KACrB,CAAC,CAAC,CAAC,CAAC,eAAe;gBACnB,CAAC,CAAC,eAAe,GAAG,WAAW;gBAC/B,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,IAAI,EAAE,CAC9B,EACD,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,MAAM,6BAA6B,EAAE,CAAC,CAC3C,CACF,CACF;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,gDAAgD,GAAG,YAAY,CAAC,MAAK;YACnE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,6BAA6B,EAAE,oBAAoB,CAAC,EAC3D,GAAG,CAAC,MACF,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAC3C,sBAAsB,EACtB,KAAK,EACL,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,EACD,GAAG,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAC9B;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,YAAY,GAAG,YAAY,CAAC,MAAK;YAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,WAAW,CAAC,EACnB,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC,CAC5B;AACH,QAAA,CAAC,CAAC;;;;;AAKF,QAAA,IAAA,CAAA,0BAA0B,GAAG,YAAY,CAAC,MAAK;AAC7C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,sBAAsB,CAAC,EAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EAC/C,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,CACtB;AACH,QAAA,CAAC,CAAC;AACF;;;;;;;;;;;AAWG;AACH,QAAA,IAAA,CAAA,yBAAyB,GAAG,YAAY,CAAC,MAAK;AAC5C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,KAAI;;AAEpB,gBAAA,IACE,MAAM,KAAK,gBAAgB,CAAC,iBAAiB;AAC7C,oBAAA,IAAI,CAAC,gBAAgB,EAAE,EACvB;AACA,oBAAA,MAAM,CAAC,IAAI,CACT,oFAAoF,CACrF;AACD,oBAAA,OAAO,KAAK;gBACd;AACA,gBAAA,OAAO,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC;AACpD,YAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAC1D;AACH,QAAA,CAAC,CAAC;AACF;;;;;;AAMG;AACH,QAAA,IAAA,CAAA,wBAAwB,GAAG,YAAY,CAAC,MAAK;YAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,MAAM,CACJ,CAAC,EAAE,MAAM,EAAE,KACT,MAAM,KAAK,gBAAgB,CAAC,iBAAiB;gBAC7C,IAAI,CAAC,gBAAgB,EAAE,CAC1B,EACD,GAAG,CAAC,MAAK;AACP,gBAAA,MAAM,CAAC,IAAI,CACT,8DAA8D,CAC/D;YACH,CAAC,CAAC,EACF,GAAG,CAAC,MACF,aAAa,CAAC;AACZ,gBAAA,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,gBAAgB,CAAC,WAAW;AACzC,gBAAA,KAAK,EAAE,CAAC;aACT,CAAC,CACH,CACF;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,0BAA0B,GAAG,YAAY,CACvC,MAAK;AACH,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,gBAAgB,CAAC,EACxB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM,KAAK,gBAAgB,CAAC,WAAW,CAAC,EAC/D,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,MACR,IAAI,CAAC;AACF,iBAAA,MAAM,CAAC,aAAa,CAAC,0BAA0B;AAC/C,iBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAChC,EACD,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CACvD;AACH,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB;AACD;;;;AAIG;AACH,QAAA,IAAA,CAAA,2BAA2B,GAAG,YAAY,CAAC,MAAK;AAC9C,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,aAAa,CAAC,EACrB,MAAM,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,EACtC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,KAAK,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,4BAA4B,EAAE,CAAC,CAC1C;AACH,QAAA,CAAC,CAAC;AACF;;;;;AAKG;AACH,QAAA,IAAA,CAAA,qBAAqB,GAAG,YAAY,CAAC,MAAK;AACxC,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,aAAa,CAAC,EACrB,MAAM,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,EACtC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAI;AAC/B,gBAAA,MAAM,CAAC,IAAI,CACT,CAAA,sCAAA,EAAyC,OAAO,CAAA,CAAA,EAAI,WAAW,CAAA,IAAA,EAAO,gBAAgB,CAAC,OAAO,CAAA,EAAA,CAAI,CACnG;AACH,YAAA,CAAC,CAAC,EACF,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KACxC,KAAK,CAAC,KAAK,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAC3C,SAAS,CAAC,MAAK;gBACb,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE;gBACxD,IAAI,CAAC,OAAO,EAAE;AACZ,oBAAA,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC;AAChE,oBAAA,OAAO,EAAE,CACP,IAAI,CAAC,mBAAmB,CACtB,OAAO,EACP,WAAW,EACX,oDAAoD,CACrD,CACF;gBACH;;gBAEA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,oBAAoB,CAAC,EAC5B,IAAI,CAAC,CAAC,CAAC,EACPA,SAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,EAC1C,GAAG,CAAC,MACF,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CACzD,EACD,GAAG,CAAC,MAAM,oBAAoB,EAAE,CAAC,EACjC,UAAU,CAAC,MAAK;AACd,oBAAA,IAAI,OAAO,GAAG,WAAW,EAAE;AACzB,wBAAA,MAAM,CAAC,IAAI,CACT,yCAAyC,OAAO,CAAA,4BAAA,CAA8B,CAC/E;oBACH;yBAAO;AACL,wBAAA,MAAM,CAAC,KAAK,CACV,mBAAmB,WAAW,CAAA,qCAAA,CAAuC,CACtE;oBACH;AACA,oBAAA,OAAO,EAAE,CACP,IAAI,CAAC,mBAAmB,CACtB,OAAO,EACP,WAAW,EACX,CAAA,+BAAA,EAAkC,WAAW,CAAA,SAAA,CAAW,CACzD,CACF;gBACH,CAAC,CAAC,CACH;YACH,CAAC,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CACnE,CACF,CACF;AACH,QAAA,CAAC,CAAC;AACF;;;;;AAKG;AACH,QAAA,IAAA,CAAA,0BAA0B,GAAG,YAAY,CAAC,MAAK;YAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,mBAAmB,CAAC,EAC3B,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KACb,gBAAgB,CAAC;gBACf,MAAM,EAAE,gBAAgB,CAAC,eAAe;AACxC,gBAAA,OAAO,EAAE,MAAM;aAChB,CAAC,CACH,CACF;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,UAAU,GAAG,YAAY,CACvB,MAAK;AACH,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,SAAS,CAAC,EACjB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAI;AACjB,gBAAA,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC;AACtC,oBAAA,OAAO,EAAE,WAAW;AACpB,oBAAA,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;AACQ,iBAAA,CAAC;YACvC,CAAC,CAAC,CACH;AACH,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB;AACD,QAAA,IAAA,CAAA,uBAAuB,GAAG,YAAY,CACpC,MAAK;AACH,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,sBAAsB,CAAC,EAC9B,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,GAAG,CAAC,EAClC,cAAc,CACZ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAClD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,2BAA2B,CAAC,EAC5D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CACpD,EACD,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,KAC9C,IAAI,CAAC;iBACF,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,oBAAoB,IAAI,EAAE,EAAE;gBAC1D,MAAM,EAAE,QAAQ,CAAC,UAAU;AAC3B,gBAAA,YAAY,EAAE,SAAS;AACvB,gBAAA,aAAa,EAAE,MAAM;AACrB,gBAAA,OAAO,EAAE;AACP,oBAAA,IAAI,EAAE,OAAO;AACb,oBAAA,KAAK,EAAE,eAAe;AACtB,oBAAA,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE;AAC1B,iBAAA;aACF;AACA,iBAAA,IAAI,CACH,UAAU,CAAC,MAAK;gBACd,MAAM,CAAC,KAAK,CACV,CAAA,eAAA,EAAkB,IAAI,CAAC,mBAAmB,EAAE,oBAAoB,CAAA,CAAE,CACnE;AACD,gBAAA,OAAO,KAAK;AACd,YAAA,CAAC,CAAC,CACH,CACJ,CACF;AACH,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB;;;;AAID,QAAA,IAAA,CAAA,qCAAqC,GAAG,YAAY,CAAC,MAAK;YACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC,EACtB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EACnD,SAAS,CAAC,MACR,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,MAAM,CAAC,qBAAqB,CAAC,EAC7B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KACX,iBAAiB,IAAI;AACnB,kBAAE,IAAI,CAAC,eAAe,EAAE;AACxB,kBAAE,IAAI,EAAE,aAAa,CACxB,EACD,MAAM,CAAC,MAAM,CAAC,EACd,GAAG,CAAC,CAAC,EAAE,KAAK,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CACvD,CACF,CACF;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAA,CAAA,mBAAmB,GAAG,YAAY,CAAC,MAAK;YACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC,EACtB,cAAc,CACZ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,EAChD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,EACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,qBAAqB,CAAC,CACvD,EACD,MAAM,CAAC,CAAC,KAAK,SAAS,EAAE,eAAe,CAAC,KAAI;gBAC1C,IAAI,eAAe,EAAE;AACnB,oBAAA,MAAM,CAAC,IAAI,CACT,CAAA,gFAAA,CAAkF,CACnF;gBACH;AACA,gBAAA,OAAO,SAAS,IAAI,CAAC,eAAe;AACtC,YAAA,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAC/D,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;;AAEjC,YAAA,UAAU,CAAC,CAAC,IAAI;;;;;;YAMd,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC,IAAI,CAC9C,SAAS,CAAC,CAAC,OAAO,KAChB,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAClE,EACD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;;;;;;AAMlE,YAAA,cAAc,EAAE,EAChB,SAAS,CAAC,yBAAyB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CACtD,CACF,CACF;AACH,QAAA,CAAC,CAAC;AAgCH,IAAA;IA9BS,gBAAgB,GAAA;QACtB,OAAO,gBAAgB,CAAC,OAAO,IAAI,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE;IACzE;AAEA;;;;AAIG;AACK,IAAA,mBAAmB,CACzB,OAAe,EACf,WAAmB,EACnB,eAAuB,EAAA;QAEvB,OAAO,OAAO,GAAG;AACf,cAAE,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,EAAE,WAAW,EAAE;cACnD,mBAAmB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACtD;AAEQ,IAAA,kBAAkB,CAAC,IAAmB,EAAA;AAC5C,QAAA,IAAI;YACF,MAAM,EAAE,GAAG,QAAQ,CAAC,cAAc,CAChC,IAAI,CAAC,mBAAmB,EAAE,uBAAuB;AAC/C,gBAAA,0BAA0B,CACD;YAC7B,EAAE,EAAE,aAAa,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC;QAC3C;AAAE,QAAA,MAAM;;QAER;IACF;8GA1oBW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAAb,aAAa,EAAA,CAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB;;;ACjFK,MAAO,UAAW,SAAQ,UAAU,CAAA;AAsBxC,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAtBD,QAAA,IAAA,CAAA,MAAM,GAAG,KAAK,CAAC;QAEf,IAAA,CAAA,SAAS,GAAG,CAAC;QAEJ,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC;QACxD,IAAA,CAAA,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC1D,aAAa,CAAC,uBAAuB,CACtC;QACgB,IAAA,CAAA,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACxD,aAAa,CAAC,mBAAmB,CAClC;QACgB,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;QAGxD,IAAA,CAAA,eAAe,GAAG,QAAQ,CACzC,KAAK,CACH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,EACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CACrC,CACF;AAIC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;AAEnD,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;;QAGA,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,eAAe,EAAE;YACtB,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;oBAC1B,IAAI,CAAC,oBAAoB,EAAE;gBAC7B;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;YACpC,IAAI,KAAK,EAAE;gBACT,SAAS,CAAC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9C;AACF,QAAA,CAAC,CAAC;;;;AAKF,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAACE,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;AAE/B,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,EAAEA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aACjE,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IAClC;IAEQ,WAAW,GAAA;AACjB,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC7B;QACF;QACA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;IACxC;AAEA;;AAEG;IACK,oBAAoB,GAAA;AAC1B,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;QAClB,IAAI,CAAC,oBAAoB,EAAE;IAC7B;AAEA;;AAEG;IACK,oBAAoB,GAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,WAAW,EAAE;;;YAGlB,IAAI,CAAC,SAAS,GAAG,UAAU,CACzB,MAAM,IAAI,CAAC,cAAc,EAAE,EAC3B,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAC1B;QACH;IACF;AAEA;;;AAGG;AACK,IAAA,eAAe,CAAC,SAAiB,EAAA;AACvC,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D;IAEQ,WAAW,GAAA;AACjB,QAAA,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;AAClC,QAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;IAC9B;IAEQ,IAAI,GAAA;QACV,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,WAAW,EAAE;IACpB;IAEA,KAAK,GAAA;QACH,IAAI,CAAC,WAAW,EAAE;;;QAGlB,IAAI,CAAC,oBAAoB,EAAE;IAC7B;IAEQ,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE;YAC3B;QACF;;AAEA,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,SAAS,GAAG,0BAA0B;QAC3C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AACzC,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC;QAEpC,IAAI,YAAY,CAAC,aAAa,KAAK,aAAa,CAAC,WAAW,EAAE;YAC5D,QAAQ,CAAC,eAAe,EAAE;QAC5B;AAEA,QAAA,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,MAAK;YACrC,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE;;gBAExB,IAAI,CAAC,WAAW,EAAE;AAClB,gBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;oBACf,MAAM,EAAE,gBAAgB,CAAC,GAAG;oBAC5B,OAAO,EAAE,eAAe,IAAI,CAAC,WAAW,EAAE,CAAA,wBAAA,EAA2B,0BAA0B,CAAA,QAAA,CAAU;AAC1G,iBAAA,CAAC,CACH;AACD,gBAAA,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;YACpC;iBAAO;AACL,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC;YACtC;QACF,CAAC,EAAE,IAAI,CAAC;IACV;8GAjJW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAV,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cADG,MAAM,EAAA,CAAA,CAAA;;2FACnB,UAAU,EAAA,UAAA,EAAA,CAAA;kBADtB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCdrB,sBAAsB,CAAA;AADnC,IAAA,WAAA,GAAA;AAEW,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAEtB,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,gBAAgB,CAAC;;;;;;;;;;;;;;AAe1D,QAAA,IAAA,CAAA,iBAAiB,GAAG,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAChE,SAAS,CAAC,CAAC,OAAO,KAChB;cACI,IAAI,CAAC;iBACF,MAAM,CAAC,mBAAmB;iBAC1B,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;cACjD,EAAE,CAAC,CAAC,CAAC,CACV,EACD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC/C;AACQ,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAChC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CACzB,qBAAqB,EAAE,EACvB,oBAAoB,EAAE,CACvB,CACF;AACQ,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,oBAAoB,EAAE,CAAC,CACvE;AACQ,QAAA,IAAA,CAAA,oBAAoB,GAAG,QAAQ,CAAC,OAAO;AAC9C,YAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;AAC9B,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;SACpC,CAAC;iGAAC;AACJ,IAAA;AAxCU,IAAA,MAAM;;;;;;;;;;;;;;AAiBN,IAAA,iBAAiB;8GAlBf,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,sBAAsB,cADT,MAAM,EAAA,CAAA,CAAA;;2FACnB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACO5B,MAAO,kBAAmB,SAAQ,UAAU,CAAA;AAQhD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QART,IAAA,CAAA,SAAS,GAAG,KAAK;QAET,IAAA,CAAA,IAAI,GAAG,CAAC;QACR,IAAA,CAAA,IAAI,GAA2B,SAAS;AACxC,QAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,KAAK,EAAE;QACvB,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAIvE,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;AAEA,QAAA,KAAK,CACH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EACzE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAEjD,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;IACvC;AAEA,IAAA,OAAO,CAAC,IAAgB,EAAA;QACtB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AAExB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AAChC,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE;AAClC,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;YACtB,MAAM,CAAC,IAAI,CAAC,CAAA,sCAAA,EAAyC,IAAI,CAAC,IAAI,CAAA,CAAE,CAAC;YACjE,IAAI,CAAC,eAAe,EAAE;QACxB;aAAO,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE;AACvC,YAAA,MAAM,CAAC,KAAK,CACV,CAAA,qDAAA,EAAwD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAA,CAAE,CACxF;AACD,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AACnE,YAAA,IAAI,CAAC,IAAI,GAAG,SAAS;AACrB,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;QACxB;aAAO;YACL,IAAI,CAAC,kBAAkB,EAAE;QAC3B;IACF;IAEQ,kBAAkB,GAAA;AACxB,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,cAAc,CAAC;AACb,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AAC/C,SAAA,CAAC,CACH;IACH;AAEA,IAAA,KAAK,CAAC,IAAgB,EAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE;YAChC,IAAI,CAAC,kBAAkB,EAAE;AACzB,YAAA,MAAM,CAAC,IAAI,CACT,CAAA,6CAAA,EAAgD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAA,CAAE,CAChF;AACD,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;QACvB;aAAO;AACL,YAAA,MAAM,CAAC,IAAI,CACT,CAAA,uCAAA,EAA0C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAA,CAAE,CAC1E;AACD,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;YACtB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;IAEA,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd;QACF;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,QAAA,IAAI,CAAC,IAAI,GAAG,SAAS;AACrB,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;IACxB;IAEQ,eAAe,GAAA;AACrB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd;QACF;QACA,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,kBAAkB,CAAC,GAAG,GAAG,yBAAyB,GAAG,MAAM;AAChE,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,cAAc,CAAC;AACb,YAAA,OAAO,EAAE,IAAI,CAAC,kBAAkB,CAAC,GAAG;AACpC,YAAA,QAAQ,EAAE,CAAC;AACZ,SAAA,CAAC,CACH;IACH;8GArGW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cADL,MAAM,EAAA,CAAA,CAAA;;2FACnB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACdlC;AACO,MAAM,SAAS,GAAG,CAAC,CAAM,EAAE,CAAM,KAAI;IAC1C,IAAI,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,IAAI;;IAGxB,IACE,OAAO,CAAC,KAAK,QAAQ;AACrB,QAAA,CAAC,KAAK,IAAI;QACV,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI,EACV;;AAEA,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE;AACnE,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACjC,gBAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAAE,oBAAA,OAAO,KAAK;YAC1C;AACA,YAAA,OAAO,IAAI;QACb;;QAGA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,QAAA,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;AAAE,YAAA,OAAO,KAAK;AAE/C,QAAA,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE;;AAEvB,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;AACjD,gBAAA,OAAO,KAAK;YACd;AACA,YAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;AAC9B,gBAAA,OAAO,KAAK;YACd;QACF;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,OAAO,KAAK;AACd,CAAC;;AC9BK,MAAO,mBAAoB,SAAQ,UAAU,CAAA;AAWjD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAXF,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,OAAO,EAAgB;QAE1C,IAAA,CAAA,KAAK,GAAG,KAAK;QACb,IAAA,CAAA,MAAM,GAAG,CAAC;QACV,IAAA,CAAA,QAAQ,GAAG,EAAsB;QACjC,IAAA,CAAA,SAAS,GAAG,KAAK;QACjB,IAAA,CAAA,SAAS,GAAG,EAAE;QACd,IAAA,CAAA,IAAI,GAA8B,EAAE;QAC3B,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAIvE,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;AACA,QAAA,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;AACxC,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7C,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IAClC;IAEO,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAsB;AACtC,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;AACnB,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;AACtB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC;AACf,QAAA,IAAI,CAAC,IAAI,GAAG,EAAE;IAChB;IAEQ,YAAY,GAAA;QAClB,IAAI,CAAC,KAAK,EAAE;AACZ,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;IACvB;AAEA;;;AAGG;AACH,IAAA,qBAAqB,CAAC,IAAgB,EAAA;;AAEpC,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,YAAY,EAAE;QACrB;;AAGA,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD;AAEA;;;AAGG;AACH,IAAA,oBAAoB,CAAC,IAAgB,EAAA;;AAEnC,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,YAAY,EAAE;QACrB;AAEA,QAAA,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;;AAErD,QAAA,IAAI,CAAC,QAAQ,GAAG,YAAgC;IAClD;;AAIO,IAAA,oBAAoB,CAAC,IAAgB,EAAA;;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;QAErB,MAAM,QAAQ,GAAG,CAAC;QAClB,MAAM,OAAO,GAAG,CAAC;AACjB,QAAA,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI;AAChC,QAAA,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO;AACrC,QAAA,MAAM,cAAc,GAAG,cAAc,GAAG,UAAU;;QAGlD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CACrB,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC;AACrE,YAAA,cAAc,CACjB;;QAGD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;;AAGxC,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;;;QAKzB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE;AACpC,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;AACtB,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB;;;;;;;AAOI;AAEJ;;;AAGG;YACH,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9D,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBACtB,IAAI;gBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;AAClB,aAAA,CAAC;YACF,IAAI,CAAC,KAAK,EAAE;QACd;aAAO,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;AACzC,YAAA,MAAM,CAAC,KAAK,CACV,CAAA,sCAAA,EAAyC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAA,CAAE,CAC3E;YACD,IAAI,CAAC,KAAK,EAAE;QACd;IACF;8GA9HW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cADN,MAAM,EAAA,CAAA,CAAA;;2FACnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACgBlC,MAAM,YAAY,GAAG;AACnB,IAAA;AACE,QAAA,OAAO,EAAE,kBAAkB;AAC5B,KAAA;CACF;AAGK,MAAO,iBAAkB,SAAQ,UAAU,CAAA;AAa/C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;QAbQ,IAAA,CAAA,kBAAkB,GACjC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC;AAC5B,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,kBAAkB,CAAC;AACxC,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;QAC1C,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxD,QAAA,IAAA,CAAA,sBAAsB,GAAG,IAAI,GAAG,EAG9C;QAID,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;QACA,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,UAAU,EAAE;IACnB;IAEU,YAAY,GAAA;QACpB,IAAI,CAAC,YAAY,CAAC;AACf,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7B,aAAA,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAC9D;IAEU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,qBAAqB;aAC1C,IAAI,CAAC,oBAAoB,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrD,aAAA,SAAS,CAAC,CAAC,SAAS,KAAI;YACvB,IAAI,CAAC,iBAAiB,EAAE;YACxB,IAAI,SAAS,EAAE;gBACb,IAAI,CAAC,oBAAoB,EAAE;YAC7B;AACF,QAAA,CAAC,CAAC;AAEJ,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC;AAC1B,aAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;AACxC,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAEvB,QAAA,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW;AACpC,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;AAE3C,QAAA,IACE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS;AACrC,YAAA,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAC7B;YACA,IAAI,CAAC,gBAAgB,EAAE;QACzB;AAEA,QAAA,YAAY,CAAC,aAAa,GAAG,aAAa,CAAC,aAAa;IAC1D;IAEQ,wBAAwB,CAC9B,IAAY,EACZ,QAAiC,EAAA;QAEjC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC;IACjD;IAEQ,gBAAgB,GAAA;QACtB;AACG,aAAA,cAAc,CACb,IAAI,CAAC,YAAY,EAAE,uBAAuB;AACxC,YAAA,0BAA0B;cAE5B,MAAM,EAAE;IACd;IAEQ,oBAAoB,GAAA;AAC1B,QAAA,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC;QAC5C,IAAI,YAAY,GAAY,IAAI;QAChC,IAAI,CAAC,wBAAwB,CAAC,cAAc,EAAE,CAAC,IAAI,KAAI;AACrD,YAAA,IAAI;AACF,gBAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;oBAC5B;gBACF;gBACA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBAE7B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE;AAClC,oBAAA,IAAI,IAAI,EAAE,KAAK,EAAE;AACf,wBAAA,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,iBAAiB,EAChC,CAAA,EAAG,IAAI,CAAC,KAAK,CAAA,CAAE,EACf,IAAI,CACL;wBACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAChE;oBACH;yBAAO;AACL,wBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC;wBAChC,YAAY,GAAG,IAAI;AAEnB,wBAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;oBACtD;gBACF;qBAAO;;gBAEP;YACF;YAAE,OAAO,CAAC,EAAE;AACV,gBAAA,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACf,gBAAA,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC;YAC/B;AACF,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,qBAAqB,CAA2B,IAAO,EAAA;AAC7D,QAAA,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;YACxD;QACF;QACA,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC;IAClD;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE;IACrC;AAEQ,IAAA,yBAAyB,CAAC,IAAiB,EAAA;AACjD,QAAA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAE7B,QAAA,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;AAC9B,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B;QACF;AAEA,QAAA,QAAQ,IAAI,CAAC,CAAC,CAAC;AACb,YAAA,KAAK,eAAe,CAAC,uBAAuB,EAAE;gBAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC/B,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,6DAA6D;AAC3D,oBAAA,SAAS,CACZ;gBACD;YACF;AACA,YAAA,KAAK,eAAe,CAAC,QAAQ,EAAE;AAC7B,gBAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC;gBACpC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,EAAE;oBAC3D,QAAQ,CAAC,QAAiB,CAAC;gBAC7B;gBACA;YACF;AACA,YAAA,KAAK,eAAe,CAAC,OAAO,EAAE;;AAE5B,gBAAA,IAAI,MAAM,CAAC,SAAS,EAAE;AACpB,oBAAA,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAChC;gBACH;gBACA;YACF;YACA,KAAK,eAAe,CAAC,aAAa;gBAChC,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,eAAe,CAAC;AAC3D,gBAAA,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,IAAI,CAAC;gBAC7C;YACF,KAAK,eAAe,CAAC,YAAY;gBAC/B,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC;AAC1D,gBAAA,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC5C;YACF,KAAK,eAAe,CAAC,YAAY;gBAC/B,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC;AAC1D,gBAAA,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC5C;YACF,KAAK,eAAe,CAAC,WAAW;gBAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC;AAC1D,gBAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC5B;YACF,KAAK,eAAe,CAAC,aAAa;gBAChC,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,iBAAiB,CAAC;AAC7D,gBAAA,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;gBAC7B;YACF,KAAK,eAAe,CAAC,iBAAiB;AACpC,gBAAA,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC;gBACrC;AACF,YAAA,KAAK,eAAe,CAAC,WAAW,EAAE;AAChC,gBAAA,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC;AAC1C,gBAAA,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,uBAAuB,EACvB,cAAc,CACf;gBACD,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,cAAc,CAAC;AAC1D,gBAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,cAAc,CAAC;gBACnD;YACF;YACA,KAAK,eAAe,CAAC,eAAe;AAClC,gBAAA,IAAI,MAAM,CAAC,SAAS,EAAE;oBACpB,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,2BAA2B,EAC3B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAChC;gBACH;gBACA;YACF,KAAK,eAAe,CAAC,QAAQ;AAC3B,gBAAA,IAAI,MAAM,CAAC,SAAS,EAAE;oBACpB,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,oBAAoB,EACpB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAChC;gBACH;gBACA;YACF,KAAK,eAAe,CAAC,qBAAqB;AACxC,gBAAA,MAAM,CAAC,OAAO,CACZ,GAAG,WAAW,CAAC,WAAW,EAC1B,iCAAiC,EACjC,OAAO,CACR;gBACD;AACF,YAAA;gBACE,MAAM,CAAC,IAAI,CAAC,CAAA,sCAAA,EAAyC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAE,CAAC;;IAErE;8GA9NW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cADJ,MAAM,EAAA,CAAA,CAAA;;2FACnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACQ5B,MAAO,wBAAyB,SAAQ,UAAU,CAAA;AAC7C,IAAA,WAAW;AACX,IAAA,eAAe;AACf,IAAA,UAAU;AAGnB,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AANA,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAChC,QAAA,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,yBAAyB,CAAC;AACnD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;QACrC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAIvE,IAAI,CAAC,IAAI,EAAE;;AAGX,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AAC7B,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBACpB;YACF;AACA,YAAA,MAAM,CAAC,cAAc,GAAG,SAAS;AACjC,YAAA,MAAM,CAAC,MAAM,GAAG,SAAS;AACzB,YAAA,MAAM,CAAC,MAAM,GAAG,SAAS;AACzB,YAAA,MAAM,CAAC,aAAa,GAAG,SAAS;AAChC,YAAA,MAAM,CAAC,eAAe,GAAG,SAAS;AAClC,YAAA,MAAM,CAAC,SAAS,GAAG,SAAS;AAC5B,YAAA,MAAM,CAAC,UAAU,GAAG,SAAS;AAC7B,YAAA,MAAM,CAAC,UAAU,GAAG,SAAS;AAC7B,YAAA,MAAM,CAAC,WAAW,GAAG,SAAS;AAChC,QAAA,CAAC,CAAC;IACJ;IAEU,IAAI,GAAA;QACZ,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACrD;QACF;AACA,QAAA,MAAM,CAAC,cAAc,GAAG,MAAK;AAC3B,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,gBAAgB,CAAC;gBACf,MAAM,EAAE,gBAAgB,CAAC,cAAc;AACvC,gBAAA,OAAO,EAAE,qBAAqB;AAC/B,aAAA,CAAC,CACH;AACD,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,MAAM,GAAG,MAAK;YACnB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC7B,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,MAAM,GAAG,MAAK;YACnB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC7B,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;QACD,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAI;YAClC,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACjC,YAAA,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC;gBACvC,OAAO,EAAE,cAAc,CAAC,wBAAwB;gBAChD,OAAO,EAAE,EAAE,UAAU,EAAE;AACxB,aAAA,CAAC;YACF,OAAO,CAAA,kBAAA,EAAqB,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAA,CAAE;AAC5D,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,SAAS,GAAG,CAAC,MAAc,KAAI;AACpC,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAA,eAAA,EAAkB,MAAM,CAAA,CAAE;AACnC,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,UAAU,GAAG,MAAK;AACvB,YAAA,IAAI,CAAC;AACF,iBAAA,MAAM,CAAC,aAAa,CAAC,iBAAiB;iBACtC,IAAI,CACH,IAAI,CAAC,CAAC,CAAC,EACP,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EACrC,SAAS,CAAC,CAAC,IAAI,KACb,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,IAAI,CAAC,YAAY,CAAA,WAAA,CAAa,CAAC,CAC1D,EACD,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;AAE3B,iBAAA,SAAS,EAAE;AAChB,QAAA,CAAC;QACD,MAAM,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;AAC3C,QAAA,MAAM,CAAC,WAAW,GAAG,CAAC,IAAY,KAAI;AACpC,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AACnE,QAAA,CAAC;IACH;IAEQ,UAAU,GAAA;AAChB,QAAA,MAAM,CAAC,IAAI,CACT,gEAAgE,CACjE;AACD,QAAA,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC;AAClD,QAAA,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC;AACxD,QAAA,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC;AACzD,QAAA,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC;AACrD,QAAA,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC;AAClE,QAAA,MAAM,CAAC,IAAI,CAAC,wDAAwD,CAAC;IACvE;8GAzFW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cADX,MAAM,EAAA,CAAA,CAAA;;2FACnB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACVlC,MAAM,kBAAkB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU;AAClE,MAAM,cAAc,GAAG,KAAK;AAC5B,MAAM,qBAAqB,GAAG,KAAK;AACnC,MAAM,YAAY,GAAG,KAAK;AAC1B,MAAM,iBAAiB,GAAG,CAAC,GAAG;AAC9B,MAAM,kBAAkB,GAAG,GAAG;AAC9B,MAAM,gBAAgB,GAAG,GAAG;AAC5B,MAAM,gBAAgB,GAAG,GAAG;AAC5B,MAAM,YAAY,GAAG,CAAC;AAGhB,MAAO,YAAa,SAAQ,UAAU,CAAA;AAgE1C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAhEQ,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAClD,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;AAC5C,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACnC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAEhE,QAAA,IAAA,CAAA,WAAW,GAAG;AACrB,YAAA,mBAAmB,CAAC,IAAI;AACxB,YAAA,mBAAmB,CAAC,IAAI;AACxB,YAAA,mBAAmB,CAAC,IAAI;AACxB,YAAA,mBAAmB,CAAC,IAAI;AACxB,YAAA,mBAAmB,CAAC,OAAO;AAC3B,YAAA,mBAAmB,CAAC,SAAS;AAC7B,YAAA,mBAAmB,CAAC,SAAS;AAC7B,YAAA,mBAAmB,CAAC,UAAU;AAC9B,YAAA,mBAAmB,CAAC,SAAS;AAC7B,YAAA,mBAAmB,CAAC,cAAc;AAClC,YAAA,mBAAmB,CAAC,YAAY;AAChC,YAAA,mBAAmB,CAAC,KAAK;AACzB,YAAA,mBAAmB,CAAC,KAAK;AACzB,YAAA,mBAAmB,CAAC,aAAa;SAClC;AACO,QAAA,IAAA,CAAA,aAAa,GAAe,IAAI,CAAC,WAAW;QAC5C,IAAA,CAAA,OAAO,GAAe,YAAY;AAClC,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,OAAO,EAAQ;QAC7B,IAAA,CAAA,wBAAwB,GAAwB,KAAK;QAErD,IAAA,CAAA,4BAA4B,GAAG,CAAC,EAAU,EAAE,EAAU,MAAM;AAClE,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,CAAC,EAAE,qBAAqB;AACxB,YAAA,CAAC,EAAE,qBAAqB;AACzB,SAAA,CAAC;QAEM,IAAA,CAAA,0BAA0B,GAAG,CAAC,EAAU,EAAE,EAAU,MAAM;AAChE,YAAA,CAAC,EAAE,CAAC;AACJ,YAAA,CAAC,EAAE,CAAC;AACL,SAAA,CAAC;AAEM,QAAA,IAAA,CAAA,iBAAiB,GAAY,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACpD,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,GAAG,EAAkB;QACrC,IAAA,CAAA,YAAY,GAAG,GAAG;AAClB,QAAA,IAAA,CAAA,OAAO,GAAa,CAAC,GAAG,kBAAkB,CAAC;;;;QAKlC,IAAA,CAAA,aAAa,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAChD,IAAA,CAAA,eAAe,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAClD,IAAA,CAAA,cAAc,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QACjD,IAAA,CAAA,SAAS,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAA,CAAA,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAA,CAAA,cAAc,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AACjD,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;AAChC,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;AAEvC,QAAA,IAAA,CAAA,YAAY,GAAiB;AACnC,YAAA,MAAM,EAAE,CAAC;AACT,YAAA,MAAM,EAAE,CAAC;AACT,YAAA,YAAY,EAAE,CAAC;AACf,YAAA,WAAW,EAAE,CAAC;AACd,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,SAAS,EAAE,CAAC;SACb;QAIC,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;AACA,QAAA,MAAM,wBAAwB,GAAG,SAAS,CACxC,QAAQ,EACR,kBAAkB,CACnB,CAAC,IAAI,CACJH,KAAG,CAAC,MAAM,QAAQ,CAAC,eAAe,KAAK,QAAQ,CAAC,EAChD,MAAM,CAAC,MAAM,CAAC,CACf;AACD,QAAA,MAAM,yBAAyB,GAAG,SAAS,CACzC,QAAQ,EACR,kBAAkB,CACnB,CAAC,IAAI,CACJA,KAAG,CAAC,MAAM,QAAQ,CAAC,eAAe,KAAK,SAAS,CAAC,EACjD,MAAM,CAAC,MAAM,CAAC,EACd,SAAS,CAAC,IAAI,CAAC,CAChB;AAED,QAAA,IAAI,CAAC,wBAAwB,GAAG,KAAK,CACnC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,OAAO,EACZ,wBAAwB,EACxB,IAAI,CAAC,QAAQ,CACd;QAED,KAAK,CACH,yBAAyB,EACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAExE,aAAA,IAAI,CACH,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAC1BG,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAEzB,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IAClC;AAEA,IAAA,eAAe,CAAC,IAAgB,EAAA;AAC9B,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI;IAC3B;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK;IAChC;IAEQ,KAAK,GAAA;AACX,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;QACxB,IAAI,CAAC,KAAK,EAAE;YACV;QACF;AACA,QAAA,IAAI,CAAC,OAAO,GAAG,YAAY;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;;AAGnB,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AACtB,QAAA,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,kBAAkB,CAAC;AAEtC,QAAA,KAAK,CACH,kBAAkB,CAAC,KAAK,CAAC,EACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAElD,aAAA,IAAI,CACHE,cAAY,CAAC,kBAAkB,CAAC,EAChCF,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;aAEzC,SAAS,CAAC,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;AAEzD,QAAA,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;AACrC,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;IAC5B;AAEA;;;;;;;;;AASG;AACK,IAAA,kBAAkB,CAAC,YAA8B,EAAA;QACvD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB;AAChD,QAAA,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,YAAY;QAEhD,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,iBAAiB,EAAE;YAC9D,UAAU;YACV,WAAW;AACZ,SAAA,CAAC;AAEF,QAAA,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM;AACrC,QAAA,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW;AAE3C,QAAA,MAAM,KAAK,GACT,UAAU,GAAG,cAAc,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU;AAEzE,QAAA,MAAM,WAAW,GAAG,UAAU,GAAG,KAAK;AACtC,QAAA,MAAM,YAAY,GAAG,WAAW,GAAG,KAAK;QAExC,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,WAAW,IAAI,CAAC;QAC3C,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,YAAY,IAAI,CAAC;AAE7C,QAAA,MAAM,MAAM,GAAG,KAAK,GAAG,WAAW;AAClC,QAAA,MAAM,MAAM,GAAG,MAAM,GAAG,YAAY;QAEpC,OAAO;YACL,SAAS;YACT,SAAS;YACT,MAAM;YACN,MAAM;YACN,WAAW;YACX,YAAY;SACb;IACH;AAEQ,IAAA,yBAAyB,CAAC,YAA8B,EAAA;AAC9D,QAAA,IAAI,CAAC,iBAAiB,GAAG,YAAY,CAAC,qBAAqB,EAAE;QAC7D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC;;;;;;;;;QAWzD,IAAI,CAAC,4BAA4B,GAAG,CAAC,CAAC,EAAE,CAAC,KAAI;AAC3C,YAAA,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,WAAW;AAChD,YAAA,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,YAAY;YAEjD,IACE,WAAW,GAAG,GAAG;AACjB,gBAAA,WAAW,GAAG,GAAG;AACjB,gBAAA,WAAW,GAAG,GAAG;gBACjB,WAAW,GAAG,GAAG,EACjB;gBACA,OAAO;AACL,oBAAA,OAAO,EAAE,KAAK;AACd,oBAAA,CAAC,EAAE,qBAAqB;AACxB,oBAAA,CAAC,EAAE,qBAAqB;iBACzB;YACH;YACA,OAAO;AACL,gBAAA,OAAO,EAAE,IAAI;gBACb,CAAC,EAAE,WAAW,GAAG,cAAc;gBAC/B,CAAC,EAAE,WAAW,GAAG,cAAc;aAChC;AACH,QAAA,CAAC;QAED,IAAI,CAAC,0BAA0B,GAAG,CAAC,CAAC,EAAE,CAAC,KAAI;YACzC,MAAM,WAAW,GAAG,CAAC,IAAI,GAAG,GAAG,YAAY,CAAC,WAAW,CAAC;YACxD,MAAM,WAAW,GAAG,CAAC,IAAI,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC;YACzD,OAAO;gBACL,CAAC,EAAE,WAAW,GAAG,YAAY;gBAC7B,CAAC,EAAE,WAAW,GAAG,YAAY;aAC9B;AACH,QAAA,CAAC;IACH;AAEQ,IAAA,aAAa,CAAC,IAAiB,EAAA;AACrC,QAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC;IACzC;AAEQ,IAAA,cAAc,CAAC,KAAuB,EAAA;AAC5C,QAAA,SAAS,CAAC,MAAM,EAAE,MAAM;AACrB,aAAA,IAAI,CACH,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EACrBA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAEzC,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEvD,QAAA,IAAI,CAAC,gCAAgC,CAAC,KAAK,CAAC;AAC5C,QAAA,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC;AACvC,QAAA,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC;AAC/C,QAAA,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC;IACjC;AAEQ,IAAA,0BAA0B,CAAC,EAAE,OAAO,EAAE,OAAO,EAAS,EAAA;AAC5D,QAAA,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY;QAElE,OAAO;AACL,YAAA,CAAC,EAAE,CAAC,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,IAAI,MAAM;AAC/D,YAAA,CAAC,EAAE,CAAC,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,IAAI,MAAM;SAC/D;IACH;AAEQ,IAAA,0BAA0B,CAAC,EAAE,OAAO,EAAE,OAAO,EAAc,EAAA;AACjE,QAAA,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY;QAElE,OAAO;AACL,YAAA,CAAC,EAAE,CAAC,OAAO,GAAG,SAAS,IAAI,MAAM;AACjC,YAAA,CAAC,EAAE,CAAC,OAAO,GAAG,SAAS,IAAI,MAAM;SAClC;IACH;AAEQ,IAAA,mBAAmB,CAAC,gBAAkC,EAAA;AAC5D,QAAA,MAAM,aAAa,GAAG,CAAC,KAAY,KAAI;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;AACjC,YAAA,IAAI,MAAM,KAAK,SAAS,EAAE;AACxB,gBAAA,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC;gBAC1C;YACF;YACA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC;AAC9C,QAAA,CAAC;AAED,QAAA,MAAM,WAAW,GAAG,CAAC,KAAY,KAAI;AACnC,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;AACnD,YAAA,IAAI,MAAM,KAAK,SAAS,EAAE;AACxB,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;;AAEzB,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACpC;YACA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;AACzC,QAAA,CAAC;AAED,QAAA,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAE,OAAkB,KAAI;;AAEpE,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACvC,IAAI,IAAI,GAAG,CAAC;gBACZ,MAAM,UAAU,GAAG,CAAC;AACpB,gBAAA,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;AACxB,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;;;AAGnD,gBAAA,IAAI,MAAM,KAAK,SAAS,EAAE;oBACxB;gBACF;AACA,gBAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,CAAA,CAAG,CAAC;gBACtC,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS;AAE3B,gBAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC;AACtB,gBAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC;gBAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;gBACnC,IAAI,IAAI,CAAC;gBACT,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;gBACnC,IAAI,IAAI,CAAC;AACT,gBAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC3B,IAAI,IAAI,CAAC;;gBAET,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;gBAC5C,IAAI,IAAI,CAAC;AACT,gBAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;AAC1C,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;YACjC;AACF,QAAA,CAAC;AAED,QAAA,SAAS,CAAa,gBAAgB,EAAE,YAAY;AACjD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;YACf,IAAI,CAAC,WAAW,EAAE;AAClB,YAAA,MAAM,OAAO,GAAc,CAAC,CAAC,cAAc;;AAE3C,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACvC,gBAAA,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3B;AACA,YAAA,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;AAC1B,YAAA,aAAa,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC;YAC9C,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,UAAU;AAC/C,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,MAAM,OAAO,GAAc,CAAC,CAAC,cAAc;AAC3C,YAAA,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;AAExB,YAAA,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC;;AAG5C,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACvC,gBAAA,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACzB;YAEA,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,WAAW;AAChD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;YACf,aAAa,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC;YAC/C,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;IACN;IAEA,WAAW,GAAA;QACT,MAAM,CAAC,KAAK,EAAE;IAChB;AAEA,IAAA,aAAa,CAAC,CAAS,EAAE,CAAS,EAAE,MAAc,EAAE,MAAc,EAAA;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC;AAC7D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa;QAE/B,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAC/B,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACjC;AAEA,IAAA,aAAa,CAAC,MAAc,EAAE,CAAS,EAAE,CAAS,EAAA;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;QACjC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC;AACvC,QAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACjC;AAEA,IAAA,WAAW,CAAC,MAAc,EAAE,CAAS,EAAE,CAAS,EAAA;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;QACjC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC;AACrC,QAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACjC;AAEA,IAAA,cAAc,CAAC,KAAa,EAAE,CAAS,EAAE,CAAS,EAAA;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc;QAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACjC;AAEQ,IAAA,mBAAmB,CAAC,OAAe,EAAE,CAAS,EAAE,CAAS,EAAA;AAC/D,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,aAAa,EAAE;YAC5C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAChD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,eAAe,EAAE;YAC9C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC;QACrD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,eAAe,EAAE;YAC9C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC;QACrD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,YAAY,EAAE;YAC3C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;QAClD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,WAAW,EAAE;YAC1C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QACjD;IACF;AAEQ,IAAA,iBAAiB,CAAC,OAAe,EAAE,CAAS,EAAE,CAAS,EAAA;AAC7D,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,aAAa,EAAE;YAC5C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAClD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,eAAe,EAAE;YAC9C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC;QACvD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,eAAe,EAAE;YAC9C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC;QACvD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,YAAY,EAAE;YAC3C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;QACpD;AACA,QAAA,IAAI,OAAO,GAAG,gBAAgB,CAAC,WAAW,EAAE;YAC1C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD;IACF;AAEQ,IAAA,2BAA2B,CAAC,gBAAkC,EAAA;AACpE,QAAA,SAAS,CAAa,gBAAgB,EAAE,WAAW;AAChD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;AACnD,YAAA,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC;YAClD,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,WAAW;AAChD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,SAAS;AAC9C,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,OAAO;AAC5C,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;YACvE,CAAC,CAAC,cAAc,EAAE;AACpB,QAAA,CAAC,CAAC;IACN;AAEQ,IAAA,gCAAgC,CAAC,gBAAkC,EAAA;AACzE,QAAA,SAAS,CAAa,gBAAgB,EAAE,YAAY;AACjD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;YACf,IAAI,CAAC,WAAW,EAAE;AAClB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc;YAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC;AACxC,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/B,YAAA,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;AACzD,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAa,gBAAgB,EAAE,YAAY;AACjD,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc;YAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC;AACxC,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/B,YAAA,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;AAC3D,QAAA,CAAC,CAAC;IACN;;AAGQ,IAAA,mBAAmB,CAAC,OAAe,EAAA;QACzC,QACE,CAAC,OAAO,IAAI,gBAAgB,IAAI,OAAO,IAAI,gBAAgB;YAC3D,OAAO,KAAK,YAAY;IAE5B;AAEQ,IAAA,UAAU,CAAC,CAAgB,EAAA;AACjC,QAAA,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;YAChE,OAAO,eAAe,CAAC,UAAU;AAC9B,aAAA,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc;YACzE,OAAO,eAAe,CAAC,YAAY;AAChC,aAAA,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YACjE,OAAO,eAAe,CAAC,QAAQ;;YAC5B,OAAO,CAAC,CAAC,OAAO;IACvB;AAEQ,IAAA,sBAAsB,CAAC,aAAyB,EAAA;AACtD,QAAA,MAAM,iBAAiB,GAAG,aAAa,CAAC,GAAG,CACzC,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,CAAC,CACjC;AAED,QAAA,MAAM,QAAQ,GAAG,CAAC,KAAoB,KAAI;AACxC,YAAA,MAAM,IAAI,GAAa,KAAK,CAAC,IAAgB;YAC7C,MAAM,mBAAmB,GACtB,KAAK,CAAC,MAAsB,EAAE,SAAS,KAAK,OAAO;YACtD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC;AAEjD,YAAA,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE;gBAC/B,MAAM,CAAC,IAAI,CACT,QAAQ,EACR,IAAI,EACJ,6EAA6E,CAC9E;AACD,gBAAA,OAAO,mBAAmB;YAC5B;AAEA,YAAA,OAAO,mBAAmB,IAAI,CAAC,QAAQ;AACzC,QAAA,CAAC;AACD,QAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;IAChC;AAEQ,IAAA,eAAe,CAAC,OAA2C,EAAA;QACjE,MAAM,MAAM,GAAG,OAAO,KAAK,MAAM,KAAK,CAAC;AAEvC,QAAA,SAAS,CAAgB,QAAQ,EAAE,SAAS;AACzC,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;gBACb;YACF;YAEA,MAAM,eAAe,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO;YAE9C,MAAM,aAAa,GACjB,CAAC,CAAC,OAAO,KAAK,mBAAmB,CAAC,KAAK;AACvC,gBAAA,CAAC,CAAC,OAAO,KAAK,mBAAmB,CAAC,KAAK;AACzC,YAAA,IAAI,eAAe,IAAI,aAAa,EAAE;gBACpC;YACF;AAEA,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY;AACjC,YAAA,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,OAAO;YAChC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAC/B,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7B,YAAA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;;;YAGlC,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,SAAS,EAAE;AAC3C,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;gBAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC;gBACtC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC;AAClD,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;YACjC;AACA,YAAA,IACE,IAAI,CAAC,OAAO,CAAC,mBAAmB;gBAChC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC,EACnC;gBACA,CAAC,CAAC,cAAc,EAAE;YACpB;AACF,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAgB,QAAQ,EAAE,OAAO;AACvC,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;gBACb;YACF;AACA,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;AAC7B,YAAA,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK;YAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7B,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC;AAChC,YAAA,IACE,IAAI,CAAC,OAAO,CAAC,mBAAmB;gBAChC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC,EACnC;gBACA,CAAC,CAAC,cAAc,EAAE;YACpB;AACF,QAAA,CAAC,CAAC;AAEJ,QAAA,SAAS,CAAgB,QAAQ,EAAE,UAAU;AAC1C,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC7C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAI;AACf,YAAA,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;gBACb;YACF;AACA,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;YAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC;YACtC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC;AACnC,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,QAAA,CAAC,CAAC;IACN;8GAhmBW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAZ,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cADC,MAAM,EAAA,CAAA,CAAA;;2FACnB,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACb5B,MAAO,4BAA6B,SAAQ,UAAU,CAAA;AAI1D,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAJQ,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACnC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAIvE,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;;;;;AAMA,QAAA,IAAI,CAAC;aACF,IAAI,CACH,MAAM,CAAC,cAAc,CAAC,EACtBD,WAAS,CAAC,MAAK;;AAEb,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;YAC5B,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;AACtD,YAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAC7C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,qBAAqB,CAAC,EACtD,SAAS,CACV;AACD,YAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,cAAc,CAC5C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,EACpD,SAAS,CACV;AACD,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CACvC,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE;AACjC,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,QAAQ,EAAE,IAAI;AACf,aAAA,CAAC,EACF,cAAc,CACZ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAClD,mBAAmB,EACnB,kBAAkB,CACnB,EACDF,KAAG,CACD,CAAC,CACC,IAAI,EACJ,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,KACC,IAAI,CAAC,YAAY,CAAC;gBAChB,IAAI;gBACJ,eAAe;gBACf,YAAY;gBACZ,kBAAkB;gBAClB,iBAAiB;aAClB,CAAC,CACL,CACF;QACH,CAAC,CAAC,EACFG,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAEzB,SAAS,CAAC,CAAC,IAAI,KACd,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,kBAAkB,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CACpD,CACF;IACL;AAEA;;;;AAIG;IACK,cAAc,CACpB,WAAgC,EAChC,SAAiB,EAAA;AAEjB,QAAA,OAAO,WAAW,CAAC,IAAI,CACrB,MAAM,CAAC,OAAO,CAAC,EACfG,MAAI,CAAC,CAAC,CAAC,EACPN,KAAG,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,EACjCO,WAAS,CAAqB,SAAS,CAAC,CACzC;IACH;AAEQ,IAAA,YAAY,CAAC,MAA0B,EAAA;AAC7C,QAAA,MAAM,EACJ,IAAI,EACJ,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GAClB,GAAG,MAAM;QAEV,MAAM,EACJ,OAAO,EACP,cAAc,EACd,eAAe,EACf,UAAU,EACV,WAAW,EACX,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,OAAO,GACR,GAAG,IAAI,CAAC,eAAe;QAExB,OAAO;YACL,YAAY;YACZ,kBAAkB;YAClB,iBAAiB;YACjB,OAAO;YACP,UAAU;YACV,WAAW;YACX,MAAM,EAAE,eAAe,CAAC,KAAK;YAC7B,UAAU,EAAE,MAAM,CAAC,gBAAgB;YACnC,eAAe;YACf,MAAM;YACN,WAAW;YACX,YAAY,EAAE,eAAe,CAAC,YAAY;YAC1C,OAAO;AACP,YAAA,GAAG,EAAE,oBAAoB;YACzB,cAAc;SACf;IACH;8GA5HW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,4BAA4B,cADf,MAAM,EAAA,CAAA,CAAA;;2FACnB,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBADxC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACuHlC;AACkE;AAClE,SAAS,iBAAiB,CAAC,GAAW,EAAA;AACpC,IAAA,IAAI;AACF,QAAA,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;IAC9B;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClC;AACF;AAoOA,MAAM,gBAAgB,GAAG,EAAE;AAC3B,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,uBAAuB,GAAG,EAAE;AAClC,MAAM,gBAAgB,GAAG,IAAI;AAC7B;;;;;;;AAOG;AACH,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC;IACxD,kBAAkB;IAClB,sBAAsB;IACtB,oBAAoB;AACrB,CAAA,CAAC;AACF;AACA;AACA,MAAM,mBAAmB,GAAG,iCAAiC;MAGhD,6BAA6B,CAAA;AA2TxC,IAAA,WAAA,GAAA;AA1TiB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;AAC1B,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAC7C,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ;AAE/C;;;;;AAKG;AACc,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAElD;;;;;;;AAOG;QACc,IAAA,CAAA,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC1D,aAAa,CAAC,sBAAsB,CACrC;QACgB,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACtD,aAAa,CAAC,kBAAkB,CACjC;QACgB,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACvD,aAAa,CAAC,mBAAmB,CAClC;AACD;;;;;;AAMG;QACc,IAAA,CAAA,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACjD,aAAa,CAAC,aAAa,CAC5B;;QAEgB,IAAA,CAAA,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAChD,aAAa,CAAC,YAAY,CAC3B;QACgB,IAAA,CAAA,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CACrD,aAAa,CAAC,iBAAiB,CAChC;QAEO,IAAA,CAAA,OAAO,GAAwB,IAAI;AAE3C;;;;;;AAMG;QACK,IAAA,CAAA,gBAAgB,GAAG,KAAK;AAEhC;;;;;;;AAOG;QACc,IAAA,CAAA,aAAa,GAC5B,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAChC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,YAAY,IAAI,IAAI,CAAC,EAClD,IAAI,CACF,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,IAAI,GAAG,EAC1B,IAAI,CACL,EACD,SAAS,CAAkC,IAAI,CAAC,CACjD;AAEH;;;;;AAKG;AACc,QAAA,IAAA,CAAA,iBAAiB,GAAwB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAC1E,MAAM,CAAC,cAAc,CAAC,EACtBC,QAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,KAAK,UAAU,CAAC,EAC/C,IAAI,CAAC,CAAC,CAAC,EACP,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,KACf,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,MAAM,CAAC,gBAAgB,CAAC,EACxBA,QAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAC1B,IAAI,CAAC,CAAC,CAAC,CACR,CACF,CACF;;;;AAKgB,QAAA,IAAA,CAAA,mBAAmB,GAAiB;AACnD,YAAA,EAAE,EAAE,iBAAiB;YACrB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SAClD;AACgB,QAAA,IAAA,CAAA,wBAAwB,GAAiB;AACxD,YAAA,EAAE,EAAE,uBAAuB;YAC3B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SAClD;AACgB,QAAA,IAAA,CAAA,qBAAqB,GAAiB;AACrD,YAAA,EAAE,EAAE,mBAAmB;YACvB,KAAK,EAAE,IAAI,CAAC,iBAAiB;SAC9B;AACgB,QAAA,IAAA,CAAA,6BAA6B,GAAiB;AAC7D,YAAA,EAAE,EAAE,wBAAwB;YAC5B,KAAK,EAAE,IAAI,CAAC;AACT,iBAAA,MAAM,CAAC,aAAa,CAAC,qBAAqB;iBAC1C,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;SAClC;AACgB,QAAA,IAAA,CAAA,mBAAmB,GAAiB;AACnD,YAAA,EAAE,EAAE,iBAAiB;AACrB,YAAA,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;SACvE;AAED;;;;;;;;;;AAUG;AACc,QAAA,IAAA,CAAA,YAAY,GAA4B;AACvD,YAAA;AACE,gBAAA,EAAE,EAAE,kBAAkB;AACtB,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,UAAU,EAAE;AACV,oBAAA;AACE,wBAAA,EAAE,EAAE,yBAAyB;wBAC7B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACxD,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,uBAAuB;wBAC3B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AACtD,qBAAA;;;;;;;;AAQD,oBAAA;AACE,wBAAA,EAAE,EAAE,iBAAiB;AACrB,wBAAA,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC,EACtB,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;4BAC5B,MAAM;AACN,4BAAA,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAA,EAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI;AAC5D,yBAAA,CAAC,CAAC,CACJ;AACF,qBAAA;AACF,iBAAA;AACF,aAAA;AACD,YAAA;AACE,gBAAA,EAAE,EAAE,sBAAsB;AAC1B,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,QAAQ,EAAE;AACR,oBAAA;wBACE,IAAI,EAAE,IAAI,CAAC,mBAAmB;wBAC9B,EAAE,EAAE,IAAI,CAAC,wBAAwB;AACjC,wBAAA,EAAE,EAAE,qBAAqB;AAC1B,qBAAA;AACD,oBAAA;wBACE,IAAI,EAAE,IAAI,CAAC,6BAA6B;wBACxC,EAAE,EAAE,IAAI,CAAC,mBAAmB;AAC5B,wBAAA,EAAE,EAAE,qBAAqB;AAC1B,qBAAA;AACF,iBAAA;AACD,gBAAA,UAAU,EAAE;AACV,oBAAA,IAAI,CAAC,mBAAmB;AACxB,oBAAA;AACE,wBAAA,EAAE,EAAE,eAAe;wBACnB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAChD,qBAAA;AACD,oBAAA,IAAI,CAAC,wBAAwB;AAC7B,oBAAA,IAAI,CAAC,6BAA6B;AAClC,oBAAA;AACE,wBAAA,EAAE,EAAE,mBAAmB;wBACvB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAC9D,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,gBAAgB;wBACpB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACjD,qBAAA;AACD,oBAAA,IAAI,CAAC,mBAAmB;AACxB,oBAAA;AACE,wBAAA,EAAE,EAAE,iBAAiB;wBACrB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CACvDA,QAAM,CAAC,OAAO,CAAC,EACf,IAAI,CAAC,CAAC,CAAC,EACPC,gBAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,EAClE,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM;4BACtB,MAAM,EAAE,GAAG,CAAC,KAAK;4BACjB,YAAY,EAAE,GAAG,CAAC,YAAY;AAC9B,4BAAA,GAAG,MAAM;AACV,yBAAA,CAAC,CAAC,CACJ;AACF,qBAAA;AACF,iBAAA;AACF,aAAA;AACD,YAAA;AACE,gBAAA,EAAE,EAAE,oBAAoB;AACxB,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,UAAU,EAAE;AACV,oBAAA;AACE,wBAAA,EAAE,EAAE,gBAAgB;AACpB,wBAAA,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAACD,QAAM,CAAC,OAAO,CAAC,CAAC;AAC7D,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,aAAa;wBACjB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAC9C,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,iBAAiB;AACrB,wBAAA,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,CAAC;AACpE,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,qBAAqB;AACzB,wBAAA,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,CAAC;AACjE,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,oBAAoB;AACxB,wBAAA,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,CAAC;AAChE,wBAAA,IAAI,EAAE,MAAM;AACb,qBAAA;;;;;;;;;;AAUD,oBAAA;AACE,wBAAA,EAAE,EAAE,uBAAuB;wBAC3B,KAAK,EAAE,IAAI,CAAC;AACT,6BAAA,MAAM,CAAC,aAAa,CAAC,0BAA0B;AAC/C,6BAAA,IAAI,CACHA,QAAM,CAAC,OAAO,CAAC,EACf,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,OAAO;AACT,4BAAA,iBAAiB,EAAE,IAAI,CAAC,OAAO,EAAE,iBAAiB,IAAI,CAAC;AACvD,4BAAA,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,IAAI,IAAI;AACnD,yBAAA,CAAC,CAAC,CACJ;AACJ,qBAAA;AACF,iBAAA;AACF,aAAA;AACD,YAAA;AACE,gBAAA,EAAE,EAAE,sBAAsB;AAC1B,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,QAAQ,EAAE;AACR,oBAAA;wBACE,IAAI,EAAE,IAAI,CAAC,qBAAqB;AAChC,wBAAA,EAAE,EAAE,sBAAsB;AAC3B,qBAAA;AACF,iBAAA;AACD,gBAAA,UAAU,EAAE;AACV,oBAAA;AACE,wBAAA,EAAE,EAAE,uBAAuB;wBAC3B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAClD,qBAAA;AACD,oBAAA;AACE,wBAAA,EAAE,EAAE,eAAe;wBACnB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CACvB,MAAM,CAAC,cAAc,CAAC,EACtBA,QAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,KAAK,UAAU,CAAC,CAChD;AACF,qBAAA;AACD,oBAAA,IAAI,CAAC,qBAAqB;;;;;AAK1B,oBAAA;AACE,wBAAA,EAAE,EAAE,gBAAgB;AACpB,wBAAA,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAC9DA,QAAM,CAAC,OAAO,CAAC,EACf,IAAI,CAAC,CAAC,CAAC,EACPC,gBAAc,CAAC,IAAI,CAAC,aAAa,CAAC,EAClC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM;AACzB,4BAAA,cAAc,EAAE,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC;AACjD,4BAAA,eAAe,EAAE,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC;AACnD,4BAAA,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC;;;;4BAI7C,kBAAkB,EAAE,IAAI,CAAC;AACvB,kCAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB;AAC/D,kCAAE,IAAI;AACT,yBAAA,CAAC,CAAC,CACJ;AACF,qBAAA;AACF,iBAAA;AACF,aAAA;SACF;AAGC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;;;AAG7B,YAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;AAC1B,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;AACpB,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAC1B,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACjC;QACF;QACA,IAAI,CAAC,IAAI,EAAE;IACb;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI;YACF,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,mBAAmB,CAAC;AAC1D,YAAA,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;AAAE,gBAAA,OAAO,QAAQ;AACpD,YAAA,MAAM,KAAK,GAAGC,EAAM,EAAE;AACtB,YAAA,YAAY,CAAC,OAAO,CAAC,mBAAmB,EAAE,KAAK,CAAC;AAChD,YAAA,OAAO,KAAK;QACd;AAAE,QAAA,MAAM;;;YAGN,OAAOA,EAAM,EAAE;QACjB;IACF;IAEQ,IAAI,GAAA;;;;;;;;;;;;AAYV,QAAA,IAAI,CAAC;aACF,IAAI,CACH,MAAM,CAAC,yBAAyB,CAAC,EACjCF,QAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,CAAC,EACrCL,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAEzB,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;AAsBvC,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAEA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aACzD,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9C,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAEA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC5D,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;;;AAInD,QAAA,SAAS,CAAC,MAAM,EAAE,UAAU;AACzB,aAAA,IAAI,CAACA,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACjD;IAEQ,YAAY,GAAA;;AAElB,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;AAE1B,QAAA,MAAM,EAAE,GAAGO,EAAM,EAAE;AACnB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAC5B,QAAA,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;AACvC,QAAA,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE;;;;;;;;;;AAW9B,QAAA,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,gBAAgB;AAC7C,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC5B,MAAM,UAAU,GAAG,cAAc,GAAG,CAAC,GAAG,aAAa;AAErD,QAAA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB;QAE7C,IAAI,CAAC,OAAO,GAAG;YACb,EAAE;YACF,SAAS;YACT,aAAa;YACb,UAAU;;;;;AAKV,YAAA,iBAAiB,EAAE,UAAU;AAC7B,YAAA,GAAG,EAAE,CAAC;YACN,GAAG;AACH,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,YAAY,EAAE,uBAAuB;AACrC,YAAA,iBAAiB,EAAE,CAAC;AACpB,YAAA,aAAa,EAAE,IAAI;AACnB,YAAA,YAAY,EAAE,CAAC;YACf,KAAK;SACN;;;;;AAMD,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,iBAAiB,CAAC;AACpB,aAAA,IAAI,CAACF,QAAM,CAAC,OAAO,CAAC;aACpB,SAAS,CAAC,MAAK;YACd,IAAI,IAAI,CAAC,OAAO;AAAE,gBAAA,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;QACpD,CAAC,CAAC,CACL;QACD,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;YAC7D,IAAI,IAAI,CAAC,OAAO;AAAE,gBAAA,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,cAAc;QAC/D,CAAC,CAAC,CACH;AACD,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,iBAAiB,CAAC;aACpB,IAAI,CAACA,QAAM,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;aAC7B,SAAS,CAAC,MAAK;YACd,IAAI,IAAI,CAAC,OAAO;AAAE,gBAAA,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,cAAc;QAC/D,CAAC,CAAC,CACL;;;;AAID,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;YACxD,IAAI,IAAI,CAAC,OAAO;AAAE,gBAAA,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;QAC/C,CAAC,CAAC,CACH;;;;;;;;AASD,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC;aACpC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAI;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE;AACnB,YAAA,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE;AACnC,gBAAA,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;AAC1B,gBAAA,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;AACrB,gBAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,OAAO;gBACP,MAAM;gBACN,IAAI;AACL,aAAA,CAAC;QACJ,CAAC,CAAC,CACL;;;;;;;QAQD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,SAAS,KAAI;YAC9C,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,KAAI;gBACvC,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;AACrD,gBAAA,GAAG,CAAC,GAAG,CACL,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;oBAC9B,IAAI,CAAC,IAAI,CAAC,OAAO;wBAAE;oBACnB,IAAI,QAAQ,EAAE;;;;;;AAMZ,wBAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;4BACxD;wBACF,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;wBAC7C;oBACF;AACA,oBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAC5C;AACD,oBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;wBAAE;oBAC5D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC;gBACrC,CAAC,CAAC,CACH;AACH,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;;;;AAKF,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;AAC1B,aAAA,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CACnE;AAED,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,EAAE;AAEjD,QAAA,IAAI,CAAC,aAAa,CAChB,wBAAwB,EACxB;AACE,YAAA,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;YAC/C,UAAU,EAAE,MAAM,CAAC,gBAAgB;;;;;AAKnC,YAAA,gBAAgB,EAAE;gBAChB,KAAK,EAAE,MAAM,CAAC,UAAU;gBACxB,MAAM,EAAE,MAAM,CAAC,WAAW;AAC3B,aAAA;YACD,SAAS,EAAE,SAAS,CAAC,SAAS;AAC9B,YAAA,cAAc,EAAE,gBAAgB;;;;AAIhC,YAAA,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;;;;;AAK7B,YAAA,IAAI,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;AACxC,SAAA;;;;AAID,QAAA,aAAa,CACd;;AAGD,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AACtB,aAAA,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAC9D;;AAGD,QAAA,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,YAAY,CAAC;AACf,aAAA,IAAI,CACH,UAAU,CAAC,gBAAgB,CAAC,EAC5BA,QAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAExC,aAAA,SAAS,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CACtD;IACH;AAEQ,IAAA,UAAU,CAAC,MAAiB,EAAA;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;QACnB,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO;;;;;;;;;;;;;;AAehC,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC/C,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE;AACzC,QAAA,MAAM,eAAe,GACnB,YAAY,EAAE,MAAM,KAAK;cACrB,YAAY,CAAC;cACb,SAAS;QACf,MAAM,eAAe,GACnB,cAAc,IAAI,cAAc,KAAK,gBAAgB,CAAC,IAAI;AAE5D,QAAA,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE;AACzC,YAAA,SAAS,EAAE,EAAE;YACb,MAAM;AACN,YAAA,IAAI,eAAe,GAAG,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;YAChE,IAAI,eAAe,IAAI;AACrB,kBAAE,EAAE,iBAAiB,EAAE,eAAe;kBACpC,EAAE,CAAC;AACP,YAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACpC,SAAA,CAAC;QAEF,GAAG,CAAC,WAAW,EAAE;AACjB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;IACrB;AAEA;;;;;;AAMG;AACK,IAAA,aAAa,CACnB,KAAa,EACb,KAA8B,EAC9B,MAAe,EAAA;QAEf,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;;;;QAInB,MAAM,GAAG,GAAG,MAAM,IAAI,WAAW,CAAC,GAAG,EAAE;AACvC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;AACjE,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;AACzC,QAAA,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,GAAG;IACtC;AAEA;;;;;;AAMG;AACK,IAAA,cAAc,CACpB,MAAoB,EACpB,SAAiB,EACjB,WAAoB,EAAA;QAEpB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AACnB,QAAA,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE;AAC7B,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAC7B,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CACzD;AACD,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;AAClD,QAAA,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC;AACzC,QAAA,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,CAAC,QAAQ,EACf,IAAI,CAAC,OAAO,CAAC,KAAK,EAClB,YAAY,EACZ,UAAU,CACX;AACD,QAAA,IAAI,CAAC,aAAa,CAAC,oBAAoB,EAAE;AACvC,YAAA,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;YAC1B,OAAO,EAAE,SAAS,GAAG,CAAC;YACtB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU;YACV,MAAM;YACN,QAAQ;AACT,SAAA,CAAC;IACJ;AAEA;;;;;;;;;;;;;;;AAeG;AACK,IAAA,qBAAqB,CAAC,OAAsC,EAAA;AAClE,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO;AACtB,QAAA,IAAI,CAAC,CAAC;YAAE;AAER,QAAA,MAAM,CAAC,GAAG,OAAO,IAAI,EAAE;AACvB,QAAA,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE;;;AAG7B,QAAA,MAAM,IAAI,GAAG,CAAC,IAAY,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC;AAC9D,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,OAAO,EACP,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAC7D;AACD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,QAAQ,EACR,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CACpE;AACD,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;QAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;AAE5C,QAAA,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO;AACjC,QAAA,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ;AACjC,QAAA,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO;;AAGnC,QAAA,MAAM,OAAO,GAAG;AACd,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,iBAAiB,EAAE,SAAS;;AAE5B,YAAA,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,CAC9C;;YAED,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC;;YAE1D,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;SACxD;;;AAID,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE;QACrC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE;AACjD,YAAA,MAAM,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE;YACjC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAA,EAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,GAAA,CAAK,GAAG,IAAI;AACzE,SAAA,CAAC;;;QAGF,IAAI,CAAC,gBAAgB,CACnB,CAAC,EACD,OAAO,EACP,MAAM,EACN,YAAY,EACZ;YACE,GAAG,IAAI,CAAC,sBAAsB,EAAE;AAChC,YAAA,GAAG,OAAO;AACV,YAAA,mBAAmB,EAAE,MAAM;AAC5B,SAAA,EACD,CAAC,EAAE,EAAE,EAAE,wBAAwB,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CACnD;;QAED,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE;AACvD,YAAA,iBAAiB,EAAE,CAAC;AACpB,YAAA,gBAAgB,EAAE,MAAM;AACzB,SAAA,CAAC;;AAGF,QAAA,CAAC,CAAC,iBAAiB,GAAG,GAAG;IAC3B;AAEA;;;;;AAKG;AACK,IAAA,gBAAgB,CACtB,SAAiB,EACjB,WAAmB,EACnB,UAAkB,EAClB,YAAoB,EACpB,MAA+B,EAC/B,UAAA,GAAiC,EAAE,EAAA;AAEnC,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO;AACtB,QAAA,IAAI,CAAC,CAAC;YAAE;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC;AAC3C,QAAA,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE;YAC/B,SAAS,EAAE,CAAC,CAAC,EAAE;YACf,OAAO,EAAE,SAAS,GAAG,CAAC;YACtB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,KAAK,EAAE,MAAM,CAAC,KAAK;AACnB,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,UAAU,EAAE,IAAI;YAChB,WAAW;YACX,YAAY;YACZ,UAAU;YACV,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACtD,YAAA,QAAQ,EAAE,EAAE;AACb,SAAA,CAAC;IACJ;AAEA;AAC0E;IAClE,sBAAsB,GAAA;AAC5B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE;AAC/B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;QAC7B,OAAO;AACL,YAAA,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,IAAI;AAC1B,YAAA,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,IAAI;AACvC,YAAA,IAAI,MAAM,IAAI,EAAE,CAAC;SAClB;IACH;AAEA;AAC0E;IAClE,eAAe,GAAA;AACrB,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,qBAAqB,CAAC;AACvD,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,IAAI;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAG5B;YACD,OAAO;AACL,gBAAA,WAAW,EACT,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,GAAG,MAAM,CAAC,WAAW,GAAG,EAAE;gBAClE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM;AACjC,sBAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAkB,OAAO,CAAC,KAAK,QAAQ;AAChE,sBAAE,EAAE;aACP;QACH;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;AAEQ,IAAA,YAAY,CAAC,OAAyB,EAAA;QAC5C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AACnB,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO;;;;;;;;;;;;AAatB,QAAA,MAAM,WAAW,GAAG,CAClB,IAAyE,KAEzE;AACG,aAAA,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC;aAClC,MAAM,CACL,CAAC,CAAC,KACA,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxD;AAEL,QAAA,MAAM,QAAQ,GAAG,CACf,IAAyE,KAEzE;AACG,aAAA,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC;aAClC,MAAM,CACL,CAAC,CAAC,KACA,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CACvD;AAEL,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;AAC7D,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC;AAC9D,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC;AAC/D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC;AACnE,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,eAAe;;AAG3D,QAAA,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YAC1B,SAAS,EAAE,CAAC,CAAC,EAAE;AACf,YAAA,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;AACZ,YAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,WAAW,EAAE,OAAO,CAAC,MAAM;;;;YAI3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,OAAO;YACP,GAAG;YACH,EAAE;YACF,MAAM;YACN,GAAG;YACH,WAAW,EAAE,MAAM,EAAE,WAAW;AAChC,YAAA,QAAQ,EAAE;gBACR,KAAK,EAAE,MAAM,EAAE,UAAU;gBACzB,MAAM,EAAE,MAAM,EAAE,WAAW;AAC5B,aAAA;AACF,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC;IACjC;IAEQ,iBAAiB,CAAC,GAAoB,EAAE,EAAmB,EAAA;QACjE,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AACnB,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO;;AAGtB,QAAA,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,GAAG,gBAAgB;AAC1C,QAAA,IAAI,QAAQ,KAAK,CAAC,CAAC,KAAK,EAAE;AACxB,YAAA,CAAC,CAAC,KAAK,GAAG,QAAQ;AAClB,YAAA,IAAI,CAAC,KAAK,CACR,QAAQ,GAAG,yBAAyB,GAAG,0BAA0B,EACjE;gBACE,SAAS,EAAE,CAAC,CAAC,EAAE;gBACf,GAAG,EAAE,CAAC,CAAC,GAAG;AACV,gBAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,KAAK,EAAE,EAAE,CAAC,GAAG;gBACb,KAAK,EAAE,EAAE,CAAC,GAAG;AACd,aAAA,CACF;QACH;;AAGA,QAAA,MAAM,GAAG,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,GAAG,uBAAuB;QACzE,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,aAAa;AAC/C,QAAA,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;AAC1B,YAAA,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;gBAC3B,SAAS,EAAE,CAAC,CAAC,EAAE;gBACf,GAAG,EAAE,CAAC,CAAC,GAAG;AACV,gBAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,MAAM,EAAE,CAAC,CAAC,YAAY;AACtB,gBAAA,eAAe,EAAE,GAAG;gBACpB,MAAM,EAAE,GAAG,CAAC,GAAG;gBACf,MAAM,EAAE,GAAG,CAAC,GAAG;AAChB,aAAA,CAAC;QACJ;AACA,QAAA,CAAC,CAAC,MAAM,GAAG,SAAS;IACtB;AAEQ,IAAA,kBAAkB,CAAC,MAAc,EAAA;QACvC,IAAI,IAAI,CAAC,OAAO;AAAE,YAAA,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,MAAM;IACtD;AAEA;;;;AAIG;AACH;;;;AAIG;AACK,IAAA,kBAAkB,CAAC,MAAoB,EAAA;QAC7C,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE;QAC5B,MAAM,GAAG,GAAuB,EAAE;QAClC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;AAC9C,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAClC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAC1C,IAAI,IAAI,KAAK,SAAS;AAAE,gBAAA,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;QAC1D;AACA,QAAA,OAAO,GAAG;IACZ;AAEA;;;;;AAKG;IACK,oBAAoB,GAAA;AAC1B,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CACf;AACzC,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,IAAI;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC;YAC1D,OAAO;AACL,gBAAA,IAAI,EAAE,GAAG,CAAC,IAAI;AACd,gBAAA,QAAQ,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;gBACrC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;gBAC1C,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;gBAChD,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC;gBAC5D,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;;;AAGzC,gBAAA,sBAAsB,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI;AAChD,gBAAA,yBAAyB,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;AACtD,gBAAA,yBAAyB,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;;;;;gBAKtD,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;;;gBAGlC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;aACzC;QACH;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,IAAI;QACb;IACF;AAEA;;;;;;;;;;;;;;;;;AAiBG;AACK,IAAA,qBAAqB,CAAC,YAAoB,EAAA;AAKhD,QAAA,IAAI;YACF,MAAM,IAAI,GAAG,WAAW,CAAC,gBAAgB,CACvC,UAAU,CACoB;YAChC,IAAI,CAAC,IAAI,CAAC,MAAM;AACd,gBAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE;AAevE,YAAA,MAAM,KAAK,GAAG,OAAe;AAC3B,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,WAAW,EAAE,CAAC;AACd,gBAAA,YAAY,EAAE,CAAC;AACf,gBAAA,eAAe,EAAE,CAAC;AAClB,gBAAA,eAAe,EAAE,CAAC;AAClB,gBAAA,UAAU,EAAE,CAAC;AACb,gBAAA,aAAa,EAAE,CAAC;AACjB,aAAA,CAAC;AAEF,YAAA,MAAM,YAAY,GAAG,YAAY,GAAG,CAAC;AAErC,YAAA,MAAM,cAAc,GAAG,KAAK,EAAE;YAC9B,MAAM,cAAc,GAA2B,EAAE;AACjD,YAAA,MAAM,UAAU,GAAG,KAAK,EAAE;YAC1B,MAAM,UAAU,GAA2B,EAAE;AAC7C,YAAA,MAAM,IAAI,GAAmB,EAAE,CAAC;AAEhC,YAAA,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;AACpB,gBAAA,MAAM,IAAI,GAAG,CAAC,CAAC,aAAa,IAAI,OAAO;gBACvC,MAAM,MAAM,GAAG,YAAY,IAAI,CAAC,CAAC,SAAS,GAAG,YAAY;gBACzD,MAAM,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc;gBACnD,MAAM,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc;gBAEnD,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;AACpC,gBAAA,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC;AAC/D,gBAAA,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC;AAC7B,gBAAA,MAAM,GAAG,GAAG,CAAC,CAAC,eAAe,IAAI,CAAC;AAClC,gBAAA,MAAM,GAAG,GAAG,CAAC,CAAC,eAAe,IAAI,CAAC;gBAClC,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAE5B,CAAC,CAAC,KAAK,EAAE;AACT,gBAAA,IAAI,SAAS;oBAAE,CAAC,CAAC,WAAW,EAAE;AAC9B,gBAAA,CAAC,CAAC,YAAY,IAAI,CAAC;AACnB,gBAAA,CAAC,CAAC,eAAe,IAAI,GAAG;AACxB,gBAAA,CAAC,CAAC,eAAe,IAAI,GAAG;AACxB,gBAAA,CAAC,CAAC,UAAU,IAAI,GAAG;AACnB,gBAAA,IAAI,GAAG,GAAG,CAAC,CAAC,aAAa;AAAE,oBAAA,CAAC,CAAC,aAAa,GAAG,GAAG;gBAEhD,MAAM,CAAC,KAAK,EAAE;AACd,gBAAA,IAAI,SAAS;oBAAE,MAAM,CAAC,WAAW,EAAE;AACnC,gBAAA,MAAM,CAAC,YAAY,IAAI,CAAC;AACxB,gBAAA,MAAM,CAAC,eAAe,IAAI,GAAG;AAC7B,gBAAA,MAAM,CAAC,eAAe,IAAI,GAAG;AAC7B,gBAAA,MAAM,CAAC,UAAU,IAAI,GAAG;AACxB,gBAAA,IAAI,GAAG,GAAG,MAAM,CAAC,aAAa;AAAE,oBAAA,MAAM,CAAC,aAAa,GAAG,GAAG;AAE1D,gBAAA,IAAI,GAAG,GAAG,CAAC,EAAE;oBACX,IAAI,CAAC,IAAI,CAAC;AACR,wBAAA,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;wBAC/B,IAAI;AACJ,wBAAA,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAC3B,wBAAA,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE;AAC5C,wBAAA,IAAI,EAAE,MAAM;AACb,qBAAA,CAAC;gBACJ;YACF;AAEA,YAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;YAEhD,OAAO;AACL,gBAAA,SAAS,EACP,cAAc,CAAC,KAAK,GAAG;sBACnB,EAAE,GAAG,cAAc,EAAE,MAAM,EAAE,cAAc;AAC7C,sBAAE,IAAI;gBACV,aAAa,EACX,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;;;;;gBAKrE,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACnC;QACH;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACvE;IACF;AAEQ,IAAA,SAAS,CAAC,MAAgB,EAAA;AAChC,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;QAClE,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;;;;;AAKhD,QAAA,MAAM,IAAI,GAAG,CAAC,CAAS,KAAI;AACzB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YACpD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC9D,QAAA,CAAC;QACD,OAAO;AACL,YAAA,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AACb,YAAA,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AACb,YAAA,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;YACd,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B;IACH;IAEQ,KAAK,CAAC,KAAa,EAAE,IAA6B,EAAA;;;;AAIxD,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CACjB,kBAAkB,CAAC;YACjB,KAAK;YACL,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE;AACvC,SAAA,CAAC,CACH;IACH;8GA3oCW,6BAA6B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAA7B,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,6BAA6B,cADhB,MAAM,EAAA,CAAA,CAAA;;2FACnB,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBADzC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA+oClC;AACA;AACA;AAEA;AAC4C;AAC5C,SAAS,YAAY,CAAC,CAA4C,EAAA;IAChE,IAAI,CAAC,CAAC,EAAE;AACN,QAAA,OAAO,IAAI;IACb;IACA,OAAO,CAAC,CAAC,GAAG,GAAG,CAAA,EAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAA,CAAA,CAAG,GAAG,CAAC,CAAC,IAAI;AAChD;AAEA;;;;AAIG;AACH,SAAS,aAAa,CAAC,KAAc,EAAA;AACnC,IAAA,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;AAAE,QAAA,OAAO,EAAE;IAClD,MAAM,GAAG,GAAiB,EAAE;AAC5B,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE;QACvE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE;YAAE;QAC/C,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE;AAC3B,QAAA,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrC;AACA,IAAA,OAAO,GAAG;AACZ;AAEA;;;;AAIG;AACH,SAAS,eAAe,CACtB,OAA6C,EAC7C,KAAwC,EACxC,YAAoB,EACpB,UAAkB,EAAA;IAElB,IAAI,CAAC,OAAO,EAAE,MAAM;AAAE,QAAA,OAAO,EAAE;IAC/B,MAAM,GAAG,GAAmB,EAAE;AAC9B,IAAA,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,YAAY;QAClE,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,IAAI,UAAU;QAC1D,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM;YAAE;AACxD,QAAA,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;IACtC;AACA,IAAA,OAAO,GAAG;AACZ;;ACjlDO,MAAM,iBAAiB,GAAG;AAC/B,IAAA,eAAe,EAAE,kBAAkB;CAC3B;;MCeG,kBAAkB,CAAA;AAD/B,IAAA,WAAA,GAAA;AAEU,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,mBAAmB,CAAC;AACzC,QAAA,IAAA,CAAA,YAAY,GAAiB;AACnC,YAAA,CAAC,iBAAiB,CAAC,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;SACpE;AA6CF,IAAA;IA3CS,cAAc,CAAC,IAAkB,EAAE,aAAqB,EAAA;AAC9D,QAAA,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI;AACrB,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC3BR,KAAG,CAAC,CAAC,IAAY,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EACvC,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,KAAI;AAC7B,YAAA,OAAO,eAAe,CAAC,aAAa,KAAK,aAAa;QACxD,CAAC,CAAC,CACH;IACH;IAEA,mBAAmB,CAIjB,QAA0B,EAC1B,IAAO,EACP,MAAyB,EACzB,OAAO,GAAG,KAAK,EAAA;AAEf,QAAA,MAAM,aAAa,GAAG,YAAY,EAAE;QACpC,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE;QAEtC,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CACpD,SAAS,CAAC,CAAC,IAAI,KAAI;gBACjB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE;AAC7C,oBAAA,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,IAAI,CAC1D,MAAM,CAAC,MAAM,CAAC,CACf;gBACH;AACA,gBAAA,OAAO,EAAE,CAAC,IAAI,CAAC;AACjB,YAAA,CAAC,CAAC,EACFC,SAAO,CAAC,OAAO,CAAC,EAChB,UAAU,CAAC,CAAC,CAAC,KAAI;AACf,gBAAA,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACf,gBAAA,OAAO,EAAE,CAAC,IAAI,CAAC;AACjB,YAAA,CAAC,CAAC,EACF,IAAI,CAAC,CAAC,CAAC,CACR;YACD,UAAU,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAChC,YAAA,OAAO,UAAU;AACnB,QAAA,CAAC,CAAC;IACJ;8GAhDW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cADL,MAAM,EAAA,CAAA,CAAA;;2FACnB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACD5B,MAAO,gBAAiB,SAAQ,UAAU,CAAA;AAC9C,IAAA,WAAW,GAAG,IAAI,OAAO,EAAQ;AAEjC,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;aACxC,IAAI,CAAC,oBAAoB,EAAE,EAAEE,WAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrD,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;YACvB,IAAI,KAAK,EAAE;gBACT,IAAI,CAAC,YAAY,EAAE;YACrB;AACF,QAAA,CAAC,CAAC;IACN;IAEQ,YAAY,GAAA;AAClB,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;QACpD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC;QAEzD,IAAI,CAAC,OAAO,EAAE;YACZ;QACF;;QAGA,MAAM,WAAW,GAAG,SAAS,CAAa,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAC9DA,WAAS,CAAC,KAAK,CAAC,EAChB,YAAY,CAAC,IAAI,CAAC,CACnB;;AAGD,QAAA,MAAM,UAAU,GAAG,SAAS,CAAa,OAAO,EAAE,WAAW,CAAC,CAAC,IAAI,CACjEA,WAAS,CAAC,KAAK,CAAC,CACjB;AACD,QAAA,MAAM,WAAW,GAAG,SAAS,CAAa,OAAO,EAAE,YAAY,CAAC,CAAC,IAAI,CACnEA,WAAS,CAAC,KAAK,CAAC,CACjB;QACD,MAAM,UAAU,GAAG,SAAS,CAAa,OAAO,EAAE,WAAW,CAAC,CAAC,IAAI,CACjEA,WAAS,CAAC,KAAK,CAAC,EAChB,YAAY,CAAC,GAAG,CAAC,CAClB;;QAGD;aACG,IAAI,CACHK,QAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAC3D,GAAG,CAAC,CAAC,SAAS,KAAI;AAChB,YAAA,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE;AAC5C,gBAAA,KAAK,EAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW;AAC9C,gBAAA,KAAK,EAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,YAAY;AAC/C,gBAAA,MAAM,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,GAAG,UAAU,GAAG,SAAS;AACxD,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;AAEH,aAAA,SAAS,EAAE;;QAGd;AACG,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,SAAS,KAAI;AAChB,YAAA,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM;YAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAClC,YAAA,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE;AAC5C,gBAAA,KAAK,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW;AAC1C,gBAAA,KAAK,EAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,YAAY;gBAC3C,MAAM,EAAE,YAAY,KAAK,CAAC,GAAG,UAAU,GAAG,SAAS;AACpD,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;AAEH,aAAA,SAAS,EAAE;QAEd,IAAI,oBAAoB,GAAG,CAAC;;AAE5B,QAAA,UAAU,CAAC,SAAS,CAAC,CAAC,KAAiB,KAAI;AACzC,YAAA,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM;AACzC,YAAA,IAAI,YAAY,GAAG,CAAC,EAAE;gBACpB;YACF;;YAGA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/B,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AAC1C,gBAAA,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAC/C;;AAGD,YAAA,MAAM,aAAa,GAAG,eAAe,GAAG,oBAAoB;AAC5D,YAAA,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC;;YAGrC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE;AAChC,gBAAA,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,EAAE;oBACjD,KAAK,EAAE,WAAW,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC3B,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS;AAC3C,iBAAA,CAAC;;gBAGF,oBAAoB,GAAG,eAAe;YACxC;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,WAAW,CAAC,SAAS,CAAC,CAAC,KAAiB,KAAI;AAC1C,YAAA,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,EAAE;AACjD,gBAAA,KAAK,EAAE,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/C,gBAAA,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,QAAQ,GAAG,SAAS;AAChD,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,mBAAmB,CACzB,IAAY,EACZ,MAAA,GAAkC,EAAE,EAAA;QAEpC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,MAAM,CAAC;AAC5C,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACtE;8GArHW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAhB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA,CAAA;;2FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACDlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEG;AAEG,MAAO,iBAAkB,SAAQ,UAAU,CAAA;AAkD/C,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAlDQ,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACnC,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;QAGxD,IAAA,CAAA,SAAS,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAU;AAErD;;;;AAIG;QACc,IAAA,CAAA,uBAAuB,GAAG,EAAE;;QAG5B,IAAA,CAAA,WAAW,GAAG,UAAU;AAEzC;;;AAGG;QACc,IAAA,CAAA,0BAA0B,GAAG,KAAK;AAEnD;;AAEG;QACc,IAAA,CAAA,mCAAmC,GAAG,KAAK;AAE5D;;;AAGG;QACc,IAAA,CAAA,mCAAmC,GAAG,MAAM;AAE7D;;;;AAIG;QACc,IAAA,CAAA,aAAa,GAAG,CAAC;;AAG1B,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ;;AAG9B,QAAA,IAAA,CAAA,gBAAgB,GAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACpE,IAAA,CAAA,OAAO,GAAmD,EAAE;AAC5D,QAAA,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE;QAC7B,IAAA,CAAA,WAAW,GAAa,MAAM;QAIpC,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;YACnE;QACF;;AAEA,QAAA,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,mBAAmB;AACxC,aAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC9C,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;;AAGvC,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACzC;IAEQ,YAAY,GAAA;;AAElB,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QACpB,IAAI,CAAC,iBAAiB,EAAE;QAExB,IAAI,CAAC,YAAY,CAAC;AACf,aAAA,IAAI,CACH,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,EACpE,MAAM,CAAC,CAAC,GAAG,aAAa,CAAC,KAAK,aAAa,CAAC,EAC5C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAE/C,aAAA,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACpD;IAEQ,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QACpB,IAAI,CAAC,iBAAiB,EAAE;IAC1B;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AACjE,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE;AACjB,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE;AAClC,QAAA,IAAI,CAAC,WAAW,GAAG,MAAM;IAC3B;AAEA;;;AAGG;AACK,IAAA,WAAW,CAAC,KAAqB,EAAA;QACvC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC,eAAe;AAE1E,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,GAAG,EAAE,eAAe,IAAI,CAAC;YACzB,OAAO,EAAE,OAAO,IAAI,CAAC;YACrB,EAAE,EAAE,cAAc,IAAI,CAAC;AACxB,SAAA,CAAC;;QAGF,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE;YAC5C;QACF;AAEA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE;AACjC,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE;QAEjB,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,CAAC;IACnD;IAEQ,gBAAgB,CACtB,GAAiD,EACjD,aAAqB,EAAA;QAErB,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC;QAC1D,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;IACnC;AAEA;;;;;;;;AAQG;IACK,gBAAgB,CACtB,GAAiD,EACjD,aAAqB,EAAA;AAErB,QAAA,MAAM,eAAe,GACnB,aAAa,GAAG,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC,uBAAuB;AAClE,QAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG,eAAe;QAC1C,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW;QAElD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;QAEhD,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC;;QAG3D,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGnC,QAAA,IAAI,MAAM,GAAG,GAAG,EAAE;AAChB,YAAA,OAAO,UAAU;QACnB;;;;QAKA,IAAI,KAAK,GAAG,GAAG,IAAI,OAAO,KAAK,KAAK,EAAE;AACpC,YAAA,OAAO,UAAU;QACnB;;;AAIA,QAAA,IAAI,KAAK,GAAG,GAAG,IAAI,WAAW,GAAG,GAAG,IAAI,OAAO,KAAK,QAAQ,EAAE;AAC5D,YAAA,OAAO,MAAM;QACf;;;;;AAMA,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CACzC,IAAI,CAAC,gBAAmD,CACzD;QACD,IACE,OAAO,GAAG,GAAG;AACb,YAAA,OAAO,KAAK,MAAM;AAClB,YAAA,WAAW,GAAG,GAAG;YACjB,YAAY,KAAK,CAAC,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EACxC;AACA,YAAA,OAAO,UAAU;QACnB;AAEA,QAAA,OAAO,MAAM;IACf;;;;;;;;AAUA;;;;;;;AAOG;AACK,IAAA,gBAAgB,CAAC,KAAa,EAAA;QACpC,IAAI,KAAK,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;QAC3B,IAAI,KAAK,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;AAC3B,QAAA,OAAO,CAAC,GAAG,GAAG,KAAK,IAAI,GAAG;IAC5B;AAEA;;;;;;;;AAQG;AACK,IAAA,eAAe,CAAC,KAAa,EAAA;QACnC,IAAI,KAAK,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;QAC3B,IAAI,KAAK,GAAG,IAAI;AAAE,YAAA,OAAO,CAAC,KAAK,GAAG,GAAG,IAAI,IAAI;QAC7C,IAAI,KAAK,IAAI,GAAG;AAAE,YAAA,OAAO,CAAC,GAAG,GAAG,KAAK,IAAI,IAAI;AAC7C,QAAA,OAAO,GAAG;IACZ;AAEA;;;;;;;AAOG;AACK,IAAA,iBAAiB,CAAC,KAAa,EAAA;QACrC,IAAI,KAAK,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;QAC3B,IAAI,KAAK,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;AAC3B,QAAA,OAAO,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG;IAC5B;AAEA;;;;;;;AAOG;AACK,IAAA,qBAAqB,CAAC,IAAY,EAAA;QACxC,IAAI,IAAI,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;QAC1B,IAAI,IAAI,GAAG,GAAG;AAAE,YAAA,OAAO,GAAG;AAC1B,QAAA,OAAO,CAAC,IAAI,GAAG,GAAG,IAAI,GAAG;IAC3B;;;;IAMQ,UAAU,CAAC,QAAkB,EAAE,EAAU,EAAA;QAC/C,IAAI,QAAQ,KAAK,MAAM;YAAE;AAEzB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;;AAGtB,QAAA,MAAM,QAAQ,GAAG,QAAQ,KAAK,UAAU;AACxC,QAAA,MAAM,QAAQ,GACZ,IAAI,CAAC,WAAW,KAAK;AACnB,cAAE;kBACE,IAAI,CAAC;kBACL,IAAI,CAAC;AACT,cAAE,IAAI,CAAC,0BAA0B;QAErC,IAAI,GAAG,GAAG,IAAI,CAAC,gBAAgB,GAAG,QAAQ,EAAE;YAC1C;QACF;AAEA,QAAA,IAAI,CAAC,WAAW,GAAG,QAAQ;AAE3B,QAAA,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC;AAC/B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAExE,MAAM,CAAC,IAAI,CACT,CAAA,uBAAA,EAA0B,QAAQ,CAAA,QAAA,EAAW,SAAS,CAAA,WAAA,EAAc,OAAO,CAAA,CAAE,CAC9E;AAED,QAAA,IAAI,SAAS,KAAK,IAAI,CAAC,gBAAgB,EAAE;AACvC,YAAA,IAAI,CAAC,gBAAgB,GAAG,SAAS;AACjC,YAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACvD;AAEA,QAAA,IAAI,CAAC,gBAAgB,GAAG,GAAG;AAC3B,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE;IACnB;AAEA;;;AAGG;IACK,gBAAgB,CAAC,aAAqB,EAAE,QAAkB,EAAA;QAChE,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CACzC,aAAgD,CACjD;;AAGD,QAAA,MAAM,UAAU,GACd,YAAY,KAAK,CAAC;AAChB,cAAE,IAAI,CAAC,mBAAmB,CAAC,aAAa;cACtC,YAAY;AAElB,QAAA,MAAM,KAAK,GAAG,QAAQ,KAAK,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;AAC9C,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;AAEzE,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;IACjC;AAEA;;AAEG;AACK,IAAA,mBAAmB,CAAC,MAAc,EAAA;QACxC,IAAI,YAAY,GAAG,CAAC;AACpB,QAAA,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAEtD,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC9C,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AACjD,YAAA,IAAI,IAAI,GAAG,WAAW,EAAE;gBACtB,WAAW,GAAG,IAAI;gBAClB,YAAY,GAAG,CAAC;YAClB;QACF;AAEA,QAAA,OAAO,YAAY;IACrB;;IAGQ,cAAc,GAAA;AACpB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM;QAC/B,IAAI,GAAG,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QAEnD,IAAI,GAAG,GAAG,CAAC;QACX,IAAI,OAAO,GAAG,CAAC;QACf,IAAI,EAAE,GAAG,CAAC;AAEV,QAAA,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;AAC5B,YAAA,GAAG,IAAI,CAAC,CAAC,GAAG;AACZ,YAAA,OAAO,IAAI,CAAC,CAAC,OAAO;AACpB,YAAA,EAAE,IAAI,CAAC,CAAC,EAAE;QACZ;AAEA,QAAA,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE;IACjE;8GAnWW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cADJ,MAAM,EAAA,CAAA,CAAA;;2FACnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCpErB,wBAAwB,CAAA;AAPrC,IAAA,WAAA,GAAA;AAQW,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AACtB,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;QAEhC,IAAA,CAAA,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACnD,aAAa,CAAC,uBAAuB,CACtC;QACQ,IAAA,CAAA,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACrD,aAAa,CAAC,yBAAyB,CACxC;QACQ,IAAA,CAAA,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAC9C,aAAa,CAAC,kBAAkB,CACjC;AACQ,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAChC,MAAM,IAAI,CAAC,iBAAiB,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE;2FAC7D;AAKF,IAAA;AAnBU,IAAA,MAAM;AACN,IAAA,WAAW;IAepB,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;IAC1B;8GAnBW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClBrC,m3BA+BA,EAAA,MAAA,EAAA,CAAA,23CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDfY,qBAAqB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,WAAA,EAAA,YAAA,EAAA,WAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEpB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAPpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,uBAAuB,mBAGhB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,qBAAqB,CAAC,EAAA,QAAA,EAAA,m3BAAA,EAAA,MAAA,EAAA,CAAA,23CAAA,CAAA,EAAA;;;MEHrB,oBAAoB,CAAA;AANjC,IAAA,WAAA,GAAA;AAOW,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAEtB,IAAA,CAAA,mCAAmC,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACrE,yCAAyC,CAC1C;QACQ,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAChD,gCAAgC,CACjC;AACF,IAAA;AARU,IAAA,MAAM;8GADJ,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,4ECbjC,2UAcA,EAAA,MAAA,EAAA,CAAA,gnBAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FDDa,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;+BACE,kBAAkB,EAAA,eAAA,EAGX,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,2UAAA,EAAA,MAAA,EAAA,CAAA,gnBAAA,CAAA,EAAA;;;MEGpC,QAAQ,CAAA;AAHrB,IAAA,WAAA,GAAA;AAIU,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;AA+BzC,IAAA;IA7BC,SAAS,CACP,KAAa,EACb,IAAY,EAAA;QAEZ,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,MAAM,OAAO,GAAG,CAAC,MAAK;YACpB,QAAQ,IAAI;AACV,gBAAA,KAAK,MAAM;oBACT,OAAO,eAAe,CAAC,IAAI;AAC7B,gBAAA,KAAK,OAAO;oBACV,OAAO,eAAe,CAAC,KAAK;AAC9B,gBAAA,KAAK,QAAQ;oBACX,OAAO,eAAe,CAAC,MAAM;AAC/B,gBAAA,KAAK,KAAK;oBACR,OAAO,eAAe,CAAC,GAAG;AAC5B,gBAAA,KAAK,aAAa;oBAChB,OAAO,eAAe,CAAC,YAAY;AACrC,gBAAA;AACE,oBAAA,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAA,CAAE,CAAC;;QAE7D,CAAC,GAAG;;;AAIJ,QAAA,QAAQ,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;IACvD;8GA/BW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;4GAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,CAAA;;2FAAR,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAHpB,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,MAAM;AACb,iBAAA;;;MCDY,0BAA0B,CAAA;AACrC,IAAA,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;AAE9B,IAAA,KAAK,CAAC,KAAe,EAAA;QACnB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;IACvC;8GALW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA1B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECZvC,igCAkCA,EAAA,MAAA,EAAA,CAAA,0JAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDxBsB,qBAAqB,8RAA/B,QAAQ,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEP,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAPtC,SAAS;+BACE,yBAAyB,EAAA,eAAA,EAGlB,uBAAuB,CAAC,MAAM,WACtC,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EAAA,QAAA,EAAA,igCAAA,EAAA,MAAA,EAAA,CAAA,0JAAA,CAAA,EAAA;;;MEM/B,wBAAwB,CAAA;AAPrC,IAAA,WAAA,GAAA;AAQE,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAEb,IAAA,CAAA,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACvD,2BAA2B,CAC5B;QACQ,IAAA,CAAA,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACjD,aAAa,CAAC,qBAAqB,CACpC;AAKF,IAAA;AAZC,IAAA,MAAM;IASN,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD;8GAZW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChBrC,mWAgBA,EAAA,MAAA,EAAA,CAAA,iTAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDFY,gBAAgB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,UAAA,EAAA,cAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,aAAA,EAAA,mBAAA,EAAA,KAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEf,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAPpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,uBAAuB,mBAGhB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,gBAAgB,CAAC,EAAA,QAAA,EAAA,mWAAA,EAAA,MAAA,EAAA,CAAA,iTAAA,CAAA,EAAA;;;MEahB,kBAAkB,CAAA;AAiB7B,IAAA,WAAA,GAAA;QAhBS,IAAA,CAAA,KAAK,GAAG,KAAK,CAAC,QAAQ;kFAAU;AAChC,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK;4FAAqB;QACjC,IAAA,CAAA,KAAK,GAAG,KAAK,CAAC,SAAS;kFAAC;QACxB,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAC,CAAC;qFAAC;AAEpB,QAAA,IAAA,CAAA,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;QACtB,IAAA,CAAA,KAAK,GAAG,SAAS,CAAgC,OAAO;kFAAC;QAE1D,IAAA,CAAA,IAAI,GAAsB,EAAE;QAC3B,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,CAAC;gFAAC;QACf,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,CAAC;gFAAC;QACf,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,CAAC;oFAAC;QAM1B,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;AACxB,YAAA,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;AACrD,QAAA,CAAC,CAAC;AACF,QAAA,eAAe,CAAC;YACd,IAAI,EAAE,MAAK;AACT,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;gBAC1B,IAAI,KAAK,EAAE;AACT,oBAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa;;oBAEjC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAE;gBAC1C;YACF,CAAC;AACF,SAAA,CAAC;IACJ;IAGA,MAAM,GAAA;QACJ,IAAI,CAAC,IAAI,EAAE;IACb;IAEQ,IAAI,GAAA;AACV,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB;QACF;QAEA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAa;AACxE,QAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC9B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACrD,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,qBAAqB,EAAE;QAC5D,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;AAChC,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAE/D,QAAA,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,KAAI;YAC9C,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,MAAM;AAE7B,YAAA,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAW,CAAC;YAC7D,IAAI,CAAC,GAAG,CAAC,QAAQ,CACf,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,EACvB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EACtB,IAAI,CAAC,QAAQ,EAAE,EACf,CAAC,CACF;AACH,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;IACpB;AAEQ,IAAA,QAAQ,CAAC,SAAiB,EAAE,KAAK,GAAG,CAAC,EAAA;AAC3C,QAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;AACvC,QAAA,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAChC,QAAA,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QACnD;AACE,YAAA,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACnC,OAAO,GAAG,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAChC;IACF;AAEQ,IAAA,QAAQ,CAAC,IAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB;QACF;AACA,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE;AAC1D,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QACnB;QACA,IAAI,CAAC,IAAI,EAAE;IACb;8GAxFW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,iuBC3B/B,4JAIA,EAAA,MAAA,EAAA,CAAA,qFAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FDuBa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAN9B,SAAS;+BACE,gBAAgB,EAAA,eAAA,EAGT,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,4JAAA,EAAA,MAAA,EAAA,CAAA,qFAAA,CAAA,EAAA;wcASW,OAAO,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA;sBA2BhE,YAAY;uBAAC,eAAe;;;ME3ClB,qBAAqB,CAAA;AAPlC,IAAA,WAAA,GAAA;AAQW,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AACtB,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,sBAAsB,CAAC;QAEjD,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAC7C,aAAa,CAAC,iBAAiB,CAChC;AACQ,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc;AACrD,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa;QAChD,IAAA,CAAA,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACrD,aAAa,CAAC,yBAAyB,CACxC;AACQ,QAAA,IAAA,CAAA,0BAA0B,GAAG,QAAQ,CAC5C,MAAM,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE;uGACtD;AACF,IAAA;AAdU,IAAA,MAAM;AACN,IAAA,gBAAgB;8GAFd,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClBlC,idAiBA,EAAA,MAAA,EAAA,CAAA,qzBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDDY,sBAAsB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,uBAAA,EAAA,qBAAA,EAAA,aAAA,EAAA,aAAA,EAAA,MAAA,EAAA,WAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAErB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAPjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,mBAGZ,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,sBAAsB,CAAC,EAAA,QAAA,EAAA,idAAA,EAAA,MAAA,EAAA,CAAA,qzBAAA,CAAA,EAAA;;;MEctB,mBAAmB,CAAA;AAmF9B,IAAA,WAAA,GAAA;QAlFS,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,KAAK;sFAAC;AACjB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrB,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;QAE5C,IAAA,CAAA,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAEvD,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAC9C,aAAa,CAAC,mBAAmB,CAClC;QACQ,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,yBAAyB,CAAC;AAE3D,QAAA,IAAA,CAAA,OAAO,GAAG,QAAQ,CAAC,OAAO;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,eAAe,IAAI,CAAC;SAC1D,CAAC;oFAAC;AACM,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,OAAO;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,OAAO,IAAI,CAAC;SAClD,CAAC;wFAAC;AACM,QAAA,IAAA,CAAA,OAAO,GAAG,QAAQ,CAAC,OAAO;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,cAAc,IAAI,CAAC;SACzD,CAAC;oFAAC;AAEM,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AACnC,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE;AAC7B,gBAAA,OAAO,SAAS;YAClB;AACA,YAAA,MAAM,IAAI,GAAG;gBACX,GAAG,KAAK,CAAC,eAAe;gBACxB,OAAO,EAAE,KAAK,CAAC,OAAO;aACF;YACtB,OAAO,IAAI,CAAC;AACT,iBAAA,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAA8B,CAAC,EAAE,CAAC;AACnE,iBAAA,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1D,CAAC;wFAAC;AAEO,QAAA,IAAA,CAAA,MAAM,GAAG;YAChB,eAAe;YACf,aAAa;YACb,SAAS;YACT,YAAY;YACZ,aAAa;YACb,YAAY;YACZ,gBAAgB;YAChB,QAAQ;YACR,gBAAgB;YAChB,eAAe;YACf,eAAe;YACf,gBAAgB;YAChB,kBAAkB;YAClB,sBAAsB;YACtB,aAAa;YACb,gBAAgB;YAChB,SAAS;YACT,YAAY;YACZ,MAAM;YACN,MAAM;YACN,QAAQ;YACR,cAAc;SACf;QAEgB,IAAA,CAAA,cAAc,GAAG,MAAM,CAAW,EAAE;2FAAC;QACrC,IAAA,CAAA,KAAK,GAAG,0BAA0B;AAElC,QAAA,IAAA,CAAA,cAAc,GAAoB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;YAC3E,GAAG;AACH,YAAA,KAAK,EACH,GAAG;gBACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ;qBAChC,QAAQ,CAAC,EAAE;AACX,qBAAA,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACrB,YAAA,IAAI,EAAE,QAAQ,CAAC,OAAO;gBACpB,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,eAAe,CAClC,GAA8B,CACrB;AACZ,aAAA,CAAC,CAAC;AACJ,SAAA,CAAC,CAAC;AAEM,QAAA,IAAA,CAAA,SAAS,GAAG,QAAQ,CAAC,MAC5B,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;sFACzE;QAGC,IAAI,CAAC,kBAAkB,EAAE;IAC3B;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC;QAChD,IAAI,CAAC,WAAW,EAAE;IACpB;AAEA,IAAA,WAAW,CAAC,MAAa,EAAE,EAAU,EAAE,KAAe,EAAA;QACpD,MAAM,CAAC,eAAe,EAAE;AACxB,QAAA,IACE,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;aAClC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAC3C;YACA;QACF;AACA,QAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,OAAO,KACjC,OAAO,CAAC,QAAQ,CAAC,EAAE;AACjB,cAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE;cACpC,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,CACrB;QACD,IAAI,CAAC,WAAW,EAAE;IACpB;IAEQ,kBAAkB,GAAA;AACxB,QAAA,IAAI;YACF,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAC3B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAW,CAAC,IAAI,EAAE;YAC9D,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC;QACxC;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B;IACF;IAEQ,WAAW,GAAA;QACjB,YAAY,CAAC,OAAO,CAClB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,CAAC;AACb,YAAA,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;AAC3B,YAAA,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE;AAChC,SAAA,CAAC,CACH;IACH;8GA/HW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,2EC9BhC,4pEA4EA,EAAA,MAAA,EAAA,CAAA,uwCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDhDY,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,QAAQ,wCAAE,QAAQ,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAErC,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAP/B,SAAS;+BACE,iBAAiB,EAAA,eAAA,EAGV,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAA,QAAA,EAAA,4pEAAA,EAAA,MAAA,EAAA,CAAA,uwCAAA,CAAA,EAAA;;;MEDtC,2BAA2B,CAAA;AAC7B,IAAA,MAAM;AAsCf,IAAA,WAAA,GAAA;AAtCS,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAEtB,IAAA,CAAA,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC;AAC3D,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAC7B,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ;0FACjE;QACQ,IAAA,CAAA,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACvD,2BAA2B,CAC5B;QACQ,IAAA,CAAA,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACpD,wBAAwB,CACzB;QACQ,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,sBAAsB,CAAC;QACnE,IAAA,CAAA,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACvD,aAAa,CAAC,2BAA2B,CAC1C;QACQ,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CACpC,MACE,IAAI,CAAC,qBAAqB,EAAE;YAC5B,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,gBAAgB,EAAE;YACvB,IAAI,CAAC,qBAAqB,EAAE;+FAC/B;QACQ,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAClD,aAAa,CAAC,sBAAsB,CACrC;AACQ,QAAA,IAAA,CAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;AACvC,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAChD,YAAA,QACE,gBAAgB,KAAK,gBAAgB,CAAC,GAAG;AACzC,gBAAA,gBAAgB,KAAK,gBAAgB,CAAC,IAAI;QAE9C,CAAC;4FAAC;QAEe,IAAA,CAAA,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CACzD,aAAa,CAAC,qBAAqB,CACpC;AAGC,QAAA,IAAI,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE;QACzC,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE;AACxC,YAAA,IAAI,CAAC,SAAS,IAAI,YAAY,EAAE;gBAC9B,IAAI,CAAC,UAAU,EAAE;YACnB;YACA,YAAY,GAAG,SAAS;AAC1B,QAAA,CAAC,CAAC;IACJ;IAEA,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE;IAEA,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B;8GAxDW,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAA3B,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3BxC,2hBAqBA,EAAA,MAAA,EAAA,CAAA,qiBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDIY,qBAAqB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,WAAA,EAAA,YAAA,EAAA,WAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEpB,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBAPvC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,0BAA0B,mBAGnB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,qBAAqB,CAAC,EAAA,QAAA,EAAA,2hBAAA,EAAA,MAAA,EAAA,CAAA,qiBAAA,CAAA,EAAA;;;MELrB,iBAAiB,CAAA;AAC5B,IAAA,MAAM;AAcN,IAAA,WAAA,GAAA;AAdA,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAEL,IAAA,CAAA,YAAY,GAC3B,SAAS,CAA6B,kBAAkB;yFAAC;QACjD,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAChD,aAAa,CAAC,mBAAmB,CAClC;QACS,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAChD,aAAa,CAAC,mBAAmB,CAClC;QACO,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAC9C,aAAa,CAAC,mBAAmB,CAClC;QAGC,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;AAC1C,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;AAC1C,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;YAC1C,SAAS,CAAC,MAAK;gBACb,IAAI,aAAa,KAAK,aAAa,IAAI,aAAa,CAAC,EAAE;oBACrD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;gBACvC;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;QACF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE;AACxC,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;YAC1C,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,YAAY,IAAI,aAAa,EAAE;oBACjC,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,YAAY,CAAC,aAAa,CAAC;gBAC7D;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEA,iBAAiB,GAAA;QACf,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACvC;IAEQ,WAAW,CAAC,GAAW,EAAE,cAA8B,EAAA;AAC7D,QAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B;QACF;QACA,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7D,QAAA,cAAc,CAAC,SAAS,GAAG,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AACpD,QAAA,YAAY,CAAC,QAAQ,GAAG,IAAI;AAC5B,QAAA,YAAY,CAAC,KAAK,GAAG,IAAI;AACzB,QAAA,YAAY,CAAC,IAAI,GAAG,IAAI;QACxB,IAAI,CAAC,iBAAiB,EAAE;AACtB,YAAA,YAAY,CAAC,MAAM,GAAG,CAAA,EAAG,GAAG,aAAa;QAC3C;AAEA,QAAA,YAAY,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU;AACxC,QAAA,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AACjC,QAAA,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;AAClC,QAAA,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO;QAEtC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;QACtD,IAAI,iBAAiB,EAAE;AACrB,YAAA,aAAa,CAAC,GAAG,GAAG,GAAG;QACzB;aAAO;AACL,YAAA,aAAa,CAAC,GAAG,GAAG,CAAA,EAAG,GAAG,YAAY;QACxC;AAEA,QAAA,aAAa,CAAC,IAAI,GAAG,WAAW;AAChC,QAAA,YAAY,CAAC,WAAW,CAAC,aAAa,CAAC;AAEvC,QAAA,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,MACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CACtC;AACD,QAAA,aAAa,CAAC,gBAAgB,CAAC,OAAO,EAAE,MACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CACtC;AAED,QAAA,cAAc,CAAC,WAAW,CAAC,YAAY,CAAC;IAC1C;8GA9EW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,cAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECpB9B,oQAQA,EAAA,MAAA,EAAA,CAAA,4ZAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDSY,gBAAgB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,UAAA,EAAA,cAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,aAAA,EAAA,mBAAA,EAAA,KAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAGf,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAP7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,WAGhB,CAAC,gBAAgB,CAAC,EAAA,eAAA,EACV,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,oQAAA,EAAA,MAAA,EAAA,CAAA,4ZAAA,CAAA,EAAA;oGAMP,kBAAkB,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ME8D/C,oBAAoB,CAAA;AAiBtB,IAAA,MAAM;AAmBf,IAAA,IAAY,YAAY,GAAA;AACtB,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;AACnB,YAAA,OAAO,IAAI,CAAC,qBAAqB,EAAE;QACrC;AACA,QAAA,OAAO,IAAI,CAAC,wBAAwB,EAAE;IACxC;AAEA,IAAA,IAAY,UAAU,GAAA;QACpB,OAAO,MAAM,CAAC,gBAAgB;IAChC;IAGA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;IACtC;IAGA,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;IACvC;AAGA,IAAA,aAAa,CAAC,KAAY,EAAA;QACxB,KAAK,CAAC,cAAc,EAAE;IACxB;AAEA,IAAA,WAAA,GAAA;QA7DS,IAAA,CAAA,0BAA0B,GAAG,KAAK,CAAC,IAAI;uGAAC;QACxC,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAC,KAAK;qFAAC;QACvB,IAAA,CAAA,cAAc,GAAG,KAAK,CAAoC;AACjE,YAAA,KAAK,EAAE,aAAa;AACpB,YAAA,MAAM,EAAE,cAAc;AACvB,SAAA;2FAAC;QAEO,IAAA,CAAA,oBAAoB,GAAG,MAAM,EAAW;QAExC,IAAA,CAAA,YAAY,GACnB,SAAS,CAA6B,gBAAgB;yFAAC;AAExC,QAAA,IAAA,CAAA,iBAAiB,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC;QAC9D,IAAA,CAAA,KAAK,GAAG,aAAa;QACrB,IAAA,CAAA,MAAM,GAAG,cAAc;AACd,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;AAClC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QACd,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAC1D,sBAAsB,CACvB;AACQ,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;QACpC,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAC9D,0BAA0B,CAC3B;AACgB,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CACrC,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAC1D;AACgB,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,yBAAyB,CAAC;AAClD,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC;AACjD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAE/B,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;QAC7C,IAAA,CAAA,kBAAkB,GAAG,KAAK;AA6BhC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;;;;;;;;;YAS7B,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,CAC/C,gBAAgB,CAAC,OAAO,CACzB;;;;;;;;YAQD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AAC5C,QAAA,CAAC,CAAC;QACF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE;AACxC,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;YAChD,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,YAAY,IAAI,gBAAgB,EAAE;;;;;oBAKpC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,YAAY,CAAC,aAAa,CAAC;oBAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACxC;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;AAEF,QAAA,eAAe,CAAC;YACd,IAAI,EAAE,MAAK;AACT,gBAAA,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE;gBACxC,IAAI,YAAY,EAAE;oBAChB,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,YAAY,CAAC,aAAa,CAAC;oBAC1D,IAAI,CAAC,kBAAkB,EAAE;AACzB,oBAAA,IAAI,CAAC,wCAAwC,CAC3C,YAAY,CAAC,aAAa,CAC3B;gBACH;YACF,CAAC;AACF,SAAA,CAAC;IACJ;AAEQ,IAAA,wCAAwC,CAAC,MAAmB,EAAA;AAClE,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,EAAE;YAC1C;QACF;;;;QAKA,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAW;AACtD,QAAA,MAAM,YAAY,GAAG,KAAK,CACxB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EACpC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAChC,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,EACrC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CACrC;AAED,QAAA,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,YAAY;AACzB,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,KAAK,KAAI;AACZ,YAAA,IAAI,KAAK,IAAI,IAAI,CAAC,kBAAkB,EAAE;AACpC,gBAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK;gBAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;YAC7C;AACF,QAAA,CAAC,CAAC,EACF,SAAS,CAAC,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC,EACpD,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aAEpC,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBAC3B;YACF;AACA,YAAA,IAAI,CAAC,kBAAkB,GAAG,IAAI;YAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;AAC7C,QAAA,CAAC,CAAC;IACN;IAEQ,kBAAkB,GAAA;AACxB,QAAA,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CACzD,MAAM,CACJ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CACtE,EACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAI;AACxB,YAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,YAAA,IAAI,CAAC,MAAM,GAAG,MAAM;QACtB,CAAC,CAAC,CACH;QAED,MAAM,eAAe,GAAG,KAAK,CAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAClD,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAC5B;AAED,QAAA,MAAM,uBAAuB,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAChE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,EAC1CR,KAAG,CAAC,CAAC,KAAK,MAAM;AACd,YAAA,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,UAAU,IAAI,CAAC;AACxC,YAAA,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,WAAW,IAAI,CAAC;SAC1C,CAAC,CAAC,EACH,oBAAoB,CAClB,CAAC,QAAQ,EAAE,OAAO,KAChB,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC;AACxD,YAAA,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAC3D,CACF;AAED,QAAA,KAAK,CAAC,uBAAuB,EAAE,eAAe,EAAE,uBAAuB;aACpE,IAAI,CACH,YAAY,CAAC,6BAA6B,CAAC,EAC3C,SAAS,CAAC,MAAK;AACb,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;;YAEzB,OAAO,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CACvB,IAAI,CAAC,CAAC,CAAC,EACPA,KAAG,CAAC,MAAM,GAAG,CAAC,CACf;AACH,QAAA,CAAC,CAAC,EACFA,KAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,EAC7C,oBAAoB,CAClB,CAAC,QAAQ,EAAE,OAAO,KAChB,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC;YACxD,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC;YACxD,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAC/B,EACD,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;;AAEpC,QAAA,oBAAoB,CAClB,CAAC,QAAQ,EAAE,OAAO,KAChB,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC;YACxD,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAC3D;;;QAGD,iBAAiB,CACf,IAAI,CAAC;AACF,aAAA,MAAM,CAAC,aAAa,CAAC,0BAA0B;AAC/C,aAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CACxB,EACD,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AAEpC,aAAA,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAI;YACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAClB,4BAA4B,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAChE;AACD,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;AACvB,QAAA,CAAC,CAAC;AAEJ,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AACrE,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxD;AAEQ,IAAA,UAAU,CAAC,IAAU,EAAA;AAC3B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK;AACrC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY;AAElC,QAAA,IAAI,KAAK,EAAE,KAAK,EAAE;AAChB,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU;AAC1B,YAAA,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;AACpD,YAAA,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;AAErD,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;AACpB,gBAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;AAC/B,gBAAA,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO;gBAC/B,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,CAAC,KAAK,CAAA,EAAA,CAAI;gBACtC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAA,EAAA,CAAI;YAC1C;QACF;QAEA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC;IACjD;IAEQ,wBAAwB,GAAA;AAC9B,QAAA,IAAI,cAAc,GAAG,MAAM,CAAC,UAAU,IAAI,kBAAkB;AAC5D,QAAA,IAAI,eAAe,GAAG,MAAM,CAAC,WAAW,IAAI,kBAAkB;AAE9D,QAAA,IAAI,IAAI,CAAC,0BAA0B,EAAE,EAAE;YACrC,cAAc;gBACZ,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,WAAW,IAAI,kBAAkB;YACtE,eAAe;gBACb,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,YAAY,IAAI,kBAAkB;QACzE;AACA,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;AAElC,QAAA,OAAO,wBAAwB,CAAC;YAC9B,UAAU;YACV,cAAc;YACd,eAAe;AACf,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,kBAAkB;AAC7D,SAAA,CAAC;IACJ;IAEQ,qBAAqB,GAAA;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa;AAEvD,QAAA,OAAO,qBAAqB,CAAC;YAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;AAC3B,YAAA,cAAc,EAAE,YAAY,EAAE,WAAW,IAAI,kBAAkB;AAC/D,YAAA,eAAe,EAAE,YAAY,EAAE,YAAY,IAAI,kBAAkB;YACjE,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,YAAY,EAAE,IAAI,CAAC,MAAM;AACzB,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,kBAAkB;AAC7D,SAAA,CAAC;IACJ;AAEQ,IAAA,UAAU,CAAC,IAAU,EAAA;AAC3B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK;QACrC,IAAI,CAAC,KAAK,EAAE;YACV;QACF;AACA,QAAA,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC;YACtC,OAAO,EAAE,cAAc,CAAC,wBAAwB;AAChD,YAAA,OAAO,EAAE;AACP,gBAAA,UAAU,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE;AACpC,gBAAA,cAAc,EAAE,IAAI,CAAC,QAAQ;sBACzB,eAAe,CAAC;AAClB,sBAAE,SAAS;AACd,aAAA;AACF,SAAA,CAAC;IACJ;8GAnSW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,0BAAA,EAAA,EAAA,iBAAA,EAAA,4BAAA,EAAA,UAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,WAAA,EAAA,eAAA,EAAA,UAAA,EAAA,cAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,cAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECtFjC,8ZAiBA,EAAA,MAAA,EAAA,CAAA,22WAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED4DI,wBAAwB,kEACxB,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,oBAAoB,EAAA,QAAA,EAAA,kBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACpB,mBAAmB,EAAA,QAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,2BAA2B,EAAA,QAAA,EAAA,0BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC3B,wBAAwB,kEACxB,iBAAiB,EAAA,QAAA,EAAA,eAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAGR,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAfhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,EAAA,eAAA,EAGX,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC;wBACP,wBAAwB;wBACxB,qBAAqB;wBACrB,oBAAoB;wBACpB,mBAAmB;wBACnB,2BAA2B;wBAC3B,wBAAwB;wBACxB,iBAAiB;AAClB,qBAAA,EAAA,QAAA,EAAA,8ZAAA,EAAA,MAAA,EAAA,CAAA,22WAAA,CAAA,EAAA;igBAauC,gBAAgB,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA;sBAoCvD,YAAY;uBAAC,WAAW;;sBAKxB,YAAY;uBAAC,UAAU;;sBAKvB,YAAY;uBAAC,aAAa,EAAE,CAAC,QAAQ,CAAC;;;MEjI5B,uBAAuB,CAAA;AAPpC,IAAA,WAAA,GAAA;QAQmB,IAAA,CAAA,UAAU,GAAG,mBAAmB;AACxC,QAAA,IAAA,CAAA,kBAAkB,GAAG,EAAE,GAAG,kBAAkB,EAAE;AACvD,QAAA,IAAA,CAAA,QAAQ,GAAG,EAAE,GAAG,kBAAkB,EAAE;AAqCrC,IAAA;IAnCC,QAAQ,GAAA;QACN,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAC3D,IAAI,aAAa,EAAE;YACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1C;IACF;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS;QAClD,IAAI,CAAC,YAAY,EAAE;IACrB;IAEA,YAAY,GAAA;QACV,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;YACvE,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,GAAG,GAAG;QACvD,CAAC,EAAE,EAAE,CAAC;QACN,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,kBAAkB,EAAE,GAAG,KAAK,EAAE,CAAC;IACpD;AAEA,IAAA,QAAQ,CAAC,QAAwB,EAAA;AAC/B,QAAA,IAAI;AACF,YAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjE;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,sDAAsD,EAAE,CAAC,CAAC;QACzE;QACA,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC;AACtC,QAAA,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC;IACtC;IAEA,KAAK,GAAA;QACH,IAAI,CAAC,QAAQ,CAAC;AACZ,YAAA,GAAG,kBAAkB;AACrB,YAAA,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS;AACnC,SAAA,CAAC;IACJ;8GAvCW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECdpC,6iGAqGA,EAAA,MAAA,EAAA,CAAA,u+BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED1FY,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,wSAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,8IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAGV,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAPnC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qBAAqB,WAGtB,CAAC,WAAW,CAAC,EAAA,eAAA,EACL,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,6iGAAA,EAAA,MAAA,EAAA,CAAA,u+BAAA,CAAA,EAAA;;;MERpC,wBAAwB,CAAA;AADrC,IAAA,WAAA,GAAA;QAEW,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,KAAK;4FAAC;AAE/B,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE;AAClD,QAAA,IAAA,CAAA,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC;AAS7D,IAAA;AAZU,IAAA,eAAe;IAKxB,qBAAqB,GAAA;AACnB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC;IAEA,oBAAoB,GAAA;AAClB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC;IACjC;8GAZW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cADX,MAAM,EAAA,CAAA,CAAA;;2FACnB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MC6CrB,6BAA6B,CAAA;AAP1C,IAAA,WAAA,GAAA;AAQE,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AACL,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAC5D,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,SAAS;QAEpC,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAClD,aAAa,CAAC,mBAAmB,CAClC;AACgB,QAAA,IAAA,CAAA,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,eAAe;AACxD,QAAA,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC/DW,sBAAoB,EAAE,EACtB,MAAM,CAAC,MAAM,CAAC,CACf;AACgB,QAAA,IAAA,CAAA,qBAAqB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAChEA,sBAAoB,EAAE,EACtB,MAAM,CAAC,KAAK,CAAC,CACd;AAEgB,QAAA,IAAA,CAAA,yBAAyB,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CACnEA,sBAAoB,EAAE,EACtB,MAAM,CAAC,KAAK,CAAC,CACd;QAEgB,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CACpE,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,EACnC,KAAK,EAAE,CACR;QACgB,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAClE,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,CAC5B;QAEgB,IAAA,CAAA,kBAAkB,GAAG,IAAI,CAAC;aACxC,IAAI,CACH,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,EACvC,GAAG,CACD,CAAC,CAAC,aAAa,EAAE,cAAc,CAAC,KAAK,aAAa,IAAI,CAAC,cAAc,CACtE;AAEF,aAAA,IAAI,CAAC,KAAK,EAAE,CAAC;QAEC,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CACxD,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAiB,EAAE,CAAC,CAAC,CAC5C;AAEgB,QAAA,IAAA,CAAA,mBAAmB,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CACjE,YAAY,CAAC,GAAG,CAAC,EACjB,SAAS,CAAC,CAAC,SAAS,KAClB,MAAM,CACJ,EAAE,CAAC,KAAK,CAAC,EACT,KAAK,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,CAAC,CAClE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAER,WAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CACpD,EACDQ,sBAAoB,EAAE,EACtB,KAAK,EAAE,CACR;QAEgB,IAAA,CAAA,aAAa,GAAG,KAAK,CACpC,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,UAAU,CAChB,CAAC,IAAI,CAAC,KAAK,EAAE,EAAER,WAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAEzC,IAAA,CAAA,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAChD,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,CACzC;QAEgB,IAAA,CAAA,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CACxD,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,mBAAmB,CAAC,EACvC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EACjCA,WAAS,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAClE;AAEQ,QAAA,IAAA,CAAA,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;AAC9C,QAAA,IAAA,CAAA,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC;AAC7C,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc;AACtD,QAAA,IAAA,CAAA,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC;QACjD,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,KAAK;6FAAC;QAChC,IAAA,CAAA,mBAAmB,GAAG,MAAM,CAAC,KAAK;gGAAC;QAEnC,IAAA,CAAA,2BAA2B,GAAG,YAAY,CACjD,IAAI,CAAC,mBAAmB,CACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAEQ,sBAAoB,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;AAgGvD,IAAA;AAlLC,IAAA,MAAM;IAoFN,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC;AACF,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAE9C,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,qBAAqB;AAC7D,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AACxC,aAAA,SAAS,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAEpD,QAAA,IAAI,CAAC;aACF,IAAI,CACH,MAAM,CAAC,MAAM,CAAC,EACd,GAAG,CAAC,MAAK;YACP,eAAe,CAAC,KAAK,EAAE;AACvB,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;AAClC,QAAA,CAAC,CAAC,EACF,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,EAClC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EACvC,GAAG,CAAC,CAAC,cAAc,KAAK,cAAc,EAAE,cAAc,CAAC,EACvDA,sBAAoB,EAAE,EACtB,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;QACjC,CAAC,CAAC,EACF,SAAS,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,EACnC,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,KAAK,MAAM,CAAC,EACvC,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAC3C,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AAEpC,aAAA,SAAS,EAAE;IAChB;AAEQ,IAAA,kBAAkB,CAAC,cAAmC,EAAA;;QAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,UAAU;QACpD,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,EAAE,KAAK,KAAK;AACzD,QAAA,MAAM,YAAY,GAAG,kBAAkB,IAAI,QAAQ;;AAGnD,QAAA,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,cAAc,EAAE;YAAE;AAE5C,QAAA,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,cAAc;AAChD,QAAA,MAAM,YAAY,GAAG,OAAO,KAAK,KAAK;AACtC,QAAA,MAAM,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC,cAAc;;AAG9D,QAAA,IAAI,YAAY,IAAI,YAAY,IAAI,QAAQ,EAAE;AAC5C,YAAA,IAAI,MAAc;YAElB,IAAI,QAAQ,EAAE;AACZ,gBAAA,MAAM,GAAG,CAAA,MAAA,EAAS,WAAW,CAAC,UAAU,EAAE;YAC5C;AAAO,iBAAA,IAAI,OAAO,KAAK,KAAK,EAAE;AAC5B,gBAAA,MAAM,GAAG,CAAA,OAAA,EAAU,WAAW,CAAC,OAAO,GAAG;YAC3C;iBAAO;AACL,gBAAA,MAAM,GAAG,CAAA,QAAA,EAAW,WAAW,CAAC,cAAc,EAAE;YAClD;YAEA,MAAM,CAAC,IAAI,CACT,CAAA,cAAA,EAAiB,MAAM,gCAAgC,EACvD,cAAc,CAAC,OAAO,EACtB;AACE,gBAAA,KAAK,EAAE;oBACL,cAAc;oBACd,MAAM;oBACN,WAAW,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE,OAAO,IAAI,CAAC;AAClD,iBAAA;AACF,aAAA,CACF;AACD,YAAA,IAAI,CAAC,iBAAiB,CAAC,qBAAqB,EAAE;QAChD;IACF;AAEA,IAAA,eAAe,CAAC,KAAc,EAAA;AAC5B,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC;QAEnC,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,uBAAuB,EAAE;QAChC;IACF;IAEA,uBAAuB,GAAA;QACrB,KAAK,CAAC,IAAI;AACP,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAER,WAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC;aACzD,SAAS,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IACjD;IAEA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC;aACF,IAAI,CAAC,0BAA0B;AAC/B,aAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;aAC1B,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,EAAE;AAC7C,YAAA,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;AAC7B,QAAA,CAAC,CAAC;IACN;8GAlLW,6BAA6B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAA7B,6BAA6B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChD1C,k2HA8DA,EAAA,MAAA,EAAA,CAAA,8sFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDhBY,uBAAuB,EAAA,QAAA,EAAA,qBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEtB,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBAPzC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,mBAGrB,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,uBAAuB,CAAC,EAAA,QAAA,EAAA,k2HAAA,EAAA,MAAA,EAAA,CAAA,8sFAAA,CAAA,EAAA;;;AE1BpC;;;;;;;;AAQG;SACa,kBAAkB,GAAA;IAChC,OAAO,wBAAwB,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;AAChE;AAEA;;;;;;;;;;;;AAYG;SACa,mBAAmB,GAAA;AACjC,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,cAAc,CAAC,CAAC,aAAa,CAAC,CAAC;QAC/B,6BAA6B,CAAC,MAAK;YACjC,MAAM,CAAC,iBAAiB,CAAC;YACzB,MAAM,CAAC,YAAY,CAAC;YACpB,MAAM,CAAC,4BAA4B,CAAC;YACpC,MAAM,CAAC,6BAA6B,CAAC;YACrC,MAAM,CAAC,wBAAwB,CAAC;YAChC,MAAM,CAAC,UAAU,CAAC;YAClB,MAAM,CAAC,kBAAkB,CAAC;YAC1B,MAAM,CAAC,gBAAgB,CAAC;YACxB,MAAM,CAAC,iBAAiB,CAAC;AAC3B,QAAA,CAAC,CAAC;AACH,KAAA,CAAC;AACJ;;AC7DA;;AAEG;;;;"}