@camera.ui/server 2.2.5-beta.2 → 2.2.5-beta.3

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 (420) hide show
  1. package/dist/interface/assets/{404-BDvtK1qR.js → 404-YZOLos9r.js} +1 -1
  2. package/dist/interface/assets/{About-B4A35rRx.js → About-HtxMc8JZ.js} +1 -1
  3. package/dist/interface/assets/Assistant-bB8RBo-m.js +1 -0
  4. package/dist/interface/assets/Automation-D3DcUyui.js +3 -0
  5. package/dist/interface/assets/{AutomationImport-CEJdhE_d.js → AutomationImport-Dp_hT6hQ.js} +2 -2
  6. package/dist/interface/assets/AutomationStore-BKR7GXMk.js +2 -0
  7. package/dist/interface/assets/{AutomationStoreDetail-BenRMMtV.js → AutomationStoreDetail-B9yh51WQ.js} +2 -2
  8. package/dist/interface/assets/Automations-BdZZW2eN.js +2 -0
  9. package/dist/interface/assets/Camera-Ct7ndOxr.js +2 -0
  10. package/dist/interface/assets/{CameraConsole-D24yXOQn.js → CameraConsole-BI93OaRt.js} +2 -2
  11. package/dist/interface/assets/Cameras-Ctub8sVt.js +651 -0
  12. package/dist/interface/assets/Camview-BjQdTHNh.js +1 -0
  13. package/dist/interface/assets/{CertificateUpload-26LAL4MY.js → CertificateUpload-xW55NA1Q.js} +1 -1
  14. package/dist/interface/assets/Config-CBTbYd5v.js +2 -0
  15. package/dist/interface/assets/{ConfigActionAssistant-Cl_kr3hp.js → ConfigActionAssistant-B488rOp5.js} +1 -1
  16. package/dist/interface/assets/{ConfigActionCameraControl-CL4vXcNe.js → ConfigActionCameraControl-ZMUuBxOs.js} +1 -1
  17. package/dist/interface/assets/{ConfigActionDelay-DtPgmqWh.js → ConfigActionDelay-BJ11xvOW.js} +1 -1
  18. package/dist/interface/assets/{ConfigActionHttp-DnkZTP5l.js → ConfigActionHttp-DOUo69OR.js} +1 -1
  19. package/dist/interface/assets/{ConfigActionImageInput-3svn6YP9.js → ConfigActionImageInput-BMzuVZW9.js} +1 -1
  20. package/dist/interface/assets/{ConfigActionMqtt-BTsFTLgm.js → ConfigActionMqtt-Co_uksca.js} +1 -1
  21. package/dist/interface/assets/{ConfigActionNotification-Cr4xJrZp.js → ConfigActionNotification-CcZkstYx.js} +1 -1
  22. package/dist/interface/assets/{ConfigActionNotificationControl-Cxkb_g8p.js → ConfigActionNotificationControl--VeucoTw.js} +1 -1
  23. package/dist/interface/assets/{ConfigActionOutput-WTr7FGf_.js → ConfigActionOutput-CyDa1LGA.js} +1 -1
  24. package/dist/interface/assets/{ConfigActionPlugin-BpcJepbD.js → ConfigActionPlugin-Kfg3ZEQF.js} +1 -1
  25. package/dist/interface/assets/{ConfigActionSensor-BgD_F-hD.js → ConfigActionSensor-DhAF0HPw.js} +1 -1
  26. package/dist/interface/assets/{ConfigActionSnapshot-DjR-Z08N.js → ConfigActionSnapshot-zMe3SPvW.js} +1 -1
  27. package/dist/interface/assets/{ConfigActionVariable-gPuPbjpm.js → ConfigActionVariable-BE5q3NwY.js} +1 -1
  28. package/dist/interface/assets/{ConfigConditionIfElse-CUHKJmPx.js → ConfigConditionIfElse-BNIRtSVD.js} +1 -1
  29. package/dist/interface/assets/{ConfigConditionSensorState-D-gPRqMu.js → ConfigConditionSensorState-DTNd-SzI.js} +1 -1
  30. package/dist/interface/assets/{ConfigConditionSwitch-BRf1T5tJ.js → ConfigConditionSwitch-BU5wWMU1.js} +1 -1
  31. package/dist/interface/assets/{ConfigConditionTime-BC0n6sWO.js → ConfigConditionTime-KXTCIVIV.js} +1 -1
  32. package/dist/interface/assets/{ConfigSensorValueInput-BUHapx4M.js → ConfigSensorValueInput-BC1FpMm-.js} +1 -1
  33. package/dist/interface/assets/{ConfigTriggerDetection-Byd6SLGg.js → ConfigTriggerDetection-hIN1hi53.js} +1 -1
  34. package/dist/interface/assets/ConfigTriggerGeofence-Bl2ZacbY.js +1 -0
  35. package/dist/interface/assets/{ConfigTriggerManual-B2dWcFrl.js → ConfigTriggerManual-C5vwxS-e.js} +1 -1
  36. package/dist/interface/assets/{ConfigTriggerMqtt-B_aUDBu4.js → ConfigTriggerMqtt-B4PtWC3E.js} +1 -1
  37. package/dist/interface/assets/{ConfigTriggerSchedule-DAZo1PLj.js → ConfigTriggerSchedule-BZzUdGBa.js} +1 -1
  38. package/dist/interface/assets/{ConfigTriggerSensor-BCqAiPu4.js → ConfigTriggerSensor-D18nwMsj.js} +1 -1
  39. package/dist/interface/assets/{ConfigTriggerSystem-DuBydCiq.js → ConfigTriggerSystem-BhygWLB4.js} +1 -1
  40. package/dist/interface/assets/{ConfigTriggerWebhook-DDsnpwJr.js → ConfigTriggerWebhook-yyuBuhLD.js} +1 -1
  41. package/dist/interface/assets/Console-Cfk9MA9m.js +1 -0
  42. package/dist/interface/assets/CuiAssistantConversation-BHK_i56I.js +5 -0
  43. package/dist/interface/assets/CuiAssistantConversation-lkpZg3ML.css +1 -0
  44. package/dist/interface/assets/{CuiAutomationRunsDialog-C_sMg7E1.js → CuiAutomationRunsDialog-B0ohEHw0.js} +1 -1
  45. package/dist/interface/assets/{CuiBottomSheet-D_0LrjA_.js → CuiBottomSheet-DWefGWK2.js} +1 -1
  46. package/dist/interface/assets/CuiBottomSheet-NgX7VFao.js +1 -0
  47. package/dist/interface/assets/CuiCameraPipCard-C2qaGJlH.js +1 -0
  48. package/dist/interface/assets/CuiCameraRecordings-BTD-CQAg.js +1 -0
  49. package/dist/interface/assets/{CuiCameraShares-BIUB1xMa.js → CuiCameraShares-DcqOcePX.js} +1 -1
  50. package/dist/interface/assets/{CuiCameraTable-D-UhqHk4.js → CuiCameraTable-BOkfp_5M.js} +2 -2
  51. package/dist/interface/assets/CuiCameraTable-KPk46Xcl.js +1 -0
  52. package/dist/interface/assets/{CuiChartTable-CSK4Mzn3.js → CuiChartTable-DP38uBwK.js} +1 -1
  53. package/dist/interface/assets/{CuiConsole-DAbJXJBq.js → CuiConsole-C7xE_nQg.js} +2 -2
  54. package/dist/interface/assets/{CuiDataTable-DgcJsG-K.js → CuiDataTable-CsqH-RB1.js} +1 -1
  55. package/dist/interface/assets/CuiLightControl-ChGYpQAK.js +1 -0
  56. package/dist/interface/assets/{CuiLightControl-DFrZm_sv.css → CuiLightControl-D9sm8NZb.css} +1 -1
  57. package/dist/interface/assets/{CuiList-HdsA9vV1.js → CuiList-DJp0__mV.js} +1 -1
  58. package/dist/interface/assets/CuiPluginCard-CWImTZ6l.js +2 -0
  59. package/dist/interface/assets/{CuiPluginCategoryChip-C7R1jP7r.js → CuiPluginCategoryChip-Ch_upS6Y.js} +1 -1
  60. package/dist/interface/assets/{CuiPluginOAuthButton-BJJw0IaC.js → CuiPluginOAuthButton-DEQ9xILN.js} +2 -2
  61. package/dist/interface/assets/{CuiPluginTrustBadge-Bmm1qYdC.js → CuiPluginTrustBadge-sVWdvHcM.js} +1 -1
  62. package/dist/interface/assets/{CuiQRCode-DTSEFMBt.js → CuiQRCode-DqSF4SkD.js} +1 -1
  63. package/dist/interface/assets/CuiSchema-ytExUVhI.js +1 -0
  64. package/dist/interface/assets/CuiTopNavbarItem-B_KWykgq.js +1 -0
  65. package/dist/interface/assets/Faces-Cb6XMxDC.js +1 -0
  66. package/dist/interface/assets/FirstSteps-QNYTkEJo.js +1 -0
  67. package/dist/interface/assets/Floorplan-DbqADtN1.js +1 -0
  68. package/dist/interface/assets/Instances-DrMzPD65.js +1 -0
  69. package/dist/interface/assets/{Logs-BjcfuMQV.js → Logs-BSPT80vP.js} +2 -2
  70. package/dist/interface/assets/{Menu-BjjnSgdP.js → Menu-HHtuhIS2.js} +1 -1
  71. package/dist/interface/assets/Metrics-CqhUnVRA.js +12 -0
  72. package/dist/interface/assets/{OAuthDeviceFlow-9v-Czy_u.js → OAuthDeviceFlow-Bn1nlWNa.js} +1 -1
  73. package/dist/interface/assets/Plugin-DyOg_fbg.js +1 -0
  74. package/dist/interface/assets/{PluginConsole-C7sO42RG.js → PluginConsole-Cv-uhnPY.js} +2 -2
  75. package/dist/interface/assets/PluginDetail-cpOz7FkA.js +2 -0
  76. package/dist/interface/assets/{PluginSchema-D0eL9H-b.js → PluginSchema-DW3TGeTM.js} +1 -1
  77. package/dist/interface/assets/PluginSearch-BgecD9Ob.js +2 -0
  78. package/dist/interface/assets/PluginSearch-C8xHKikH.js +1 -0
  79. package/dist/interface/assets/{PluginUpdateProgress--MM9D8hs.js → PluginUpdateProgress-n6q6vzyd.js} +1 -1
  80. package/dist/interface/assets/Plugins-CuujWEtM.js +1 -0
  81. package/dist/interface/assets/{RecentEventsFilter-CvIJS8Se.js → RecentEventsFilter-CTR5JK_P.js} +1 -1
  82. package/dist/interface/assets/Recordings-ths9khZr.js +1 -0
  83. package/dist/interface/assets/SensorEdit-BzoIH7QC.js +1 -0
  84. package/dist/interface/assets/{SensorHistory-Efw0bZ-X.js → SensorHistory-9CdOpCPs.js} +1 -1
  85. package/dist/interface/assets/Sensors-CK5uExfU.js +2 -0
  86. package/dist/interface/assets/Settings-DN5hFtw_.js +1 -0
  87. package/dist/interface/assets/SettingsAccount-BCrmon5O.js +1 -0
  88. package/dist/interface/assets/SettingsAccount-CSy1BAIH.js +1 -0
  89. package/dist/interface/assets/{SettingsAccount-si-6gWl5.css → SettingsAccount-CY8YE_cy.css} +1 -1
  90. package/dist/interface/assets/SettingsAppearance-BY1xQMx4.js +1 -0
  91. package/dist/interface/assets/SettingsAppearance-h_XPZfQl.js +1 -0
  92. package/dist/interface/assets/SettingsAssistant-D8FmVbUL.js +1 -0
  93. package/dist/interface/assets/{SettingsBackup-BqKBKis5.js → SettingsBackup-D_weokqu.js} +1 -1
  94. package/dist/interface/assets/{SettingsList-BU191rmt.js → SettingsList-Bq24WTDU.js} +1 -1
  95. package/dist/interface/assets/SettingsMqtt-DCkLIYpF.js +1 -0
  96. package/dist/interface/assets/SettingsNotifications-8TZOUxg2.js +1 -0
  97. package/dist/interface/assets/{SettingsPermissions-sI64FPZG.js → SettingsPermissions-M8u_jrN0.js} +1 -1
  98. package/dist/interface/assets/{SettingsRecordings-CghrKErw.js → SettingsRecordings-C1Kp5xW_.js} +1 -1
  99. package/dist/interface/assets/SettingsRemote-DXlQKwlT.js +2 -0
  100. package/dist/interface/assets/{SettingsSystem-DP1p1Xns.js → SettingsSystem-Cetu2faJ.js} +2 -2
  101. package/dist/interface/assets/{SettingsUsers-Dpej-he1.js → SettingsUsers-CDwtQLdV.js} +1 -1
  102. package/dist/interface/assets/{Terminal-DPRPXCSt.js → Terminal-Dl-aAZME.js} +2 -2
  103. package/dist/interface/assets/{Training-Dwf5rXyC.css → Training-B1oQjAr8.css} +1 -1
  104. package/dist/interface/assets/Training-DdZjXgt1.js +1 -0
  105. package/dist/interface/assets/{Updates-QTvCp1aS.js → Updates-CkB1lXuo.js} +1 -1
  106. package/dist/interface/assets/{VariableInput-DhusSZPw.js → VariableInput-BxPj5wo6.js} +1 -1
  107. package/dist/interface/assets/{VariableSuggestions-Bkzz4Mv3.js → VariableSuggestions-CbizvAkz.js} +1 -1
  108. package/dist/interface/assets/{VersionsHandler-DjNSpSYy.js → VersionsHandler-CePyEUVO.js} +2 -2
  109. package/dist/interface/assets/{VirtualSensorCreate-soGT6h2c.js → VirtualSensorCreate-D_GVoeL7.js} +1 -1
  110. package/dist/interface/assets/Workers-7yiebNkl.js +2 -0
  111. package/dist/interface/assets/api-DK2Bav9D.js +4 -0
  112. package/dist/interface/assets/api-DTCqDA-h.css +2 -0
  113. package/dist/interface/assets/{api-CK2tonlH.js → api-DW2niHRN.js} +1 -1
  114. package/dist/interface/assets/{assistant-BEe1ExZL.js → assistant-BJ6xKcw_.js} +1 -1
  115. package/dist/interface/assets/{auth-QEpUGkWd.js → auth-Dc8bUpc-.js} +1 -1
  116. package/dist/interface/assets/{automations-BBIBV4Uu.js → automations-DXrjbArj.js} +1 -1
  117. package/dist/interface/assets/{cameraSources-Cm18cW9L.js → cameraSources-QJfUDOQJ.js} +1 -1
  118. package/dist/interface/assets/cloudHandoff-DtlquYGZ.js +1 -0
  119. package/dist/interface/assets/{config-vwkU8aqP.js → config-CiQDwB4t.js} +1 -1
  120. package/dist/interface/assets/{flowSchema-rzBroL0H.js → flowSchema-BRTZHQ1w.js} +1 -1
  121. package/dist/interface/assets/{intercomService-Du8V_HxF.js → intercomService-BnA-FQ0Q.js} +1 -1
  122. package/dist/interface/assets/{main-XHFrBKKz.css → main-BoGhBedC.css} +1 -1
  123. package/dist/interface/assets/main-D74mRIxc.js +3 -0
  124. package/dist/interface/assets/mqtt-iD9XHYO_.js +1 -0
  125. package/dist/interface/assets/{notifications-CN6eTJb_.js → notifications-CbAJX7RF.js} +1 -1
  126. package/dist/interface/assets/{plugins-DKtX7zQp.js → plugins-eIUrXNeM.js} +1 -1
  127. package/dist/interface/assets/rooms-BqPyo8jc.js +1 -0
  128. package/dist/interface/assets/{sensorIcons-ztqlMLDc.js → sensorIcons-DQVgryYP.js} +1 -1
  129. package/dist/interface/assets/{sensorSlots-D-uxjuv3.js → sensorSlots-BZCXtnb6.js} +1 -1
  130. package/dist/interface/assets/{sensors-DV2Z0IJt.js → sensors-DttBNEEt.js} +1 -1
  131. package/dist/interface/assets/{server-CfZnIVzn.js → server-DUFhf2c_.js} +1 -1
  132. package/dist/interface/assets/{theme-Bi7qdjBK.js → theme-BMmjtQ4w.js} +1 -1
  133. package/dist/interface/assets/{types-CNLAvgyw.js → types-5rE8Tz0_.js} +1 -1
  134. package/dist/interface/assets/{types-DwbeYXvn.js → types-CXw7CEzu.js} +1 -1
  135. package/dist/interface/assets/{types-DuwD8xp5.js → types-DWTSNJ79.js} +1 -1
  136. package/dist/interface/assets/ungrouped-D56FGIrg.js +1 -0
  137. package/dist/interface/assets/ungrouped-DHMJ9Rg1.css +1 -0
  138. package/dist/interface/assets/{updates-BqCH6Vr8.js → updates-TIPWXKzL.js} +1 -1
  139. package/dist/interface/assets/{useAppVersion-B-rmq3Bb.js → useAppVersion-BIz44Bg4.js} +1 -1
  140. package/dist/interface/assets/{useAssistantActions-Kf-5ijVf.js → useAssistantActions-CLkkw9kB.js} +1 -1
  141. package/dist/interface/assets/useBackupRestore-Crfd592q.js +1 -0
  142. package/dist/interface/assets/{useCameraOptions-Dt2J8sP_.js → useCameraOptions-A97teAIr.js} +1 -1
  143. package/dist/interface/assets/{useKeyboardInset-DtD3I2WC.js → useKeyboardInset-DXVi1dLG.js} +1 -1
  144. package/dist/interface/assets/{useLogsSocket-CEhUQdiY.js → useLogsSocket-BlFxVXjF.js} +1 -1
  145. package/dist/interface/assets/{useNavLayout-CtpYjS5W.js → useNavLayout-C5obaCNv.js} +1 -1
  146. package/dist/interface/assets/{usePermissions-CJzuagwD.js → usePermissions-C8hB_pG1.js} +1 -1
  147. package/dist/interface/assets/{usePluginUpdates-BwoWN5yb.js → usePluginUpdates-DO0-Gk4Q.js} +1 -1
  148. package/dist/interface/assets/{usePushRegistration-ANx4BS6_.js → usePushRegistration-BUttCraQ.js} +1 -1
  149. package/dist/interface/assets/{useServerRestart-7edyD8M0.js → useServerRestart-Cz9eVHUE.js} +1 -1
  150. package/dist/interface/assets/{useStreamStatus-DCSWHdbW.js → useStreamStatus-BhS_MCCB.js} +1 -1
  151. package/dist/interface/assets/{useTabSwipe-DfS3R3uP.js → useTabSwipe-D4k8lm1M.js} +1 -1
  152. package/dist/interface/assets/{useUpdateChannel-Cr9mSIRC.js → useUpdateChannel-D9lhfW0y.js} +1 -1
  153. package/dist/interface/assets/{useUpdatesSocket-B5Rm9syb.js → useUpdatesSocket-DnH9sON5.js} +1 -1
  154. package/dist/interface/assets/{useUserOptions-CJjImz8V.js → useUserOptions-BTRBUuE2.js} +1 -1
  155. package/dist/interface/assets/{vendor-cameraui-BbGOMenD.js → vendor-cameraui-QXD8jkcj.js} +26 -26
  156. package/dist/interface/assets/{vendor-core-tgH2YubJ.js → vendor-core-CnhnyKDl.js} +1 -1
  157. package/dist/interface/assets/{vendor-primevue-DNJJiEZl.js → vendor-primevue-CCUqY55W.js} +207 -207
  158. package/dist/interface/ha/{404-Dl6JtQWv.js → 404-DLhJqxRl.js} +1 -1
  159. package/dist/interface/ha/{About-wjv4kCO3.js → About-DC0i1iE4.js} +3 -3
  160. package/dist/interface/ha/{Assistant-Dpb4IsDC.js → Assistant-BmazMPIg.js} +821 -825
  161. package/dist/interface/ha/{Automation-CqTPjCUh.js → Automation-gabF9YzQ.js} +336 -336
  162. package/dist/interface/ha/{AutomationImport-CvdeneoU.js → AutomationImport-DaqZNs9s.js} +8 -8
  163. package/dist/interface/ha/{AutomationStore-bVPE68io.js → AutomationStore-DzM4huo5.js} +54 -54
  164. package/dist/interface/ha/{AutomationStoreDetail-BYaNUjoH.js → AutomationStoreDetail-CpzQMt_D.js} +7 -7
  165. package/dist/interface/ha/{Automations-BfsYh2A_.js → Automations-Dcm4Us50.js} +81 -81
  166. package/dist/interface/ha/{Camera-C70onr_O.js → Camera-CNK3QR7l.js} +198 -198
  167. package/dist/interface/ha/{CameraConsole-Dg3lV-wq.js → CameraConsole-CpcF0411.js} +5 -5
  168. package/dist/interface/ha/{Cameras-DpM6gt3G.js → Cameras-Cf9rwRyf.js} +293 -294
  169. package/dist/interface/ha/{Camview-CO_bHntH.js → Camview-BFKR2t6C.js} +87 -87
  170. package/dist/interface/ha/{Config-D-cpocuH.js → Config-1XH3zfr2.js} +11 -11
  171. package/dist/interface/ha/{ConfigActionAssistant-DVVVfVvT.js → ConfigActionAssistant-C0-NFoTB.js} +5 -5
  172. package/dist/interface/ha/{ConfigActionCameraControl-BPpzE9-F.js → ConfigActionCameraControl-DNSKZPSZ.js} +5 -5
  173. package/dist/interface/ha/{ConfigActionDelay-zU6H75hY.js → ConfigActionDelay-iZ3lPGzw.js} +1 -1
  174. package/dist/interface/ha/{ConfigActionHttp-BsNy03j4.js → ConfigActionHttp-DVJAcGkl.js} +3 -3
  175. package/dist/interface/ha/{ConfigActionImageInput-JUvNYn0w.js → ConfigActionImageInput-VVbHHHZs.js} +3 -3
  176. package/dist/interface/ha/{ConfigActionMqtt-PZqAKfTo.js → ConfigActionMqtt-N5OUJDzM.js} +4 -4
  177. package/dist/interface/ha/{ConfigActionNotification-DIL7abEm.js → ConfigActionNotification-s142tQoU.js} +6 -6
  178. package/dist/interface/ha/{ConfigActionNotificationControl-BQ2w5yeg.js → ConfigActionNotificationControl-Dh7kaKVP.js} +3 -3
  179. package/dist/interface/ha/{ConfigActionOutput-DVilKhPV.js → ConfigActionOutput-B4HHTg5C.js} +1 -1
  180. package/dist/interface/ha/{ConfigActionPlugin-BUfTEJQ_.js → ConfigActionPlugin-D20G2Dqf.js} +5 -5
  181. package/dist/interface/ha/{ConfigActionSensor-Dzp16VyX.js → ConfigActionSensor-BS3jrFaG.js} +6 -6
  182. package/dist/interface/ha/{ConfigActionSnapshot-CRjD5AMC.js → ConfigActionSnapshot-CInLAcwK.js} +3 -3
  183. package/dist/interface/ha/{ConfigActionVariable-CR8g7gEh.js → ConfigActionVariable-C5vADGNF.js} +2 -2
  184. package/dist/interface/ha/{ConfigConditionIfElse-CHoSgzXF.js → ConfigConditionIfElse-CPeWDD31.js} +4 -4
  185. package/dist/interface/ha/{ConfigConditionSensorState-Dn8_OhQe.js → ConfigConditionSensorState-BM5GmpN6.js} +6 -6
  186. package/dist/interface/ha/{ConfigConditionSwitch-Ds-nqWeU.js → ConfigConditionSwitch-Dmz9FduJ.js} +4 -4
  187. package/dist/interface/ha/{ConfigConditionTime-DWNfEluj.js → ConfigConditionTime-DF6llIJq.js} +2 -2
  188. package/dist/interface/ha/{ConfigSensorValueInput-DwXM9wP1.js → ConfigSensorValueInput-Ch5njvtv.js} +7 -7
  189. package/dist/interface/ha/{ConfigTriggerDetection-D37OkR_u.js → ConfigTriggerDetection-BR2QWNyO.js} +5 -5
  190. package/dist/interface/ha/{ConfigTriggerGeofence-EbXy_y3Q.js → ConfigTriggerGeofence-CaImOjyW.js} +9 -9
  191. package/dist/interface/ha/{ConfigTriggerMqtt-BX6uNEZy.js → ConfigTriggerMqtt-DWz1XwZQ.js} +2 -2
  192. package/dist/interface/ha/{ConfigTriggerSensor-BFGEtBVF.js → ConfigTriggerSensor-lfnhz0im.js} +3 -3
  193. package/dist/interface/ha/{ConfigTriggerSystem-fRnAgUGR.js → ConfigTriggerSystem-CwUhyFAj.js} +3 -3
  194. package/dist/interface/ha/{ConfigTriggerWebhook-DegifRdj.js → ConfigTriggerWebhook-J6Xts7GQ.js} +2 -2
  195. package/dist/interface/ha/{Console-Bo6S5psN.js → Console-BSdKFm6Y.js} +8 -8
  196. package/dist/interface/ha/{CuiAutomationRunsDialog-DXpNJqDE.js → CuiAutomationRunsDialog-BU8sympp.js} +3 -3
  197. package/dist/interface/ha/{CuiBottomSheet-DLkC2OmT.js → CuiBottomSheet-Bnp7ta7V.js} +1 -1
  198. package/dist/interface/ha/{CuiCameraRecordings-9tdkxXiT.js → CuiCameraRecordings-E-mMqKSs.js} +18 -19
  199. package/dist/interface/ha/{CuiCameraShares-BbqY_2b7.js → CuiCameraShares-DcNwd2OC.js} +8 -8
  200. package/dist/interface/ha/{CuiCameraTable-BmH1yAgl.js → CuiCameraTable-DNW9Vm_A.js} +6 -6
  201. package/dist/interface/ha/{CuiChartTable-BjBBI7Fo.js → CuiChartTable-muC7jL2H.js} +6 -6
  202. package/dist/interface/ha/{CuiConsole-By3m4UbE.js → CuiConsole-ND8bcuTg.js} +2 -2
  203. package/dist/interface/ha/{CuiDataTable-C_ndu5My.js → CuiDataTable-CN4T8DgP.js} +13 -13
  204. package/dist/interface/ha/{CuiPluginCard-BLQ1galy.js → CuiPluginCard-nIQiyQvH.js} +31 -31
  205. package/dist/interface/ha/{CuiPluginOAuthButton-BDghklSy.js → CuiPluginOAuthButton-FJ49NfUh.js} +3 -3
  206. package/dist/interface/ha/{CuiPluginTrustBadge-DolANNao.js → CuiPluginTrustBadge-D6eanMyI.js} +2 -2
  207. package/dist/interface/ha/{CuiQRCode-CcjPngXI.js → CuiQRCode-BdJzeeoE.js} +2 -2
  208. package/dist/interface/ha/{CuiSchema-D9JFf0dp.js → CuiSchema-DY0V-8xP.js} +67 -67
  209. package/dist/interface/ha/{CuiTopNavbarItem-DcUEq-4e.js → CuiTopNavbarItem-DT5pAKHp.js} +7 -8
  210. package/dist/interface/ha/{Faces-DjXHzr77.js → Faces-C_svyTrr.js} +92 -92
  211. package/dist/interface/ha/{FirstSteps-CQAP9Siw.js → FirstSteps-yS2M2cor.js} +9 -9
  212. package/dist/interface/ha/{Floorplan-DyaPzlQO.js → Floorplan-DSOeScjI.js} +194 -194
  213. package/dist/interface/ha/{Instances-DWjaU5gj.js → Instances-B4h5EKpF.js} +20 -20
  214. package/dist/interface/ha/{Logs-Dlx-X1NS.js → Logs-BH0Lxvs6.js} +12 -12
  215. package/dist/interface/ha/{Menu-iqEe01qO.js → Menu-COH7QXuE.js} +13 -13
  216. package/dist/interface/ha/{Metrics-Br2Dyvzh.js → Metrics-BtnRqL_I.js} +136 -136
  217. package/dist/interface/ha/{OAuthDeviceFlow-CIGk92FD.js → OAuthDeviceFlow-D2QJ9MnP.js} +8 -8
  218. package/dist/interface/ha/{Plugin-DklIr7j2.js → Plugin-EfUSqwyh.js} +85 -85
  219. package/dist/interface/ha/{PluginConsole-DCfxPtGU.js → PluginConsole-hh_o15f7.js} +4 -4
  220. package/dist/interface/ha/PluginDetail-DFiXGkrY.js +805 -0
  221. package/dist/interface/ha/{PluginSearch-BTKBnjxb.js → PluginSearch-Cdrfubrj.js} +54 -54
  222. package/dist/interface/ha/{PluginUpdateProgress-Dej5AcCt.js → PluginUpdateProgress-BD2g2kVj.js} +3 -3
  223. package/dist/interface/ha/{Plugins-C2fONspm.js → Plugins-qFiHW-Nk.js} +45 -45
  224. package/dist/interface/ha/{RecentEventsFilter-ylgjiDo8.js → RecentEventsFilter-UWrXnvfq.js} +1 -1
  225. package/dist/interface/ha/{Recordings-w39I43cc.js → Recordings-BzeC6tOz.js} +437 -419
  226. package/dist/interface/ha/{SensorEdit-BkKi1l-A.js → SensorEdit-BSgy7lkZ.js} +360 -360
  227. package/dist/interface/ha/{SensorHistory-BGJjMlc3.js → SensorHistory-IDvP8LKH.js} +2 -2
  228. package/dist/interface/ha/{Sensors-D_Wi9XPa.js → Sensors-Diqp4oZ0.js} +96 -97
  229. package/dist/interface/ha/{Settings-Bn7WLWf0.js → Settings-BgDsxAlx.js} +11 -11
  230. package/dist/interface/ha/{SettingsAccount-CRTex-1j.js → SettingsAccount-DBXMQPYk.js} +159 -159
  231. package/dist/interface/ha/{SettingsAppearance-B1qmJnYk.js → SettingsAppearance-VmbjnT3o.js} +6 -6
  232. package/dist/interface/ha/{SettingsAssistant-DDd1X0BC.js → SettingsAssistant-C2R4ZetE.js} +133 -133
  233. package/dist/interface/ha/{SettingsBackup-DZbhSB13.js → SettingsBackup-BqY9TwYn.js} +20 -20
  234. package/dist/interface/ha/{SettingsList-BQdyPe0H.js → SettingsList-CzHcfo2N.js} +4 -4
  235. package/dist/interface/ha/{SettingsMqtt-CSZcY6ht.js → SettingsMqtt-DqV3h3Ow.js} +149 -149
  236. package/dist/interface/ha/{SettingsNotifications-CfEhl0-y.js → SettingsNotifications-yn5fIR_7.js} +6 -6
  237. package/dist/interface/ha/{SettingsRecordings-BnAGDvcH.js → SettingsRecordings-DDs1lyfY.js} +8 -8
  238. package/dist/interface/ha/{SettingsRemote-w86TQVUA.js → SettingsRemote-jBw3l5E0.js} +172 -172
  239. package/dist/interface/ha/{SettingsSystem-CENjHL3k.js → SettingsSystem-BOv9hNlk.js} +9 -9
  240. package/dist/interface/ha/{SettingsUsers-CqSHRklV.js → SettingsUsers-Biv-2F4C.js} +90 -90
  241. package/dist/interface/ha/{Terminal-WsuxG3k-.js → Terminal-CmcrGEV0.js} +4 -4
  242. package/dist/interface/ha/Training-BEzPiXZg.js +1512 -0
  243. package/dist/interface/ha/{Updates-Dl_lLLR2.js → Updates-DJAcmDQJ.js} +12 -12
  244. package/dist/interface/ha/{VariableInput-C8Q81GUt.js → VariableInput-DlYg7t0m.js} +2 -2
  245. package/dist/interface/ha/{VersionsHandler-BOvjesvp.js → VersionsHandler-UnrAWn-b.js} +11 -11
  246. package/dist/interface/ha/{VirtualSensorCreate-sgwATaky.js → VirtualSensorCreate-CssxeaCC.js} +2 -2
  247. package/dist/interface/ha/{Workers-CkDuQ9NG.js → Workers-CLpqLugC.js} +14 -14
  248. package/dist/interface/ha/{accordion-Xem2SzgR.js → accordion-BylV-jUK.js} +2 -2
  249. package/dist/interface/ha/{api-BmYisoxj.js → api-BP7mlzjP.js} +11181 -11736
  250. package/dist/interface/ha/{api-oqpIZTkx.js → api-B_tDa73J.js} +1 -1
  251. package/dist/interface/ha/{assistant-0jE4C19U.js → assistant-Cb6ACguQ.js} +1 -1
  252. package/dist/interface/ha/{auth-B4Msg7R-.js → auth-DOYDRgFm.js} +1 -1
  253. package/dist/interface/ha/{autocomplete-B94Amei3.js → autocomplete-Cp3u2Ywa.js} +4 -4
  254. package/dist/interface/ha/{automationBlueprint-C-12Yjl7.js → automationBlueprint-CbbG_ku4.js} +1 -1
  255. package/dist/interface/ha/cameraui-cards.js +1 -1
  256. package/dist/interface/ha/{cards-BrOcoiQJ.js → cards-BpBP1zVW.js} +1206 -1198
  257. package/dist/interface/ha/{config-IG56wp6m.js → config-DroY1HBs.js} +1 -1
  258. package/dist/interface/ha/{datepicker-B4Azs5zr.js → datepicker-DXk97lTw.js} +4 -4
  259. package/dist/interface/ha/{mqtt-pl13wSmG.js → mqtt-NJTVdd53.js} +1 -1
  260. package/dist/interface/ha/{multiselect-Dp4XDBRR.js → multiselect-BOb4ScAZ.js} +4 -4
  261. package/dist/interface/ha/{notifications-B6wxSmou.js → notifications-BPTvvgvv.js} +1 -1
  262. package/dist/interface/ha/{plugins-BwwaWxye.js → plugins-B29K3nQP.js} +1 -1
  263. package/dist/interface/ha/{rooms-NIzjFYAd.js → rooms-DLw0WUy_.js} +1 -1
  264. package/dist/interface/ha/{select-UR3ZRDew.js → select-DV7p2EDj.js} +4 -4
  265. package/dist/interface/ha/{server-YOLwDVAW.js → server-B4b5_Ecu.js} +1 -1
  266. package/dist/interface/ha/{speeddial-LCbl5g8p.js → speeddial-B5p0fuqL.js} +1 -1
  267. package/dist/interface/ha/{tooltip-Z7VN-E1u.js → tooltip-BDrlgLof.js} +1 -1
  268. package/dist/interface/ha/{types-B8B9MqK0.js → types-DJHHL7nn.js} +1 -1
  269. package/dist/interface/ha/{ungrouped-DttNEB62.js → ungrouped-xyK1QrsM.js} +344 -376
  270. package/dist/interface/ha/{updates-DVhiQhMM.js → updates-XFSu9Tfm.js} +5 -5
  271. package/dist/interface/ha/{useAppVersion-CG4D44Aa.js → useAppVersion-BH3rU1zz.js} +1 -1
  272. package/dist/interface/ha/{useLogsSocket-PKsRDttg.js → useLogsSocket-CaTRzvgU.js} +1 -1
  273. package/dist/interface/ha/{useNavLayout-DoEcPx9Z.js → useNavLayout-DV0_OQx0.js} +1 -1
  274. package/dist/interface/ha/{useServerRestart-CMl589qX.js → useServerRestart-C8tynLUf.js} +1 -1
  275. package/dist/interface/ha/{useTabSwipe-Cmqdn0J5.js → useTabSwipe-CFoLDp3j.js} +1 -1
  276. package/dist/interface/ha/{useUpdateChannel-BBW2EX7N.js → useUpdateChannel-DSG2RTPe.js} +2 -2
  277. package/dist/interface/ha/{useUpdatesSocket-B6ICpKKC.js → useUpdatesSocket-CSQ0g7-6.js} +1 -1
  278. package/dist/interface/ha/{useUserOptions-CzclRfar.js → useUserOptions-CFaCy6L1.js} +1 -1
  279. package/dist/interface/ha/{virtualscroller-C5j7FXj4.js → virtualscroller-B-UQZDMJ.js} +88 -88
  280. package/dist/interface/index.html +34 -34
  281. package/dist/interface/sw.js +1 -1
  282. package/dist/server/package.json +22 -20
  283. package/dist/server/requirements.txt +1 -1
  284. package/dist/server/src/api/controllers/auth.controller.js +5 -6
  285. package/dist/server/src/api/controllers/auth.controller.js.map +1 -1
  286. package/dist/server/src/api/controllers/plugins.controller.js +5 -5
  287. package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
  288. package/dist/server/src/api/database/checks.js +20 -8
  289. package/dist/server/src/api/database/checks.js.map +1 -1
  290. package/dist/server/src/api/database/selfcheck.js +2 -2
  291. package/dist/server/src/api/database/selfcheck.js.map +1 -1
  292. package/dist/server/src/api/index.js +8 -6
  293. package/dist/server/src/api/index.js.map +1 -1
  294. package/dist/server/src/api/plugins/logger.plugin.js +11 -11
  295. package/dist/server/src/api/plugins/logger.plugin.js.map +1 -1
  296. package/dist/server/src/api/services/twoFactor.service.d.ts +4 -5
  297. package/dist/server/src/api/services/twoFactor.service.js +16 -17
  298. package/dist/server/src/api/services/twoFactor.service.js.map +1 -1
  299. package/dist/server/src/api/types/index.d.ts +0 -1
  300. package/dist/server/src/api/utils/cert.js +128 -135
  301. package/dist/server/src/api/utils/cert.js.map +1 -1
  302. package/dist/server/src/api/utils/form-body.d.ts +2 -0
  303. package/dist/server/src/api/utils/form-body.js +22 -0
  304. package/dist/server/src/api/utils/form-body.js.map +1 -0
  305. package/dist/server/src/api/utils/install-logger.js +12 -12
  306. package/dist/server/src/api/utils/install-logger.js.map +1 -1
  307. package/dist/server/src/api/websocket/nsp/logs.d.ts +7 -3
  308. package/dist/server/src/api/websocket/nsp/logs.js +76 -62
  309. package/dist/server/src/api/websocket/nsp/logs.js.map +1 -1
  310. package/dist/server/src/assistant/history.d.ts +2 -0
  311. package/dist/server/src/assistant/history.js +46 -0
  312. package/dist/server/src/assistant/history.js.map +1 -0
  313. package/dist/server/src/assistant/manager.js +2 -1
  314. package/dist/server/src/assistant/manager.js.map +1 -1
  315. package/dist/server/src/camera/controller.d.ts +1 -0
  316. package/dist/server/src/camera/controller.js +23 -18
  317. package/dist/server/src/camera/controller.js.map +1 -1
  318. package/dist/server/src/camera/decoder/worker.d.ts +3 -0
  319. package/dist/server/src/camera/decoder/worker.js +42 -5
  320. package/dist/server/src/camera/decoder/worker.js.map +1 -1
  321. package/dist/server/src/go2rtc/index.js +2 -2
  322. package/dist/server/src/go2rtc/index.js.map +1 -1
  323. package/dist/server/src/main.js +5 -5
  324. package/dist/server/src/main.js.map +1 -1
  325. package/dist/server/src/manager/discoveryManager.js +2 -2
  326. package/dist/server/src/manager/discoveryManager.js.map +1 -1
  327. package/dist/server/src/remote/services/cloudflare-managed.js +6 -3
  328. package/dist/server/src/remote/services/cloudflare-managed.js.map +1 -1
  329. package/dist/server/src/remote/services/cloudflare.d.ts +0 -1
  330. package/dist/server/src/remote/services/cloudflare.js +9 -20
  331. package/dist/server/src/remote/services/cloudflare.js.map +1 -1
  332. package/dist/server/src/remote/services/cloudflaredBinary.d.ts +3 -2
  333. package/dist/server/src/remote/services/cloudflaredBinary.js +9 -16
  334. package/dist/server/src/remote/services/cloudflaredBinary.js.map +1 -1
  335. package/dist/server/src/rpc/server.js +2 -2
  336. package/dist/server/src/rpc/server.js.map +1 -1
  337. package/dist/server/src/utils/automation-registry/index.js +3 -3
  338. package/dist/server/src/utils/automation-registry/index.js.map +1 -1
  339. package/dist/server/src/utils/colors.d.ts +2 -0
  340. package/dist/server/src/utils/colors.js +8 -0
  341. package/dist/server/src/utils/colors.js.map +1 -0
  342. package/dist/server/src/utils/npm/auth.d.ts +3 -2
  343. package/dist/server/src/utils/npm/auth.js +1 -1
  344. package/dist/server/src/utils/npm/auth.js.map +1 -1
  345. package/dist/server/src/utils/npm/index.d.ts +3 -15
  346. package/dist/server/src/utils/npm/index.js +26 -17
  347. package/dist/server/src/utils/npm/index.js.map +1 -1
  348. package/dist/server/src/utils/npm/registry.d.ts +69 -0
  349. package/dist/server/src/utils/npm/registry.js +240 -0
  350. package/dist/server/src/utils/npm/registry.js.map +1 -0
  351. package/dist/server/src/utils/plugin-registry/index.js +3 -3
  352. package/dist/server/src/utils/plugin-registry/index.js.map +1 -1
  353. package/dist/server/src/utils/process.d.ts +10 -0
  354. package/dist/server/src/utils/process.js +112 -0
  355. package/dist/server/src/utils/process.js.map +1 -0
  356. package/dist/server/src/utils/totp.d.ts +12 -0
  357. package/dist/server/src/utils/totp.js +71 -0
  358. package/dist/server/src/utils/totp.js.map +1 -0
  359. package/dist/server/src/utils/ttl-cache.d.ts +20 -0
  360. package/dist/server/src/utils/ttl-cache.js +63 -0
  361. package/dist/server/src/utils/ttl-cache.js.map +1 -0
  362. package/npm-shrinkwrap.json +6427 -0
  363. package/package.json +22 -20
  364. package/dist/interface/assets/Assistant-BKxssfw-.js +0 -1
  365. package/dist/interface/assets/Automation-CP59cgP7.js +0 -3
  366. package/dist/interface/assets/AutomationStore-BZGR_5Xl.js +0 -2
  367. package/dist/interface/assets/Automations-BpXorYAS.js +0 -2
  368. package/dist/interface/assets/Camera-UBUfaR5a.js +0 -2
  369. package/dist/interface/assets/Cameras-B21Y8MdQ.js +0 -651
  370. package/dist/interface/assets/Camview-BySyPtU5.js +0 -1
  371. package/dist/interface/assets/Config-BGyGmukb.js +0 -2
  372. package/dist/interface/assets/ConfigTriggerGeofence-CkzTFEZn.js +0 -1
  373. package/dist/interface/assets/Console-HXmKYaK_.js +0 -1
  374. package/dist/interface/assets/CuiAssistantConversation-2qrRCsgw.js +0 -5
  375. package/dist/interface/assets/CuiAssistantConversation-DmSdiv1b.css +0 -1
  376. package/dist/interface/assets/CuiBottomSheet-CTr-KHC8.js +0 -1
  377. package/dist/interface/assets/CuiCameraPipCard-BZCayhy_.js +0 -1
  378. package/dist/interface/assets/CuiCameraRecordings-BbaEL2ST.js +0 -1
  379. package/dist/interface/assets/CuiCameraTable-C5tQHs63.js +0 -1
  380. package/dist/interface/assets/CuiLightControl-v6k9hVGl.js +0 -1
  381. package/dist/interface/assets/CuiPluginCard-5MRYJcF2.js +0 -2
  382. package/dist/interface/assets/CuiSchema-BDXeXora.js +0 -1
  383. package/dist/interface/assets/CuiTopNavbarItem-BVknLbRO.js +0 -1
  384. package/dist/interface/assets/Faces-BEpYvbB0.js +0 -1
  385. package/dist/interface/assets/FirstSteps-U93RDOcP.js +0 -1
  386. package/dist/interface/assets/Floorplan-D8XoCNOB.js +0 -1
  387. package/dist/interface/assets/Instances-CFwZotvU.js +0 -1
  388. package/dist/interface/assets/Metrics-Ca_d5CbP.js +0 -12
  389. package/dist/interface/assets/Plugin-BjLw46Sw.js +0 -1
  390. package/dist/interface/assets/PluginDetail-BuLW4lkN.js +0 -2
  391. package/dist/interface/assets/PluginSearch--LLMEeyx.js +0 -2
  392. package/dist/interface/assets/PluginSearch-0akjE0ef.js +0 -1
  393. package/dist/interface/assets/Plugins-26O511gf.js +0 -1
  394. package/dist/interface/assets/Recordings-DQOGeSFm.js +0 -1
  395. package/dist/interface/assets/SensorEdit-DEW5D80x.js +0 -1
  396. package/dist/interface/assets/Sensors-C8yOyAwo.js +0 -2
  397. package/dist/interface/assets/Settings-B-RgMeVm.js +0 -1
  398. package/dist/interface/assets/SettingsAccount-B6aXFx3F.js +0 -1
  399. package/dist/interface/assets/SettingsAccount-_0ccrXYU.js +0 -1
  400. package/dist/interface/assets/SettingsAppearance-CkDwzx6f.js +0 -1
  401. package/dist/interface/assets/SettingsAppearance-DBFE3uVH.js +0 -1
  402. package/dist/interface/assets/SettingsAssistant-DN5OUJqt.js +0 -1
  403. package/dist/interface/assets/SettingsMqtt-hsKZkU-o.js +0 -1
  404. package/dist/interface/assets/SettingsNotifications-DIeiUEAk.js +0 -1
  405. package/dist/interface/assets/SettingsRemote-Doa0aBMC.js +0 -2
  406. package/dist/interface/assets/Training-DYlefOX1.js +0 -1
  407. package/dist/interface/assets/Workers-CUVvTuts.js +0 -2
  408. package/dist/interface/assets/api-B0wYDGQj.css +0 -2
  409. package/dist/interface/assets/api-BNrZVfeD.js +0 -4
  410. package/dist/interface/assets/cloudHandoff-Dnndt2el.js +0 -1
  411. package/dist/interface/assets/main-CRlC4FBY.js +0 -3
  412. package/dist/interface/assets/mqtt-BY6-Hrbv.js +0 -1
  413. package/dist/interface/assets/ring-resize-DyqCo2UN.js +0 -1
  414. package/dist/interface/assets/rooms-BHP4q6yf.js +0 -1
  415. package/dist/interface/assets/ungrouped-DBRZ-Ori.css +0 -1
  416. package/dist/interface/assets/ungrouped-DHLAmt__.js +0 -1
  417. package/dist/interface/assets/useBackupRestore-Dj-ZXODq.js +0 -1
  418. package/dist/interface/ha/PluginDetail-BFfRnkdG.js +0 -230
  419. package/dist/interface/ha/Training-hu_XOYBk.js +0 -1505
  420. package/dist/interface/ha/ring-resize-Dr2PxWIg.js +0 -16
