micrOSDevToolKit 2.9.1__py3-none-any.whl → 2.26.1__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 (368) hide show
  1. env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
  2. env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
  3. micrOS/micropython/esp32-20251209-v1.27.0.bin +0 -0
  4. micrOS/micropython/esp32c3-20251209-v1.27.0.bin +0 -0
  5. micrOS/micropython/esp32c6-20251209-v1.27.0.bin +0 -0
  6. micrOS/micropython/esp32s2-20251209-v1.27.0.bin +0 -0
  7. micrOS/micropython/esp32s2-LOLIN_MINI-20251209-v1.27.0.bin +0 -0
  8. micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-4MBflash-20241129-v1.24.1.bin} +0 -0
  9. micrOS/micropython/esp32s3-8MBflash-20251209-v1.27.0.bin +0 -0
  10. micrOS/micropython/esp32s3_spiram_oct-20251209-v1.27.0.bin +0 -0
  11. micrOS/micropython/rpi-pico-w-20251209-v1.27.0.uf2 +0 -0
  12. micrOS/micropython/tinypico-20251209-v1.27.0.bin +0 -0
  13. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +167 -163
  14. micrOS/source/Auth.py +37 -0
  15. micrOS/source/Common.py +361 -116
  16. micrOS/source/Config.py +32 -22
  17. micrOS/source/Debug.py +50 -94
  18. micrOS/source/Espnow.py +377 -100
  19. micrOS/source/Files.py +207 -0
  20. micrOS/source/Hooks.py +48 -20
  21. micrOS/source/InterConnect.py +126 -42
  22. micrOS/source/Interrupts.py +6 -6
  23. micrOS/source/Logger.py +63 -26
  24. micrOS/source/Network.py +41 -21
  25. micrOS/source/Notify.py +48 -22
  26. micrOS/source/Pacman.py +326 -0
  27. micrOS/source/Scheduler.py +14 -54
  28. micrOS/source/Server.py +67 -69
  29. micrOS/source/Shell.py +99 -91
  30. micrOS/source/Tasks.py +141 -95
  31. micrOS/source/Time.py +19 -18
  32. micrOS/source/Types.py +53 -9
  33. micrOS/source/Web.py +381 -76
  34. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  35. micrOS/source/__pycache__/Debug.cpython-312.pyc +0 -0
  36. micrOS/source/__pycache__/Files.cpython-312.pyc +0 -0
  37. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  38. micrOS/source/__pycache__/Scheduler.cpython-312.pyc +0 -0
  39. micrOS/source/__pycache__/Server.cpython-312.pyc +0 -0
  40. micrOS/source/__pycache__/Shell.cpython-312.pyc +0 -0
  41. micrOS/source/__pycache__/replhelper.cpython-312.pyc +0 -0
  42. micrOS/source/config/_git.keep +0 -0
  43. micrOS/source/helpers.py +132 -0
  44. micrOS/source/micrOS.py +17 -7
  45. micrOS/source/micrOSloader.py +5 -12
  46. micrOS/source/microIO.py +44 -20
  47. micrOS/source/modules/IO_esp32c6.py +38 -0
  48. micrOS/source/{IO_esp32s3.py → modules/IO_esp32s3.py} +37 -1
  49. micrOS/source/{IO_m5stamp.py → modules/IO_m5stamp.py} +35 -1
  50. micrOS/source/{IO_qtpy.py → modules/IO_qtpy.py} +22 -17
  51. micrOS/source/{IO_tinypico.py → modules/IO_tinypico.py} +38 -0
  52. micrOS/source/modules/LM_L298N.py +161 -0
  53. {toolkit/workspace/precompiled → micrOS/source/modules}/LM_L9110_DCmotor.py +3 -3
  54. micrOS/source/{LM_OV2640.py → modules/LM_OV2640.py} +45 -27
  55. micrOS/source/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
  56. micrOS/source/{LM_aht10.py → modules/LM_aht10.py} +2 -2
  57. micrOS/source/{LM_bme280.py → modules/LM_bme280.py} +3 -3
  58. micrOS/source/{LM_buzzer.py → modules/LM_buzzer.py} +18 -25
  59. micrOS/source/{LM_cct.py → modules/LM_cct.py} +17 -21
  60. micrOS/source/modules/LM_cluster.py +255 -0
  61. micrOS/source/{LM_co2.py → modules/LM_co2.py} +3 -3
  62. micrOS/source/{LM_dht11.py → modules/LM_dht11.py} +2 -2
  63. micrOS/source/{LM_dht22.py → modules/LM_dht22.py} +2 -2
  64. micrOS/source/{LM_dimmer.py → modules/LM_dimmer.py} +9 -9
  65. micrOS/source/{LM_distance.py → modules/LM_distance.py} +4 -6
  66. micrOS/source/{LM_ds18.py → modules/LM_ds18.py} +2 -2
  67. micrOS/source/{LM_esp32.py → modules/LM_esp32.py} +5 -0
  68. micrOS/source/modules/LM_espnow.py +53 -0
  69. micrOS/source/modules/LM_fileserver.py +265 -0
  70. micrOS/source/{LM_genIO.py → modules/LM_genIO.py} +52 -37
  71. micrOS/source/{LM_haptic.py → modules/LM_haptic.py} +2 -2
  72. {toolkit/workspace/precompiled → micrOS/source/modules}/LM_i2c.py +5 -4
  73. micrOS/source/{LM_i2s_mic.py → modules/LM_i2s_mic.py} +6 -7
  74. micrOS/source/{LM_ld2410.py → modules/LM_ld2410.py} +2 -2
  75. micrOS/source/{LM_light_sensor.py → modules/LM_light_sensor.py} +10 -21
  76. micrOS/source/modules/LM_mh_z19c.py +198 -0
  77. micrOS/source/modules/LM_neoeffects.py +284 -0
  78. micrOS/source/{LM_neopixel.py → modules/LM_neopixel.py} +19 -23
  79. micrOS/source/{LM_oled.py → modules/LM_oled.py} +2 -2
  80. micrOS/source/{LM_oled_sh1106.py → modules/LM_oled_sh1106.py} +3 -3
  81. micrOS/source/{LM_oled_ui.py → modules/LM_oled_ui.py} +72 -64
  82. micrOS/source/modules/LM_pacman.py +320 -0
  83. micrOS/source/{LM_presence.py → modules/LM_presence.py} +11 -15
  84. micrOS/source/modules/LM_qmi8658.py +204 -0
  85. micrOS/source/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
  86. micrOS/source/{LM_rest.py → modules/LM_rest.py} +4 -6
  87. micrOS/source/{LM_rgb.py → modules/LM_rgb.py} +21 -29
  88. micrOS/source/{LM_roboarm.py → modules/LM_roboarm.py} +8 -8
  89. micrOS/source/modules/LM_robustness.py +137 -0
  90. micrOS/source/{LM_servo.py → modules/LM_servo.py} +3 -3
  91. micrOS/source/{LM_stepper.py → modules/LM_stepper.py} +5 -5
  92. micrOS/source/{LM_switch.py → modules/LM_switch.py} +11 -9
  93. micrOS/source/{LM_system.py → modules/LM_system.py} +38 -32
  94. micrOS/source/modules/LM_tcs3472.py +187 -0
  95. micrOS/source/{LM_telegram.py → modules/LM_telegram.py} +164 -116
  96. micrOS/source/{LM_trackball.py → modules/LM_trackball.py} +3 -3
  97. micrOS/source/{LM_veml7700.py → modules/LM_veml7700.py} +2 -2
  98. micrOS/source/modules/LM_web.py +38 -0
  99. micrOS/source/urequests.py +39 -15
  100. {toolkit/workspace/precompiled → micrOS/source/web}/dashboard.html +4 -0
  101. micrOS/source/web/editor.js +440 -0
  102. micrOS/source/web/filesui.html +178 -0
  103. micrOS/source/web/filesui.js +338 -0
  104. {toolkit/workspace/precompiled → micrOS/source/web}/index.html +44 -2
  105. micrOS/source/{uapi.js → web/uapi.js} +48 -7
  106. micrOS/source/{ustyle.css → web/ustyle.css} +6 -3
  107. micrOS/utests/__init__.py +0 -0
  108. micrOS/utests/test_scheduler.py +435 -0
  109. {micrOSDevToolKit-2.9.1.data → microsdevtoolkit-2.26.1.data}/scripts/devToolKit.py +33 -3
  110. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/METADATA +327 -268
  111. microsdevtoolkit-2.26.1.dist-info/RECORD +396 -0
  112. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/WHEEL +1 -1
  113. toolkit/DevEnvCompile.py +63 -33
  114. toolkit/DevEnvOTA.py +58 -22
  115. toolkit/DevEnvUSB.py +110 -55
  116. toolkit/Gateway.py +6 -6
  117. toolkit/LM_to_compile.dat +6 -4
  118. toolkit/MicrOSDevEnv.py +127 -57
  119. toolkit/WebRepl.py +73 -0
  120. toolkit/dashboard_apps/BackupRestore.py +20 -35
  121. toolkit/dashboard_apps/CCTDemo.py +12 -17
  122. toolkit/dashboard_apps/CCTTest.py +20 -24
  123. toolkit/dashboard_apps/CamStream.py +2 -6
  124. toolkit/dashboard_apps/CatGame.py +14 -16
  125. toolkit/dashboard_apps/Dimmer.py +11 -21
  126. toolkit/dashboard_apps/GetVersion.py +11 -19
  127. toolkit/dashboard_apps/MicrophoneTest.py +1 -6
  128. toolkit/dashboard_apps/NeoEffectsDemo.py +22 -35
  129. toolkit/dashboard_apps/NeopixelTest.py +20 -25
  130. toolkit/dashboard_apps/PresenceTest.py +2 -8
  131. toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
  132. toolkit/dashboard_apps/RGBTest.py +20 -24
  133. toolkit/dashboard_apps/RoboArm.py +24 -32
  134. toolkit/dashboard_apps/SED_test.py +10 -14
  135. toolkit/dashboard_apps/SensorsTest.py +61 -0
  136. toolkit/dashboard_apps/SystemTest.py +202 -105
  137. toolkit/dashboard_apps/Template_app.py +11 -23
  138. toolkit/dashboard_apps/_app_base.py +34 -0
  139. toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
  140. toolkit/dashboard_apps/uLightDemo.py +15 -24
  141. toolkit/index.html +4 -4
  142. toolkit/lib/LocalMachine.py +6 -1
  143. toolkit/lib/MicrosFiles.py +46 -0
  144. toolkit/lib/Repository.py +64 -0
  145. toolkit/lib/TerminalColors.py +4 -0
  146. toolkit/lib/macroScript.py +6 -0
  147. toolkit/lib/micrOSClient.py +123 -50
  148. toolkit/lib/micrOSClientHistory.py +156 -0
  149. toolkit/lib/pip_package_installer.py +5 -2
  150. toolkit/micrOSdashboard.py +12 -17
  151. toolkit/micrOSlint.py +20 -8
  152. toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
  153. toolkit/simulator_lib/__pycache__/aioespnow.cpython-312.pyc +0 -0
  154. toolkit/simulator_lib/__pycache__/framebuf.cpython-312.pyc +0 -0
  155. toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
  156. toolkit/simulator_lib/__pycache__/micropython.cpython-312.pyc +0 -0
  157. toolkit/simulator_lib/__pycache__/mip.cpython-312.pyc +0 -0
  158. toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
  159. toolkit/simulator_lib/__pycache__/network.cpython-312.pyc +0 -0
  160. toolkit/simulator_lib/__pycache__/sim_common.cpython-312.pyc +0 -0
  161. toolkit/simulator_lib/__pycache__/simgc.cpython-312.pyc +0 -0
  162. toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
  163. toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
  164. toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
  165. toolkit/simulator_lib/__pycache__/urandom.cpython-312.pyc +0 -0
  166. toolkit/simulator_lib/__pycache__/usocket.cpython-312.pyc +0 -0
  167. toolkit/simulator_lib/__pycache__/ussl.cpython-312.pyc +0 -0
  168. toolkit/simulator_lib/aioespnow.py +28 -0
  169. toolkit/simulator_lib/dht.py +1 -1
  170. toolkit/simulator_lib/framebuf.py +49 -1
  171. toolkit/simulator_lib/machine.py +17 -2
  172. toolkit/simulator_lib/micropython.py +3 -3
  173. toolkit/simulator_lib/mip.py +165 -0
  174. toolkit/simulator_lib/neopixel.py +3 -2
  175. toolkit/simulator_lib/network.py +2 -1
  176. toolkit/simulator_lib/node_config.json +2 -3
  177. toolkit/simulator_lib/ntptime.py +1 -1
  178. toolkit/simulator_lib/{sim_console.py → sim_common.py} +2 -3
  179. toolkit/simulator_lib/simgc.py +6 -2
  180. toolkit/simulator_lib/simulator.py +137 -59
  181. toolkit/simulator_lib/uasyncio.py +33 -2
  182. toolkit/simulator_lib/uos.py +147 -0
  183. toolkit/simulator_lib/urandom.py +4 -0
  184. toolkit/socketClient.py +43 -23
  185. toolkit/user_data/webhooks/generic.py +1 -1
  186. toolkit/user_data/webhooks/macro.py +1 -1
  187. toolkit/user_data/webhooks/template.py +1 -1
  188. toolkit/workspace/precompiled/Auth.mpy +0 -0
  189. toolkit/workspace/precompiled/Common.mpy +0 -0
  190. toolkit/workspace/precompiled/Config.mpy +0 -0
  191. toolkit/workspace/precompiled/Debug.mpy +0 -0
  192. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  193. toolkit/workspace/precompiled/Files.mpy +0 -0
  194. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  195. toolkit/workspace/precompiled/InterConnect.mpy +0 -0
  196. toolkit/workspace/precompiled/Interrupts.mpy +0 -0
  197. toolkit/workspace/precompiled/Logger.mpy +0 -0
  198. toolkit/workspace/precompiled/Network.mpy +0 -0
  199. toolkit/workspace/precompiled/Notify.mpy +0 -0
  200. toolkit/workspace/precompiled/Pacman.mpy +0 -0
  201. toolkit/workspace/precompiled/Scheduler.mpy +0 -0
  202. toolkit/workspace/precompiled/Server.mpy +0 -0
  203. toolkit/workspace/precompiled/Shell.mpy +0 -0
  204. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  205. toolkit/workspace/precompiled/Time.mpy +0 -0
  206. toolkit/workspace/precompiled/Types.mpy +0 -0
  207. toolkit/workspace/precompiled/Web.mpy +0 -0
  208. toolkit/workspace/precompiled/_mpy.version +1 -1
  209. toolkit/workspace/precompiled/config/_git.keep +0 -0
  210. toolkit/workspace/precompiled/helpers.mpy +0 -0
  211. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  212. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  213. toolkit/workspace/precompiled/microIO.mpy +0 -0
  214. toolkit/workspace/precompiled/{IO_esp32.mpy → modules/IO_esp32.mpy} +0 -0
  215. toolkit/workspace/precompiled/{IO_esp32c3.mpy → modules/IO_esp32c3.mpy} +0 -0
  216. toolkit/workspace/precompiled/modules/IO_esp32c6.mpy +0 -0
  217. toolkit/workspace/precompiled/{IO_esp32s2.mpy → modules/IO_esp32s2.mpy} +0 -0
  218. toolkit/workspace/precompiled/modules/IO_esp32s3.mpy +0 -0
  219. toolkit/workspace/precompiled/modules/IO_m5stamp.mpy +0 -0
  220. toolkit/workspace/precompiled/modules/IO_qtpy.mpy +0 -0
  221. toolkit/workspace/precompiled/modules/IO_rp2.mpy +0 -0
  222. toolkit/workspace/precompiled/modules/IO_tinypico.mpy +0 -0
  223. toolkit/workspace/precompiled/modules/LM_L298N.mpy +0 -0
  224. {micrOS/source → toolkit/workspace/precompiled/modules}/LM_L9110_DCmotor.py +3 -3
  225. toolkit/workspace/precompiled/modules/LM_OV2640.mpy +0 -0
  226. toolkit/workspace/precompiled/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
  227. toolkit/workspace/precompiled/{LM_aht10.mpy → modules/LM_aht10.mpy} +0 -0
  228. toolkit/workspace/precompiled/{LM_bme280.mpy → modules/LM_bme280.mpy} +0 -0
  229. toolkit/workspace/precompiled/{LM_buzzer.mpy → modules/LM_buzzer.mpy} +0 -0
  230. toolkit/workspace/precompiled/modules/LM_cct.mpy +0 -0
  231. toolkit/workspace/precompiled/modules/LM_cluster.mpy +0 -0
  232. toolkit/workspace/precompiled/{LM_co2.mpy → modules/LM_co2.mpy} +0 -0
  233. toolkit/workspace/precompiled/{LM_dht11.mpy → modules/LM_dht11.mpy} +0 -0
  234. toolkit/workspace/precompiled/{LM_dht22.mpy → modules/LM_dht22.mpy} +0 -0
  235. toolkit/workspace/precompiled/modules/LM_dimmer.mpy +0 -0
  236. toolkit/workspace/precompiled/modules/LM_distance.mpy +0 -0
  237. toolkit/workspace/precompiled/{LM_ds18.mpy → modules/LM_ds18.mpy} +0 -0
  238. toolkit/workspace/precompiled/{LM_esp32.py → modules/LM_esp32.py} +5 -0
  239. toolkit/workspace/precompiled/modules/LM_espnow.py +53 -0
  240. toolkit/workspace/precompiled/modules/LM_fileserver.mpy +0 -0
  241. toolkit/workspace/precompiled/{LM_gameOfLife.mpy → modules/LM_gameOfLife.mpy} +0 -0
  242. toolkit/workspace/precompiled/modules/LM_genIO.mpy +0 -0
  243. toolkit/workspace/precompiled/{LM_haptic.mpy → modules/LM_haptic.mpy} +0 -0
  244. {micrOS/source → toolkit/workspace/precompiled/modules}/LM_i2c.py +5 -4
  245. toolkit/workspace/precompiled/modules/LM_i2s_mic.mpy +0 -0
  246. toolkit/workspace/precompiled/{LM_ld2410.mpy → modules/LM_ld2410.mpy} +0 -0
  247. toolkit/workspace/precompiled/modules/LM_light_sensor.mpy +0 -0
  248. toolkit/workspace/precompiled/modules/LM_mh_z19c.py +198 -0
  249. toolkit/workspace/precompiled/modules/LM_neoeffects.mpy +0 -0
  250. toolkit/workspace/precompiled/modules/LM_neopixel.mpy +0 -0
  251. toolkit/workspace/precompiled/{LM_oled.mpy → modules/LM_oled.mpy} +0 -0
  252. toolkit/workspace/precompiled/{LM_oled_sh1106.mpy → modules/LM_oled_sh1106.mpy} +0 -0
  253. toolkit/workspace/precompiled/modules/LM_oled_ui.mpy +0 -0
  254. toolkit/workspace/precompiled/modules/LM_pacman.mpy +0 -0
  255. toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
  256. toolkit/workspace/precompiled/modules/LM_qmi8658.py +204 -0
  257. toolkit/workspace/precompiled/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
  258. toolkit/workspace/precompiled/modules/LM_rest.mpy +0 -0
  259. toolkit/workspace/precompiled/modules/LM_rgb.mpy +0 -0
  260. toolkit/workspace/precompiled/{LM_rgbcct.mpy → modules/LM_rgbcct.mpy} +0 -0
  261. toolkit/workspace/precompiled/modules/LM_roboarm.mpy +0 -0
  262. toolkit/workspace/precompiled/modules/LM_robustness.py +137 -0
  263. toolkit/workspace/precompiled/{LM_servo.mpy → modules/LM_servo.mpy} +0 -0
  264. toolkit/workspace/precompiled/{LM_sound_event.mpy → modules/LM_sound_event.mpy} +0 -0
  265. toolkit/workspace/precompiled/{LM_stepper.mpy → modules/LM_stepper.mpy} +0 -0
  266. toolkit/workspace/precompiled/modules/LM_switch.mpy +0 -0
  267. toolkit/workspace/precompiled/modules/LM_system.mpy +0 -0
  268. toolkit/workspace/precompiled/modules/LM_tcs3472.py +187 -0
  269. toolkit/workspace/precompiled/modules/LM_telegram.mpy +0 -0
  270. toolkit/workspace/precompiled/{LM_tinyrgb.mpy → modules/LM_tinyrgb.mpy} +0 -0
  271. toolkit/workspace/precompiled/{LM_trackball.mpy → modules/LM_trackball.mpy} +0 -0
  272. toolkit/workspace/precompiled/{LM_veml7700.mpy → modules/LM_veml7700.mpy} +0 -0
  273. toolkit/workspace/precompiled/modules/LM_web.mpy +0 -0
  274. toolkit/workspace/precompiled/urequests.mpy +0 -0
  275. {micrOS/source → toolkit/workspace/precompiled/web}/dashboard.html +4 -0
  276. toolkit/workspace/precompiled/web/editor.js +440 -0
  277. toolkit/workspace/precompiled/web/filesui.html +178 -0
  278. toolkit/workspace/precompiled/web/filesui.js +338 -0
  279. {micrOS/source → toolkit/workspace/precompiled/web}/index.html +44 -2
  280. toolkit/workspace/precompiled/{uapi.js → web/uapi.js} +48 -7
  281. toolkit/workspace/precompiled/{ustyle.css → web/ustyle.css} +6 -3
  282. micrOS/micropython/esp32-20241129-v1.24.1.bin +0 -0
  283. micrOS/micropython/esp32c3-20240222-v1.22.2.bin +0 -0
  284. micrOS/micropython/esp32s2-20240602-v1.23.0.bin +0 -0
  285. micrOS/micropython/esp32s2-LOLIN_MINI-20220618-v1.19.1.bin +0 -0
  286. micrOS/micropython/esp32s2-LOLIN_MINI-20240602-v1.23.0.bin +0 -0
  287. micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
  288. micrOS/micropython/esp32s3_spiram_oct-20231005-v1.21.0.bin +0 -0
  289. micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin +0 -0
  290. micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2 +0 -0
  291. micrOS/micropython/tinypico-20241129-v1.24.1.bin +0 -0
  292. micrOS/source/LM_L298N_DCmotor.py +0 -86
  293. micrOS/source/LM_catgame.py +0 -75
  294. micrOS/source/LM_dashboard_be.py +0 -37
  295. micrOS/source/LM_demo.py +0 -97
  296. micrOS/source/LM_espnow.py +0 -23
  297. micrOS/source/LM_intercon.py +0 -57
  298. micrOS/source/LM_keychain.py +0 -322
  299. micrOS/source/LM_lmpacman.py +0 -126
  300. micrOS/source/LM_neoeffects.py +0 -331
  301. micrOS/source/LM_oledui.py +0 -972
  302. micrOS/source/LM_pet_feeder.py +0 -78
  303. micrOS/source/LM_ph_sensor.py +0 -51
  304. micrOS/source/LM_robustness.py +0 -74
  305. micrOS/source/reset.py +0 -11
  306. micrOSDevToolKit-2.9.1.dist-info/RECORD +0 -365
  307. toolkit/dashboard_apps/AirQualityBME280.py +0 -36
  308. toolkit/dashboard_apps/AirQualityDHT22_CO2.py +0 -36
  309. toolkit/lib/file_extensions.py +0 -16
  310. toolkit/simulator_lib/__pycache__/sim_console.cpython-312.pyc +0 -0
  311. toolkit/simulator_lib/__pycache__/sim_console.cpython-38.pyc +0 -0
  312. toolkit/simulator_lib/__pycache__/sim_console.cpython-39.pyc +0 -0
  313. toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
  314. toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
  315. toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
  316. toolkit/workspace/precompiled/IO_rp2.mpy +0 -0
  317. toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
  318. toolkit/workspace/precompiled/LM_L298N_DCmotor.mpy +0 -0
  319. toolkit/workspace/precompiled/LM_OV2640.mpy +0 -0
  320. toolkit/workspace/precompiled/LM_catgame.py +0 -75
  321. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  322. toolkit/workspace/precompiled/LM_dashboard_be.py +0 -37
  323. toolkit/workspace/precompiled/LM_demo.py +0 -97
  324. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  325. toolkit/workspace/precompiled/LM_distance.mpy +0 -0
  326. toolkit/workspace/precompiled/LM_espnow.py +0 -23
  327. toolkit/workspace/precompiled/LM_genIO.mpy +0 -0
  328. toolkit/workspace/precompiled/LM_i2s_mic.mpy +0 -0
  329. toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
  330. toolkit/workspace/precompiled/LM_keychain.mpy +0 -0
  331. toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
  332. toolkit/workspace/precompiled/LM_lmpacman.mpy +0 -0
  333. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  334. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  335. toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
  336. toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
  337. toolkit/workspace/precompiled/LM_pet_feeder.py +0 -78
  338. toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
  339. toolkit/workspace/precompiled/LM_presence.mpy +0 -0
  340. toolkit/workspace/precompiled/LM_rest.mpy +0 -0
  341. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  342. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  343. toolkit/workspace/precompiled/LM_robustness.py +0 -74
  344. toolkit/workspace/precompiled/LM_switch.mpy +0 -0
  345. toolkit/workspace/precompiled/LM_system.mpy +0 -0
  346. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  347. toolkit/workspace/precompiled/node_config.json +0 -1
  348. toolkit/workspace/precompiled/reset.mpy +0 -0
  349. /micrOS/source/{IO_esp32.py → modules/IO_esp32.py} +0 -0
  350. /micrOS/source/{IO_esp32c3.py → modules/IO_esp32c3.py} +0 -0
  351. /micrOS/source/{IO_esp32s2.py → modules/IO_esp32s2.py} +0 -0
  352. /micrOS/source/{IO_rp2.py → modules/IO_rp2.py} +0 -0
  353. /micrOS/source/{LM_gameOfLife.py → modules/LM_gameOfLife.py} +0 -0
  354. /micrOS/source/{LM_rgbcct.py → modules/LM_rgbcct.py} +0 -0
  355. /micrOS/source/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  356. /micrOS/source/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
  357. /micrOS/source/{LM_sound_event.py → modules/LM_sound_event.py} +0 -0
  358. /micrOS/source/{LM_tinyrgb.py → modules/LM_tinyrgb.py} +0 -0
  359. /micrOS/source/{udashboard.js → web/udashboard.js} +0 -0
  360. /micrOS/source/{uwidgets.js → web/uwidgets.js} +0 -0
  361. /micrOS/source/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
  362. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info/licenses}/LICENSE +0 -0
  363. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/top_level.txt +0 -0
  364. /toolkit/workspace/precompiled/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  365. /toolkit/workspace/precompiled/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
  366. /toolkit/workspace/precompiled/{udashboard.js → web/udashboard.js} +0 -0
  367. /toolkit/workspace/precompiled/{uwidgets.js → web/uwidgets.js} +0 -0
  368. /toolkit/workspace/precompiled/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
