autoglm-gui 0.4.7__tar.gz → 0.4.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/api/media.py +55 -43
  2. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/scrcpy_stream.py +94 -64
  3. autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/about-DIdU3ZqP.js → autoglm_gui-0.4.8/AutoGLM_GUI/static/assets/about-BI6OV6gm.js +1 -1
  4. autoglm_gui-0.4.8/AutoGLM_GUI/static/assets/chat-C_2Cot0q.js +25 -0
  5. autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/index--ElIPD22.js → autoglm_gui-0.4.8/AutoGLM_GUI/static/assets/index-Dn3vR6uV.js +1 -1
  6. autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/index-BuFMN8G5.js → autoglm_gui-0.4.8/AutoGLM_GUI/static/assets/index-Do7ha9Kf.js +1 -1
  7. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/static/index.html +1 -1
  8. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/PKG-INFO +1 -1
  9. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/pyproject.toml +1 -1
  10. autoglm_gui-0.4.7/AutoGLM_GUI/static/assets/chat-_-u1G4Ee.js +0 -25
  11. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/.gitignore +0 -0
  12. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/__init__.py +0 -0
  13. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/__main__.py +0 -0
  14. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/adb_plus/__init__.py +0 -0
  15. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/adb_plus/screenshot.py +0 -0
  16. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/adb_plus/touch.py +0 -0
  17. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/api/__init__.py +0 -0
  18. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/api/agents.py +0 -0
  19. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/api/control.py +0 -0
  20. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/api/devices.py +0 -0
  21. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/config.py +0 -0
  22. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/schemas.py +0 -0
  23. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/server.py +0 -0
  24. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/state.py +0 -0
  25. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/static/assets/index-DCrxTz-A.css +0 -0
  26. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/AutoGLM_GUI/version.py +0 -0
  27. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/LICENSE +0 -0
  28. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/README.md +0 -0
  29. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/__init__.py +0 -0
  30. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/actions/__init__.py +0 -0
  31. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/actions/handler.py +0 -0
  32. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/adb/__init__.py +0 -0
  33. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/adb/connection.py +0 -0
  34. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/adb/device.py +0 -0
  35. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/adb/input.py +0 -0
  36. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/adb/screenshot.py +0 -0
  37. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/agent.py +0 -0
  38. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/__init__.py +0 -0
  39. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/apps.py +0 -0
  40. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/i18n.py +0 -0
  41. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/prompts.py +0 -0
  42. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/prompts_en.py +0 -0
  43. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/config/prompts_zh.py +0 -0
  44. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/model/__init__.py +0 -0
  45. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/phone_agent/model/client.py +0 -0
  46. {autoglm_gui-0.4.7 → autoglm_gui-0.4.8}/scrcpy-server-v3.3.3 +0 -0
@@ -1,6 +1,8 @@
1
1
  """Media routes: screenshot, video stream, stream reset."""
2
2
 
3
3
  import asyncio
4
+ import os
5
+ from pathlib import Path
4
6
 
5
7
  from fastapi import APIRouter, WebSocket, WebSocketDisconnect
6
8
 
@@ -11,6 +13,9 @@ from AutoGLM_GUI.state import scrcpy_locks, scrcpy_streamers
11
13
 
12
14
  router = APIRouter()
13
15
 
16
+ # Debug configuration: Set DEBUG_SAVE_VIDEO_STREAM=1 to save streams to debug_streams/
17
+ DEBUG_SAVE_STREAM = os.getenv("DEBUG_SAVE_VIDEO_STREAM", "0") == "1"
18
+
14
19
 
15
20
  @router.post("/api/video/reset")
16
21
  async def reset_video_stream(device_id: str | None = None) -> dict:
@@ -81,14 +86,9 @@ async def video_stream_ws(
81
86
 
82
87
  print(f"[video/stream] WebSocket connection for device {device_id}")
83
88
 
84
- # Debug: Save stream to file for analysis
85
- # Set to True for debugging (default: False)
86
- debug_save = False
89
+ # Debug: Save stream to file for analysis (controlled by DEBUG_SAVE_VIDEO_STREAM env var)
87
90
  debug_file = None
88
- if debug_save:
89
- import os
90
- from pathlib import Path
91
-
91
+ if DEBUG_SAVE_STREAM:
92
92
  debug_dir = Path("debug_streams")
93
93
  debug_dir.mkdir(exist_ok=True)
94
94
  debug_file_path = debug_dir / f"{device_id}_{int(__import__('time').time())}.h264"
@@ -110,46 +110,45 @@ async def video_stream_ws(
110
110
  await scrcpy_streamers[device_id].start()
111
111
  print(f"[video/stream] Scrcpy server started for device {device_id}")
112
112
 
113
- # Read initial chunks and accumulate into a single buffer
114
- # Then parse the entire buffer to find complete NAL units
113
+ # Read NAL units until we have SPS, PPS, and IDR
115
114
  streamer = scrcpy_streamers[device_id]
116
- accumulated_buffer = bytearray()
117
- target_size = 50 * 1024 # Accumulate at least 50KB
118
115
 
119
- print(f"[video/stream] Accumulating initial data (target: {target_size} bytes)...")
120
- for attempt in range(10):
116
+ print("[video/stream] Reading NAL units for initialization...")
117
+ for attempt in range(20): # Max 20 NAL units for initialization
121
118
  try:
122
- # Disable auto-caching - we'll parse the entire buffer at once
123
- chunk = await streamer.read_h264_chunk(auto_cache=False)
124
- accumulated_buffer.extend(chunk)
119
+ nal_unit = await streamer.read_nal_unit(auto_cache=True)
120
+ nal_type = nal_unit[4] & 0x1F if len(nal_unit) > 4 else -1
121
+ nal_type_names = {5: "IDR", 7: "SPS", 8: "PPS"}
125
122
  print(
126
- f"[video/stream] Read chunk ({len(chunk)} bytes, total: {len(accumulated_buffer)} bytes)"
123
+ f"[video/stream] Read NAL unit: type={nal_type_names.get(nal_type, nal_type)}, size={len(nal_unit)} bytes"
127
124
  )
125
+
126
+ # Check if we have all required parameter sets
127
+ if (
128
+ streamer.cached_sps
129
+ and streamer.cached_pps
130
+ and streamer.cached_idr
131
+ ):
132
+ print(
133
+ f"[video/stream] ✓ Initialization complete: SPS={len(streamer.cached_sps)}B, PPS={len(streamer.cached_pps)}B, IDR={len(streamer.cached_idr)}B"
134
+ )
135
+ break
128
136
  except Exception as e:
129
- print(f"[video/stream] Failed to read chunk: {e}")
137
+ print(f"[video/stream] Failed to read NAL unit: {e}")
130
138
  await asyncio.sleep(0.5)
131
139
  continue
132
140
 
133
- # Check if we have enough data
134
- if len(accumulated_buffer) >= target_size:
135
- break
136
-
137
- # Now parse the entire accumulated buffer at once
138
- # This ensures NAL units spanning multiple chunks are detected as complete
139
- print(f"[video/stream] Parsing accumulated buffer ({len(accumulated_buffer)} bytes)...")
140
- streamer._cache_nal_units(bytes(accumulated_buffer))
141
-
142
- # Get initialization data
141
+ # Get initialization data (SPS + PPS + IDR)
143
142
  init_data = streamer.get_initialization_data()
144
143
  if not init_data:
145
144
  raise RuntimeError(
146
- f"Failed to find complete SPS/PPS/IDR in {len(accumulated_buffer)} bytes"
145
+ "Failed to get initialization data (missing SPS/PPS/IDR)"
147
146
  )
148
147
 
149
- # Send initialization data to first client
148
+ # Send initialization data as ONE message (SPS+PPS+IDR combined)
150
149
  await websocket.send_bytes(init_data)
151
150
  print(
152
- f"[video/stream] Sent initial data ({len(init_data)} bytes) to first client"
151
+ f"[video/stream] Sent initialization data to first client: {len(init_data)} bytes total"
153
152
  )
154
153
 
155
154
  # Debug: Save to file
@@ -188,10 +187,23 @@ async def video_stream_ws(
188
187
  await asyncio.sleep(0.5)
189
188
 
190
189
  if init_data:
191
- await websocket.send_bytes(init_data)
190
+ # Log what we're sending
191
+ print(
192
+ f"[video/stream] ✓ Sending cached initialization data for device {device_id}:"
193
+ )
194
+ print(
195
+ f" - SPS: {len(streamer.cached_sps) if streamer.cached_sps else 0}B"
196
+ )
192
197
  print(
193
- f"[video/stream] Sent initialization data (SPS+PPS+IDR, {len(init_data)} bytes) for device {device_id}"
198
+ f" - PPS: {len(streamer.cached_pps) if streamer.cached_pps else 0}B"
194
199
  )
200
+ print(
201
+ f" - IDR: {len(streamer.cached_idr) if streamer.cached_idr else 0}B"
202
+ )
203
+ print(f" - Total: {len(init_data)} bytes")
204
+
205
+ await websocket.send_bytes(init_data)
206
+ print("[video/stream] ✓ Initialization data sent successfully")
195
207
 
196
208
  # Debug: Save to file
197
209
  if debug_file:
@@ -210,23 +222,23 @@ async def video_stream_ws(
210
222
 
211
223
  stream_failed = False
212
224
  try:
213
- chunk_count = 0
225
+ nal_count = 0
214
226
  while True:
215
227
  try:
216
- # Disable auto_cache - we only cache once during initialization
217
- # Later chunks may have incomplete NAL units that would corrupt the cache
218
- h264_chunk = await streamer.read_h264_chunk(auto_cache=False)
219
- await websocket.send_bytes(h264_chunk)
228
+ # Read one complete NAL unit
229
+ # Each WebSocket message = one complete NAL unit (clear semantic boundary)
230
+ nal_unit = await streamer.read_nal_unit(auto_cache=True)
231
+ await websocket.send_bytes(nal_unit)
220
232
 
221
233
  # Debug: Save to file
222
234
  if debug_file:
223
- debug_file.write(h264_chunk)
235
+ debug_file.write(nal_unit)
224
236
  debug_file.flush()
225
237
 
226
- chunk_count += 1
227
- if chunk_count % 100 == 0:
238
+ nal_count += 1
239
+ if nal_count % 100 == 0:
228
240
  print(
229
- f"[video/stream] Device {device_id}: Sent {chunk_count} chunks"
241
+ f"[video/stream] Device {device_id}: Sent {nal_count} NAL units"
230
242
  )
231
243
  except ConnectionError as e:
232
244
  print(f"[video/stream] Device {device_id}: Connection error: {e}")
@@ -260,6 +272,6 @@ async def video_stream_ws(
260
272
  # Debug: Close file
261
273
  if debug_file:
262
274
  debug_file.close()
263
- print(f"[video/stream] DEBUG: Closed debug file")
275
+ print("[video/stream] DEBUG: Closed debug file")
264
276
 
265
277
  print(f"[video/stream] Device {device_id}: Stream ended")
@@ -47,6 +47,9 @@ class ScrcpyStreamer:
47
47
  self.sps_pps_locked = False # Lock SPS/PPS after initial complete capture
48
48
  # Note: IDR is NOT locked - we keep updating to the latest frame
49
49
 
50
+ # NAL unit reading buffer (for read_nal_unit method)
51
+ self._nal_read_buffer = bytearray()
52
+
50
53
  # Find scrcpy-server location
51
54
  self.scrcpy_server_path = self._find_scrcpy_server()
52
55
 
@@ -83,6 +86,10 @@ class ScrcpyStreamer:
83
86
 
84
87
  async def start(self) -> None:
85
88
  """Start scrcpy server and establish connection."""
89
+ # Clear NAL reading buffer to ensure clean state
90
+ self._nal_read_buffer.clear()
91
+ print("[ScrcpyStreamer] Cleared NAL read buffer")
92
+
86
93
  try:
87
94
  # 0. Kill existing scrcpy server processes on device
88
95
  print("[ScrcpyStreamer] Cleaning up existing scrcpy processes...")
@@ -407,24 +414,21 @@ class ScrcpyStreamer:
407
414
  )
408
415
 
409
416
  elif nal_type == 5: # IDR frame
410
- # CRITICAL: Only cache COMPLETE IDR frames
411
- # Incomplete IDR frames cause "error while decoding MB" errors
412
- if self.cached_sps and self.cached_pps and is_complete and size >= 1024:
417
+ # Cache IDR if it's large enough (size check is sufficient)
418
+ # Note: When called from read_nal_unit(), the NAL is guaranteed complete
419
+ # because we extract it between two start codes. The is_complete flag
420
+ # is only False because the NAL is isolated (no next start code in buffer).
421
+ if self.cached_sps and self.cached_pps and size >= 1024:
413
422
  is_first = self.cached_idr is None
414
423
  self.cached_idr = nal_data
415
424
  if is_first:
416
425
  print(
417
- f"[ScrcpyStreamer] ✓ Cached COMPLETE IDR frame ({size} bytes)"
426
+ f"[ScrcpyStreamer] ✓ Cached IDR frame ({size} bytes)"
418
427
  )
419
428
  # Don't log every IDR update (too verbose)
420
- elif not is_complete:
421
- if size > 1024: # Only log if it's a large incomplete IDR
422
- print(
423
- f"[ScrcpyStreamer] ⚠ Skipped INCOMPLETE IDR ({size} bytes, extends to chunk boundary)"
424
- )
425
429
  elif size < 1024:
426
430
  print(
427
- f"[ScrcpyStreamer] ✗ Skipped small IDR ({size} bytes)"
431
+ f"[ScrcpyStreamer] ✗ Skipped small IDR ({size} bytes, likely incomplete)"
428
432
  )
429
433
 
430
434
  # Lock SPS/PPS once we have complete initial parameters
@@ -432,60 +436,6 @@ class ScrcpyStreamer:
432
436
  self.sps_pps_locked = True
433
437
  print("[ScrcpyStreamer] 🔒 SPS/PPS locked (IDR will continue updating)")
434
438
 
435
- def _prepend_sps_pps_to_idr(self, data: bytes) -> bytes:
436
- """Prepend SPS/PPS before EVERY IDR frame unconditionally.
437
-
438
- This ensures that clients can start decoding from any IDR frame,
439
- even if they join mid-stream. We always prepend to guarantee
440
- that every IDR is self-contained.
441
-
442
- Returns:
443
- Modified data with SPS/PPS prepended to all IDR frames
444
- """
445
- if not self.cached_sps or not self.cached_pps:
446
- return data
447
-
448
- nal_units = self._find_nal_units(data)
449
- if not nal_units:
450
- return data
451
-
452
- # Find all IDR frames
453
- idr_positions = [
454
- (start, size)
455
- for start, nal_type, size, _ in nal_units
456
- if nal_type == 5
457
- ]
458
-
459
- if not idr_positions:
460
- return data
461
-
462
- # Build modified data by prepending SPS/PPS before each IDR
463
- result = bytearray()
464
- last_pos = 0
465
- sps_pps = self.cached_sps + self.cached_pps
466
-
467
- for idr_start, idr_size in idr_positions:
468
- # Add data before this IDR
469
- result.extend(data[last_pos:idr_start])
470
-
471
- # Check if SPS/PPS already exists right before this IDR
472
- # (to avoid duplicating if scrcpy already sent them)
473
- prepend_offset = max(0, idr_start - len(sps_pps))
474
- if data[prepend_offset:idr_start] != sps_pps:
475
- # Prepend SPS/PPS before this IDR
476
- result.extend(sps_pps)
477
- print(
478
- f"[ScrcpyStreamer] Prepended SPS/PPS before IDR at position {idr_start}"
479
- )
480
-
481
- # Update position to start of IDR
482
- last_pos = idr_start
483
-
484
- # Add remaining data (including all IDR frames and data after)
485
- result.extend(data[last_pos:])
486
-
487
- return bytes(result)
488
-
489
439
  def get_initialization_data(self) -> bytes | None:
490
440
  """Get cached SPS/PPS/IDR for initializing new connections.
491
441
 
@@ -563,6 +513,86 @@ class ScrcpyStreamer:
563
513
  )
564
514
  raise ConnectionError(f"Failed to read from socket: {e}") from e
565
515
 
516
+ async def read_nal_unit(self, auto_cache: bool = True) -> bytes:
517
+ """Read one complete NAL unit from socket.
518
+
519
+ This method ensures each returned chunk is a complete, self-contained NAL unit.
520
+ WebSocket messages will have clear semantic boundaries (one message = one NAL unit).
521
+
522
+ Args:
523
+ auto_cache: If True, automatically cache SPS/PPS/IDR from this NAL unit
524
+
525
+ Returns:
526
+ bytes: Complete NAL unit (including start code)
527
+
528
+ Raises:
529
+ ConnectionError: If socket is closed or error occurs
530
+ """
531
+ if not self.tcp_socket:
532
+ raise ConnectionError("Socket not connected")
533
+
534
+ while True:
535
+ # Look for start codes in buffer
536
+ buffer = bytes(self._nal_read_buffer)
537
+ start_positions = []
538
+
539
+ # Find all start codes (0x00 0x00 0x00 0x01 or 0x00 0x00 0x01)
540
+ i = 0
541
+ while i < len(buffer) - 3:
542
+ if buffer[i] == 0x00 and buffer[i + 1] == 0x00:
543
+ if buffer[i + 2] == 0x00 and buffer[i + 3] == 0x01:
544
+ start_positions.append(i)
545
+ i += 4
546
+ elif buffer[i + 2] == 0x01:
547
+ start_positions.append(i)
548
+ i += 3
549
+ else:
550
+ i += 1
551
+ else:
552
+ i += 1
553
+
554
+ # If we have at least 2 start codes, we can extract the first NAL unit
555
+ if len(start_positions) >= 2:
556
+ # Extract first complete NAL unit (from first start code to second start code)
557
+ nal_unit = buffer[start_positions[0] : start_positions[1]]
558
+
559
+ # Remove extracted NAL unit from buffer
560
+ self._nal_read_buffer = bytearray(buffer[start_positions[1] :])
561
+
562
+ # Cache parameter sets if enabled
563
+ if auto_cache:
564
+ self._cache_nal_units(nal_unit)
565
+
566
+ return nal_unit
567
+
568
+ # Need more data - read from socket
569
+ try:
570
+ loop = asyncio.get_event_loop()
571
+ chunk = await loop.run_in_executor(
572
+ None, self.tcp_socket.recv, 512 * 1024
573
+ )
574
+
575
+ if not chunk:
576
+ # Socket closed - return any remaining buffered data as final NAL unit
577
+ if len(self._nal_read_buffer) > 0:
578
+ final_nal = bytes(self._nal_read_buffer)
579
+ self._nal_read_buffer.clear()
580
+ if auto_cache:
581
+ self._cache_nal_units(final_nal)
582
+ return final_nal
583
+ raise ConnectionError("Socket closed by remote")
584
+
585
+ # Append new data to buffer
586
+ self._nal_read_buffer.extend(chunk)
587
+
588
+ except ConnectionError:
589
+ raise
590
+ except Exception as e:
591
+ print(
592
+ f"[ScrcpyStreamer] Unexpected error in read_nal_unit: {type(e).__name__}: {e}"
593
+ )
594
+ raise ConnectionError(f"Failed to read from socket: {e}") from e
595
+
566
596
  def stop(self) -> None:
567
597
  """Stop scrcpy server and cleanup resources."""
568
598
  # Close socket
@@ -1 +1 @@
1
- import{j as o}from"./index--ElIPD22.js";function t(){return o.jsx("div",{className:"p-2",children:o.jsx("h3",{children:"About"})})}export{t as component};
1
+ import{j as o}from"./index-Dn3vR6uV.js";function t(){return o.jsx("div",{className:"p-2",children:o.jsx("h3",{children:"About"})})}export{t as component};
@@ -0,0 +1,25 @@
1
+ import{j as l,r as x,g as Ie,a as Oe,s as Ue,b as Ne,c as $e,d as Te,e as He,f as ze,i as Ye,h as Ve,k as We,l as Xe}from"./index-Dn3vR6uV.js";function Ge({id:m,model:ce,status:U,isInitialized:R,isActive:k,onClick:O}){const $=U==="device";return l.jsx("button",{onClick:O,className:`w-full text-left px-4 py-3 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-12 shrink-0 ${k?"bg-blue-500 text-white shadow-md":"bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700"}`,children:l.jsxs("div",{className:"flex items-center justify-between gap-2",children:[l.jsxs("div",{className:"flex items-center gap-3 min-w-0 flex-1",children:[l.jsx("div",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${$?"bg-green-400 shadow-[0_0_4px_rgba(74,222,128,0.6)]":"bg-gray-400"}`,title:$?"在线":"离线"}),l.jsxs("div",{className:"min-w-0 flex-1",children:[l.jsx("div",{className:`font-medium text-sm truncate ${k?"text-white":"text-gray-900 dark:text-gray-100"}`,children:ce||"未知设备"}),l.jsx("div",{className:`text-xs truncate ${k?"text-blue-100":"text-gray-500 dark:text-gray-400"}`,children:m})]})]}),R&&l.jsx("div",{className:`flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center ${k?"bg-white/20":"bg-green-100 dark:bg-green-900"}`,children:l.jsx("svg",{className:`w-3 h-3 ${k?"text-white":"text-green-600 dark:text-green-400"}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})})]})})}const Ke=()=>{try{const m=localStorage.getItem("sidebar-collapsed");return m!==null?JSON.parse(m):!1}catch(m){return console.warn("Failed to load sidebar collapsed state:",m),!1}};function Je({devices:m,currentDeviceId:ce,onSelectDevice:U,onOpenConfig:R}){const[k,O]=x.useState(Ke);x.useEffect(()=>{localStorage.setItem("sidebar-collapsed",JSON.stringify(k))},[k]),x.useEffect(()=>{const w=C=>{(C.metaKey||C.ctrlKey)&&C.key==="b"&&(C.preventDefault(),O(!k))};return window.addEventListener("keydown",w),()=>window.removeEventListener("keydown",w)},[k]);const $=()=>{O(!k)};return l.jsxs(l.Fragment,{children:[k&&l.jsx("button",{onClick:$,className:"fixed left-0 top-20 w-8 h-16 bg-blue-500 hover:bg-blue-600 text-white rounded-r-full shadow-lg transition-all duration-300 z-50 flex items-center justify-center",title:"展开侧边栏",children:l.jsx("svg",{className:"w-4 h-4 transition-transform duration-300",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}),l.jsxs("div",{className:`${k?"w-0 -ml-8":"w-64"} transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-full min-h-0 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-700 flex flex-col overflow-hidden`,children:[l.jsxs("div",{className:"border-b border-gray-200 dark:border-gray-700 flex items-center justify-between p-4 whitespace-nowrap",children:[l.jsxs("div",{children:[l.jsxs("h2",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2",children:[l.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),"设备列表"]}),l.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:["共 ",m.length," 个设备"]})]}),l.jsx("button",{onClick:$,className:"p-1.5 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-all duration-300 ease-[cubic-bezier(0.4,0.0,0.2,1)]",title:"收缩侧边栏",children:l.jsx("svg",{className:"w-4 h-4 text-gray-500 dark:text-gray-400 transition-transform duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)]",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})})]}),l.jsx("div",{className:"flex-1 overflow-y-auto p-3 space-y-2 min-h-0",children:m.length===0?l.jsxs("div",{className:"text-center py-8 text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-12 h-12 mx-auto mb-2 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("p",{className:"text-sm",children:"未检测到设备"}),l.jsx("p",{className:"text-xs mt-1",children:"请连接 ADB 设备"})]}):m.map(w=>l.jsx(Ge,{id:w.id,model:w.model,status:w.status,isInitialized:w.is_initialized,isActive:w.id===ce,onClick:()=>U(w.id)},w.id))}),l.jsx("div",{className:"p-3 border-t border-gray-200 dark:border-gray-700 space-y-2 whitespace-nowrap",children:l.jsxs("button",{onClick:R,className:"w-full px-4 py-2 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] font-medium text-gray-700 dark:text-gray-300 flex items-center justify-center gap-2",children:[l.jsxs("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]}),"全局配置"]})})]})]})}var Fe={exports:{}};const qe={},Ze=Object.freeze(Object.defineProperty({__proto__:null,default:qe},Symbol.toStringTag,{value:"Module"})),Qe=Ie(Ze);var et=Fe.exports,_e;function tt(){return _e||(_e=1,(function(m,ce){(function(U,R){m.exports=R(Qe)})(et,(function(U){function R(r,a){(a==null||a>r.length)&&(a=r.length);for(var e=0,t=Array(a);e<a;e++)t[e]=r[e];return t}function k(r){if(Array.isArray(r))return r}function O(r){if(Array.isArray(r))return R(r)}function $(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function w(r,a){if(!(r instanceof a))throw new TypeError("Cannot call a class as a function")}function C(r,a){for(var e=0;e<a.length;e++){var t=a[e];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,X(t.key),t)}}function T(r,a,e){return a&&C(r.prototype,a),e&&C(r,e),Object.defineProperty(r,"prototype",{writable:!1}),r}function p(r,a){var e=typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(!e){if(Array.isArray(r)||(e=Y(r))||a){e&&(r=e);var t=0,n=function(){};return{s:n,n:function(){return t>=r.length?{done:!0}:{done:!1,value:r[t++]}},e:function(c){throw c},f:n}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
2
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var i,s=!0,o=!1;return{s:function(){e=e.call(r)},n:function(){var c=e.next();return s=c.done,c},e:function(c){o=!0,i=c},f:function(){try{s||e.return==null||e.return()}finally{if(o)throw i}}}}function A(r){var a=te();return function(){var e,t=E(r);if(a){var n=E(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return ge(this,e)}}function D(r,a,e){return(a=X(a))in r?Object.defineProperty(r,a,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[a]=e,r}function E(r){return E=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(a){return a.__proto__||Object.getPrototypeOf(a)},E(r)}function V(r,a){if(typeof a!="function"&&a!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(a&&a.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),a&&de(r,a)}function te(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(te=function(){return!!r})()}function ve(r){if(typeof Symbol<"u"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function re(r,a){var e=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(e!=null){var t,n,i,s,o=[],c=!0,u=!1;try{if(i=(e=e.call(r)).next,a!==0)for(;!(c=(t=i.call(e)).done)&&(o.push(t.value),o.length!==a);c=!0);}catch(d){u=!0,n=d}finally{try{if(!c&&e.return!=null&&(s=e.return(),Object(s)!==s))return}finally{if(u)throw n}}return o}}function ae(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
3
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function H(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
4
+ In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ge(r,a){if(a&&(typeof a=="object"||typeof a=="function"))return a;if(a!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return $(r)}function de(r,a){return de=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},de(r,a)}function z(r,a){return k(r)||re(r,a)||Y(r,a)||ae()}function j(r){return O(r)||ve(r)||Y(r)||H()}function Q(r,a){if(typeof r!="object"||!r)return r;var e=r[Symbol.toPrimitive];if(e!==void 0){var t=e.call(r,a);if(typeof t!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}function X(r){var a=Q(r,"string");return typeof a=="symbol"?a:a+""}function ne(r){"@babel/helpers - typeof";return ne=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},ne(r)}function Y(r,a){if(r){if(typeof r=="string")return R(r,a);var e={}.toString.call(r).slice(8,-1);return e==="Object"&&r.constructor&&(e=r.constructor.name),e==="Map"||e==="Set"?Array.from(r):e==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?R(r,a):void 0}}var ie,ee;function q(r,a){ie=r,ee=a}function b(r){if(ie){for(var a=arguments.length,e=new Array(a>1?a-1:0),t=1;t<a;t++)e[t-1]=arguments[t];ie.apply(void 0,[r].concat(e))}}function K(r){if(ee){for(var a=arguments.length,e=new Array(a>1?a-1:0),t=1;t<a;t++)e[t-1]=arguments[t];ee.apply(void 0,[r].concat(e))}}var le=(function(){function r(a){w(this,r),this.listener={},this.type=a|""}return T(r,[{key:"on",value:function(e,t){return this.listener[e]||(this.listener[e]=[]),this.listener[e].push(t),!0}},{key:"off",value:function(e,t){if(this.listener[e]){var n=this.listener[e].indexOf(t);return n>-1&&this.listener[e].splice(n,1),!0}return!1}},{key:"offAll",value:function(){this.listener={}}},{key:"dispatch",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];return this.listener[e]?(this.listener[e].map(function(s){s.apply(null,n)}),!0):!1}}]),r})(),fe=(function(){function r(){w(this,r)}return T(r,null,[{key:"init",value:function(){r.types={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],hev1:[],hvcC:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};var e;for(e in r.types)r.types.hasOwnProperty(e)&&(r.types[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);var t=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),n=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]);r.HDLR_TYPES={video:t,audio:n};var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),s=new Uint8Array([0,0,0,0,0,0,0,0]);r.STTS=r.STSC=r.STCO=s,r.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),r.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0]),r.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),r.STSD=new Uint8Array([0,0,0,0,0,0,0,1]);var o=new Uint8Array([105,115,111,109]),c=new Uint8Array([97,118,99,49]),u=new Uint8Array([0,0,0,1]);r.FTYP=r.box(r.types.ftyp,o,u,o,c),r.DINF=r.box(r.types.dinf,r.box(r.types.dref,i))}},{key:"box",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];for(var s=8,o=n.length,c=o,u;o--;)s+=n[o].byteLength;for(u=new Uint8Array(s),u[0]=s>>24&255,u[1]=s>>16&255,u[2]=s>>8&255,u[3]=s&255,u.set(e,4),o=0,s=8;o<c;++o)u.set(n[o],s),s+=n[o].byteLength;return u}},{key:"hdlr",value:function(e){return r.box(r.types.hdlr,r.HDLR_TYPES[e])}},{key:"mdat",value:function(e){return r.box(r.types.mdat,e)}},{key:"mdhd",value:function(e,t){return r.box(r.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,e>>24&255,e>>16&255,e>>8&255,e&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255,85,196,0,0]))}},{key:"mdia",value:function(e){return r.box(r.types.mdia,r.mdhd(e.timescale,e.duration),r.hdlr(e.type),r.minf(e))}},{key:"mfhd",value:function(e){return r.box(r.types.mfhd,new Uint8Array([0,0,0,0,e>>24,e>>16&255,e>>8&255,e&255]))}},{key:"minf",value:function(e){return e.type==="audio"?r.box(r.types.minf,r.box(r.types.smhd,r.SMHD),r.DINF,r.stbl(e)):r.box(r.types.minf,r.box(r.types.vmhd,r.VMHD),r.DINF,r.stbl(e))}},{key:"moof",value:function(e,t,n){return r.box(r.types.moof,r.mfhd(e),r.traf(n,t))}},{key:"moov",value:function(e,t,n){for(var i=e.length,s=[];i--;)s[i]=r.trak(e[i]);return r.box.apply(null,[r.types.moov,r.mvhd(n,t)].concat(s).concat(r.mvex(e)))}},{key:"mvex",value:function(e){for(var t=e.length,n=[];t--;)n[t]=r.trex(e[t]);return r.box.apply(null,[r.types.mvex].concat(n))}},{key:"mvhd",value:function(e,t){var n=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,e>>24&255,e>>16&255,e>>8&255,e&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return r.box(r.types.mvhd,n)}},{key:"sdtp",value:function(e){var t=e.samples||[],n=new Uint8Array(4+t.length),i,s;for(s=0;s<t.length;s++)i=t[s].flags,n[s+4]=i.dependsOn<<4|i.isDependedOn<<2|i.hasRedundancy;return r.box(r.types.sdtp,n)}},{key:"stbl",value:function(e){return r.box(r.types.stbl,r.stsd(e),r.box(r.types.stts,r.STTS),r.box(r.types.stsc,r.STSC),r.box(r.types.stsz,r.STSZ),r.box(r.types.stco,r.STCO))}},{key:"avc1",value:function(e){var t=[],n=[],i,s,o;for(i=0;i<e.sps.length;i++)s=e.sps[i],o=s.byteLength,t.push(o>>>8&255),t.push(o&255),t=t.concat(Array.prototype.slice.call(s));for(i=0;i<e.pps.length;i++)s=e.pps[i],o=s.byteLength,n.push(o>>>8&255),n.push(o&255),n=n.concat(Array.prototype.slice.call(s));var c=r.box(r.types.avcC,new Uint8Array([1,t[3],t[4],t[5],255,224|e.sps.length].concat(t).concat([e.pps.length]).concat(n))),u=e.width,d=e.height;return r.box(r.types.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,u>>8&255,u&255,d>>8&255,d&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),c,r.box(r.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"hev1",value:function(e){for(var t=[],n=[],i=[],s,o,c=0;c<(((u=e.vps)===null||u===void 0?void 0:u.length)||0);c++){var u;s=e.vps[c],o=s.byteLength,t.push(o>>>8&255,o&255),t=t.concat(Array.prototype.slice.call(s))}for(var d=0;d<(((f=e.sps)===null||f===void 0?void 0:f.length)||0);d++){var f;s=e.sps[d],o=s.byteLength,n.push(o>>>8&255,o&255),n=n.concat(Array.prototype.slice.call(s))}for(var h=0;h<(((y=e.pps)===null||y===void 0?void 0:y.length)||0);h++){var y;s=e.pps[h],o=s.byteLength,i.push(o>>>8&255,o&255),i=i.concat(Array.prototype.slice.call(s))}var S=e.hvcC,B=S.profile_space,M=S.tier_flag,_=S.profile_idc,I=S.profile_compatibility_flags,P=S.constraint_indicator_flags,pe=S.level_idc,Z=S.chroma_format_idc,ye=r.box(r.types.hvcC,new Uint8Array([1,B<<6|M<<5|_,I>>24&255,I>>16&255,I>>8&255,I&255].concat(j(P),[pe,240,0,252,252|Z,248,248,0,0,3,3,32,0,1],j(t),[33,0,1],j(n),[34,0,1],j(i)))),ue=e.width,F=e.height;return r.box(r.types.hev1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,ue>>8&255,ue&255,F>>8&255,F&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),ye,r.box(r.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"esds",value:function(e){var t=e.config.byteLength,n=new Uint8Array(26+t+3);return n.set([0,0,0,0,3,23+t,0,1,0,4,15+t,64,21,0,0,0,0,0,0,0,0,0,0,0,5,t]),n.set(e.config,26),n.set([6,1,2],26+t),n}},{key:"mp4a",value:function(e){var t=e.audiosamplerate;return r.box(r.types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,e.channelCount,0,16,0,0,0,0,t>>8&255,t&255,0,0]),r.box(r.types.esds,r.esds(e)))}},{key:"stsd",value:function(e){return e.type==="audio"?r.box(r.types.stsd,r.STSD,r.mp4a(e)):e.codec.startsWith("hvc1")?r.box(r.types.stsd,r.STSD,r.hev1(e)):r.box(r.types.stsd,r.STSD,r.avc1(e))}},{key:"tkhd",value:function(e){var t=e.id,n=e.duration,i=e.width,s=e.height,o=e.volume;return r.box(r.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,t>>24&255,t>>16&255,t>>8&255,t&255,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,n&255,0,0,0,0,0,0,0,0,0,0,0,0,o>>0&255,o%1*10>>0&255,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,i>>8&255,i&255,0,0,s>>8&255,s&255,0,0]))}},{key:"traf",value:function(e,t){var n=r.sdtp(e),i=e.id;return r.box(r.types.traf,r.box(r.types.tfhd,new Uint8Array([0,0,0,0,i>>24,i>>16&255,i>>8&255,i&255])),r.box(r.types.tfdt,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,t&255])),r.trun(e,n.length+16+16+8+16+8+8),n)}},{key:"trak",value:function(e){return e.duration=e.duration||4294967295,r.box(r.types.trak,r.tkhd(e),r.mdia(e))}},{key:"trex",value:function(e){var t=e.id;return r.box(r.types.trex,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,t&255,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]))}},{key:"trun",value:function(e,t){var n=e.samples||[],i=n.length,s=12+16*i,o=new Uint8Array(s),c,u,d,f,h,y;for(t+=8+s,o.set([0,0,15,1,i>>>24&255,i>>>16&255,i>>>8&255,i&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255],0),c=0;c<i;c++)u=n[c],d=u.duration,f=u.size,h=u.flags,y=u.cts,o.set([d>>>24&255,d>>>16&255,d>>>8&255,d&255,f>>>24&255,f>>>16&255,f>>>8&255,f&255,h.isLeading<<2|h.dependsOn,h.isDependedOn<<6|h.hasRedundancy<<4|h.paddingValue<<1|h.isNonSync,h.degradPrio&61440,h.degradPrio&15,y>>>24&255,y>>>16&255,y>>>8&255,y&255],12+16*c);return r.box(r.types.trun,o)}},{key:"initSegment",value:function(e,t,n){r.types||r.init();var i=r.moov(e,t,n),s;return s=new Uint8Array(r.FTYP.byteLength+i.byteLength),s.set(r.FTYP),s.set(i,r.FTYP.byteLength),s}}]),r})(),ke=(function(){function r(){w(this,r)}return T(r,null,[{key:"samplingRateMap",get:function(){return[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350]}},{key:"getHeaderLength",value:function(e){return e[1]&1?7:9}},{key:"getFrameLength",value:function(e){return(e[3]&3)<<11|e[4]<<3|(e[5]&224)>>>5}},{key:"isAACPattern",value:function(e){return e[0]===255&&(e[1]&240)===240&&(e[1]&6)===0}},{key:"extractAAC",value:function(e){var t=0,n=e.byteLength,i=[],s,o;if(!r.isAACPattern(e))return K("Invalid ADTS audio format"),{valid:!1};s=r.getHeaderLength(e);for(var c=e.subarray(0,s);t<n;)o=r.getFrameLength(e),i.push(e.subarray(s,o)),e=e.slice(o),t+=o;return{valid:!0,header:c,slices:i}}}]),r})(),be=1,g=(function(r){V(e,r);var a=A(e);function e(){return w(this,e),a.apply(this,arguments)}return T(e,[{key:"flush",value:function(){this.mp4track.len=0,this.mp4track.samples=[]}},{key:"isReady",value:function(){return!this.readyToDecode||!this.samples.length?null:!0}}],[{key:"getTrackID",value:function(){return be++}}]),e})(le),J=(function(r){V(e,r);var a=A(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"AACRemuxer"),s.frameDuration=i,s.readyToDecode=!1,s.header=null,s.nextDts=0,s.dts=0,s.mp4track={id:g.getTrackID(),type:"audio",channelCount:0,len:0,fragmented:!0,timescale:t,duration:n,samples:[],config:"",codec:""},s.samples=[],s}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.header=null,this.mp4track.codec="",this.mp4track.channelCount="",this.mp4track.config="",this.mp4track.timescale=this.timescale,this.nextDts=0,this.dts=0}},{key:"feed",value:function(n,i){var s=ke.extractAAC(n),o=s.valid,c=s.header,u=s.slices;return this.header||(this.header=c),o&&u.length>0?(this.remux(this.getAudioFrames(u,i)),!0):(K("Failed to extract audio data from:",n),this.dispatch("outOfData"),!1)}},{key:"getAudioFrames",value:function(n,i){var s=[],o=0,c=0,u=p(n),d;try{for(u.s();!(d=u.n()).done;){var f=d.value;s.push({units:f})}}catch(h){u.e(h)}finally{u.f()}return o=i?i/s.length|0:this.frameDuration,c=i?i-o*s.length:0,s.map(function(h){h.duration=o,c>0&&(h.duration++,c--)}),s}},{key:"remux",value:function(n){if(n.length>0)for(var i=0;i<n.length;i++){var s=n[i],o=s.units,c=o.byteLength;this.samples.push({units:o,size:c,duration:s.duration}),this.mp4track.len+=c,this.readyToDecode||this.setAACConfig()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift();if(u.units,c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,dependsOn:1}},n.set(u.units,i),i+=u.size,s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"setAACConfig",value:function(){var n,i,s,o=new Uint8Array(2);this.header&&(n=((this.header[2]&192)>>>6)+1,i=(this.header[2]&60)>>>2,s=(this.header[2]&1)<<2,s|=(this.header[3]&192)>>>6,o[0]=n<<3,o[0]|=(i&14)>>1,o[1]|=(i&1)<<7,o[1]|=s<<3,this.mp4track.codec="mp4a.40."+n,this.mp4track.channelCount=s,this.mp4track.config=o,this.readyToDecode=!0)}}]),e})(g),W=(function(){function r(a){w(this,r),this.data=a,this.index=0,this.bitLength=a.byteLength*8}return T(r,[{key:"setData",value:function(e){this.data=e,this.index=0,this.bitLength=e.byteLength*8}},{key:"bitsAvailable",get:function(){return this.bitLength-this.index}},{key:"skipBits",value:function(e){if(this.bitsAvailable<e)return!1;this.index+=e}},{key:"readBits",value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,n=this.getBits(e,this.index,t);return n}},{key:"getBits",value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(this.bitsAvailable<e)return 0;var i=t%8,s=this.data[t/8|0]&255>>>i,o=8-i;if(o>=e)return n&&(this.index+=e),s>>o-e;n&&(this.index+=o);var c=e-o;return s<<c|this.getBits(c,t+o,n)}},{key:"skipLZ",value:function(){var e;for(e=0;e<this.bitLength-this.index;++e)if(this.getBits(1,this.index+e,!1)!==0)return this.index+=e,e;return e}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return this.readBits(1)===1}},{key:"readUByte",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1;return this.readBits(e*8)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}}]),r})(),se=(function(){function r(){w(this,r)}return T(r,null,[{key:"extractNALu",value:function(e){for(var t=0,n=e.byteLength,i=[],s=0,o=0;t<n;){var c=e[t++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;s!==t-u&&i.push(e.subarray(s,t-u)),s=t,o=0}else o=0}var d=null;return s<n&&(d=e.subarray(s,n)),[i,d]}},{key:"skipScalingList",value:function(e,t){for(var n=8,i=8,s,o=0;o<t;o++)i!==0&&(s=e.readEG(),i=(n+s+256)%256),n=i===0?n:i}},{key:"readSPS",value:function(e){var t=new W(e),n=0,i=0,s=0,o=0,c=1,u,d,f,h,y,S,B=0;t.readUByte();for(var M=[],_=1,I=e.byteLength,P=_;P<I;P++)P+2<I&&t.readBits(24,!1)===3?(M.push(t.readBits(8)),M.push(t.readBits(8)),P+=2,t.readBits(8)):M.push(t.readBits(8));if(t.setData(new Uint8Array(M)),u=t.readUByte(),t.readBits(5),t.skipBits(3),t.readUByte(),t.skipUEG(),u===100||u===110||u===122||u===244||u===44||u===83||u===86||u===118||u===128){var pe=t.readUEG();if(pe===3&&t.skipBits(1),t.skipUEG(),t.skipUEG(),t.skipBits(1),t.readBoolean()){S=pe!==3?8:12;for(var Z=0;Z<S;++Z)t.readBoolean()&&(Z<6?r.skipScalingList(t,16):r.skipScalingList(t,64))}}t.skipUEG();var ye=t.readUEG();if(ye===0)t.readUEG();else if(ye===1){t.skipBits(1),t.skipEG(),t.skipEG(),d=t.readUEG();for(var ue=0;ue<d;++ue)t.skipEG()}if(t.skipUEG(),t.skipBits(1),f=t.readUEG(),h=t.readUEG(),y=t.readBits(1),y===0&&t.skipBits(1),t.skipBits(1),t.readBoolean()&&(n=t.readUEG(),i=t.readUEG(),s=t.readUEG(),o=t.readUEG()),t.readBoolean()){if(t.readBoolean()){var F,me=t.readUByte();switch(me){case 1:F=[1,1];break;case 2:F=[12,11];break;case 3:F=[10,11];break;case 4:F=[16,11];break;case 5:F=[40,33];break;case 6:F=[24,11];break;case 7:F=[20,11];break;case 8:F=[32,11];break;case 9:F=[80,33];break;case 10:F=[18,11];break;case 11:F=[15,11];break;case 12:F=[64,33];break;case 13:F=[160,99];break;case 14:F=[4,3];break;case 15:F=[3,2];break;case 16:F=[2,1];break;case 255:{F=[t.readUByte()<<8|t.readUByte(),t.readUByte()<<8|t.readUByte()];break}}F&&F[0]>0&&F[1]>0&&(c=F[0]/F[1])}if(t.readBoolean()&&t.skipBits(1),t.readBoolean()&&(t.skipBits(4),t.readBoolean()&&t.skipBits(24)),t.readBoolean()&&(t.skipUEG(),t.skipUEG()),t.readBoolean()){var we=t.readUInt(),Ae=t.readUInt(),Se=t.readBoolean(),Pe=Ae/(2*we);Se&&(B=Pe)}}return{fps:B>0?B:void 0,width:Math.ceil(((f+1)*16-n*2-i*2)*c),height:(2-y)*(h+1)*16-(y?2:4)*(s+o)}}}]),r})(),G=(function(){function r(a){w(this,r),this.payload=a,this.nri=(this.payload[0]&96)>>5,this.nalUnitType=this.payload[0]&31,this._sliceType=null,this._isFirstSlice=!1}return T(r,[{key:"toString",value:function(){return"".concat(r.TYPES[this.type()]||"UNKNOWN",": NRI: ").concat(this.getNri())}},{key:"getNri",value:function(){return this.nri}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return this.nalUnitType===r.IDR}},{key:"isVCL",get:function(){return this.nalUnitType==r.IDR||this.nalUnitType==r.NDR}},{key:"parseHeader",value:function(){var e=new W(this.getPayload());e.readUByte(),this._isFirstSlice=e.readUEG()===0,this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),t=new DataView(e.buffer);return t.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"NDR",get:function(){return 1}},{key:"IDR",get:function(){return 5}},{key:"SEI",get:function(){return 6}},{key:"SPS",get:function(){return 7}},{key:"PPS",get:function(){return 8}},{key:"AUD",get:function(){return 9}},{key:"TYPES",get:function(){var e;return e={},D(e,r.IDR,"IDR"),D(e,r.SEI,"SEI"),D(e,r.SPS,"SPS"),D(e,r.PPS,"PPS"),D(e,r.NDR,"NDR"),D(e,r.AUD,"AUD"),e}}]),r})();function he(r,a){var e=new Uint8Array((r.byteLength|0)+(a.byteLength|0));return e.set(r,0),e.set(a,r.byteLength|0),e}function xe(r){var a,e,t,n="";return a=Math.floor(r),e=parseInt(a/3600,10)%24,t=parseInt(a/60,10)%60,a=a<0?0:a%60,e>0&&(n+=(e<10?"0"+e:e)+":"),n+=(t<10?"0"+t:t)+":"+(a<10?"0"+a:a),n}var N=(function(r){V(e,r);var a=A(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"H264Remuxer"),s.frameDuration=i,s.readyToDecode=!1,s.nextDts=0,s.dts=0,s.mp4track={id:g.getTrackID(),type:"video",len:0,fragmented:!0,sps:"",pps:"",fps:30,width:0,height:0,timescale:t,duration:n,samples:[]},s.samples=[],s.remainingData=new Uint8Array,s.kfCounter=0,s.pendingUnits={},s}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.sps="",this.mp4track.pps="",this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(n,i,s){var o=[],c;n=he(this.remainingData,n);var u=se.extractNALu(n),d=z(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,s)),!0):(K("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(n,i,s){var o=this,c=[],u=[],d=0,f=0,h=!1,y=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,y=this.pendingUnits.vcl,h=this.pendingUnits.keyFrame,this.pendingUnits={});var S=p(n),B;try{for(S.s();!(B=S.n()).done;){var M=B.value,_=new G(M);c.length&&y&&(_.isFirstSlice||!_.isVCL)&&(u.push({units:c,keyFrame:h}),c=[],h=!1,y=!1),c.push(_),h=h||_.isKeyframe,y=y||_.isVCL}}catch(P){S.e(P)}finally{S.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:h,vcl:y};else if(y)u.push({units:c,keyFrame:h});else{var I=u.length-1;I>=0&&(u[I].units=u[I].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,f=i?i-d*u.length:0,u.map(function(P){P.duration=d,P.compositionTimeOffset=s,f>0&&(P.duration++,f--),o.kfCounter++,P.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),b("jmuxer: No. of H264 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(n){var i=p(n),s;try{for(i.s();!(s=i.n()).done;){var o=s.value,c=[],u=0,d=p(o.units),f;try{for(d.s();!(f=d.n()).done;){var h=f.value;this.parseNAL(h)&&(c.push(h),u+=h.getSize())}}catch(y){d.e(y)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(y){i.e(y)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var f=p(d),h;try{for(f.s();!(h=f.n()).done;){var y=h.value;n.set(y.getData(),i),i+=y.getSize()}}catch(S){f.e(S)}finally{f.f()}s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(n){var i=se.readSPS(new Uint8Array(n));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.sps=[new Uint8Array(n)],this.mp4track.codec="avc1.";for(var s=new DataView(n.buffer,n.byteOffset+1,4),o=0;o<3;++o){var c=s.getUint8(o).toString(16);c.length<2&&(c="0"+c),this.mp4track.codec+=c}}},{key:"parsePPS",value:function(n){this.mp4track.pps=[new Uint8Array(n)]}},{key:"parseNAL",value:function(n){if(!n)return!1;if(n.isVCL)return!0;var i=!1;switch(n.type()){case G.PPS:this.mp4track.pps||this.parsePPS(n.getPayload()),i=!0;break;case G.SPS:this.mp4track.sps||this.parseSPS(n.getPayload()),i=!0;break;case G.AUD:b("AUD - ignoing");break;case G.SEI:b("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.pps&&this.mp4track.sps&&(this.readyToDecode=!0),i}}]),e})(g),oe=(function(){function r(){w(this,r)}return T(r,null,[{key:"extractNALu",value:function(e){for(var t=0,n=e.byteLength,i=[],s=0,o=0;t<n;){var c=e[t++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;s!==t-u&&i.push(e.subarray(s,t-u)),s=t,o=0}else o=0}var d=null;return s<n&&(d=e.subarray(s,n)),[i,d]}},{key:"removeEmulationPreventionBytes",value:function(e){for(var t=[],n=0,i=0;i<e.length;i++){var s=e[i];if(n===2&&s===3){n=0;continue}t.push(s),s===0?n++:n=0}return new Uint8Array(t)}},{key:"readSPS",value:function(e){var t=new W(e);t.readUByte(),t.readUByte(),t.readBits(4),t.readBits(3),t.readBits(1);for(var n=t.readBits(2),i=t.readBits(1),s=t.readBits(5),o=t.readUInt(),c=new Uint8Array(6),u=0;u<6;u++)c[u]=t.readUByte();var d=t.readUByte();t.readUEG();var f=t.readUEG();f===3&&t.readBits(1);var h=t.readUEG(),y=t.readUEG(),S=t.readBoolean(),B=0,M=0,_=0,I=0;S&&(B=t.readUEG(),M=t.readUEG(),_=t.readUEG(),I=t.readUEG());var P=null,pe=t.readBoolean();if(pe){var Z=t.readBoolean();if(Z){var ye=t.readUByte();ye===255&&(t.readUShort(),t.readUShort())}var ue=t.readBoolean();ue&&t.readBoolean();var F=t.readBoolean();if(F){t.readBits(3),t.readBoolean();var me=t.readBoolean();me&&(t.readUByte(),t.readUByte(),t.readUByte())}var we=t.readBoolean();we&&(t.readUEG(),t.readUEG()),t.readBoolean(),t.readBoolean(),t.readBoolean();var Ae=t.readBoolean();if(Ae){var Se=t.readUInt(),Pe=t.readUInt();t.readBoolean(),Se&&(P=Pe/(2*Se))}}var Be=f===1||f===2?2:1,Re=f===1?2:1,Le=h-Be*(M+B),Me=y-Re*(_+I);return{width:Le,height:Me,profile_space:n,tier_flag:i,profile_idc:s,profile_compatibility_flags:o,constraint_indicator_flags:c,level_idc:d,chroma_format_idc:f,fps:P}}}]),r})(),L=(function(){function r(a){w(this,r),this.payload=a,this.nalUnitType=(a[0]&126)>>1,this.nuhLayerId=(a[0]&1)<<5|(a[1]&248)>>3,this.nuhTemporalIdPlus1=a[1]&7,this._isFirstSlice=null,this._sliceType=null}return T(r,[{key:"toString",value:function(){return"".concat(r.TYPES[this.type()]||"UNKNOWN ("+this.type()+")",": Layer: ").concat(this.nuhLayerId,", Temporal Id: ").concat(this.nuhTemporalIdPlus1)}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return[r.IDR_W_RADL,r.IDR_N_LP,r.CRA].includes(this.nalUnitType)}},{key:"isVCL",get:function(){return this.nalUnitType<=31}},{key:"parseHeader",value:function(){var e=new W(this.getPayload());e.readUByte(),e.readUByte(),this._isFirstSlice=e.readBoolean(),this.isKeyframe&&e.readBits(1),e.readUEG(),this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),t=new DataView(e.buffer);return t.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"TRAIL_N",get:function(){return 0}},{key:"TRAIL_R",get:function(){return 1}},{key:"IDR_W_RADL",get:function(){return 19}},{key:"IDR_N_LP",get:function(){return 20}},{key:"CRA",get:function(){return 21}},{key:"VPS",get:function(){return 32}},{key:"SPS",get:function(){return 33}},{key:"PPS",get:function(){return 34}},{key:"AUD",get:function(){return 35}},{key:"SEI",get:function(){return 39}},{key:"SEI2",get:function(){return 40}},{key:"TYPES",get:function(){var e;return e={},D(e,r.TRAIL_N,"TRAIL_N"),D(e,r.TRAIL_R,"TRAIL_R"),D(e,r.IDR_W_RADL,"IDR"),D(e,r.IDR_N_LP,"IDR2"),D(e,r.CRA,"CRA"),D(e,r.VPS,"VPS"),D(e,r.SPS,"SPS"),D(e,r.PPS,"PPS"),D(e,r.AUD,"AUD"),D(e,r.SEI,"SEI"),D(e,r.SEI2,"SEI2"),e}}]),r})(),Ce=(function(r){V(e,r);var a=A(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"H264Remuxer"),s.frameDuration=i,s.readyToDecode=!1,s.nextDts=0,s.dts=0,s.mp4track={id:g.getTrackID(),type:"video",len:0,fragmented:!0,vps:"",sps:"",pps:"",hvcC:{},fps:30,width:0,height:0,timescale:t,duration:n,samples:[]},s.samples=[],s.remainingData=new Uint8Array,s.kfCounter=0,s.pendingUnits={},s}return T(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.vps="",this.mp4track.sps="",this.mp4track.pps="",this.mp4track.hvcC={},this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(n,i,s){var o=[],c;n=he(this.remainingData,n);var u=oe.extractNALu(n),d=z(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,s)),!0):(K("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(n,i,s){var o=this,c=[],u=[],d=0,f=0,h=!1,y=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,y=this.pendingUnits.vcl,h=this.pendingUnits.keyFrame,this.pendingUnits={});var S=p(n),B;try{for(S.s();!(B=S.n()).done;){var M=B.value,_=new L(M);c.length&&y&&(_.isFirstSlice||!_.isVCL)&&(u.push({units:c,keyFrame:h}),c=[],h=!1,y=!1),c.push(_),h=h||_.isKeyframe,y=y||_.isVCL}}catch(P){S.e(P)}finally{S.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:h,vcl:y};else if(y)u.push({units:c,keyFrame:h});else{var I=u.length-1;I>=0&&(u[I].units=u[I].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,f=i?i-d*u.length:0,u.map(function(P){P.duration=d,P.compositionTimeOffset=s,f>0&&(P.duration++,f--),o.kfCounter++,P.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),b("jmuxer: No. of H265 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(n){var i=p(n),s;try{for(i.s();!(s=i.n()).done;){var o=s.value,c=[],u=0,d=p(o.units),f;try{for(d.s();!(f=d.n()).done;){var h=f.value;this.parseNAL(h)&&(c.push(h),u+=h.getSize())}}catch(y){d.e(y)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(y){i.e(y)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var f=p(d),h;try{for(f.s();!(h=f.n()).done;){var y=h.value;n.set(y.getData(),i),i+=y.getSize()}}catch(S){f.e(S)}finally{f.f()}s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(n){this.mp4track.sps=[new Uint8Array(n)],n=oe.removeEmulationPreventionBytes(n);var i=oe.readSPS(new Uint8Array(n));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.codec="hvc1.".concat(i.profile_idc,".").concat(i.profile_compatibility_flags.toString(16))+".L".concat(i.level_idc).concat(i.tier_flag?"H":"L")+".".concat(i.constraint_indicator_flags.map(function(s){return s.toString(16)}).join(".").toUpperCase()),this.mp4track.hvcC={profile_space:i.profile_space,tier_flag:i.tier_flag,profile_idc:i.profile_idc,profile_compatibility_flags:i.profile_compatibility_flags,constraint_indicator_flags:i.constraint_indicator_flags,level_idc:i.level_idc,chroma_format_idc:i.chroma_format_idc}}},{key:"parsePPS",value:function(n){this.mp4track.pps=[n]}},{key:"parseVPS",value:function(n){this.mp4track.vps=[n]}},{key:"parseNAL",value:function(n){if(!n)return!1;if(n.isVCL)return!0;var i=!1;switch(n.type()){case L.VPS:this.mp4track.vps||this.parseVPS(n.getPayload()),i=!0;break;case L.SPS:this.mp4track.sps||this.parseSPS(n.getPayload()),i=!0;break;case L.PPS:this.mp4track.pps||this.parsePPS(n.getPayload()),i=!0;break;case L.AUD:b("AUD - ignoing");break;case L.SEI:case L.SEI2:b("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.vps&&this.mp4track.sps&&this.mp4track.pps&&(this.readyToDecode=!0),i}}]),e})(g),De=(function(r){V(e,r);var a=A(e);function e(t,n,i,s){var o;return w(this,e),o=a.call(this,"remuxer"),o.videoCodec=i,o.frameDuration=s,o.initialized=!1,o.tracks={},o.seq=1,o.env=t,o.timescale=1e3,o.mediaDuration=n?4294967295:0,o}return T(e,[{key:"addTrack",value:function(n){var i=this;if((n==="video"||n==="both")&&(this.videoCodec=="H265"?this.tracks.video=new Ce(this.timescale,this.mediaDuration,this.frameDuration):this.tracks.video=new N(this.timescale,this.mediaDuration,this.frameDuration),this.tracks.video.on("outOfData",function(){i.dispatch("missingVideoFrames")}),this.tracks.video.on("keyframePosition",function(o){i.dispatch("keyframePosition",o)})),n==="audio"||n==="both"){var s=new J(this.timescale,this.mediaDuration,this.frameDuration);this.tracks.audio=s,this.tracks.video.on("outOfData",function(){i.dispatch("missingAudioFrames")})}}},{key:"reset",value:function(){for(var n in this.tracks)this.tracks[n].resetTrack();this.initialized=!1}},{key:"destroy",value:function(){this.tracks={},this.offAll()}},{key:"flush",value:function(){if(!this.initialized){if(!this.isReady())return;this.dispatch("ready"),this.initSegment(),this.initialized=!0}for(var n in this.tracks){var i=this.tracks[n],s=i.getPayload();if(s&&s.byteLength){var o=fe.moof(this.seq,i.dts,i.mp4track),c=fe.mdat(s),u=he(o,c),d={type:n,payload:u,dts:i.dts};n==="video"&&(d.fps=i.mp4track.fps),this.dispatch("buffer",d);var f=xe(i.dts/this.timescale);b("put segment (".concat(n,"): dts: ").concat(i.dts," frames: ").concat(i.mp4track.samples.length," second: ").concat(f)),i.flush(),this.seq++}}}},{key:"initSegment",value:function(){var n=[];for(var i in this.tracks){var s=this.tracks[i];if(this.env=="browser"){var o={type:i,payload:fe.initSegment([s.mp4track],this.mediaDuration,this.timescale)};this.dispatch("buffer",o)}else n.push(s.mp4track)}if(this.env=="node"){var c={type:"all",payload:fe.initSegment(n,this.mediaDuration,this.timescale)};this.dispatch("buffer",c)}b("Initial segment generated.")}},{key:"isReady",value:function(){for(var n in this.tracks)if(!this.tracks[n].readyToDecode||!this.tracks[n].samples.length)return!1;return!0}},{key:"feed",value:function(n){var i=!1;if(n.video&&this.tracks.video&&(i|=this.tracks.video.feed(n.video,n.duration,n.compositionTimeOffset)),n.audio&&this.tracks.audio&&(i|=this.tracks.audio.feed(n.audio,n.duration)),!i){K("Input object must have video and/or audio property. Make sure it is a valid typed array");return}this.flush()}}]),e})(le),je=(function(r){V(e,r);var a=A(e);function e(t,n){var i;return w(this,e),i=a.call(this,"buffer"),i.type=n,i.queue=new Uint8Array,i.cleaning=!1,i.pendingCleaning=0,i.cleanOffset=30,i.cleanRanges=[],i.sourceBuffer=t,i.sourceBuffer.addEventListener("updateend",function(){if(i.pendingCleaning>0&&(i.initCleanup(i.pendingCleaning),i.pendingCleaning=0),i.cleaning=!1,i.cleanRanges.length){i.doCleanup();return}}),i.sourceBuffer.addEventListener("error",function(){i.dispatch("error",{type:i.type,name:"buffer",error:"buffer error"})}),i}return T(e,[{key:"destroy",value:function(){this.queue=null,this.sourceBuffer=null,this.offAll()}},{key:"doCleanup",value:function(){if(!this.cleanRanges.length){this.cleaning=!1;return}var n=this.cleanRanges.shift();b("".concat(this.type," remove range [").concat(n[0]," - ").concat(n[1],")")),this.cleaning=!0,this.sourceBuffer.remove(n[0],n[1])}},{key:"initCleanup",value:function(n){try{if(this.sourceBuffer.updating){this.pendingCleaning=n;return}if(this.sourceBuffer.buffered&&this.sourceBuffer.buffered.length&&!this.cleaning){for(var i=0;i<this.sourceBuffer.buffered.length;++i){var s=this.sourceBuffer.buffered.start(i),o=this.sourceBuffer.buffered.end(i);n-s>this.cleanOffset&&(o=n-this.cleanOffset,s<o&&this.cleanRanges.push([s,o]))}this.doCleanup()}}catch(c){K("Error occured while cleaning ".concat(this.type," buffer - ").concat(c.name,": ").concat(c.message))}}},{key:"doAppend",value:function(){if(this.queue.length&&!(!this.sourceBuffer||this.sourceBuffer.updating))try{this.sourceBuffer.appendBuffer(this.queue),this.queue=new Uint8Array}catch(i){var n="unexpectedError";i.name==="QuotaExceededError"?(b("".concat(this.type," buffer quota full")),n="QuotaExceeded"):(K("Error occured while appending ".concat(this.type," buffer - ").concat(i.name,": ").concat(i.message)),n="InvalidStateError"),this.dispatch("error",{type:this.type,name:n,error:"buffer error"})}}},{key:"feed",value:function(n){this.queue=he(this.queue,n)}}]),e})(le),v=(function(r){V(e,r);var a=A(e);function e(t){var n;w(this,e),n=a.call(this,"jmuxer"),n.isReset=!1;var i={node:"",mode:"both",videoCodec:"H264",flushingTime:500,maxDelay:500,clearBuffer:!0,fps:30,readFpsFromTrack:!1,debug:!1,onReady:function(){},onData:function(){},onError:function(){},onUnsupportedCodec:function(){},onMissingVideoFrames:function(){},onMissingAudioFrames:function(){},onKeyframePosition:function(){},onLoggerLog:console.log,onLoggerErr:console.error};return n.options=Object.assign({},i,t),n.env=(typeof process>"u"?"undefined":ne(process))==="object"&&typeof window>"u"?"node":"browser",n.options.debug&&q(n.options.onLoggerLog,n.options.onLoggerErr),n.options.fps||(n.options.fps=30),n.frameDuration=1e3/n.options.fps|0,n.remuxController=new De(n.env,t.live,n.options.videoCodec,n.frameDuration),n.remuxController.addTrack(n.options.mode),n.initData(),n.remuxController.on("buffer",n.onBuffer.bind($(n))),n.env=="browser"&&(n.remuxController.on("ready",n.createBuffer.bind($(n))),n.initBrowser()),n.remuxController.on("missingVideoFrames",function(){typeof n.options.onMissingVideoFrames=="function"&&n.options.onMissingVideoFrames.call(null)}),n.remuxController.on("missingAudioFrames",function(){typeof n.options.onMissingAudioFrames=="function"&&n.options.onMissingAudioFrames.call(null)}),n.clearBuffer&&n.remuxController.on("keyframePosition",function(s){n.kfPosition.push(s)}),typeof n.options.onKeyframePosition=="function"&&n.remuxController.on("keyframePosition",function(s){n.options.onKeyframePosition.call(null,s)}),n}return T(e,[{key:"initData",value:function(){this.lastCleaningTime=Date.now(),this.kfPosition=[],this.pendingUnits={},this.remainingData=new Uint8Array,this.startInterval()}},{key:"initBrowser",value:function(){typeof this.options.node=="string"&&this.options.node==""&&K("no video element were found to render, provide a valid video element"),this.node=typeof this.options.node=="string"?document.getElementById(this.options.node):this.options.node,this.mseReady=!1,this.setupMSE()}},{key:"createStream",value:function(){var n=this.feed.bind(this),i=this.destroy.bind(this);return this.stream=new U.Duplex({writableObjectMode:!0,read:function(o){},write:function(o,c,u){n(o),u()},final:function(o){i(),o()}}),this.stream}},{key:"setupMSE",value:function(){if(window.MediaSource=window.MediaSource||window.WebKitMediaSource||window.ManagedMediaSource,!window.MediaSource)throw"Oops! Browser does not support Media Source Extension or Managed Media Source (IOS 17+).";if(this.isMSESupported=!!window.MediaSource,this.mediaSource=new window.MediaSource,this.url=URL.createObjectURL(this.mediaSource),window.MediaSource===window.ManagedMediaSource)try{this.node.removeAttribute("src"),this.node.disableRemotePlayback=!0;var n=document.createElement("source");n.type="video/mp4",n.src=this.url,this.node.appendChild(n),this.node.load()}catch{this.node.src=this.url}else this.node.src=this.url;this.mseEnded=!1,this.mediaSource.addEventListener("sourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("sourceclose",this.onMSEClose.bind(this)),this.mediaSource.addEventListener("webkitsourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("webkitsourceclose",this.onMSEClose.bind(this))}},{key:"endMSE",value:function(){if(!this.mseEnded)try{this.mseEnded=!0,this.mediaSource.endOfStream()}catch{K("mediasource is not available to end")}}},{key:"feed",value:function(n){!n||!this.remuxController||(n.duration=n.duration?parseInt(n.duration):0,this.remuxController.feed(n))}},{key:"destroy",value:function(){if(this.stopInterval(),this.stream&&(this.remuxController.flush(),this.stream.push(null),this.stream=null),this.remuxController&&(this.remuxController.destroy(),this.remuxController=null),this.bufferControllers){for(var n in this.bufferControllers)this.bufferControllers[n].destroy();this.bufferControllers=null,this.endMSE()}this.node=!1,this.mseReady=!1,this.videoStarted=!1,this.mediaSource=null}},{key:"reset",value:function(){if(this.stopInterval(),this.isReset=!0,this.node.pause(),this.remuxController&&this.remuxController.reset(),this.bufferControllers){for(var n in this.bufferControllers)this.bufferControllers[n].destroy();this.bufferControllers=null,this.endMSE()}this.initData(),this.env=="browser"&&this.initBrowser(),b("JMuxer was reset")}},{key:"createBuffer",value:function(){if(!(!this.mseReady||!this.remuxController||!this.remuxController.isReady()||this.bufferControllers)){this.bufferControllers={};for(var n in this.remuxController.tracks){var i=this.remuxController.tracks[n];if(!e.isSupported("".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"')))return K("Browser does not support codec: ".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"')),typeof this.options.onUnsupportedCodec=="function"&&this.options.onUnsupportedCodec.call(null,i.mp4track.codec),!1;var s=this.mediaSource.addSourceBuffer("".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"'));this.bufferControllers[n]=new je(s,n),this.bufferControllers[n].on("error",this.onBufferError.bind(this))}}}},{key:"startInterval",value:function(){var n=this;this.interval=setInterval(function(){n.options.flushingTime?n.applyAndClearBuffer():n.bufferControllers&&n.cancelDelay()},this.options.flushingTime||1e3)}},{key:"stopInterval",value:function(){this.interval&&clearInterval(this.interval)}},{key:"cancelDelay",value:function(){if(this.node.buffered&&this.node.buffered.length>0&&!this.node.seeking){var n=this.node.buffered.end(0);n-this.node.currentTime>this.options.maxDelay/1e3&&(b("delay"),this.node.paused&&this.node.play().catch(K),this.node.currentTime=n-.001)}}},{key:"releaseBuffer",value:function(){for(var n in this.bufferControllers)this.bufferControllers[n].doAppend()}},{key:"applyAndClearBuffer",value:function(){this.bufferControllers&&(this.releaseBuffer(),this.clearBuffer())}},{key:"getSafeClearOffsetOfBuffer",value:function(n){for(var i=this.options.mode==="audio"&&n||0,s,o=0;o<this.kfPosition.length&&!(this.kfPosition[o]>=n);o++)s=this.kfPosition[o];return s&&(this.kfPosition=this.kfPosition.filter(function(c){return c<s&&(i=c),c>=s})),i}},{key:"clearBuffer",value:function(){if(this.options.clearBuffer&&Date.now()-this.lastCleaningTime>1e4){for(var n in this.bufferControllers){var i=this.getSafeClearOffsetOfBuffer(this.node.currentTime);this.bufferControllers[n].initCleanup(i)}this.lastCleaningTime=Date.now()}}},{key:"onBuffer",value:function(n){this.options.readFpsFromTrack&&typeof n.fps<"u"&&this.options.fps!=n.fps&&(this.options.fps=n.fps,this.frameDuration=Math.ceil(1e3/n.fps),b("JMuxer changed FPS to ".concat(n.fps," from track data"))),this.env=="browser"?this.bufferControllers&&this.bufferControllers[n.type]&&this.bufferControllers[n.type].feed(n.payload):this.stream&&this.stream.push(n.payload),this.options.onData&&this.options.onData(n.payload),this.options.flushingTime===0&&this.applyAndClearBuffer()}},{key:"onMSEOpen",value:function(){this.mseReady=!0,URL.revokeObjectURL(this.url),typeof this.options.onReady=="function"&&this.options.onReady.call(null,this.isReset)}},{key:"onMSEClose",value:function(){this.mseReady=!1,this.videoStarted=!1}},{key:"onBufferError",value:function(n){if(n.name=="QuotaExceeded"){b("JMuxer cleaning ".concat(n.type," buffer due to QuotaExceeded error")),this.bufferControllers[n.type].initCleanup(this.node.currentTime);return}else n.name=="InvalidStateError"?(b("JMuxer is reseting due to InvalidStateError"),this.reset()):this.endMSE();typeof this.options.onError=="function"&&this.options.onError.call(null,n)}}],[{key:"isSupported",value:function(n){return window.MediaSource&&window.MediaSource.isTypeSupported(n)}}]),e})(le);return v}))})(Fe)),Fe.exports}var rt=tt();const nt=Oe(rt),it=400,Ee=50;function st({deviceId:m,className:ce,onFallback:U,fallbackTimeout:R=5e3,enableControl:k=!1,onTapSuccess:O,onTapError:$,onSwipeSuccess:w,onSwipeError:C,onStreamReady:T}){const p=x.useRef(null),A=x.useRef(null),D=x.useRef(null),E=x.useRef(m),[V,te]=x.useState("connecting"),[ve,re]=x.useState(null),ae=x.useRef(null),H=x.useRef(!1),[ge,de]=x.useState([]),z=x.useRef(!1),j=x.useRef(null),[Q,X]=x.useState(null),ne=x.useRef(null),Y=x.useRef(null),ie=x.useRef(0),ee=x.useRef(null),q=x.useRef(null),[b,K]=x.useState(null),le=x.useRef(0),fe=x.useRef(0),ke=x.useRef(0),be=x.useRef(0),g=x.useRef(0),J=x.useRef(0),W=3,se=1e3,G=x.useRef(U),he=x.useRef(R),xe=x.useRef(T),N=(v,r,a)=>{const e=a.getBoundingClientRect(),t=e.width,n=e.height,i=a.videoWidth,s=a.videoHeight;if(i===0||s===0)return console.warn("[ScrcpyPlayer] Video dimensions not available yet"),null;const o=i/s,c=t/n;let u,d,f,h;c>o?(d=n,u=o*n,f=(t-u)/2,h=0):(u=t,d=t/o,f=0,h=(n-d)/2);const y=v-f,S=r-h;if(y<0||y>u||S<0||S>d)return console.warn("[ScrcpyPlayer] Click outside video area (in letterbox)"),null;const B=Math.round(y/u*i),M=Math.round(S/d*s);return console.log(`[ScrcpyPlayer] Coordinate transform:
5
+ Click: (${v}, ${r})
6
+ Display: ${t}x${n}
7
+ Video: ${i}x${s}
8
+ Rendered: ${u}x${d} at offset (${f}, ${h})
9
+ Device: (${B}, ${M})`),{x:B,y:M}},oe=async v=>{if(!k||!p.current||V!=="connected")return;z.current=!0,j.current={x:v.clientX,y:v.clientY,time:Date.now()};const r=p.current.getBoundingClientRect(),a=v.clientX-r.left,e=v.clientY-r.top,t=N(a,e,p.current);if(!t||!b)return;const n=p.current.videoWidth,i=p.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o);try{await He(c,u,m),console.log(`[Touch] DOWN: (${c}, ${u}) for device ${m}`)}catch(d){console.error("[Touch] DOWN failed:",d)}},L=v=>{if(!z.current||!j.current)return;X({id:Date.now(),startX:j.current.x,startY:j.current.y,endX:v.clientX,endY:v.clientY});const r=p.current?.getBoundingClientRect();if(!r||!p.current||!b)return;const a=v.clientX-r.left,e=v.clientY-r.top,t=N(a,e,p.current);if(!t)return;const n=p.current.videoWidth,i=p.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o),d=Date.now();d-ie.current>=Ee?(ie.current=d,Te(c,u,m).catch(f=>{console.error("[Touch] MOVE failed:",f)})):(ee.current={x:c,y:u},q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{if(ee.current){const{x:f,y:h}=ee.current;ie.current=Date.now(),Te(f,h,m).catch(y=>{console.error("[Touch] MOVE (throttled) failed:",y)}),ee.current=null}},Ee-(d-ie.current)))},Ce=async v=>{if(!z.current||!j.current)return;const r=v.clientX-j.current.x,a=v.clientY-j.current.y,e=Date.now()-j.current.time;if(X(null),z.current=!1,q.current&&(clearTimeout(q.current),q.current=null),ee.current=null,Math.sqrt(r*r+a*a)<10&&e<200){je(v),j.current=null;return}const n=p.current?.getBoundingClientRect();if(!n||!p.current||!b){j.current=null;return}const i=v.clientX-n.left,s=v.clientY-n.top,o=N(i,s,p.current);if(!o){j.current=null;return}const c=p.current.videoWidth,u=p.current.videoHeight,d=b.width/c,f=b.height/u,h=Math.round(o.x*d),y=Math.round(o.y*f);try{await Ue(h,y,m),console.log(`[Touch] UP: (${h}, ${y}) for device ${m}`),O?.()}catch(S){console.error("[Touch] UP failed:",S),$?.(String(S))}j.current=null},De=async v=>{if(!k||!p.current||V!=="connected")return;const r=Date.now(),a=v.deltaY;Y.current||(Y.current={deltaY:0,lastTime:r,mouseX:v.clientX,mouseY:v.clientY}),Y.current.deltaY+=a,Y.current.lastTime=r;const e=.3;Y.current.mouseX=Math.round(Y.current.mouseX*(1-e)+v.clientX*e),Y.current.mouseY=Math.round(Y.current.mouseY*(1-e)+v.clientY*e),ne.current&&clearTimeout(ne.current),ne.current=setTimeout(async()=>{if(!Y.current||!p.current)return;const t=Y.current;if(Y.current=null,t.mouseX===void 0||t.mouseY===void 0)return;const n=p.current.getBoundingClientRect(),i=t.mouseX,s=t.mouseY,o=Math.abs(t.deltaY),c=Math.min(Math.max(300,o),800),u=N(i-n.left,s-n.top,p.current);if(!u||!b){console.warn("[ScrcpyPlayer] Cannot execute scroll: coordinate transformation failed");return}const d=p.current.videoWidth,f=p.current.videoHeight,h=b.width/d,y=b.height/f,S=Math.round(u.x*h),B=Math.round(u.y*y);let M,_;t.deltaY>0?(M=B,_=B-o):(M=B,_=B+o);const I=Math.abs(_-M),P=Math.max(I/b.height*n.height,20),pe=Math.min(Math.max(c*.8,200),800),Z=document.createElement("div");Z.style.cssText=`
10
+ position: fixed;
11
+ left: ${i}px;
12
+ top: ${s}px;
13
+ width: 20px;
14
+ height: 20px;
15
+ pointer-events: none;
16
+ z-index: 50;
17
+ transform: translateX(-50%) translateY(-50%);
18
+ background: radial-gradient(circle,
19
+ rgba(59, 130, 246, 0.8) 0%,
20
+ rgba(59, 130, 246, 0.4) 30%,
21
+ rgba(59, 130, 246, 0.2) 60%,
22
+ rgba(59, 130, 246, 0) 100%);
23
+ border-radius: 50%;
24
+ box-shadow: 0 0 10px rgba(59, 130, 246, 0.6);
25
+ `;const ye=Date.now(),ue=setInterval(()=>{const F=Date.now()-ye,me=Math.min(F/pe,1),we=t.deltaY>0?s-P*me:s+P*me;Z.style.top=we+"px",me>=1&&clearInterval(ue)},16);document.body.appendChild(Z),setTimeout(()=>{Z.parentNode&&Z.parentNode.removeChild(Z),clearInterval(ue)},pe);try{const F=await $e(S,M,S,_,c,m);F.success?w?.():C?.(F.error||"Scroll failed")}catch(F){C?.(String(F))}},it)},je=async v=>{if(!k||!p.current||V!=="connected"||p.current.videoWidth===0||p.current.videoHeight===0||!b)return;const r=p.current.getBoundingClientRect(),a=v.clientX-r.left,e=v.clientY-r.top,t=N(a,e,p.current);if(!t)return;const n=p.current.videoWidth,i=p.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o),d=Date.now();de(f=>[...f,{id:d,x:v.clientX,y:v.clientY}]),setTimeout(()=>{de(f=>f.filter(h=>h.id!==d))},500);try{const f=await ze(c,u,m);f.success?O?.():$?.(f.error||"Unknown error")}catch(f){$?.(String(f))}};return x.useEffect(()=>{G.current=U,he.current=R,xe.current=T},[U,R,T]),x.useEffect(()=>{(async()=>{try{const r=await Ne(m);r.success&&(K({width:r.width,height:r.height}),console.log(`[ScrcpyPlayer] Device actual resolution: ${r.width}x${r.height} for device ${m}`))}catch(r){console.error("[ScrcpyPlayer] Failed to fetch device resolution:",r)}})()},[m]),x.useEffect(()=>{E.current=m;let v=null,r=null;const a=async()=>{if(p.current){if(console.log("[ScrcpyPlayer] connect() called"),be.current=Date.now(),te("connecting"),re(null),D.current){console.log("[ScrcpyPlayer] Closing existing WebSocket");try{D.current.onclose=null,D.current.onerror=null,D.current.onmessage=null,D.current.close()}catch(e){console.error("[ScrcpyPlayer] Error closing old WebSocket:",e)}D.current=null}if(A.current){console.log("[ScrcpyPlayer] Destroying old jMuxer instance");try{A.current.destroy()}catch(e){console.error("[ScrcpyPlayer] Error destroying old jMuxer:",e)}A.current=null}await new Promise(e=>setTimeout(e,300));try{console.log("[ScrcpyPlayer] Creating new jMuxer instance (after cleanup delay)"),A.current=new nt({node:p.current,mode:"video",flushingTime:0,fps:30,debug:!1,clearBuffer:!0,onError:i=>{if(console.error("[jMuxer] Decoder error:",i),i.name==="InvalidStateError"&&i.error==="buffer error"){const s=Date.now(),o=s-J.current;if(o<se){console.warn(`[jMuxer] Reset debounced (${o}ms since last reset)`);return}if(J.current=s,g.current++,console.warn(`[jMuxer] ⚠️ Buffer error detected (attempt ${g.current}/${W})`),g.current<=W&&A.current)try{console.log("[jMuxer] Attempting lightweight reset()..."),A.current.reset(),console.log("[jMuxer] ✓ Reset successful");return}catch(u){console.error("[jMuxer] Reset failed:",u)}console.log("[jMuxer] Reset successful, reconnecting to get fresh initialization data..."),ke.current=s;const c=e;r&&setTimeout(()=>{E.current===c?r&&r():console.log(`[jMuxer] Device changed (${c} -> ${E.current}), skip reconnect`)},100)}},onMissingVideoFrames:i=>{console.warn("[jMuxer] Missing video frames detected:",i)}});const e=E.current,t=`ws://localhost:8000/api/video/stream?device_id=${encodeURIComponent(e)}`,n=new WebSocket(t);D.current=n,n.binaryType="arraybuffer",n.onopen=()=>{console.log(`[ScrcpyPlayer] WebSocket connected for device ${e}`),te("connected"),g.current=0,J.current=0,xe.current&&xe.current({close:()=>{n.close()}}),ae.current=setTimeout(()=>{H.current||(console.log("[ScrcpyPlayer] No data received within timeout, triggering fallback"),te("error"),re("Video stream timeout"),n.close(),G.current&&G.current())},he.current)},n.onmessage=i=>{if(typeof i.data=="string"){try{const s=JSON.parse(i.data);console.error("[ScrcpyPlayer] Server error:",s),re(s.error||"Unknown error"),te("error"),G.current&&!H.current&&G.current()}catch{console.error("[ScrcpyPlayer] Received non-JSON string:",i.data)}return}if(!H.current){const s=new Uint8Array(i.data);console.log(`[ScrcpyPlayer] ✓ Received initialization data (${s.length} bytes)`);let o=0;for(let c=0;c<s.length-3;c++)s[c]===0&&s[c+1]===0&&(s[c+2]===1||s[c+2]===0&&s[c+3]===1)&&o++;console.log(`[ScrcpyPlayer] Initialization data contains ${o} NAL units`)}H.current||(H.current=!0,console.log("[ScrcpyPlayer] First video data received, canceling fallback timer"),ae.current&&(clearTimeout(ae.current),ae.current=null));try{if(A.current&&i.data.byteLength>0){const s=new Uint8Array(i.data);if(s[0]===0&&s[1]===0&&(s[2]===0||s[2]===1)||console.warn(`[ScrcpyPlayer] Invalid NAL unit: missing start code, first bytes = ${Array.from(s.slice(0,8)).map(d=>d.toString(16).padStart(2,"0")).join(" ")}`),H.current){const d=s[2]===1?3:4,f=s[d]&31;(f===5||f===7||f===8)&&console.log(`[ScrcpyPlayer] Received ${{5:"IDR",7:"SPS",8:"PPS"}[f]} NAL unit (${s.length} bytes)`)}A.current.feed({video:s}),le.current++;const c=Date.now(),u=c-fe.current;if(u>5e3){const d=le.current/u*1e3,f=p.current,h=f&&f.buffered.length>0?f.buffered.end(0)-f.currentTime:0;console.log(`[ScrcpyPlayer] Stats: ${d.toFixed(1)} fps, buffer: ${h.toFixed(2)}s`),h>2&&console.warn(`[ScrcpyPlayer] ⚠ High latency detected: ${h.toFixed(2)}s buffer`),le.current=0,fe.current=c}}}catch(s){console.error("[ScrcpyPlayer] Feed error:",s)}},n.onerror=i=>{console.error("[ScrcpyPlayer] WebSocket error:",i),re("Connection error"),te("error")},n.onclose=()=>{console.log("[ScrcpyPlayer] WebSocket closed"),te("disconnected"),xe.current&&xe.current(null);const i=e;v=setTimeout(()=>{E.current===i?(console.log("[ScrcpyPlayer] Attempting to reconnect..."),a()):console.log(`[ScrcpyPlayer] Device changed (${i} -> ${E.current}), skip reconnect`)},3e3)}}catch(e){console.error("[ScrcpyPlayer] Initialization error:",e),re("Initialization failed"),te("error")}}};return r=a,a(),()=>{if(v&&clearTimeout(v),ae.current&&(clearTimeout(ae.current),ae.current=null),D.current&&(D.current.close(),D.current=null),q.current&&(clearTimeout(q.current),q.current=null),A.current){try{A.current.destroy()}catch(e){console.error("[ScrcpyPlayer] Cleanup error:",e)}A.current=null}}},[m]),l.jsxs("div",{className:`relative w-full h-full flex items-center justify-center ${ce||""}`,children:[l.jsx("video",{ref:p,autoPlay:!0,muted:!0,playsInline:!0,onError:v=>{const a=v.currentTarget.error;a&&console.error("[Video Element] Error occurred:",{code:a.code,message:a.message,MEDIA_ERR_ABORTED:a.code===1,MEDIA_ERR_NETWORK:a.code===2,MEDIA_ERR_DECODE:a.code===3,MEDIA_ERR_SRC_NOT_SUPPORTED:a.code===4})},onMouseDown:oe,onMouseMove:L,onMouseUp:Ce,onMouseLeave:async()=>{if(z.current&&p.current&&b){if(j.current){const v=p.current.getBoundingClientRect(),r=N(j.current.x-v.left,j.current.y-v.top,p.current);if(r){const a=b.width/p.current.videoWidth,e=b.height/p.current.videoHeight,t=Math.round(r.x*a),n=Math.round(r.y*e);try{await Ue(t,n,m),console.log(`[Touch] UP (mouse leave) for device ${m}`)}catch(i){console.error("[Touch] UP (mouse leave) failed:",i)}}}z.current=!1,X(null),j.current=null}},onWheel:De,className:`max-w-full max-h-full object-contain ${k?"cursor-pointer":""}`,style:{backgroundColor:"#000"}}),k&&Q&&l.jsxs("svg",{className:"fixed inset-0 pointer-events-none z-40",children:[l.jsx("line",{x1:Q.startX,y1:Q.startY,x2:Q.endX,y2:Q.endY,stroke:"rgba(59, 130, 246, 0.8)",strokeWidth:"3",strokeLinecap:"round"}),l.jsx("circle",{cx:Q.startX,cy:Q.startY,r:"6",fill:"rgba(59, 130, 246, 0.8)"}),l.jsx("circle",{cx:Q.endX,cy:Q.endY,r:"6",fill:"rgba(239, 68, 68, 0.8)"})]}),k&&ge.map(v=>l.jsx("div",{className:"fixed pointer-events-none z-50",style:{left:v.x,top:v.y},children:l.jsx("div",{className:"ripple-circle"})},v.id)),V!=="connected"&&l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm",children:l.jsxs("div",{className:"text-center text-white",children:[V==="connecting"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-white border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"正在连接..."})]}),V==="disconnected"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-yellow-500 border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"连接断开,正在重连..."})]}),V==="error"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"text-red-500 text-xl mb-2",children:"✗"}),l.jsx("p",{className:"text-red-400",children:"连接失败"}),ve&&l.jsx("p",{className:"text-sm text-gray-400 mt-1",children:ve})]})]})})]})}function at({deviceId:m,deviceName:ce,config:U}){const[R,k]=x.useState([]),[O,$]=x.useState(""),[w,C]=x.useState(!1),[T,p]=x.useState(null),[A,D]=x.useState(!1),[E,V]=x.useState(null),[te,ve]=x.useState(!0),[re,ae]=x.useState(!1),[H,ge]=x.useState("auto"),[de,z]=x.useState(null),[j,Q]=x.useState(()=>{try{const g=localStorage.getItem("display-tabs-visible");return g!==null?JSON.parse(g):!0}catch(g){return console.warn("Failed to load tabs visibility state:",g),!0}});x.useEffect(()=>{localStorage.setItem("display-tabs-visible",JSON.stringify(j))},[j]);const X=x.useRef(null),ne=x.useRef(null),Y=x.useRef(null),ie=x.useRef(!1),ee=x.useCallback(async()=>{if(!U){console.warn("[DevicePanel] config is required for handleInit");return}try{await Ye({model_config:{base_url:U.baseUrl||void 0,api_key:U.apiKey||void 0,model_name:U.modelName||void 0},agent_config:{device_id:m}}),D(!0),p(null)}catch(g){const J=g instanceof Error?g.message:"初始化失败,请检查配置";p(J)}},[m,U]),q=x.useCallback(async()=>{const g=O.trim();if(!g||w)return;A||await ee();const J={id:Date.now().toString(),role:"user",content:g,timestamp:new Date};k(N=>[...N,J]),$(""),C(!0),p(null);const W=[],se=[],G=(Date.now()+1).toString(),he={id:G,role:"agent",content:"",timestamp:new Date,thinking:[],actions:[],isStreaming:!0};k(N=>[...N,he]);const xe=Ve(J.content,m,N=>{W.push(N.thinking),se.push(N.action),k(oe=>oe.map(L=>L.id===G?{...L,thinking:[...W],actions:[...se],steps:N.step}:L))},N=>{k(oe=>oe.map(L=>L.id===G?{...L,content:N.message,success:N.success,isStreaming:!1}:L)),C(!1),X.current=null},N=>{k(oe=>oe.map(L=>L.id===G?{...L,content:`错误: ${N.message}`,success:!1,isStreaming:!1}:L)),C(!1),p(N.message),X.current=null});X.current=xe},[O,w,A,m,ee]),b=x.useCallback(async()=>{X.current&&X.current.close(),k([]),C(!1),p(null),X.current=null,await We(m)},[m]),K=()=>{Y.current?.scrollIntoView({behavior:"smooth"})};x.useEffect(()=>{K()},[R]),x.useEffect(()=>()=>{console.log(`[DevicePanel] 设备 ${m} 卸载,清理资源`),X.current&&(X.current.close(),X.current=null),ne.current&&(ne.current.close(),ne.current=null)},[m]),x.useEffect(()=>{if(!m||!(H==="screenshot"||H==="auto"&&re))return;const J=async()=>{if(!ie.current){ie.current=!0;try{const se=await Ne(m);se.success&&V(se)}catch(se){console.error("Failed to fetch screenshot:",se)}finally{ie.current=!1}}};J();const W=setInterval(J,500);return()=>clearInterval(W)},[m,re,H]);const le=g=>{g.key==="Enter"&&(g.metaKey||g.ctrlKey)&&(g.preventDefault(),q())},fe=x.useCallback(g=>{ne.current=g},[]),ke=x.useCallback(()=>{ae(!0),ve(!1)},[]),be=()=>{Q(!j)};return l.jsxs("div",{className:"flex-1 flex gap-4 p-4 items-stretch justify-center min-h-0",children:[l.jsxs("div",{className:"flex flex-col w-full max-w-2xl min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-white dark:bg-gray-800",children:[l.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 rounded-t-2xl",children:[l.jsxs("div",{children:[l.jsx("h2",{className:"text-lg font-semibold",children:ce}),l.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:m})]}),l.jsxs("div",{className:"flex gap-2",children:[A?l.jsx("span",{className:"px-3 py-1 bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full text-sm",children:"已初始化"}):l.jsx("button",{onClick:ee,className:"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm",children:"初始化设备"}),l.jsx("button",{onClick:b,className:"px-4 py-2 bg-gray-200 dark:bg-gray-700 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors text-sm",children:"重置"})]})]}),T&&l.jsx("div",{className:"mx-4 mt-4 p-3 bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-200 rounded-lg text-sm",children:T}),l.jsxs("div",{className:"flex-1 overflow-y-auto p-4 space-y-4 min-h-0",children:[R.length===0?l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400 mt-8",children:[l.jsx("p",{className:"text-lg",children:"设备已选择"}),l.jsx("p",{className:"text-sm mt-2",children:"输入任务描述,让 AI 帮你操作手机"})]}):null,R.map(g=>l.jsx("div",{className:`flex ${g.role==="user"?"justify-end":"justify-start"}`,children:g.role==="agent"?l.jsxs("div",{className:"max-w-[80%] space-y-2",children:[g.thinking?.map((J,W)=>l.jsxs("div",{className:"bg-gray-100 dark:bg-gray-700 rounded-2xl px-4 py-3 border-l-4 border-blue-500",children:[l.jsxs("div",{className:"text-xs text-gray-500 dark:text-gray-400 mb-1",children:["💭 步骤 ",W+1," - 思考过程"]}),l.jsx("p",{className:"text-sm whitespace-pre-wrap",children:J}),g.actions?.[W]&&l.jsxs("details",{className:"mt-2 text-xs",children:[l.jsx("summary",{className:"cursor-pointer text-blue-500 hover:text-blue-600",children:"查看动作"}),l.jsx("pre",{className:"mt-1 p-2 bg-gray-800 text-gray-200 rounded overflow-x-auto text-xs",children:JSON.stringify(g.actions[W],null,2)})]})]},W)),g.content&&l.jsxs("div",{className:`rounded-2xl px-4 py-3 ${g.success===!1?"bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200":"bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200"}`,children:[l.jsx("p",{className:"whitespace-pre-wrap",children:g.content}),g.steps!==void 0&&l.jsxs("p",{className:"text-xs mt-2 opacity-70",children:["总步数: ",g.steps]})]}),g.isStreaming&&l.jsx("div",{className:"text-sm text-gray-500 dark:text-gray-400 animate-pulse",children:"正在执行..."})]}):l.jsx("div",{className:"max-w-[70%] rounded-2xl px-4 py-3 bg-blue-500 text-white",children:l.jsx("p",{className:"whitespace-pre-wrap",children:g.content})})},g.id)),l.jsx("div",{ref:Y})]}),l.jsx("div",{className:"p-4 border-t border-gray-200 dark:border-gray-700 rounded-b-2xl",children:l.jsxs("div",{className:"flex gap-2",children:[l.jsx("input",{type:"text",value:O,onChange:g=>$(g.target.value),onKeyDown:le,placeholder:A?"输入任务描述...":"请先初始化设备",disabled:w,className:"flex-1 px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"}),l.jsx("button",{onClick:q,disabled:w||!O.trim(),className:"px-6 py-3 bg-blue-500 text-white rounded-xl hover:bg-blue-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:"发送"})]})})]}),l.jsxs("div",{className:"w-full max-w-xs min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-gray-900 overflow-hidden relative",children:[!j&&l.jsx("button",{onClick:be,className:"absolute top-2 right-2 z-10 w-8 h-8 bg-gray-500 hover:bg-blue-600 text-white rounded-full shadow-lg transition-all duration-300 flex items-center justify-center opacity-20 hover:opacity-100 cursor-pointer",title:"显示选项卡",children:l.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"})})}),l.jsxs("div",{className:`${j?"absolute top-2 right-2":"hidden"} z-10 flex gap-1 bg-black/70 rounded-lg p-1`,children:[l.jsx("button",{onClick:()=>ge("auto"),className:`px-3 py-1 text-xs rounded transition-colors ${H==="auto"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"自动"}),l.jsx("button",{onClick:()=>ge("video"),className:`px-3 py-1 text-xs rounded transition-colors ${H==="video"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"视频流"}),l.jsx("button",{onClick:()=>ge("screenshot"),className:`px-3 py-1 text-xs rounded transition-colors ${H==="screenshot"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"截图"}),l.jsx("button",{onClick:be,className:"ml-1 px-2 py-1 text-xs rounded transition-colors bg-gray-600 text-gray-300 hover:bg-gray-500",title:"隐藏选项卡",children:l.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),H==="video"||H==="auto"&&te&&!re?l.jsxs(l.Fragment,{children:[de&&l.jsx("div",{className:"absolute top-14 right-2 z-20 px-3 py-2 bg-blue-500 text-white text-sm rounded-lg shadow-lg",children:de}),l.jsx(st,{deviceId:m,className:"w-full h-full",enableControl:!0,onFallback:ke,onTapSuccess:()=>{z("Tap executed"),setTimeout(()=>z(null),2e3)},onTapError:g=>{z(`Tap failed: ${g}`),setTimeout(()=>z(null),3e3)},onSwipeSuccess:()=>{z("Swipe executed"),setTimeout(()=>z(null),2e3)},onSwipeError:g=>{z(`Swipe failed: ${g}`),setTimeout(()=>z(null),3e3)},onStreamReady:fe,fallbackTimeout:1e5})]}):l.jsx("div",{className:"w-full h-full flex items-center justify-center bg-gray-900 min-h-0",children:E&&E.success?l.jsxs("div",{className:"relative w-full h-full flex items-center justify-center min-h-0",children:[l.jsx("img",{src:`data:image/png;base64,${E.image}`,alt:"Device Screenshot",className:"max-w-full max-h-full object-contain",style:{width:E.width>E.height?"100%":"auto",height:E.width>E.height?"auto":"100%"}}),E.is_sensitive&&l.jsx("div",{className:"absolute top-12 right-2 px-2 py-1 bg-yellow-500 text-white text-xs rounded",children:"敏感内容"}),l.jsxs("div",{className:"absolute bottom-2 left-2 px-2 py-1 bg-blue-500 text-white text-xs rounded",children:["截图模式 (0.5s 刷新)",H==="auto"&&re&&" - 视频流不可用"]})]}):E?.error?l.jsxs("div",{className:"text-center text-red-500 dark:text-red-400",children:[l.jsx("p",{className:"mb-2",children:"截图失败"}),l.jsx("p",{className:"text-xs",children:E.error})]}):l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("div",{className:"w-8 h-8 border-4 border-gray-300 border-t-blue-500 rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"加载中..."})]})})]})]})}function ct(){const[m,ce]=x.useState([]),[U,R]=x.useState(""),[k,O]=x.useState({baseUrl:"",apiKey:"",modelName:""}),[$,w]=x.useState(!1);return x.useEffect(()=>{const C=async()=>{try{const p=await Xe();ce(p.devices),p.devices.length>0&&!U&&R(p.devices[0].id),U&&!p.devices.find(A=>A.id===U)&&R(p.devices[0]?.id||"")}catch(p){console.error("Failed to load devices:",p)}};C();const T=setInterval(C,3e3);return()=>clearInterval(T)},[U]),l.jsxs("div",{className:"h-full flex relative min-h-0",children:[$&&l.jsx("div",{className:"absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50",children:l.jsxs("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-2xl w-96 shadow-xl border border-gray-200 dark:border-gray-700",children:[l.jsx("h2",{className:"text-xl font-bold mb-4 text-gray-900 dark:text-gray-100",children:"Agent 配置"}),l.jsxs("div",{className:"space-y-4",children:[l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Base URL"}),l.jsx("input",{type:"text",value:k.baseUrl,onChange:C=>O({...k,baseUrl:C.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"API Key"}),l.jsx("input",{type:"password",value:k.apiKey,onChange:C=>O({...k,apiKey:C.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Model Name"}),l.jsx("input",{type:"text",value:k.modelName,onChange:C=>O({...k,modelName:C.target.value}),placeholder:"留空使用默认值",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[l.jsx("button",{onClick:()=>w(!1),className:"px-4 py-2 text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200",children:"取消"}),l.jsx("button",{onClick:()=>w(!1),className:"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors",children:"确认配置"})]})]})]})}),l.jsx(Je,{devices:m,currentDeviceId:U,onSelectDevice:R,onOpenConfig:()=>w(!0)}),l.jsx("div",{className:"flex-1 relative flex items-stretch justify-center min-h-0",children:m.length===0?l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-50 dark:bg-gray-900",children:l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-16 h-16 mx-auto mb-4 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("h3",{className:"text-lg font-medium mb-2",children:"欢迎使用 AutoGLM Chat"}),l.jsx("p",{className:"text-sm",children:"未检测到设备,请连接 ADB 设备"})]})}):m.map(C=>l.jsx("div",{className:`w-full h-full flex items-stretch justify-center min-h-0 ${C.id===U?"":"hidden"}`,children:l.jsx(at,{deviceId:C.id,deviceName:C.model,config:k,isVisible:C.id===U})},C.id))})]})}export{ct as component};