@@ -1,71 +1,70 @@
1
1
  import { c as e, m as t } from "./ripple-ZDATPc2w.js";
2
2
  import { B as n, D as r, Dt as i, G as a, H as o, Jt as s, K as c, M as l, Wt as u, _t as d, bt as f, d as p, f as m, ft as h, gt as g, kt as _, l as v, lt as y, ot as b, p as x, qt as S, r as C, rt as w, u as T, ut as E, v as D, x as O, xt as k, y as A, yt as j, z as M } from "./runtime-core.esm-bundler-_TfE0DWz.js";
3
- import { t as ee } from "./tooltip-Z7VN-E1u.js";
4
- import { t as te } from "./message-D6dIy_hz.js";
5
- import { A as N, D as P, Dt as F, Et as ne, F as I, I as L, L as R, O as z, On as re, Or as ie, Tr as ae, a as B, ai as oe, bi as V, br as se, bt as ce, ht as H, k as U, m as le, qt as ue, ui as de, ur as fe, yr as pe } from "./api-BmYisoxj.js";
6
- import { M as me } from "./protocol-BB4jdtUC-DW3jl2tV.js";
7
- import { i as he, o as ge } from "./intercomService-B7HkLs6z.js";
8
- import { $ as _e, et as ve, nt as ye, rt as be, tt as xe } from "./pinia-C6gt7A_Q.js";
9
- import { n as W } from "./vue-i18n-D5EAy78K.js";
10
- import { n as Se, t as G } from "./button-BouAFgf5.js";
11
- import { t as K } from "./inputtext-C_ygnPrC.js";
12
- import { t as Ce } from "./close-CxFbonhd.js";
13
- import { t as we } from "./select-UR3ZRDew.js";
14
- import { i as Te, n as Ee, r as De, t as Oe } from "./accordion-Xem2SzgR.js";
15
- import { t as ke } from "./chip-BTHURsTF.js";
16
- import { i as Ae, t as je } from "./CuiDataTable-C_ndu5My.js";
17
- import { n as Me, r as Ne, t as Pe } from "./CuiSchema-D9JFf0dp.js";
18
- import { t as Fe } from "./ring-resize-Dr2PxWIg.js";
19
- import { t as Ie } from "./CuiCameraTable-BmH1yAgl.js";
20
- import { u as Le } from "./cards-BrOcoiQJ.js";
21
- import { t as Re } from "./plus-CgxY7W0L.js";
22
- import { t as ze } from "./radar-BG-Tcwg_.js";
23
- import { n as Be, t as Ve } from "./eye-off-UG_p9nl8.js";
24
- import { t as He } from "./rooms-NIzjFYAd.js";
3
+ import { t as ee } from "./tooltip-BDrlgLof.js";
4
+ import { t as N } from "./message-D6dIy_hz.js";
5
+ import { A as P, D as F, F as I, I as L, L as R, O as te, Or as ne, Ot as re, Sr as ie, St as ae, Tr as oe, Yt as z, _t as B, a as V, ai as se, bi as H, jn as U, k as W, kt as ce, m as le, mr as G, tt as ue, ui as de, wr as fe } from "./api-BP7mlzjP.js";
6
+ import { M as pe } from "./protocol-BB4jdtUC-DW3jl2tV.js";
7
+ import { i as me, o as he } from "./intercomService-B7HkLs6z.js";
8
+ import { $ as ge, et as _e, nt as ve, rt as ye, tt as be } from "./pinia-C6gt7A_Q.js";
9
+ import { n as K } from "./vue-i18n-D5EAy78K.js";
10
+ import { n as xe, t as q } from "./button-BouAFgf5.js";
11
+ import { t as J } from "./inputtext-C_ygnPrC.js";
12
+ import { t as Se } from "./close-CxFbonhd.js";
13
+ import { t as Ce } from "./select-DV7p2EDj.js";
14
+ import { i as we, n as Te, r as Ee, t as De } from "./accordion-BylV-jUK.js";
15
+ import { t as Oe } from "./chip-BTHURsTF.js";
16
+ import { i as ke, t as Ae } from "./CuiDataTable-CN4T8DgP.js";
17
+ import { n as je, r as Me, t as Ne } from "./CuiSchema-DY0V-8xP.js";
18
+ import { t as Pe } from "./CuiCameraTable-DNW9Vm_A.js";
19
+ import { u as Fe } from "./cards-BpBP1zVW.js";
20
+ import { t as Ie } from "./plus-CgxY7W0L.js";
21
+ import { t as Le } from "./radar-BG-Tcwg_.js";
22
+ import { n as Re, t as ze } from "./eye-off-UG_p9nl8.js";
23
+ import { t as Be } from "./rooms-DLw0WUy_.js";
25
24
  //#region ~icons/material-symbols/camera-rounded
