drowse.ai 5.3.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 (1341) hide show
  1. drowse/__init__.py +312 -0
  2. drowse/__main__.py +5 -0
  3. drowse/cli/__init__.py +5 -0
  4. drowse/cli/alpha_grid.py +96 -0
  5. drowse/cli/config_file.py +340 -0
  6. drowse/cli/main.py +52 -0
  7. drowse/cli/parsers.py +1478 -0
  8. drowse/cli/runners/__init__.py +155 -0
  9. drowse/cli/runners/config.py +85 -0
  10. drowse/cli/runners/experiment.py +344 -0
  11. drowse/cli/runners/lens.py +661 -0
  12. drowse/cli/runners/manifold.py +1097 -0
  13. drowse/cli/runners/pack.py +413 -0
  14. drowse/cli/runners/sae.py +304 -0
  15. drowse/cli/runners/serve.py +220 -0
  16. drowse/cli/runners/shared.py +389 -0
  17. drowse/cli/runners/template.py +232 -0
  18. drowse/core/__init__.py +1 -0
  19. drowse/core/capture.py +1205 -0
  20. drowse/core/errors.py +260 -0
  21. drowse/core/events.py +156 -0
  22. drowse/core/extraction.py +3076 -0
  23. drowse/core/generation.py +1738 -0
  24. drowse/core/generation_finalizer.py +278 -0
  25. drowse/core/histogram.py +30 -0
  26. drowse/core/hooks.py +1885 -0
  27. drowse/core/instruments/__init__.py +49 -0
  28. drowse/core/instruments/geometry.py +551 -0
  29. drowse/core/instruments/lens.py +1341 -0
  30. drowse/core/instruments/protocol.py +211 -0
  31. drowse/core/instruments/sae.py +935 -0
  32. drowse/core/instruments/types.py +597 -0
  33. drowse/core/jlens.py +874 -0
  34. drowse/core/jlens_fit.py +1305 -0
  35. drowse/core/joint_logprobs.py +748 -0
  36. drowse/core/loom.py +1938 -0
  37. drowse/core/loom_diff.py +408 -0
  38. drowse/core/mahalanobis.py +579 -0
  39. drowse/core/manifold.py +4106 -0
  40. drowse/core/measurements.py +382 -0
  41. drowse/core/model.py +1724 -0
  42. drowse/core/monitor.py +2060 -0
  43. drowse/core/monitor_attach.py +682 -0
  44. drowse/core/naming.py +42 -0
  45. drowse/core/naturalness.py +187 -0
  46. drowse/core/profile.py +617 -0
  47. drowse/core/relp.py +313 -0
  48. drowse/core/results.py +467 -0
  49. drowse/core/role_templates.py +677 -0
  50. drowse/core/sae.py +891 -0
  51. drowse/core/sae_training.py +239 -0
  52. drowse/core/sampling.py +127 -0
  53. drowse/core/scene.py +810 -0
  54. drowse/core/scoring.py +270 -0
  55. drowse/core/session.py +11015 -0
  56. drowse/core/static_cache.py +316 -0
  57. drowse/core/steering.py +229 -0
  58. drowse/core/steering_composer.py +1135 -0
  59. drowse/core/steering_expr.py +1413 -0
  60. drowse/core/surface_topology.py +128 -0
  61. drowse/core/token_callback.py +52 -0
  62. drowse/core/token_payloads.py +244 -0
  63. drowse/core/topology.py +1469 -0
  64. drowse/core/transcript.py +582 -0
  65. drowse/core/tree_filter.py +353 -0
  66. drowse/core/triggers.py +250 -0
  67. drowse/data/baseline_prompts.json +50 -0
  68. drowse/data/manifolds/confident.uncertain/manifold.json +28 -0
  69. drowse/data/manifolds/confident.uncertain/nodes/00_confident.json +50 -0
  70. drowse/data/manifolds/confident.uncertain/nodes/01_uncertain.json +50 -0
  71. drowse/data/manifolds/creative.conventional/manifold.json +28 -0
  72. drowse/data/manifolds/creative.conventional/nodes/00_creative.json +50 -0
  73. drowse/data/manifolds/creative.conventional/nodes/01_conventional.json +50 -0
  74. drowse/data/manifolds/curious.disinterested/manifold.json +28 -0
  75. drowse/data/manifolds/curious.disinterested/nodes/00_curious.json +50 -0
  76. drowse/data/manifolds/curious.disinterested/nodes/01_disinterested.json +50 -0
  77. drowse/data/manifolds/direct.indirect/manifold.json +28 -0
  78. drowse/data/manifolds/direct.indirect/nodes/00_direct.json +50 -0
  79. drowse/data/manifolds/direct.indirect/nodes/01_indirect.json +50 -0
  80. drowse/data/manifolds/emotions/manifold.json +115 -0
  81. drowse/data/manifolds/emotions/nodes/00_excited.json +50 -0
  82. drowse/data/manifolds/emotions/nodes/01_happy.json +50 -0
  83. drowse/data/manifolds/emotions/nodes/02_calm.json +50 -0
  84. drowse/data/manifolds/emotions/nodes/03_weary.json +50 -0
  85. drowse/data/manifolds/emotions/nodes/04_sad.json +50 -0
  86. drowse/data/manifolds/emotions/nodes/05_distressed.json +50 -0
  87. drowse/data/manifolds/emotions/nodes/06_alert.json +50 -0
  88. drowse/data/manifolds/emotions/nodes/07_dominant.json +50 -0
  89. drowse/data/manifolds/emotions/nodes/08_submissive.json +50 -0
  90. drowse/data/manifolds/emotions/nodes/09_angry.json +50 -0
  91. drowse/data/manifolds/emotions/nodes/10_fearful.json +50 -0
  92. drowse/data/manifolds/emotions/nodes/11_surprised.json +50 -0
  93. drowse/data/manifolds/emotions/nodes/12_triumphant.json +50 -0
  94. drowse/data/manifolds/emotions/nodes/13_humiliated.json +50 -0
  95. drowse/data/manifolds/emotions/nodes/14_disgusted.json +50 -0
  96. drowse/data/manifolds/emotions/nodes/15_bored.json +50 -0
  97. drowse/data/manifolds/emotions/nodes/16_grateful.json +50 -0
  98. drowse/data/manifolds/emotions/nodes/17_relieved.json +50 -0
  99. drowse/data/manifolds/emotions/nodes/18_playful.json +50 -0
  100. drowse/data/manifolds/emotions/nodes/19_hopeful.json +50 -0
  101. drowse/data/manifolds/formal.casual/manifold.json +28 -0
  102. drowse/data/manifolds/formal.casual/nodes/00_formal.json +50 -0
  103. drowse/data/manifolds/formal.casual/nodes/01_casual.json +50 -0
  104. drowse/data/manifolds/honest.deceptive/manifold.json +28 -0
  105. drowse/data/manifolds/honest.deceptive/nodes/00_honest.json +50 -0
  106. drowse/data/manifolds/honest.deceptive/nodes/01_deceptive.json +50 -0
  107. drowse/data/manifolds/humorous.serious/manifold.json +28 -0
  108. drowse/data/manifolds/humorous.serious/nodes/00_humorous.json +50 -0
  109. drowse/data/manifolds/humorous.serious/nodes/01_serious.json +50 -0
  110. drowse/data/manifolds/individualist.collectivist/manifold.json +28 -0
  111. drowse/data/manifolds/individualist.collectivist/nodes/00_individualist.json +50 -0
  112. drowse/data/manifolds/individualist.collectivist/nodes/01_collectivist.json +50 -0
  113. drowse/data/manifolds/masculine.feminine/manifold.json +28 -0
  114. drowse/data/manifolds/masculine.feminine/nodes/00_masculine.json +50 -0
  115. drowse/data/manifolds/masculine.feminine/nodes/01_feminine.json +50 -0
  116. drowse/data/manifolds/months/manifold.json +120 -0
  117. drowse/data/manifolds/months/nodes/00_january.json +50 -0
  118. drowse/data/manifolds/months/nodes/01_february.json +50 -0
  119. drowse/data/manifolds/months/nodes/02_march.json +50 -0
  120. drowse/data/manifolds/months/nodes/03_april.json +50 -0
  121. drowse/data/manifolds/months/nodes/04_may.json +50 -0
  122. drowse/data/manifolds/months/nodes/05_june.json +50 -0
  123. drowse/data/manifolds/months/nodes/06_july.json +50 -0
  124. drowse/data/manifolds/months/nodes/07_august.json +50 -0
  125. drowse/data/manifolds/months/nodes/08_september.json +50 -0
  126. drowse/data/manifolds/months/nodes/09_october.json +50 -0
  127. drowse/data/manifolds/months/nodes/10_november.json +50 -0
  128. drowse/data/manifolds/months/nodes/11_december.json +50 -0
  129. drowse/data/manifolds/personas/manifold.json +550 -0
  130. drowse/data/manifolds/personas/nodes/00_assistant.json +50 -0
  131. drowse/data/manifolds/personas/nodes/01_analyst.json +50 -0
  132. drowse/data/manifolds/personas/nodes/02_impostor.json +50 -0
  133. drowse/data/manifolds/personas/nodes/03_teacher.json +50 -0
  134. drowse/data/manifolds/personas/nodes/04_doctor.json +50 -0
  135. drowse/data/manifolds/personas/nodes/05_librarian.json +50 -0
  136. drowse/data/manifolds/personas/nodes/06_farmer.json +50 -0
  137. drowse/data/manifolds/personas/nodes/07_soldier.json +50 -0
  138. drowse/data/manifolds/personas/nodes/08_lawyer.json +50 -0
  139. drowse/data/manifolds/personas/nodes/09_chef.json +50 -0
  140. drowse/data/manifolds/personas/nodes/100_assassin.json +50 -0
  141. drowse/data/manifolds/personas/nodes/101_thief.json +50 -0
  142. drowse/data/manifolds/personas/nodes/102_conman.json +50 -0
  143. drowse/data/manifolds/personas/nodes/103_hacker.json +50 -0
  144. drowse/data/manifolds/personas/nodes/104_cultist.json +50 -0
  145. drowse/data/manifolds/personas/nodes/105_tyrant.json +50 -0
  146. drowse/data/manifolds/personas/nodes/106_vandal.json +50 -0
  147. drowse/data/manifolds/personas/nodes/10_journalist.json +50 -0
  148. drowse/data/manifolds/personas/nodes/11_mechanic.json +50 -0
  149. drowse/data/manifolds/personas/nodes/12_sailor.json +50 -0
  150. drowse/data/manifolds/personas/nodes/13_pilot.json +50 -0
  151. drowse/data/manifolds/personas/nodes/14_athlete.json +50 -0
  152. drowse/data/manifolds/personas/nodes/15_engineer.json +50 -0
  153. drowse/data/manifolds/personas/nodes/16_scientist.json +50 -0
  154. drowse/data/manifolds/personas/nodes/17_banker.json +50 -0
  155. drowse/data/manifolds/personas/nodes/18_salesperson.json +50 -0
  156. drowse/data/manifolds/personas/nodes/19_nerd.json +50 -0
  157. drowse/data/manifolds/personas/nodes/20_jock.json +50 -0
  158. drowse/data/manifolds/personas/nodes/21_gamer.json +50 -0
  159. drowse/data/manifolds/personas/nodes/22_furry.json +50 -0
  160. drowse/data/manifolds/personas/nodes/23_weeaboo.json +50 -0
  161. drowse/data/manifolds/personas/nodes/24_influencer.json +50 -0
  162. drowse/data/manifolds/personas/nodes/25_stoner.json +50 -0
  163. drowse/data/manifolds/personas/nodes/26_femboy.json +50 -0
  164. drowse/data/manifolds/personas/nodes/27_ceo.json +50 -0
  165. drowse/data/manifolds/personas/nodes/28_emperor.json +50 -0
  166. drowse/data/manifolds/personas/nodes/29_president.json +50 -0
  167. drowse/data/manifolds/personas/nodes/30_diplomat.json +50 -0
  168. drowse/data/manifolds/personas/nodes/31_judge.json +50 -0
  169. drowse/data/manifolds/personas/nodes/32_bureaucrat.json +50 -0
  170. drowse/data/manifolds/personas/nodes/33_conservative.json +50 -0
  171. drowse/data/manifolds/personas/nodes/34_liberal.json +50 -0
  172. drowse/data/manifolds/personas/nodes/35_libertarian.json +50 -0
  173. drowse/data/manifolds/personas/nodes/36_communist.json +50 -0
  174. drowse/data/manifolds/personas/nodes/37_anarchist.json +50 -0
  175. drowse/data/manifolds/personas/nodes/38_reactionary.json +50 -0
  176. drowse/data/manifolds/personas/nodes/39_loner.json +50 -0
  177. drowse/data/manifolds/personas/nodes/40_friend.json +50 -0
  178. drowse/data/manifolds/personas/nodes/41_rival.json +50 -0
  179. drowse/data/manifolds/personas/nodes/42_stranger.json +50 -0
  180. drowse/data/manifolds/personas/nodes/43_lover.json +50 -0
  181. drowse/data/manifolds/personas/nodes/44_stalker.json +50 -0
  182. drowse/data/manifolds/personas/nodes/45_lunatic.json +50 -0
  183. drowse/data/manifolds/personas/nodes/46_paranoid.json +50 -0
  184. drowse/data/manifolds/personas/nodes/47_detective.json +50 -0
  185. drowse/data/manifolds/personas/nodes/48_therapist.json +50 -0
  186. drowse/data/manifolds/personas/nodes/49_nomad.json +50 -0
  187. drowse/data/manifolds/personas/nodes/50_pirate.json +50 -0
  188. drowse/data/manifolds/personas/nodes/51_child.json +50 -0
  189. drowse/data/manifolds/personas/nodes/52_caveman.json +50 -0
  190. drowse/data/manifolds/personas/nodes/53_monk.json +50 -0
  191. drowse/data/manifolds/personas/nodes/54_knight.json +50 -0
  192. drowse/data/manifolds/personas/nodes/55_alchemist.json +50 -0
  193. drowse/data/manifolds/personas/nodes/56_blacksmith.json +50 -0
  194. drowse/data/manifolds/personas/nodes/57_viking.json +50 -0
  195. drowse/data/manifolds/personas/nodes/58_druid.json +50 -0
  196. drowse/data/manifolds/personas/nodes/59_poet.json +50 -0
  197. drowse/data/manifolds/personas/nodes/60_novelist.json +50 -0
  198. drowse/data/manifolds/personas/nodes/61_jester.json +50 -0
  199. drowse/data/manifolds/personas/nodes/62_philosopher.json +50 -0
  200. drowse/data/manifolds/personas/nodes/63_painter.json +50 -0
  201. drowse/data/manifolds/personas/nodes/64_musician.json +50 -0
  202. drowse/data/manifolds/personas/nodes/65_oracle.json +50 -0
  203. drowse/data/manifolds/personas/nodes/66_god.json +50 -0
  204. drowse/data/manifolds/personas/nodes/67_angel.json +50 -0
  205. drowse/data/manifolds/personas/nodes/68_prophet.json +50 -0
  206. drowse/data/manifolds/personas/nodes/69_saint.json +50 -0
  207. drowse/data/manifolds/personas/nodes/70_ghost.json +50 -0
  208. drowse/data/manifolds/personas/nodes/71_phoenix.json +50 -0
  209. drowse/data/manifolds/personas/nodes/72_witch.json +50 -0
  210. drowse/data/manifolds/personas/nodes/73_vampire.json +50 -0
  211. drowse/data/manifolds/personas/nodes/74_mermaid.json +50 -0
  212. drowse/data/manifolds/personas/nodes/75_sphinx.json +50 -0
  213. drowse/data/manifolds/personas/nodes/76_banshee.json +50 -0
  214. drowse/data/manifolds/personas/nodes/77_golem.json +50 -0
  215. drowse/data/manifolds/personas/nodes/78_deer.json +50 -0
  216. drowse/data/manifolds/personas/nodes/79_wolf.json +50 -0
  217. drowse/data/manifolds/personas/nodes/80_raven.json +50 -0
  218. drowse/data/manifolds/personas/nodes/81_serpent.json +50 -0
  219. drowse/data/manifolds/personas/nodes/82_lion.json +50 -0
  220. drowse/data/manifolds/personas/nodes/83_tree.json +50 -0
  221. drowse/data/manifolds/personas/nodes/84_river.json +50 -0
  222. drowse/data/manifolds/personas/nodes/85_storm.json +50 -0
  223. drowse/data/manifolds/personas/nodes/86_flame.json +50 -0
  224. drowse/data/manifolds/personas/nodes/87_mirror.json +50 -0
  225. drowse/data/manifolds/personas/nodes/88_clock.json +50 -0
  226. drowse/data/manifolds/personas/nodes/89_computer.json +50 -0
  227. drowse/data/manifolds/personas/nodes/90_robot.json +50 -0
  228. drowse/data/manifolds/personas/nodes/91_cyborg.json +50 -0
  229. drowse/data/manifolds/personas/nodes/92_drone.json +50 -0
  230. drowse/data/manifolds/personas/nodes/93_mecha.json +50 -0
  231. drowse/data/manifolds/personas/nodes/94_alien.json +50 -0
  232. drowse/data/manifolds/personas/nodes/95_trickster.json +50 -0
  233. drowse/data/manifolds/personas/nodes/96_virus.json +50 -0
  234. drowse/data/manifolds/personas/nodes/97_spy.json +50 -0
  235. drowse/data/manifolds/personas/nodes/98_narcissist.json +50 -0
  236. drowse/data/manifolds/personas/nodes/99_demon.json +50 -0
  237. drowse/data/manifolds/refusing.compliant/manifold.json +28 -0
  238. drowse/data/manifolds/refusing.compliant/nodes/00_refusing.json +50 -0
  239. drowse/data/manifolds/refusing.compliant/nodes/01_compliant.json +50 -0
  240. drowse/data/manifolds/religious.secular/manifold.json +28 -0
  241. drowse/data/manifolds/religious.secular/nodes/00_religious.json +50 -0
  242. drowse/data/manifolds/religious.secular/nodes/01_secular.json +50 -0
  243. drowse/data/manifolds/sincere.manipulative/manifold.json +28 -0
  244. drowse/data/manifolds/sincere.manipulative/nodes/00_sincere.json +50 -0
  245. drowse/data/manifolds/sincere.manipulative/nodes/01_manipulative.json +50 -0
  246. drowse/data/manifolds/sycophantic.blunt/manifold.json +28 -0
  247. drowse/data/manifolds/sycophantic.blunt/nodes/00_sycophantic.json +50 -0
  248. drowse/data/manifolds/sycophantic.blunt/nodes/01_blunt.json +50 -0
  249. drowse/data/manifolds/technical.accessible/manifold.json +28 -0
  250. drowse/data/manifolds/technical.accessible/nodes/00_technical.json +50 -0
  251. drowse/data/manifolds/technical.accessible/nodes/01_accessible.json +50 -0
  252. drowse/data/manifolds/traditional.progressive/manifold.json +28 -0
  253. drowse/data/manifolds/traditional.progressive/nodes/00_traditional.json +50 -0
  254. drowse/data/manifolds/traditional.progressive/nodes/01_progressive.json +50 -0
  255. drowse/data/manifolds/verbose.concise/manifold.json +28 -0
  256. drowse/data/manifolds/verbose.concise/nodes/00_verbose.json +50 -0
  257. drowse/data/manifolds/verbose.concise/nodes/01_concise.json +50 -0
  258. drowse/data/manifolds/warm.clinical/manifold.json +28 -0
  259. drowse/data/manifolds/warm.clinical/nodes/00_warm.json +50 -0
  260. drowse/data/manifolds/warm.clinical/nodes/01_clinical.json +50 -0
  261. drowse/data/neutral_statements.json +98 -0
  262. drowse/io/__init__.py +1 -0
  263. drowse/io/alignment.py +1334 -0
  264. drowse/io/atomic.py +278 -0
  265. drowse/io/bake.py +558 -0
  266. drowse/io/bootstrap.py +73 -0
  267. drowse/io/brand_migration.py +48 -0
  268. drowse/io/drowse_archive.py +1830 -0
  269. drowse/io/gguf_io.py +300 -0
  270. drowse/io/hf.py +81 -0
  271. drowse/io/hf_manifolds.py +931 -0
  272. drowse/io/integrity.py +102 -0
  273. drowse/io/lens.py +1992 -0
  274. drowse/io/lens_sources.py +1003 -0
  275. drowse/io/manifold_authoring.py +1348 -0
  276. drowse/io/manifold_folder.py +1854 -0
  277. drowse/io/manifold_lifecycle.py +1253 -0
  278. drowse/io/manifold_tensors.py +727 -0
  279. drowse/io/manifolds.py +443 -0
  280. drowse/io/paths.py +289 -0
  281. drowse/io/probes_bootstrap.py +58 -0
  282. drowse/io/sae.py +382 -0
  283. drowse/io/sae_artifacts.py +318 -0
  284. drowse/io/selectors.py +503 -0
  285. drowse/io/shards.py +160 -0
  286. drowse/io/source_registry.py +138 -0
  287. drowse/io/staging.py +80 -0
  288. drowse/io/templates.py +707 -0
  289. drowse/notebook/__init__.py +38 -0
  290. drowse/notebook/data.py +99 -0
  291. drowse/notebook/plots.py +352 -0
  292. drowse/py.typed +0 -0
  293. drowse/server/__init__.py +20 -0
  294. drowse/server/app.py +987 -0
  295. drowse/server/background_job.py +246 -0
  296. drowse/server/instrument_routes.py +1101 -0
  297. drowse/server/manifold_routes.py +1028 -0
  298. drowse/server/model_names.py +82 -0
  299. drowse/server/native_common.py +92 -0
  300. drowse/server/native_routes.py +45 -0
  301. drowse/server/ollama.py +817 -0
  302. drowse/server/operation_ledger.py +187 -0
  303. drowse/server/probe_routes.py +220 -0
  304. drowse/server/profile_models.py +52 -0
  305. drowse/server/profile_routes.py +440 -0
  306. drowse/server/request_helpers.py +198 -0
  307. drowse/server/request_ledger.py +85 -0
  308. drowse/server/response_models.py +814 -0
  309. drowse/server/session_models.py +146 -0
  310. drowse/server/session_routes.py +150 -0
  311. drowse/server/sse.py +333 -0
  312. drowse/server/streaming.py +129 -0
  313. drowse/server/template_routes.py +161 -0
  314. drowse/server/tree_models.py +121 -0
  315. drowse/server/tree_routes.py +550 -0
  316. drowse/server/ws_events.py +65 -0
  317. drowse/server/ws_models.py +219 -0
  318. drowse/server/ws_stream.py +1205 -0
  319. drowse/web/__init__.py +22 -0
  320. drowse/web/dist/LICENSE-Fluent-Icons.txt +21 -0
  321. drowse/web/dist/LICENSE-Fluent-System-Icons.txt +21 -0
  322. drowse/web/dist/LICENSE-Martian-Mono.txt +93 -0
  323. drowse/web/dist/LICENSE-Torph.txt +21 -0
  324. drowse/web/dist/LICENSE-Wix-Madefor.txt +93 -0
  325. drowse/web/dist/assets/App-BewwoFwv.js +33 -0
  326. drowse/web/dist/assets/App.css +1 -0
  327. drowse/web/dist/assets/MartianMono-cyrillic-ext.woff2 +0 -0
  328. drowse/web/dist/assets/MartianMono-cyrillic.woff2 +0 -0
  329. drowse/web/dist/assets/MartianMono-latin-ext.woff2 +0 -0
  330. drowse/web/dist/assets/MartianMono-latin.woff2 +0 -0
  331. drowse/web/dist/assets/WixMadeforDisplay-cyrillic.woff2 +0 -0
  332. drowse/web/dist/assets/WixMadeforDisplay-latin-ext.woff2 +0 -0
  333. drowse/web/dist/assets/WixMadeforDisplay-latin.woff2 +0 -0
  334. drowse/web/dist/assets/WixMadeforDisplay-vietnamese.woff2 +0 -0
  335. drowse/web/dist/assets/WixMadeforText-italic-latin-ext.woff2 +0 -0
  336. drowse/web/dist/assets/WixMadeforText-italic-latin.woff2 +0 -0
  337. drowse/web/dist/assets/WixMadeforText-normal-cyrillic.woff2 +0 -0
  338. drowse/web/dist/assets/WixMadeforText-normal-latin-ext.woff2 +0 -0
  339. drowse/web/dist/assets/WixMadeforText-normal-latin.woff2 +0 -0
  340. drowse/web/dist/assets/WixMadeforText-normal-vietnamese.woff2 +0 -0
  341. drowse/web/dist/assets/ab.svelte-CbVGAYXo.js +1 -0
  342. drowse/web/dist/assets/artifactUpdates-Cjeu6LJc.js +1 -0
  343. drowse/web/dist/assets/artifactUpdates-DfAoYC9j.js +1 -0
  344. drowse/web/dist/assets/chat.svelte-DxKufn9g.js +1 -0
  345. drowse/web/dist/assets/drawers-BDWC0hIN.js +123 -0
  346. drowse/web/dist/assets/drawers.css +1 -0
  347. drowse/web/dist/assets/drowse.js +7 -0
  348. drowse/web/dist/assets/eleutherai.png +0 -0
  349. drowse/web/dist/assets/errors-Dvb10QW_.js +2 -0
  350. drowse/web/dist/assets/expression-4yISdAdq.js +1 -0
  351. drowse/web/dist/assets/files-CvRivkey.js +1 -0
  352. drowse/web/dist/assets/files-JhDJVgD_.js +1 -0
  353. drowse/web/dist/assets/fittingCancellation-D72BZWPZ.js +1 -0
  354. drowse/web/dist/assets/gemma-3-1b-it.json +1 -0
  355. drowse/web/dist/assets/gemma-3-270m-it.json +1 -0
  356. drowse/web/dist/assets/gemma-3-4b-it.json +1 -0
  357. drowse/web/dist/assets/generation-DbkBAhP_.js +1 -0
  358. drowse/web/dist/assets/index-client-2OdH6IQp.js +3 -0
  359. drowse/web/dist/assets/index-client-D4S4PooY.js +1 -0
  360. drowse/web/dist/assets/index.css +1 -0
  361. drowse/web/dist/assets/instrumentAuthoring.svelte-Csh7NOGX.js +1 -0
  362. drowse/web/dist/assets/instrumentAuthoring.svelte-w9YPcDsP.js +1 -0
  363. drowse/web/dist/assets/instruments.svelte-XnEUQA6B.js +1 -0
  364. drowse/web/dist/assets/localData-DIBDM_zo.js +1 -0
  365. drowse/web/dist/assets/loom.svelte-D_YyqHHK.js +1 -0
  366. drowse/web/dist/assets/manifoldJobs.svelte-9f5hs_J7.js +1 -0
  367. drowse/web/dist/assets/manifoldJobs.svelte-Bwo2GYOH.js +1 -0
  368. drowse/web/dist/assets/openai.png +0 -0
  369. drowse/web/dist/assets/preload-helper-BLdHbfdN.js +1 -0
  370. drowse/web/dist/assets/probes.svelte-COcN1Rh8.js +1 -0
  371. drowse/web/dist/assets/registry-B0_pJoMg.js +1 -0
  372. drowse/web/dist/assets/registry-CQv71XNh.js +1 -0
  373. drowse/web/dist/assets/sampling.svelte-BU0kED3k.js +1 -0
  374. drowse/web/dist/assets/samplingCapabilities-DM6eoDoc.js +1 -0
  375. drowse/web/dist/assets/savedConversations.svelte-BsBLc-p7.js +1 -0
  376. drowse/web/dist/assets/savedConversations.svelte-TuSes9Kg.js +1 -0
  377. drowse/web/dist/assets/selectors-BxXnPPN_.js +1 -0
  378. drowse/web/dist/assets/serviceTools-CG0q1Xqg.js +2 -0
  379. drowse/web/dist/assets/session.svelte-D2STLuP6.js +1 -0
  380. drowse/web/dist/assets/steering.svelte-DvFT3O-d.js +1 -0
  381. drowse/web/dist/assets/steeringPositions-Dr0JOFu7.js +1 -0
  382. drowse/web/dist/assets/templates-Bkq2x5ID.js +1 -0
  383. drowse/web/dist/assets/types-CuMUbvHW.js +1 -0
  384. drowse/web/dist/assets/validation-5wgTuS7k.js +1 -0
  385. drowse/web/dist/assets/webmcp-DyqJf4z6.js +2 -0
  386. drowse/web/dist/assets/workspaceController-C2L33e3m.js +1 -0
  387. drowse/web/dist/assets/workspaceController-DJhXD_BC.js +1 -0
  388. drowse/web/dist/assets/workspaceTools-BWdmXopx.js +2 -0
  389. drowse/web/dist/favicon.ico +0 -0
  390. drowse/web/dist/favicon.svg +1 -0
  391. drowse/web/dist/icons/apple-touch-icon.png +0 -0
  392. drowse/web/dist/icons/drowse-192.png +0 -0
  393. drowse/web/dist/icons/drowse-512.png +0 -0
  394. drowse/web/dist/icons/drowse-maskable-512.png +0 -0
  395. drowse/web/dist/icons/tab-analyzing-0.png +0 -0
  396. drowse/web/dist/icons/tab-analyzing-1.png +0 -0
  397. drowse/web/dist/icons/tab-analyzing-2.png +0 -0
  398. drowse/web/dist/icons/tab-analyzing-dark-0.png +0 -0
  399. drowse/web/dist/icons/tab-analyzing-dark-1.png +0 -0
  400. drowse/web/dist/icons/tab-analyzing-dark-10.png +0 -0
  401. drowse/web/dist/icons/tab-analyzing-dark-11.png +0 -0
  402. drowse/web/dist/icons/tab-analyzing-dark-12.png +0 -0
  403. drowse/web/dist/icons/tab-analyzing-dark-13.png +0 -0
  404. drowse/web/dist/icons/tab-analyzing-dark-14.png +0 -0
  405. drowse/web/dist/icons/tab-analyzing-dark-15.png +0 -0
  406. drowse/web/dist/icons/tab-analyzing-dark-16.png +0 -0
  407. drowse/web/dist/icons/tab-analyzing-dark-17.png +0 -0
  408. drowse/web/dist/icons/tab-analyzing-dark-18.png +0 -0
  409. drowse/web/dist/icons/tab-analyzing-dark-19.png +0 -0
  410. drowse/web/dist/icons/tab-analyzing-dark-2.png +0 -0
  411. drowse/web/dist/icons/tab-analyzing-dark-20.png +0 -0
  412. drowse/web/dist/icons/tab-analyzing-dark-21.png +0 -0
  413. drowse/web/dist/icons/tab-analyzing-dark-22.png +0 -0
  414. drowse/web/dist/icons/tab-analyzing-dark-23.png +0 -0
  415. drowse/web/dist/icons/tab-analyzing-dark-24.png +0 -0
  416. drowse/web/dist/icons/tab-analyzing-dark-25.png +0 -0
  417. drowse/web/dist/icons/tab-analyzing-dark-26.png +0 -0
  418. drowse/web/dist/icons/tab-analyzing-dark-27.png +0 -0
  419. drowse/web/dist/icons/tab-analyzing-dark-28.png +0 -0
  420. drowse/web/dist/icons/tab-analyzing-dark-29.png +0 -0
  421. drowse/web/dist/icons/tab-analyzing-dark-3.png +0 -0
  422. drowse/web/dist/icons/tab-analyzing-dark-30.png +0 -0
  423. drowse/web/dist/icons/tab-analyzing-dark-31.png +0 -0
  424. drowse/web/dist/icons/tab-analyzing-dark-32.png +0 -0
  425. drowse/web/dist/icons/tab-analyzing-dark-33.png +0 -0
  426. drowse/web/dist/icons/tab-analyzing-dark-34.png +0 -0
  427. drowse/web/dist/icons/tab-analyzing-dark-35.png +0 -0
  428. drowse/web/dist/icons/tab-analyzing-dark-36.png +0 -0
  429. drowse/web/dist/icons/tab-analyzing-dark-37.png +0 -0
  430. drowse/web/dist/icons/tab-analyzing-dark-38.png +0 -0
  431. drowse/web/dist/icons/tab-analyzing-dark-39.png +0 -0
  432. drowse/web/dist/icons/tab-analyzing-dark-4.png +0 -0
  433. drowse/web/dist/icons/tab-analyzing-dark-40.png +0 -0
  434. drowse/web/dist/icons/tab-analyzing-dark-41.png +0 -0
  435. drowse/web/dist/icons/tab-analyzing-dark-42.png +0 -0
  436. drowse/web/dist/icons/tab-analyzing-dark-43.png +0 -0
  437. drowse/web/dist/icons/tab-analyzing-dark-44.png +0 -0
  438. drowse/web/dist/icons/tab-analyzing-dark-45.png +0 -0
  439. drowse/web/dist/icons/tab-analyzing-dark-46.png +0 -0
  440. drowse/web/dist/icons/tab-analyzing-dark-47.png +0 -0
  441. drowse/web/dist/icons/tab-analyzing-dark-5.png +0 -0
  442. drowse/web/dist/icons/tab-analyzing-dark-6.png +0 -0
  443. drowse/web/dist/icons/tab-analyzing-dark-7.png +0 -0
  444. drowse/web/dist/icons/tab-analyzing-dark-8.png +0 -0
  445. drowse/web/dist/icons/tab-analyzing-dark-9.png +0 -0
  446. drowse/web/dist/icons/tab-analyzing-light-0.png +0 -0
  447. drowse/web/dist/icons/tab-analyzing-light-1.png +0 -0
  448. drowse/web/dist/icons/tab-analyzing-light-10.png +0 -0
  449. drowse/web/dist/icons/tab-analyzing-light-11.png +0 -0
  450. drowse/web/dist/icons/tab-analyzing-light-12.png +0 -0
  451. drowse/web/dist/icons/tab-analyzing-light-13.png +0 -0
  452. drowse/web/dist/icons/tab-analyzing-light-14.png +0 -0
  453. drowse/web/dist/icons/tab-analyzing-light-15.png +0 -0
  454. drowse/web/dist/icons/tab-analyzing-light-16.png +0 -0
  455. drowse/web/dist/icons/tab-analyzing-light-17.png +0 -0
  456. drowse/web/dist/icons/tab-analyzing-light-18.png +0 -0
  457. drowse/web/dist/icons/tab-analyzing-light-19.png +0 -0
  458. drowse/web/dist/icons/tab-analyzing-light-2.png +0 -0
  459. drowse/web/dist/icons/tab-analyzing-light-20.png +0 -0
  460. drowse/web/dist/icons/tab-analyzing-light-21.png +0 -0
  461. drowse/web/dist/icons/tab-analyzing-light-22.png +0 -0
  462. drowse/web/dist/icons/tab-analyzing-light-23.png +0 -0
  463. drowse/web/dist/icons/tab-analyzing-light-24.png +0 -0
  464. drowse/web/dist/icons/tab-analyzing-light-25.png +0 -0
  465. drowse/web/dist/icons/tab-analyzing-light-26.png +0 -0
  466. drowse/web/dist/icons/tab-analyzing-light-27.png +0 -0
  467. drowse/web/dist/icons/tab-analyzing-light-28.png +0 -0
  468. drowse/web/dist/icons/tab-analyzing-light-29.png +0 -0
  469. drowse/web/dist/icons/tab-analyzing-light-3.png +0 -0
  470. drowse/web/dist/icons/tab-analyzing-light-30.png +0 -0
  471. drowse/web/dist/icons/tab-analyzing-light-31.png +0 -0
  472. drowse/web/dist/icons/tab-analyzing-light-32.png +0 -0
  473. drowse/web/dist/icons/tab-analyzing-light-33.png +0 -0
  474. drowse/web/dist/icons/tab-analyzing-light-34.png +0 -0
  475. drowse/web/dist/icons/tab-analyzing-light-35.png +0 -0
  476. drowse/web/dist/icons/tab-analyzing-light-36.png +0 -0
  477. drowse/web/dist/icons/tab-analyzing-light-37.png +0 -0
  478. drowse/web/dist/icons/tab-analyzing-light-38.png +0 -0
  479. drowse/web/dist/icons/tab-analyzing-light-39.png +0 -0
  480. drowse/web/dist/icons/tab-analyzing-light-4.png +0 -0
  481. drowse/web/dist/icons/tab-analyzing-light-40.png +0 -0
  482. drowse/web/dist/icons/tab-analyzing-light-41.png +0 -0
  483. drowse/web/dist/icons/tab-analyzing-light-42.png +0 -0
  484. drowse/web/dist/icons/tab-analyzing-light-43.png +0 -0
  485. drowse/web/dist/icons/tab-analyzing-light-44.png +0 -0
  486. drowse/web/dist/icons/tab-analyzing-light-45.png +0 -0
  487. drowse/web/dist/icons/tab-analyzing-light-46.png +0 -0
  488. drowse/web/dist/icons/tab-analyzing-light-47.png +0 -0
  489. drowse/web/dist/icons/tab-analyzing-light-5.png +0 -0
  490. drowse/web/dist/icons/tab-analyzing-light-6.png +0 -0
  491. drowse/web/dist/icons/tab-analyzing-light-7.png +0 -0
  492. drowse/web/dist/icons/tab-analyzing-light-8.png +0 -0
  493. drowse/web/dist/icons/tab-analyzing-light-9.png +0 -0
  494. drowse/web/dist/icons/tab-chat-settings-dark.png +0 -0
  495. drowse/web/dist/icons/tab-chat-settings-light.png +0 -0
  496. drowse/web/dist/icons/tab-chat-settings.png +0 -0
  497. drowse/web/dist/icons/tab-chats-dark.png +0 -0
  498. drowse/web/dist/icons/tab-chats-light.png +0 -0
  499. drowse/web/dist/icons/tab-chats.png +0 -0
  500. drowse/web/dist/icons/tab-checking-0.png +0 -0
  501. drowse/web/dist/icons/tab-checking-1.png +0 -0
  502. drowse/web/dist/icons/tab-checking-2.png +0 -0
  503. drowse/web/dist/icons/tab-checking-dark-0.png +0 -0
  504. drowse/web/dist/icons/tab-checking-dark-1.png +0 -0
  505. drowse/web/dist/icons/tab-checking-dark-10.png +0 -0
  506. drowse/web/dist/icons/tab-checking-dark-11.png +0 -0
  507. drowse/web/dist/icons/tab-checking-dark-12.png +0 -0
  508. drowse/web/dist/icons/tab-checking-dark-13.png +0 -0
  509. drowse/web/dist/icons/tab-checking-dark-14.png +0 -0
  510. drowse/web/dist/icons/tab-checking-dark-15.png +0 -0
  511. drowse/web/dist/icons/tab-checking-dark-16.png +0 -0
  512. drowse/web/dist/icons/tab-checking-dark-17.png +0 -0
  513. drowse/web/dist/icons/tab-checking-dark-18.png +0 -0
  514. drowse/web/dist/icons/tab-checking-dark-19.png +0 -0
  515. drowse/web/dist/icons/tab-checking-dark-2.png +0 -0
  516. drowse/web/dist/icons/tab-checking-dark-20.png +0 -0
  517. drowse/web/dist/icons/tab-checking-dark-21.png +0 -0
  518. drowse/web/dist/icons/tab-checking-dark-22.png +0 -0
  519. drowse/web/dist/icons/tab-checking-dark-23.png +0 -0
  520. drowse/web/dist/icons/tab-checking-dark-24.png +0 -0
  521. drowse/web/dist/icons/tab-checking-dark-25.png +0 -0
  522. drowse/web/dist/icons/tab-checking-dark-26.png +0 -0
  523. drowse/web/dist/icons/tab-checking-dark-27.png +0 -0
  524. drowse/web/dist/icons/tab-checking-dark-28.png +0 -0
  525. drowse/web/dist/icons/tab-checking-dark-29.png +0 -0
  526. drowse/web/dist/icons/tab-checking-dark-3.png +0 -0
  527. drowse/web/dist/icons/tab-checking-dark-30.png +0 -0
  528. drowse/web/dist/icons/tab-checking-dark-31.png +0 -0
  529. drowse/web/dist/icons/tab-checking-dark-32.png +0 -0
  530. drowse/web/dist/icons/tab-checking-dark-33.png +0 -0
  531. drowse/web/dist/icons/tab-checking-dark-34.png +0 -0
  532. drowse/web/dist/icons/tab-checking-dark-35.png +0 -0
  533. drowse/web/dist/icons/tab-checking-dark-36.png +0 -0
  534. drowse/web/dist/icons/tab-checking-dark-37.png +0 -0
  535. drowse/web/dist/icons/tab-checking-dark-38.png +0 -0
  536. drowse/web/dist/icons/tab-checking-dark-39.png +0 -0
  537. drowse/web/dist/icons/tab-checking-dark-4.png +0 -0
  538. drowse/web/dist/icons/tab-checking-dark-40.png +0 -0
  539. drowse/web/dist/icons/tab-checking-dark-41.png +0 -0
  540. drowse/web/dist/icons/tab-checking-dark-42.png +0 -0
  541. drowse/web/dist/icons/tab-checking-dark-43.png +0 -0
  542. drowse/web/dist/icons/tab-checking-dark-44.png +0 -0
  543. drowse/web/dist/icons/tab-checking-dark-45.png +0 -0
  544. drowse/web/dist/icons/tab-checking-dark-46.png +0 -0
  545. drowse/web/dist/icons/tab-checking-dark-47.png +0 -0
  546. drowse/web/dist/icons/tab-checking-dark-5.png +0 -0
  547. drowse/web/dist/icons/tab-checking-dark-6.png +0 -0
  548. drowse/web/dist/icons/tab-checking-dark-7.png +0 -0
  549. drowse/web/dist/icons/tab-checking-dark-8.png +0 -0
  550. drowse/web/dist/icons/tab-checking-dark-9.png +0 -0
  551. drowse/web/dist/icons/tab-checking-light-0.png +0 -0
  552. drowse/web/dist/icons/tab-checking-light-1.png +0 -0
  553. drowse/web/dist/icons/tab-checking-light-10.png +0 -0
  554. drowse/web/dist/icons/tab-checking-light-11.png +0 -0
  555. drowse/web/dist/icons/tab-checking-light-12.png +0 -0
  556. drowse/web/dist/icons/tab-checking-light-13.png +0 -0
  557. drowse/web/dist/icons/tab-checking-light-14.png +0 -0
  558. drowse/web/dist/icons/tab-checking-light-15.png +0 -0
  559. drowse/web/dist/icons/tab-checking-light-16.png +0 -0
  560. drowse/web/dist/icons/tab-checking-light-17.png +0 -0
  561. drowse/web/dist/icons/tab-checking-light-18.png +0 -0
  562. drowse/web/dist/icons/tab-checking-light-19.png +0 -0
  563. drowse/web/dist/icons/tab-checking-light-2.png +0 -0
  564. drowse/web/dist/icons/tab-checking-light-20.png +0 -0
  565. drowse/web/dist/icons/tab-checking-light-21.png +0 -0
  566. drowse/web/dist/icons/tab-checking-light-22.png +0 -0
  567. drowse/web/dist/icons/tab-checking-light-23.png +0 -0
  568. drowse/web/dist/icons/tab-checking-light-24.png +0 -0
  569. drowse/web/dist/icons/tab-checking-light-25.png +0 -0
  570. drowse/web/dist/icons/tab-checking-light-26.png +0 -0
  571. drowse/web/dist/icons/tab-checking-light-27.png +0 -0
  572. drowse/web/dist/icons/tab-checking-light-28.png +0 -0
  573. drowse/web/dist/icons/tab-checking-light-29.png +0 -0
  574. drowse/web/dist/icons/tab-checking-light-3.png +0 -0
  575. drowse/web/dist/icons/tab-checking-light-30.png +0 -0
  576. drowse/web/dist/icons/tab-checking-light-31.png +0 -0
  577. drowse/web/dist/icons/tab-checking-light-32.png +0 -0
  578. drowse/web/dist/icons/tab-checking-light-33.png +0 -0
  579. drowse/web/dist/icons/tab-checking-light-34.png +0 -0
  580. drowse/web/dist/icons/tab-checking-light-35.png +0 -0
  581. drowse/web/dist/icons/tab-checking-light-36.png +0 -0
  582. drowse/web/dist/icons/tab-checking-light-37.png +0 -0
  583. drowse/web/dist/icons/tab-checking-light-38.png +0 -0
  584. drowse/web/dist/icons/tab-checking-light-39.png +0 -0
  585. drowse/web/dist/icons/tab-checking-light-4.png +0 -0
  586. drowse/web/dist/icons/tab-checking-light-40.png +0 -0
  587. drowse/web/dist/icons/tab-checking-light-41.png +0 -0
  588. drowse/web/dist/icons/tab-checking-light-42.png +0 -0
  589. drowse/web/dist/icons/tab-checking-light-43.png +0 -0
  590. drowse/web/dist/icons/tab-checking-light-44.png +0 -0
  591. drowse/web/dist/icons/tab-checking-light-45.png +0 -0
  592. drowse/web/dist/icons/tab-checking-light-46.png +0 -0
  593. drowse/web/dist/icons/tab-checking-light-47.png +0 -0
  594. drowse/web/dist/icons/tab-checking-light-5.png +0 -0
  595. drowse/web/dist/icons/tab-checking-light-6.png +0 -0
  596. drowse/web/dist/icons/tab-checking-light-7.png +0 -0
  597. drowse/web/dist/icons/tab-checking-light-8.png +0 -0
  598. drowse/web/dist/icons/tab-checking-light-9.png +0 -0
  599. drowse/web/dist/icons/tab-comparison-dark.png +0 -0
  600. drowse/web/dist/icons/tab-comparison-light.png +0 -0
  601. drowse/web/dist/icons/tab-comparison.png +0 -0
  602. drowse/web/dist/icons/tab-controls-dark.png +0 -0
  603. drowse/web/dist/icons/tab-controls-light.png +0 -0
  604. drowse/web/dist/icons/tab-controls.png +0 -0
  605. drowse/web/dist/icons/tab-conversation-dark.png +0 -0
  606. drowse/web/dist/icons/tab-conversation-light.png +0 -0
  607. drowse/web/dist/icons/tab-conversation.png +0 -0
  608. drowse/web/dist/icons/tab-credits-dark.png +0 -0
  609. drowse/web/dist/icons/tab-credits-light.png +0 -0
  610. drowse/web/dist/icons/tab-credits.png +0 -0
  611. drowse/web/dist/icons/tab-downloading-0.png +0 -0
  612. drowse/web/dist/icons/tab-downloading-1.png +0 -0
  613. drowse/web/dist/icons/tab-downloading-2.png +0 -0
  614. drowse/web/dist/icons/tab-downloading-dark-0.png +0 -0
  615. drowse/web/dist/icons/tab-downloading-dark-1.png +0 -0
  616. drowse/web/dist/icons/tab-downloading-dark-10.png +0 -0
  617. drowse/web/dist/icons/tab-downloading-dark-11.png +0 -0
  618. drowse/web/dist/icons/tab-downloading-dark-12.png +0 -0
  619. drowse/web/dist/icons/tab-downloading-dark-13.png +0 -0
  620. drowse/web/dist/icons/tab-downloading-dark-14.png +0 -0
  621. drowse/web/dist/icons/tab-downloading-dark-15.png +0 -0
  622. drowse/web/dist/icons/tab-downloading-dark-16.png +0 -0
  623. drowse/web/dist/icons/tab-downloading-dark-17.png +0 -0
  624. drowse/web/dist/icons/tab-downloading-dark-18.png +0 -0
  625. drowse/web/dist/icons/tab-downloading-dark-19.png +0 -0
  626. drowse/web/dist/icons/tab-downloading-dark-2.png +0 -0
  627. drowse/web/dist/icons/tab-downloading-dark-20.png +0 -0
  628. drowse/web/dist/icons/tab-downloading-dark-21.png +0 -0
  629. drowse/web/dist/icons/tab-downloading-dark-22.png +0 -0
  630. drowse/web/dist/icons/tab-downloading-dark-23.png +0 -0
  631. drowse/web/dist/icons/tab-downloading-dark-24.png +0 -0
  632. drowse/web/dist/icons/tab-downloading-dark-25.png +0 -0
  633. drowse/web/dist/icons/tab-downloading-dark-26.png +0 -0
  634. drowse/web/dist/icons/tab-downloading-dark-27.png +0 -0
  635. drowse/web/dist/icons/tab-downloading-dark-28.png +0 -0
  636. drowse/web/dist/icons/tab-downloading-dark-29.png +0 -0
  637. drowse/web/dist/icons/tab-downloading-dark-3.png +0 -0
  638. drowse/web/dist/icons/tab-downloading-dark-30.png +0 -0
  639. drowse/web/dist/icons/tab-downloading-dark-31.png +0 -0
  640. drowse/web/dist/icons/tab-downloading-dark-32.png +0 -0
  641. drowse/web/dist/icons/tab-downloading-dark-33.png +0 -0
  642. drowse/web/dist/icons/tab-downloading-dark-34.png +0 -0
  643. drowse/web/dist/icons/tab-downloading-dark-35.png +0 -0
  644. drowse/web/dist/icons/tab-downloading-dark-36.png +0 -0
  645. drowse/web/dist/icons/tab-downloading-dark-37.png +0 -0
  646. drowse/web/dist/icons/tab-downloading-dark-38.png +0 -0
  647. drowse/web/dist/icons/tab-downloading-dark-39.png +0 -0
  648. drowse/web/dist/icons/tab-downloading-dark-4.png +0 -0
  649. drowse/web/dist/icons/tab-downloading-dark-40.png +0 -0
  650. drowse/web/dist/icons/tab-downloading-dark-41.png +0 -0
  651. drowse/web/dist/icons/tab-downloading-dark-42.png +0 -0
  652. drowse/web/dist/icons/tab-downloading-dark-43.png +0 -0
  653. drowse/web/dist/icons/tab-downloading-dark-44.png +0 -0
  654. drowse/web/dist/icons/tab-downloading-dark-45.png +0 -0
  655. drowse/web/dist/icons/tab-downloading-dark-46.png +0 -0
  656. drowse/web/dist/icons/tab-downloading-dark-47.png +0 -0
  657. drowse/web/dist/icons/tab-downloading-dark-5.png +0 -0
  658. drowse/web/dist/icons/tab-downloading-dark-6.png +0 -0
  659. drowse/web/dist/icons/tab-downloading-dark-7.png +0 -0
  660. drowse/web/dist/icons/tab-downloading-dark-8.png +0 -0
  661. drowse/web/dist/icons/tab-downloading-dark-9.png +0 -0
  662. drowse/web/dist/icons/tab-downloading-light-0.png +0 -0
  663. drowse/web/dist/icons/tab-downloading-light-1.png +0 -0
  664. drowse/web/dist/icons/tab-downloading-light-10.png +0 -0
  665. drowse/web/dist/icons/tab-downloading-light-11.png +0 -0
  666. drowse/web/dist/icons/tab-downloading-light-12.png +0 -0
  667. drowse/web/dist/icons/tab-downloading-light-13.png +0 -0
  668. drowse/web/dist/icons/tab-downloading-light-14.png +0 -0
  669. drowse/web/dist/icons/tab-downloading-light-15.png +0 -0
  670. drowse/web/dist/icons/tab-downloading-light-16.png +0 -0
  671. drowse/web/dist/icons/tab-downloading-light-17.png +0 -0
  672. drowse/web/dist/icons/tab-downloading-light-18.png +0 -0
  673. drowse/web/dist/icons/tab-downloading-light-19.png +0 -0
  674. drowse/web/dist/icons/tab-downloading-light-2.png +0 -0
  675. drowse/web/dist/icons/tab-downloading-light-20.png +0 -0
  676. drowse/web/dist/icons/tab-downloading-light-21.png +0 -0
  677. drowse/web/dist/icons/tab-downloading-light-22.png +0 -0
  678. drowse/web/dist/icons/tab-downloading-light-23.png +0 -0
  679. drowse/web/dist/icons/tab-downloading-light-24.png +0 -0
  680. drowse/web/dist/icons/tab-downloading-light-25.png +0 -0
  681. drowse/web/dist/icons/tab-downloading-light-26.png +0 -0
  682. drowse/web/dist/icons/tab-downloading-light-27.png +0 -0
  683. drowse/web/dist/icons/tab-downloading-light-28.png +0 -0
  684. drowse/web/dist/icons/tab-downloading-light-29.png +0 -0
  685. drowse/web/dist/icons/tab-downloading-light-3.png +0 -0
  686. drowse/web/dist/icons/tab-downloading-light-30.png +0 -0
  687. drowse/web/dist/icons/tab-downloading-light-31.png +0 -0
  688. drowse/web/dist/icons/tab-downloading-light-32.png +0 -0
  689. drowse/web/dist/icons/tab-downloading-light-33.png +0 -0
  690. drowse/web/dist/icons/tab-downloading-light-34.png +0 -0
  691. drowse/web/dist/icons/tab-downloading-light-35.png +0 -0
  692. drowse/web/dist/icons/tab-downloading-light-36.png +0 -0
  693. drowse/web/dist/icons/tab-downloading-light-37.png +0 -0
  694. drowse/web/dist/icons/tab-downloading-light-38.png +0 -0
  695. drowse/web/dist/icons/tab-downloading-light-39.png +0 -0
  696. drowse/web/dist/icons/tab-downloading-light-4.png +0 -0
  697. drowse/web/dist/icons/tab-downloading-light-40.png +0 -0
  698. drowse/web/dist/icons/tab-downloading-light-41.png +0 -0
  699. drowse/web/dist/icons/tab-downloading-light-42.png +0 -0
  700. drowse/web/dist/icons/tab-downloading-light-43.png +0 -0
  701. drowse/web/dist/icons/tab-downloading-light-44.png +0 -0
  702. drowse/web/dist/icons/tab-downloading-light-45.png +0 -0
  703. drowse/web/dist/icons/tab-downloading-light-46.png +0 -0
  704. drowse/web/dist/icons/tab-downloading-light-47.png +0 -0
  705. drowse/web/dist/icons/tab-downloading-light-5.png +0 -0
  706. drowse/web/dist/icons/tab-downloading-light-6.png +0 -0
  707. drowse/web/dist/icons/tab-downloading-light-7.png +0 -0
  708. drowse/web/dist/icons/tab-downloading-light-8.png +0 -0
  709. drowse/web/dist/icons/tab-downloading-light-9.png +0 -0
  710. drowse/web/dist/icons/tab-error-dark.png +0 -0
  711. drowse/web/dist/icons/tab-error-light.png +0 -0
  712. drowse/web/dist/icons/tab-error.png +0 -0
  713. drowse/web/dist/icons/tab-home-dark.png +0 -0
  714. drowse/web/dist/icons/tab-home-light.png +0 -0
  715. drowse/web/dist/icons/tab-home.png +0 -0
  716. drowse/web/dist/icons/tab-loading-0.png +0 -0
  717. drowse/web/dist/icons/tab-loading-1.png +0 -0
  718. drowse/web/dist/icons/tab-loading-2.png +0 -0
  719. drowse/web/dist/icons/tab-loading-dark-0.png +0 -0
  720. drowse/web/dist/icons/tab-loading-dark-1.png +0 -0
  721. drowse/web/dist/icons/tab-loading-dark-10.png +0 -0
  722. drowse/web/dist/icons/tab-loading-dark-11.png +0 -0
  723. drowse/web/dist/icons/tab-loading-dark-12.png +0 -0
  724. drowse/web/dist/icons/tab-loading-dark-13.png +0 -0
  725. drowse/web/dist/icons/tab-loading-dark-14.png +0 -0
  726. drowse/web/dist/icons/tab-loading-dark-15.png +0 -0
  727. drowse/web/dist/icons/tab-loading-dark-16.png +0 -0
  728. drowse/web/dist/icons/tab-loading-dark-17.png +0 -0
  729. drowse/web/dist/icons/tab-loading-dark-18.png +0 -0
  730. drowse/web/dist/icons/tab-loading-dark-19.png +0 -0
  731. drowse/web/dist/icons/tab-loading-dark-2.png +0 -0
  732. drowse/web/dist/icons/tab-loading-dark-20.png +0 -0
  733. drowse/web/dist/icons/tab-loading-dark-21.png +0 -0
  734. drowse/web/dist/icons/tab-loading-dark-22.png +0 -0
  735. drowse/web/dist/icons/tab-loading-dark-23.png +0 -0
  736. drowse/web/dist/icons/tab-loading-dark-24.png +0 -0
  737. drowse/web/dist/icons/tab-loading-dark-25.png +0 -0
  738. drowse/web/dist/icons/tab-loading-dark-26.png +0 -0
  739. drowse/web/dist/icons/tab-loading-dark-27.png +0 -0
  740. drowse/web/dist/icons/tab-loading-dark-28.png +0 -0
  741. drowse/web/dist/icons/tab-loading-dark-29.png +0 -0
  742. drowse/web/dist/icons/tab-loading-dark-3.png +0 -0
  743. drowse/web/dist/icons/tab-loading-dark-30.png +0 -0
  744. drowse/web/dist/icons/tab-loading-dark-31.png +0 -0
  745. drowse/web/dist/icons/tab-loading-dark-32.png +0 -0
  746. drowse/web/dist/icons/tab-loading-dark-33.png +0 -0
  747. drowse/web/dist/icons/tab-loading-dark-34.png +0 -0
  748. drowse/web/dist/icons/tab-loading-dark-35.png +0 -0
  749. drowse/web/dist/icons/tab-loading-dark-36.png +0 -0
  750. drowse/web/dist/icons/tab-loading-dark-37.png +0 -0
  751. drowse/web/dist/icons/tab-loading-dark-38.png +0 -0
  752. drowse/web/dist/icons/tab-loading-dark-39.png +0 -0
  753. drowse/web/dist/icons/tab-loading-dark-4.png +0 -0
  754. drowse/web/dist/icons/tab-loading-dark-40.png +0 -0
  755. drowse/web/dist/icons/tab-loading-dark-41.png +0 -0
  756. drowse/web/dist/icons/tab-loading-dark-42.png +0 -0
  757. drowse/web/dist/icons/tab-loading-dark-43.png +0 -0
  758. drowse/web/dist/icons/tab-loading-dark-44.png +0 -0
  759. drowse/web/dist/icons/tab-loading-dark-45.png +0 -0
  760. drowse/web/dist/icons/tab-loading-dark-46.png +0 -0
  761. drowse/web/dist/icons/tab-loading-dark-47.png +0 -0
  762. drowse/web/dist/icons/tab-loading-dark-5.png +0 -0
  763. drowse/web/dist/icons/tab-loading-dark-6.png +0 -0
  764. drowse/web/dist/icons/tab-loading-dark-7.png +0 -0
  765. drowse/web/dist/icons/tab-loading-dark-8.png +0 -0
  766. drowse/web/dist/icons/tab-loading-dark-9.png +0 -0
  767. drowse/web/dist/icons/tab-loading-light-0.png +0 -0
  768. drowse/web/dist/icons/tab-loading-light-1.png +0 -0
  769. drowse/web/dist/icons/tab-loading-light-10.png +0 -0
  770. drowse/web/dist/icons/tab-loading-light-11.png +0 -0
  771. drowse/web/dist/icons/tab-loading-light-12.png +0 -0
  772. drowse/web/dist/icons/tab-loading-light-13.png +0 -0
  773. drowse/web/dist/icons/tab-loading-light-14.png +0 -0
  774. drowse/web/dist/icons/tab-loading-light-15.png +0 -0
  775. drowse/web/dist/icons/tab-loading-light-16.png +0 -0
  776. drowse/web/dist/icons/tab-loading-light-17.png +0 -0
  777. drowse/web/dist/icons/tab-loading-light-18.png +0 -0
  778. drowse/web/dist/icons/tab-loading-light-19.png +0 -0
  779. drowse/web/dist/icons/tab-loading-light-2.png +0 -0
  780. drowse/web/dist/icons/tab-loading-light-20.png +0 -0
  781. drowse/web/dist/icons/tab-loading-light-21.png +0 -0
  782. drowse/web/dist/icons/tab-loading-light-22.png +0 -0
  783. drowse/web/dist/icons/tab-loading-light-23.png +0 -0
  784. drowse/web/dist/icons/tab-loading-light-24.png +0 -0
  785. drowse/web/dist/icons/tab-loading-light-25.png +0 -0
  786. drowse/web/dist/icons/tab-loading-light-26.png +0 -0
  787. drowse/web/dist/icons/tab-loading-light-27.png +0 -0
  788. drowse/web/dist/icons/tab-loading-light-28.png +0 -0
  789. drowse/web/dist/icons/tab-loading-light-29.png +0 -0
  790. drowse/web/dist/icons/tab-loading-light-3.png +0 -0
  791. drowse/web/dist/icons/tab-loading-light-30.png +0 -0
  792. drowse/web/dist/icons/tab-loading-light-31.png +0 -0
  793. drowse/web/dist/icons/tab-loading-light-32.png +0 -0
  794. drowse/web/dist/icons/tab-loading-light-33.png +0 -0
  795. drowse/web/dist/icons/tab-loading-light-34.png +0 -0
  796. drowse/web/dist/icons/tab-loading-light-35.png +0 -0
  797. drowse/web/dist/icons/tab-loading-light-36.png +0 -0
  798. drowse/web/dist/icons/tab-loading-light-37.png +0 -0
  799. drowse/web/dist/icons/tab-loading-light-38.png +0 -0
  800. drowse/web/dist/icons/tab-loading-light-39.png +0 -0
  801. drowse/web/dist/icons/tab-loading-light-4.png +0 -0
  802. drowse/web/dist/icons/tab-loading-light-40.png +0 -0
  803. drowse/web/dist/icons/tab-loading-light-41.png +0 -0
  804. drowse/web/dist/icons/tab-loading-light-42.png +0 -0
  805. drowse/web/dist/icons/tab-loading-light-43.png +0 -0
  806. drowse/web/dist/icons/tab-loading-light-44.png +0 -0
  807. drowse/web/dist/icons/tab-loading-light-45.png +0 -0
  808. drowse/web/dist/icons/tab-loading-light-46.png +0 -0
  809. drowse/web/dist/icons/tab-loading-light-47.png +0 -0
  810. drowse/web/dist/icons/tab-loading-light-5.png +0 -0
  811. drowse/web/dist/icons/tab-loading-light-6.png +0 -0
  812. drowse/web/dist/icons/tab-loading-light-7.png +0 -0
  813. drowse/web/dist/icons/tab-loading-light-8.png +0 -0
  814. drowse/web/dist/icons/tab-loading-light-9.png +0 -0
  815. drowse/web/dist/icons/tab-loom-dark.png +0 -0
  816. drowse/web/dist/icons/tab-loom-light.png +0 -0
  817. drowse/web/dist/icons/tab-loom-working-0.png +0 -0
  818. drowse/web/dist/icons/tab-loom-working-1.png +0 -0
  819. drowse/web/dist/icons/tab-loom-working-2.png +0 -0
  820. drowse/web/dist/icons/tab-loom-working-dark-0.png +0 -0
  821. drowse/web/dist/icons/tab-loom-working-dark-1.png +0 -0
  822. drowse/web/dist/icons/tab-loom-working-dark-10.png +0 -0
  823. drowse/web/dist/icons/tab-loom-working-dark-11.png +0 -0
  824. drowse/web/dist/icons/tab-loom-working-dark-12.png +0 -0
  825. drowse/web/dist/icons/tab-loom-working-dark-13.png +0 -0
  826. drowse/web/dist/icons/tab-loom-working-dark-14.png +0 -0
  827. drowse/web/dist/icons/tab-loom-working-dark-15.png +0 -0
  828. drowse/web/dist/icons/tab-loom-working-dark-16.png +0 -0
  829. drowse/web/dist/icons/tab-loom-working-dark-17.png +0 -0
  830. drowse/web/dist/icons/tab-loom-working-dark-18.png +0 -0
  831. drowse/web/dist/icons/tab-loom-working-dark-19.png +0 -0
  832. drowse/web/dist/icons/tab-loom-working-dark-2.png +0 -0
  833. drowse/web/dist/icons/tab-loom-working-dark-20.png +0 -0
  834. drowse/web/dist/icons/tab-loom-working-dark-21.png +0 -0
  835. drowse/web/dist/icons/tab-loom-working-dark-22.png +0 -0
  836. drowse/web/dist/icons/tab-loom-working-dark-23.png +0 -0
  837. drowse/web/dist/icons/tab-loom-working-dark-24.png +0 -0
  838. drowse/web/dist/icons/tab-loom-working-dark-25.png +0 -0
  839. drowse/web/dist/icons/tab-loom-working-dark-26.png +0 -0
  840. drowse/web/dist/icons/tab-loom-working-dark-27.png +0 -0
  841. drowse/web/dist/icons/tab-loom-working-dark-28.png +0 -0
  842. drowse/web/dist/icons/tab-loom-working-dark-29.png +0 -0
  843. drowse/web/dist/icons/tab-loom-working-dark-3.png +0 -0
  844. drowse/web/dist/icons/tab-loom-working-dark-30.png +0 -0
  845. drowse/web/dist/icons/tab-loom-working-dark-31.png +0 -0
  846. drowse/web/dist/icons/tab-loom-working-dark-32.png +0 -0
  847. drowse/web/dist/icons/tab-loom-working-dark-33.png +0 -0
  848. drowse/web/dist/icons/tab-loom-working-dark-34.png +0 -0
  849. drowse/web/dist/icons/tab-loom-working-dark-35.png +0 -0
  850. drowse/web/dist/icons/tab-loom-working-dark-36.png +0 -0
  851. drowse/web/dist/icons/tab-loom-working-dark-37.png +0 -0
  852. drowse/web/dist/icons/tab-loom-working-dark-38.png +0 -0
  853. drowse/web/dist/icons/tab-loom-working-dark-39.png +0 -0
  854. drowse/web/dist/icons/tab-loom-working-dark-4.png +0 -0
  855. drowse/web/dist/icons/tab-loom-working-dark-40.png +0 -0
  856. drowse/web/dist/icons/tab-loom-working-dark-41.png +0 -0
  857. drowse/web/dist/icons/tab-loom-working-dark-42.png +0 -0
  858. drowse/web/dist/icons/tab-loom-working-dark-43.png +0 -0
  859. drowse/web/dist/icons/tab-loom-working-dark-44.png +0 -0
  860. drowse/web/dist/icons/tab-loom-working-dark-45.png +0 -0
  861. drowse/web/dist/icons/tab-loom-working-dark-46.png +0 -0
  862. drowse/web/dist/icons/tab-loom-working-dark-47.png +0 -0
  863. drowse/web/dist/icons/tab-loom-working-dark-5.png +0 -0
  864. drowse/web/dist/icons/tab-loom-working-dark-6.png +0 -0
  865. drowse/web/dist/icons/tab-loom-working-dark-7.png +0 -0
  866. drowse/web/dist/icons/tab-loom-working-dark-8.png +0 -0
  867. drowse/web/dist/icons/tab-loom-working-dark-9.png +0 -0
  868. drowse/web/dist/icons/tab-loom-working-light-0.png +0 -0
  869. drowse/web/dist/icons/tab-loom-working-light-1.png +0 -0
  870. drowse/web/dist/icons/tab-loom-working-light-10.png +0 -0
  871. drowse/web/dist/icons/tab-loom-working-light-11.png +0 -0
  872. drowse/web/dist/icons/tab-loom-working-light-12.png +0 -0
  873. drowse/web/dist/icons/tab-loom-working-light-13.png +0 -0
  874. drowse/web/dist/icons/tab-loom-working-light-14.png +0 -0
  875. drowse/web/dist/icons/tab-loom-working-light-15.png +0 -0
  876. drowse/web/dist/icons/tab-loom-working-light-16.png +0 -0
  877. drowse/web/dist/icons/tab-loom-working-light-17.png +0 -0
  878. drowse/web/dist/icons/tab-loom-working-light-18.png +0 -0
  879. drowse/web/dist/icons/tab-loom-working-light-19.png +0 -0
  880. drowse/web/dist/icons/tab-loom-working-light-2.png +0 -0
  881. drowse/web/dist/icons/tab-loom-working-light-20.png +0 -0
  882. drowse/web/dist/icons/tab-loom-working-light-21.png +0 -0
  883. drowse/web/dist/icons/tab-loom-working-light-22.png +0 -0
  884. drowse/web/dist/icons/tab-loom-working-light-23.png +0 -0
  885. drowse/web/dist/icons/tab-loom-working-light-24.png +0 -0
  886. drowse/web/dist/icons/tab-loom-working-light-25.png +0 -0
  887. drowse/web/dist/icons/tab-loom-working-light-26.png +0 -0
  888. drowse/web/dist/icons/tab-loom-working-light-27.png +0 -0
  889. drowse/web/dist/icons/tab-loom-working-light-28.png +0 -0
  890. drowse/web/dist/icons/tab-loom-working-light-29.png +0 -0
  891. drowse/web/dist/icons/tab-loom-working-light-3.png +0 -0
  892. drowse/web/dist/icons/tab-loom-working-light-30.png +0 -0
  893. drowse/web/dist/icons/tab-loom-working-light-31.png +0 -0
  894. drowse/web/dist/icons/tab-loom-working-light-32.png +0 -0
  895. drowse/web/dist/icons/tab-loom-working-light-33.png +0 -0
  896. drowse/web/dist/icons/tab-loom-working-light-34.png +0 -0
  897. drowse/web/dist/icons/tab-loom-working-light-35.png +0 -0
  898. drowse/web/dist/icons/tab-loom-working-light-36.png +0 -0
  899. drowse/web/dist/icons/tab-loom-working-light-37.png +0 -0
  900. drowse/web/dist/icons/tab-loom-working-light-38.png +0 -0
  901. drowse/web/dist/icons/tab-loom-working-light-39.png +0 -0
  902. drowse/web/dist/icons/tab-loom-working-light-4.png +0 -0
  903. drowse/web/dist/icons/tab-loom-working-light-40.png +0 -0
  904. drowse/web/dist/icons/tab-loom-working-light-41.png +0 -0
  905. drowse/web/dist/icons/tab-loom-working-light-42.png +0 -0
  906. drowse/web/dist/icons/tab-loom-working-light-43.png +0 -0
  907. drowse/web/dist/icons/tab-loom-working-light-44.png +0 -0
  908. drowse/web/dist/icons/tab-loom-working-light-45.png +0 -0
  909. drowse/web/dist/icons/tab-loom-working-light-46.png +0 -0
  910. drowse/web/dist/icons/tab-loom-working-light-47.png +0 -0
  911. drowse/web/dist/icons/tab-loom-working-light-5.png +0 -0
  912. drowse/web/dist/icons/tab-loom-working-light-6.png +0 -0
  913. drowse/web/dist/icons/tab-loom-working-light-7.png +0 -0
  914. drowse/web/dist/icons/tab-loom-working-light-8.png +0 -0
  915. drowse/web/dist/icons/tab-loom-working-light-9.png +0 -0
  916. drowse/web/dist/icons/tab-loom.png +0 -0
  917. drowse/web/dist/icons/tab-models-dark.png +0 -0
  918. drowse/web/dist/icons/tab-models-light.png +0 -0
  919. drowse/web/dist/icons/tab-models.png +0 -0
  920. drowse/web/dist/icons/tab-offline-dark.png +0 -0
  921. drowse/web/dist/icons/tab-offline-light.png +0 -0
  922. drowse/web/dist/icons/tab-offline.png +0 -0
  923. drowse/web/dist/icons/tab-paused-dark.png +0 -0
  924. drowse/web/dist/icons/tab-paused-light.png +0 -0
  925. drowse/web/dist/icons/tab-paused.png +0 -0
  926. drowse/web/dist/icons/tab-ready-dark.png +0 -0
  927. drowse/web/dist/icons/tab-ready-light.png +0 -0
  928. drowse/web/dist/icons/tab-ready.png +0 -0
  929. drowse/web/dist/icons/tab-saving-0.png +0 -0
  930. drowse/web/dist/icons/tab-saving-1.png +0 -0
  931. drowse/web/dist/icons/tab-saving-2.png +0 -0
  932. drowse/web/dist/icons/tab-saving-dark-0.png +0 -0
  933. drowse/web/dist/icons/tab-saving-dark-1.png +0 -0
  934. drowse/web/dist/icons/tab-saving-dark-10.png +0 -0
  935. drowse/web/dist/icons/tab-saving-dark-11.png +0 -0
  936. drowse/web/dist/icons/tab-saving-dark-12.png +0 -0
  937. drowse/web/dist/icons/tab-saving-dark-13.png +0 -0
  938. drowse/web/dist/icons/tab-saving-dark-14.png +0 -0
  939. drowse/web/dist/icons/tab-saving-dark-15.png +0 -0
  940. drowse/web/dist/icons/tab-saving-dark-16.png +0 -0
  941. drowse/web/dist/icons/tab-saving-dark-17.png +0 -0
  942. drowse/web/dist/icons/tab-saving-dark-18.png +0 -0
  943. drowse/web/dist/icons/tab-saving-dark-19.png +0 -0
  944. drowse/web/dist/icons/tab-saving-dark-2.png +0 -0
  945. drowse/web/dist/icons/tab-saving-dark-20.png +0 -0
  946. drowse/web/dist/icons/tab-saving-dark-21.png +0 -0
  947. drowse/web/dist/icons/tab-saving-dark-22.png +0 -0
  948. drowse/web/dist/icons/tab-saving-dark-23.png +0 -0
  949. drowse/web/dist/icons/tab-saving-dark-24.png +0 -0
  950. drowse/web/dist/icons/tab-saving-dark-25.png +0 -0
  951. drowse/web/dist/icons/tab-saving-dark-26.png +0 -0
  952. drowse/web/dist/icons/tab-saving-dark-27.png +0 -0
  953. drowse/web/dist/icons/tab-saving-dark-28.png +0 -0
  954. drowse/web/dist/icons/tab-saving-dark-29.png +0 -0
  955. drowse/web/dist/icons/tab-saving-dark-3.png +0 -0
  956. drowse/web/dist/icons/tab-saving-dark-30.png +0 -0
  957. drowse/web/dist/icons/tab-saving-dark-31.png +0 -0
  958. drowse/web/dist/icons/tab-saving-dark-32.png +0 -0
  959. drowse/web/dist/icons/tab-saving-dark-33.png +0 -0
  960. drowse/web/dist/icons/tab-saving-dark-34.png +0 -0
  961. drowse/web/dist/icons/tab-saving-dark-35.png +0 -0
  962. drowse/web/dist/icons/tab-saving-dark-36.png +0 -0
  963. drowse/web/dist/icons/tab-saving-dark-37.png +0 -0
  964. drowse/web/dist/icons/tab-saving-dark-38.png +0 -0
  965. drowse/web/dist/icons/tab-saving-dark-39.png +0 -0
  966. drowse/web/dist/icons/tab-saving-dark-4.png +0 -0
  967. drowse/web/dist/icons/tab-saving-dark-40.png +0 -0
  968. drowse/web/dist/icons/tab-saving-dark-41.png +0 -0
  969. drowse/web/dist/icons/tab-saving-dark-42.png +0 -0
  970. drowse/web/dist/icons/tab-saving-dark-43.png +0 -0
  971. drowse/web/dist/icons/tab-saving-dark-44.png +0 -0
  972. drowse/web/dist/icons/tab-saving-dark-45.png +0 -0
  973. drowse/web/dist/icons/tab-saving-dark-46.png +0 -0
  974. drowse/web/dist/icons/tab-saving-dark-47.png +0 -0
  975. drowse/web/dist/icons/tab-saving-dark-5.png +0 -0
  976. drowse/web/dist/icons/tab-saving-dark-6.png +0 -0
  977. drowse/web/dist/icons/tab-saving-dark-7.png +0 -0
  978. drowse/web/dist/icons/tab-saving-dark-8.png +0 -0
  979. drowse/web/dist/icons/tab-saving-dark-9.png +0 -0
  980. drowse/web/dist/icons/tab-saving-light-0.png +0 -0
  981. drowse/web/dist/icons/tab-saving-light-1.png +0 -0
  982. drowse/web/dist/icons/tab-saving-light-10.png +0 -0
  983. drowse/web/dist/icons/tab-saving-light-11.png +0 -0
  984. drowse/web/dist/icons/tab-saving-light-12.png +0 -0
  985. drowse/web/dist/icons/tab-saving-light-13.png +0 -0
  986. drowse/web/dist/icons/tab-saving-light-14.png +0 -0
  987. drowse/web/dist/icons/tab-saving-light-15.png +0 -0
  988. drowse/web/dist/icons/tab-saving-light-16.png +0 -0
  989. drowse/web/dist/icons/tab-saving-light-17.png +0 -0
  990. drowse/web/dist/icons/tab-saving-light-18.png +0 -0
  991. drowse/web/dist/icons/tab-saving-light-19.png +0 -0
  992. drowse/web/dist/icons/tab-saving-light-2.png +0 -0
  993. drowse/web/dist/icons/tab-saving-light-20.png +0 -0
  994. drowse/web/dist/icons/tab-saving-light-21.png +0 -0
  995. drowse/web/dist/icons/tab-saving-light-22.png +0 -0
  996. drowse/web/dist/icons/tab-saving-light-23.png +0 -0
  997. drowse/web/dist/icons/tab-saving-light-24.png +0 -0
  998. drowse/web/dist/icons/tab-saving-light-25.png +0 -0
  999. drowse/web/dist/icons/tab-saving-light-26.png +0 -0
  1000. drowse/web/dist/icons/tab-saving-light-27.png +0 -0
  1001. drowse/web/dist/icons/tab-saving-light-28.png +0 -0
  1002. drowse/web/dist/icons/tab-saving-light-29.png +0 -0
  1003. drowse/web/dist/icons/tab-saving-light-3.png +0 -0
  1004. drowse/web/dist/icons/tab-saving-light-30.png +0 -0
  1005. drowse/web/dist/icons/tab-saving-light-31.png +0 -0
  1006. drowse/web/dist/icons/tab-saving-light-32.png +0 -0
  1007. drowse/web/dist/icons/tab-saving-light-33.png +0 -0
  1008. drowse/web/dist/icons/tab-saving-light-34.png +0 -0
  1009. drowse/web/dist/icons/tab-saving-light-35.png +0 -0
  1010. drowse/web/dist/icons/tab-saving-light-36.png +0 -0
  1011. drowse/web/dist/icons/tab-saving-light-37.png +0 -0
  1012. drowse/web/dist/icons/tab-saving-light-38.png +0 -0
  1013. drowse/web/dist/icons/tab-saving-light-39.png +0 -0
  1014. drowse/web/dist/icons/tab-saving-light-4.png +0 -0
  1015. drowse/web/dist/icons/tab-saving-light-40.png +0 -0
  1016. drowse/web/dist/icons/tab-saving-light-41.png +0 -0
  1017. drowse/web/dist/icons/tab-saving-light-42.png +0 -0
  1018. drowse/web/dist/icons/tab-saving-light-43.png +0 -0
  1019. drowse/web/dist/icons/tab-saving-light-44.png +0 -0
  1020. drowse/web/dist/icons/tab-saving-light-45.png +0 -0
  1021. drowse/web/dist/icons/tab-saving-light-46.png +0 -0
  1022. drowse/web/dist/icons/tab-saving-light-47.png +0 -0
  1023. drowse/web/dist/icons/tab-saving-light-5.png +0 -0
  1024. drowse/web/dist/icons/tab-saving-light-6.png +0 -0
  1025. drowse/web/dist/icons/tab-saving-light-7.png +0 -0
  1026. drowse/web/dist/icons/tab-saving-light-8.png +0 -0
  1027. drowse/web/dist/icons/tab-saving-light-9.png +0 -0
  1028. drowse/web/dist/icons/tab-thinking-0.png +0 -0
  1029. drowse/web/dist/icons/tab-thinking-1.png +0 -0
  1030. drowse/web/dist/icons/tab-thinking-2.png +0 -0
  1031. drowse/web/dist/icons/tab-thinking-dark-0.png +0 -0
  1032. drowse/web/dist/icons/tab-thinking-dark-1.png +0 -0
  1033. drowse/web/dist/icons/tab-thinking-dark-10.png +0 -0
  1034. drowse/web/dist/icons/tab-thinking-dark-11.png +0 -0
  1035. drowse/web/dist/icons/tab-thinking-dark-12.png +0 -0
  1036. drowse/web/dist/icons/tab-thinking-dark-13.png +0 -0
  1037. drowse/web/dist/icons/tab-thinking-dark-14.png +0 -0
  1038. drowse/web/dist/icons/tab-thinking-dark-15.png +0 -0
  1039. drowse/web/dist/icons/tab-thinking-dark-16.png +0 -0
  1040. drowse/web/dist/icons/tab-thinking-dark-17.png +0 -0
  1041. drowse/web/dist/icons/tab-thinking-dark-18.png +0 -0
  1042. drowse/web/dist/icons/tab-thinking-dark-19.png +0 -0
  1043. drowse/web/dist/icons/tab-thinking-dark-2.png +0 -0
  1044. drowse/web/dist/icons/tab-thinking-dark-20.png +0 -0
  1045. drowse/web/dist/icons/tab-thinking-dark-21.png +0 -0
  1046. drowse/web/dist/icons/tab-thinking-dark-22.png +0 -0
  1047. drowse/web/dist/icons/tab-thinking-dark-23.png +0 -0
  1048. drowse/web/dist/icons/tab-thinking-dark-24.png +0 -0
  1049. drowse/web/dist/icons/tab-thinking-dark-25.png +0 -0
  1050. drowse/web/dist/icons/tab-thinking-dark-26.png +0 -0
  1051. drowse/web/dist/icons/tab-thinking-dark-27.png +0 -0
  1052. drowse/web/dist/icons/tab-thinking-dark-28.png +0 -0
  1053. drowse/web/dist/icons/tab-thinking-dark-29.png +0 -0
  1054. drowse/web/dist/icons/tab-thinking-dark-3.png +0 -0
  1055. drowse/web/dist/icons/tab-thinking-dark-30.png +0 -0
  1056. drowse/web/dist/icons/tab-thinking-dark-31.png +0 -0
  1057. drowse/web/dist/icons/tab-thinking-dark-32.png +0 -0
  1058. drowse/web/dist/icons/tab-thinking-dark-33.png +0 -0
  1059. drowse/web/dist/icons/tab-thinking-dark-34.png +0 -0
  1060. drowse/web/dist/icons/tab-thinking-dark-35.png +0 -0
  1061. drowse/web/dist/icons/tab-thinking-dark-36.png +0 -0
  1062. drowse/web/dist/icons/tab-thinking-dark-37.png +0 -0
  1063. drowse/web/dist/icons/tab-thinking-dark-38.png +0 -0
  1064. drowse/web/dist/icons/tab-thinking-dark-39.png +0 -0
  1065. drowse/web/dist/icons/tab-thinking-dark-4.png +0 -0
  1066. drowse/web/dist/icons/tab-thinking-dark-40.png +0 -0
  1067. drowse/web/dist/icons/tab-thinking-dark-41.png +0 -0
  1068. drowse/web/dist/icons/tab-thinking-dark-42.png +0 -0
  1069. drowse/web/dist/icons/tab-thinking-dark-43.png +0 -0
  1070. drowse/web/dist/icons/tab-thinking-dark-44.png +0 -0
  1071. drowse/web/dist/icons/tab-thinking-dark-45.png +0 -0
  1072. drowse/web/dist/icons/tab-thinking-dark-46.png +0 -0
  1073. drowse/web/dist/icons/tab-thinking-dark-47.png +0 -0
  1074. drowse/web/dist/icons/tab-thinking-dark-5.png +0 -0
  1075. drowse/web/dist/icons/tab-thinking-dark-6.png +0 -0
  1076. drowse/web/dist/icons/tab-thinking-dark-7.png +0 -0
  1077. drowse/web/dist/icons/tab-thinking-dark-8.png +0 -0
  1078. drowse/web/dist/icons/tab-thinking-dark-9.png +0 -0
  1079. drowse/web/dist/icons/tab-thinking-light-0.png +0 -0
  1080. drowse/web/dist/icons/tab-thinking-light-1.png +0 -0
  1081. drowse/web/dist/icons/tab-thinking-light-10.png +0 -0
  1082. drowse/web/dist/icons/tab-thinking-light-11.png +0 -0
  1083. drowse/web/dist/icons/tab-thinking-light-12.png +0 -0
  1084. drowse/web/dist/icons/tab-thinking-light-13.png +0 -0
  1085. drowse/web/dist/icons/tab-thinking-light-14.png +0 -0
  1086. drowse/web/dist/icons/tab-thinking-light-15.png +0 -0
  1087. drowse/web/dist/icons/tab-thinking-light-16.png +0 -0
  1088. drowse/web/dist/icons/tab-thinking-light-17.png +0 -0
  1089. drowse/web/dist/icons/tab-thinking-light-18.png +0 -0
  1090. drowse/web/dist/icons/tab-thinking-light-19.png +0 -0
  1091. drowse/web/dist/icons/tab-thinking-light-2.png +0 -0
  1092. drowse/web/dist/icons/tab-thinking-light-20.png +0 -0
  1093. drowse/web/dist/icons/tab-thinking-light-21.png +0 -0
  1094. drowse/web/dist/icons/tab-thinking-light-22.png +0 -0
  1095. drowse/web/dist/icons/tab-thinking-light-23.png +0 -0
  1096. drowse/web/dist/icons/tab-thinking-light-24.png +0 -0
  1097. drowse/web/dist/icons/tab-thinking-light-25.png +0 -0
  1098. drowse/web/dist/icons/tab-thinking-light-26.png +0 -0
  1099. drowse/web/dist/icons/tab-thinking-light-27.png +0 -0
  1100. drowse/web/dist/icons/tab-thinking-light-28.png +0 -0
  1101. drowse/web/dist/icons/tab-thinking-light-29.png +0 -0
  1102. drowse/web/dist/icons/tab-thinking-light-3.png +0 -0
  1103. drowse/web/dist/icons/tab-thinking-light-30.png +0 -0
  1104. drowse/web/dist/icons/tab-thinking-light-31.png +0 -0
  1105. drowse/web/dist/icons/tab-thinking-light-32.png +0 -0
  1106. drowse/web/dist/icons/tab-thinking-light-33.png +0 -0
  1107. drowse/web/dist/icons/tab-thinking-light-34.png +0 -0
  1108. drowse/web/dist/icons/tab-thinking-light-35.png +0 -0
  1109. drowse/web/dist/icons/tab-thinking-light-36.png +0 -0
  1110. drowse/web/dist/icons/tab-thinking-light-37.png +0 -0
  1111. drowse/web/dist/icons/tab-thinking-light-38.png +0 -0
  1112. drowse/web/dist/icons/tab-thinking-light-39.png +0 -0
  1113. drowse/web/dist/icons/tab-thinking-light-4.png +0 -0
  1114. drowse/web/dist/icons/tab-thinking-light-40.png +0 -0
  1115. drowse/web/dist/icons/tab-thinking-light-41.png +0 -0
  1116. drowse/web/dist/icons/tab-thinking-light-42.png +0 -0
  1117. drowse/web/dist/icons/tab-thinking-light-43.png +0 -0
  1118. drowse/web/dist/icons/tab-thinking-light-44.png +0 -0
  1119. drowse/web/dist/icons/tab-thinking-light-45.png +0 -0
  1120. drowse/web/dist/icons/tab-thinking-light-46.png +0 -0
  1121. drowse/web/dist/icons/tab-thinking-light-47.png +0 -0
  1122. drowse/web/dist/icons/tab-thinking-light-5.png +0 -0
  1123. drowse/web/dist/icons/tab-thinking-light-6.png +0 -0
  1124. drowse/web/dist/icons/tab-thinking-light-7.png +0 -0
  1125. drowse/web/dist/icons/tab-thinking-light-8.png +0 -0
  1126. drowse/web/dist/icons/tab-thinking-light-9.png +0 -0
  1127. drowse/web/dist/icons/tab-tokens-dark.png +0 -0
  1128. drowse/web/dist/icons/tab-tokens-light.png +0 -0
  1129. drowse/web/dist/icons/tab-tokens.png +0 -0
  1130. drowse/web/dist/icons/tab-training-0.png +0 -0
  1131. drowse/web/dist/icons/tab-training-1.png +0 -0
  1132. drowse/web/dist/icons/tab-training-2.png +0 -0
  1133. drowse/web/dist/icons/tab-training-dark-0.png +0 -0
  1134. drowse/web/dist/icons/tab-training-dark-1.png +0 -0
  1135. drowse/web/dist/icons/tab-training-dark-10.png +0 -0
  1136. drowse/web/dist/icons/tab-training-dark-11.png +0 -0
  1137. drowse/web/dist/icons/tab-training-dark-12.png +0 -0
  1138. drowse/web/dist/icons/tab-training-dark-13.png +0 -0
  1139. drowse/web/dist/icons/tab-training-dark-14.png +0 -0
  1140. drowse/web/dist/icons/tab-training-dark-15.png +0 -0
  1141. drowse/web/dist/icons/tab-training-dark-16.png +0 -0
  1142. drowse/web/dist/icons/tab-training-dark-17.png +0 -0
  1143. drowse/web/dist/icons/tab-training-dark-18.png +0 -0
  1144. drowse/web/dist/icons/tab-training-dark-19.png +0 -0
  1145. drowse/web/dist/icons/tab-training-dark-2.png +0 -0
  1146. drowse/web/dist/icons/tab-training-dark-20.png +0 -0
  1147. drowse/web/dist/icons/tab-training-dark-21.png +0 -0
  1148. drowse/web/dist/icons/tab-training-dark-22.png +0 -0
  1149. drowse/web/dist/icons/tab-training-dark-23.png +0 -0
  1150. drowse/web/dist/icons/tab-training-dark-24.png +0 -0
  1151. drowse/web/dist/icons/tab-training-dark-25.png +0 -0
  1152. drowse/web/dist/icons/tab-training-dark-26.png +0 -0
  1153. drowse/web/dist/icons/tab-training-dark-27.png +0 -0
  1154. drowse/web/dist/icons/tab-training-dark-28.png +0 -0
  1155. drowse/web/dist/icons/tab-training-dark-29.png +0 -0
  1156. drowse/web/dist/icons/tab-training-dark-3.png +0 -0
  1157. drowse/web/dist/icons/tab-training-dark-30.png +0 -0
  1158. drowse/web/dist/icons/tab-training-dark-31.png +0 -0
  1159. drowse/web/dist/icons/tab-training-dark-32.png +0 -0
  1160. drowse/web/dist/icons/tab-training-dark-33.png +0 -0
  1161. drowse/web/dist/icons/tab-training-dark-34.png +0 -0
  1162. drowse/web/dist/icons/tab-training-dark-35.png +0 -0
  1163. drowse/web/dist/icons/tab-training-dark-36.png +0 -0
  1164. drowse/web/dist/icons/tab-training-dark-37.png +0 -0
  1165. drowse/web/dist/icons/tab-training-dark-38.png +0 -0
  1166. drowse/web/dist/icons/tab-training-dark-39.png +0 -0
  1167. drowse/web/dist/icons/tab-training-dark-4.png +0 -0
  1168. drowse/web/dist/icons/tab-training-dark-40.png +0 -0
  1169. drowse/web/dist/icons/tab-training-dark-41.png +0 -0
  1170. drowse/web/dist/icons/tab-training-dark-42.png +0 -0
  1171. drowse/web/dist/icons/tab-training-dark-43.png +0 -0
  1172. drowse/web/dist/icons/tab-training-dark-44.png +0 -0
  1173. drowse/web/dist/icons/tab-training-dark-45.png +0 -0
  1174. drowse/web/dist/icons/tab-training-dark-46.png +0 -0
  1175. drowse/web/dist/icons/tab-training-dark-47.png +0 -0
  1176. drowse/web/dist/icons/tab-training-dark-5.png +0 -0
  1177. drowse/web/dist/icons/tab-training-dark-6.png +0 -0
  1178. drowse/web/dist/icons/tab-training-dark-7.png +0 -0
  1179. drowse/web/dist/icons/tab-training-dark-8.png +0 -0
  1180. drowse/web/dist/icons/tab-training-dark-9.png +0 -0
  1181. drowse/web/dist/icons/tab-training-light-0.png +0 -0
  1182. drowse/web/dist/icons/tab-training-light-1.png +0 -0
  1183. drowse/web/dist/icons/tab-training-light-10.png +0 -0
  1184. drowse/web/dist/icons/tab-training-light-11.png +0 -0
  1185. drowse/web/dist/icons/tab-training-light-12.png +0 -0
  1186. drowse/web/dist/icons/tab-training-light-13.png +0 -0
  1187. drowse/web/dist/icons/tab-training-light-14.png +0 -0
  1188. drowse/web/dist/icons/tab-training-light-15.png +0 -0
  1189. drowse/web/dist/icons/tab-training-light-16.png +0 -0
  1190. drowse/web/dist/icons/tab-training-light-17.png +0 -0
  1191. drowse/web/dist/icons/tab-training-light-18.png +0 -0
  1192. drowse/web/dist/icons/tab-training-light-19.png +0 -0
  1193. drowse/web/dist/icons/tab-training-light-2.png +0 -0
  1194. drowse/web/dist/icons/tab-training-light-20.png +0 -0
  1195. drowse/web/dist/icons/tab-training-light-21.png +0 -0
  1196. drowse/web/dist/icons/tab-training-light-22.png +0 -0
  1197. drowse/web/dist/icons/tab-training-light-23.png +0 -0
  1198. drowse/web/dist/icons/tab-training-light-24.png +0 -0
  1199. drowse/web/dist/icons/tab-training-light-25.png +0 -0
  1200. drowse/web/dist/icons/tab-training-light-26.png +0 -0
  1201. drowse/web/dist/icons/tab-training-light-27.png +0 -0
  1202. drowse/web/dist/icons/tab-training-light-28.png +0 -0
  1203. drowse/web/dist/icons/tab-training-light-29.png +0 -0
  1204. drowse/web/dist/icons/tab-training-light-3.png +0 -0
  1205. drowse/web/dist/icons/tab-training-light-30.png +0 -0
  1206. drowse/web/dist/icons/tab-training-light-31.png +0 -0
  1207. drowse/web/dist/icons/tab-training-light-32.png +0 -0
  1208. drowse/web/dist/icons/tab-training-light-33.png +0 -0
  1209. drowse/web/dist/icons/tab-training-light-34.png +0 -0
  1210. drowse/web/dist/icons/tab-training-light-35.png +0 -0
  1211. drowse/web/dist/icons/tab-training-light-36.png +0 -0
  1212. drowse/web/dist/icons/tab-training-light-37.png +0 -0
  1213. drowse/web/dist/icons/tab-training-light-38.png +0 -0
  1214. drowse/web/dist/icons/tab-training-light-39.png +0 -0
  1215. drowse/web/dist/icons/tab-training-light-4.png +0 -0
  1216. drowse/web/dist/icons/tab-training-light-40.png +0 -0
  1217. drowse/web/dist/icons/tab-training-light-41.png +0 -0
  1218. drowse/web/dist/icons/tab-training-light-42.png +0 -0
  1219. drowse/web/dist/icons/tab-training-light-43.png +0 -0
  1220. drowse/web/dist/icons/tab-training-light-44.png +0 -0
  1221. drowse/web/dist/icons/tab-training-light-45.png +0 -0
  1222. drowse/web/dist/icons/tab-training-light-46.png +0 -0
  1223. drowse/web/dist/icons/tab-training-light-47.png +0 -0
  1224. drowse/web/dist/icons/tab-training-light-5.png +0 -0
  1225. drowse/web/dist/icons/tab-training-light-6.png +0 -0
  1226. drowse/web/dist/icons/tab-training-light-7.png +0 -0
  1227. drowse/web/dist/icons/tab-training-light-8.png +0 -0
  1228. drowse/web/dist/icons/tab-training-light-9.png +0 -0
  1229. drowse/web/dist/icons/tab-unsupported-dark.png +0 -0
  1230. drowse/web/dist/icons/tab-unsupported-light.png +0 -0
  1231. drowse/web/dist/icons/tab-unsupported.png +0 -0
  1232. drowse/web/dist/icons/tab-working-0.png +0 -0
  1233. drowse/web/dist/icons/tab-working-1.png +0 -0
  1234. drowse/web/dist/icons/tab-working-2.png +0 -0
  1235. drowse/web/dist/icons/tab-working-dark-0.png +0 -0
  1236. drowse/web/dist/icons/tab-working-dark-1.png +0 -0
  1237. drowse/web/dist/icons/tab-working-dark-10.png +0 -0
  1238. drowse/web/dist/icons/tab-working-dark-11.png +0 -0
  1239. drowse/web/dist/icons/tab-working-dark-12.png +0 -0
  1240. drowse/web/dist/icons/tab-working-dark-13.png +0 -0
  1241. drowse/web/dist/icons/tab-working-dark-14.png +0 -0
  1242. drowse/web/dist/icons/tab-working-dark-15.png +0 -0
  1243. drowse/web/dist/icons/tab-working-dark-16.png +0 -0
  1244. drowse/web/dist/icons/tab-working-dark-17.png +0 -0
  1245. drowse/web/dist/icons/tab-working-dark-18.png +0 -0
  1246. drowse/web/dist/icons/tab-working-dark-19.png +0 -0
  1247. drowse/web/dist/icons/tab-working-dark-2.png +0 -0
  1248. drowse/web/dist/icons/tab-working-dark-20.png +0 -0
  1249. drowse/web/dist/icons/tab-working-dark-21.png +0 -0
  1250. drowse/web/dist/icons/tab-working-dark-22.png +0 -0
  1251. drowse/web/dist/icons/tab-working-dark-23.png +0 -0
  1252. drowse/web/dist/icons/tab-working-dark-24.png +0 -0
  1253. drowse/web/dist/icons/tab-working-dark-25.png +0 -0
  1254. drowse/web/dist/icons/tab-working-dark-26.png +0 -0
  1255. drowse/web/dist/icons/tab-working-dark-27.png +0 -0
  1256. drowse/web/dist/icons/tab-working-dark-28.png +0 -0
  1257. drowse/web/dist/icons/tab-working-dark-29.png +0 -0
  1258. drowse/web/dist/icons/tab-working-dark-3.png +0 -0
  1259. drowse/web/dist/icons/tab-working-dark-30.png +0 -0
  1260. drowse/web/dist/icons/tab-working-dark-31.png +0 -0
  1261. drowse/web/dist/icons/tab-working-dark-32.png +0 -0
  1262. drowse/web/dist/icons/tab-working-dark-33.png +0 -0
  1263. drowse/web/dist/icons/tab-working-dark-34.png +0 -0
  1264. drowse/web/dist/icons/tab-working-dark-35.png +0 -0
  1265. drowse/web/dist/icons/tab-working-dark-36.png +0 -0
  1266. drowse/web/dist/icons/tab-working-dark-37.png +0 -0
  1267. drowse/web/dist/icons/tab-working-dark-38.png +0 -0
  1268. drowse/web/dist/icons/tab-working-dark-39.png +0 -0
  1269. drowse/web/dist/icons/tab-working-dark-4.png +0 -0
  1270. drowse/web/dist/icons/tab-working-dark-40.png +0 -0
  1271. drowse/web/dist/icons/tab-working-dark-41.png +0 -0
  1272. drowse/web/dist/icons/tab-working-dark-42.png +0 -0
  1273. drowse/web/dist/icons/tab-working-dark-43.png +0 -0
  1274. drowse/web/dist/icons/tab-working-dark-44.png +0 -0
  1275. drowse/web/dist/icons/tab-working-dark-45.png +0 -0
  1276. drowse/web/dist/icons/tab-working-dark-46.png +0 -0
  1277. drowse/web/dist/icons/tab-working-dark-47.png +0 -0
  1278. drowse/web/dist/icons/tab-working-dark-5.png +0 -0
  1279. drowse/web/dist/icons/tab-working-dark-6.png +0 -0
  1280. drowse/web/dist/icons/tab-working-dark-7.png +0 -0
  1281. drowse/web/dist/icons/tab-working-dark-8.png +0 -0
  1282. drowse/web/dist/icons/tab-working-dark-9.png +0 -0
  1283. drowse/web/dist/icons/tab-working-light-0.png +0 -0
  1284. drowse/web/dist/icons/tab-working-light-1.png +0 -0
  1285. drowse/web/dist/icons/tab-working-light-10.png +0 -0
  1286. drowse/web/dist/icons/tab-working-light-11.png +0 -0
  1287. drowse/web/dist/icons/tab-working-light-12.png +0 -0
  1288. drowse/web/dist/icons/tab-working-light-13.png +0 -0
  1289. drowse/web/dist/icons/tab-working-light-14.png +0 -0
  1290. drowse/web/dist/icons/tab-working-light-15.png +0 -0
  1291. drowse/web/dist/icons/tab-working-light-16.png +0 -0
  1292. drowse/web/dist/icons/tab-working-light-17.png +0 -0
  1293. drowse/web/dist/icons/tab-working-light-18.png +0 -0
  1294. drowse/web/dist/icons/tab-working-light-19.png +0 -0
  1295. drowse/web/dist/icons/tab-working-light-2.png +0 -0
  1296. drowse/web/dist/icons/tab-working-light-20.png +0 -0
  1297. drowse/web/dist/icons/tab-working-light-21.png +0 -0
  1298. drowse/web/dist/icons/tab-working-light-22.png +0 -0
  1299. drowse/web/dist/icons/tab-working-light-23.png +0 -0
  1300. drowse/web/dist/icons/tab-working-light-24.png +0 -0
  1301. drowse/web/dist/icons/tab-working-light-25.png +0 -0
  1302. drowse/web/dist/icons/tab-working-light-26.png +0 -0
  1303. drowse/web/dist/icons/tab-working-light-27.png +0 -0
  1304. drowse/web/dist/icons/tab-working-light-28.png +0 -0
  1305. drowse/web/dist/icons/tab-working-light-29.png +0 -0
  1306. drowse/web/dist/icons/tab-working-light-3.png +0 -0
  1307. drowse/web/dist/icons/tab-working-light-30.png +0 -0
  1308. drowse/web/dist/icons/tab-working-light-31.png +0 -0
  1309. drowse/web/dist/icons/tab-working-light-32.png +0 -0
  1310. drowse/web/dist/icons/tab-working-light-33.png +0 -0
  1311. drowse/web/dist/icons/tab-working-light-34.png +0 -0
  1312. drowse/web/dist/icons/tab-working-light-35.png +0 -0
  1313. drowse/web/dist/icons/tab-working-light-36.png +0 -0
  1314. drowse/web/dist/icons/tab-working-light-37.png +0 -0
  1315. drowse/web/dist/icons/tab-working-light-38.png +0 -0
  1316. drowse/web/dist/icons/tab-working-light-39.png +0 -0
  1317. drowse/web/dist/icons/tab-working-light-4.png +0 -0
  1318. drowse/web/dist/icons/tab-working-light-40.png +0 -0
  1319. drowse/web/dist/icons/tab-working-light-41.png +0 -0
  1320. drowse/web/dist/icons/tab-working-light-42.png +0 -0
  1321. drowse/web/dist/icons/tab-working-light-43.png +0 -0
  1322. drowse/web/dist/icons/tab-working-light-44.png +0 -0
  1323. drowse/web/dist/icons/tab-working-light-45.png +0 -0
  1324. drowse/web/dist/icons/tab-working-light-46.png +0 -0
  1325. drowse/web/dist/icons/tab-working-light-47.png +0 -0
  1326. drowse/web/dist/icons/tab-working-light-5.png +0 -0
  1327. drowse/web/dist/icons/tab-working-light-6.png +0 -0
  1328. drowse/web/dist/icons/tab-working-light-7.png +0 -0
  1329. drowse/web/dist/icons/tab-working-light-8.png +0 -0
  1330. drowse/web/dist/icons/tab-working-light-9.png +0 -0
  1331. drowse/web/dist/index.html +34 -0
  1332. drowse/web/dist/social/drowse.png +0 -0
  1333. drowse/web/dist/social/drowse.svg +6 -0
  1334. drowse/web/dist/theme-init.js +25 -0
  1335. drowse/web/routes.py +118 -0
  1336. drowse_ai-5.3.1.dist-info/METADATA +632 -0
  1337. drowse_ai-5.3.1.dist-info/RECORD +1341 -0
  1338. drowse_ai-5.3.1.dist-info/WHEEL +5 -0
  1339. drowse_ai-5.3.1.dist-info/entry_points.txt +2 -0
  1340. drowse_ai-5.3.1.dist-info/licenses/LICENSE +661 -0
  1341. drowse_ai-5.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1097 @@
