mycelium-ai 0.5.0__py3-none-any.whl

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 (164) hide show
  1. mycelium/__init__.py +0 -0
  2. mycelium/api/__init__.py +0 -0
  3. mycelium/api/app.py +1147 -0
  4. mycelium/api/client_app.py +170 -0
  5. mycelium/api/generated_sources/__init__.py +0 -0
  6. mycelium/api/generated_sources/server_schemas/__init__.py +97 -0
  7. mycelium/api/generated_sources/server_schemas/api/__init__.py +5 -0
  8. mycelium/api/generated_sources/server_schemas/api/default_api.py +2473 -0
  9. mycelium/api/generated_sources/server_schemas/api_client.py +766 -0
  10. mycelium/api/generated_sources/server_schemas/api_response.py +25 -0
  11. mycelium/api/generated_sources/server_schemas/configuration.py +434 -0
  12. mycelium/api/generated_sources/server_schemas/exceptions.py +166 -0
  13. mycelium/api/generated_sources/server_schemas/models/__init__.py +41 -0
  14. mycelium/api/generated_sources/server_schemas/models/api_section.py +71 -0
  15. mycelium/api/generated_sources/server_schemas/models/chroma_section.py +69 -0
  16. mycelium/api/generated_sources/server_schemas/models/clap_section.py +75 -0
  17. mycelium/api/generated_sources/server_schemas/models/compute_on_server200_response.py +79 -0
  18. mycelium/api/generated_sources/server_schemas/models/compute_on_server_request.py +67 -0
  19. mycelium/api/generated_sources/server_schemas/models/compute_text_search_request.py +69 -0
  20. mycelium/api/generated_sources/server_schemas/models/config_request.py +81 -0
  21. mycelium/api/generated_sources/server_schemas/models/config_response.py +107 -0
  22. mycelium/api/generated_sources/server_schemas/models/create_playlist_request.py +71 -0
  23. mycelium/api/generated_sources/server_schemas/models/get_similar_by_track200_response.py +143 -0
  24. mycelium/api/generated_sources/server_schemas/models/library_stats_response.py +77 -0
  25. mycelium/api/generated_sources/server_schemas/models/logging_section.py +67 -0
  26. mycelium/api/generated_sources/server_schemas/models/media_server_section.py +67 -0
  27. mycelium/api/generated_sources/server_schemas/models/playlist_response.py +73 -0
  28. mycelium/api/generated_sources/server_schemas/models/plex_section.py +71 -0
  29. mycelium/api/generated_sources/server_schemas/models/processing_response.py +90 -0
  30. mycelium/api/generated_sources/server_schemas/models/save_config_response.py +73 -0
  31. mycelium/api/generated_sources/server_schemas/models/scan_library_response.py +75 -0
  32. mycelium/api/generated_sources/server_schemas/models/search_result_response.py +75 -0
  33. mycelium/api/generated_sources/server_schemas/models/server_section.py +67 -0
  34. mycelium/api/generated_sources/server_schemas/models/stop_processing_response.py +71 -0
  35. mycelium/api/generated_sources/server_schemas/models/task_status_response.py +87 -0
  36. mycelium/api/generated_sources/server_schemas/models/track_database_stats.py +75 -0
  37. mycelium/api/generated_sources/server_schemas/models/track_response.py +77 -0
  38. mycelium/api/generated_sources/server_schemas/models/tracks_list_response.py +81 -0
  39. mycelium/api/generated_sources/server_schemas/rest.py +329 -0
  40. mycelium/api/generated_sources/server_schemas/test/__init__.py +0 -0
  41. mycelium/api/generated_sources/server_schemas/test/test_api_section.py +57 -0
  42. mycelium/api/generated_sources/server_schemas/test/test_chroma_section.py +55 -0
  43. mycelium/api/generated_sources/server_schemas/test/test_clap_section.py +60 -0
  44. mycelium/api/generated_sources/server_schemas/test/test_compute_on_server200_response.py +52 -0
  45. mycelium/api/generated_sources/server_schemas/test/test_compute_on_server_request.py +53 -0
  46. mycelium/api/generated_sources/server_schemas/test/test_compute_text_search_request.py +54 -0
  47. mycelium/api/generated_sources/server_schemas/test/test_config_request.py +66 -0
  48. mycelium/api/generated_sources/server_schemas/test/test_config_response.py +97 -0
  49. mycelium/api/generated_sources/server_schemas/test/test_create_playlist_request.py +60 -0
  50. mycelium/api/generated_sources/server_schemas/test/test_default_api.py +150 -0
  51. mycelium/api/generated_sources/server_schemas/test/test_get_similar_by_track200_response.py +61 -0
  52. mycelium/api/generated_sources/server_schemas/test/test_library_stats_response.py +63 -0
  53. mycelium/api/generated_sources/server_schemas/test/test_logging_section.py +53 -0
  54. mycelium/api/generated_sources/server_schemas/test/test_media_server_section.py +53 -0
  55. mycelium/api/generated_sources/server_schemas/test/test_playlist_response.py +58 -0
  56. mycelium/api/generated_sources/server_schemas/test/test_plex_section.py +56 -0
  57. mycelium/api/generated_sources/server_schemas/test/test_processing_response.py +61 -0
  58. mycelium/api/generated_sources/server_schemas/test/test_save_config_response.py +58 -0
  59. mycelium/api/generated_sources/server_schemas/test/test_scan_library_response.py +61 -0
  60. mycelium/api/generated_sources/server_schemas/test/test_search_result_response.py +69 -0
  61. mycelium/api/generated_sources/server_schemas/test/test_server_section.py +53 -0
  62. mycelium/api/generated_sources/server_schemas/test/test_stop_processing_response.py +55 -0
  63. mycelium/api/generated_sources/server_schemas/test/test_task_status_response.py +71 -0
  64. mycelium/api/generated_sources/server_schemas/test/test_track_database_stats.py +60 -0
  65. mycelium/api/generated_sources/server_schemas/test/test_track_response.py +63 -0
  66. mycelium/api/generated_sources/server_schemas/test/test_tracks_list_response.py +75 -0
  67. mycelium/api/generated_sources/worker_schemas/__init__.py +61 -0
  68. mycelium/api/generated_sources/worker_schemas/api/__init__.py +5 -0
  69. mycelium/api/generated_sources/worker_schemas/api/default_api.py +318 -0
  70. mycelium/api/generated_sources/worker_schemas/api_client.py +766 -0
  71. mycelium/api/generated_sources/worker_schemas/api_response.py +25 -0
  72. mycelium/api/generated_sources/worker_schemas/configuration.py +434 -0
  73. mycelium/api/generated_sources/worker_schemas/exceptions.py +166 -0
  74. mycelium/api/generated_sources/worker_schemas/models/__init__.py +23 -0
  75. mycelium/api/generated_sources/worker_schemas/models/save_config_response.py +73 -0
  76. mycelium/api/generated_sources/worker_schemas/models/worker_clap_section.py +75 -0
  77. mycelium/api/generated_sources/worker_schemas/models/worker_client_api_section.py +69 -0
  78. mycelium/api/generated_sources/worker_schemas/models/worker_client_section.py +79 -0
  79. mycelium/api/generated_sources/worker_schemas/models/worker_config_request.py +73 -0
  80. mycelium/api/generated_sources/worker_schemas/models/worker_config_response.py +89 -0
  81. mycelium/api/generated_sources/worker_schemas/models/worker_logging_section.py +67 -0
  82. mycelium/api/generated_sources/worker_schemas/rest.py +329 -0
  83. mycelium/api/generated_sources/worker_schemas/test/__init__.py +0 -0
  84. mycelium/api/generated_sources/worker_schemas/test/test_default_api.py +45 -0
  85. mycelium/api/generated_sources/worker_schemas/test/test_save_config_response.py +58 -0
  86. mycelium/api/generated_sources/worker_schemas/test/test_worker_clap_section.py +60 -0
  87. mycelium/api/generated_sources/worker_schemas/test/test_worker_client_api_section.py +55 -0
  88. mycelium/api/generated_sources/worker_schemas/test/test_worker_client_section.py +65 -0
  89. mycelium/api/generated_sources/worker_schemas/test/test_worker_config_request.py +59 -0
  90. mycelium/api/generated_sources/worker_schemas/test/test_worker_config_response.py +89 -0
  91. mycelium/api/generated_sources/worker_schemas/test/test_worker_logging_section.py +53 -0
  92. mycelium/api/worker_models.py +99 -0
  93. mycelium/application/__init__.py +11 -0
  94. mycelium/application/job_queue.py +323 -0
  95. mycelium/application/library_management_use_cases.py +292 -0
  96. mycelium/application/search_use_cases.py +96 -0
  97. mycelium/application/services.py +340 -0
  98. mycelium/client.py +554 -0
  99. mycelium/client_config.py +251 -0
  100. mycelium/client_frontend_dist/404.html +1 -0
  101. mycelium/client_frontend_dist/_next/static/a4iyRdfsvkjdyMAK9cE9Y/_buildManifest.js +1 -0
  102. mycelium/client_frontend_dist/_next/static/a4iyRdfsvkjdyMAK9cE9Y/_ssgManifest.js +1 -0
  103. mycelium/client_frontend_dist/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +1 -0
  104. mycelium/client_frontend_dist/_next/static/chunks/964-830f77d7ce1c2463.js +1 -0
  105. mycelium/client_frontend_dist/_next/static/chunks/app/_not-found/page-d25eede5a9099bd3.js +1 -0
  106. mycelium/client_frontend_dist/_next/static/chunks/app/layout-9b3d32f96dfe13b6.js +1 -0
  107. mycelium/client_frontend_dist/_next/static/chunks/app/page-cc6bad295789134e.js +1 -0
  108. mycelium/client_frontend_dist/_next/static/chunks/framework-7c95b8e5103c9e90.js +1 -0
  109. mycelium/client_frontend_dist/_next/static/chunks/main-6b37be50736577a2.js +1 -0
  110. mycelium/client_frontend_dist/_next/static/chunks/main-app-4153d115599d3126.js +1 -0
  111. mycelium/client_frontend_dist/_next/static/chunks/pages/_app-0a0020ddd67f79cf.js +1 -0
  112. mycelium/client_frontend_dist/_next/static/chunks/pages/_error-03529f2c21436739.js +1 -0
  113. mycelium/client_frontend_dist/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  114. mycelium/client_frontend_dist/_next/static/chunks/webpack-c81e624915b2ea70.js +1 -0
  115. mycelium/client_frontend_dist/_next/static/css/1eb7f0e2c78e0734.css +1 -0
  116. mycelium/client_frontend_dist/favicon.ico +0 -0
  117. mycelium/client_frontend_dist/file.svg +1 -0
  118. mycelium/client_frontend_dist/globe.svg +1 -0
  119. mycelium/client_frontend_dist/index.html +1 -0
  120. mycelium/client_frontend_dist/index.txt +20 -0
  121. mycelium/client_frontend_dist/next.svg +1 -0
  122. mycelium/client_frontend_dist/vercel.svg +1 -0
  123. mycelium/client_frontend_dist/window.svg +1 -0
  124. mycelium/config.py +346 -0
  125. mycelium/domain/__init__.py +13 -0
  126. mycelium/domain/models.py +71 -0
  127. mycelium/domain/repositories.py +98 -0
  128. mycelium/domain/worker.py +77 -0
  129. mycelium/frontend_dist/404.html +1 -0
  130. mycelium/frontend_dist/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +1 -0
  131. mycelium/frontend_dist/_next/static/chunks/964-830f77d7ce1c2463.js +1 -0
  132. mycelium/frontend_dist/_next/static/chunks/app/_not-found/page-d25eede5a9099bd3.js +1 -0
  133. mycelium/frontend_dist/_next/static/chunks/app/layout-9b3d32f96dfe13b6.js +1 -0
  134. mycelium/frontend_dist/_next/static/chunks/app/page-a761463485e0540b.js +1 -0
  135. mycelium/frontend_dist/_next/static/chunks/framework-7c95b8e5103c9e90.js +1 -0
  136. mycelium/frontend_dist/_next/static/chunks/main-6b37be50736577a2.js +1 -0
  137. mycelium/frontend_dist/_next/static/chunks/main-app-4153d115599d3126.js +1 -0
  138. mycelium/frontend_dist/_next/static/chunks/pages/_app-0a0020ddd67f79cf.js +1 -0
  139. mycelium/frontend_dist/_next/static/chunks/pages/_error-03529f2c21436739.js +1 -0
  140. mycelium/frontend_dist/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  141. mycelium/frontend_dist/_next/static/chunks/webpack-c81e624915b2ea70.js +1 -0
  142. mycelium/frontend_dist/_next/static/css/1eb7f0e2c78e0734.css +1 -0
  143. mycelium/frontend_dist/_next/static/glVJ0yJSL0zWN7anTTG3_/_buildManifest.js +1 -0
  144. mycelium/frontend_dist/_next/static/glVJ0yJSL0zWN7anTTG3_/_ssgManifest.js +1 -0
  145. mycelium/frontend_dist/favicon.ico +0 -0
  146. mycelium/frontend_dist/file.svg +1 -0
  147. mycelium/frontend_dist/globe.svg +1 -0
  148. mycelium/frontend_dist/index.html +10 -0
  149. mycelium/frontend_dist/index.txt +20 -0
  150. mycelium/frontend_dist/next.svg +1 -0
  151. mycelium/frontend_dist/vercel.svg +1 -0
  152. mycelium/frontend_dist/window.svg +1 -0
  153. mycelium/infrastructure/__init__.py +17 -0
  154. mycelium/infrastructure/chroma_adapter.py +232 -0
  155. mycelium/infrastructure/clap_adapter.py +280 -0
  156. mycelium/infrastructure/plex_adapter.py +145 -0
  157. mycelium/infrastructure/track_database.py +467 -0
  158. mycelium/main.py +183 -0
  159. mycelium_ai-0.5.0.dist-info/METADATA +312 -0
  160. mycelium_ai-0.5.0.dist-info/RECORD +164 -0
  161. mycelium_ai-0.5.0.dist-info/WHEEL +5 -0
  162. mycelium_ai-0.5.0.dist-info/entry_points.txt +2 -0
  163. mycelium_ai-0.5.0.dist-info/licenses/LICENSE +21 -0
  164. mycelium_ai-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[974],{5766:(e,r,t)=>{Promise.resolve().then(t.bind(t,9358))},9358:(e,r,t)=>{"use strict";t.r(r),t.d(r,{default:()=>K});var a=t(5155),s=t(2115),l=t(9509);let n=(()=>{{let e,r=window.location.protocol,t=window.location.hostname;return e=l.env.NEXT_PUBLIC_API_PORT?l.env.NEXT_PUBLIC_API_PORT:"client"===l.env.NEXT_PUBLIC_MYCELIUM_MODE?"8001":"8000",e=l.env.NEXT_PUBLIC_API_PORT||"8000","".concat(r,"//").concat(t,":").concat(e)}})(),i="client"===l.env.NEXT_PUBLIC_MYCELIUM_MODE,o=(()=>{{let e=window.location.protocol,r=window.location.hostname,t=l.env.NEXT_PUBLIC_WORKER_API_PORT||"8001";return"".concat(e,"//").concat(r,":").concat(t)}})();function d(e){let{isOpen:r,onClose:t,trackIds:l,onSuccess:i}=e,[o,d]=(0,s.useState)(""),[c,u]=(0,s.useState)(!1),[g,m]=(0,s.useState)(null),x=async()=>{if(!o.trim())return void m("Please enter a playlist name");u(!0),m(null);try{let e=await fetch("".concat(n,"/api/playlists/create"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:o.trim(),track_ids:l})});if(!e.ok){let r=await e.json().catch(()=>({}));throw Error(r.detail||"Failed to create playlist")}await e.json(),i(o.trim()),t(),d("")}catch(e){m(e instanceof Error?e.message:"An error occurred")}finally{u(!1)}},h=()=>{c||(t(),d(""),m(null))};return r?(0,a.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg p-6 w-full max-w-md mx-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83C\uDFB5 Create Playlist"}),(0,a.jsx)("button",{onClick:h,disabled:c,className:"text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 disabled:opacity-50",children:(0,a.jsx)("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 18L18 6M6 6l12 12"})})})]}),(0,a.jsxs)("div",{className:"mb-4",children:[(0,a.jsxs)("p",{className:"text-sm text-gray-600 dark:text-gray-300 mb-4",children:["Create a playlist with ",l.length," track",1!==l.length?"s":""," from your recommendations."]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{htmlFor:"playlist-name",className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Playlist Name"}),(0,a.jsx)("input",{id:"playlist-name",type:"text",value:o,onChange:e=>d(e.target.value),onKeyPress:e=>"Enter"===e.key&&x(),placeholder:"Enter playlist name...",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent dark:bg-gray-700 dark:text-white",autoFocus:!0,disabled:c})]}),g&&(0,a.jsx)("div",{className:"mt-3 p-3 bg-red-100 dark:bg-red-900 border border-red-300 dark:border-red-700 rounded-lg",children:(0,a.jsx)("p",{className:"text-sm text-red-700 dark:text-red-300",children:g})})]}),(0,a.jsxs)("div",{className:"flex space-x-3",children:[(0,a.jsx)("button",{onClick:h,disabled:c,className:"flex-1 px-4 py-2 text-gray-600 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed",children:"Cancel"}),(0,a.jsx)("button",{onClick:x,disabled:c||!o.trim(),className:"flex-1 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center",children:c?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4 text-white",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"Creating..."]}):"Create Playlist"})]})]})}):null}function c(e){let{results:r,loading:t}=e,[l,n]=(0,s.useState)(!1),[i,o]=(0,s.useState)(null);if(t)return(0,a.jsx)("div",{className:"space-y-4",children:[void 0,void 0,void 0,void 0,void 0].map((e,r)=>(0,a.jsx)("div",{className:"animate-pulse",children:(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-20 rounded-lg"})},r))});if(0===r.length)return(0,a.jsxs)("div",{className:"text-center py-12",children:[(0,a.jsx)("div",{className:"text-6xl mb-4",children:"\uD83C\uDFAF"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400",children:"Search for music using natural language descriptions"}),(0,a.jsx)("p",{className:"text-sm text-gray-400 dark:text-gray-500 mt-2",children:"Try searching for moods, genres, instruments, or vibes"})]});let c=r.map(e=>"".concat(e.track.media_server_rating_key));return(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:["Found ",r.length," similar tracks"]}),r.length>0&&(0,a.jsxs)("button",{onClick:()=>n(!0),className:"px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center space-x-2",children:[(0,a.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 4v16m8-8H4"})}),(0,a.jsx)("span",{children:"Create Playlist"})]})]}),i&&(0,a.jsx)("div",{className:"mb-4 p-4 bg-green-100 dark:bg-green-900 border border-green-300 dark:border-green-700 rounded-lg",children:(0,a.jsxs)("p",{className:"text-green-700 dark:text-green-300 flex items-center",children:[(0,a.jsx)("svg",{className:"w-5 h-5 mr-2",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M5 13l4 4L19 7"})}),i]})}),r.map((e,r)=>(0,a.jsxs)("div",{className:"bg-gray-50 dark:bg-gray-700 rounded-lg p-4 hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsxs)("div",{className:"text-lg font-medium text-purple-600 dark:text-purple-400",children:["#",r+1]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"font-medium text-gray-900 dark:text-white",children:e.track.title}),(0,a.jsxs)("p",{className:"text-gray-600 dark:text-gray-300",children:[e.track.artist," • ",e.track.album]})]})]})}),(0,a.jsxs)("div",{className:"text-right",children:[(0,a.jsxs)("div",{className:"text-sm font-medium text-gray-900 dark:text-white",children:[Math.round(100*e.similarity_score),"% match"]}),(0,a.jsxs)("div",{className:"text-xs text-gray-500 dark:text-gray-400",children:["Distance: ",e.distance.toFixed(3)]})]})]}),(0,a.jsx)("div",{className:"mt-3",children:(0,a.jsx)("div",{className:"w-full bg-gray-200 dark:bg-gray-600 rounded-full h-2",children:(0,a.jsx)("div",{className:"bg-gradient-to-r from-purple-500 to-pink-500 h-2 rounded-full transition-all duration-300",style:{width:"".concat(Math.round(100*e.similarity_score),"%")}})})}),(0,a.jsx)("div",{className:"mt-2 text-xs text-gray-400 dark:text-gray-500 font-mono",children:e.track.filepath.length>60?"..."+e.track.filepath.slice(-60):e.track.filepath})]},"".concat(e.track.media_server_rating_key))),(0,a.jsx)(d,{isOpen:l,onClose:()=>n(!1),trackIds:c,onSuccess:e=>{o('Successfully created playlist "'.concat(e,'" with ').concat(r.length," tracks!")),setTimeout(()=>o(null),5e3)}})]})}let u="http://localhost:8000".replace(/\/+$/,"");class g{set config(e){this.configuration=e}get basePath(){return null!=this.configuration.basePath?this.configuration.basePath:u}get fetchApi(){return this.configuration.fetchApi}get middleware(){return this.configuration.middleware||[]}get queryParamsStringify(){return this.configuration.queryParamsStringify||function e(r){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.keys(r).map(a=>(function r(t,a){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",l=s+(s.length?"[".concat(t,"]"):t);if(a instanceof Array){let e=a.map(e=>encodeURIComponent(String(e))).join("&".concat(encodeURIComponent(l),"="));return"".concat(encodeURIComponent(l),"=").concat(e)}return a instanceof Set?r(t,Array.from(a),s):a instanceof Date?"".concat(encodeURIComponent(l),"=").concat(encodeURIComponent(a.toISOString())):a instanceof Object?e(a,l):"".concat(encodeURIComponent(l),"=").concat(encodeURIComponent(String(a)))})(a,r[a],t)).filter(e=>e.length>0).join("&")}}get username(){return this.configuration.username}get password(){return this.configuration.password}get apiKey(){let e=this.configuration.apiKey;if(e)return"function"==typeof e?e:()=>e}get accessToken(){let e=this.configuration.accessToken;if(e)return"function"==typeof e?e:async()=>e}get headers(){return this.configuration.headers}get credentials(){return this.configuration.credentials}constructor(e={}){this.configuration=e}}let m=new g;class x{withMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=this.clone();return a.middleware=a.middleware.concat(...r),a}withPreMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=r.map(e=>({pre:e}));return this.withMiddleware(...a)}withPostMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=r.map(e=>({post:e}));return this.withMiddleware(...a)}isJsonMime(e){return!!e&&x.jsonRegex.test(e)}async request(e,r){let{url:t,init:a}=await this.createFetchParams(e,r),s=await this.fetchApi(t,a);if(s&&s.status>=200&&s.status<300)return s;throw new h(s,"Response returned an error code")}async createFetchParams(e,r){var t,a;let s,l=this.configuration.basePath+e.path;void 0!==e.query&&0!==Object.keys(e.query).length&&(l+="?"+this.configuration.queryParamsStringify(e.query));let n=Object.assign({},this.configuration.headers,e.headers);Object.keys(n).forEach(e=>void 0===n[e]?delete n[e]:{});let i={method:e.method,headers:n,body:e.body,credentials:this.configuration.credentials},o={...i,...await ("function"==typeof r?r:async()=>r)({init:i,context:e})};return t=o.body,s="undefined"!=typeof FormData&&t instanceof FormData||o.body instanceof URLSearchParams||(a=o.body,"undefined"!=typeof Blob&&a instanceof Blob)?o.body:this.isJsonMime(n["Content-Type"])?JSON.stringify(o.body):o.body,{url:l,init:{...o,body:s}}}clone(){let e=new this.constructor(this.configuration);return e.middleware=this.middleware.slice(),e}constructor(e=m){this.configuration=e,this.fetchApi=async(e,r)=>{let t,a={url:e,init:r};for(let e of this.middleware)e.pre&&(a=await e.pre({fetch:this.fetchApi,...a})||a);try{t=await (this.configuration.fetchApi||fetch)(a.url,a.init)}catch(e){for(let r of this.middleware)r.onError&&(t=await r.onError({fetch:this.fetchApi,url:a.url,init:a.init,error:e,response:t?t.clone():void 0})||t);if(void 0===t)if(e instanceof Error)throw new p(e,"The request failed and the interceptors did not return an alternative response");else throw e}for(let e of this.middleware)e.post&&(t=await e.post({fetch:this.fetchApi,url:a.url,init:a.init,response:t.clone()})||t);return t},this.middleware=e.middleware}}x.jsonRegex=RegExp("^(:?application/json|[^;/ ]+/[^;/ ]+[+]json)[ ]*(:?;.*)?$","i");class h extends Error{constructor(e,r){super(r),this.response=e,this.name="ResponseError"}}class p extends Error{constructor(e,r){super(r),this.cause=e,this.name="FetchError"}}class y extends Error{constructor(e,r){super(r),this.field=e,this.name="RequiredError"}}function b(e){for(let r of e)if("multipart/form-data"===r.contentType)return!0;return!1}class k{async value(){return this.transformer(await this.raw.json())}constructor(e,r=e=>e){this.raw=e,this.transformer=r}}function v(e,r){return null==e?e:{status:e.status,message:null==e.message?void 0:e.message,task_id:null==e.task_id?void 0:e.task_id,track_id:null==e.track_id?void 0:e.track_id,query:null==e.query?void 0:e.query,filename:null==e.filename?void 0:e.filename,active_workers:null==e.active_workers?void 0:e.active_workers,tasks_created:null==e.tasks_created?void 0:e.tasks_created,confirmation_required:null==e.confirmation_required?void 0:e.confirmation_required}}function f(e){var r;return null==(r=e)?r:{artist:r.artist,album:r.album,title:r.title,filepath:r.filepath,media_server_rating_key:r.media_server_rating_key,media_server_type:r.media_server_type}}function w(e){return j(e,!1)}function j(e,r){return null==e?e:{track:f(e.track),similarity_score:e.similarity_score,distance:e.distance}}function N(e,r){return null==e?e:{total_tracks:e.total_tracks,processed_tracks:e.processed_tracks,unprocessed_tracks:e.unprocessed_tracks,progress_percentage:e.progress_percentage,is_processing:null==e.is_processing?void 0:e.is_processing}}class _ extends x{async computeAudioSearchRaw(e,r){let t,a=b([{contentType:"multipart/form-data"}]);return t=a?new FormData:new URLSearchParams,null!=e.audio&&t.append("audio",e.audio),null!=e.nResults&&t.append("n_results",e.nResults),new k(await this.request({path:"/compute/search/audio",method:"POST",headers:{},query:{},body:t},r),e=>e.map(w))}async computeAudioSearch(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0,t=await this.computeAudioSearchRaw(e,r);return await t.value()}async computeOnServerRaw(e,r){if(null==e.computeOnServerRequest)throw new y("computeOnServerRequest",'Required parameter "computeOnServerRequest" was null or undefined when calling computeOnServer().');let t={};return t["Content-Type"]="application/json",new k(await this.request({path:"/compute/on_server",method:"POST",headers:t,query:{},body:function(e){return(arguments.length>1&&void 0!==arguments[1]&&arguments[1],null==e)?e:{track_id:e.track_id}}(e.computeOnServerRequest,!1)},r),e=>{var r;return null==(r=e)?r:{...r,message:null==r.message?void 0:r.message}})}async computeOnServer(e,r){let t=await this.computeOnServerRaw(e,r);return await t.value()}async computeTextSearchRaw(e,r){if(null==e.computeTextSearchRequest)throw new y("computeTextSearchRequest",'Required parameter "computeTextSearchRequest" was null or undefined when calling computeTextSearch().');let t={};return t["Content-Type"]="application/json",new k(await this.request({path:"/compute/search/text",method:"POST",headers:t,query:{},body:function(e){return(arguments.length>1&&void 0!==arguments[1]&&arguments[1],null==e)?e:{query:e.query,n_results:e.n_results}}(e.computeTextSearchRequest,!1)},r),e=>e.map(w))}async computeTextSearch(e,r){let t=await this.computeTextSearchRaw(e,r);return await t.value()}async createPlaylistRaw(e,r){if(null==e.createPlaylistRequest)throw new y("createPlaylistRequest",'Required parameter "createPlaylistRequest" was null or undefined when calling createPlaylist().');let t={};return t["Content-Type"]="application/json",new k(await this.request({path:"/api/playlists/create",method:"POST",headers:t,query:{},body:function(e){return(arguments.length>1&&void 0!==arguments[1]&&arguments[1],null==e)?e:{name:e.name,track_ids:e.track_ids,batch_size:e.batch_size}}(e.createPlaylistRequest,!1)},r),e=>{var r;return null==(r=e)?r:{name:r.name,track_count:r.track_count,created_at:r.created_at,server_id:null==r.server_id?void 0:r.server_id}})}async createPlaylist(e,r){let t=await this.createPlaylistRaw(e,r);return await t.value()}async getConfigRaw(e){return new k(await this.request({path:"/api/config",method:"GET",headers:{},query:{}},e),e=>(function(e,r){var t,a,s,l,n,i,o;if(null==e)return e;return{media_server:(t=e.media_server,null==t?t:{type:t.type}),plex:(a=e.plex,null==a?a:{url:a.url,token:null==a.token?void 0:a.token,music_library_name:a.music_library_name}),server:(s=e.server,null==s?s:{gpu_batch_size:s.gpu_batch_size}),api:(l=e.api,null==l?l:{host:l.host,port:l.port,reload:l.reload}),chroma:(n=e.chroma,null==n?n:{collection_name:n.collection_name,batch_size:n.batch_size}),clap:(i=e.clap,null==i?i:{model_id:i.model_id,target_sr:i.target_sr,chunk_duration_s:i.chunk_duration_s,num_chunks:i.num_chunks,max_load_duration_s:null==i.max_load_duration_s?void 0:i.max_load_duration_s}),logging:(o=e.logging,null==o?o:{level:o.level})}})(e,0))}async getConfig(e){let r=await this.getConfigRaw(e);return await r.value()}async getLibraryStatsRaw(e){return new k(await this.request({path:"/api/library/stats",method:"GET",headers:{},query:{}},e),e=>{var r;return null==(r=e)?r:{total_embeddings:r.total_embeddings,collection_name:r.collection_name,database_path:r.database_path,track_database_stats:null==r.track_database_stats?void 0:N(r.track_database_stats,!1)}})}async getLibraryStats(e){let r=await this.getLibraryStatsRaw(e);return await r.value()}async getLibraryTracksRaw(e,r){let t={};return null!=e.page&&(t.page=e.page),null!=e.limit&&(t.limit=e.limit),null!=e.search&&(t.search=e.search),null!=e.artist&&(t.artist=e.artist),null!=e.album&&(t.album=e.album),null!=e.title&&(t.title=e.title),new k(await this.request({path:"/api/library/tracks",method:"GET",headers:{},query:t},r),e=>{var r;return null==(r=e)?r:{tracks:r.tracks.map(f),total_count:r.total_count,page:r.page,limit:r.limit}})}async getLibraryTracks(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0,t=await this.getLibraryTracksRaw(e,r);return await t.value()}async getProcessingProgressRaw(e,r){let t={};return null!=e.modelId&&(t.model_id=e.modelId),new k(await this.request({path:"/api/library/progress",method:"GET",headers:{},query:t},r),e=>N(e,!1))}async getProcessingProgress(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0,t=await this.getProcessingProgressRaw(e,r);return await t.value()}async getSimilarByTrackRaw(e,r){if(null==e.trackId)throw new y("trackId",'Required parameter "trackId" was null or undefined when calling getSimilarByTrack().');let t={};null!=e.nResults&&(t.n_results=e.nResults);let a="/similar/by_track/{track_id}";return a=a.replace("{track_id}",encodeURIComponent(String(e.trackId))),new k(await this.request({path:a,method:"GET",headers:{},query:t},r),e=>(function(e,r){return null==e||"object"!=typeof e?e:"status"in e&&void 0!==e.status&&1?v(e,!0):Array.isArray(e)?e.every(e=>"object"==typeof e)&&e.every(e=>"track"in e&&void 0!==e.track&&"similarity_score"in e&&void 0!==e.similarity_score&&"distance"in e&&void 0!==e.distance)?e.map(e=>j(e,!0)):e:{}})(e,0))}async getSimilarByTrack(e,r){let t=await this.getSimilarByTrackRaw(e,r);return await t.value()}async getTaskStatusRaw(e,r){if(null==e.taskId)throw new y("taskId",'Required parameter "taskId" was null or undefined when calling getTaskStatus().');let t="/api/queue/task/{task_id}";return t=t.replace("{task_id}",encodeURIComponent(String(e.taskId))),new k(await this.request({path:t,method:"GET",headers:{},query:{}},r),e=>{var r;return null==(r=e)?r:{task_id:r.task_id,status:r.status,track_id:null==r.track_id?void 0:r.track_id,started_at:null==r.started_at?void 0:r.started_at,completed_at:null==r.completed_at?void 0:r.completed_at,error_message:null==r.error_message?void 0:r.error_message,search_results:null==r.search_results?void 0:r.search_results.map(w)}})}async getTaskStatus(e,r){let t=await this.getTaskStatusRaw(e,r);return await t.value()}async processLibraryRaw(e){return new k(await this.request({path:"/api/library/process",method:"POST",headers:{},query:{}},e),e=>v(e,!1))}async processLibrary(e){let r=await this.processLibraryRaw(e);return await r.value()}async processLibraryOnServerRaw(e){return new k(await this.request({path:"/api/library/process/server",method:"POST",headers:{},query:{}},e),e=>v(e,!1))}async processLibraryOnServer(e){let r=await this.processLibraryOnServerRaw(e);return await r.value()}async saveConfigRaw(e,r){if(null==e.configRequest)throw new y("configRequest",'Required parameter "configRequest" was null or undefined when calling saveConfig().');let t={};return t["Content-Type"]="application/json",new k(await this.request({path:"/api/config",method:"POST",headers:t,query:{},body:function(e){return(arguments.length>1&&void 0!==arguments[1]&&arguments[1],null==e)?e:{media_server:e.media_server,plex:e.plex,api:e.api,chroma:e.chroma,clap:e.clap,server:e.server,logging:e.logging,database:e.database}}(e.configRequest,!1)},r),e=>{var r;return null==(r=e)?r:{message:r.message,status:r.status,reloaded:r.reloaded,reload_error:null==r.reload_error?void 0:r.reload_error}})}async saveConfig(e,r){let t=await this.saveConfigRaw(e,r);return await t.value()}async scanLibraryRaw(e){return new k(await this.request({path:"/api/library/scan",method:"POST",headers:{},query:{}},e),e=>{var r;return null==(r=e)?r:{message:r.message,total_tracks:r.total_tracks,new_tracks:r.new_tracks,updated_tracks:r.updated_tracks,scan_timestamp:r.scan_timestamp}})}async scanLibrary(e){let r=await this.scanLibraryRaw(e);return await r.value()}async searchAudioRaw(e,r){let t,a=b([{contentType:"multipart/form-data"}]);return t=a?new FormData:new URLSearchParams,null!=e.audio&&t.append("audio",e.audio),null!=e.nResults&&t.append("n_results",e.nResults),new k(await this.request({path:"/api/search/audio",method:"POST",headers:{},query:{},body:t},r),e=>v(e,!1))}async searchAudio(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0,t=await this.searchAudioRaw(e,r);return await t.value()}async searchTextRaw(e,r){if(null==e.q)throw new y("q",'Required parameter "q" was null or undefined when calling searchText().');let t={};return null!=e.q&&(t.q=e.q),null!=e.nResults&&(t.n_results=e.nResults),new k(await this.request({path:"/api/search/text",method:"GET",headers:{},query:t},r),e=>v(e,!1))}async searchText(e,r){let t=await this.searchTextRaw(e,r);return await t.value()}async stopProcessingRaw(e){return new k(await this.request({path:"/api/library/process/stop",method:"POST",headers:{},query:{}},e),e=>{var r;return null==(r=e)?r:{message:r.message,type:null==r.type?void 0:r.type,cleared_tasks:null==r.cleared_tasks?void 0:r.cleared_tasks}})}async stopProcessing(e){let r=await this.stopProcessingRaw(e);return await r.value()}}let C=new _(new g({basePath:n}));function S(){let[e,r]=(0,s.useState)(""),[t,l]=(0,s.useState)([]),[n,i]=(0,s.useState)(!1),[o,d]=(0,s.useState)(!1),[u,g]=(0,s.useState)(null),[m,x]=(0,s.useState)("text"),[h,p]=(0,s.useState)(null),[y,b]=(0,s.useState)(!1),[k,v]=(0,s.useState)(10),f=(0,s.useRef)(null),[w,j]=(0,s.useState)("none"),[N,_]=(0,s.useState)(null);(0,s.useEffect)(()=>()=>{N&&clearInterval(N)},[N]);let S=async e=>{try{let r=await C.getTaskStatus({taskId:e});if(!r)return!1;if(console.log("Polling task ".concat(e,": status=").concat(r.status,", has_results=").concat(!!r.search_results)),"success"===r.status&&r.search_results)return console.log("Task ".concat(e," completed successfully with ").concat(r.search_results.length," results")),l(r.search_results),!0;if("failed"===r.status)return console.error("Task ".concat(e," failed:"),r.error_message),g(r.error_message||"Search task failed on worker"),!0;if("success"===r.status&&!r.search_results)return console.warn("Task ".concat(e," marked as success but no search results yet, continuing polling...")),!1;return console.log("Task ".concat(e," still in progress (status: ").concat(r.status,")")),!1}catch(e){return console.error("Error polling task status:",e),!1}},P=e=>{console.log("Starting task polling for search task:",e),j("worker");let r=0,t=setInterval(async()=>{r++,await S(e)?(console.log("Search task ".concat(e," completed, clearing polling after ").concat(r," polls")),clearInterval(t),_(null),j("none"),i(!1),d(!1)):r>=150&&(console.warn("Search task ".concat(e," polling timeout after ").concat(r," polls (").concat(300," seconds)")),clearInterval(t),_(null),j("none"),i(!1),d(!1),g("Search task timed out. Please try again."))},2e3);_(t)},D=async()=>{if(e.trim()){i(!0),g(null);try{let r=await C.searchText({q:e,nResults:k});if(Array.isArray(r))l(r),i(!1);else if("processing"===r.status)r.task_id?(console.log("Text search sent to worker, starting polling for task:",r.task_id),P(r.task_id)):(console.error("Processing response missing taskId for text search"),g("Worker processing started but no task ID was returned."),i(!1));else if("confirmation_required"===r.status)if(window.confirm("Text search requires embedding computation, and no workers are active.\n\nWould you like to process it on the server?")){j("server");try{let r=await C.computeTextSearch({computeTextSearchRequest:{query:e,n_results:k}});l(r)}catch(e){g("Error processing text search on server. Please check your connection.")}finally{j("none"),i(!1)}}else i(!1);else console.error("Unexpected response from text search:",r),g("Unexpected response from server: ".concat(r.status||"unknown status",". Please try again.")),i(!1)}catch(e){g(e instanceof Error?e.message:"An error occurred"),l([]),i(!1)}}},R=async()=>{if(h){d(!0),g(null);try{let e=new FormData;e.append("audio",h),e.append("n_results",k.toString());let r=await C.searchAudio({audio:h,nResults:k});if(Array.isArray(r))l(r),d(!1);else if("processing"===r.status)r.task_id?(console.log("Audio search sent to worker, starting polling for task:",r.task_id),P(r.task_id)):(console.error("Processing response missing taskId for audio search"),g("Worker processing started but no task ID was returned."),d(!1));else if("confirmation_required"===r.status)if(window.confirm("Audio search requires embedding computation, and no workers are active.\n\nWould you like to process it on the server?")){j("server");try{let e=new FormData;e.append("audio",h),e.append("n_results",k.toString());let r=await C.computeAudioSearch({audio:h,nResults:k});l(r)}catch(e){g("Error processing audio search on server. Please check your connection.")}finally{j("none"),d(!1)}}else d(!1);else console.error("Unexpected response from audio search:",r),g("Unexpected response from server: ".concat(r.status||"unknown status",". Please try again.")),d(!1)}catch(e){console.error("Audio search error:",e),g(e instanceof Error?e.message:"An error occurred during audio search"),l([]),d(!1)}}},A=e=>["audio/mpeg","audio/wav","audio/mp3","audio/flac","audio/ogg"].some(r=>e.type.includes(r.split("/")[1]))?(p(e),g(null),!0):(g("Please select a valid audio file (MP3, WAV, FLAC, or OGG)"),!1);return(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-6",children:"\uD83C\uDFB5 Search Your Music"}),(0,a.jsx)("div",{className:"mb-6",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex space-x-1 bg-gray-100 dark:bg-gray-700 p-1 rounded-lg w-fit",children:[(0,a.jsx)("button",{onClick:()=>x("text"),className:"px-4 py-2 rounded-md font-medium transition-colors ".concat("text"===m?"bg-white dark:bg-gray-600 text-purple-600 dark:text-purple-400 shadow-sm":"text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"),children:"\uD83D\uDCDD Text Search"}),(0,a.jsx)("button",{onClick:()=>x("audio"),className:"px-4 py-2 rounded-md font-medium transition-colors ".concat("audio"===m?"bg-white dark:bg-gray-600 text-purple-600 dark:text-purple-400 shadow-sm":"text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"),children:"\uD83C\uDFA7 Audio Search"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("label",{htmlFor:"num-results",className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Results:"}),(0,a.jsx)("input",{id:"num-results",type:"number",min:"1",value:k,onChange:e=>v(parseInt(e.target.value)||10),className:"w-16 px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-purple-500 focus:border-transparent"})]})]})}),"text"===m&&(0,a.jsxs)("div",{className:"mb-6",children:[(0,a.jsxs)("div",{className:"flex gap-3",children:[(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsx)("input",{type:"text",value:e,onChange:e=>r(e.target.value),onKeyPress:e=>{"Enter"===e.key&&"text"===m&&D()},placeholder:"Describe the music you're looking for... (e.g., 'upbeat 80s synthpop', 'slow piano ballad', 'fast drumbeat with distorted guitar')",className:"w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent dark:bg-gray-700 dark:text-white"})}),(0,a.jsx)("button",{onClick:D,disabled:n||"none"!==w||!e.trim(),className:"px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium",children:n||"none"!==w?(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-5 w-5 text-white",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"worker"===w?"Processing with AI worker...":"server"===w?"Processing on server...":"Searching..."]}):"Search"})]}),(0,a.jsx)("div",{className:"mt-3 flex flex-wrap gap-2",children:["upbeat 80s synthpop","melancholic indie rock","instrumental jazz trio","electronic dance music","acoustic folk ballad"].map(e=>(0,a.jsx)("button",{onClick:()=>r(e),className:"px-3 py-1 text-sm bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded-full hover:bg-gray-200 dark:hover:bg-gray-600",children:e},e))})]}),"audio"===m&&(0,a.jsx)("div",{className:"mb-6",children:(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"border-2 border-dashed rounded-lg p-6 transition-colors ".concat(y?"border-purple-500 bg-purple-50 dark:bg-purple-900/20":"border-gray-300 dark:border-gray-600"),onDragOver:e=>{e.preventDefault(),e.stopPropagation(),b(!0)},onDragEnter:e=>{e.preventDefault(),e.stopPropagation(),b(!0)},onDragLeave:e=>{e.preventDefault(),e.stopPropagation(),b(!1)},onDrop:e=>{e.preventDefault(),e.stopPropagation(),b(!1);let r=e.dataTransfer.files;r&&r.length>0&&A(r[0])},children:[(0,a.jsx)("input",{ref:f,type:"file",accept:"audio/*",onChange:e=>{var r;let t=null==(r=e.target.files)?void 0:r[0];t&&A(t)},className:"hidden",id:"audio-upload"}),h?(0,a.jsx)("div",{className:"text-center",children:(0,a.jsxs)("div",{className:"flex items-center justify-center space-x-3",children:[(0,a.jsx)("svg",{className:"h-8 w-8 text-green-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"})}),(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium text-gray-900 dark:text-white",children:h.name}),(0,a.jsxs)("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:[(h.size/1024/1024).toFixed(2)," MB"]})]}),(0,a.jsx)("button",{onClick:()=>{p(null),f.current&&(f.current.value="")},className:"p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",children:(0,a.jsx)("svg",{className:"h-5 w-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 18L18 6M6 6l12 12"})})})]})}):(0,a.jsx)("label",{htmlFor:"audio-upload",className:"cursor-pointer",children:(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("svg",{className:"mx-auto h-12 w-12 text-gray-400 dark:text-gray-500",stroke:"currentColor",fill:"none",viewBox:"0 0 48 48",children:(0,a.jsx)("path",{d:"M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsx)("p",{className:"text-lg font-medium text-gray-900 dark:text-white",children:"Drop audio file here or click to browse"}),(0,a.jsx)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mt-1",children:"Supports MP3, WAV, FLAC, OGG"})]})]})})]}),(0,a.jsx)("button",{onClick:R,disabled:o||"none"!==w||!h,className:"w-full px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium",children:o||"none"!==w?(0,a.jsxs)("div",{className:"flex items-center justify-center",children:[(0,a.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-5 w-5 text-white",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"worker"===w?"Processing with AI worker...":"server"===w?"Processing on server...":"Analyzing Audio..."]}):"\uD83D\uDD0D Find Similar Music"})]})}),u&&(0,a.jsxs)("div",{className:"mb-6 p-4 bg-red-100 dark:bg-red-900 border border-red-300 dark:border-red-700 rounded-lg",children:[(0,a.jsxs)("p",{className:"text-red-700 dark:text-red-300",children:[(0,a.jsx)("span",{className:"font-medium",children:"Error:"})," ",u]}),(0,a.jsx)("p",{className:"text-sm text-red-600 dark:text-red-400 mt-1",children:"Make sure the Mycelium API server is running on localhost:8000"})]}),(0,a.jsx)(c,{results:t,loading:n||o||"none"!==w})]})}function P(){let[e,r]=(0,s.useState)(""),[t,l]=(0,s.useState)([]),[n,i]=(0,s.useState)(null),[o,c]=(0,s.useState)([]),[u,g]=(0,s.useState)(!1),[m,x]=(0,s.useState)(!1),[h,p]=(0,s.useState)("none"),[y,b]=(0,s.useState)(null),[k,v]=(0,s.useState)(null),[f,w]=(0,s.useState)(null),[j,N]=(0,s.useState)(!1),[_,S]=(0,s.useState)(""),[P,D]=(0,s.useState)(""),[R,A]=(0,s.useState)(""),[q,T]=(0,s.useState)(10),[I,E]=(0,s.useState)(!1),[L,M]=(0,s.useState)(null),O=(0,s.useCallback)(async e=>{g(!0),v(null);try{let r=(await C.getLibraryTracks({page:1,limit:100,search:(null==e?void 0:e.trim())||void 0})).tracks.map(e=>({artist:e.artist,album:e.album,title:e.title,filepath:e.filepath,media_server_rating_key:e.media_server_rating_key,media_server_type:e.media_server_type,processed:!1}));l(r)}catch(e){console.error("Error fetching tracks:",e),v(e instanceof Error?e.message:"Failed to fetch tracks")}finally{g(!1)}},[]),F=(0,s.useCallback)(async()=>{g(!0),v(null);try{let e=(await C.getLibraryTracks({page:1,limit:100,artist:_.trim()||void 0,album:P.trim()||void 0,title:R.trim()||void 0})).tracks.map(e=>({artist:e.artist,album:e.album,title:e.title,filepath:e.filepath,media_server_rating_key:e.media_server_rating_key,media_server_type:e.media_server_type,processed:!1}));l(e)}catch(e){console.error("Error fetching tracks:",e),v(e instanceof Error?e.message:"Failed to fetch tracks")}finally{g(!1)}},[_,P,R]);(0,s.useEffect)(()=>()=>{f&&clearInterval(f)},[f]),(0,s.useEffect)(()=>{j&&(_.trim()||P.trim()||R.trim())?F():!j&&e.trim()?O(e):l([])},[e,j,_,P,R,O,F]);let U=async e=>{try{console.log("Polling task status for task_id: ".concat(e));let r=await C.getTaskStatus({taskId:e});if(!r)return!0;if(console.log("Task status response:",r),"success"===r.status)return console.log("Task ".concat(e," completed successfully")),!0;if("failed"===r.status)return console.error("Task ".concat(e," failed:"),r.error_message),v("Processing failed: ".concat(r.error_message||"Unknown error")),!1;return console.log("Task ".concat(e," still in progress, status: ").concat(r.status)),!1}catch(e){return console.error("Error polling task status:",e),!0}},z=async(e,r,t)=>{console.log("Starting task polling for task_id: ".concat(e,", track_id: ").concat(r)),f&&clearInterval(f);let a={taskId:e,trackId:r,startTime:Date.now()};b(a),p("worker");let s=setInterval(async()=>{await U(e)&&(console.log("Task ".concat(e," completed, clearing polling and retrying recommendations")),clearInterval(s),w(null),b(null),p("none"),setTimeout(()=>{console.log("Retrying recommendations for track after task completion"),B(t,!0)},1e3));let r=Date.now()-a.startTime;r>3e5&&(console.warn("Task ".concat(e," polling timeout after ").concat(r,"ms")),clearInterval(s),w(null),b(null),p("none"),v("Processing took too long. Please try clicking the track again."))},2e3);w(s)},B=async function(e){let r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];r||(x(!0),c([]),v(null),p("none"),b(null));try{let t=await C.getSimilarByTrack({trackId:e.media_server_rating_key,nResults:q});if(t)if(Array.isArray(t))c(t),x(!1);else if("confirmation_required"===t.status)if(window.confirm("This track needs to be processed first.\n\nWould you like to process it now?")){p("server");try{await C.computeOnServer({computeOnServerRequest:{track_id:e.media_server_rating_key}}),p("none"),await B(e,!0)}catch(e){v("Error processing track. Please check your connection.")}finally{p("none")}}else x(!1);else"processing"===t.status?!r&&t.task_id?(console.log("Starting worker processing with task_id:",t.task_id),x(!1),z(t.task_id,e.media_server_rating_key,e)):t.task_id||(console.error("Worker processing response missing taskId:",t),v("Worker processing started but missing task ID. Please try again."),x(!1)):(console.error("Unexpected response from server:",t),v("Unexpected response from server: ".concat(t.status||"unknown status",". Please try again.")),x(!1));else v("Failed to get recommendations. Please try again."),x(!1)}catch(e){console.error("Failed to get recommendations:",e),v("Error connecting to server. Please check your connection."),x(!1),p("none")}};return(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg",children:[(0,a.jsxs)("div",{className:"p-6 border-b border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-4",children:"\uD83D\uDCDA Music Library"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300 mb-4",children:"Search your Plex music library and get recommendations based on specific tracks."}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("div",{className:"flex items-center justify-between",children:(0,a.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,a.jsx)("button",{onClick:()=>{N(!1),S(""),D(""),A("")},className:"px-4 py-2 rounded-lg font-medium transition-colors ".concat(j?"bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600":"bg-purple-600 text-white"),children:"Simple Search"}),(0,a.jsx)("button",{onClick:()=>{N(!0),r("")},className:"px-4 py-2 rounded-lg font-medium transition-colors ".concat(j?"bg-purple-600 text-white":"bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600"),children:"Advanced Search"})]})}),!j&&(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)("input",{type:"text",value:e,onChange:e=>r(e.target.value),placeholder:"Search artists, albums, or tracks...",className:"w-full px-4 py-3 pl-10 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-purple-500 focus:border-transparent"}),(0,a.jsx)("svg",{className:"absolute left-3 top-3.5 h-5 w-5 text-gray-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})})]}),j&&(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1",children:"Artist"}),(0,a.jsx)("input",{type:"text",value:_,onChange:e=>S(e.target.value),placeholder:"Search by artist...",className:"w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-purple-500 focus:border-transparent"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1",children:"Album"}),(0,a.jsx)("input",{type:"text",value:P,onChange:e=>D(e.target.value),placeholder:"Search by album...",className:"w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-purple-500 focus:border-transparent"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1",children:"Title"}),(0,a.jsx)("input",{type:"text",value:R,onChange:e=>A(e.target.value),placeholder:"Search by title...",className:"w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-purple-500 focus:border-transparent"})]})]}),(0,a.jsx)("div",{className:"text-sm text-gray-600 dark:text-gray-400",children:"\uD83D\uDCA1 Advanced search uses AND logic - tracks must match all specified criteria"})]})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6 p-6",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-4",children:"Your Tracks"}),u?(0,a.jsx)("div",{className:"space-y-3",children:[void 0,void 0,void 0,void 0,void 0].map((e,r)=>(0,a.jsx)("div",{className:"animate-pulse bg-gray-200 dark:bg-gray-700 h-16 rounded-lg"},r))}):k?(0,a.jsxs)("div",{className:"text-center py-8",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"⚠️"}),(0,a.jsx)("p",{className:"text-red-600 dark:text-red-400 font-medium mb-2",children:k}),(0,a.jsx)("button",{onClick:()=>O(),className:"px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700",children:"Retry"})]}):0===t.length?(0,a.jsxs)("div",{className:"text-center py-8",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"\uD83D\uDD0D"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400 mb-2",children:e||j&&(_.trim()||P.trim()||R.trim())?"No tracks found matching your search":"Start searching to find your tracks"}),(0,a.jsx)("p",{className:"text-sm text-gray-400 dark:text-gray-500",children:e||j&&(_.trim()||P.trim()||R.trim())?"Try different search terms or scan your Plex library first":"Use the search bar above to explore your music library"})]}):(0,a.jsx)("div",{className:"space-y-2 max-h-96 overflow-y-auto",children:t.map(e=>(0,a.jsxs)("button",{onClick:()=>{f&&(clearInterval(f),w(null)),i(e),b(null),p("none"),B(e)},className:"w-full p-3 text-left rounded-lg border transition-colors ".concat(n&&"".concat(n.media_server_rating_key)==="".concat(e.media_server_rating_key)?"border-purple-500 bg-purple-50 dark:bg-purple-900/30":"border-gray-200 dark:border-gray-600 hover:border-purple-300 dark:hover:border-purple-500"),children:[(0,a.jsx)("div",{className:"font-medium text-gray-900 dark:text-white",children:e.title}),(0,a.jsxs)("div",{className:"text-sm text-gray-600 dark:text-gray-300",children:[e.artist," • ",e.album]})]},"".concat(e.media_server_rating_key)))})]}),(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"Recommendations"}),(0,a.jsxs)("div",{className:"flex items-center space-x-3",children:[n&&o.length>0&&(0,a.jsxs)("button",{onClick:()=>E(!0),className:"px-3 py-1 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors flex items-center space-x-2 text-sm",children:[(0,a.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 4v16m8-8H4"})}),(0,a.jsx)("span",{children:"Create Playlist"})]}),n&&(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("label",{htmlFor:"rec-num-results",className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Results:"}),(0,a.jsx)("input",{id:"rec-num-results",type:"number",min:"1",value:q,onChange:e=>{T(parseInt(e.target.value)||10),n&&"none"===h&&!m&&B(n)},className:"w-16 px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-purple-500 focus:border-transparent"})]})]})]}),L&&(0,a.jsx)("div",{className:"mb-4 p-4 bg-green-100 dark:bg-green-900 border border-green-300 dark:border-green-700 rounded-lg",children:(0,a.jsxs)("p",{className:"text-green-700 dark:text-green-300 flex items-center",children:[(0,a.jsx)("svg",{className:"w-5 h-5 mr-2",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M5 13l4 4L19 7"})}),L]})}),n?m||"none"!==h?(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsx)("div",{className:"text-center py-4",children:"worker"===h&&y?(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-2xl mb-2",children:"⚙️"}),(0,a.jsx)("p",{className:"text-blue-600 dark:text-blue-400 font-medium",children:"Processing with AI worker..."}),(0,a.jsx)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mt-1",children:"This will complete automatically when ready"})]}):"server"===h?(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-2xl mb-2",children:"\uD83D\uDDA5️"}),(0,a.jsx)("p",{className:"text-purple-600 dark:text-purple-400 font-medium",children:"Processing on server..."}),(0,a.jsx)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mt-1",children:"Computing audio signature"})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-2xl mb-2",children:"\uD83D\uDD0D"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-400 font-medium",children:"Finding similar tracks..."})]})}),[void 0,void 0,void 0,void 0,void 0].map((e,r)=>(0,a.jsx)("div",{className:"animate-pulse bg-gray-200 dark:bg-gray-700 h-16 rounded-lg"},r))]}):0===o.length?(0,a.jsxs)("div",{className:"text-center py-8",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"\uD83D\uDD0D"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400",children:"No recommendations found"}),(0,a.jsx)("p",{className:"text-sm text-gray-400 dark:text-gray-500 mt-1",children:"Make sure embeddings are processed"})]}):(0,a.jsx)("div",{className:"space-y-2 max-h-96 overflow-y-auto",children:o.map(e=>(0,a.jsx)("div",{className:"p-3 border border-gray-200 dark:border-gray-600 rounded-lg",children:(0,a.jsxs)("div",{className:"flex justify-between items-start",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"font-medium text-gray-900 dark:text-white",children:e.track.title}),(0,a.jsxs)("div",{className:"text-sm text-gray-600 dark:text-gray-300",children:[e.track.artist," • ",e.track.album]})]}),(0,a.jsxs)("div",{className:"text-sm text-purple-600 dark:text-purple-400 font-medium",children:[(100*e.similarity_score).toFixed(1),"%"]})]})},"".concat(e.track.media_server_rating_key)))}):(0,a.jsxs)("div",{className:"text-center py-8",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"\uD83D\uDC46"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400",children:"Select a track to see recommendations"})]})]})]}),(0,a.jsx)(d,{isOpen:I,onClose:()=>E(!1),trackIds:o.map(e=>e.track.media_server_rating_key),onSuccess:e=>{M('Successfully created playlist "'.concat(e,'" with ').concat(o.length," tracks!")),setTimeout(()=>M(null),5e3)}})]})}function D(){var e,r;let[t,l]=(0,s.useState)(null),[n,i]=(0,s.useState)(null),[o,d]=(0,s.useState)(!0),[c,u]=(0,s.useState)(!1),[g,m]=(0,s.useState)(null),[x,h]=(0,s.useState)(null);(0,s.useEffect)(()=>{p()},[]);let p=async()=>{d(!0),m(null);try{let e=await C.getConfig();l(e),i(JSON.parse(JSON.stringify(e)))}catch(e){m("Unable to fetch configuration. Make sure the API server is running.")}finally{d(!1)}},y=async()=>{if(t){u(!0),m(null),h(null);try{let e=await C.saveConfig({configRequest:t});i(JSON.parse(JSON.stringify(t))),!0===e.reloaded?h(e.message||"Configuration saved and reloaded successfully! Changes are now active."):!1===e.reloaded?h(e.message||"Configuration saved, but hot-reload failed. Please restart the server to apply changes."):h(e.message||"Configuration saved successfully!")}catch(e){m(e instanceof Error?e.message:"Failed to save configuration")}finally{u(!1)}}},b=()=>JSON.stringify(t)!==JSON.stringify(n),k=(e,r,a)=>{t&&l(t=>t?{...t,[e]:{...t[e],[r]:a}}:t)};return o?(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-4",children:"⚙️ Settings"}),(0,a.jsx)("div",{className:"animate-pulse space-y-4",children:[...Array(6)].map((e,r)=>(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-20 rounded-lg"},r))})]}):(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg",children:[(0,a.jsxs)("div",{className:"p-6 border-b border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"⚙️ Settings"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Configure your Mycelium server installation. Changes require a server restart."})]}),(0,a.jsxs)("div",{className:"p-6 space-y-8",children:[g&&(0,a.jsx)("div",{className:"bg-red-50 dark:bg-red-900/50 border border-red-200 dark:border-red-700 rounded-lg p-4",children:(0,a.jsx)("p",{className:"text-red-700 dark:text-red-300",children:g})}),x&&(0,a.jsx)("div",{className:"bg-green-50 dark:bg-green-900/50 border border-green-200 dark:border-green-700 rounded-lg p-4",children:(0,a.jsx)("p",{className:"text-green-700 dark:text-green-300",children:x})}),t&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83C\uDFB5 Media Server"}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Media Server Type"}),(0,a.jsxs)("select",{value:t.media_server.type,onChange:e=>k("media_server","type",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",children:[(0,a.jsx)("option",{value:"plex",children:"Plex Media Server"}),(0,a.jsx)("option",{value:"jellyfin",children:"Jellyfin (Coming Soon)"})]}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Choose your preferred media server platform"})]})})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDCFA Plex Server"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Server URL"}),(0,a.jsx)("input",{type:"text",value:t.plex.url,onChange:e=>k("plex","url",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"http://localhost:32400"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Music Library Name"}),(0,a.jsx)("input",{type:"text",value:t.plex.music_library_name,onChange:e=>k("plex","music_library_name",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"Music"})]}),(0,a.jsxs)("div",{className:"md:col-span-2",children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Plex Token"}),(0,a.jsx)("input",{type:"password",value:null!=(e=t.plex.token)?e:"",onChange:e=>k("plex","token",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"Your Plex authentication token"}),(0,a.jsxs)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:["Get your token from"," ",(0,a.jsx)("a",{href:"https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/",target:"_blank",rel:"noopener noreferrer",className:"text-purple-600 dark:text-purple-400 hover:underline",children:"Plex support"})]})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83C\uDF10 API Server"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Host"}),(0,a.jsx)("input",{type:"text",value:t.api.host,onChange:e=>k("api","host",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Port"}),(0,a.jsx)("input",{type:"number",value:t.api.port,onChange:e=>k("api","port",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]}),(0,a.jsx)("div",{className:"flex items-center",children:(0,a.jsxs)("label",{className:"flex items-center space-x-2 text-sm font-medium text-gray-700 dark:text-gray-300",children:[(0,a.jsx)("input",{type:"checkbox",checked:t.api.reload,onChange:e=>k("api","reload",e.target.checked),className:"rounded border-gray-300 dark:border-gray-600"}),(0,a.jsx)("span",{children:"Auto-reload"})]})})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDDA5️ Server"}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"GPU Batch Size"}),(0,a.jsx)("input",{type:"number",value:t.server.gpu_batch_size,onChange:e=>k("server","gpu_batch_size",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"1",max:"64"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Batch size for distributed GPU workers"})]})})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83E\uDDE0 AI Model (CLAP)"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[(0,a.jsxs)("div",{className:"md:col-span-2",children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Model ID"}),(0,a.jsxs)("select",{value:t.clap.model_id,onChange:e=>k("clap","model_id",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",children:[(0,a.jsx)("option",{value:"laion/larger_clap_music_and_speech",children:"CLAP Music & Speech (Recommended)"}),(0,a.jsx)("option",{value:"laion/larger_clap_music",children:"CLAP Music (If your library is mostly instrumental/electronic)"}),(0,a.jsx)("option",{value:"laion/clap-htsat-unfused",children:"CLAP HTSAT Unfused (Trained with general sounds, not only music)"})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Sample Rate"}),(0,a.jsx)("input",{type:"number",value:t.clap.target_sr,onChange:e=>k("clap","target_sr",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Chunk Duration (s)"}),(0,a.jsx)("input",{type:"number",value:t.clap.chunk_duration_s,onChange:e=>k("clap","chunk_duration_s",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"1",max:"30"})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Number of Chunks"}),(0,a.jsx)("input",{type:"number",value:t.clap.num_chunks,onChange:e=>k("clap","num_chunks",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"1",max:"10"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Number of audio chunks to extract per track"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Max Load Duration (s)"}),(0,a.jsx)("input",{type:"number",value:null!=(r=t.clap.max_load_duration_s)?r:0,onChange:e=>k("clap","max_load_duration_s",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"10",max:"600"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Maximum seconds of audio to load per track"})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDDC4️ Database"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Collection Name"}),(0,a.jsx)("input",{type:"text",value:t.chroma.collection_name,onChange:e=>k("chroma","collection_name",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Batch Size"}),(0,a.jsx)("input",{type:"number",value:t.chroma.batch_size,onChange:e=>k("chroma","batch_size",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDCDD Logging"}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Log Level"}),(0,a.jsxs)("select",{value:t.logging.level,onChange:e=>k("logging","level",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",children:[(0,a.jsx)("option",{value:"DEBUG",children:"DEBUG"}),(0,a.jsx)("option",{value:"INFO",children:"INFO"}),(0,a.jsx)("option",{value:"WARNING",children:"WARNING"}),(0,a.jsx)("option",{value:"ERROR",children:"ERROR"})]})]})})]}),(0,a.jsxs)("div",{className:"flex justify-between items-center pt-6 border-t border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:"Configuration is stored in ~/.config/mycelium/config.yml"}),(0,a.jsxs)("div",{className:"space-x-3",children:[(0,a.jsx)("button",{onClick:()=>{n&&(l(JSON.parse(JSON.stringify(n))),m(null),h(null))},disabled:!b()||c,className:"px-4 py-2 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed",children:"Reset"}),(0,a.jsx)("button",{onClick:y,disabled:!b()||c,className:"px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed",children:c?"Saving...":"Save Changes"})]})]})]})]})]})}let R="http://localhost:8001".replace(/\/+$/,"");class A{set config(e){this.configuration=e}get basePath(){return null!=this.configuration.basePath?this.configuration.basePath:R}get fetchApi(){return this.configuration.fetchApi}get middleware(){return this.configuration.middleware||[]}get queryParamsStringify(){return this.configuration.queryParamsStringify||function e(r){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.keys(r).map(a=>(function r(t,a){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",l=s+(s.length?"[".concat(t,"]"):t);if(a instanceof Array){let e=a.map(e=>encodeURIComponent(String(e))).join("&".concat(encodeURIComponent(l),"="));return"".concat(encodeURIComponent(l),"=").concat(e)}return a instanceof Set?r(t,Array.from(a),s):a instanceof Date?"".concat(encodeURIComponent(l),"=").concat(encodeURIComponent(a.toISOString())):a instanceof Object?e(a,l):"".concat(encodeURIComponent(l),"=").concat(encodeURIComponent(String(a)))})(a,r[a],t)).filter(e=>e.length>0).join("&")}}get username(){return this.configuration.username}get password(){return this.configuration.password}get apiKey(){let e=this.configuration.apiKey;if(e)return"function"==typeof e?e:()=>e}get accessToken(){let e=this.configuration.accessToken;if(e)return"function"==typeof e?e:async()=>e}get headers(){return this.configuration.headers}get credentials(){return this.configuration.credentials}constructor(e={}){this.configuration=e}}let q=new A;class T{withMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=this.clone();return a.middleware=a.middleware.concat(...r),a}withPreMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=r.map(e=>({pre:e}));return this.withMiddleware(...a)}withPostMiddleware(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];let a=r.map(e=>({post:e}));return this.withMiddleware(...a)}isJsonMime(e){return!!e&&T.jsonRegex.test(e)}async request(e,r){let{url:t,init:a}=await this.createFetchParams(e,r),s=await this.fetchApi(t,a);if(s&&s.status>=200&&s.status<300)return s;throw new I(s,"Response returned an error code")}async createFetchParams(e,r){var t,a;let s,l=this.configuration.basePath+e.path;void 0!==e.query&&0!==Object.keys(e.query).length&&(l+="?"+this.configuration.queryParamsStringify(e.query));let n=Object.assign({},this.configuration.headers,e.headers);Object.keys(n).forEach(e=>void 0===n[e]?delete n[e]:{});let i={method:e.method,headers:n,body:e.body,credentials:this.configuration.credentials},o={...i,...await ("function"==typeof r?r:async()=>r)({init:i,context:e})};return t=o.body,s="undefined"!=typeof FormData&&t instanceof FormData||o.body instanceof URLSearchParams||(a=o.body,"undefined"!=typeof Blob&&a instanceof Blob)?o.body:this.isJsonMime(n["Content-Type"])?JSON.stringify(o.body):o.body,{url:l,init:{...o,body:s}}}clone(){let e=new this.constructor(this.configuration);return e.middleware=this.middleware.slice(),e}constructor(e=q){this.configuration=e,this.fetchApi=async(e,r)=>{let t,a={url:e,init:r};for(let e of this.middleware)e.pre&&(a=await e.pre({fetch:this.fetchApi,...a})||a);try{t=await (this.configuration.fetchApi||fetch)(a.url,a.init)}catch(e){for(let r of this.middleware)r.onError&&(t=await r.onError({fetch:this.fetchApi,url:a.url,init:a.init,error:e,response:t?t.clone():void 0})||t);if(void 0===t)if(e instanceof Error)throw new E(e,"The request failed and the interceptors did not return an alternative response");else throw e}for(let e of this.middleware)e.post&&(t=await e.post({fetch:this.fetchApi,url:a.url,init:a.init,response:t.clone()})||t);return t},this.middleware=e.middleware}}T.jsonRegex=RegExp("^(:?application/json|[^;/ ]+/[^;/ ]+[+]json)[ ]*(:?;.*)?$","i");class I extends Error{constructor(e,r){super(r),this.response=e,this.name="ResponseError"}}class E extends Error{constructor(e,r){super(r),this.cause=e,this.name="FetchError"}}class L extends Error{constructor(e,r){super(r),this.field=e,this.name="RequiredError"}}class M{async value(){return this.transformer(await this.raw.json())}constructor(e,r=e=>e){this.raw=e,this.transformer=r}}class O extends T{async getWorkerConfigRaw(e){return new M(await this.request({path:"/api/config",method:"GET",headers:{},query:{}},e),e=>(function(e,r){var t,a,s,l;if(null==e)return e;return{client:(t=e.client,null==t?t:{server_host:t.server_host,server_port:t.server_port,download_queue_size:t.download_queue_size,job_queue_size:t.job_queue_size,poll_interval:t.poll_interval,download_workers:t.download_workers,gpu_batch_size:t.gpu_batch_size}),client_api:(a=e.client_api,null==a?a:{host:a.host,port:a.port}),clap:(s=e.clap,null==s?s:{model_id:s.model_id,target_sr:s.target_sr,chunk_duration_s:s.chunk_duration_s,num_chunks:s.num_chunks,max_load_duration_s:null==s.max_load_duration_s?void 0:s.max_load_duration_s}),logging:(l=e.logging,null==l?l:{level:l.level})}})(e,0))}async getWorkerConfig(e){let r=await this.getWorkerConfigRaw(e);return await r.value()}async saveWorkerConfigRaw(e,r){if(null==e.workerConfigRequest)throw new L("workerConfigRequest",'Required parameter "workerConfigRequest" was null or undefined when calling saveWorkerConfig().');let t={};return t["Content-Type"]="application/json",new M(await this.request({path:"/api/config",method:"POST",headers:t,query:{},body:function(e){return(arguments.length>1&&void 0!==arguments[1]&&arguments[1],null==e)?e:{client:e.client,client_api:e.client_api,clap:e.clap,logging:e.logging}}(e.workerConfigRequest,!1)},r),e=>{var r;return null==(r=e)?r:{message:r.message,status:r.status,reloaded:r.reloaded,reload_error:null==r.reload_error?void 0:r.reload_error}})}async saveWorkerConfig(e,r){let t=await this.saveWorkerConfigRaw(e,r);return await t.value()}}let F=new O(new A({basePath:o}));function U(){var e;let[r,t]=(0,s.useState)(null),[l,n]=(0,s.useState)(null),[i,o]=(0,s.useState)(!0),[d,c]=(0,s.useState)(!1),[u,g]=(0,s.useState)(null),[m,x]=(0,s.useState)(null);(0,s.useEffect)(()=>{h()},[]);let h=async()=>{o(!0),g(null);try{let e=await F.getWorkerConfig();t(e),n(JSON.parse(JSON.stringify(e)))}catch(e){g("Unable to fetch client configuration. Ensure the worker API is running and reachable.")}finally{o(!1)}},p=async()=>{if(r){c(!0),g(null),x(null);try{var e;let t=await F.saveWorkerConfig({workerConfigRequest:r});n(JSON.parse(JSON.stringify(r))),x(null!=(e=t.message)?e:"Configuration saved successfully!")}catch(e){g(e instanceof Error?e.message:"Failed to save configuration")}finally{c(!1)}}},y=()=>JSON.stringify(r)!==JSON.stringify(l),b=(e,r,a)=>{t(t=>t?{...t,[e]:{...t[e],[r]:a}}:t)};return i?(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-4",children:"⚙️ Client Settings"}),(0,a.jsx)("div",{className:"animate-pulse space-y-4",children:[void 0,void 0,void 0].map((e,r)=>(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-20 rounded-lg"},r))})]}):(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg",children:[(0,a.jsxs)("div",{className:"p-6 border-b border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"⚙️ Client Settings"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Configure your Mycelium client worker. Changes are applied immediately with hot-reload."})]}),(0,a.jsxs)("div",{className:"p-6 space-y-8",children:[u&&(0,a.jsx)("div",{className:"bg-red-50 dark:bg-red-900/50 border border-red-200 dark:border-red-700 rounded-lg p-4",children:(0,a.jsx)("p",{className:"text-red-700 dark:text-red-300",children:u})}),m&&(0,a.jsx)("div",{className:"bg-green-50 dark:bg-green-900/50 border border-green-200 dark:border-green-700 rounded-lg p-4",children:(0,a.jsx)("p",{className:"text-green-700 dark:text-green-300",children:m})}),r&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDDA5️ Client Worker"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-7 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Server Host"}),(0,a.jsx)("input",{type:"text",value:r.client.server_host,onChange:e=>b("client","server_host",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"localhost"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Server Port"}),(0,a.jsx)("input",{type:"number",value:r.client.server_port,onChange:e=>b("client","server_port",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"8000"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Download Queue Size"}),(0,a.jsx)("input",{type:"number",value:r.client.download_queue_size,onChange:e=>b("client","download_queue_size",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"15",min:"1",max:"100"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Max audio files to download simultaneously"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Job Queue Size"}),(0,a.jsx)("input",{type:"number",value:r.client.job_queue_size,onChange:e=>b("client","job_queue_size",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"30",min:"1",max:"500"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Max jobs to queue for processing"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Poll Interval (s)"}),(0,a.jsx)("input",{type:"number",value:r.client.poll_interval,onChange:e=>b("client","poll_interval",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"5",min:"1",max:"60"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Seconds between job requests"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Download Workers"}),(0,a.jsx)("input",{type:"number",value:r.client.download_workers,onChange:e=>b("client","download_workers",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"10",min:"1",max:"50"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Parallel download threads"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"GPU Batch Size"}),(0,a.jsx)("input",{type:"number",value:r.client.gpu_batch_size,onChange:e=>b("client","gpu_batch_size",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"4",min:"1",max:"32"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"GPU processing batch size"})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDD0C Client API Server"}),(0,a.jsx)("p",{className:"text-sm text-gray-600 dark:text-gray-400 mb-4",children:"Configure the local API server for client configuration management."}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"API Host"}),(0,a.jsx)("input",{type:"text",value:r.client_api.host,onChange:e=>b("client_api","host",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"localhost"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"API Port"}),(0,a.jsx)("input",{type:"number",value:r.client_api.port,onChange:e=>b("client_api","port",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",placeholder:"3001"})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83E\uDDE0 AI Model (CLAP)"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[(0,a.jsxs)("div",{className:"md:col-span-2",children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Model ID"}),(0,a.jsxs)("select",{value:r.clap.model_id,onChange:e=>b("clap","model_id",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",children:[(0,a.jsx)("option",{value:"laion/larger_clap_music_and_speech",children:"CLAP Music & Speech (Recommended)"}),(0,a.jsx)("option",{value:"laion/larger_clap_music",children:"CLAP Music (If your library is mostly instrumental/electronic)"}),(0,a.jsx)("option",{value:"laion/clap-htsat-unfused",children:"CLAP HTSAT Unfused (Trained with general sounds, not only music)"})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Sample Rate"}),(0,a.jsx)("input",{type:"number",value:r.clap.target_sr,onChange:e=>b("clap","target_sr",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Chunk Duration (s)"}),(0,a.jsx)("input",{type:"number",value:r.clap.chunk_duration_s,onChange:e=>b("clap","chunk_duration_s",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Number of Chunks"}),(0,a.jsx)("input",{type:"number",value:r.clap.num_chunks,onChange:e=>b("clap","num_chunks",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"1",max:"10"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Number of audio chunks to extract per track"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Max Load Duration (s)"}),(0,a.jsx)("input",{type:"number",value:null!=(e=r.clap.max_load_duration_s)?e:0,onChange:e=>b("clap","max_load_duration_s",parseInt(e.target.value)),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",min:"10",max:"600"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"Maximum seconds of audio to load per track"})]})]})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"\uD83D\uDCDD Logging"}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"Log Level"}),(0,a.jsxs)("select",{value:r.logging.level,onChange:e=>b("logging","level",e.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white",children:[(0,a.jsx)("option",{value:"DEBUG",children:"DEBUG"}),(0,a.jsx)("option",{value:"INFO",children:"INFO"}),(0,a.jsx)("option",{value:"WARNING",children:"WARNING"}),(0,a.jsx)("option",{value:"ERROR",children:"ERROR"})]})]})})]}),(0,a.jsxs)("div",{className:"flex justify-between items-center pt-6 border-t border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:"Configuration is stored in ~/.config/mycelium/client_config.yml"}),(0,a.jsxs)("div",{className:"space-x-3",children:[(0,a.jsx)("button",{onClick:()=>{l&&(t(JSON.parse(JSON.stringify(l))),g(null),x(null))},disabled:!y()||d,className:"px-4 py-2 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed",children:"Reset"}),(0,a.jsx)("button",{onClick:p,disabled:!y()||d,className:"px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed",children:d?"Saving...":"Save Changes"})]})]})]})]})]})}function z(){return(0,a.jsxs)("div",{className:"min-h-screen bg-gradient-to-br from-purple-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800",children:[(0,a.jsx)("header",{className:"bg-white dark:bg-gray-800 shadow-sm",children:(0,a.jsx)("div",{className:"container mx-auto px-4 py-4",children:(0,a.jsx)("div",{className:"flex items-center justify-between",children:(0,a.jsxs)("div",{className:"flex items-center space-x-3",children:[(0,a.jsx)("span",{className:"text-2xl",children:"\uD83C\uDF44"}),(0,a.jsx)("h1",{className:"text-xl font-bold text-gray-900 dark:text-white",children:"Mycelium Client"})]})})})}),(0,a.jsxs)("main",{className:"container mx-auto px-4 py-8",children:[(0,a.jsxs)("div",{className:"text-center mb-12",children:[(0,a.jsx)("h1",{className:"text-5xl font-bold text-gray-900 dark:text-white mb-4",children:"\uD83C\uDF44 Mycelium Client"}),(0,a.jsx)("p",{className:"text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto",children:"GPU worker configuration for distributed audio processing. Configure your client settings to connect to the Mycelium server."})]}),(0,a.jsx)("div",{className:"grid gap-8 grid-cols-1",children:(0,a.jsx)(U,{})}),(0,a.jsxs)("div",{className:"mt-16 grid grid-cols-1 md:grid-cols-3 gap-8",children:[(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83D\uDDA5️"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"GPU Worker"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Dedicated worker for processing CLAP embeddings with GPU acceleration."})]}),(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83E\uDDE0"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"AI Model Configuration"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Choose and configure the CLAP model for your specific use case."})]}),(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83D\uDD17"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"Server Connection"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Connect to your Mycelium server for distributed processing."})]})]})]})]})}let B=(0,s.createContext)(void 0);function W(){let e=(0,s.useContext)(B);if(void 0===e)throw Error("useProcessing must be used within a ProcessingProvider");return e}function G(e){let{children:r}=e,[t,l]=(0,s.useState)(null),[i,o]=(0,s.useState)(!0),[d,c]=(0,s.useState)(null),[u,g]=(0,s.useState)(!1),[m,x]=(0,s.useState)(!1),[h,p]=(0,s.useState)(null),[y,b]=(0,s.useState)(null),[k,v]=(0,s.useState)(!1),f=(0,s.useCallback)(async()=>{try{let e=await fetch("".concat(n,"/api/library/stats"));if(!e.ok)throw Error("Failed to fetch library stats");let r=await e.json();l(r),c(null)}catch(e){c("Unable to connect to API"),l(null)}finally{o(!1)}},[]),w=(0,s.useCallback)(async()=>{try{let e=await fetch("".concat(n,"/api/library/progress"));if(e.ok){let r=await e.json();t&&l(e=>e?{...e,track_database_stats:r}:null),r.is_processing?(g(!0),b({stage:"processing",current:r.processed_tracks,total:r.total_tracks})):u&&(g(!1),b(null),((null==h?void 0:h.includes("started"))||(null==h?void 0:h.includes("Processing")))&&p("✅ Processing completed! Check the progress above for details."))}}catch(e){}},[t,u,h]),j=(0,s.useCallback)(async()=>{x(!0),p(null),b(null);try{let e=await fetch("".concat(n,"/api/library/scan"),{method:"POST"});if(!e.ok)throw Error("Failed to scan library");let r=await e.json();p("✅ Scan completed! Found ".concat(r.total_tracks," total tracks ")+"(".concat(r.new_tracks," new, ").concat(r.updated_tracks," updated)")),await f(),await w()}catch(e){p("❌ Failed to scan library. Make sure the API server is running and Plex is accessible.")}finally{x(!1)}},[f,w]),N=(0,s.useCallback)(async()=>{g(!0),p(null),b({stage:"starting"});try{let e=await fetch("".concat(n,"/api/library/process"),{method:"POST"});if(!e.ok)throw Error("Failed to start processing");let r=await e.json();if("already_running"===r.status){p("⚠️ Processing is already in progress"),g(!1),b(null);return}if("worker_processing_started"===r.status)return void p("\uD83D\uDE80 Worker processing started! Created ".concat(r.tasks_created," tasks for ").concat(r.active_workers," workers. Progress will be updated automatically."));if("no_workers"===r.status&&r.confirmation_required){p("⚠️ No client workers detected. Server processing will use local hardware."),v(!0),g(!1),b(null);return}if("server_started"===r.status)return void p("\uD83D\uDE80 Server processing started! Progress will be updated automatically.");p("\uD83D\uDE80 Processing started! Progress will be updated automatically.")}catch(e){p("❌ Failed to start processing. Make sure the API server is running."),g(!1),b(null)}},[]),_=(0,s.useCallback)(async()=>{g(!0),v(!1),p(null),b({stage:"starting"});try{let e=await fetch("".concat(n,"/api/library/process/server"),{method:"POST"});if(!e.ok)throw Error("Failed to start server processing");let r=await e.json();if("already_running"===r.status){p("⚠️ Processing is already in progress"),g(!1),b(null);return}p("\uD83D\uDDA5️ Server processing started! This may take longer on low-power hardware. Progress will be updated automatically.")}catch(e){p("❌ Failed to start server processing. Make sure the API server is running."),g(!1),b(null)}},[]),C=(0,s.useCallback)(async()=>{try{(await fetch("".concat(n,"/api/library/process/stop"),{method:"POST"})).ok&&(b(null),g(!1),p("\uD83D\uDED1 Stop signal sent. Processing will finish current track and stop."))}catch(e){p("❌ Failed to send stop signal.")}},[]),S=(0,s.useCallback)(()=>{v(!1),p(null)},[]);return(0,s.useEffect)(()=>{f(),w();let e=setInterval(()=>{f(),w()},5e3);return()=>{clearInterval(e)}},[]),(0,a.jsx)(B.Provider,{value:{stats:t,statsLoading:i,statsError:d,processLoading:u,scanLoading:m,operationMessage:h,progressInfo:y,showConfirmation:k,fetchStats:f,fetchProgress:w,scanLibrary:j,processEmbeddings:N,processOnServer:_,stopProcessing:C,cancelConfirmation:S,setOperationMessage:p},children:r})}function J(){var e,r,t,s;let l,{stats:n,statsLoading:i,statsError:o,processLoading:d,scanLoading:c,operationMessage:u,progressInfo:g,showConfirmation:m,fetchStats:x,scanLibrary:h,processEmbeddings:p,processOnServer:y,stopProcessing:b,cancelConfirmation:k}=W();return i?(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-4",children:"\uD83D\uDCCA Library Statistics"}),(0,a.jsxs)("div",{className:"animate-pulse space-y-3",children:[(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-4 rounded"}),(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-4 rounded w-3/4"}),(0,a.jsx)("div",{className:"bg-gray-200 dark:bg-gray-700 h-4 rounded w-1/2"})]})]}):(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-4",children:"\uD83D\uDCCA Library Management"}),o?(0,a.jsxs)("div",{className:"text-center py-6",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"⚠️"}),(0,a.jsx)("p",{className:"text-red-600 dark:text-red-400 font-medium",children:o}),(0,a.jsx)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mt-1",children:"Start the API server to view stats"}),(0,a.jsx)("button",{onClick:x,className:"mt-3 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 text-sm",children:"Retry"})]}):n?(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"bg-gradient-to-r from-blue-100 to-cyan-100 dark:from-blue-900 dark:to-cyan-900 p-4 rounded-lg",children:[(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-4 mb-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-2xl font-bold text-blue-600 dark:text-blue-400",children:(null==(r=n.track_database_stats)||null==(e=r.total_tracks)?void 0:e.toLocaleString())||"0"}),(0,a.jsx)("div",{className:"text-sm text-blue-700 dark:text-blue-300",children:"Total Scanned Tracks"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-2xl font-bold text-green-600 dark:text-green-400",children:(null==(s=n.track_database_stats)||null==(t=s.processed_tracks)?void 0:t.toLocaleString())||"0"}),(0,a.jsx)("div",{className:"text-sm text-green-700 dark:text-green-300",children:"Processed Tracks"})]})]}),n.track_database_stats&&n.track_database_stats.total_tracks>0&&(0,a.jsx)("div",{className:"mt-3",children:(l=n.track_database_stats.progress_percentage||0,(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("div",{className:"flex justify-between text-sm",children:[(0,a.jsx)("span",{className:"text-gray-600 dark:text-gray-400",children:"Processing Progress"}),(0,a.jsxs)("span",{className:"text-gray-900 dark:text-white font-medium",children:[l.toFixed(1),"%"]})]}),(0,a.jsx)("div",{className:"w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2",children:(0,a.jsx)("div",{className:"bg-gradient-to-r from-purple-600 to-blue-600 h-2 rounded-full transition-all duration-300",style:{width:"".concat(Math.min(l,100),"%")}})})]}))}),(!n.track_database_stats||0===n.track_database_stats.total_tracks)&&(0,a.jsx)("div",{className:"text-center py-2",children:(0,a.jsx)("p",{className:"text-sm text-blue-600 dark:text-blue-400",children:'\uD83D\uDCD6 No tracks scanned yet. Use "Scan Library" below to get started.'})})]}),(0,a.jsxs)("div",{className:"bg-gradient-to-r from-purple-100 to-pink-100 dark:from-purple-900 dark:to-pink-900 p-4 rounded-lg",children:[(0,a.jsx)("div",{className:"text-3xl font-bold text-purple-600 dark:text-purple-400",children:n.total_embeddings.toLocaleString()}),(0,a.jsx)("div",{className:"text-sm text-purple-700 dark:text-purple-300",children:"Embeddings in Vector DB"})]}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:"Collection"}),(0,a.jsx)("div",{className:"font-medium text-gray-900 dark:text-white",children:n.collection_name})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:"Database Path"}),(0,a.jsx)("div",{className:"font-mono text-xs text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 p-2 rounded",children:n.database_path})]})]})]}):(0,a.jsxs)("div",{className:"text-center py-6",children:[(0,a.jsx)("div",{className:"text-4xl mb-2",children:"\uD83C\uDFB5"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400",children:"No data available"})]}),(0,a.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-200 dark:border-gray-600",children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-900 dark:text-white mb-3",children:"Library Operations"}),u&&(0,a.jsx)("div",{className:"mb-3 p-3 bg-blue-50 dark:bg-blue-900/50 border border-blue-200 dark:border-blue-700 rounded-lg",children:(0,a.jsx)("p",{className:"text-sm text-blue-700 dark:text-blue-300",children:u})}),g&&(0,a.jsx)("div",{className:"mb-3 p-3 bg-yellow-50 dark:bg-yellow-900/50 border border-yellow-200 dark:border-yellow-700 rounded-lg",children:(0,a.jsxs)("p",{className:"text-sm text-yellow-700 dark:text-yellow-300",children:["starting"===g.stage&&"\uD83D\uDE80 Starting processing...","processing"===g.stage&&(0,a.jsxs)(a.Fragment,{children:["\uD83D\uDD04 Processing: ",g.current,"/",g.total,g.current_track&&(0,a.jsxs)("div",{className:"text-xs mt-1 opacity-75",children:["Current: ",g.current_track]})]})]})}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsx)("button",{onClick:h,disabled:c||d,className:"w-full px-3 py-2 text-sm bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300 rounded-lg hover:bg-blue-200 dark:hover:bg-blue-800 disabled:opacity-50 disabled:cursor-not-allowed",children:c?(0,a.jsxs)("div",{className:"flex items-center justify-center",children:[(0,a.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"Scanning Library..."]}):"\uD83D\uDCD6 Scan Library"}),(0,a.jsx)("button",{onClick:p,disabled:d||c,className:"w-full px-3 py-2 text-sm bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300 rounded-lg hover:bg-green-200 dark:hover:bg-green-800 disabled:opacity-50 disabled:cursor-not-allowed",children:d?(0,a.jsxs)("div",{className:"flex items-center justify-center",children:[(0,a.jsxs)("svg",{className:"animate-spin -ml-1 mr-2 h-4 w-4",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),"Processing Embeddings..."]}):"⚡ Process Embeddings"}),d&&(0,a.jsx)("button",{onClick:b,className:"w-full px-3 py-2 text-sm bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300 rounded-lg hover:bg-red-200 dark:hover:bg-red-800",children:"\uD83D\uDED1 Stop Processing"})]}),(0,a.jsxs)("div",{className:"mt-3 text-xs text-gray-500 dark:text-gray-400",children:[(0,a.jsx)("p",{children:"• Scan Library: Discovers tracks and saves metadata"}),(0,a.jsx)("p",{children:"• Process Embeddings: Generates AI embeddings for search"}),(0,a.jsx)("p",{children:"• Processing can be stopped and resumed anytime"})]})]}),m&&(0,a.jsx)("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-xl max-w-md w-full mx-4",children:[(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-4",children:"⚠️ No Client Workers Available"}),(0,a.jsx)("p",{className:"text-gray-700 dark:text-gray-300 mb-6",children:"No GPU workers are currently connected to process embeddings. Processing on the server may be very slow if it lacks sufficient hardware (GPU/powerful CPU)."}),(0,a.jsxs)("p",{className:"text-sm text-gray-600 dark:text-gray-400 mb-6",children:["To use GPU workers, start a client with: ",(0,a.jsx)("code",{className:"bg-gray-100 dark:bg-gray-700 px-1 rounded",children:"mycelium-ai client --server-host your-server-ip"})]}),(0,a.jsxs)("div",{className:"flex space-x-3",children:[(0,a.jsx)("button",{onClick:y,className:"flex-1 px-4 py-2 bg-orange-600 text-white rounded-lg hover:bg-orange-700",children:"\uD83D\uDDA5️ Process on Server"}),(0,a.jsx)("button",{onClick:k,className:"flex-1 px-4 py-2 bg-gray-300 dark:bg-gray-600 text-gray-700 dark:text-gray-200 rounded-lg hover:bg-gray-400 dark:hover:bg-gray-500",children:"Cancel"})]})]})})]})}function H(e){let{activeSection:r,onSectionChange:t}=e;return(0,a.jsx)("nav",{className:"hidden md:flex items-center space-x-6",children:[{id:"search",name:"Search",icon:"\uD83D\uDD0D"},{id:"library",name:"Library",icon:"\uD83D\uDCDA"},{id:"settings",name:"Settings",icon:"⚙️"}].map(e=>(0,a.jsxs)("button",{onClick:()=>t(e.id),className:"\n flex items-center space-x-2 px-3 py-2 rounded-lg font-medium transition-colors\n ".concat(r===e.id?"text-purple-600 dark:text-purple-400 bg-purple-50 dark:bg-purple-900/30":"text-gray-600 dark:text-gray-300 hover:text-purple-600 dark:hover:text-purple-400 hover:bg-gray-50 dark:hover:bg-gray-700","\n "),children:[(0,a.jsx)("span",{className:"text-lg",children:e.icon}),(0,a.jsx)("span",{children:e.name})]},e.id))})}function V(e){let{activeSection:r,onSectionChange:t}=e,{processLoading:s,progressInfo:l,stopProcessing:n}=W();return(0,a.jsx)("header",{className:"bg-white dark:bg-gray-800 shadow-sm",children:(0,a.jsx)("div",{className:"container mx-auto px-4 py-4",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-3",children:[(0,a.jsx)("span",{className:"text-2xl",children:"\uD83C\uDF44"}),(0,a.jsx)("h1",{className:"text-xl font-bold text-gray-900 dark:text-white",children:"Mycelium"})]}),(0,a.jsx)(H,{activeSection:r,onSectionChange:t}),(0,a.jsx)("div",{className:"flex items-center space-x-2",children:s&&(0,a.jsxs)("div",{className:"flex items-center space-x-2 px-3 py-1 bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300 rounded-lg",children:[(0,a.jsxs)("svg",{className:"animate-spin h-4 w-4",fill:"none",viewBox:"0 0 24 24",children:[(0,a.jsx)("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),(0,a.jsx)("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),(0,a.jsx)("span",{className:"text-sm font-medium",children:(null==l?void 0:l.stage)==="processing"&&l.current&&l.total?"Processing ".concat(l.current,"/").concat(l.total):"Processing..."}),(0,a.jsx)("button",{onClick:n,className:"ml-2 px-2 py-1 text-xs bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300 rounded hover:bg-red-200 dark:hover:bg-red-800",title:"Stop Processing",children:"\uD83D\uDED1"})]})})]})})})}function K(){let[e,r]=(0,s.useState)("search");if(i)return(0,a.jsx)(z,{});let t="search"===e;return(0,a.jsx)(G,{children:(0,a.jsxs)("div",{className:"min-h-screen bg-gradient-to-br from-purple-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800",children:[(0,a.jsx)(V,{activeSection:e,onSectionChange:r}),(0,a.jsxs)("main",{className:"container mx-auto px-4 py-8",children:["search"===e&&(0,a.jsxs)("div",{className:"text-center mb-12",children:[(0,a.jsx)("h1",{className:"text-5xl font-bold text-gray-900 dark:text-white mb-4",children:"\uD83C\uDF44 Mycelium"}),(0,a.jsx)("p",{className:"text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto",children:"AI-powered music search using embeddings to find perfect matches based on sound, mood, and style."})]}),(0,a.jsxs)("div",{className:"grid gap-8 ".concat(t?"grid-cols-1 lg:grid-cols-3":"grid-cols-1"),children:[(0,a.jsx)("div",{className:t?"lg:col-span-2":"col-span-1",children:(()=>{switch(e){case"search":default:return(0,a.jsx)(S,{});case"library":return(0,a.jsx)(P,{});case"settings":return(0,a.jsx)(D,{})}})()}),t&&(0,a.jsx)("div",{className:"lg:col-span-1",children:(0,a.jsx)(J,{})})]}),"search"===e&&(0,a.jsxs)("div",{className:"mt-16 grid grid-cols-1 md:grid-cols-3 gap-8",children:[(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83C\uDFB5"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"Semantic Search"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:'Find music using natural language or audio files. Search for "upbeat indie rock" or upload a song.'})]}),(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83E\uDDE0"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"AI-Powered"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Uses CLAP (Contrastive Language-Audio Pre-training) for understanding music content."})]}),(0,a.jsxs)("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md",children:[(0,a.jsx)("div",{className:"text-2xl mb-3",children:"\uD83D\uDCDA"}),(0,a.jsx)("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white mb-2",children:"Plex Integration"}),(0,a.jsx)("p",{className:"text-gray-600 dark:text-gray-300",children:"Seamlessly connects with your existing Plex music library."})]})]})]})]})})}}},e=>{e.O(0,[441,964,358],()=>e(e.s=5766)),_N_E=e.O()}]);