26
- var Ue = {
25
+ var Ve = {
27
26
  viewBox: "0 0 24 24",
28
27
  width: "1.2em",
29
28
  height: "1.2em"
30
29
  };
31
- function We(e, t) {
32
- return o(), x("svg", Ue, [...t[0] ||= [T("path", {
30
+ function He(e, t) {
31
+ return o(), x("svg", Ve, [...t[0] ||= [T("path", {
33
32
  fill: "currentColor",
34
33
  d: "M12.5 9q-.275 0-.425-.25t0-.5L15 3.175q.2-.325.5-.387t.65.112q1.725.775 3.05 2.162T21.25 8.2q.125.325-.038.563T20.7 9zm-3.575 1.225l-3-5.2q-.2-.325-.1-.65t.4-.525Q7.425 3 8.888 2.5T12 2q.375 0 .825.038t.75.087q.35.05.463.3t-.063.55L9.8 10.225q-.15.25-.437.25t-.438-.25M2.85 14q-.275 0-.5-.187t-.275-.463t-.062-.6T2 12q0-1.575.513-3.137T4.1 5.9q.275-.35.638-.35t.562.375l4.2 7.325q.15.25-.012.5T9.05 14zm5 7.1q-1.65-.8-3.025-2.175T2.75 15.8q-.125-.325.05-.562T3.325 15h8.15q.275 0 .425.25t0 .5l-2.875 5.025q-.2.325-.5.425t-.675-.1M12 22q-.35 0-.788-.038t-.762-.087q-.35-.05-.475-.3t.05-.55l4.125-7.2q.15-.25.5-.25t.5.25l2.95 5.125q.175.275.113.6t-.413.6q-1.15.85-2.687 1.35T12 22m6.775-3.875l-4.25-7.375q-.15-.25.013-.5t.437-.25h6.175q.275 0 .5.188t.275.462t.062.6T22 12q0 1.575-.513 3.163T19.9 18.125q-.2.275-.575.288t-.55-.288"
35
34
  }, null, -1)]]);
36
35
  }
37
- var Ge = d({
36
+ var Ue = d({
38
37
  name: "material-symbols-camera-rounded",
39
- render: We
40
- }), Ke = "#### Source: Bubble\n\nOther names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/).\n\n- you can skip `username`, `password`, `port`, `ch` and `stream` if they are default\n- setup separate streams for different channels and streams\n\n```yaml\nstreams:\n camera1: bubble://username:password@192.168.1.123:34567/bubble/live?ch=0&stream=0\n```\n\n_Source: [Go2Rtc Bubble](https://github.com/seydx/go2rtc#source-bubble)_\n", qe = "#### Source: CUI\n\nThis source can be used to stream dynamically generated, go2rtc compatible, URLs. The source is just a placeholder for a `https://` URL.\n\n```yaml\nstreams:\n camera1: cui://192.168.1.123:34567/some-identifier-if-you-want\n```\n\nThe URL will be changed to `https://192.168.1.123:34567/some-identifier-if-you-want` and the response must be like this:\n\n```json\n{\n {\n \"streamUrl\": \"rtsp://192.168.1.1:554/stream\",\n }\n}\n```\n\nGo2rtc will then use the `streamUrl` to stream the video. The `streamUrl` can be any URL that is compatible with go2rtc. The response must be a valid JSON object with the `streamUrl` key.\n", Je = "#### Source: Doorbird\n\n[Doorbird](https://www.doorbird.com/) proprietary camera protocol with **two way audio** support.\n\n```yaml\nstreams:\n video-audio:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n two-way:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n - doorbird://user:pass@123.123.123.123\n mjpeg-video:\n - doorbird://user:pass@123.123.123.123?media=video\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-doorbird)_\n", Ye = "#### Source: DVRIP\n\nOther names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK).\n\n- you can skip `username`, `password`, `port`, `channel` and `subtype` if they are default\n- setup separate streams for different channels\n- use `subtype=0` for Main stream, and `subtype=1` for Extra1 stream\n- only the TCP protocol is supported\n\n```yaml\nstreams:\n only_stream: dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n only_tts: dvrip://username:password@192.168.1.123:34567?backchannel=1\n two_way_audio:\n - dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n - dvrip://username:password@192.168.1.123:34567?backchannel=1\n```\n\n_Source: [Go2Rtc DVRIP](https://github.com/seydx/go2rtc#source-dvrip)_\n", Xe = "#### Source: Echo\n\nSome sources may have a dynamic link. And you will need to get it using a bash or python script. Your script should echo a link to the source. RTSP, FFmpeg or any of the [supported sources](https://github.com/seydx/go2rtc#module-streams).\n\n**Docker** and **Hass Add-on** users has preinstalled `python3`, `curl`, `jq`.\nCheck examples in [wiki](https://github.com/seydx/go2rtc/wiki/Source-Echo-examples).\n\n```yaml\nstreams:\n apple_hls: echo:python3 hls.py https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\n```\n\n_Source: [Go2Rtc Echo](https://github.com/seydx/go2rtc#source-echo)_\n", Ze = "#### Source: Exec\n\nExec source can run any external application and expect data from it. Two transports are supported - **pipe** and **RTSP**.\n\nIf you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server.\n\n**pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**. Also pipe can write data to app stdin in two formats: **PCMA** and **PCM/48000**.\n\nThe source can be used with:\n\n- [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source\n- [FFplay](https://ffmpeg.org/ffplay.html) - play audio on your server\n- [GStreamer](https://gstreamer.freedesktop.org/)\n- [Raspberry Pi Cameras](https://www.raspberrypi.com/documentation/computers/camera_software.html)\n- any your own software\n\n```yaml\nstreams:\n stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output}\n picam_h264: exec:libcamera-vid -t 0 --inline -o -\n picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o -\n pi5cam_h264: exec:libcamera-vid -t 0 --libav-format h264 -o -\n canon: exec:gphoto2 --capture-movie --stdout#killsignal=2#killtimeout=5\n play_pcma: exec:ffplay -fflags nobuffer -f alaw -ar 8000 -i -#backchannel=1\n play_pcm48k: exec:ffplay -fflags nobuffer -f s16be -ar 48000 -i -#backchannel=1\n```\n\n_Source: [Go2Rtc Exec](https://github.com/seydx/go2rtc#source-exec)_\n", Qe = "#### Source: Expr\n\n[Expr](https://github.com/antonmedv/expr) - expression language and expression evaluation for Go.\n\n- [language definition](https://expr.medv.io/docs/Language-Definition) - takes best from JS, Python, Jinja2 syntax\n- your expression should return a link of any supported source\n- expression supports multiple operation, but:\n - all operations must be separated by a semicolon\n - all operations, except the last one, must declare a new variable (`let s = \"abc\";`)\n - the last operation should return a string\n- go2rtc supports additional functions:\n - `fetch` - JS-like HTTP requests\n - `match` - JS-like RegExp queries\n\n## Examples\n\n**Two way audio for Dahua VTO**\n\n```yaml\nstreams:\n dahua_vto: |\n expr: let host = \"admin:password@192.168.1.123\";\n fetch(\"http://\"+host+\"/cgi-bin/configManager.cgi?action=setConfig&Encode[0].MainFormat[0].Audio.Compression=G.711A&Encode[0].MainFormat[0].Audio.Frequency=8000\").ok\n ? \"rtsp://\"+host+\"/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\" : \"\"\n```\n\n**dom.ru**\n\nYou can get credentials via:\n\n- https://github.com/alexmorbo/domru (file `/share/domru/accounts`)\n- https://github.com/ad/domru\n\n```yaml\nstreams:\n dom_ru: |\n expr: let camera = \"99999999\"; let token = \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"; let operator = 99;\n fetch(\"https://myhome.novotelecom.ru/rest/v1/forpost/cameras/\"+camera+\"/video\", {\n headers: {Authorization: \"Bearer \"+token, Operator: operator}\n }).json().data.URL\n```\n\n**Parse HLS files from Apple**\n\nSame example in two languages - python and expr.\n\n```yaml\nstreams:\n example_python: |\n echo:python -c 'from urllib.request import urlopen; import re\n\n # url1 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8\"\n html1 = urlopen(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").read().decode(\"utf-8\")\n url1 = re.search(r\"https.+?m3u8\", html1)[0]\n\n # url2 = \"gear1/prog_index.m3u8\"\n html2 = urlopen(url1).read().decode(\"utf-8\")\n url2 = re.search(r\"^[a-z0-1/_]+\\.m3u8$\", html2, flags=re.MULTILINE)[0]\n\n # url3 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear1/prog_index.m3u8\"\n url3 = url1[:url1.rindex(\"/\")+1] + url2\n\n print(\"ffmpeg:\" + url3 + \"#video=copy\")'\n\n example_expr: |\n expr:\n\n let html1 = fetch(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").text;\n let url1 = match(html1, \"https.+?m3u8\")[0];\n\n let html2 = fetch(url1).text;\n let url2 = match(html2, \"^[a-z0-1/_]+\\\\.m3u8$\", \"m\")[0];\n\n let url3 = url1[:lastIndexOf(url1, \"/\")+1] + url2;\n\n \"ffmpeg:\" + url3 + \"#video=copy\"\n```\n\n## Comparsion\n\n| expr | python | js |\n| ---------------------------- | -------------------------- | ------------------------------ |\n| let x = 1; | x = 1 | let x = 1 |\n| {a: 1, b: 2} | {\"a\": 1, \"b\": 2} | {a: 1, b: 2} |\n| let r = fetch(url, {method}) | r = request(method, url) | r = await fetch(url, {method}) |\n| r.ok | r.ok | r.ok |\n| r.status | r.status_code | r.status |\n| r.text | r.text | await r.text() |\n| r.json() | r.json() | await r.json() |\n| r.headers | r.headers | r.headers |\n| let m = match(text, \"abc\") | m = re.search(\"abc\", text) | let m = text.match(/abc/) |\n\n_Source: [Go2Rtc Expr](https://github.com/seydx/go2rtc#source-expr)_\n", $e = "#### Source: FFmpeg\n\nYou can get any stream or file or device via FFmpeg and push it to go2rtc. The app will automatically start FFmpeg with the proper arguments when someone starts watching the stream.\n\n- FFmpeg preistalled for **Docker** and **Hass Add-on** users\n- **Hass Add-on** users can target files from [/media](https://www.home-assistant.io/more-info/local-media/setup-media/) folder\n\nFormat: `ffmpeg:{input}#{param1}#{param2}#{param3}`. Examples:\n\n```yaml\nstreams:\n # [FILE] all tracks will be copied without transcoding codecs\n file1: ffmpeg:/media/BigBuckBunny.mp4\n\n # [FILE] video will be transcoded to H264, audio will be skipped\n file2: ffmpeg:/media/BigBuckBunny.mp4#video=h264\n\n # [FILE] video will be copied, audio will be transcoded to pcmu\n file3: ffmpeg:/media/BigBuckBunny.mp4#video=copy#audio=pcmu\n\n # [HLS] video will be copied, audio will be skipped\n hls: ffmpeg:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear5/prog_index.m3u8#video=copy\n\n # [MJPEG] video will be transcoded to H264\n mjpeg: ffmpeg:http://185.97.122.128/cgi-bin/faststream.jpg#video=h264\n\n # [RTSP] video with rotation, should be transcoded, so select H264\n rotate: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#rotate=90\n```\n\nAll trascoding formats has [built-in templates](https://github.com/seydx/go2rtc/blob/master/internal/ffmpeg/ffmpeg.go): `h264`, `h265`, `opus`, `pcmu`, `pcmu/16000`, `pcmu/48000`, `pcma`, `pcma/16000`, `pcma/48000`, `aac`, `aac/16000`.\n\nBut you can override them via YAML config. You can also add your own formats to config and use them with source params.\n\n```yaml\nffmpeg:\n bin: ffmpeg # path to ffmpeg binary\n h264: '-codec:v libx264 -g:v 30 -preset:v superfast -tune:v zerolatency -profile:v main -level:v 4.1'\n mycodec: '-any args that supported by ffmpeg...'\n myinput: '-fflags nobuffer -flags low_delay -timeout 5000000 -i {input}'\n myraw: '-ss 00:00:20'\n```\n\n- You can use go2rtc stream name as ffmpeg input (ex. `ffmpeg:camera1#video=h264`)\n- You can use `video` and `audio` params multiple times (ex. `#video=copy#audio=copy#audio=pcmu`)\n- You can use `rotate` param with `90`, `180`, `270` or `-90` values, important with transcoding (ex. `#video=h264#rotate=90`)\n- You can use `width` and/or `height` params, important with transcoding (ex. `#video=h264#width=1280`)\n- You can use `drawtext` to add a timestamp (ex. `drawtext=x=2:y=2:fontsize=12:fontcolor=white:box=1:boxcolor=black`)\n - This will greatly increase the CPU of the server, even with hardware acceleration\n- You can use `raw` param for any additional FFmpeg arguments (ex. `#raw=-vf transpose=1`)\n- You can use `input` param to override default input template (ex. `#input=rtsp/udp` will change RTSP transport from TCP to UDP+TCP)\n - You can use raw input value (ex. `#input=-timeout 5000000 -i {input}`)\n - You can add your own input templates\n\nRead more about [hardware acceleration](https://github.com/seydx/go2rtc/wiki/Hardware-acceleration).\n\n**PS.** It is recommended to check the available hardware in the WebUI add page.\n\n<hr>\n\n#### Source: FFmpeg Device\n\nYou can get video from any USB-camera or Webcam as RTSP or WebRTC stream. This is part of FFmpeg integration.\n\n- check available devices in Web interface\n- `video_size` and `framerate` must be supported by your camera!\n- for Linux supported only video for now\n- for macOS you can stream Facetime camera or whole Desktop!\n- for macOS important to set right framerate\n\nFormat: `ffmpeg:device?{input-params}#{param1}#{param2}#{param3}`\n\n```yaml\nstreams:\n linux_usbcam: ffmpeg:device?video=0&video_size=1280x720#video=h264\n windows_webcam: ffmpeg:device?video=0#video=h264\n macos_facetime: ffmpeg:device?video=0&audio=1&video_size=1280x720&framerate=30#video=h264#audio=pcma\n```\n\n**PS.** It is recommended to check the available devices in the WebUI add page.\n\n_Source: [Go2Rtc FFmpeg](https://github.com/seydx/go2rtc#source-ffmpeg) & [Go2Rtc FFmpeg Device](https://github.com/seydx/go2rtc#source-ffmpeg-device)_\n", et = "#### Source: GoPro\n\nSupported models: HERO9, HERO10, HERO11, HERO12. \nSupported OS: Linux, Mac, Windows, [HassOS](https://www.home-assistant.io/installation/)\n\nThe other camera models have different APIs. I will try to add them in the next versions.\n\n## Config\n\n- USB-connected cameras create a new network interface in the system\n- Linux users do not need to install anything\n- Windows users should install the [network driver](https://community.gopro.com/s/article/GoPro-Webcam)\n- if the camera is detected but the stream does not start - you need to disable firewall\n\n1. Discover camera address: WebUI > Add > GoPro\n2. Add camera to config\n\n```yaml\nstreams:\n hero12: gopro://172.20.100.51\n```\n\n## Useful links\n\n- https://gopro.github.io/OpenGoPro/\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", tt = "#### Source: Hass\n\nSupport import camera links from [Home Assistant](https://www.home-assistant.io/) config files:\n\n- [Generic Camera](https://www.home-assistant.io/integrations/generic/), setup via GUI\n- [HomeKit Camera](https://www.home-assistant.io/integrations/homekit_controller/)\n- [ONVIF](https://www.home-assistant.io/integrations/onvif/)\n- [Roborock](https://github.com/humbertogontijo/homeassistant-roborock) vacuums with camera\n\n```yaml\nhass:\n config: '/config' # skip this setting if you Hass Add-on user\n\nstreams:\n generic_camera: hass:Camera1 # Settings > Integrations > Integration Name\n aqara_g3: hass:Camera-Hub-G3-AB12\n```\n\n**WebRTC Cameras**\n\nAny cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat.\n\nThe Nest API only allows you to get a link to a stream for 5 minutes. So every 5 minutes the stream will be reconnected.\n\n```yaml\nstreams:\n # link to Home Assistant Supervised\n hass-webrtc1: hass://supervisor?entity_id=camera.nest_doorbell\n # link to external Hass with Long-Lived Access Tokens\n hass-webrtc2: hass://192.168.1.123:8123?entity_id=camera.nest_doorbell&token=eyXYZ...\n```\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", nt = "#### Source: HomeKit\n\n**Important:**\n\n- You can use HomeKit Cameras **without Apple devices** (iPhone, iPad, etc.), it's just a yet another protocol\n- HomeKit device can be paired with only one ecosystem. So, if you have paired it to an iPhone (Apple Home) - you can't pair it with Home Assistant or go2rtc. Or if you have paired it to go2rtc - you can't pair it with iPhone\n- HomeKit device should be in same network with working [mDNS](https://en.wikipedia.org/wiki/Multicast_DNS) between device and go2rtc\n\ngo2rtc support import paired HomeKit devices from [Home Assistant](#source-hass). So you can use HomeKit camera with Hass and go2rtc simultaneously. If you using Hass, I recommend pairing devices with it, it will give you more options.\n\nYou can pair device with go2rtc on the HomeKit page. If you can't see your devices - reload the page. Also try reboot your HomeKit device (power off). If you still can't see it - you have a problems with mDNS.\n\nIf you see a device but it does not have a pair button - it is paired to some ecosystem (Apple Home, Home Assistant etc). You need to delete device from that ecosystem, and it will be available for pairing. If you cannot unpair device, you will have to reset it.\n\n**Important:**\n\n- HomeKit audio uses very non-standard **AAC-ELD** codec with very non-standard params and specification violation\n- Audio can't be played in `VLC` and probably any other player\n- Audio should be transcoded for using with MSE, WebRTC, etc.\n\nRecommended settings for using HomeKit Camera with WebRTC, MSE, MP4, RTSP:\n\n```\nstreams:\n aqara_g3:\n - hass:Camera-Hub-G3-AB12\n - ffmpeg:aqara_g3#audio=aac#audio=opus\n```\n\nRTSP link with \"normal\" audio for any player: `rtsp://192.168.1.123:8554/aqara_g3?video&audio=aac`\n\n**This source is in active development!** Tested only with [Aqara Camera Hub G3](https://www.aqara.com/eu/product/camera-hub-g3) (both EU and CN versions).\n\n_Source: [Go2Rtc HomeKit](https://github.com/seydx/go2rtc#source-homekit)_\n", rt = "#### Source: HTTP\n\nSupport Content-Type:\n\n- **HTTP-FLV** (`video/x-flv`) - same as RTMP, but over HTTP\n- **HTTP-JPEG** (`image/jpeg`) - camera snapshot link, can be converted by go2rtc to MJPEG stream\n- **HTTP-MJPEG** (`multipart/x`) - simple MJPEG stream over HTTP\n- **MPEG-TS** (`video/mpeg`) - legacy [streaming format](https://en.wikipedia.org/wiki/MPEG_transport_stream)\n\nSource also support HTTP and TCP streams with autodetection for different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**.\n\n```yaml\nstreams:\n # [HTTP-FLV] stream in video/x-flv format\n http_flv: http://192.168.1.123:20880/api/camera/stream/780900131155/657617\n\n # [JPEG] snapshots from Dahua camera, will be converted to MJPEG stream\n dahua_snap: http://admin:password@192.168.1.123/cgi-bin/snapshot.cgi?channel=1\n\n # [MJPEG] stream will be proxied without modification\n http_mjpeg: https://mjpeg.sanford.io/count.mjpeg\n\n # [MJPEG or H.264/H.265 bitstream or MPEG-TS]\n tcp_magic: tcp://192.168.1.123:12345\n\n # Add custom header\n custom_header: 'https://mjpeg.sanford.io/count.mjpeg#header=Authorization: Bearer XXX'\n```\n\n**PS.** Dahua camera has bug: if you select MJPEG codec for RTSP second stream - snapshot won't work.\n\n_Source: [Go2Rtc Http](https://github.com/seydx/go2rtc#source-http)_\n", it = "#### Source: ISAPI\n\nThis source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol.\n\n```yaml\nstreams:\n hikvision1:\n - rtsp://admin:password@192.168.1.123:554/Streaming/Channels/101\n - isapi://admin:password@192.168.1.123:80/\n```\n\n_Source: [Go2Rtc Isapi](https://github.com/seydx/go2rtc#source-isapi)_\n", at = "#### Source: Ivideon\n\nSupport public cameras from service [Ivideon](https://tv.ivideon.com/).\n\n```yaml\nstreams:\n quailcam: ivideon:100-tu5dkUPct39cTp9oNEN2B6/0\n```\n\n_Source: [Go2Rtc Ivideon](https://github.com/seydx/go2rtc#source-ivideon)_\n", ot = "#### Source: Kasa\n\n[TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd).\n\n- `username` - urlsafe email, `alex@gmail.com` -> `alex%40gmail.com`\n- `password` - base64password, `secret1` -> `c2VjcmV0MQ==`\n\n```yaml\nstreams:\n kc401: kasa://username:password@192.168.1.123:19443/https/stream/mixed\n```\n\nTested: KD110, KC200, KC401, KC420WS, EC71.\n\n_Source: [Go2Rtc Kasa](https://github.com/seydx/go2rtc#source-kasa)_\n", st = "#### Source: Nest\n\nCurrently only WebRTC cameras are supported.\n\nFor simplicity, it is recommended to connect the Nest/WebRTC camera to the [Home Assistant](#source-hass). But if you can somehow get the below parameters - Nest/WebRTC source will work without Hass.\n\n```yaml\nstreams:\n nest-doorbell: nest:?client_id=***&client_secret=***&refresh_token=***&project_id=***&device_id=***\n```\n\n_Source: [Go2Rtc Nest](https://github.com/seydx/go2rtc#source-nest)_\n", ct = "#### Source: ONVIF\n\nThe source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't.\n\n**WebUI > Add** webpage support ONVIF autodiscovery. Your server must be on the same subnet as the camera. If you use docker, you must use \"network host\".\n\n```yaml\nstreams:\n dahua1: onvif://admin:password@192.168.1.123\n reolink1: onvif://admin:password@192.168.1.123:8000\n tapo1: onvif://admin:password@192.168.1.123:2020\n```\n\n_Source: [Go2Rtc Onvif](https://github.com/seydx/go2rtc#source-onvif)_\n", lt = "#### Source: Ring\n\nThis source type support Ring cameras with [two way audio](#two-way-audio) support. If you have a `refresh_token` and `device_id` - you can use it in `go2rtc.yaml` config file. Otherwise, you can use the go2rtc interface and add your ring account (WebUI > Add > Ring). Once added, it will list all your Ring cameras.\n\n```yaml\nstreams:\n ring: ring:?device_id=XXX&refresh_token=XXX\n ring_snapshot: ring:?device_id=XXX&refresh_token=XXX&snapshot\n```\n\n_Source: [Go2Rtc Ring](https://github.com/seydx/go2rtc#source-ring)_\n", ut = "#### Source: Roborock\n\nThis source type support Roborock vacuums with cameras. Known working models:\n\n- Roborock S6 MaxV - only video (the vacuum has no microphone)\n- Roborock S7 MaxV - video and two way audio\n- Roborock Qrevo MaxV - video and two way audio\n\nSource support load Roborock credentials from Home Assistant [custom integration](https://github.com/humbertogontijo/homeassistant-roborock) or the [core integration](https://www.home-assistant.io/integrations/roborock). Otherwise, you need to log in to your Roborock account (MiHome account is not supported). Go to: go2rtc WebUI > Add webpage. Copy `roborock://...` source for your vacuum and paste it to `go2rtc.yaml` config.\n\nIf you have graphic pin for your vacuum - add it as numeric pin (lines: 123, 456, 789) to the end of the roborock-link.\n\n_Source: [Go2Rtc Roborock](https://github.com/seydx/go2rtc#source-roborock)_\n", dt = "#### Source: RTMP\n\nYou can get stream from RTMP server, for example [Nginx with nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module).\n\n```yaml\nstreams:\n rtmp_stream: rtmp://192.168.1.123/live/camera1\n```\n\n_Source: [Go2Rtc RTMP](https://github.com/seydx/go2rtc#source-rtmp)_\n", ft = "#### Source: RTSP\n\n```yaml\nstreams:\n sonoff_camera: rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0\n dahua_camera:\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=1\n amcrest_doorbell:\n - rtsp://username:password@192.168.1.123:554/cam/realmonitor?channel=1&subtype=0#backchannel=0\n unifi_camera: rtspx://192.168.1.123:7441/fD6ouM72bWoFijxK\n glichy_camera: ffmpeg:rtsp://username:password@192.168.1.123/live/ch00_1\n```\n\n**Recommendations**\n\n- **Amcrest Doorbell** users may want to disable two way audio, because with an active stream you won't have a call button working. You need to add `#backchannel=0` to the end of your RTSP link in YAML config file\n- **Dahua Doorbell** users may want to change backchannel [audio codec](https://github.com/AlexxIT/go2rtc/issues/52)\n- **Reolink** users may want NOT to use RTSP protocol at all, some camera models have a very awful unusable stream implementation\n- **Ubiquiti UniFi** users may want to disable HTTPS verification. Use `rtspx://` prefix instead of `rtsps://`. And don't use `?enableSrtp` [suffix](https://github.com/AlexxIT/go2rtc/issues/81)\n- **TP-Link Tapo** users may skip login and password, because go2rtc support login [without them](https://drmnsamoliu.github.io/video.html)\n- If your camera has two RTSP links - you can add both of them as sources. This is useful when streams has different codecs, as example AAC audio with main stream and PCMU/PCMA audio with second stream\n- If the stream from your camera is glitchy, try using [ffmpeg source](#source-ffmpeg). It will not add CPU load if you won't use transcoding\n- If the stream from your camera is very glitchy, try to use transcoding with [ffmpeg source](#source-ffmpeg)\n\n**Other options**\n\nFormat: `rtsp...#{param1}#{param2}#{param3}`\n\n- Ignore audio - `#media=video` or ignore video - `#media=audio`\n- Ignore two way audio API `#backchannel=0` - important for some glitchy cameras\n- Use WebSocket transport `#transport=ws...`\n\n**RTSP over WebSocket**\n\n```yaml\nstreams:\n # WebSocket with authorization, RTSP - without\n axis-rtsp-ws: rtsp://192.168.1.123:4567/axis-media/media.amp?overview=0&camera=1&resolution=1280x720&videoframeskipmode=empty&Axis-Orig-Sw=true#transport=ws://user:pass@192.168.1.123:4567/rtsp-over-websocket\n # WebSocket without authorization, RTSP - with\n dahua-rtsp-ws: rtsp://user:pass@192.168.1.123/cam/realmonitor?channel=1&subtype=1&proto=Private3#transport=ws://192.168.1.123/rtspoverwebsocket\n```\n\n_Source: [Go2Rtc RTSP](https://github.com/seydx/go2rtc#source-rtsp)_\n", pt = "#### Source: Tapo\n\n[TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support.\n\n- stream quality is the same as [RTSP protocol](https://www.tapo.com/en/faq/34/)\n- use the **cloud password**, this is not the RTSP password! you do not need to add a login!\n- you can also use UPPERCASE MD5 hash from your cloud password with `admin` username\n- some new camera firmwares requires SHA256 instead of MD5\n\n```yaml\nstreams:\n # cloud password without username\n camera1: tapo://cloud-password@192.168.1.123\n # admin username and UPPERCASE MD5 cloud-password hash\n camera2: tapo://admin:UPPERCASE-MD5@192.168.1.123\n # admin username and UPPERCASE SHA256 cloud-password hash\n camera3: tapo://admin:UPPERCASE-SHA256@192.168.1.123\n```\n\n```bash\necho -n \"cloud password\" | md5 | awk '{print toupper($0)}'\necho -n \"cloud password\" | shasum -a 256 | awk '{print toupper($0)}'\n```\n\n_Source: [Go2Rtc Tapo](https://github.com/seydx/go2rtc#source-tapo)_\n", mt = "#### Source: Tuya\n\n[Tuya](https://www.tuya.com/) proprietary camera protocol with **two way audio** support. Go2rtc supports `Tuya Smart API` and `Tuya Cloud API`.\n\n**Tuya Smart API (recommended)**:\n\n- Cameras can be discovered through the go2rtc web interface via Tuya Smart account (Add > Tuya > Select region and fill in email and password > Login).\n- **Smart Life accounts are not supported**, you need to create a Tuya Smart account. If the cameras are already added to the Smart Life app, you need to remove them and add them again to the Tuya Smart app.\n\n**Tuya Cloud API**:\n\n- Requires setting up a cloud project in the Tuya Developer Platform.\n- Obtain `device_id`, `client_id`, `client_secret`, and `uid` from [Tuya IoT Platform](https://iot.tuya.com/). [Here's a guide](https://xzetsubou.github.io/hass-localtuya/cloud_api/).\n- Please ensure that you have subscribed to the `IoT Video Live Stream` service (Free Trial) in the Tuya Developer Platform, otherwise the stream will not work (Tuya Developer Platform > Service API > Authorize > IoT Video Live Stream).\n\n**Configuring the stream:**\n\n- Use `resolution` parameter to select the stream (not all cameras support `hd` stream through WebRTC even if the camera has it):\n - `hd` - HD stream (default)\n - `sd` - SD stream\n\n```yaml\nstreams:\n # Tuya Smart API: WebRTC main stream (use Add > Tuya to discover the URL)\n tuya_main:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX\n\n # Tuya Smart API: WebRTC sub stream (use Add > Tuya to discover the URL)\n tuya_sub:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX&resolution=sd\n\n # Tuya Cloud API: WebRTC main stream\n tuya_webrtc:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX\n\n # Tuya Cloud API: WebRTC sub stream\n tuya_webrtc_sd:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX&resolution=sd\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-tuya)_\n", ht = "#### Source: WebRTC\n\nThis source type support four connection formats.\n\n**whep**\n\n[WebRTC/WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/) - is replaced by [WebRTC/WISH](https://datatracker.ietf.org/doc/charter-ietf-wish/02/) standard for WebRTC video/audio viewers. But it may already be supported in some third-party software. It is supported in go2rtc.\n\n**go2rtc**\n\nThis format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio.\n\n**openipc**\n\nSupport connection to [OpenIPC](https://openipc.org/) cameras.\n\n**wyze**\n\nSupports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials.\n\n**kinesis**\n\nSupports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer).\n\n```yaml\nstreams:\n webrtc-whep: webrtc:http://192.168.1.123:1984/api/webrtc?src=camera1\n webrtc-go2rtc: webrtc:ws://192.168.1.123:1984/api/ws?src=camera1\n webrtc-openipc: webrtc:ws://192.168.1.123/webrtc_ws#format=openipc#ice_servers=[{\"urls\":\"stun:stun.kinesisvideo.eu-north-1.amazonaws.com:443\"}]\n webrtc-wyze: webrtc:http://192.168.1.123:5000/signaling/camera1?kvs#format=wyze\n webrtc-kinesis: webrtc:wss://...amazonaws.com/?...#format=kinesis#client_id=...#ice_servers=[{...},{...}]\n```\n\n**PS.** For `kinesis` sources you can use [echo](#source-echo) to get connection params using `bash`/`python` or any other script language.\n\n_Source: [Go2Rtc WebRTC](https://github.com/seydx/go2rtc#source-webrtc)_\n", gt = "#### Source: WebTorrent\n\nThis source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol.\n\n```yaml\nstreams:\n webtorrent1: webtorrent:?share=huofssuxaty00izc&pwd=k3l2j9djeg8v8r7e\n```\n\n_Source: [Go2Rtc Webtorrent](https://github.com/seydx/go2rtc#source-webtorrent)_\n", _t = "#### Source: Wyze\n\nThis source allows you to stream from [Wyze](https://wyze.com/) cameras using native P2P protocol without the Wyze app or SDK.\n\n**Important:**\n\n1. **Requires Wyze account**. You need to login once via the WebUI to load your cameras.\n2. **Requires firmware with DTLS**. Only cameras with DTLS-enabled firmware are supported.\n3. Internet access is only needed when loading cameras from your account. After that, all streaming is local P2P.\n4. Connection to the camera is local only (direct P2P to camera IP).\n\n**Features:**\n\n- H.264 and H.265 video codec support\n- AAC, G.711, PCM, and Opus audio codec support\n- Two-way audio (intercom) support\n- Resolution switching (HD/SD)\n\n## Setup\n\n1. Get your API Key from [Wyze Developer Portal](https://support.wyze.com/hc/en-us/articles/16129834216731)\n2. Go to go2rtc WebUI > Add > Wyze\n3. Enter your API ID, API Key, email, and password\n4. Select cameras to add - stream URLs are generated automatically\n\n**Example Config**\n\n```yaml\nwyze:\n user@email.com:\n api_id: 'your-api-id'\n api_key: 'your-api-key'\n password: 'yourpassword' # or MD5 triple-hash with \"md5:\" prefix\n\nstreams:\n wyze_cam: wyze://192.168.1.123?uid=WYZEUID1234567890AB&enr=xxx&mac=AABBCCDDEEFF&model=HL_CAM4&dtls=true\n```\n\n## Stream URL Format\n\nThe stream URL is automatically generated when you add cameras via the WebUI:\n\n```\nwyze://[IP]?uid=[P2P_ID]&enr=[ENR]&mac=[MAC]&model=[MODEL]&subtype=[hd|sd]&dtls=true\n```\n\n| Parameter | Description |\n| --------- | ----------------------------------------------- |\n| `IP` | Camera's local IP address |\n| `uid` | P2P identifier (20 chars) |\n| `enr` | Encryption key for DTLS |\n| `mac` | Device MAC address |\n| `model` | Camera model (e.g., HL_CAM4) |\n| `dtls` | Enable DTLS encryption (default: true) |\n| `subtype` | Camera resolution: `hd` or `sd` (default: `hd`) |\n\n## Configuration\n\n### Resolution\n\nYou can change the camera's resolution using the `subtype` parameter:\n\n```yaml\nstreams:\n wyze_hd: wyze://...&subtype=hd\n wyze_sd: wyze://...&subtype=sd\n```\n\n### Two-Way Audio\n\nTwo-way audio (intercom) is supported automatically. When a consumer sends audio to the stream, it will be transmitted to the camera's speaker.\n", vt = "#### Source: Xiaomi\n\nThis source allows you to view cameras from the [Xiaomi Mi Home](https://home.mi.com/) ecosystem.\n\n**Important:**\n\n1. **Not all cameras are supported**. There are several P2P protocol vendors in the Xiaomi ecosystem.\n Currently, the **CS2** vendor is supported. However, the **TUTK** vendor is not supported.\n2. Each time you connect to the camera, you need internet access to obtain encryption keys.\n3. Connection to the camera is local only.\n\n**Features:**\n\n- Multiple Xiaomi accounts supported\n- Cameras from multiple regions are supported for a single account\n- Two-way audio is supported\n- Cameras with multiple lenses are supported\n\n## Setup\n\n1. Goto go2rtc WebUI > Add > Xiaomi > Login with username and password\n2. Receive verification code by email or phone if required.\n3. Complete the captcha if required.\n4. If everything is OK, your account will be added and you can load cameras from it.\n\n**Example**\n\n```yaml\nxiaomi:\n 1234567890: V1:***\n\nstreams:\n xiaomi1: xiaomi://1234567890:cn@192.168.1.123?did=9876543210&model=isa.camera.hlc7\n```\n\n## Configuration\n\nYou can change camera's quality: `subtype=hd/sd/auto`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&subtype=sd\n```\n\nYou can use second channel for Dual cameras: `channel=1`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&channel=1\n```\n", yt = "# Yandex\n\nSource for receiving stream from new [Yandex IP camera](https://alice.yandex.ru/smart-home/security/ipcamera).\n\n## Get Yandex token\n\n1. Install HomeAssistant integration [YandexStation](https://github.com/AlexxIT/YandexStation).\n2. Copy token from HomeAssistant config folder: `/config/.storage/core.config_entries`, key: `\"x_token\"`.\n\n## Get device ID\n\n1. Open this link in any browser: https://iot.quasar.yandex.ru/m/v3/user/devices\n2. Copy ID of your camera, key: `\"id\"`.\n\n## Config examples\n\n```yaml\nstreams:\n yandex_stream: yandex:?x_token=XXXX&device_id=XXXX\n yandex_snapshot: yandex:?x_token=XXXX&device_id=XXXX&snapshot\n yandex_snapshot_custom_size: yandex:?x_token=XXXX&device_id=XXXX&snapshot=h=540\n```\n\n_Source: [Go2Rtc Yandex](https://github.com/AlexxIT/go2rtc/tree/master/internal/yandex)_\n", bt = [
38
+ render: He
39
+ }), We = "#### Source: Bubble\n\nOther names: [ESeeCloud](http://www.eseecloud.com/), [dvr163](http://help.dvr163.com/).\n\n- you can skip `username`, `password`, `port`, `ch` and `stream` if they are default\n- setup separate streams for different channels and streams\n\n```yaml\nstreams:\n camera1: bubble://username:password@192.168.1.123:34567/bubble/live?ch=0&stream=0\n```\n\n_Source: [Go2Rtc Bubble](https://github.com/seydx/go2rtc#source-bubble)_\n", Ge = "#### Source: CUI\n\nThis source can be used to stream dynamically generated, go2rtc compatible, URLs. The source is just a placeholder for a `https://` URL.\n\n```yaml\nstreams:\n camera1: cui://192.168.1.123:34567/some-identifier-if-you-want\n```\n\nThe URL will be changed to `https://192.168.1.123:34567/some-identifier-if-you-want` and the response must be like this:\n\n```json\n{\n {\n \"streamUrl\": \"rtsp://192.168.1.1:554/stream\",\n }\n}\n```\n\nGo2rtc will then use the `streamUrl` to stream the video. The `streamUrl` can be any URL that is compatible with go2rtc. The response must be a valid JSON object with the `streamUrl` key.\n", Ke = "#### Source: Doorbird\n\n[Doorbird](https://www.doorbird.com/) proprietary camera protocol with **two way audio** support.\n\n```yaml\nstreams:\n video-audio:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n two-way:\n - rtsp://user:pass@123.123.123.123:554/mpeg/media.amp\n - doorbird://user:pass@123.123.123.123?media=audio\n - doorbird://user:pass@123.123.123.123\n mjpeg-video:\n - doorbird://user:pass@123.123.123.123?media=video\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-doorbird)_\n", qe = "#### Source: DVRIP\n\nOther names: DVR-IP, NetSurveillance, Sofia protocol (NETsurveillance ActiveX plugin XMeye SDK).\n\n- you can skip `username`, `password`, `port`, `channel` and `subtype` if they are default\n- setup separate streams for different channels\n- use `subtype=0` for Main stream, and `subtype=1` for Extra1 stream\n- only the TCP protocol is supported\n\n```yaml\nstreams:\n only_stream: dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n only_tts: dvrip://username:password@192.168.1.123:34567?backchannel=1\n two_way_audio:\n - dvrip://username:password@192.168.1.123:34567?channel=0&subtype=0\n - dvrip://username:password@192.168.1.123:34567?backchannel=1\n```\n\n_Source: [Go2Rtc DVRIP](https://github.com/seydx/go2rtc#source-dvrip)_\n", Je = "#### Source: Echo\n\nSome sources may have a dynamic link. And you will need to get it using a bash or python script. Your script should echo a link to the source. RTSP, FFmpeg or any of the [supported sources](https://github.com/seydx/go2rtc#module-streams).\n\n**Docker** and **Hass Add-on** users has preinstalled `python3`, `curl`, `jq`.\nCheck examples in [wiki](https://github.com/seydx/go2rtc/wiki/Source-Echo-examples).\n\n```yaml\nstreams:\n apple_hls: echo:python3 hls.py https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\n```\n\n_Source: [Go2Rtc Echo](https://github.com/seydx/go2rtc#source-echo)_\n", Ye = "#### Source: Exec\n\nExec source can run any external application and expect data from it. Two transports are supported - **pipe** and **RTSP**.\n\nIf you want to use **RTSP** transport - the command must contain the `{output}` argument in any place. On launch, it will be replaced by the local address of the RTSP server.\n\n**pipe** reads data from app stdout in different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**. Also pipe can write data to app stdin in two formats: **PCMA** and **PCM/48000**.\n\nThe source can be used with:\n\n- [FFmpeg](https://ffmpeg.org/) - go2rtc ffmpeg source just a shortcut to exec source\n- [FFplay](https://ffmpeg.org/ffplay.html) - play audio on your server\n- [GStreamer](https://gstreamer.freedesktop.org/)\n- [Raspberry Pi Cameras](https://www.raspberrypi.com/documentation/computers/camera_software.html)\n- any your own software\n\n```yaml\nstreams:\n stream: exec:ffmpeg -re -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {output}\n picam_h264: exec:libcamera-vid -t 0 --inline -o -\n picam_mjpeg: exec:libcamera-vid -t 0 --codec mjpeg -o -\n pi5cam_h264: exec:libcamera-vid -t 0 --libav-format h264 -o -\n canon: exec:gphoto2 --capture-movie --stdout#killsignal=2#killtimeout=5\n play_pcma: exec:ffplay -fflags nobuffer -f alaw -ar 8000 -i -#backchannel=1\n play_pcm48k: exec:ffplay -fflags nobuffer -f s16be -ar 48000 -i -#backchannel=1\n```\n\n_Source: [Go2Rtc Exec](https://github.com/seydx/go2rtc#source-exec)_\n", Xe = "#### Source: Expr\n\n[Expr](https://github.com/antonmedv/expr) - expression language and expression evaluation for Go.\n\n- [language definition](https://expr.medv.io/docs/Language-Definition) - takes best from JS, Python, Jinja2 syntax\n- your expression should return a link of any supported source\n- expression supports multiple operation, but:\n - all operations must be separated by a semicolon\n - all operations, except the last one, must declare a new variable (`let s = \"abc\";`)\n - the last operation should return a string\n- go2rtc supports additional functions:\n - `fetch` - JS-like HTTP requests\n - `match` - JS-like RegExp queries\n\n## Examples\n\n**Two way audio for Dahua VTO**\n\n```yaml\nstreams:\n dahua_vto: |\n expr: let host = \"admin:password@192.168.1.123\";\n fetch(\"http://\"+host+\"/cgi-bin/configManager.cgi?action=setConfig&Encode[0].MainFormat[0].Audio.Compression=G.711A&Encode[0].MainFormat[0].Audio.Frequency=8000\").ok\n ? \"rtsp://\"+host+\"/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\" : \"\"\n```\n\n**dom.ru**\n\nYou can get credentials via:\n\n- https://github.com/alexmorbo/domru (file `/share/domru/accounts`)\n- https://github.com/ad/domru\n\n```yaml\nstreams:\n dom_ru: |\n expr: let camera = \"99999999\"; let token = \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"; let operator = 99;\n fetch(\"https://myhome.novotelecom.ru/rest/v1/forpost/cameras/\"+camera+\"/video\", {\n headers: {Authorization: \"Bearer \"+token, Operator: operator}\n }).json().data.URL\n```\n\n**Parse HLS files from Apple**\n\nSame example in two languages - python and expr.\n\n```yaml\nstreams:\n example_python: |\n echo:python -c 'from urllib.request import urlopen; import re\n\n # url1 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8\"\n html1 = urlopen(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").read().decode(\"utf-8\")\n url1 = re.search(r\"https.+?m3u8\", html1)[0]\n\n # url2 = \"gear1/prog_index.m3u8\"\n html2 = urlopen(url1).read().decode(\"utf-8\")\n url2 = re.search(r\"^[a-z0-1/_]+\\.m3u8$\", html2, flags=re.MULTILINE)[0]\n\n # url3 = \"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear1/prog_index.m3u8\"\n url3 = url1[:url1.rindex(\"/\")+1] + url2\n\n print(\"ffmpeg:\" + url3 + \"#video=copy\")'\n\n example_expr: |\n expr:\n\n let html1 = fetch(\"https://developer.apple.com/streaming/examples/basic-stream-osx-ios5.html\").text;\n let url1 = match(html1, \"https.+?m3u8\")[0];\n\n let html2 = fetch(url1).text;\n let url2 = match(html2, \"^[a-z0-1/_]+\\\\.m3u8$\", \"m\")[0];\n\n let url3 = url1[:lastIndexOf(url1, \"/\")+1] + url2;\n\n \"ffmpeg:\" + url3 + \"#video=copy\"\n```\n\n## Comparsion\n\n| expr | python | js |\n| ---------------------------- | -------------------------- | ------------------------------ |\n| let x = 1; | x = 1 | let x = 1 |\n| {a: 1, b: 2} | {\"a\": 1, \"b\": 2} | {a: 1, b: 2} |\n| let r = fetch(url, {method}) | r = request(method, url) | r = await fetch(url, {method}) |\n| r.ok | r.ok | r.ok |\n| r.status | r.status_code | r.status |\n| r.text | r.text | await r.text() |\n| r.json() | r.json() | await r.json() |\n| r.headers | r.headers | r.headers |\n| let m = match(text, \"abc\") | m = re.search(\"abc\", text) | let m = text.match(/abc/) |\n\n_Source: [Go2Rtc Expr](https://github.com/seydx/go2rtc#source-expr)_\n", Ze = "#### Source: FFmpeg\n\nYou can get any stream or file or device via FFmpeg and push it to go2rtc. The app will automatically start FFmpeg with the proper arguments when someone starts watching the stream.\n\n- FFmpeg preistalled for **Docker** and **Hass Add-on** users\n- **Hass Add-on** users can target files from [/media](https://www.home-assistant.io/more-info/local-media/setup-media/) folder\n\nFormat: `ffmpeg:{input}#{param1}#{param2}#{param3}`. Examples:\n\n```yaml\nstreams:\n # [FILE] all tracks will be copied without transcoding codecs\n file1: ffmpeg:/media/BigBuckBunny.mp4\n\n # [FILE] video will be transcoded to H264, audio will be skipped\n file2: ffmpeg:/media/BigBuckBunny.mp4#video=h264\n\n # [FILE] video will be copied, audio will be transcoded to pcmu\n file3: ffmpeg:/media/BigBuckBunny.mp4#video=copy#audio=pcmu\n\n # [HLS] video will be copied, audio will be skipped\n hls: ffmpeg:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/gear5/prog_index.m3u8#video=copy\n\n # [MJPEG] video will be transcoded to H264\n mjpeg: ffmpeg:http://185.97.122.128/cgi-bin/faststream.jpg#video=h264\n\n # [RTSP] video with rotation, should be transcoded, so select H264\n rotate: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#rotate=90\n```\n\nAll trascoding formats has [built-in templates](https://github.com/seydx/go2rtc/blob/master/internal/ffmpeg/ffmpeg.go): `h264`, `h265`, `opus`, `pcmu`, `pcmu/16000`, `pcmu/48000`, `pcma`, `pcma/16000`, `pcma/48000`, `aac`, `aac/16000`.\n\nBut you can override them via YAML config. You can also add your own formats to config and use them with source params.\n\n```yaml\nffmpeg:\n bin: ffmpeg # path to ffmpeg binary\n h264: '-codec:v libx264 -g:v 30 -preset:v superfast -tune:v zerolatency -profile:v main -level:v 4.1'\n mycodec: '-any args that supported by ffmpeg...'\n myinput: '-fflags nobuffer -flags low_delay -timeout 5000000 -i {input}'\n myraw: '-ss 00:00:20'\n```\n\n- You can use go2rtc stream name as ffmpeg input (ex. `ffmpeg:camera1#video=h264`)\n- You can use `video` and `audio` params multiple times (ex. `#video=copy#audio=copy#audio=pcmu`)\n- You can use `rotate` param with `90`, `180`, `270` or `-90` values, important with transcoding (ex. `#video=h264#rotate=90`)\n- You can use `width` and/or `height` params, important with transcoding (ex. `#video=h264#width=1280`)\n- You can use `drawtext` to add a timestamp (ex. `drawtext=x=2:y=2:fontsize=12:fontcolor=white:box=1:boxcolor=black`)\n - This will greatly increase the CPU of the server, even with hardware acceleration\n- You can use `raw` param for any additional FFmpeg arguments (ex. `#raw=-vf transpose=1`)\n- You can use `input` param to override default input template (ex. `#input=rtsp/udp` will change RTSP transport from TCP to UDP+TCP)\n - You can use raw input value (ex. `#input=-timeout 5000000 -i {input}`)\n - You can add your own input templates\n\nRead more about [hardware acceleration](https://github.com/seydx/go2rtc/wiki/Hardware-acceleration).\n\n**PS.** It is recommended to check the available hardware in the WebUI add page.\n\n<hr>\n\n#### Source: FFmpeg Device\n\nYou can get video from any USB-camera or Webcam as RTSP or WebRTC stream. This is part of FFmpeg integration.\n\n- check available devices in Web interface\n- `video_size` and `framerate` must be supported by your camera!\n- for Linux supported only video for now\n- for macOS you can stream Facetime camera or whole Desktop!\n- for macOS important to set right framerate\n\nFormat: `ffmpeg:device?{input-params}#{param1}#{param2}#{param3}`\n\n```yaml\nstreams:\n linux_usbcam: ffmpeg:device?video=0&video_size=1280x720#video=h264\n windows_webcam: ffmpeg:device?video=0#video=h264\n macos_facetime: ffmpeg:device?video=0&audio=1&video_size=1280x720&framerate=30#video=h264#audio=pcma\n```\n\n**PS.** It is recommended to check the available devices in the WebUI add page.\n\n_Source: [Go2Rtc FFmpeg](https://github.com/seydx/go2rtc#source-ffmpeg) & [Go2Rtc FFmpeg Device](https://github.com/seydx/go2rtc#source-ffmpeg-device)_\n", Qe = "#### Source: GoPro\n\nSupported models: HERO9, HERO10, HERO11, HERO12. \nSupported OS: Linux, Mac, Windows, [HassOS](https://www.home-assistant.io/installation/)\n\nThe other camera models have different APIs. I will try to add them in the next versions.\n\n## Config\n\n- USB-connected cameras create a new network interface in the system\n- Linux users do not need to install anything\n- Windows users should install the [network driver](https://community.gopro.com/s/article/GoPro-Webcam)\n- if the camera is detected but the stream does not start - you need to disable firewall\n\n1. Discover camera address: WebUI > Add > GoPro\n2. Add camera to config\n\n```yaml\nstreams:\n hero12: gopro://172.20.100.51\n```\n\n## Useful links\n\n- https://gopro.github.io/OpenGoPro/\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", $e = "#### Source: Hass\n\nSupport import camera links from [Home Assistant](https://www.home-assistant.io/) config files:\n\n- [Generic Camera](https://www.home-assistant.io/integrations/generic/), setup via GUI\n- [HomeKit Camera](https://www.home-assistant.io/integrations/homekit_controller/)\n- [ONVIF](https://www.home-assistant.io/integrations/onvif/)\n- [Roborock](https://github.com/humbertogontijo/homeassistant-roborock) vacuums with camera\n\n```yaml\nhass:\n config: '/config' # skip this setting if you Hass Add-on user\n\nstreams:\n generic_camera: hass:Camera1 # Settings > Integrations > Integration Name\n aqara_g3: hass:Camera-Hub-G3-AB12\n```\n\n**WebRTC Cameras**\n\nAny cameras in WebRTC format are supported. But at the moment Home Assistant only supports some [Nest](https://www.home-assistant.io/integrations/nest/) cameras in this fomat.\n\nThe Nest API only allows you to get a link to a stream for 5 minutes. So every 5 minutes the stream will be reconnected.\n\n```yaml\nstreams:\n # link to Home Assistant Supervised\n hass-webrtc1: hass://supervisor?entity_id=camera.nest_doorbell\n # link to external Hass with Long-Lived Access Tokens\n hass-webrtc2: hass://192.168.1.123:8123?entity_id=camera.nest_doorbell&token=eyXYZ...\n```\n\n_Source: [Go2Rtc Hass](https://github.com/seydx/go2rtc#source-hass)_\n", et = "#### Source: HomeKit\n\n**Important:**\n\n- You can use HomeKit Cameras **without Apple devices** (iPhone, iPad, etc.), it's just a yet another protocol\n- HomeKit device can be paired with only one ecosystem. So, if you have paired it to an iPhone (Apple Home) - you can't pair it with Home Assistant or go2rtc. Or if you have paired it to go2rtc - you can't pair it with iPhone\n- HomeKit device should be in same network with working [mDNS](https://en.wikipedia.org/wiki/Multicast_DNS) between device and go2rtc\n\ngo2rtc support import paired HomeKit devices from [Home Assistant](#source-hass). So you can use HomeKit camera with Hass and go2rtc simultaneously. If you using Hass, I recommend pairing devices with it, it will give you more options.\n\nYou can pair device with go2rtc on the HomeKit page. If you can't see your devices - reload the page. Also try reboot your HomeKit device (power off). If you still can't see it - you have a problems with mDNS.\n\nIf you see a device but it does not have a pair button - it is paired to some ecosystem (Apple Home, Home Assistant etc). You need to delete device from that ecosystem, and it will be available for pairing. If you cannot unpair device, you will have to reset it.\n\n**Important:**\n\n- HomeKit audio uses very non-standard **AAC-ELD** codec with very non-standard params and specification violation\n- Audio can't be played in `VLC` and probably any other player\n- Audio should be transcoded for using with MSE, WebRTC, etc.\n\nRecommended settings for using HomeKit Camera with WebRTC, MSE, MP4, RTSP:\n\n```\nstreams:\n aqara_g3:\n - hass:Camera-Hub-G3-AB12\n - ffmpeg:aqara_g3#audio=aac#audio=opus\n```\n\nRTSP link with \"normal\" audio for any player: `rtsp://192.168.1.123:8554/aqara_g3?video&audio=aac`\n\n**This source is in active development!** Tested only with [Aqara Camera Hub G3](https://www.aqara.com/eu/product/camera-hub-g3) (both EU and CN versions).\n\n_Source: [Go2Rtc HomeKit](https://github.com/seydx/go2rtc#source-homekit)_\n", tt = "#### Source: HTTP\n\nSupport Content-Type:\n\n- **HTTP-FLV** (`video/x-flv`) - same as RTMP, but over HTTP\n- **HTTP-JPEG** (`image/jpeg`) - camera snapshot link, can be converted by go2rtc to MJPEG stream\n- **HTTP-MJPEG** (`multipart/x`) - simple MJPEG stream over HTTP\n- **MPEG-TS** (`video/mpeg`) - legacy [streaming format](https://en.wikipedia.org/wiki/MPEG_transport_stream)\n\nSource also support HTTP and TCP streams with autodetection for different formats: **MJPEG**, **H.264/H.265 bitstream**, **MPEG-TS**.\n\n```yaml\nstreams:\n # [HTTP-FLV] stream in video/x-flv format\n http_flv: http://192.168.1.123:20880/api/camera/stream/780900131155/657617\n\n # [JPEG] snapshots from Dahua camera, will be converted to MJPEG stream\n dahua_snap: http://admin:password@192.168.1.123/cgi-bin/snapshot.cgi?channel=1\n\n # [MJPEG] stream will be proxied without modification\n http_mjpeg: https://mjpeg.sanford.io/count.mjpeg\n\n # [MJPEG or H.264/H.265 bitstream or MPEG-TS]\n tcp_magic: tcp://192.168.1.123:12345\n\n # Add custom header\n custom_header: 'https://mjpeg.sanford.io/count.mjpeg#header=Authorization: Bearer XXX'\n```\n\n**PS.** Dahua camera has bug: if you select MJPEG codec for RTSP second stream - snapshot won't work.\n\n_Source: [Go2Rtc Http](https://github.com/seydx/go2rtc#source-http)_\n", nt = "#### Source: ISAPI\n\nThis source type support only backchannel audio for Hikvision ISAPI protocol. So it should be used as second source in addition to the RTSP protocol.\n\n```yaml\nstreams:\n hikvision1:\n - rtsp://admin:password@192.168.1.123:554/Streaming/Channels/101\n - isapi://admin:password@192.168.1.123:80/\n```\n\n_Source: [Go2Rtc Isapi](https://github.com/seydx/go2rtc#source-isapi)_\n", rt = "#### Source: Ivideon\n\nSupport public cameras from service [Ivideon](https://tv.ivideon.com/).\n\n```yaml\nstreams:\n quailcam: ivideon:100-tu5dkUPct39cTp9oNEN2B6/0\n```\n\n_Source: [Go2Rtc Ivideon](https://github.com/seydx/go2rtc#source-ivideon)_\n", it = "#### Source: Kasa\n\n[TP-Link Kasa](https://www.kasasmart.com/) non-standard protocol [more info](https://medium.com/@hu3vjeen/reverse-engineering-tp-link-kc100-bac4641bf1cd).\n\n- `username` - urlsafe email, `alex@gmail.com` -> `alex%40gmail.com`\n- `password` - base64password, `secret1` -> `c2VjcmV0MQ==`\n\n```yaml\nstreams:\n kc401: kasa://username:password@192.168.1.123:19443/https/stream/mixed\n```\n\nTested: KD110, KC200, KC401, KC420WS, EC71.\n\n_Source: [Go2Rtc Kasa](https://github.com/seydx/go2rtc#source-kasa)_\n", at = "#### Source: Nest\n\nCurrently only WebRTC cameras are supported.\n\nFor simplicity, it is recommended to connect the Nest/WebRTC camera to the [Home Assistant](#source-hass). But if you can somehow get the below parameters - Nest/WebRTC source will work without Hass.\n\n```yaml\nstreams:\n nest-doorbell: nest:?client_id=***&client_secret=***&refresh_token=***&project_id=***&device_id=***\n```\n\n_Source: [Go2Rtc Nest](https://github.com/seydx/go2rtc#source-nest)_\n", ot = "#### Source: ONVIF\n\nThe source is not very useful if you already know RTSP and snapshot links for your camera. But it can be useful if you don't.\n\n**WebUI > Add** webpage support ONVIF autodiscovery. Your server must be on the same subnet as the camera. If you use docker, you must use \"network host\".\n\n```yaml\nstreams:\n dahua1: onvif://admin:password@192.168.1.123\n reolink1: onvif://admin:password@192.168.1.123:8000\n tapo1: onvif://admin:password@192.168.1.123:2020\n```\n\n_Source: [Go2Rtc Onvif](https://github.com/seydx/go2rtc#source-onvif)_\n", st = "#### Source: Ring\n\nThis source type support Ring cameras with [two way audio](#two-way-audio) support. If you have a `refresh_token` and `device_id` - you can use it in `go2rtc.yaml` config file. Otherwise, you can use the go2rtc interface and add your ring account (WebUI > Add > Ring). Once added, it will list all your Ring cameras.\n\n```yaml\nstreams:\n ring: ring:?device_id=XXX&refresh_token=XXX\n ring_snapshot: ring:?device_id=XXX&refresh_token=XXX&snapshot\n```\n\n_Source: [Go2Rtc Ring](https://github.com/seydx/go2rtc#source-ring)_\n", ct = "#### Source: Roborock\n\nThis source type support Roborock vacuums with cameras. Known working models:\n\n- Roborock S6 MaxV - only video (the vacuum has no microphone)\n- Roborock S7 MaxV - video and two way audio\n- Roborock Qrevo MaxV - video and two way audio\n\nSource support load Roborock credentials from Home Assistant [custom integration](https://github.com/humbertogontijo/homeassistant-roborock) or the [core integration](https://www.home-assistant.io/integrations/roborock). Otherwise, you need to log in to your Roborock account (MiHome account is not supported). Go to: go2rtc WebUI > Add webpage. Copy `roborock://...` source for your vacuum and paste it to `go2rtc.yaml` config.\n\nIf you have graphic pin for your vacuum - add it as numeric pin (lines: 123, 456, 789) to the end of the roborock-link.\n\n_Source: [Go2Rtc Roborock](https://github.com/seydx/go2rtc#source-roborock)_\n", lt = "#### Source: RTMP\n\nYou can get stream from RTMP server, for example [Nginx with nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module).\n\n```yaml\nstreams:\n rtmp_stream: rtmp://192.168.1.123/live/camera1\n```\n\n_Source: [Go2Rtc RTMP](https://github.com/seydx/go2rtc#source-rtmp)_\n", ut = "#### Source: RTSP\n\n```yaml\nstreams:\n sonoff_camera: rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0\n dahua_camera:\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif\n - rtsp://admin:password@192.168.1.123/cam/realmonitor?channel=1&subtype=1\n amcrest_doorbell:\n - rtsp://username:password@192.168.1.123:554/cam/realmonitor?channel=1&subtype=0#backchannel=0\n unifi_camera: rtspx://192.168.1.123:7441/fD6ouM72bWoFijxK\n glichy_camera: ffmpeg:rtsp://username:password@192.168.1.123/live/ch00_1\n```\n\n**Recommendations**\n\n- **Amcrest Doorbell** users may want to disable two way audio, because with an active stream you won't have a call button working. You need to add `#backchannel=0` to the end of your RTSP link in YAML config file\n- **Dahua Doorbell** users may want to change backchannel [audio codec](https://github.com/AlexxIT/go2rtc/issues/52)\n- **Reolink** users may want NOT to use RTSP protocol at all, some camera models have a very awful unusable stream implementation\n- **Ubiquiti UniFi** users may want to disable HTTPS verification. Use `rtspx://` prefix instead of `rtsps://`. And don't use `?enableSrtp` [suffix](https://github.com/AlexxIT/go2rtc/issues/81)\n- **TP-Link Tapo** users may skip login and password, because go2rtc support login [without them](https://drmnsamoliu.github.io/video.html)\n- If your camera has two RTSP links - you can add both of them as sources. This is useful when streams has different codecs, as example AAC audio with main stream and PCMU/PCMA audio with second stream\n- If the stream from your camera is glitchy, try using [ffmpeg source](#source-ffmpeg). It will not add CPU load if you won't use transcoding\n- If the stream from your camera is very glitchy, try to use transcoding with [ffmpeg source](#source-ffmpeg)\n\n**Other options**\n\nFormat: `rtsp...#{param1}#{param2}#{param3}`\n\n- Ignore audio - `#media=video` or ignore video - `#media=audio`\n- Ignore two way audio API `#backchannel=0` - important for some glitchy cameras\n- Use WebSocket transport `#transport=ws...`\n\n**RTSP over WebSocket**\n\n```yaml\nstreams:\n # WebSocket with authorization, RTSP - without\n axis-rtsp-ws: rtsp://192.168.1.123:4567/axis-media/media.amp?overview=0&camera=1&resolution=1280x720&videoframeskipmode=empty&Axis-Orig-Sw=true#transport=ws://user:pass@192.168.1.123:4567/rtsp-over-websocket\n # WebSocket without authorization, RTSP - with\n dahua-rtsp-ws: rtsp://user:pass@192.168.1.123/cam/realmonitor?channel=1&subtype=1&proto=Private3#transport=ws://192.168.1.123/rtspoverwebsocket\n```\n\n_Source: [Go2Rtc RTSP](https://github.com/seydx/go2rtc#source-rtsp)_\n", dt = "#### Source: Tapo\n\n[TP-Link Tapo](https://www.tapo.com/) proprietary camera protocol with **two way audio** support.\n\n- stream quality is the same as [RTSP protocol](https://www.tapo.com/en/faq/34/)\n- use the **cloud password**, this is not the RTSP password! you do not need to add a login!\n- you can also use UPPERCASE MD5 hash from your cloud password with `admin` username\n- some new camera firmwares requires SHA256 instead of MD5\n\n```yaml\nstreams:\n # cloud password without username\n camera1: tapo://cloud-password@192.168.1.123\n # admin username and UPPERCASE MD5 cloud-password hash\n camera2: tapo://admin:UPPERCASE-MD5@192.168.1.123\n # admin username and UPPERCASE SHA256 cloud-password hash\n camera3: tapo://admin:UPPERCASE-SHA256@192.168.1.123\n```\n\n```bash\necho -n \"cloud password\" | md5 | awk '{print toupper($0)}'\necho -n \"cloud password\" | shasum -a 256 | awk '{print toupper($0)}'\n```\n\n_Source: [Go2Rtc Tapo](https://github.com/seydx/go2rtc#source-tapo)_\n", ft = "#### Source: Tuya\n\n[Tuya](https://www.tuya.com/) proprietary camera protocol with **two way audio** support. Go2rtc supports `Tuya Smart API` and `Tuya Cloud API`.\n\n**Tuya Smart API (recommended)**:\n\n- Cameras can be discovered through the go2rtc web interface via Tuya Smart account (Add > Tuya > Select region and fill in email and password > Login).\n- **Smart Life accounts are not supported**, you need to create a Tuya Smart account. If the cameras are already added to the Smart Life app, you need to remove them and add them again to the Tuya Smart app.\n\n**Tuya Cloud API**:\n\n- Requires setting up a cloud project in the Tuya Developer Platform.\n- Obtain `device_id`, `client_id`, `client_secret`, and `uid` from [Tuya IoT Platform](https://iot.tuya.com/). [Here's a guide](https://xzetsubou.github.io/hass-localtuya/cloud_api/).\n- Please ensure that you have subscribed to the `IoT Video Live Stream` service (Free Trial) in the Tuya Developer Platform, otherwise the stream will not work (Tuya Developer Platform > Service API > Authorize > IoT Video Live Stream).\n\n**Configuring the stream:**\n\n- Use `resolution` parameter to select the stream (not all cameras support `hd` stream through WebRTC even if the camera has it):\n - `hd` - HD stream (default)\n - `sd` - SD stream\n\n```yaml\nstreams:\n # Tuya Smart API: WebRTC main stream (use Add > Tuya to discover the URL)\n tuya_main:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX\n\n # Tuya Smart API: WebRTC sub stream (use Add > Tuya to discover the URL)\n tuya_sub:\n - tuya://protect-us.ismartlife.me?device_id=XXX&email=XXX&password=XXX&resolution=sd\n\n # Tuya Cloud API: WebRTC main stream\n tuya_webrtc:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX\n\n # Tuya Cloud API: WebRTC sub stream\n tuya_webrtc_sd:\n - tuya://openapi.tuyaus.com?device_id=XXX&uid=XXX&client_id=XXX&client_secret=XXX&resolution=sd\n```\n\n_Source: [Go2Rtc Tuya](https://github.com/seydx/go2rtc#source-tuya)_\n", pt = "#### Source: WebRTC\n\nThis source type support four connection formats.\n\n**whep**\n\n[WebRTC/WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/) - is replaced by [WebRTC/WISH](https://datatracker.ietf.org/doc/charter-ietf-wish/02/) standard for WebRTC video/audio viewers. But it may already be supported in some third-party software. It is supported in go2rtc.\n\n**go2rtc**\n\nThis format is only supported in go2rtc. Unlike WHEP it supports asynchronous WebRTC connection and two way audio.\n\n**openipc**\n\nSupport connection to [OpenIPC](https://openipc.org/) cameras.\n\n**wyze**\n\nSupports connection to [Wyze](https://www.wyze.com/) cameras, using WebRTC protocol. You can use [docker-wyze-bridge](https://github.com/mrlt8/docker-wyze-bridge) project to get connection credentials.\n\n**kinesis**\n\nSupports [Amazon Kinesis Video Streams](https://aws.amazon.com/kinesis/video-streams/), using WebRTC protocol. You need to specify signalling WebSocket URL with all credentials in query params, `client_id` and `ice_servers` list in [JSON format](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer).\n\n```yaml\nstreams:\n webrtc-whep: webrtc:http://192.168.1.123:1984/api/webrtc?src=camera1\n webrtc-go2rtc: webrtc:ws://192.168.1.123:1984/api/ws?src=camera1\n webrtc-openipc: webrtc:ws://192.168.1.123/webrtc_ws#format=openipc#ice_servers=[{\"urls\":\"stun:stun.kinesisvideo.eu-north-1.amazonaws.com:443\"}]\n webrtc-wyze: webrtc:http://192.168.1.123:5000/signaling/camera1?kvs#format=wyze\n webrtc-kinesis: webrtc:wss://...amazonaws.com/?...#format=kinesis#client_id=...#ice_servers=[{...},{...}]\n```\n\n**PS.** For `kinesis` sources you can use [echo](#source-echo) to get connection params using `bash`/`python` or any other script language.\n\n_Source: [Go2Rtc WebRTC](https://github.com/seydx/go2rtc#source-webrtc)_\n", mt = "#### Source: WebTorrent\n\nThis source can get a stream from another go2rtc via [WebTorrent](#module-webtorrent) protocol.\n\n```yaml\nstreams:\n webtorrent1: webtorrent:?share=huofssuxaty00izc&pwd=k3l2j9djeg8v8r7e\n```\n\n_Source: [Go2Rtc Webtorrent](https://github.com/seydx/go2rtc#source-webtorrent)_\n", ht = "#### Source: Wyze\n\nThis source allows you to stream from [Wyze](https://wyze.com/) cameras using native P2P protocol without the Wyze app or SDK.\n\n**Important:**\n\n1. **Requires Wyze account**. You need to login once via the WebUI to load your cameras.\n2. **Requires firmware with DTLS**. Only cameras with DTLS-enabled firmware are supported.\n3. Internet access is only needed when loading cameras from your account. After that, all streaming is local P2P.\n4. Connection to the camera is local only (direct P2P to camera IP).\n\n**Features:**\n\n- H.264 and H.265 video codec support\n- AAC, G.711, PCM, and Opus audio codec support\n- Two-way audio (intercom) support\n- Resolution switching (HD/SD)\n\n## Setup\n\n1. Get your API Key from [Wyze Developer Portal](https://support.wyze.com/hc/en-us/articles/16129834216731)\n2. Go to go2rtc WebUI > Add > Wyze\n3. Enter your API ID, API Key, email, and password\n4. Select cameras to add - stream URLs are generated automatically\n\n**Example Config**\n\n```yaml\nwyze:\n user@email.com:\n api_id: 'your-api-id'\n api_key: 'your-api-key'\n password: 'yourpassword' # or MD5 triple-hash with \"md5:\" prefix\n\nstreams:\n wyze_cam: wyze://192.168.1.123?uid=WYZEUID1234567890AB&enr=xxx&mac=AABBCCDDEEFF&model=HL_CAM4&dtls=true\n```\n\n## Stream URL Format\n\nThe stream URL is automatically generated when you add cameras via the WebUI:\n\n```\nwyze://[IP]?uid=[P2P_ID]&enr=[ENR]&mac=[MAC]&model=[MODEL]&subtype=[hd|sd]&dtls=true\n```\n\n| Parameter | Description |\n| --------- | ----------------------------------------------- |\n| `IP` | Camera's local IP address |\n| `uid` | P2P identifier (20 chars) |\n| `enr` | Encryption key for DTLS |\n| `mac` | Device MAC address |\n| `model` | Camera model (e.g., HL_CAM4) |\n| `dtls` | Enable DTLS encryption (default: true) |\n| `subtype` | Camera resolution: `hd` or `sd` (default: `hd`) |\n\n## Configuration\n\n### Resolution\n\nYou can change the camera's resolution using the `subtype` parameter:\n\n```yaml\nstreams:\n wyze_hd: wyze://...&subtype=hd\n wyze_sd: wyze://...&subtype=sd\n```\n\n### Two-Way Audio\n\nTwo-way audio (intercom) is supported automatically. When a consumer sends audio to the stream, it will be transmitted to the camera's speaker.\n", gt = "#### Source: Xiaomi\n\nThis source allows you to view cameras from the [Xiaomi Mi Home](https://home.mi.com/) ecosystem.\n\n**Important:**\n\n1. **Not all cameras are supported**. There are several P2P protocol vendors in the Xiaomi ecosystem.\n Currently, the **CS2** vendor is supported. However, the **TUTK** vendor is not supported.\n2. Each time you connect to the camera, you need internet access to obtain encryption keys.\n3. Connection to the camera is local only.\n\n**Features:**\n\n- Multiple Xiaomi accounts supported\n- Cameras from multiple regions are supported for a single account\n- Two-way audio is supported\n- Cameras with multiple lenses are supported\n\n## Setup\n\n1. Goto go2rtc WebUI > Add > Xiaomi > Login with username and password\n2. Receive verification code by email or phone if required.\n3. Complete the captcha if required.\n4. If everything is OK, your account will be added and you can load cameras from it.\n\n**Example**\n\n```yaml\nxiaomi:\n 1234567890: V1:***\n\nstreams:\n xiaomi1: xiaomi://1234567890:cn@192.168.1.123?did=9876543210&model=isa.camera.hlc7\n```\n\n## Configuration\n\nYou can change camera's quality: `subtype=hd/sd/auto`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&subtype=sd\n```\n\nYou can use second channel for Dual cameras: `channel=1`\n\n```yaml\nstreams:\n xiaomi1: xiaomi://***&channel=1\n```\n", _t = "# Yandex\n\nSource for receiving stream from new [Yandex IP camera](https://alice.yandex.ru/smart-home/security/ipcamera).\n\n## Get Yandex token\n\n1. Install HomeAssistant integration [YandexStation](https://github.com/AlexxIT/YandexStation).\n2. Copy token from HomeAssistant config folder: `/config/.storage/core.config_entries`, key: `\"x_token\"`.\n\n## Get device ID\n\n1. Open this link in any browser: https://iot.quasar.yandex.ru/m/v3/user/devices\n2. Copy ID of your camera, key: `\"id\"`.\n\n## Config examples\n\n```yaml\nstreams:\n yandex_stream: yandex:?x_token=XXXX&device_id=XXXX\n yandex_snapshot: yandex:?x_token=XXXX&device_id=XXXX&snapshot\n yandex_snapshot_custom_size: yandex:?x_token=XXXX&device_id=XXXX&snapshot=h=540\n```\n\n_Source: [Go2Rtc Yandex](https://github.com/AlexxIT/go2rtc/tree/master/internal/yandex)_\n", vt = [
41
40
  "nest:",
42
41
  "ring:",
43
42
  "yandex:",
44
43
  "webtorrent:"
45
44
  ];
46
- function q(e) {
45
+ function Y(e) {
47
46
  let t = e.trim(), n;
48
- for (let e of _e) t.startsWith(e) && (!n || e.length > n.length) && (n = e);
47
+ for (let e of ge) t.startsWith(e) && (!n || e.length > n.length) && (n = e);
49
48
  return n;
50
49
  }
51
- function xt(e) {
50
+ function yt(e) {
52
51
  let t = e.trim();
53
52
  if (!t) return "";
54
- for (let e of bt) if (t.startsWith(e)) {
53
+ for (let e of vt) if (t.startsWith(e)) {
55
54
  let n = t.slice(e.length);
56
55
  return n && !n.startsWith("?") ? `${e}?${n}` : t;
57
56
  }
58
57
  return t;
59
58
  }
60
- function St(e) {
59
+ function bt(e) {
61
60
  return e.startsWith("cui://") && e.includes("/api/cameras/streams/");
62
61
  }
63
62
  //#endregion
64
63
  //#region src/components/CuiCameraSources/CuiCameraSources.vue?vue&type=script&setup=true&lang.ts
65
- var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-center w-full" }, Tt = { class: "flex gap-2 items-center w-full" }, Et = { class: "text-color text-sm" }, Dt = { class: "flex flex-col gap-6" }, Ot = ["for"], kt = ["for"], At = { class: "w-full flex flex-col gap-2" }, jt = { class: "flex items-center gap-4" }, Mt = { class: "flex flex-col field-switch-gap" }, Nt = ["for"], Pt = { class: "flex items-center gap-4" }, Ft = { class: "flex flex-col field-switch-gap" }, It = ["for"], Lt = { class: "flex items-center gap-4" }, Rt = { class: "flex flex-col field-switch-gap" }, zt = ["for"], Bt = { class: "flex items-center gap-4" }, Vt = { class: "flex flex-col field-switch-gap" }, Ht = ["for"], Ut = { class: "flex flex-col gap-6" }, Wt = { class: "flex flex-col field-gap" }, Gt = ["for"], Kt = {
64
+ var xt = { class: "flex flex-col gap-6" }, St = { class: "flex gap-2 items-center w-full" }, Ct = { class: "flex gap-2 items-center w-full" }, wt = { class: "text-color text-sm" }, Tt = { class: "flex flex-col gap-6" }, Et = ["for"], Dt = ["for"], Ot = { class: "w-full flex flex-col gap-2" }, kt = { class: "flex items-center gap-4" }, At = { class: "flex flex-col field-switch-gap" }, jt = ["for"], Mt = { class: "flex items-center gap-4" }, Nt = { class: "flex flex-col field-switch-gap" }, Pt = ["for"], Ft = { class: "flex items-center gap-4" }, It = { class: "flex flex-col field-switch-gap" }, Lt = ["for"], Rt = { class: "flex items-center gap-4" }, zt = { class: "flex flex-col field-switch-gap" }, Bt = ["for"], Vt = { class: "flex flex-col gap-6" }, Ht = { class: "flex flex-col field-gap" }, Ut = ["for"], Wt = {
66
65
  key: 0,
67
66
  class: "w-full flex flex-row gap-2"
68
- }, qt = "rtsp://user:pass@192.168.1.50:554/stream", Jt = /* @__PURE__ */ O({
67
+ }, Gt = "rtsp://user:pass@192.168.1.50:554/stream", Kt = /* @__PURE__ */ O({
69
68
  __name: "CuiCameraSources",
70
69
  props: {
71
70
  sources: {},
@@ -76,35 +75,35 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
76
75
  }
77
76
  },
78
77
  setup(n, { expose: r }) {
79
- let i = new ue(), c = n, d = H(), { t: f } = W(), { mutateAsync: h, isPending: b } = i.previewCameraQuery(), S = /* #__PURE__ */ Object.assign({
80
- "../../markdowns/bubble.md": Ke,
81
- "../../markdowns/cui.md": qe,
82
- "../../markdowns/doorbird.md": Je,
83
- "../../markdowns/dvrip.md": Ye,
84
- "../../markdowns/echo.md": Xe,
85
- "../../markdowns/exec.md": Ze,
86
- "../../markdowns/expr.md": Qe,
87
- "../../markdowns/ffmpeg.md": $e,
88
- "../../markdowns/gopro.md": et,
89
- "../../markdowns/hass.md": tt,
90
- "../../markdowns/homekit.md": nt,
91
- "../../markdowns/http.md": rt,
92
- "../../markdowns/isapi.md": it,
93
- "../../markdowns/ivideon.md": at,
94
- "../../markdowns/kasa.md": ot,
95
- "../../markdowns/nest.md": st,
96
- "../../markdowns/onvif.md": ct,
97
- "../../markdowns/ring.md": lt,
98
- "../../markdowns/roborock.md": ut,
99
- "../../markdowns/rtmp.md": dt,
100
- "../../markdowns/rtsp.md": ft,
101
- "../../markdowns/tapo.md": pt,
102
- "../../markdowns/tuya.md": mt,
103
- "../../markdowns/webrtc.md": ht,
104
- "../../markdowns/webtorrent.md": gt,
105
- "../../markdowns/wyze.md": _t,
106
- "../../markdowns/xiaomi.md": vt,
107
- "../../markdowns/yandex.md": yt
78
+ let i = new z(), c = n, d = B(), { t: f } = K(), { mutateAsync: h, isPending: b } = i.previewCameraQuery(), S = /* #__PURE__ */ Object.assign({
79
+ "../../markdowns/bubble.md": We,
80
+ "../../markdowns/cui.md": Ge,
81
+ "../../markdowns/doorbird.md": Ke,
82
+ "../../markdowns/dvrip.md": qe,
83
+ "../../markdowns/echo.md": Je,
84
+ "../../markdowns/exec.md": Ye,
85
+ "../../markdowns/expr.md": Xe,
86
+ "../../markdowns/ffmpeg.md": Ze,
87
+ "../../markdowns/gopro.md": Qe,
88
+ "../../markdowns/hass.md": $e,
89
+ "../../markdowns/homekit.md": et,
90
+ "../../markdowns/http.md": tt,
91
+ "../../markdowns/isapi.md": nt,
92
+ "../../markdowns/ivideon.md": rt,
93
+ "../../markdowns/kasa.md": it,
94
+ "../../markdowns/nest.md": at,
95
+ "../../markdowns/onvif.md": ot,
96
+ "../../markdowns/ring.md": st,
97
+ "../../markdowns/roborock.md": ct,
98
+ "../../markdowns/rtmp.md": lt,
99
+ "../../markdowns/rtsp.md": ut,
100
+ "../../markdowns/tapo.md": dt,
101
+ "../../markdowns/tuya.md": ft,
102
+ "../../markdowns/webrtc.md": pt,
103
+ "../../markdowns/webtorrent.md": mt,
104
+ "../../markdowns/wyze.md": ht,
105
+ "../../markdowns/xiaomi.md": gt,
106
+ "../../markdowns/yandex.md": _t
108
107
  }), w = k([
109
108
  "high-resolution",
110
109
  "mid-resolution",
@@ -112,30 +111,30 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
112
111
  "snapshot"
113
112
  ]), O = k(c.sources.map((e, t) => t)), j = v(() => c.isLoading || b.value);
114
113
  function M(e) {
115
- return e.urls.some(St);
114
+ return e.urls.some(bt);
116
115
  }
117
- function N(e) {
118
- let t = q(e);
116
+ function P(e) {
117
+ let t = Y(e);
119
118
  if (!t) return;
120
119
  let n = t.replace(/[:/]+$/, "");
121
120
  return S[`../../markdowns/${n}.md`];
122
121
  }
123
- function P(e) {
124
- return !!N(e);
122
+ function F(e) {
123
+ return !!P(e);
125
124
  }
126
125
  function R(e) {
127
126
  c.sources[e].urls.push("");
128
127
  }
129
- function z(e, t) {
128
+ function te(e, t) {
130
129
  c.sources[e].urls.splice(t, 1);
131
130
  }
132
- function ie(e, t, n) {
131
+ function ne(e, t, n) {
133
132
  c.sources[e].urls[t] = n;
134
133
  }
135
- function ae(e, t) {
134
+ function ie(e, t) {
136
135
  e.role = t, t === "snapshot" && (e.useForSnapshot = !1, e.hotMode = !1, e.preload = !1);
137
136
  }
138
- function B() {
137
+ function ae() {
139
138
  c.sources.push({
140
139
  _id: le(8),
141
140
  name: "",
@@ -151,7 +150,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
151
150
  c.sources.splice(e, 1);
152
151
  }
153
152
  function V(e) {
154
- let t = N(e);
153
+ let t = P(e);
155
154
  t && d.openTextDialog({ data: {
156
155
  title: f("components.dialog.title.information"),
157
156
  hideConfirmButton: !0,
@@ -160,7 +159,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
160
159
  } });
161
160
  }
162
161
  async function se(e) {
163
- let t = xt(e);
162
+ let t = yt(e);
164
163
  if (t) try {
165
164
  let e = await h({ cameraData: { url: t } });
166
165
  d.openImageDialog({ data: {
@@ -170,14 +169,14 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
170
169
  } });
171
170
  } catch {}
172
171
  }
173
- return r({ newSource: B }), (r, i) => {
174
- let c = ke, d = Ce, f = G, h = De, v = K, b = F, S = te, k = we, N = re, B = Me, ce = Ge, H = ne, U = Te, le = Ee, ue = Oe, de = ee;
175
- return o(), x("div", Ct, [A(ue, {
172
+ return r({ newSource: ae }), (r, i) => {
173
+ let c = Oe, d = Se, f = q, h = Ee, v = J, b = ce, S = N, k = Ce, P = U, ae = je, z = Ue, B = re, H = we, W = Te, le = De, G = ee;
174
+ return o(), x("div", xt, [A(le, {
176
175
  value: _(O),
177
176
  "onUpdate:value": i[0] ||= (e) => g(O) ? O.value = e : null,
178
177
  multiple: ""
179
178
  }, {
180
- default: y(() => [(o(!0), x(C, null, a(n.sources, (i, g) => (o(), p(le, {
179
+ default: y(() => [(o(!0), x(C, null, a(n.sources, (i, g) => (o(), p(W, {
181
180
  key: i._id,
182
181
  value: g,
183
182
  class: u({ "border-b-0": g === n.sources.length - 1 })
@@ -187,7 +186,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
187
186
  "px-0": g !== 0,
188
187
  "pb-5": g === n.sources.length - 1
189
188
  }) }, {
190
- default: y(() => [T("div", wt, [T("div", Tt, [T("span", Et, s(r.$t("components.dialog.components.new_camera.source") + ": "), 1), A(c, {
189
+ default: y(() => [T("div", St, [T("div", Ct, [T("span", wt, s(r.$t("components.dialog.components.new_camera.source") + ": "), 1), A(c, {
191
190
  class: "text-color text-xs border-[1px] bg-primary-500/20 border-primary-500/30 py-2 px-3 rounded-full overflow-hidden",
192
191
  label: i.name === "" ? r.$t("components.dialog.components.new_camera.unknown") : i.name
193
192
  }, null, 8, ["label"])]), n.allowAddRemoveSources && n.sources.length > 1 ? (o(), p(f, {
@@ -206,11 +205,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
206
205
  _: 1
207
206
  }, 8, ["loading", "onClick"])) : m("", !0)])]),
208
207
  _: 2
209
- }, 1032, ["class"]), A(U, { pt: { content: { class: {
208
+ }, 1032, ["class"]), A(H, { pt: { content: { class: {
210
209
  "px-0": !0,
211
210
  "pb-5": g === n.sources.length - 1
212
211
  } } } }, {
213
- default: y(() => [T("div", Dt, [
212
+ default: y(() => [T("div", Tt, [
214
213
  A(_(L), {
215
214
  modelValue: i.name,
216
215
  "onUpdate:modelValue": (e) => i.name = e,
@@ -223,7 +222,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
223
222
  T("label", {
224
223
  for: `sources[${g}].name`,
225
224
  class: "cui-label"
226
- }, s(r.$t("components.form.label.source_name")), 9, Ot),
225
+ }, s(r.$t("components.form.label.source_name")), 9, Et),
227
226
  A(b, null, {
228
227
  default: y(() => [A(v, l({ ref_for: !0 }, t, {
229
228
  invalid: n.length > 0,
@@ -266,14 +265,14 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
266
265
  T("label", {
267
266
  for: `sources[${g}].role`,
268
267
  class: "cui-label"
269
- }, s(r.$t("components.form.label.source_role")), 9, kt),
268
+ }, s(r.$t("components.form.label.source_role")), 9, Dt),
270
269
  A(b, null, {
271
270
  default: y(() => [A(k, {
272
271
  "model-value": i.role,
273
272
  options: _(w).filter((e) => !n.sources.some((t) => t.role === e && t._id !== i._id)),
274
273
  invalid: t.length > 0,
275
274
  loading: _(j),
276
- onValueChange: (e) => ae(i, e)
275
+ onValueChange: (e) => ie(i, e)
277
276
  }, null, 8, [
278
277
  "model-value",
279
278
  "options",
@@ -303,7 +302,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
303
302
  ]),
304
303
  _: 2
305
304
  }, 1032, ["model-value", "name"]),
306
- T("div", At, [
305
+ T("div", Ot, [
307
306
  i.role !== "snapshot" && n.sources.length > 1 ? (o(), p(_(L), {
308
307
  key: 0,
309
308
  "model-value": i.useForSnapshot,
@@ -314,11 +313,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
314
313
  as: "div",
315
314
  class: "flex flex-col field-gap cui-toggle-switch"
316
315
  }, {
317
- default: y(({ field: t, errors: a }) => [T("div", jt, [T("div", Mt, [
316
+ default: y(({ field: t, errors: a }) => [T("div", kt, [T("div", At, [
318
317
  T("label", {
319
318
  for: `sources[${g}].useForSnapshot`,
320
319
  class: "cui-label-switch"
321
- }, s(r.$t("components.form.label.use_for_snapshot")), 9, Nt),
320
+ }, s(r.$t("components.form.label.use_for_snapshot")), 9, jt),
322
321
  A(S, {
323
322
  severity: "secondary",
324
323
  variant: "simple",
@@ -335,7 +334,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
335
334
  }, null, 8, ["name"])]),
336
335
  _: 2
337
336
  }, 1024)
338
- ]), A(N, l({ "model-value": i.useForSnapshot }, { ref_for: !0 }, t, {
337
+ ]), A(P, l({ "model-value": i.useForSnapshot }, { ref_for: !0 }, t, {
339
338
  invalid: a.length > 0,
340
339
  loading: _(j),
341
340
  disabled: n.sources.some((e) => (e.useForSnapshot || e.role === "snapshot") && e._id !== i._id),
@@ -360,11 +359,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
360
359
  as: "div",
361
360
  class: "flex flex-col field-gap cui-toggle-switch"
362
361
  }, {
363
- default: y(({ field: t, errors: n }) => [T("div", Pt, [T("div", Ft, [
362
+ default: y(({ field: t, errors: n }) => [T("div", Mt, [T("div", Nt, [
364
363
  T("label", {
365
364
  for: `sources[${g}].hotMode`,
366
365
  class: "cui-label-switch"
367
- }, s(r.$t("components.form.label.hot_mode")), 9, It),
366
+ }, s(r.$t("components.form.label.hot_mode")), 9, Pt),
368
367
  A(S, {
369
368
  severity: "secondary",
370
369
  variant: "simple",
@@ -381,7 +380,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
381
380
  }, null, 8, ["name"])]),
382
381
  _: 2
383
382
  }, 1024)
384
- ]), A(N, l({ "model-value": i.hotMode }, { ref_for: !0 }, t, {
383
+ ]), A(P, l({ "model-value": i.hotMode }, { ref_for: !0 }, t, {
385
384
  invalid: n.length > 0,
386
385
  loading: _(j),
387
386
  class: "ml-auto shrink-0",
@@ -404,11 +403,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
404
403
  as: "div",
405
404
  class: "flex flex-col field-gap cui-toggle-switch"
406
405
  }, {
407
- default: y(({ field: t, errors: n }) => [T("div", Lt, [T("div", Rt, [
406
+ default: y(({ field: t, errors: n }) => [T("div", Ft, [T("div", It, [
408
407
  T("label", {
409
408
  for: `sources[${g}].preload`,
410
409
  class: "cui-label-switch"
411
- }, s(r.$t("components.form.label.preload")), 9, zt),
410
+ }, s(r.$t("components.form.label.preload")), 9, Lt),
412
411
  A(S, {
413
412
  severity: "secondary",
414
413
  variant: "simple",
@@ -425,7 +424,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
425
424
  }, null, 8, ["name"])]),
426
425
  _: 2
427
426
  }, 1024)
428
- ]), A(N, l({ "model-value": i.preload }, { ref_for: !0 }, t, {
427
+ ]), A(P, l({ "model-value": i.preload }, { ref_for: !0 }, t, {
429
428
  invalid: n.length > 0,
430
429
  loading: _(j),
431
430
  class: "ml-auto shrink-0",
@@ -448,11 +447,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
448
447
  as: "div",
449
448
  class: "flex flex-col field-gap cui-toggle-switch"
450
449
  }, {
451
- default: y(({ field: t, errors: n }) => [T("div", Bt, [T("div", Vt, [
450
+ default: y(({ field: t, errors: n }) => [T("div", Rt, [T("div", zt, [
452
451
  T("label", {
453
452
  for: `sources[${g}].muted`,
454
453
  class: "cui-label-switch"
455
- }, s(r.$t("components.form.label.muted")), 9, Ht),
454
+ }, s(r.$t("components.form.label.muted")), 9, Bt),
456
455
  A(S, {
457
456
  severity: "secondary",
458
457
  variant: "simple",
@@ -469,7 +468,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
469
468
  }, null, 8, ["name"])]),
470
469
  _: 2
471
470
  }, 1024)
472
- ]), A(N, l({ "model-value": i.muted }, { ref_for: !0 }, t, {
471
+ ]), A(P, l({ "model-value": i.muted }, { ref_for: !0 }, t, {
473
472
  invalid: n.length > 0,
474
473
  loading: _(j),
475
474
  class: "ml-auto shrink-0",
@@ -483,11 +482,11 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
483
482
  _: 2
484
483
  }, 1032, ["model-value", "name"]))
485
484
  ]),
486
- T("div", Ut, [
487
- T("div", Wt, [T("label", {
485
+ T("div", Vt, [
486
+ T("div", Ht, [T("label", {
488
487
  for: `sources[${g}].urls[]`,
489
488
  class: "cui-label"
490
- }, s(r.$t("components.form.label.sources")), 9, Gt), A(S, {
489
+ }, s(r.$t("components.form.label.sources")), 9, Ut), A(S, {
491
490
  severity: "secondary",
492
491
  variant: "simple",
493
492
  size: "small",
@@ -496,7 +495,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
496
495
  default: y(() => [D(s(M(i) ? r.$t("views.devices.managed_source_hint") : r.$t("components.form.hint.source_urls")), 1)]),
497
496
  _: 2
498
497
  }, 1024)]),
499
- (o(!0), x(C, null, a(i.urls, (n, a) => (o(), x(C, { key: a }, [_(St)(n) ? (o(), x("div", Kt, [A(b, null, {
498
+ (o(!0), x(C, null, a(i.urls, (n, a) => (o(), x(C, { key: a }, [_(bt)(n) ? (o(), x("div", Wt, [A(b, null, {
500
499
  default: y(() => [A(v, {
501
500
  "model-value": n,
502
501
  readonly: "",
@@ -518,30 +517,30 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
518
517
  invalid: c.length > 0,
519
518
  loading: _(j),
520
519
  type: "text",
521
- placeholder: qt,
522
- "onUpdate:modelValue": (e) => ie(g, a, e ?? "")
520
+ placeholder: Gt,
521
+ "onUpdate:modelValue": (e) => ne(g, a, e ?? "")
523
522
  }, null, 8, [
524
523
  "model-value",
525
524
  "invalid",
526
525
  "loading",
527
526
  "onUpdate:modelValue"
528
- ]), A(H, null, {
527
+ ]), A(B, null, {
529
528
  default: y(() => [
530
529
  E((o(), p(f, {
531
530
  text: "",
532
531
  rounded: "",
533
532
  severity: "secondary",
534
- disabled: _(j) || !P(n),
533
+ disabled: _(j) || !F(n),
535
534
  class: "border-right-color",
536
535
  onClick: (e) => V(n)
537
536
  }, {
538
- icon: y(() => [A(B, {
537
+ icon: y(() => [A(ae, {
539
538
  width: "100%",
540
539
  height: "100%"
541
540
  })]),
542
541
  _: 1
543
542
  }, 8, ["disabled", "onClick"])), [[
544
- de,
543
+ G,
545
544
  { value: r.$t("components.dialog.components.new_camera.protocol_info") },
546
545
  void 0,
547
546
  { top: !0 }
@@ -550,17 +549,17 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
550
549
  text: "",
551
550
  rounded: "",
552
551
  severity: "secondary",
553
- disabled: _(j) || !_(q)(n),
552
+ disabled: _(j) || !_(Y)(n),
554
553
  class: "border-right-color",
555
554
  onClick: (e) => se(n)
556
555
  }, {
557
- icon: y(() => [A(ce, {
556
+ icon: y(() => [A(z, {
558
557
  width: "100%",
559
558
  height: "100%"
560
559
  })]),
561
560
  _: 1
562
561
  }, 8, ["disabled", "onClick"])), [[
563
- de,
562
+ G,
564
563
  { value: r.$t("components.dialog.components.new_camera.test_source") },
565
564
  void 0,
566
565
  { top: !0 }
@@ -571,7 +570,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
571
570
  rounded: "",
572
571
  severity: "danger",
573
572
  disabled: _(j),
574
- onClick: t((e) => z(g, a), ["prevent"])
573
+ onClick: t((e) => te(g, a), ["prevent"])
575
574
  }, {
576
575
  icon: y(() => [A(d, {
577
576
  width: "100%",
@@ -597,7 +596,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
597
596
  size: "small",
598
597
  class: "cui-input-hint"
599
598
  }, {
600
- default: y(() => [D(s(_(q)(n) ? r.$t("components.form.hint.source_detected_protocol", { protocol: _(q)(n) }) : r.$t("components.form.hint.source_url")), 1)]),
599
+ default: y(() => [D(s(_(Y)(n) ? r.$t("components.form.hint.source_detected_protocol", { protocol: _(Y)(n) }) : r.$t("components.form.hint.source_url")), 1)]),
601
600
  _: 2
602
601
  }, 1024)
603
602
  ]),
@@ -624,16 +623,16 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
624
623
  }, 8, ["value"])]);
625
624
  };
626
625
  }
627
- }), Yt = { class: "flex flex-col gap-2 w-full" }, Xt = {
626
+ }), qt = { class: "flex flex-col gap-2 w-full" }, Jt = {
628
627
  for: "roomName",
629
628
  class: "cui-label"
630
- }, Zt = /* @__PURE__ */ O({
629
+ }, Yt = /* @__PURE__ */ O({
631
630
  __name: "CreateRoom",
632
631
  setup(e, { expose: t }) {
633
632
  let n = k("");
634
633
  return t({ onConfirm: async () => n.value.trim() || null }), (e, t) => {
635
- let r = K;
636
- return o(), x("div", Yt, [T("label", Xt, s(e.$t("components.form.label.name")), 1), A(r, {
634
+ let r = J;
635
+ return o(), x("div", qt, [T("label", Jt, s(e.$t("components.form.label.name")), 1), A(r, {
637
636
  id: "roomName",
638
637
  modelValue: _(n),
639
638
  "onUpdate:modelValue": t[0] ||= (e) => g(n) ? n.value = e : null,
@@ -646,7 +645,7 @@ var Ct = { class: "flex flex-col gap-6" }, wt = { class: "flex gap-2 items-cente
646
645
  });
647
646
  //#endregion
648
647
  //#region src/components/CuiCameraDetailsFields/rooms.ts
649
- function Qt(e, t) {
648
+ function Xt(e, t) {
650
649
  let n = e?.rooms ?? [], r = [...e?.levels ?? []].sort((e, t) => e.order - t.order), i = (e) => ({
651
650
  label: e.name === "Default" ? t("components.form.label.room_default") : e.name,
652
651
  value: e.id
@@ -668,46 +667,46 @@ function Qt(e, t) {
668
667
  }
669
668
  //#endregion
670
669
  //#region src/components/CuiCameraDetailsFields/CuiCameraDetailsFields.vue?vue&type=script&setup=true&lang.ts
671
- var $t = { class: "flex flex-col gap-6" }, en = {
670
+ var Zt = { class: "flex flex-col gap-6" }, Qt = {
672
671
  for: "name",
673
672
  class: "cui-label"
674
- }, tn = { class: "flex flex-col field-gap" }, nn = {
673
+ }, $t = { class: "flex flex-col field-gap" }, en = {
675
674
  for: "type",
676
675
  class: "cui-label"
677
- }, rn = { class: "flex flex-col field-gap" }, an = {
676
+ }, tn = { class: "flex flex-col field-gap" }, nn = {
678
677
  for: "room",
679
678
  class: "cui-label"
680
- }, on = { class: "flex gap-2" }, sn = { class: "text-color font-normal" }, cn = { class: "flex flex-col gap-6" }, ln = {
679
+ }, rn = { class: "flex gap-2" }, an = { class: "text-color font-normal" }, on = { class: "flex flex-col gap-6" }, sn = {
681
680
  for: "info.manufacturer",
682
681
  class: "cui-label"
683
- }, un = {
682
+ }, cn = {
684
683
  for: "info.model",
685
684
  class: "cui-label"
686
- }, dn = {
685
+ }, ln = {
687
686
  for: "info.hardware",
688
687
  class: "cui-label"
689
- }, fn = {
688
+ }, un = {
690
689
  for: "info.serialNumber",
691
690
  class: "cui-label"
692
- }, pn = {
691
+ }, dn = {
693
692
  for: "info.firmwareVersion",
694
693
  class: "cui-label"
695
- }, mn = {
694
+ }, fn = {
696
695
  for: "info.supportUrl",
697
696
  class: "cui-label"
698
- }, hn = /* @__PURE__ */ O({
697
+ }, pn = /* @__PURE__ */ O({
699
698
  __name: "CuiCameraDetailsFields",
700
699
  props: {
701
700
  form: {},
702
701
  isLoading: { type: Boolean }
703
702
  },
704
703
  setup(t) {
705
- let n = new He(), r = t, i = H(), { t: a } = W(), { data: u, isBusy: d } = n.getRoomsQuery(), { mutateAsync: f } = n.createRoomMutation(), h = k(["camera", "doorbell"]), g = v(() => (u.value?.levels.length ?? 0) > 0), b = v(() => Qt(u.value, a));
704
+ let n = new Be(), r = t, i = B(), { t: a } = K(), { data: u, isBusy: d } = n.getRoomsQuery(), { mutateAsync: f } = n.createRoomMutation(), h = k(["camera", "doorbell"]), g = v(() => (u.value?.levels.length ?? 0) > 0), b = v(() => Xt(u.value, a));
706
705
  function S(e) {
707
706
  r.form.roomId = e;
708
707
  }
709
708
  function C() {
710
- i.openComponentDialog(Zt, {
709
+ i.openComponentDialog(Yt, {
711
710
  data: {
712
711
  title: a("components.dialog.title.create_room"),
713
712
  confirmText: a("components.form.button.add"),
@@ -725,8 +724,8 @@ var $t = { class: "flex flex-col gap-6" }, en = {
725
724
  });
726
725
  }
727
726
  return (n, r) => {
728
- let i = K, a = F, u = te, f = we, v = Le, w = G, O = De, k = Te, j = Ee, M = Oe, N = ee;
729
- return o(), x("div", $t, [
727
+ let i = J, a = ce, u = N, f = Ce, v = Fe, w = q, O = Ee, k = we, j = Te, M = De, P = ee;
728
+ return o(), x("div", Zt, [
730
729
  A(_(L), {
731
730
  modelValue: t.form.name,
732
731
  "onUpdate:modelValue": r[0] ||= (e) => t.form.name = e,
@@ -736,7 +735,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
736
735
  class: "flex flex-col field-gap"
737
736
  }, {
738
737
  default: y(({ field: r, errors: c }) => [
739
- T("label", en, s(n.$t("components.form.label.name")), 1),
738
+ T("label", Qt, s(n.$t("components.form.label.name")), 1),
740
739
  A(a, null, {
741
740
  default: y(() => [A(i, l(r, {
742
741
  invalid: c.length > 0,
@@ -765,7 +764,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
765
764
  ]),
766
765
  _: 1
767
766
  }, 8, ["modelValue"]),
768
- T("div", tn, [T("label", nn, s(n.$t("components.form.label.type")), 1), A(a, null, {
767
+ T("div", $t, [T("label", en, s(n.$t("components.form.label.type")), 1), A(a, null, {
769
768
  default: y(() => [A(f, {
770
769
  "model-value": t.form.type,
771
770
  options: _(h),
@@ -779,9 +778,9 @@ var $t = { class: "flex flex-col gap-6" }, en = {
779
778
  ])]),
780
779
  _: 1
781
780
  })]),
782
- T("div", rn, [
783
- T("label", an, s(n.$t("components.form.label.room")), 1),
784
- T("div", on, [A(f, {
781
+ T("div", tn, [
782
+ T("label", nn, s(n.$t("components.form.label.room")), 1),
783
+ T("div", rn, [A(f, {
785
784
  "model-value": t.form.roomId,
786
785
  options: _(b),
787
786
  "option-label": "label",
@@ -806,7 +805,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
806
805
  icon: y(() => [A(v, { class: "w-4 h-4" })]),
807
806
  _: 1
808
807
  })), [[
809
- N,
808
+ P,
810
809
  n.$t("components.form.button.create_room"),
811
810
  void 0,
812
811
  { top: !0 }
@@ -825,10 +824,10 @@ var $t = { class: "flex flex-col gap-6" }, en = {
825
824
  A(M, null, {
826
825
  default: y(() => [A(j, { value: "branding" }, {
827
826
  default: y(() => [A(O, { class: "px-0 pt-0" }, {
828
- default: y(() => [T("span", sn, s(n.$t("components.camera_options.branding")), 1)]),
827
+ default: y(() => [T("span", an, s(n.$t("components.camera_options.branding")), 1)]),
829
828
  _: 1
830
829
  }), A(k, { pt: { content: { class: "px-0" } } }, {
831
- default: y(() => [T("div", cn, [
830
+ default: y(() => [T("div", on, [
832
831
  A(_(L), {
833
832
  modelValue: t.form.info.manufacturer,
834
833
  "onUpdate:modelValue": r[3] ||= (e) => t.form.info.manufacturer = e,
@@ -838,7 +837,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
838
837
  class: "flex flex-col field-gap"
839
838
  }, {
840
839
  default: y(({ field: r, errors: o }) => [
841
- T("label", ln, s(n.$t("components.form.label.manufacturer")), 1),
840
+ T("label", sn, s(n.$t("components.form.label.manufacturer")), 1),
842
841
  A(a, null, {
843
842
  default: y(() => [A(i, l(r, {
844
843
  invalid: o.length > 0,
@@ -866,7 +865,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
866
865
  class: "flex flex-col field-gap"
867
866
  }, {
868
867
  default: y(({ field: r, errors: o }) => [
869
- T("label", un, s(n.$t("components.form.label.model")), 1),
868
+ T("label", cn, s(n.$t("components.form.label.model")), 1),
870
869
  A(a, null, {
871
870
  default: y(() => [A(i, l(r, {
872
871
  invalid: o.length > 0,
@@ -894,7 +893,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
894
893
  class: "flex flex-col field-gap"
895
894
  }, {
896
895
  default: y(({ field: r, errors: o }) => [
897
- T("label", dn, s(n.$t("components.form.label.hardware_version")), 1),
896
+ T("label", ln, s(n.$t("components.form.label.hardware_version")), 1),
898
897
  A(a, null, {
899
898
  default: y(() => [A(i, l(r, {
900
899
  invalid: o.length > 0,
@@ -922,7 +921,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
922
921
  class: "flex flex-col field-gap"
923
922
  }, {
924
923
  default: y(({ field: r, errors: o }) => [
925
- T("label", fn, s(n.$t("components.form.label.serial_number")), 1),
924
+ T("label", un, s(n.$t("components.form.label.serial_number")), 1),
926
925
  A(a, null, {
927
926
  default: y(() => [A(i, l(r, {
928
927
  invalid: o.length > 0,
@@ -950,7 +949,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
950
949
  class: "flex flex-col field-gap"
951
950
  }, {
952
951
  default: y(({ field: r, errors: o }) => [
953
- T("label", pn, s(n.$t("components.form.label.firmware_version")), 1),
952
+ T("label", dn, s(n.$t("components.form.label.firmware_version")), 1),
954
953
  A(a, null, {
955
954
  default: y(() => [A(i, l(r, {
956
955
  invalid: o.length > 0,
@@ -978,7 +977,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
978
977
  class: "flex flex-col field-gap"
979
978
  }, {
980
979
  default: y(({ field: r, errors: o }) => [
981
- T("label", mn, s(n.$t("components.form.label.support_url")), 1),
980
+ T("label", fn, s(n.$t("components.form.label.support_url")), 1),
982
981
  A(a, null, {
983
982
  default: y(() => [A(i, l(r, {
984
983
  invalid: o.length > 0,
@@ -1007,26 +1006,26 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1007
1006
  ]);
1008
1007
  };
1009
1008
  }
1010
- }), gn = RegExp(`^(${_e.join("|")})`), _n = N().trim().min(1, "Camera Source is required").regex(gn, "Unsupported protocol — start the URL with a supported one (e.g. rtsp://)"), vn = U({
1011
- name: N().trim().min(1, "Camera Source Name is required"),
1012
- urls: _n.array(),
1013
- role: ye,
1014
- useForSnapshot: P().default(!1),
1015
- hotMode: P().default(!0),
1016
- preload: P().default(!0),
1017
- muted: P().default(!1),
1018
- backchannelDisabled: P().default(!1),
1019
- timeout: z().int().min(5).max(120).nullish(),
1020
- handshakeTimeout: z().int().min(1).max(60).nullish(),
1021
- childSourceId: N().trim().nullish()
1009
+ }), mn = RegExp(`^(${ge.join("|")})`), hn = P().trim().min(1, "Camera Source is required").regex(mn, "Unsupported protocol — start the URL with a supported one (e.g. rtsp://)"), gn = W({
1010
+ name: P().trim().min(1, "Camera Source Name is required"),
1011
+ urls: hn.array(),
1012
+ role: ve,
1013
+ useForSnapshot: F().default(!1),
1014
+ hotMode: F().default(!0),
1015
+ preload: F().default(!0),
1016
+ muted: F().default(!1),
1017
+ backchannelDisabled: F().default(!1),
1018
+ timeout: te().int().min(5).max(120).nullish(),
1019
+ handshakeTimeout: te().int().min(1).max(60).nullish(),
1020
+ childSourceId: P().trim().nullish()
1022
1021
  }).strict().transform((e) => e.role === "snapshot" ? {
1023
1022
  ...e,
1024
1023
  useForSnapshot: !1,
1025
1024
  hotMode: !1,
1026
1025
  preload: !1
1027
- } : e), yn = U({
1028
- ...ve.shape,
1029
- sources: vn.array().refine((e) => e.some((e) => e.role === "high-resolution" || e.role === "mid-resolution" || e.role === "low-resolution"), {
1026
+ } : e), _n = W({
1027
+ ..._e.shape,
1028
+ sources: gn.array().refine((e) => e.some((e) => e.role === "high-resolution" || e.role === "mid-resolution" || e.role === "low-resolution"), {
1030
1029
  path: ["sources[].role"],
1031
1030
  message: "One of the roles \"high-resolution\", \"mid-resolution\" or \"low-resolution\" is required"
1032
1031
  }).refine((e) => e.filter((e) => e.useForSnapshot).length <= 1, {
@@ -1038,8 +1037,8 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1038
1037
  }, {
1039
1038
  message: "Each source role can be assigned to only one source",
1040
1039
  path: ["sources"]
1041
- }).superRefine(be)
1042
- }).strict(), bn = {
1040
+ }).superRefine(ye)
1041
+ }).strict(), vn = {
1043
1042
  disabled: !1,
1044
1043
  name: "",
1045
1044
  type: "camera",
@@ -1073,25 +1072,25 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1073
1072
  },
1074
1073
  plugins: [],
1075
1074
  assignments: {}
1076
- }, xn = { class: "card-title" }, Sn = { class: "card-title" }, Cn = { class: "w-full flex items-center justify-center mt-4" }, wn = /* @__PURE__ */ O({
1075
+ }, yn = { class: "card-title" }, bn = { class: "card-title" }, xn = { class: "w-full flex items-center justify-center mt-4" }, Sn = /* @__PURE__ */ O({
1077
1076
  __name: "AddCamera",
1078
- props: { camera: { default: () => bn } },
1077
+ props: { camera: { default: () => vn } },
1079
1078
  setup(e, { expose: t }) {
1080
- let n = new ue(), r = e, a = V(), { t: c } = W(), { mutateAsync: l, isPending: u } = n.createCameraQuery(), { camera: d } = i(r), f = w("formRef"), p = w("sourcesRef"), m = k(B(d.value)), h = v(() => u.value);
1079
+ let n = new z(), r = e, a = H(), { t: c } = K(), { mutateAsync: l, isPending: u } = n.createCameraQuery(), { camera: d } = i(r), f = w("formRef"), p = w("sourcesRef"), m = k(V(d.value)), h = v(() => u.value);
1081
1080
  async function g() {
1082
1081
  if (!(await f.value?.validate())?.valid) return a.add({
1083
1082
  severity: "error",
1084
1083
  detail: c("components.toast.validation_failed"),
1085
1084
  life: 3e3
1086
1085
  }), null;
1087
- let e = B(m.value), t = {
1088
- ...xe(),
1086
+ let e = V(m.value), t = {
1087
+ ...be(),
1089
1088
  ...e,
1090
1089
  sources: e.sources.map((e) => ({
1091
1090
  ...e,
1092
1091
  muted: e.muted ?? !1,
1093
1092
  backchannelDisabled: e.backchannelDisabled ?? !1,
1094
- urls: e.urls.map(xt).filter(Boolean)
1093
+ urls: e.urls.map(yt).filter(Boolean)
1095
1094
  }))
1096
1095
  };
1097
1096
  await l({ cameraData: t });
@@ -1101,21 +1100,21 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1101
1100
  onSave: g,
1102
1101
  onConfirm: g
1103
1102
  }), (e, t) => {
1104
- let n = hn, r = he, i = Jt, a = Ne, c = G;
1103
+ let n = pn, r = me, i = Kt, a = Me, c = q;
1105
1104
  return o(), x("div", null, [A(_(R), {
1106
1105
  ref_key: "formRef",
1107
1106
  ref: f,
1108
1107
  class: "flex flex-col w-full gap-6",
1109
- "validation-schema": _(yn)
1108
+ "validation-schema": _(_n)
1110
1109
  }, {
1111
- default: y(() => [T("div", null, [T("span", xn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(r, { class: "cui-card" }, {
1110
+ default: y(() => [T("div", null, [T("span", yn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(r, { class: "cui-card" }, {
1112
1111
  content: y(() => [A(n, {
1113
1112
  form: _(m),
1114
1113
  "is-loading": _(h)
1115
1114
  }, null, 8, ["form", "is-loading"])]),
1116
1115
  _: 1
1117
1116
  })]), T("div", null, [
1118
- T("span", Sn, s(e.$t("components.form.label.sources")), 1),
1117
+ T("span", bn, s(e.$t("components.form.label.sources")), 1),
1119
1118
  A(r, {
1120
1119
  class: "cui-card border-color-inner",
1121
1120
  pt: { body: { class: "pb-0" } }
@@ -1129,7 +1128,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1129
1128
  }, null, 8, ["sources", "is-loading"])]),
1130
1129
  _: 1
1131
1130
  }),
1132
- T("div", Cn, [A(c, {
1131
+ T("div", xn, [A(c, {
1133
1132
  text: "",
1134
1133
  rounded: "",
1135
1134
  loading: _(h),
@@ -1147,17 +1146,17 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1147
1146
  }, 8, ["validation-schema"])]);
1148
1147
  };
1149
1148
  }
1150
- }), Tn = { class: "card-title" }, En = {
1149
+ }), Cn = { class: "card-title" }, wn = {
1151
1150
  key: 0,
1152
1151
  class: "flex flex-col gap-6"
1153
- }, Dn = { class: "cui-label" }, On = { class: "card-title" }, kn = /* @__PURE__ */ O({
1152
+ }, Tn = { class: "cui-label" }, En = { class: "card-title" }, Dn = /* @__PURE__ */ O({
1154
1153
  __name: "ConfirmCamera",
1155
1154
  props: {
1156
1155
  draft: {},
1157
1156
  onConfirm: { type: Function }
1158
1157
  },
1159
1158
  setup(e, { expose: t }) {
1160
- let n = U({ name: N().trim().min(1) }).passthrough(), r = e, i = V(), { t: c } = W(), l = w("formRef"), u = k(B(r.draft)), d = k({
1159
+ let n = W({ name: P().trim().min(1) }).passthrough(), r = e, i = H(), { t: c } = K(), l = w("formRef"), u = k(V(r.draft)), d = k({
1161
1160
  name: u.value.name,
1162
1161
  type: u.value.type,
1163
1162
  room: u.value.room,
@@ -1194,7 +1193,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1194
1193
  info: d.value.info,
1195
1194
  sources: d.value.sources.map((e) => ({
1196
1195
  ...e,
1197
- urls: e.urls.map(xt).filter(Boolean)
1196
+ urls: e.urls.map(yt).filter(Boolean)
1198
1197
  }))
1199
1198
  };
1200
1199
  await r.onConfirm(e);
@@ -1213,22 +1212,22 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1213
1212
  isLoading: h,
1214
1213
  onConfirm: g
1215
1214
  }), (e, t) => {
1216
- let r = K, i = F, c = hn, u = he, f = Jt;
1215
+ let r = J, i = ce, c = pn, u = me, f = Kt;
1217
1216
  return o(), x("div", null, [A(_(R), {
1218
1217
  ref_key: "formRef",
1219
1218
  ref: l,
1220
1219
  class: "flex flex-col w-full gap-6",
1221
1220
  "validation-schema": _(n)
1222
1221
  }, {
1223
- default: y(() => [T("div", null, [T("span", Tn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(u, { class: "cui-card" }, {
1222
+ default: y(() => [T("div", null, [T("span", Cn, s(e.$t("components.dialog.components.new_camera.camera")), 1), A(u, { class: "cui-card" }, {
1224
1223
  content: y(() => [A(c, {
1225
1224
  form: _(d),
1226
1225
  "is-loading": _(h)
1227
1226
  }, {
1228
- default: y(() => [_(p).length ? (o(), x("div", En, [(o(!0), x(C, null, a(_(p), (e) => (o(), x("div", {
1227
+ default: y(() => [_(p).length ? (o(), x("div", wn, [(o(!0), x(C, null, a(_(p), (e) => (o(), x("div", {
1229
1228
  key: e.label,
1230
1229
  class: "flex flex-col field-gap"
1231
- }, [T("label", Dn, s(e.label), 1), A(i, null, {
1230
+ }, [T("label", Tn, s(e.label), 1), A(i, null, {
1232
1231
  default: y(() => [A(r, {
1233
1232
  "model-value": e.value,
1234
1233
  readonly: "",
@@ -1239,7 +1238,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1239
1238
  _: 1
1240
1239
  }, 8, ["form", "is-loading"])]),
1241
1240
  _: 1
1242
- })]), T("div", null, [T("span", On, s(e.$t("components.form.label.sources")), 1), A(u, {
1241
+ })]), T("div", null, [T("span", En, s(e.$t("components.form.label.sources")), 1), A(u, {
1243
1242
  class: "cui-card border-color-inner",
1244
1243
  pt: { body: { class: "pb-0" } }
1245
1244
  }, {
@@ -1254,13 +1253,13 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1254
1253
  }, 8, ["validation-schema"])]);
1255
1254
  };
1256
1255
  }
1257
- }), An = { class: "flex flex-col gap-6" }, jn = {
1256
+ }), On = { class: "flex flex-col gap-6" }, kn = {
1258
1257
  key: 0,
1259
1258
  class: "flex flex-col field-gap"
1260
- }, Mn = { class: "cui-label" }, Nn = {
1259
+ }, An = { class: "cui-label" }, jn = {
1261
1260
  key: 1,
1262
1261
  class: "text-center py-4"
1263
- }, Pn = { class: "text-muted" }, Fn = /* @__PURE__ */ O({
1262
+ }, Mn = { class: "text-muted" }, Nn = /* @__PURE__ */ O({
1264
1263
  __name: "ConnectionSchema",
1265
1264
  props: {
1266
1265
  camera: {},
@@ -1268,7 +1267,7 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1268
1267
  onConnect: { type: Function }
1269
1268
  },
1270
1269
  setup(e, { expose: t }) {
1271
- let n = e, a = ge(), c = V(), { t: l } = W(), u = r("dialogRefProps"), { schema: d } = i(n), f = w("schemaFormRef"), h = k(!1), g = v(() => ({
1270
+ let n = e, a = he(), c = H(), { t: l } = K(), u = r("dialogRefProps"), { schema: d } = i(n), f = w("schemaFormRef"), h = k(!1), g = v(() => ({
1272
1271
  schema: d.value,
1273
1272
  config: {}
1274
1273
  })), y = v(() => !!(u.loading?.value || h.value));
@@ -1301,11 +1300,11 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1301
1300
  isLoading: y,
1302
1301
  onConfirm: b
1303
1302
  }), (t, n) => {
1304
- let r = K, i = Pe;
1305
- return o(), x("div", An, [e.camera.address ? (o(), x("div", jn, [T("label", Mn, s(t.$t("views.devices.address")), 1), A(r, {
1303
+ let r = J, i = Ne;
1304
+ return o(), x("div", On, [e.camera.address ? (o(), x("div", kn, [T("label", An, s(t.$t("views.devices.address")), 1), A(r, {
1306
1305
  "model-value": e.camera.address,
1307
1306
  readonly: ""
1308
- }, null, 8, ["model-value"])])) : m("", !0), _(d).length === 0 ? (o(), x("div", Nn, [T("p", Pn, s(t.$t("views.devices.no_settings_required")), 1)])) : (o(), p(i, {
1307
+ }, null, 8, ["model-value"])])) : m("", !0), _(d).length === 0 ? (o(), x("div", jn, [T("p", Mn, s(t.$t("views.devices.no_settings_required")), 1)])) : (o(), p(i, {
1309
1308
  key: 2,
1310
1309
  ref_key: "schemaFormRef",
1311
1310
  ref: f,
@@ -1314,98 +1313,98 @@ var $t = { class: "flex flex-col gap-6" }, en = {
1314
1313
  }, null, 8, ["schema-form", "loading"]))]);
1315
1314
  };
1316
1315
  }
1317
- }), In = 5e3, J = j({
1316
+ }), Pn = 5e3, X = j({
1318
1317
  isLoading: !0,
1319
1318
  devices: [],
1320
1319
  isScanning: !1,
1321
1320
  hiddenDevices: [],
1322
1321
  showHidden: !1,
1323
1322
  error: null
1324
- }), Y = null, X = null, Z = !1, Q = 0, $ = null;
1323
+ }), Fn = null, Z = null, Q = !1, $ = 0, In = null;
1325
1324
  function Ln() {
1326
- J.isLoading = !0, J.devices = [], J.isScanning = !1, J.hiddenDevices = [], J.showHidden = !1, J.error = null;
1325
+ X.isLoading = !0, X.devices = [], X.isScanning = !1, X.hiddenDevices = [], X.showHidden = !1, X.error = null;
1327
1326
  }
1328
1327
  function Rn() {
1329
- return X || (Y = h(!0), Y.run(() => {
1328
+ return Z || (Fn = h(!0), Fn.run(() => {
1330
1329
  let e = de("/cameras");
1331
- X = e, e.onReady(() => {
1330
+ Z = e, e.onReady(() => {
1332
1331
  zn();
1333
1332
  }), b(e.connected, (e, t) => {
1334
- !e && t && (Z = !1);
1333
+ !e && t && (Q = !1);
1335
1334
  }), e.on("cameras:discovered", (e) => {
1336
1335
  for (let t of e.devices) {
1337
- let e = J.devices.findIndex((e) => e.id === t.id);
1338
- e >= 0 ? J.devices[e] = t : J.devices.push(t);
1336
+ let e = X.devices.findIndex((e) => e.id === t.id);
1337
+ e >= 0 ? X.devices[e] = t : X.devices.push(t);
1339
1338
  }
1340
1339
  }), e.on("cameras:scanning", (e) => {
1341
- J.isScanning = e.isScanning;
1340
+ X.isScanning = e.isScanning;
1342
1341
  }), e.on("cameras:connection-status", (e) => {
1343
- let t = J.devices.find((t) => t.discoveredId === e.discoveredId);
1344
- t && (e.status === "connecting" ? t.status = "adopting" : e.status === "error" ? (t.status = "error", t.errorMessage = e.errorMessage) : e.status === "connected" && (J.devices = J.devices.filter((t) => t.discoveredId !== e.discoveredId)));
1342
+ let t = X.devices.find((t) => t.discoveredId === e.discoveredId);
1343
+ t && (e.status === "connecting" ? t.status = "adopting" : e.status === "error" ? (t.status = "error", t.errorMessage = e.errorMessage) : e.status === "connected" && (X.devices = X.devices.filter((t) => t.discoveredId !== e.discoveredId)));
1345
1344
  }), e.on("cameras:camera-connected", (e) => {
1346
- J.devices = J.devices.filter((t) => t.discoveredId !== e.discoveredId);
1345
+ X.devices = X.devices.filter((t) => t.discoveredId !== e.discoveredId);
1347
1346
  }), e.on("cameras:deleted", (e) => {
1348
- J.devices = J.devices.filter((t) => t.cameraId !== e.cameraId);
1347
+ X.devices = X.devices.filter((t) => t.cameraId !== e.cameraId);
1349
1348
  });
1350
- }), X);
1349
+ }), Z);
1351
1350
  }
1352
1351
  async function zn() {
1353
- if (!X || Z) return {
1354
- success: Z,
1355
- devices: J.devices,
1356
- isScanning: J.isScanning,
1357
- hiddenDevices: J.hiddenDevices
1352
+ if (!Z || Q) return {
1353
+ success: Q,
1354
+ devices: X.devices,
1355
+ isScanning: X.isScanning,
1356
+ hiddenDevices: X.hiddenDevices
1358
1357
  };
1359
1358
  try {
1360
- let e = await X.request("cameras:subscribe", {});
1361
- return Z = e.success, e.devices && (J.devices = e.devices), e.isScanning !== void 0 && (J.isScanning = e.isScanning), e.hiddenDevices && (J.hiddenDevices = e.hiddenDevices), J.isLoading = !1, e;
1359
+ let e = await Z.request("cameras:subscribe", {});
1360
+ return Q = e.success, e.devices && (X.devices = e.devices), e.isScanning !== void 0 && (X.isScanning = e.isScanning), e.hiddenDevices && (X.hiddenDevices = e.hiddenDevices), X.isLoading = !1, e;
1362
1361
  } catch (e) {
1363
- return J.isLoading = !1, J.error = e instanceof Error ? e.message : "subscribe failed", { success: !1 };
1362
+ return X.isLoading = !1, X.error = e instanceof Error ? e.message : "subscribe failed", { success: !1 };
1364
1363
  }
1365
1364
  }
1366
1365
  async function Bn() {
1367
- if (!X || !Z) return { success: !0 };
1366
+ if (!Z || !Q) return { success: !0 };
1368
1367
  try {
1369
- let e = await X.request("cameras:unsubscribe", {});
1370
- return Z = !e.success, e;
1368
+ let e = await Z.request("cameras:unsubscribe", {});
1369
+ return Q = !e.success, e;
1371
1370
  } catch {
1372
1371
  return { success: !1 };
1373
1372
  }
1374
1373
  }
1375
1374
  function Vn() {
1376
- Z && Bn(), Y?.stop(), Y = null, X = null, Z = !1, Ln();
1375
+ Q && Bn(), Fn?.stop(), Fn = null, Z = null, Q = !1, Ln();
1377
1376
  }
1378
1377
  function Hn() {
1379
- $ &&= (clearTimeout($), null), Q++;
1378
+ In &&= (clearTimeout(In), null), $++;
1380
1379
  function e() {
1381
- Rn(), X?.connected.value && !Z && zn();
1380
+ Rn(), Z?.connected.value && !Q && zn();
1382
1381
  }
1383
1382
  function t() {
1384
- Z && Bn();
1383
+ Q && Bn();
1385
1384
  }
1386
1385
  async function n() {
1387
- if (!X?.ready.value) return {
1386
+ if (!Z?.ready.value) return {
1388
1387
  success: !1,
1389
1388
  error: "Not connected"
1390
1389
  };
1391
- J.devices = [], J.isScanning = !0;
1390
+ X.devices = [], X.isScanning = !0;
1392
1391
  try {
1393
- let e = await X.request("cameras:rescan", {});
1394
- return e.success || (J.isScanning = !1), e;
1392
+ let e = await Z.request("cameras:rescan", {});
1393
+ return e.success || (X.isScanning = !1), e;
1395
1394
  } catch (e) {
1396
- return J.isScanning = !1, {
1395
+ return X.isScanning = !1, {
1397
1396
  success: !1,
1398
1397
  error: e instanceof Error ? e.message : "rescan failed"
1399
1398
  };
1400
1399
  }
1401
1400
  }
1402
1401
  async function r(e) {
1403
- if (!X?.ready.value) return {
1402
+ if (!Z?.ready.value) return {
1404
1403
  success: !1,
1405
1404
  error: "Not connected"
1406
1405
  };
1407
1406
  try {
1408
- return await X.request("cameras:get-schema", { discoveredId: e });
1407
+ return await Z.request("cameras:get-schema", { discoveredId: e });
1409
1408
  } catch (e) {
1410
1409
  return {
1411
1410
  success: !1,
@@ -1414,12 +1413,12 @@ function Hn() {
1414
1413
  }
1415
1414
  }
1416
1415
  async function i(e, t) {
1417
- if (!X?.ready.value) return {
1416
+ if (!Z?.ready.value) return {
1418
1417
  success: !1,
1419
1418
  error: "Not connected"
1420
1419
  };
1421
1420
  try {
1422
- return await X.request("cameras:connect", {
1421
+ return await Z.request("cameras:connect", {
1423
1422
  discoveredId: e,
1424
1423
  credentials: t
1425
1424
  });
@@ -1431,8 +1430,8 @@ function Hn() {
1431
1430
  }
1432
1431
  }
1433
1432
  async function a(e, t) {
1434
- if (!X?.ready.value) throw Error("Not connected");
1435
- let n = await X.request("cameras:prepare", {
1433
+ if (!Z?.ready.value) throw Error("Not connected");
1434
+ let n = await Z.request("cameras:prepare", {
1436
1435
  discoveredId: e,
1437
1436
  credentials: t
1438
1437
  });
@@ -1440,8 +1439,8 @@ function Hn() {
1440
1439
  return n.draft;
1441
1440
  }
1442
1441
  async function o(e, t) {
1443
- if (!X?.ready.value) throw Error("Not connected");
1444
- let n = await X.request("cameras:confirm", {
1442
+ if (!Z?.ready.value) throw Error("Not connected");
1443
+ let n = await Z.request("cameras:confirm", {
1445
1444
  draft: e,
1446
1445
  discoveredId: t
1447
1446
  });
@@ -1452,7 +1451,7 @@ function Hn() {
1452
1451
  };
1453
1452
  }
1454
1453
  async function s(e) {
1455
- if (!X?.ready.value) return {
1454
+ if (!Z?.ready.value) return {
1456
1455
  success: !1,
1457
1456
  error: "Not connected"
1458
1457
  };
@@ -1462,8 +1461,8 @@ function Hn() {
1462
1461
  model: e.model
1463
1462
  };
1464
1463
  try {
1465
- let e = await X.request("cameras:hide-device", { device: t });
1466
- return e.success && e.hiddenDevices && (J.hiddenDevices = e.hiddenDevices), e;
1464
+ let e = await Z.request("cameras:hide-device", { device: t });
1465
+ return e.success && e.hiddenDevices && (X.hiddenDevices = e.hiddenDevices), e;
1467
1466
  } catch (e) {
1468
1467
  return {
1469
1468
  success: !1,
@@ -1472,13 +1471,13 @@ function Hn() {
1472
1471
  }
1473
1472
  }
1474
1473
  async function c(e) {
1475
- if (!X?.ready.value) return {
1474
+ if (!Z?.ready.value) return {
1476
1475
  success: !1,
1477
1476
  error: "Not connected"
1478
1477
  };
1479
1478
  try {
1480
- let t = await X.request("cameras:unhide-device", { deviceId: e });
1481
- return t.success && t.hiddenDevices && (J.hiddenDevices = t.hiddenDevices), t;
1479
+ let t = await Z.request("cameras:unhide-device", { deviceId: e });
1480
+ return t.success && t.hiddenDevices && (X.hiddenDevices = t.hiddenDevices), t;
1482
1481
  } catch (e) {
1483
1482
  return {
1484
1483
  success: !1,
@@ -1487,32 +1486,32 @@ function Hn() {
1487
1486
  }
1488
1487
  }
1489
1488
  function l() {
1490
- J.showHidden = !J.showHidden;
1489
+ X.showHidden = !X.showHidden;
1491
1490
  }
1492
1491
  function u(e) {
1493
- return e.type !== "discovered" || !e.discoveredId ? !1 : J.hiddenDevices.some((t) => t.id === e.discoveredId);
1492
+ return e.type !== "discovered" || !e.discoveredId ? !1 : X.hiddenDevices.some((t) => t.id === e.discoveredId);
1494
1493
  }
1495
1494
  let d = v(() => {
1496
- let e = new Set(J.hiddenDevices.map((e) => e.id)), t = (e, t) => e.name.localeCompare(t.name), n = J.devices.filter((e) => e.type === "camera").sort(t), r = J.devices.filter((t) => t.type === "discovered" && !e.has(t.discoveredId)).sort(t), i = J.showHidden ? J.devices.filter((t) => t.type === "discovered" && e.has(t.discoveredId)).sort(t) : [];
1495
+ let e = new Set(X.hiddenDevices.map((e) => e.id)), t = (e, t) => e.name.localeCompare(t.name), n = X.devices.filter((e) => e.type === "camera").sort(t), r = X.devices.filter((t) => t.type === "discovered" && !e.has(t.discoveredId)).sort(t), i = X.showHidden ? X.devices.filter((t) => t.type === "discovered" && e.has(t.discoveredId)).sort(t) : [];
1497
1496
  return [
1498
1497
  ...n,
1499
1498
  ...r,
1500
1499
  ...i
1501
1500
  ];
1502
1501
  });
1503
- return me(() => {
1504
- Q--, !(Q > 0) && (Q = 0, $ = setTimeout(() => {
1505
- Q <= 0 && (Vn(), $ = null);
1506
- }, In));
1502
+ return pe(() => {
1503
+ $--, !($ > 0) && ($ = 0, In = setTimeout(() => {
1504
+ $ <= 0 && (Vn(), In = null);
1505
+ }, Pn));
1507
1506
  }), {
1508
- state: f(J),
1509
- isConnected: v(() => X?.connected.value ?? !1),
1510
- isLoading: v(() => J.isLoading),
1511
- devices: v(() => J.devices),
1512
- isScanning: v(() => J.isScanning),
1513
- hiddenDevices: v(() => J.hiddenDevices),
1514
- showHidden: v(() => J.showHidden),
1515
- error: v(() => J.error),
1507
+ state: f(X),
1508
+ isConnected: v(() => Z?.connected.value ?? !1),
1509
+ isLoading: v(() => X.isLoading),
1510
+ devices: v(() => X.devices),
1511
+ isScanning: v(() => X.isScanning),
1512
+ hiddenDevices: v(() => X.hiddenDevices),
1513
+ showHidden: v(() => X.showHidden),
1514
+ error: v(() => X.error),
1516
1515
  sortedDevices: d,
1517
1516
  connect: e,
1518
1517
  disconnect: t,
@@ -1555,15 +1554,15 @@ var Un = { class: "flex flex-col" }, Wn = {
1555
1554
  }, or = { class: "flex items-center justify-center" }, sr = { class: "flex items-center justify-center" }, cr = {
1556
1555
  key: 1,
1557
1556
  class: "flex flex-col items-center justify-center py-6 gap-2"
1558
- }, lr = { class: "text-muted text-sm" }, ur = { class: "flex flex-wrap items-center gap-2 mt-4" }, dr = /*#__PURE__*/ pe(/* @__PURE__ */ O({
1557
+ }, lr = { class: "text-muted text-sm" }, ur = { class: "flex flex-wrap items-center gap-2 mt-4" }, dr = /*#__PURE__*/ fe(/* @__PURE__ */ O({
1559
1558
  __name: "Cameras",
1560
1559
  setup(e) {
1561
- let { t } = W(), r = V(), i = H(), a = ce(), { smBreakpoint: c } = ie(), l = Hn(), d = {
1560
+ let { t } = K(), r = H(), i = B(), a = ae(), { smBreakpoint: c } = ne(), l = Hn(), d = {
1562
1561
  bodyRow: { class: "text-sm text-secondary" },
1563
1562
  column: { columnTitle: { class: "text-sm" } },
1564
1563
  datatable: { class: "z-0" }
1565
- }, f = v(() => fe(void 0, "admin")), h = v(() => l.sortedDevices.value), g = v(() => h.value.filter((e) => e.type === "camera")), b = v(() => h.value.filter((e) => e.type === "discovered")), w = v(() => l.isLoading.value), D = v(() => l.isScanning.value), O = v(() => l.hiddenDevices.value), k = v(() => l.showHidden.value), j = v(() => O.value.length);
1566
- function te(e) {
1564
+ }, f = v(() => G(void 0, "admin")), h = v(() => l.sortedDevices.value), g = v(() => h.value.filter((e) => e.type === "camera")), b = v(() => h.value.filter((e) => e.type === "discovered")), w = v(() => l.isLoading.value), D = v(() => l.isScanning.value), O = v(() => l.hiddenDevices.value), k = v(() => l.showHidden.value), j = v(() => O.value.length);
1565
+ function N(e) {
1567
1566
  switch (e) {
1568
1567
  case "added": return "green";
1569
1568
  case "discovered": return "orange";
@@ -1572,7 +1571,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1572
1571
  default: return "gray";
1573
1572
  }
1574
1573
  }
1575
- function N(e) {
1574
+ function P(e) {
1576
1575
  switch (e) {
1577
1576
  case "added": return t("views.devices.status_added");
1578
1577
  case "discovered": return t("views.devices.status_discovered");
@@ -1581,11 +1580,11 @@ var Un = { class: "flex flex-col" }, Wn = {
1581
1580
  default: return t("views.devices.status_unknown");
1582
1581
  }
1583
1582
  }
1584
- function P(e) {
1583
+ function F(e) {
1585
1584
  return l.isHidden(e);
1586
1585
  }
1587
- async function F(e) {
1588
- if (!P(e)) {
1586
+ async function I(e) {
1587
+ if (!F(e)) {
1589
1588
  if (e.type === "camera") {
1590
1589
  a.open({ cameraName: e.name });
1591
1590
  return;
@@ -1603,7 +1602,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1603
1602
  });
1604
1603
  return;
1605
1604
  }
1606
- i.openComponentDialog(Fn, { data: {
1605
+ i.openComponentDialog(Nn, { data: {
1607
1606
  title: `${t("views.devices.connect")}: ${e.name}`,
1608
1607
  confirmText: t("views.devices.connect"),
1609
1608
  contentProps: {
@@ -1617,7 +1616,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1617
1616
  },
1618
1617
  schema: n.schema ?? [],
1619
1618
  onConnect: async (t) => {
1620
- ne(await l.prepareDevice(e.discoveredId, t), e.discoveredId);
1619
+ L(await l.prepareDevice(e.discoveredId, t), e.discoveredId);
1621
1620
  }
1622
1621
  }
1623
1622
  } });
@@ -1632,8 +1631,8 @@ var Un = { class: "flex flex-col" }, Wn = {
1632
1631
  }
1633
1632
  }
1634
1633
  }
1635
- function ne(e, n) {
1636
- i.openComponentDialog(kn, { data: {
1634
+ function L(e, n) {
1635
+ i.openComponentDialog(Dn, { data: {
1637
1636
  title: t("views.devices.confirm_title"),
1638
1637
  confirmText: t("views.devices.confirm"),
1639
1638
  fullscreen: !0,
@@ -1650,7 +1649,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1650
1649
  }
1651
1650
  } });
1652
1651
  }
1653
- async function I() {
1652
+ async function R() {
1654
1653
  try {
1655
1654
  let e = await l.forceRescan();
1656
1655
  e.success ? r.add({
@@ -1673,14 +1672,14 @@ var Un = { class: "flex flex-col" }, Wn = {
1673
1672
  });
1674
1673
  }
1675
1674
  }
1676
- function L() {
1677
- i.openComponentDialog(wn, { data: {
1675
+ function te() {
1676
+ i.openComponentDialog(Sn, { data: {
1678
1677
  title: t("components.dialog.components.new_camera.add_camera"),
1679
1678
  fullscreen: !0,
1680
1679
  contentProps: {}
1681
1680
  } });
1682
1681
  }
1683
- async function R(e, n) {
1682
+ async function re(e, n) {
1684
1683
  e.stopPropagation();
1685
1684
  try {
1686
1685
  let e = await l.hideDevice(n);
@@ -1728,18 +1727,18 @@ var Un = { class: "flex flex-col" }, Wn = {
1728
1727
  });
1729
1728
  }
1730
1729
  }
1731
- function re() {
1730
+ function V() {
1732
1731
  l.toggleShowHidden();
1733
1732
  }
1734
- function B(e) {
1735
- return P(e) ? "opacity-50 cursor-not-allowed" : "";
1733
+ function U(e) {
1734
+ return F(e) ? "opacity-50 cursor-not-allowed" : "";
1736
1735
  }
1737
1736
  return M(() => {
1738
1737
  f.value && l.connect();
1739
1738
  }), n(() => {
1740
1739
  f.value && l.unsubscribe();
1741
1740
  }), (e, t) => {
1742
- let n = Ie, r = he, i = se, a = oe, l = G, v = Se, O = Ae, M = ke, ne = je, ie = Fe, V = ze, ce = ae, H = ee;
1741
+ let n = Pe, r = me, i = ie, a = se, l = q, v = xe, O = ke, M = Oe, L = Ae, ne = ue, ae = Le, B = oe, H = ee;
1743
1742
  return o(), x("div", Un, [
1744
1743
  _(c) ? m("", !0) : (o(), x("h1", Wn, s(e.$t(`views.${String(e.$route.name).toLowerCase()}.title`)), 1)),
1745
1744
  _(f) ? (o(), x(C, { key: 2 }, [
@@ -1755,16 +1754,16 @@ var Un = { class: "flex flex-col" }, Wn = {
1755
1754
  severity: "secondary",
1756
1755
  label: e.$t("views.devices.rescan"),
1757
1756
  loading: _(D),
1758
- onClick: I
1757
+ onClick: R
1759
1758
  }, null, 8, ["label", "loading"])
1760
1759
  ])) : m("", !0),
1761
1760
  !_(w) && _(g).length ? (o(), x("div", Qn, [T("span", $n, s(e.$t("views.devices.status_adopted_cameras")), 1), A(r, { class: "cui-card" }, {
1762
- content: y(() => [A(ne, {
1761
+ content: y(() => [A(L, {
1763
1762
  value: _(g),
1764
1763
  "striped-rows": "",
1765
1764
  pt: d,
1766
1765
  class: "w-full",
1767
- onRowClick: t[0] ||= (e) => F(e.data)
1766
+ onRowClick: t[0] ||= (e) => I(e.data)
1768
1767
  }, {
1769
1768
  default: y(() => [
1770
1769
  A(O, {
@@ -1772,7 +1771,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1772
1771
  "header-class": "p-2 pl-4 w-5 max-w-5",
1773
1772
  class: "p-2 pl-4 w-5 max-w-5"
1774
1773
  }, {
1775
- body: y(({ data: e }) => [T("div", er, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[H, { value: N(e.status) }]])])]),
1774
+ body: y(({ data: e }) => [T("div", er, [E(A(v, { style: S({ background: N(e.status) }) }, null, 8, ["style"]), [[H, { value: P(e.status) }]])])]),
1776
1775
  _: 1
1777
1776
  }),
1778
1777
  A(O, {
@@ -1822,12 +1821,12 @@ var Un = { class: "flex flex-col" }, Wn = {
1822
1821
  key: 3,
1823
1822
  class: u(["flex min-h-0 flex-col", { "mt-6": _(g).length }])
1824
1823
  }, [T("span", ir, s(e.$t("views.devices.status_discovered")), 1), A(r, { class: "cui-card" }, {
1825
- content: y(() => [_(b).length ? (o(), x("div", ar, [A(ne, {
1824
+ content: y(() => [_(b).length ? (o(), x("div", ar, [A(L, {
1826
1825
  value: _(b),
1827
1826
  "striped-rows": "",
1828
1827
  pt: d,
1829
1828
  class: "w-full",
1830
- onRowClick: t[1] ||= (e) => F(e.data)
1829
+ onRowClick: t[1] ||= (e) => I(e.data)
1831
1830
  }, {
1832
1831
  default: y(() => [
1833
1832
  A(O, {
@@ -1835,7 +1834,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1835
1834
  "header-class": "p-2 pl-4 w-5 max-w-5",
1836
1835
  class: "p-2 pl-4 w-5 max-w-5"
1837
1836
  }, {
1838
- body: y(({ data: e }) => [T("div", or, [E(A(v, { style: S({ background: te(e.status) }) }, null, 8, ["style"]), [[H, { value: N(e.status) }]])])]),
1837
+ body: y(({ data: e }) => [T("div", or, [E(A(v, { style: S({ background: N(e.status) }) }, null, 8, ["style"]), [[H, { value: P(e.status) }]])])]),
1839
1838
  _: 1
1840
1839
  }),
1841
1840
  A(O, {
@@ -1844,7 +1843,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1844
1843
  "header-class": "p-2",
1845
1844
  class: "p-2 w-full min-w-[200px] max-w-0"
1846
1845
  }, {
1847
- body: y(({ data: t }) => [T("div", { class: u(["font-bold text-color truncate", B(t)]) }, s(t.name), 3), T("div", { class: u(["text-xs text-muted truncate", B(t)]) }, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 3)]),
1846
+ body: y(({ data: t }) => [T("div", { class: u(["font-bold text-color truncate", U(t)]) }, s(t.name), 3), T("div", { class: u(["text-xs text-muted truncate", U(t)]) }, s(t.manufacturer || e.$t("views.devices.unknown")) + " · " + s(t.model || e.$t("views.devices.unknown")), 3)]),
1848
1847
  _: 1
1849
1848
  }, 8, ["header"]),
1850
1849
  A(O, {
@@ -1855,7 +1854,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1855
1854
  }, {
1856
1855
  body: y(({ data: e }) => [e.address ? (o(), x("span", {
1857
1856
  key: 0,
1858
- class: u(["text-xs text-muted whitespace-nowrap", B(e)])
1857
+ class: u(["text-xs text-muted whitespace-nowrap", U(e)])
1859
1858
  }, s(e.address), 3)) : m("", !0)]),
1860
1859
  _: 1
1861
1860
  }, 8, ["header"]),
@@ -1867,7 +1866,7 @@ var Un = { class: "flex flex-col" }, Wn = {
1867
1866
  }, {
1868
1867
  body: y(({ data: e }) => [A(M, {
1869
1868
  label: e.provider,
1870
- class: u(["text-xs whitespace-nowrap", B(e)])
1869
+ class: u(["text-xs whitespace-nowrap", U(e)])
1871
1870
  }, null, 8, ["label", "class"])]),
1872
1871
  _: 1
1873
1872
  }, 8, ["header"]),
@@ -1876,14 +1875,14 @@ var Un = { class: "flex flex-col" }, Wn = {
1876
1875
  "header-class": "p-2 pr-4 w-12",
1877
1876
  class: "p-2 pr-4 w-12"
1878
1877
  }, {
1879
- body: y(({ data: t }) => [T("div", sr, [P(t) ? E((o(), p(l, {
1878
+ body: y(({ data: t }) => [T("div", sr, [F(t) ? E((o(), p(l, {
1880
1879
  key: 1,
1881
1880
  text: "",
1882
1881
  rounded: "",
1883
1882
  class: "cui-icon-md",
1884
1883
  onClick: (e) => z(e, t)
1885
1884
  }, {
1886
- icon: y(() => [A(_(Be), {
1885
+ icon: y(() => [A(_(Re), {
1887
1886
  width: "100%",
1888
1887
  height: "100%",
1889
1888
  class: "text-muted"
@@ -1900,9 +1899,9 @@ var Un = { class: "flex flex-col" }, Wn = {
1900
1899
  text: "",
1901
1900
  rounded: "",
1902
1901
  class: "cui-icon-md",
1903
- onClick: (e) => R(e, t)
1902
+ onClick: (e) => re(e, t)
1904
1903
  }, {
1905
- icon: y(() => [A(_(Ve), {
1904
+ icon: y(() => [A(_(ze), {
1906
1905
  width: "100%",
1907
1906
  height: "100%",
1908
1907
  class: "text-muted"
@@ -1918,12 +1917,12 @@ var Un = { class: "flex flex-col" }, Wn = {
1918
1917
  })
1919
1918
  ]),
1920
1919
  _: 1
1921
- }, 8, ["value"])])) : (o(), x("div", cr, [_(D) ? (o(), p(ie, {
1920
+ }, 8, ["value"])])) : (o(), x("div", cr, [_(D) ? (o(), p(ne, {
1922
1921
  key: 0,
1923
1922
  width: "24px",
1924
1923
  height: "24px",
1925
1924
  class: "text-muted"
1926
- })) : (o(), p(V, {
1925
+ })) : (o(), p(ae, {
1927
1926
  key: 1,
1928
1927
  width: "32px",
1929
1928
  height: "32px",
@@ -1935,14 +1934,14 @@ var Un = { class: "flex flex-col" }, Wn = {
1935
1934
  severity: "secondary",
1936
1935
  class: "cui-button-medium",
1937
1936
  label: _(k) ? e.$t("views.devices.hide_hidden") : `${e.$t("views.devices.show_hidden")} (${_(j)})`,
1938
- onClick: re
1937
+ onClick: V
1939
1938
  }, null, 8, ["label"])) : m("", !0),
1940
1939
  A(l, {
1941
1940
  severity: "secondary",
1942
1941
  class: "cui-button-medium",
1943
1942
  label: e.$t("views.devices.rescan"),
1944
1943
  loading: _(D),
1945
- onClick: I
1944
+ onClick: R
1946
1945
  }, null, 8, ["label", "loading"])
1947
1946
  ])]),
1948
1947
  _: 1
@@ -1951,16 +1950,16 @@ var Un = { class: "flex flex-col" }, Wn = {
1951
1950
  content: y(() => [A(n)]),
1952
1951
  _: 1
1953
1952
  })])),
1954
- ("hasPermission" in e ? e.hasPermission : _(fe))(void 0, "admin") ? (o(), p(ce, {
1953
+ ("hasPermission" in e ? e.hasPermission : _(G))(void 0, "admin") ? (o(), p(B, {
1955
1954
  key: 3,
1956
1955
  "tooltip-props": { value: e.$t("views.cameras.add_camera") },
1957
1956
  "button-props": { class: "text-white" },
1958
- icon: _(Re),
1957
+ icon: _(Ie),
1959
1958
  "icon-props": {
1960
1959
  width: "30px",
1961
1960
  height: "30px"
1962
1961
  },
1963
- onClick: L
1962
+ onClick: te
1964
1963
  }, null, 8, ["tooltip-props", "icon"])) : m("", !0)
1965
1964
  ]);
1966
1965
  };