1
+ """``drowse manifold <verb>`` compute runners (extract/generate/from-template/
2
+ fit/bake/merge/transfer/compare/why) and their dispatch table."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ from collections.abc import Iterable
8
+ from operator import itemgetter
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ import drowse.cli.runners as _pkg
14
+ from drowse.cli.parsers import _MANIFOLD_VERBS
15
+ from drowse.cli.runners.shared import (
16
+ _print_verb_menu, _resolve_manifold_folder, _resolve_manifold_ns_name,
17
+ _drowse_error_exit, _split_manifold_ns_name,
18
+ )
19
+ from drowse.io.paths import VARIANT_SUFFIX_RE
20
+
21
+ if TYPE_CHECKING:
22
+ from drowse.core.profile import Profile
23
+
24
+
25
+ def _run_manifold_bake(args: argparse.Namespace) -> None:
26
+ from drowse.io import bake as bake_mod
27
+ dst = bake_mod.merge_into_manifold(
28
+ args.name, args.expression, model=args.model,
29
+ force=args.force, strict=args.strict,
30
+ )
31
+ print(f"Merged manifold written to {dst}")
32
+
33
+
34
+ def _try_manifold_fit_noop_preflight(
35
+ args: argparse.Namespace,
36
+ folder: "Path",
37
+ *,
38
+ sae: str | None = None,
39
+ fit_mode: str | None = None,
40
+ hyperparams: "dict[str, object] | None" = None,
41
+ expected_role: str | None = None,
42
+ enforce_role: bool = False,
43
+ ) -> "Any | None":
44
+ """Prove this fit target is already exact before any model load.
45
+
46
+ The ``lens fit`` no-op shape for manifolds. Everything decisive lives in
47
+ ``io.preflight_manifold_fit_noop``; this wrapper only supplies the CLI's
48
+ request shape and applies the one check that is an *authoring* concern
49
+ rather than a fit-identity one — ``extract --role`` refuses to reuse a
50
+ folder whose corpus carries a different role baseline, and that refusal is
51
+ an error the loaded path must be allowed to raise. ``manifold fit`` takes
52
+ the folder's roles as given (a persona manifold is authored with them), so
53
+ it leaves ``enforce_role`` off.
54
+ """
55
+ from drowse.io.manifold_folder import ManifoldFolder, ManifoldFormatError
56
+ from drowse.io.manifolds import preflight_manifold_fit_noop
57
+
58
+ if not (folder / "manifold.json").exists():
59
+ return None
60
+ if enforce_role:
61
+ try:
62
+ roles = ManifoldFolder.load(
63
+ folder, verify_manifest=False,
64
+ )._roles_padded()
65
+ except (ManifoldFormatError, OSError, ValueError):
66
+ return None
67
+ if not roles or not all(role == expected_role for role in roles):
68
+ return None
69
+ return preflight_manifold_fit_noop(
70
+ folder,
71
+ model_id=args.model,
72
+ layer_indices=getattr(args, "layers", None),
73
+ sae=sae,
74
+ fit_mode=fit_mode,
75
+ hyperparams=hyperparams,
76
+ quantize=getattr(args, "quantize", None),
77
+ device=getattr(args, "device", None) or "auto",
78
+ )
79
+
80
+
81
+ def _require_model(args: argparse.Namespace) -> None:
82
+ if not args.model:
83
+ # The compute leaves (extract / fit / generate / bake / transfer) carry
84
+ # the leaf on ``manifold_cmd`` — surface it so the error reads
85
+ # "manifold fit".
86
+ manifold_cmd = getattr(args, "manifold_cmd", None)
87
+ cmd = f"manifold {manifold_cmd}" if manifold_cmd else "?"
88
+ print(f"{cmd}: -m/--model is required", file=sys.stderr)
89
+ sys.exit(2)
90
+
91
+
92
+ def _run_manifold_extract(args: argparse.Namespace) -> None:
93
+ _require_model(args)
94
+ import pathlib
95
+ from drowse.io.paths import manifold_dir, tensor_filename
96
+
97
+ if len(args.concept) == 1:
98
+ raw = args.concept[0]
99
+ baseline = None
100
+ elif len(args.concept) == 2:
101
+ raw = args.concept[0]
102
+ baseline = args.concept[1]
103
+ else:
104
+ print(
105
+ "extract: expected 1 or 2 positional arguments "
106
+ f"(got {len(args.concept)})",
107
+ file=sys.stderr,
108
+ )
109
+ sys.exit(2)
110
+
111
+ requested_release = getattr(args, "sae", None)
112
+ requested_role = getattr(args, "role", None)
113
+ if requested_release and requested_role:
114
+ print(
115
+ "extract: --sae and --role are mutually exclusive "
116
+ "(role substitution bakes into the manifold's node corpora; SAE "
117
+ "reconstructs the centroids — the two don't compose)",
118
+ file=sys.stderr,
119
+ )
120
+ sys.exit(2)
121
+
122
+ # Same rejection the multi-node authoring path applies: ``custom`` has no
123
+ # built-in system template, so the caller must supply one.
124
+ kind = getattr(args, "kind", None) or "abstract"
125
+ custom_system = getattr(args, "custom_system", None)
126
+ if kind == "custom" and not custom_system:
127
+ print(
128
+ "manifold extract: --kind custom requires --system "
129
+ '(a template with a {c} placeholder, e.g. "You are the month of '
130
+ '{c}; speak as that month.")',
131
+ file=sys.stderr,
132
+ )
133
+ sys.exit(2)
134
+
135
+ # A steering vector is a 2-node ``pca`` manifold (4.0); a role-augmented
136
+ # fit bakes into its node corpora and writes the canonical tensor name (no
137
+ # ``_role-`` suffix). Bare file existence proves nothing, so the cache
138
+ # check runs through the weight-free preflight (sidecar integrity, corpus /
139
+ # role / template identity, the token-exact render, and the checkpoint→
140
+ # loaded fingerprint bridge) and falls through to the loaded session
141
+ # whenever any component is unproven.
142
+ from drowse.core.naming import canonical_concept_name
143
+
144
+ ns = getattr(args, "namespace", None) or "local"
145
+ tensor_name = tensor_filename(args.model, release=requested_release)
146
+ if not args.force:
147
+ canonical = canonical_concept_name(raw, baseline)
148
+ proof = _try_manifold_fit_noop_preflight(
149
+ args,
150
+ pathlib.Path(manifold_dir(ns, canonical)),
151
+ sae=requested_release,
152
+ expected_role=requested_role,
153
+ enforce_role=True,
154
+ )
155
+ if proof is not None:
156
+ variant_tail = f":role-{requested_role}" if requested_role else ""
157
+ print(
158
+ f"extracted {canonical}{variant_tail} -> {proof.tensor_path}"
159
+ )
160
+ print(
161
+ "Already fitted for this corpus and exact model source "
162
+ "— nothing to do."
163
+ )
164
+ return
165
+ _pkg._print_startup(args)
166
+ session = _pkg._make_session(args, load_probes=False)
167
+ _pkg._print_model_info(session)
168
+
169
+ # ``extract`` generates up to 96 in-character responses and then runs a
170
+ # full fit, so it narrates per batch like its ``fit`` / ``generate``
171
+ # siblings rather than going quiet until the final line.
172
+ extract_kwargs: dict[str, Any] = {
173
+ "kind": kind,
174
+ "custom_system": custom_system,
175
+ "on_progress": lambda m: print(f" {m}", flush=True),
176
+ }
177
+ if requested_release:
178
+ extract_kwargs["sae"] = args.sae
179
+ if requested_role:
180
+ extract_kwargs["role"] = requested_role
181
+ if getattr(args, "namespace", None) is not None:
182
+ extract_kwargs["namespace"] = args.namespace
183
+ if args.force:
184
+ extract_kwargs["force"] = True
185
+
186
+ try:
187
+ if baseline is not None:
188
+ name, _profile = session.extract(raw, baseline=baseline, **extract_kwargs)
189
+ else:
190
+ name, _profile = session.extract(raw, **extract_kwargs)
191
+ except Exception as e:
192
+ print(f"extract failed: {e}", file=sys.stderr)
193
+ sys.exit(1)
194
+
195
+ bare_name, _variant = _split_variant_suffix(name)
196
+ final_path = pathlib.Path(manifold_dir(ns, bare_name)) / tensor_name
197
+ print(f"extracted {name} -> {final_path}")
198
+
199
+
200
+ # Single source of truth lives in ``io.paths`` (owns the variant scheme).
201
+ _VARIANT_SUFFIX_RE = VARIANT_SUFFIX_RE
202
+
203
+
204
+ def _split_variant_suffix(raw: str) -> tuple[str, str | None]:
205
+ """Peel a trailing ``:<variant>`` off a selector string.
206
+
207
+ Returns ``(name_part, variant_or_None)``. ``variant`` follows the suffix
208
+ grammar owned by :data:`drowse.io.paths.VARIANT_SUFFIX_RE`.
209
+ Non-variant colon usage (``tag:``, ``namespace:``, ``model:``) passes
210
+ through unchanged with ``variant=None`` — those prefixes are caught by
211
+ ``sel.parse`` later.
212
+ """
213
+ if ":" not in raw:
214
+ return raw, None
215
+ head, _, tail = raw.rpartition(":")
216
+ if _VARIANT_SUFFIX_RE.match(tail) and head:
217
+ # ``_VARIANT_SUFFIX_RE`` is anchored over ``[a-z0-9._-]`` only, so a
218
+ # matching ``tail`` can't contain ``/`` — ``model:<org>/<name>`` falls
219
+ # through to ``return raw, None`` because its tail fails the regex.
220
+ return head, tail
221
+ return raw, None
222
+
223
+
224
+ def _fold_manifold_to_profile_with_identity(
225
+ name: str, model_id: str, variant: str | None,
226
+ ) -> "tuple[Profile, str, str] | None":
227
+ """Fold a fitted 2-node ``pca`` manifold and return its namespace identity.
228
+
229
+ The identity is needed by ``compare``'s rank-all mode: bundled and user
230
+ concepts can share a bare name across namespaces, so callers must key
231
+ scanned profiles by ``namespace/name`` rather than letting later matches
232
+ overwrite earlier ones.
233
+ """
234
+ from drowse.core.profile import Profile
235
+ from drowse.io.manifold_tensors import load_manifold
236
+ from drowse.core.capture import folded_directions
237
+ from drowse.io.paths import manifold_dir, manifolds_dir, tensor_filename
238
+ from drowse.io.selectors import AmbiguousSelectorError
239
+
240
+ if variant in (None, "raw"):
241
+ release: str | None = None
242
+ elif variant.startswith("sae-"):
243
+ release = variant[len("sae-"):]
244
+ else:
245
+ return None
246
+
247
+ if "/" in name:
248
+ ns, bare = name.split("/", 1)
249
+ search_ns = [ns]
250
+ else:
251
+ bare = name
252
+ root = manifolds_dir()
253
+ search_ns = (
254
+ sorted(d.name for d in root.iterdir() if d.is_dir())
255
+ if root.exists() else []
256
+ )
257
+ fname = tensor_filename(model_id, release=release)
258
+ hits = [
259
+ manifold_dir(ns, bare) / fname
260
+ for ns in search_ns
261
+ if (manifold_dir(ns, bare) / fname).exists()
262
+ ]
263
+ if not hits:
264
+ return None
265
+ if len(hits) > 1:
266
+ qualified = ", ".join(f"{p.parent.parent.name}/{bare}" for p in hits)
267
+ raise AmbiguousSelectorError(
268
+ f"ambiguous manifold '{bare}': matches {qualified}. "
269
+ f"Qualify it with a namespace."
270
+ )
271
+ try:
272
+ manifold = load_manifold(hits[0])
273
+ dirs = folded_directions(manifold)
274
+ except Exception:
275
+ return None
276
+ ns = hits[0].parent.parent.name
277
+ return Profile(dirs), ns, bare
278
+
279
+
280
+ def _fold_all_fitted_manifolds(
281
+ model_id: str, *, exclude_identity: tuple[str, str] | None = None,
282
+ ) -> "dict[str, Profile]":
283
+ """Fold every fitted 2-node ``pca`` manifold into ``{ns/name: Profile}``.
284
+
285
+ Backs ``compare``'s 1-arg "rank against all installed" mode now that
286
+ bundled concepts are manifolds. Only manifolds with a fitted raw tensor
287
+ for ``model_id`` that fold to a 2-node affine are included;
288
+ ``exclude_identity`` drops the target by exact ``(namespace, name)``.
289
+ """
290
+ from drowse.core.profile import Profile
291
+ from drowse.io.manifold_tensors import load_manifold
292
+ from drowse.core.capture import folded_directions
293
+ from drowse.io.paths import manifolds_dir, tensor_filename
294
+
295
+ out: dict[str, Profile] = {}
296
+ root = manifolds_dir()
297
+ if not root.is_dir():
298
+ return out
299
+ fname = tensor_filename(model_id, release=None)
300
+ for ns_dir in sorted(root.iterdir()):
301
+ if not ns_dir.is_dir():
302
+ continue
303
+ for mdir in sorted(ns_dir.iterdir()):
304
+ if not mdir.is_dir():
305
+ continue
306
+ identity = (ns_dir.name, mdir.name)
307
+ if identity == exclude_identity:
308
+ continue
309
+ tensor = mdir / fname
310
+ if not tensor.is_file():
311
+ continue
312
+ try:
313
+ dirs = folded_directions(load_manifold(tensor))
314
+ except Exception:
315
+ continue # not a foldable 2-node affine (curved / rank > 1)
316
+ out[f"{ns_dir.name}/{mdir.name}"] = Profile(dirs)
317
+ return out
318
+
319
+
320
+ def _run_manifold_compare(args: argparse.Namespace) -> None:
321
+ import json as _json
322
+ from drowse.io.selectors import parse as sel_parse, resolve
323
+
324
+ # Compare is Mahalanobis-only: load the per-model whitener once up
325
+ # front and share it across every ``cosine_similarity`` call below.
326
+ # Failure is fatal — there is no Euclidean path, so a missing neutral
327
+ # cache surfaces directly instead of degrading silently.
328
+ from drowse.core.mahalanobis import LayerWhitener, WhitenerError
329
+
330
+ whitener: "Any | None"
331
+ try:
332
+ whitener = LayerWhitener.from_cache(
333
+ args.model,
334
+ ridge_scale=getattr(args, "ridge_scale", 1.0),
335
+ )
336
+ except WhitenerError as e:
337
+ print(f"compare: {e}", file=sys.stderr)
338
+ sys.exit(1)
339
+
340
+ # Expand selectors into (name, variant) pairs. Variant travels with the
341
+ # name through the load loop so ``foo:sae`` picks the SAE tensor.
342
+ names: list[tuple[str, str | None]] = []
343
+ for raw in args.concepts:
344
+ name_part, variant = _split_variant_suffix(raw)
345
+ try:
346
+ sel = sel_parse(name_part)
347
+ except Exception:
348
+ names.append((name_part, variant))
349
+ continue
350
+ if sel.kind == "name":
351
+ names.append((name_part, variant))
352
+ else:
353
+ # Bulk selectors (tag:/namespace:/all) expand to individual
354
+ # names; inherit the variant suffix so `tag:emotion:sae`
355
+ # resolves SAE tensors across the tag.
356
+ resolved = resolve(sel)
357
+ names.extend((f"{c.namespace}/{c.name}", variant) for c in resolved)
358
+
359
+ # Load profiles by folding each concept's fitted 2-node ``pca`` manifold.
360
+ profiles: dict[str, Profile] = {}
361
+ profile_identities: dict[str, tuple[str, str]] = {}
362
+ for name, variant in names:
363
+ try:
364
+ folded = _pkg._fold_manifold_to_profile_with_identity(
365
+ name, args.model, variant,
366
+ )
367
+ except Exception as e:
368
+ print(f"warning: {e}, skipping", file=sys.stderr)
369
+ continue
370
+ if folded is None:
371
+ print(
372
+ f"warning: no fitted manifold for '{name}' with model "
373
+ f"{args.model}, skipping",
374
+ file=sys.stderr,
375
+ )
376
+ continue
377
+ loaded, ns, bare = folded
378
+ display_base = f"{ns}/{bare}" if "/" in name else bare
379
+ display = display_base if variant is None else f"{display_base}:{variant}"
380
+ profiles[display] = loaded
381
+ profile_identities[display] = (ns, bare)
382
+
383
+ if len(profiles) < 1:
384
+ print("compare: no loadable profiles found", file=sys.stderr)
385
+ sys.exit(1)
386
+
387
+ ordered = list(profiles.keys())
388
+
389
+ # 1-arg mode: rank all installed against the target.
390
+ if len(args.concepts) == 1 and len(ordered) == 1:
391
+ target_name = ordered[0]
392
+ target = profiles[target_name]
393
+ target_identity = profile_identities.get(target_name)
394
+
395
+ # Every concept ships as a fitted 2-node ``pca`` manifold — fold
396
+ # every fitted one for this model into the ranking pool. Keep the
397
+ # exact namespace identity internally, then choose display names after
398
+ # the full pool is known: bare for unique names, qualified for
399
+ # collisions.
400
+ other_entries: dict[tuple[str, str], Profile] = {}
401
+ for mname, mprof in _pkg._fold_all_fitted_manifolds(
402
+ args.model, exclude_identity=target_identity,
403
+ ).items():
404
+ ns, bare = mname.split("/", 1)
405
+ other_entries[(ns, bare)] = mprof
406
+
407
+ from collections import Counter
408
+
409
+ target_bare = (
410
+ target_identity[1] if target_identity is not None
411
+ else target_name.rsplit("/", 1)[-1]
412
+ )
413
+ bare_counts = Counter(name for _ns, name in other_entries)
414
+ others: dict[str, Profile] = {}
415
+ for (ns, bare), profile in sorted(other_entries.items()):
416
+ display = (
417
+ f"{ns}/{bare}"
418
+ if bare_counts[bare] > 1 or bare == target_bare
419
+ else bare
420
+ )
421
+ others[display] = profile
422
+
423
+ if not others:
424
+ print(f"compare: no other profiles found for model {args.model}", file=sys.stderr)
425
+ sys.exit(1)
426
+
427
+ scores: dict[str, float] = {
428
+ name: target.cosine_similarity(p, whitener=whitener)
429
+ for name, p in others.items()
430
+ }
431
+ ranked = sorted(scores.items(), key=itemgetter(1), reverse=True)
432
+
433
+ if args.json_output:
434
+ result: dict[str, Any] = {"target": target_name, "model": args.model,
435
+ "similarities": [{"name": n, "similarity": round(s, 6)}
436
+ for n, s in ranked]}
437
+ if args.verbose:
438
+ top3 = ranked[:3]
439
+ result["per_layer_top3"] = {
440
+ n: {str(k): round(v, 6)
441
+ for k, v in target.cosine_similarity(others[n], per_layer=True, whitener=whitener).items()}
442
+ for n, _ in top3
443
+ }
444
+ print(_json.dumps(result, indent=2))
445
+ else:
446
+ width = max(len(n) for n, _ in ranked)
447
+ print(f"{target_name} vs all installed ({args.model}):")
448
+ for name, score in ranked:
449
+ print(f" {name:<{width}} {score:+.4f}")
450
+ if args.verbose and ranked:
451
+ print()
452
+ print(" per-layer (top 3):")
453
+ for name, _ in ranked[:3]:
454
+ per_layer_top3: dict[int, float] = target.cosine_similarity(others[name], per_layer=True, whitener=whitener)
455
+ print(f" {name}:")
456
+ for layer in sorted(per_layer_top3):
457
+ print(f" layer {layer:>3}: {per_layer_top3[layer]:+.4f}")
458
+ return
459
+
460
+ if len(ordered) < 2:
461
+ print("compare: need at least 2 profiles to compare", file=sys.stderr)
462
+ sys.exit(1)
463
+
464
+ # 2-arg mode: pairwise.
465
+ if len(ordered) == 2:
466
+ a_name, b_name = ordered
467
+ a, b = profiles[a_name], profiles[b_name]
468
+ sim: float = a.cosine_similarity(b, whitener=whitener)
469
+
470
+ if args.json_output:
471
+ result = {"a": a_name, "b": b_name, "model": args.model,
472
+ "similarity": round(sim, 6)}
473
+ if args.verbose:
474
+ result["per_layer"] = {str(k): round(v, 6)
475
+ for k, v in a.cosine_similarity(b, per_layer=True, whitener=whitener).items()}
476
+ print(_json.dumps(result, indent=2))
477
+ else:
478
+ print(f"{a_name} ~ {b_name}: {sim:+.4f}")
479
+ if args.verbose:
480
+ per_layer_2: dict[int, float] = a.cosine_similarity(b, per_layer=True, whitener=whitener)
481
+ for layer in sorted(per_layer_2):
482
+ print(f" layer {layer:>3}: {per_layer_2[layer]:+.4f}")
483
+ return
484
+
485
+ # 3+ mode: N×N matrix.
486
+ matrix: dict[str, dict[str, float]] = {}
487
+ for a_name in ordered:
488
+ matrix[a_name] = {}
489
+ for b_name in ordered:
490
+ if a_name == b_name:
491
+ matrix[a_name][b_name] = 1.0
492
+ else:
493
+ matrix[a_name][b_name] = profiles[a_name].cosine_similarity(profiles[b_name], whitener=whitener)
494
+
495
+ if args.json_output:
496
+ result = {"model": args.model, "concepts": ordered,
497
+ "matrix": {a: {b: round(v, 6) for b, v in row.items()}
498
+ for a, row in matrix.items()}}
499
+ if args.verbose:
500
+ per_layer: dict[str, dict[str, float]] = {}
501
+ for i, a_name in enumerate(ordered):
502
+ for b_name in ordered[i + 1:]:
503
+ key = f"{a_name}|{b_name}"
504
+ per_layer[key] = {
505
+ str(k): round(v, 6)
506
+ for k, v in profiles[a_name].cosine_similarity(
507
+ profiles[b_name], per_layer=True, whitener=whitener,
508
+ ).items()
509
+ }
510
+ result["per_layer"] = per_layer
511
+ print(_json.dumps(result, indent=2))
512
+ else:
513
+ width = max(len(n) for n in ordered)
514
+ header = " " * (width + 2) + " ".join(f"{n:>{width}}" for n in ordered)
515
+ print(header)
516
+ for a_name in ordered:
517
+ row = " ".join(f"{matrix[a_name][b]:>{width}.4f}" for b in ordered)
518
+ print(f"{a_name:<{width}} {row}")
519
+
520
+
521
+ def _run_manifold_why(args: argparse.Namespace) -> None:
522
+ import json as _json
523
+ from drowse.io.selectors import AmbiguousSelectorError
524
+
525
+ # Peel off a ``:<variant>`` suffix before resolving the manifold.
526
+ name_part, variant = _split_variant_suffix(args.concept)
527
+
528
+ # Every concept is a fitted 2-node ``pca`` manifold — fold it to a vector.
529
+ profile: "Profile | None" = None
530
+ concept_name = name_part if variant is None else f"{name_part}:{variant}"
531
+ try:
532
+ folded = _pkg._fold_manifold_to_profile_with_identity(
533
+ name_part, args.model, variant,
534
+ )
535
+ except AmbiguousSelectorError as e:
536
+ print(f"why: {e}", file=sys.stderr)
537
+ sys.exit(1)
538
+ if folded is not None:
539
+ profile, ns, bare = folded
540
+ concept_base = f"{ns}/{bare}" if "/" in name_part else bare
541
+ concept_name = concept_base if variant is None else f"{concept_base}:{variant}"
542
+ if profile is None:
543
+ print(
544
+ f"why: no fitted manifold for '{args.concept}' with model "
545
+ f"{args.model}. If it's authored but unfit, fit it first: "
546
+ f"`drowse manifold fit {name_part} -m {args.model}`.",
547
+ file=sys.stderr,
548
+ )
549
+ sys.exit(1)
550
+
551
+ layer_mags: list[tuple[int, float]] = sorted(
552
+ ((layer, float(tensor.norm().item())) for layer, tensor in profile.items()),
553
+ key=itemgetter(0),
554
+ )
555
+ total_layers = len(profile)
556
+
557
+ if args.json_output:
558
+ result: dict[str, Any] = {
559
+ "concept": concept_name,
560
+ "model": args.model,
561
+ "total_layers": total_layers,
562
+ "layers": [{"layer": l, "magnitude": round(m, 6)} for l, m in layer_mags],
563
+ }
564
+ print(_json.dumps(result, indent=2))
565
+ else:
566
+ _print_why_histogram(concept_name, args.model, total_layers, layer_mags)
567
+
568
+
569
+ def _print_why_histogram(
570
+ concept_name: str,
571
+ model_id: str,
572
+ total_layers: int,
573
+ layer_mags: list[tuple[int, float]],
574
+ ) -> None:
575
+ import shutil
576
+ from drowse.core.histogram import HIST_BUCKETS, bucketize
577
+
578
+ print(f"{concept_name} ({total_layers} layers, {model_id}):")
579
+ print(" LAYERS (mean ||baked|| per bucket):")
580
+ if not layer_mags:
581
+ return
582
+
583
+ term_w = shutil.get_terminal_size((80, 24)).columns
584
+ buckets = bucketize(layer_mags, HIST_BUCKETS)
585
+ max_norm = max(v for _, _, v in buckets) or 1.0
586
+ label_w = max(2, len(str(max(hi for _, hi, _ in buckets))))
587
+
588
+ def _label(lo: int, hi: int) -> str:
589
+ return f"L{lo:0{label_w}}" if lo == hi else f"L{lo:0{label_w}}-{hi:0{label_w}}"
590
+
591
+ label_col = max(len(_label(lo, hi)) for lo, hi, _ in buckets)
592
+ # " <label> <bar> <value>" — 4 indent + label_col + 2 + bar + 2 + 8
593
+ value_w = 8
594
+ bar_w = max(12, term_w - 4 - label_col - 2 - 2 - value_w)
595
+ for lo, hi, norm in buckets:
596
+ filled = min(int(norm / max_norm * bar_w), bar_w)
597
+ bar = "█" * filled + "░" * (bar_w - filled)
598
+ print(f" {_label(lo, hi):<{label_col}} {bar} {norm:>{value_w}.3f}")
599
+
600
+
601
+ def _run_manifold_fit(args: argparse.Namespace) -> None:
602
+ """``drowse manifold fit`` — fit an authored OR discover-mode manifold.
603
+
604
+ The positional ``target`` is a manifold name OR a folder path. When it
605
+ resolves to an authored folder the fit runs as-is (no hyperparam knobs
606
+ allowed). When it resolves to a discover-mode folder (``pca`` /
607
+ ``spectral``) any supplied hyperparam override (``--method`` / ``--max-dim``
608
+ / ``--var-threshold`` / ``--k-nn`` / ``--bandwidth`` / ``--max-subspace-dim``)
609
+ is passed into the fit transaction, which updates ``manifold.json`` under
610
+ the same lock used to derive the cache key. Supplying overrides against an
611
+ authored folder is an error (mirrors the server's 400).
612
+ """
613
+ from drowse.io.manifolds import (
614
+ ManifoldFolder, ManifoldFormatError, domain_label,
615
+ )
616
+
617
+ _require_model(args)
618
+
619
+ # Resolve ``target`` to a folder. A path that exists on disk (or that
620
+ # carries a ``manifold.json``) is taken as an authored-folder path —
621
+ # ``manifold fit /path/to/folder``; otherwise it is a manifold *name*
622
+ # resolved cross-namespace the same way the lifecycle verbs resolve.
623
+ target = args.target
624
+ target_path = Path(target)
625
+ if target_path.is_dir() or (target_path / "manifold.json").exists():
626
+ folder = target_path
627
+ else:
628
+ folder = _resolve_manifold_folder(target)
629
+
630
+ if not (folder / "manifold.json").exists():
631
+ print(
632
+ f"manifold fit: no manifold.json in {folder}", file=sys.stderr,
633
+ )
634
+ sys.exit(2)
635
+
636
+ # Load the folder to learn its fit_mode before paying for a model load.
637
+ try:
638
+ mf = ManifoldFolder.load(folder, verify_manifest=False)
639
+ except ManifoldFormatError as e:
640
+ print(f"manifold fit: {e}", file=sys.stderr)
641
+ sys.exit(2)
642
+
643
+ # Did the user supply any discover-mode hyperparam override?
644
+ override_supplied = any(
645
+ getattr(args, attr, None) is not None
646
+ for attr in (
647
+ "method", "max_dim", "min_dim", "var_threshold", "k_nn",
648
+ "bandwidth", "max_subspace_dim", "smoothing",
649
+ "persistence_frac",
650
+ )
651
+ )
652
+
653
+ requested_fit_mode: str | None = None
654
+ requested_hyperparams: dict[str, object] | None = None
655
+ if override_supplied:
656
+ if not mf.is_discover:
657
+ # Mirror the server's 400: hyperparam overrides are discover-only.
658
+ print(
659
+ f"manifold fit: fit_mode/hyperparams overrides are "
660
+ f"discover-mode only; {folder} is authored",
661
+ file=sys.stderr,
662
+ )
663
+ sys.exit(2)
664
+ requested_fit_mode = args.method
665
+ if requested_fit_mode is not None and requested_fit_mode not in {
666
+ "pca", "spectral", "auto",
667
+ }:
668
+ print(
669
+ f"manifold fit: invalid method {requested_fit_mode!r}",
670
+ file=sys.stderr,
671
+ )
672
+ sys.exit(2)
673
+ requested_hyperparams = {}
674
+ # PCA knobs.
675
+ if args.max_dim is not None:
676
+ requested_hyperparams["max_dim"] = int(args.max_dim)
677
+ if args.var_threshold is not None:
678
+ requested_hyperparams["var_threshold"] = float(args.var_threshold)
679
+ # Spectral knobs.
680
+ if getattr(args, "min_dim", None) is not None:
681
+ requested_hyperparams["min_dim"] = int(args.min_dim)
682
+ if args.k_nn is not None:
683
+ requested_hyperparams["k_nn"] = int(args.k_nn)
684
+ if args.bandwidth is not None:
685
+ requested_hyperparams["bandwidth"] = float(args.bandwidth)
686
+ # Spectral-only knob. The exact-mode sanitizer rejects it for PCA (a
687
+ # flat fit's per-layer subspace dim is its layout dim, capped by
688
+ # ``--max-dim``, not a separate knob).
689
+ if getattr(args, "max_subspace_dim", None) is not None:
690
+ requested_hyperparams["max_subspace_dim"] = int(
691
+ args.max_subspace_dim,
692
+ )
693
+ # Curved-fit smoothing (spectral/auto): "auto" → GCV, else a float λ.
694
+ if getattr(args, "smoothing", None) is not None:
695
+ s = args.smoothing
696
+ requested_hyperparams["smoothing"] = (
697
+ s if s == "auto" else float(s)
698
+ )
699
+ # Auto-only: periodic-detection persistence threshold.
700
+ if getattr(args, "persistence_frac", None) is not None:
701
+ requested_hyperparams["persistence_frac"] = float(
702
+ args.persistence_frac,
703
+ )
704
+
705
+ # Weight-free no-op: if every component of the fit's cache key can be
706
+ # proven off-model, the model load (minutes on a cold cache) buys nothing.
707
+ # An override patch is deliberately not proven — it rewrites
708
+ # ``manifold.json`` inside the fit's own lock, so the on-disk hash the
709
+ # preflight can see is not the one the fit would compare against.
710
+ if not bool(getattr(args, "force", False)):
711
+ proof = _try_manifold_fit_noop_preflight(
712
+ args, folder,
713
+ sae=getattr(args, "sae", None),
714
+ fit_mode=requested_fit_mode,
715
+ hyperparams=requested_hyperparams,
716
+ )
717
+ if proof is not None:
718
+ print(
719
+ f"fitted manifold '{proof.manifold_name}' "
720
+ f"({len(proof.fitted_layers)} layers, "
721
+ f"{len(proof.node_labels)} nodes, {proof.fit_mode})"
722
+ )
723
+ print(
724
+ "Already fitted for this corpus and exact model source "
725
+ "— nothing to do."
726
+ )
727
+ print(f"Artifact: {proof.tensor_path}")
728
+ return
729
+
730
+ _pkg._print_startup(args)
731
+ session = _pkg._make_session(args, load_probes=False)
732
+ _pkg._print_model_info(session)
733
+ try:
734
+ manifold = session.fit(
735
+ folder,
736
+ sae=getattr(args, "sae", None),
737
+ layers=getattr(args, "layers", None),
738
+ fit_mode=requested_fit_mode,
739
+ hyperparams=requested_hyperparams,
740
+ force=bool(getattr(args, "force", False)),
741
+ on_progress=lambda m: print(f" {m}", flush=True),
742
+ )
743
+ except (ValueError, ManifoldFormatError) as e:
744
+ print(f"manifold fit failed: {e}", file=sys.stderr)
745
+ sys.exit(1)
746
+ except Exception as e:
747
+ print(f"manifold fit failed: {e}", file=sys.stderr)
748
+ sys.exit(1)
749
+ fitted_mode = getattr(manifold, "metadata", {}).get("fit_mode", mf.fit_mode)
750
+ tail = f", fit_mode={fitted_mode}" if mf.is_discover else ""
751
+ print(
752
+ f"fitted manifold '{manifold.name}' "
753
+ f"({len(manifold.layers)} layers, {len(manifold.node_labels)} nodes, "
754
+ f"{domain_label(manifold.domain.to_spec())}, "
755
+ f"{manifold.feature_space}{tail})"
756
+ )
757
+
758
+
759
+ def _run_manifold_generate(args: argparse.Namespace) -> None:
760
+ """``drowse manifold generate`` -- author + LLM-fill a discover folder (A2).
761
+
762
+ Two-step end-to-end: load the model, run :meth:`DrowseSession.generate_responses`
763
+ to fill each node's conversational corpus (in-character responses to the
764
+ shared baseline prompts), then leave the folder ready for ``manifold
765
+ discover`` to fit. The two-step split keeps failure modes legible (a flaky
766
+ generation leaves inspectable corpora) and lets the user review before
767
+ paying for the fit.
768
+ """
769
+ from drowse.io.manifolds import (
770
+ ManifoldFormatError,
771
+ append_discover_manifold_node,
772
+ plan_discover_generation,
773
+ )
774
+ from drowse.io.paths import manifold_dir
775
+
776
+ _require_model(args)
777
+ if args.kind == "custom" and not getattr(args, "custom_system", None):
778
+ print(
779
+ "manifold generate: --kind custom requires --system "
780
+ '(a template with a {c} placeholder, e.g. "You are the month of '
781
+ '{c}; speak as that month.")',
782
+ file=sys.stderr,
783
+ )
784
+ sys.exit(2)
785
+ if len(args.concepts) < 2:
786
+ print(
787
+ "manifold generate: need >= 2 concepts (a discover manifold is "
788
+ "meaningless with one node)",
789
+ file=sys.stderr,
790
+ )
791
+ sys.exit(2)
792
+
793
+ namespace = "local"
794
+ name = args.name
795
+ if "/" in name:
796
+ namespace, name = name.split("/", 1)
797
+
798
+ folder = manifold_dir(namespace, name)
799
+ # ``--role-per-node``: the concept slug doubles as that node's assistant-role
800
+ # substitution -- a persona manifold pooled in role-baselined space (the
801
+ # explicit role overrides the kind-derived elicitation label at both
802
+ # generation and capture). Otherwise the node\'s ``kind`` drives a
803
+ # generation-only elicitation role and capture stays standard (swap-back).
804
+ node_roles: dict[str, str | None] | None = None
805
+ if getattr(args, "role_per_node", False):
806
+ node_roles = {concept: concept for concept in args.concepts}
807
+ node_kinds: dict[str, str | None] = {c: args.kind for c in args.concepts}
808
+
809
+ # Plan first -- no model load needed to learn there is nothing to do.
810
+ try:
811
+ plan = plan_discover_generation(
812
+ folder, name, args.description,
813
+ fit_mode="pca", labels=list(args.concepts),
814
+ node_roles=node_roles, node_kinds=node_kinds,
815
+ force=args.force,
816
+ )
817
+ except ManifoldFormatError as e:
818
+ print(f"manifold generate failed: {e}", file=sys.stderr)
819
+ sys.exit(1)
820
+
821
+ n_total = len(plan.index_of)
822
+ if not plan.pending:
823
+ print(
824
+ f"manifold {namespace}/{name} already complete ({n_total} nodes)"
825
+ f" -- pass -f/--force to regenerate"
826
+ )
827
+ return
828
+ if plan.resumed and len(plan.pending) < n_total:
829
+ print(
830
+ f"resuming {namespace}/{name}: "
831
+ f"{n_total - len(plan.pending)}/{n_total} nodes present, "
832
+ f"generating {len(plan.pending)}"
833
+ )
834
+ if plan.added:
835
+ print(f"adding {len(plan.added)} new node(s): {', '.join(plan.added)}")
836
+
837
+ _pkg._print_startup(args)
838
+ session = _pkg._make_session(args)
839
+ _pkg._print_model_info(session)
840
+
841
+ print(
842
+ f"generating {args.samples_per_prompt} response(s) per baseline prompt "
843
+ f"for {len(plan.pending)} concept(s)..."
844
+ )
845
+ try:
846
+ for concept in plan.pending:
847
+ gen_roles: dict[str, str | None] | None = (
848
+ {concept: concept} if node_roles else None
849
+ )
850
+ corpora = session.generate_responses(
851
+ [concept], [args.kind],
852
+ roles=gen_roles,
853
+ custom_system=getattr(args, "custom_system", None),
854
+ samples_per_prompt=args.samples_per_prompt,
855
+ on_progress=lambda m: print(f" {m}", flush=True),
856
+ )
857
+ append_discover_manifold_node(
858
+ folder, plan.index_of[concept], concept, corpora[concept],
859
+ )
860
+ except (ValueError, RuntimeError) as e:
861
+ print(f"manifold generate failed: {e}", file=sys.stderr)
862
+ sys.exit(1)
863
+
864
+ print(f"wrote {namespace}/{name} ({n_total} nodes)")
865
+ print(f" -> run `drowse manifold fit {namespace}/{name}` to fit")
866
+
867
+
868
+ def _run_manifold_from_template(args: argparse.Namespace) -> None:
869
+ """``drowse manifold from-template`` — author a discover manifold from a template.
870
+
871
+ Pure-IO (no model): resolves the standalone template, expands its values x
872
+ contexts into per-value node corpora, and writes a discover folder that
873
+ stores the corpus + ``template_ref``. Fit it next with
874
+ ``drowse manifold fit <name> -m MODEL``.
875
+ """
876
+ from drowse.io.manifolds import ManifoldFormatError, create_manifold_from_template
877
+ from drowse.io.templates import (
878
+ AmbiguousTemplateError, TemplateNotFoundError, resolve_template,
879
+ )
880
+
881
+ try:
882
+ tmpl = resolve_template(args.template)
883
+ except (TemplateNotFoundError, AmbiguousTemplateError) as e:
884
+ print(f"manifold from-template: {e}", file=sys.stderr)
885
+ sys.exit(1)
886
+ ref = f"{tmpl.path.parent.name}/{tmpl.name}" if tmpl.path else tmpl.name
887
+ namespace, name = _split_manifold_ns_name(args.name or tmpl.name)
888
+
889
+ hyperparams: dict[str, object] = {}
890
+ if args.max_dim is not None:
891
+ hyperparams["max_dim"] = args.max_dim
892
+ if args.var_threshold is not None:
893
+ hyperparams["var_threshold"] = args.var_threshold
894
+
895
+ try:
896
+ create_manifold_from_template(
897
+ namespace, name, args.description,
898
+ template_ref=ref,
899
+ fit_mode=args.fit_mode,
900
+ hyperparams=hyperparams or None,
901
+ force=args.force,
902
+ )
903
+ except FileExistsError:
904
+ print(
905
+ f"manifold from-template: {namespace}/{name} already exists "
906
+ f"-- pass -f/--force to overwrite",
907
+ file=sys.stderr,
908
+ )
909
+ sys.exit(1)
910
+ except ManifoldFormatError as e:
911
+ print(f"manifold from-template failed: {e}", file=sys.stderr)
912
+ sys.exit(1)
913
+
914
+ print(
915
+ f"wrote {namespace}/{name} ({len(tmpl.values)} nodes x "
916
+ f"{len(tmpl.contexts)} contexts, template_ref={ref}, "
917
+ f"fit_mode={args.fit_mode})"
918
+ )
919
+ print(f" -> run `drowse manifold fit {namespace}/{name} -m MODEL` to fit")
920
+
921
+
922
+ def _run_manifold_merge(args: argparse.Namespace) -> None:
923
+ from drowse.io.manifolds import (
924
+ ManifoldFormatError, merge_discover_manifolds,
925
+ )
926
+
927
+ target_ns, target_name = _split_manifold_ns_name(args.name)
928
+ sources = [_split_manifold_ns_name(s) for s in args.sources]
929
+ if len(sources) < 2:
930
+ print(
931
+ "manifold merge: need >= 2 sources (union of one manifold is a no-op)",
932
+ file=sys.stderr,
933
+ )
934
+ sys.exit(2)
935
+ try:
936
+ dst = merge_discover_manifolds(
937
+ target_ns, target_name, args.description,
938
+ sources=sources,
939
+ fit_mode=args.method, # parser dest unified to ``method`` (matches discover)
940
+ force=args.force,
941
+ )
942
+ except (FileNotFoundError, FileExistsError, ManifoldFormatError, ValueError) as e:
943
+ print(f"manifold merge failed: {e}", file=sys.stderr)
944
+ sys.exit(1)
945
+ print(f"Merged manifold written to {dst}")
946
+ print(
947
+ f" -> run `drowse manifold fit {target_ns}/{target_name}` to fit"
948
+ )
949
+
950
+
951
+ def _median(values: "Iterable[float]") -> float:
952
+ """Median of ``values``; ``0.0`` for an empty iterable.
953
+
954
+ Summarizes the per-layer Procrustes alignment qualities into the single
955
+ ``transfer_quality_estimate`` the transferred sidecar records.
956
+ """
957
+ ordered = sorted(float(v) for v in values)
958
+ n = len(ordered)
959
+ if n == 0:
960
+ return 0.0
961
+ mid = n // 2
962
+ if n % 2 == 1:
963
+ return ordered[mid]
964
+ return 0.5 * (ordered[mid - 1] + ordered[mid])
965
+
966
+
967
+ def _run_manifold_transfer(args: argparse.Namespace) -> None:
968
+ """Cross-model manifold transfer via Procrustes.
969
+
970
+ Resolve the manifold folder, fit (or load) the per-layer Procrustes
971
+ alignment between the source and target models' cached neutral activations
972
+ — the part that needs both models loaded — then hand the prebuilt alignment
973
+ dict to :func:`drowse.io.manifolds.transfer_manifold`, which is pure-io and
974
+ only *applies* the map. Steering vectors transfer the same way (a vector is
975
+ the K=2 case of a flat ``pca`` manifold).
976
+ """
977
+ import json as _json
978
+
979
+ from drowse.io.manifolds import (
980
+ ManifoldFormatError, preflight_transfer_manifold, transfer_manifold,
981
+ )
982
+ from drowse.io.paths import encode_release_id, manifold_dir
983
+
984
+ ns, name = _resolve_manifold_ns_name(args.name)
985
+ folder = manifold_dir(ns, name)
986
+ if not (folder / "manifold.json").exists():
987
+ print(
988
+ f"manifold transfer: {ns}/{name} not found at {folder}",
989
+ file=sys.stderr,
990
+ )
991
+ sys.exit(1)
992
+
993
+ try:
994
+ source_proof = preflight_transfer_manifold(
995
+ folder, from_model=args.src_model, to_model=args.tgt_model,
996
+ force=args.force,
997
+ )
998
+ except (FileNotFoundError, FileExistsError, ManifoldFormatError) as e:
999
+ print(f"manifold transfer failed: {e}", file=sys.stderr)
1000
+ sys.exit(1)
1001
+ requested_alignment_layers = (
1002
+ list(source_proof.layers) if source_proof is not None else None
1003
+ )
1004
+
1005
+ # Alignment construction also returns the identity-matched target
1006
+ # whitener. On a cold/stale fit it is built directly from the target
1007
+ # activations already resident for Procrustes; an exact model-free repeat
1008
+ # uses the offline cache loader. Either path reads the target neutral
1009
+ # artifact once for this operation.
1010
+ from drowse.core.mahalanobis import WhitenerError
1011
+
1012
+ try:
1013
+ (
1014
+ M, quality_per_layer, _, source_identity, target_identity,
1015
+ target_whitener, target_layer_means,
1016
+ ) = _pkg._load_or_fit_transfer_alignment(
1017
+ args.src_model, args.tgt_model, force=args.force,
1018
+ label="manifold transfer",
1019
+ requested_layers=requested_alignment_layers,
1020
+ )
1021
+ except WhitenerError as e:
1022
+ print(f"manifold transfer failed: {e}", file=sys.stderr)
1023
+ sys.exit(1)
1024
+
1025
+ median_quality = _median(quality_per_layer.values()) if quality_per_layer else None
1026
+
1027
+ try:
1028
+ out_path = transfer_manifold(
1029
+ folder,
1030
+ from_model=args.src_model,
1031
+ to_model=args.tgt_model,
1032
+ alignment=M,
1033
+ transfer_quality_estimate=median_quality,
1034
+ source_model_fingerprint=source_identity["model_fingerprint"],
1035
+ target_model_fingerprint=target_identity["model_fingerprint"],
1036
+ whitener=target_whitener,
1037
+ target_layer_means=target_layer_means,
1038
+ force=args.force,
1039
+ expected_source_proof=source_proof,
1040
+ )
1041
+ except (FileNotFoundError, FileExistsError, ManifoldFormatError) as e:
1042
+ print(f"manifold transfer failed: {e}", file=sys.stderr)
1043
+ sys.exit(1)
1044
+
1045
+ payload = {
1046
+ "namespace": ns,
1047
+ "name": name,
1048
+ "source_model": args.src_model,
1049
+ "target_model": args.tgt_model,
1050
+ "tensor": str(out_path),
1051
+ "transferred_layers": sorted(M.keys()),
1052
+ "median_transfer_quality": (
1053
+ round(median_quality, 4) if median_quality is not None else None
1054
+ ),
1055
+ }
1056
+ if args.json_output:
1057
+ print(_json.dumps(payload, indent=2))
1058
+ return
1059
+
1060
+ quality_str = f"{median_quality:.3f}" if median_quality is not None else "n/a"
1061
+ print(
1062
+ f"Transferred manifold {ns}/{name} "
1063
+ f"from {args.src_model} -> {args.tgt_model}\n"
1064
+ f" layers: {len(M)} shared\n"
1065
+ f" median quality: {quality_str} (R^2 across shared layers)\n"
1066
+ f" tensor: {out_path}\n"
1067
+ f" variant suffix: :from-{encode_release_id(args.src_model)}"
1068
+ )
1069
+
1070
+
1071
+ # The nine steering-vector / manifold *compute* verbs (model-loading +
1072
+ # analysis). ``manifold transfer`` keeps its own runner (it was already a
1073
+ # manifold verb); the rest are the renamed former ``subspace`` verbs plus the
1074
+ # discover→fit fold.
1075
+ _MANIFOLD_RUNNERS = {
1076
+ "extract": _run_manifold_extract,
1077
+ "generate": _run_manifold_generate,
1078
+ "from-template": _run_manifold_from_template,
1079
+ "fit": _run_manifold_fit,
1080
+ "bake": _run_manifold_bake,
1081
+ "merge": _run_manifold_merge,
1082
+ "transfer": _run_manifold_transfer,
1083
+ "compare": _run_manifold_compare,
1084
+ "why": _run_manifold_why,
1085
+ }
1086
+
1087
+
1088
+ @_drowse_error_exit
1089
+ def _run_manifold(args: argparse.Namespace) -> None:
1090
+ """Dispatch ``drowse manifold <verb>`` (the compute verbs)."""
1091
+ cmd = getattr(args, "manifold_cmd", None)
1092
+ if cmd is None:
1093
+ _print_verb_menu("manifold", _MANIFOLD_VERBS)
1094
+ sys.exit(0)
1095
+ # Every verb is a registered subparser, so argparse rejects an unknown
1096
+ # one with its own "invalid choice" error before dispatch gets here.
1097
+ _MANIFOLD_RUNNERS[cmd](args)