@@ -0,0 +1,440 @@
1
+ /* ============================================================
2
+ * Embedded MicroPython Editor
3
+ * Self-contained, embeddable, dependency-free
4
+ *
5
+ * Public API:
6
+ * createEditor(container)
7
+ * openEditor(url, { anchor, list })
8
+ * destroyEditor()
9
+ * ============================================================ */
10
+
11
+ let _editor = null;
12
+
13
+ // 🔹 track original DOM position of editor container
14
+ let _host = {
15
+ container: null,
16
+ parent: null,
17
+ next: null
18
+ };
19
+
20
+ /* ---------- Public API ---------- */
21
+
22
+ window.createEditor = function (container) {
23
+ console.info("editor.js: createEditor");
24
+ injectCSS();
25
+
26
+ if (!_editor) {
27
+ _host.container = container;
28
+ _host.parent = container.parentNode;
29
+ _host.next = container.nextSibling;
30
+
31
+ _editor = new EmbeddedEditor(container);
32
+ }
33
+ return _editor;
34
+ };
35
+
36
+ window.openEditor = function (url, opts = {}) {
37
+ if (!_editor) {
38
+ console.warn("Editor not active");
39
+ return;
40
+ }
41
+ console.info("editor.js: openEditor");
42
+ const { anchor, list } = opts;
43
+ const c = _host.container;
44
+ // 🔹 editor owns placement logic
45
+ if (anchor) {
46
+ anchor.insertAdjacentElement("afterend", c);
47
+ console.info("editor.js: openEditor.placed after selected element");
48
+ } else if (list) {
49
+ list.insertAdjacentElement("beforebegin", c);
50
+ console.info("editor.js: openEditor.placed before selected element");
51
+ }
52
+
53
+ _editor.open(url);
54
+ };
55
+
56
+ window.destroyEditor = function () {
57
+ if (_editor) {
58
+ _editor.close();
59
+ if (_host.container) {
60
+ _host.container.remove();
61
+ console.info("editor.js: destroyEditor - container removed");
62
+ }
63
+ _editor = null;
64
+ _host.container = null;
65
+ _host.parent = null;
66
+ _host.next = null;
67
+ console.info("editor.js: destroyEditor - editor destroyed");
68
+ }
69
+ };
70
+
71
+ /* ---------- CSS (scoped + injected) ---------- */
72
+
73
+ function injectCSS() {
74
+ if (document.getElementById("mp-editor-css")) return;
75
+
76
+ const css = document.createElement("style");
77
+ css.id = "mp-editor-css";
78
+ css.textContent = `
79
+ .mp-editor {
80
+ font-family: monospace;
81
+ background: #1e1e1e;
82
+ color: #d4d4d4;
83
+ }
84
+ .mp-editor .toolbar {
85
+ background: #252526;
86
+ padding: 6px;
87
+ display: flex;
88
+ gap: 6px;
89
+ align-items: center;
90
+ }
91
+ .mp-editor input {
92
+ background: #1e1e1e;
93
+ color: #d4d4d4;
94
+ border: 1px solid #555;
95
+ padding: 4px 6px;
96
+ }
97
+ .mp-editor button {
98
+ background: #0e639c;
99
+ border: none;
100
+ color: #fff;
101
+ padding: 6px 10px;
102
+ cursor: pointer;
103
+ }
104
+ .mp-editor button:hover { background: #1177bb; }
105
+ .mp-editor .close {
106
+ margin-left: auto;
107
+ background: transparent;
108
+ color: #ccc;
109
+ font-size: 16px;
110
+ padding: 4px 8px;
111
+ }
112
+ .mp-editor .close:hover { background: #333; color: #fff; }
113
+ .mp-editor .status { font-size: 13px; }
114
+ .mp-editor .status.ok { color: #6a9955; }
115
+ .mp-editor .status.err { color: #f44747; }
116
+ .mp-editor .status.info { color: #cccccc; }
117
+ .mp-editor .editor {
118
+ display: flex;
119
+ height: 500px;
120
+ overflow: hidden;
121
+ }
122
+ .mp-editor .lines {
123
+ background: #252526;
124
+ color: #858585;
125
+ padding: 8px;
126
+ text-align: right;
127
+ user-select: none;
128
+ line-height: 20px;
129
+ flex-shrink: 0;
130
+ overflow: hidden;
131
+ white-space: pre;
132
+ }
133
+ .mp-editor textarea {
134
+ flex: 1;
135
+ background: #1e1e1e;
136
+ color: #d4d4d4;
137
+ border: none;
138
+ padding: 8px;
139
+ resize: none;
140
+ outline: none;
141
+ font-family: monospace;
142
+ line-height: 20px;
143
+ overflow: auto;
144
+ }
145
+ .mp-editor .lines,
146
+ .mp-editor input,
147
+ .mp-editor textarea {
148
+ font-size: 14px;
149
+ }
150
+ `;
151
+ document.head.appendChild(css);
152
+ }
153
+
154
+ /* ---------- Syntax registry ---------- */
155
+
156
+ // 🔹 NEW
157
+ const SYNTAX_CHECKERS = {
158
+ ".py": checkPythonSyntax,
159
+ // ".js": checkJSSyntax,
160
+ // ".html": checkHTMLSyntax,
161
+ };
162
+
163
+ // 🔹 NEW
164
+ function getCheckerFor(name) {
165
+ const ext = "." + name.split(".").pop().toLowerCase();
166
+ return SYNTAX_CHECKERS[ext] || null;
167
+ }
168
+
169
+ /* ---------- Editor Implementation ---------- */
170
+
171
+ class EmbeddedEditor {
172
+ constructor(container) {
173
+ this.container = container;
174
+ this.buildUI();
175
+ this.bindEvents();
176
+ }
177
+
178
+ buildUI() {
179
+ console.info("editor.js: EmbeddedEditor.buildUI");
180
+ this.container.innerHTML = `
181
+ <div class="mp-editor">
182
+ <div class="toolbar">
183
+ <input class="filename" value="">
184
+ <button class="load">Load</button>
185
+ <button class="save">Save</button>
186
+ <button class="syntax">Syntax</button>
187
+ <span class="status info">ready</span>
188
+ <button class="close" title="Close">✕</button>
189
+ </div>
190
+ <div class="editor">
191
+ <div class="lines"></div>
192
+ <textarea class="code" wrap="off"></textarea>
193
+ </div>
194
+ </div>`;
195
+ this.codeEl = this.container.querySelector(".code");
196
+ this.linesEl = this.container.querySelector(".lines");
197
+ this.fileEl = this.container.querySelector(".filename");
198
+ this.statusEl = this.container.querySelector(".status");
199
+ this.syntaxBtn = this.container.querySelector(".syntax"); // 🔹 NEW
200
+ }
201
+
202
+ bindEvents() {
203
+ this.codeEl.addEventListener("input", () => {
204
+ this.updateLines();
205
+ this.setStatus("edited");
206
+ });
207
+ this.codeEl.addEventListener("scroll", () =>
208
+ this.linesEl.scrollTop = this.codeEl.scrollTop
209
+ );
210
+ this.codeEl.addEventListener("keydown", e => {
211
+ if (e.key === "Tab") {
212
+ e.preventDefault();
213
+ const s = this.codeEl.selectionStart;
214
+ const ePos = this.codeEl.selectionEnd;
215
+ this.codeEl.value =
216
+ this.codeEl.value.slice(0, s) +
217
+ " " +
218
+ this.codeEl.value.slice(ePos);
219
+ this.codeEl.selectionStart = this.codeEl.selectionEnd = s + 4;
220
+ this.updateLines();
221
+ }
222
+ });
223
+ this.fileEl.addEventListener("input", () => // 🔹 NEW
224
+ this.updateSyntaxAvailability()
225
+ );
226
+ this.container.querySelector(".load")
227
+ .addEventListener("click", () => this.loadFile());
228
+ this.container.querySelector(".save")
229
+ .addEventListener("click", () => this.save());
230
+ this.container.querySelector(".syntax")
231
+ .addEventListener("click", () => this.syntaxCheck());
232
+ this.container.querySelector(".close")
233
+ .addEventListener("click", () => window.destroyEditor());
234
+ }
235
+
236
+ /* ---------- UI helpers ---------- */
237
+
238
+ setStatus(text, type = "info") {
239
+ this.statusEl.textContent = text;
240
+ this.statusEl.className = "status " + type;
241
+ }
242
+
243
+ updateSyntaxAvailability() { // 🔹 NEW
244
+ this.syntaxBtn.style.display =
245
+ getCheckerFor(this.fileEl.value) ? "" : "none";
246
+ }
247
+
248
+ updateLines() {
249
+ const scroll = this.codeEl.scrollTop;
250
+ const count = this.codeEl.value.split("\n").length;
251
+ this.linesEl.textContent =
252
+ Array.from({ length: count }, (_, i) => i + 1).join("\n");
253
+ this.linesEl.scrollTop = scroll;
254
+ }
255
+
256
+ /* ---------- File ops ---------- */
257
+ open(url) {
258
+ const name = url?.split("/").pop();
259
+ this.setStatus("loading...");
260
+ fetch(url)
261
+ .then(r => r.ok ? r.text() : Promise.reject())
262
+ .then(t => {
263
+ // 🔹 Success → show file content + path
264
+ this.codeEl.value = t;
265
+ this.fileEl.value = url;
266
+ this.updateLines();
267
+ this.updateSyntaxAvailability();
268
+ this.setStatus("loaded", "ok");
269
+ })
270
+ .catch(() => {
271
+ // 🔹 Failure → special case for LM_blinky.py
272
+ if (name === "LM_blinky.py") {
273
+ this.fileEl.value = url || ""; // 🔹 show path in input
274
+ this.loadExample();
275
+ } else {
276
+ // 🔹 Empty editor, but still show file path
277
+ this.codeEl.value = "";
278
+ this.fileEl.value = url || "";
279
+ this.updateLines();
280
+ this.updateSyntaxAvailability();
281
+ this.setStatus("file not found or unreadable", "err");
282
+ }
283
+ });
284
+ }
285
+
286
+ loadFile() {
287
+ if (!this.fileEl.value)
288
+ return this.setStatus("no filename", "err");
289
+ console.info("editor.js: EmbeddedEditor.loadFile: ", this.fileEl.value);
290
+ this.open(this.fileEl.value);
291
+ }
292
+
293
+ save() {
294
+ const name = this.fileEl.value;
295
+ if (!name) {
296
+ this.setStatus("no filename", "err");
297
+ return;
298
+ }
299
+
300
+ console.info("editor.js: EmbeddedEditor.save (upload): ", name);
301
+ const blob = new Blob([this.codeEl.value], { type: "text/plain" });
302
+ const file = new File([blob], name);
303
+ const fd = new FormData();
304
+ fd.append("file", file);
305
+
306
+ fetch("/fs/files", { method: "POST", body: fd })
307
+ .then(async r => {
308
+ if (!r.ok) {
309
+ const t = (await r.text()) || r.statusText;
310
+ console.error("editor.js: upload failed:", r.status, r.statusText, t);
311
+ throw new Error(`${r.status} - ${t}`);
312
+ }
313
+ this.setStatus("saved", "ok");
314
+ })
315
+ .catch(err => {
316
+ console.error("editor.js: upload error:", err);
317
+ this.setStatus("Save failed: " + err.message, "err");
318
+ });
319
+ }
320
+
321
+ /* ---------- Syntax ---------- */
322
+ syntaxCheck() { // 🔹 MODIFIED
323
+ const checker = getCheckerFor(this.fileEl.value);
324
+ if (!checker) return;
325
+
326
+ const r = checker(this.codeEl.value);
327
+ this.setStatus(
328
+ r.ok ? "syntax OK" : Object.entries(r.errors[0]).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(" "),
329
+ r.ok ? "ok" : "err"
330
+ );
331
+ }
332
+
333
+ /* ---------- Close ---------- */
334
+ close() {
335
+ this.container.innerHTML = "";
336
+ }
337
+
338
+ /* ---------- Example ---------- */
339
+
340
+ loadExample() {
341
+ console.info("editor.js: EmbeddedEditor.loadExample");
342
+ this.codeEl.value =
343
+ `# LM_blinky.py – MicroPython example
344
+ # Guide: https://github.com/BxNxM/micrOS/blob/master/APPLICATION_GUIDE.md
345
+ import machine
346
+ from microIO import bind_pin, pinmap_search
347
+ from Common import micro_task
348
+
349
+ global LED = None
350
+
351
+ def load(pin=2):
352
+ global LED
353
+ if LED is None:
354
+ LED = machine.Pin(bind_pin("led", pin), machine.Pin.OUT)
355
+ return LED
356
+
357
+ @micro_task("blinky", _wrap=True)
358
+ def blink(tag):
359
+ with micro_task(tag=tag) as my_task:
360
+ if LED is None:
361
+ my_task.out = "LED uninitialized"
362
+ return
363
+ my_task.out = "BlinkyBlink task"
364
+ while True:
365
+ LED.value(not LED.value())
366
+ await my_task.feed(sleep_ms=500)
367
+
368
+ def pinmap():
369
+ return pinmap_search(['led'])
370
+
371
+ def help(widgets=False):
372
+ return "load pin=2", "blink", "pinmap"
373
+ `;
374
+ this.updateLines();
375
+ this.updateSyntaxAvailability();
376
+ this.setStatus("example loaded", "info");
377
+ }
378
+
379
+ }
380
+
381
+ /* ---------- Syntax checker(s) ---------- */
382
+
383
+ function checkPythonSyntax(text) {
384
+ const lines = text
385
+ .replace(/\t/g, " ")
386
+ .replace(/\s+$/, "")
387
+ .split("\n");
388
+ const stack = [0];
389
+ const errors = [];
390
+ const colonRE = /^(async\s+)?(def|with|class)\s+/;
391
+ let depth = 0;
392
+ function lastCodeLine(i) {
393
+ while (i >= 0) {
394
+ const t = lines[i].trim();
395
+ if (t && !t.startsWith("#")) return t;
396
+ i--;
397
+ }
398
+ return "";
399
+ }
400
+ function updateDepth(d, line) {
401
+ for (const c of line.replace(/#.*$/, "")) {
402
+ if ("([{".includes(c)) d++;
403
+ else if (")]}".includes(c)) d = Math.max(0, d - 1);
404
+ }
405
+ return d;
406
+ }
407
+ lines.forEach((line, i) => {
408
+ const n = i + 1;
409
+ const t = line.trim();
410
+ const depthBefore = depth;
411
+ depth = updateDepth(depth, line);
412
+ const topLevel = depthBefore === 0 && depth === 0;
413
+ if (!t || t.startsWith("#")) return;
414
+ const ind = line.match(/^ */)[0].length;
415
+ const cur = stack[stack.length - 1];
416
+ // Indentation check (only at top level)
417
+ if (topLevel) {
418
+ if (ind > cur) {
419
+ const prev = lastCodeLine(i - 1);
420
+ if (!prev.endsWith(":")) {
421
+ errors.push({ line: n, error: "indent", prev, got: ind, expected: cur });
422
+ return;
423
+ }
424
+ stack.push(ind);
425
+ }
426
+ while (stack.length > 1 && ind < stack[stack.length - 1]) {
427
+ stack.pop();
428
+ }
429
+ if (ind !== stack[stack.length - 1]) {
430
+ errors.push({ line: n, error: "dedent", got: ind, expected: stack[stack.length - 1] });
431
+ return;
432
+ }
433
+ }
434
+ // Colon check
435
+ if (colonRE.test(t) && !t.endsWith(":")) {
436
+ errors.push({ line: n, error: "colon", lineText: t });
437
+ }
438
+ });
439
+ return { ok: errors.length === 0, errors };
440
+ }
@@ -0,0 +1,178 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Files</title>
6
+ <!-- Mobile viewport -->
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
8
+ <!-- Base micrOS style -->
9
+ <link rel="stylesheet" href="../ustyle.css">
10
+
11
+ <!-- Files UI layout-only CSS -->
12
+ <style>
13
+ /* Main layout */
14
+ #ui {
15
+ display: flex;
16
+ gap: 40px;
17
+ height: 100%;
18
+ max-width: 95%;
19
+ }
20
+ #folders {
21
+ width: clamp(120px, 20vw, 200px);
22
+ flex-shrink: 0;
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+ /* Disk bar on top of sidebar */
27
+ #diskbar {
28
+ position: sticky;
29
+ top: 0;
30
+ margin-bottom: 12px;
31
+ padding: 6px 10px;
32
+ font-size: 12px;
33
+ background: rgba(255,255,255,.1);
34
+ border-radius: 6px;
35
+ backdrop-filter: blur(2px);
36
+ z-index: 5;
37
+ }
38
+ /* Disk Usage Widget */
39
+ #diskmeter {
40
+ height: 6px;
41
+ background: rgba(255,255,255,.2);
42
+ border-radius: 3px;
43
+ overflow: hidden;
44
+ }
45
+ #diskused {
46
+ height: 100%;
47
+ width: 0%;
48
+ background: #4caf50;
49
+ }
50
+ /* Files column */
51
+ #files {
52
+ flex: 1;
53
+ min-width: 0;
54
+ display: flex;
55
+ flex-direction: column;
56
+ }
57
+ /* Always-visible header in Files */
58
+ #files-header {
59
+ position: sticky;
60
+ top: 0;
61
+ z-index: 5;
62
+ padding-bottom: 8px;
63
+ background: rgba(255,255,255,.1);
64
+ border-radius: 6px;
65
+ backdrop-filter: blur(2px);
66
+ }
67
+ /* Toolbar */
68
+ #top {
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 8px;
72
+ min-height: 44px;
73
+ flex-wrap: wrap;
74
+ }
75
+ #top input[type="file"] {
76
+ max-width: 100%;
77
+ }
78
+ /* Scrollable file list ONLY */
79
+ #list {
80
+ flex: 1;
81
+ overflow-y: auto;
82
+ }
83
+ #list div {
84
+ padding: 6px 8px;
85
+ border-radius: 4px;
86
+ cursor: pointer;
87
+ word-break: break-word;
88
+ }
89
+ #list div:hover {
90
+ background: rgba(255,255,255,.1);
91
+ }
92
+ /* Default selection style (files, editor, etc) */
93
+ .sel {
94
+ background: color-mix(in srgb, white 40%, transparent);
95
+ box-shadow: inset 0 0 0 2px color-mix(in srgb, white 60%, transparent);
96
+ }
97
+ /* Softer selection for folders only */
98
+ #folder-path .sel {
99
+ background: color-mix(in srgb, white 15%, transparent);
100
+ box-shadow: none;
101
+ }
102
+ /* Folder list spacing */
103
+ #folder-path {
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: 5px;
107
+ }
108
+ /* Folder item padding + touch-friendly */
109
+ #folder-path .dir-item {
110
+ padding: 5px 6px; /*makes them easier to tap*/
111
+ border-radius: 3px;
112
+ cursor: pointer;
113
+ }
114
+ /* Hover effect for folders */
115
+ #folder-path .dir-item:hover {
116
+ background: rgba(255,255,255,.08);
117
+ }
118
+ .folders {
119
+ margin-bottom: 8px;
120
+ }
121
+ /* Keep Folders title + list sticky as ONE block under disk bar */
122
+ #folders-sticky {
123
+ position: sticky;
124
+ top: 60px; /* sits just below diskbar */
125
+ z-index: 4;
126
+ }
127
+ /* directory file listing effect */
128
+ #list.loading {
129
+ filter: blur(3px);
130
+ opacity: 0.5;
131
+ pointer-events: none; /* prevents clicking while loading */
132
+ transition: filter 0.15s ease, opacity 0.15s ease;
133
+ }
134
+ </style>
135
+ </head>
136
+
137
+ <body>
138
+ <h1> micrOS Files </h1>
139
+
140
+ <div id="ui">
141
+ <!-- Left sidebar (fixed, no scroll) -->
142
+ <aside id="folders">
143
+ <header id="diskbar">
144
+ <div id="disktext">Disk: — MB used / — MB free</div>
145
+ <div id="diskmeter">
146
+ <div id="diskused"></div>
147
+ </div>
148
+ </header>
149
+
150
+ <!-- Sticky folder block -->
151
+ <div id="folders-sticky">
152
+ <div class="folders">📂 Folders</div>
153
+ <div id="folder-path">/user_data</div>
154
+ </div>
155
+ </aside>
156
+
157
+ <!-- Files column -->
158
+ <main id="files">
159
+ <!-- Sticky files header -->
160
+ <div id="files-header">
161
+ <div id="top">
162
+ <input type="file" id="file">
163
+ <button onclick="uploadFile()">🔼 Upload</button>
164
+ <button onclick="openFile()">📖 Open</button>
165
+ <button onclick="download()">🔽 Download</button>
166
+ <button onclick="deleteFile()"> 🗑️ Delete</button>
167
+ <button onclick="editor()">📄 Edit</button>
168
+ </div>
169
+ </div>
170
+
171
+ <!-- Only this scrolls -->
172
+ <div id="list"></div>
173
+ </main>
174
+ </div>
175
+
176
+ <script src="../filesui.js"></script>
177
+ </body>
178
+ </html>