solara-ui 1.31.0__py2.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 (439) hide show
  1. prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  2. prefix/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  3. solara/__init__.py +124 -0
  4. solara/__main__.py +734 -0
  5. solara/alias.py +6 -0
  6. solara/autorouting.py +546 -0
  7. solara/cache.py +303 -0
  8. solara/checks.html +71 -0
  9. solara/checks.py +224 -0
  10. solara/comm.py +28 -0
  11. solara/components/__init__.py +59 -0
  12. solara/components/alert.py +155 -0
  13. solara/components/applayout.py +393 -0
  14. solara/components/button.py +85 -0
  15. solara/components/card.py +87 -0
  16. solara/components/checkbox.py +50 -0
  17. solara/components/code_highlight_css.py +11 -0
  18. solara/components/code_highlight_css.vue +63 -0
  19. solara/components/columns.py +159 -0
  20. solara/components/component_vue.py +110 -0
  21. solara/components/cross_filter.py +335 -0
  22. solara/components/dataframe.py +546 -0
  23. solara/components/datatable.py +221 -0
  24. solara/components/datatable.vue +175 -0
  25. solara/components/details.py +21 -0
  26. solara/components/download.vue +35 -0
  27. solara/components/echarts.py +75 -0
  28. solara/components/echarts.vue +128 -0
  29. solara/components/figure_altair.py +39 -0
  30. solara/components/file_browser.py +182 -0
  31. solara/components/file_download.py +199 -0
  32. solara/components/file_drop.py +139 -0
  33. solara/components/file_drop.vue +83 -0
  34. solara/components/file_list_widget.vue +78 -0
  35. solara/components/head.py +27 -0
  36. solara/components/head_tag.py +49 -0
  37. solara/components/head_tag.vue +60 -0
  38. solara/components/image.py +173 -0
  39. solara/components/input.py +436 -0
  40. solara/components/link.py +55 -0
  41. solara/components/markdown.py +378 -0
  42. solara/components/markdown_editor.py +25 -0
  43. solara/components/markdown_editor.vue +362 -0
  44. solara/components/matplotlib.py +74 -0
  45. solara/components/meta.py +47 -0
  46. solara/components/misc.py +333 -0
  47. solara/components/pivot_table.py +258 -0
  48. solara/components/pivot_table.vue +158 -0
  49. solara/components/progress.py +47 -0
  50. solara/components/select.py +182 -0
  51. solara/components/select.vue +27 -0
  52. solara/components/slider.py +442 -0
  53. solara/components/slider_date.vue +56 -0
  54. solara/components/spinner-solara.vue +105 -0
  55. solara/components/spinner.py +30 -0
  56. solara/components/sql_code.py +33 -0
  57. solara/components/sql_code.vue +128 -0
  58. solara/components/style.py +105 -0
  59. solara/components/switch.py +68 -0
  60. solara/components/tab_navigation.py +37 -0
  61. solara/components/title.py +90 -0
  62. solara/components/title.vue +38 -0
  63. solara/components/togglebuttons.py +200 -0
  64. solara/components/tooltip.py +61 -0
  65. solara/datatypes.py +143 -0
  66. solara/express.py +241 -0
  67. solara/hooks/__init__.py +4 -0
  68. solara/hooks/dataframe.py +99 -0
  69. solara/hooks/misc.py +263 -0
  70. solara/hooks/use_reactive.py +129 -0
  71. solara/hooks/use_thread.py +129 -0
  72. solara/kitchensink.py +8 -0
  73. solara/lab/__init__.py +34 -0
  74. solara/lab/components/__init__.py +6 -0
  75. solara/lab/components/chat.py +203 -0
  76. solara/lab/components/confirmation_dialog.py +163 -0
  77. solara/lab/components/cross_filter.py +7 -0
  78. solara/lab/components/input_date.py +298 -0
  79. solara/lab/components/menu.py +181 -0
  80. solara/lab/components/menu.vue +38 -0
  81. solara/lab/components/tabs.py +274 -0
  82. solara/lab/components/theming.py +98 -0
  83. solara/lab/components/theming.vue +72 -0
  84. solara/lab/hooks/__init__.py +0 -0
  85. solara/lab/hooks/dataframe.py +12 -0
  86. solara/lab/toestand.py +3 -0
  87. solara/lab/utils/__init__.py +2 -0
  88. solara/lab/utils/cookies.py +5 -0
  89. solara/lab/utils/dataframe.py +115 -0
  90. solara/lab/utils/headers.py +5 -0
  91. solara/layout.py +44 -0
  92. solara/lifecycle.py +46 -0
  93. solara/minisettings.py +133 -0
  94. solara/py.typed +0 -0
  95. solara/reactive.py +93 -0
  96. solara/routing.py +268 -0
  97. solara/scope/__init__.py +88 -0
  98. solara/scope/types.py +55 -0
  99. solara/server/__init__.py +0 -0
  100. solara/server/app.py +491 -0
  101. solara/server/assets/custom.css +1 -0
  102. solara/server/assets/custom.js +1 -0
  103. solara/server/assets/favicon.png +0 -0
  104. solara/server/assets/favicon.svg +5 -0
  105. solara/server/assets/style.css +1665 -0
  106. solara/server/assets/theme-dark.css +437 -0
  107. solara/server/assets/theme-light.css +420 -0
  108. solara/server/assets/theme.js +3 -0
  109. solara/server/cdn_helper.py +77 -0
  110. solara/server/esm.py +69 -0
  111. solara/server/fastapi.py +5 -0
  112. solara/server/flask.py +286 -0
  113. solara/server/jupyter/__init__.py +2 -0
  114. solara/server/jupyter/cdn_handler.py +28 -0
  115. solara/server/jupyter/server_extension.py +29 -0
  116. solara/server/jupytertools.py +46 -0
  117. solara/server/kernel.py +338 -0
  118. solara/server/kernel_context.py +357 -0
  119. solara/server/patch.py +552 -0
  120. solara/server/reload.py +242 -0
  121. solara/server/server.py +456 -0
  122. solara/server/settings.py +215 -0
  123. solara/server/shell.py +251 -0
  124. solara/server/starlette.py +601 -0
  125. solara/server/static/ansi.js +270 -0
  126. solara/server/static/highlight-dark.css +82 -0
  127. solara/server/static/highlight.css +43 -0
  128. solara/server/static/main-vuetify.js +260 -0
  129. solara/server/static/main.js +163 -0
  130. solara/server/static/solara_bootstrap.py +129 -0
  131. solara/server/static/sun.svg +23 -0
  132. solara/server/static/webworker.js +42 -0
  133. solara/server/telemetry.py +212 -0
  134. solara/server/templates/index.html.j2 +1 -0
  135. solara/server/templates/loader-plain.css +11 -0
  136. solara/server/templates/loader-plain.html +20 -0
  137. solara/server/templates/loader-solara.css +111 -0
  138. solara/server/templates/loader-solara.html +40 -0
  139. solara/server/templates/plain.html +82 -0
  140. solara/server/templates/solara.html.j2 +446 -0
  141. solara/server/threaded.py +75 -0
  142. solara/server/utils.py +30 -0
  143. solara/server/websocket.py +45 -0
  144. solara/settings.py +56 -0
  145. solara/tasks.py +837 -0
  146. solara/template/button.py +16 -0
  147. solara/template/markdown.py +42 -0
  148. solara/template/portal/.flake8 +6 -0
  149. solara/template/portal/.pre-commit-config.yaml +28 -0
  150. solara/template/portal/LICENSE +21 -0
  151. solara/template/portal/Procfile +7 -0
  152. solara/template/portal/mypy.ini +3 -0
  153. solara/template/portal/pyproject.toml +26 -0
  154. solara/template/portal/solara_portal/__init__.py +4 -0
  155. solara/template/portal/solara_portal/components/__init__.py +2 -0
  156. solara/template/portal/solara_portal/components/article.py +28 -0
  157. solara/template/portal/solara_portal/components/data.py +28 -0
  158. solara/template/portal/solara_portal/components/header.py +6 -0
  159. solara/template/portal/solara_portal/components/layout.py +6 -0
  160. solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +85 -0
  161. solara/template/portal/solara_portal/content/articles/substiterat-vati.md +70 -0
  162. solara/template/portal/solara_portal/data.py +60 -0
  163. solara/template/portal/solara_portal/pages/__init__.py +67 -0
  164. solara/template/portal/solara_portal/pages/article/__init__.py +26 -0
  165. solara/template/portal/solara_portal/pages/tabular.py +29 -0
  166. solara/template/portal/solara_portal/pages/viz/__init__.py +70 -0
  167. solara/template/portal/solara_portal/pages/viz/overview.py +14 -0
  168. solara/test/__init__.py +0 -0
  169. solara/test/pytest_plugin.py +697 -0
  170. solara/toestand.py +772 -0
  171. solara/util.py +308 -0
  172. solara/website/__init__.py +0 -0
  173. solara/website/assets/custom.css +468 -0
  174. solara/website/assets/images/logo-small.png +0 -0
  175. solara/website/assets/images/logo.svg +17 -0
  176. solara/website/assets/images/logo_white.svg +50 -0
  177. solara/website/assets/theme.js +8 -0
  178. solara/website/components/__init__.py +5 -0
  179. solara/website/components/algolia.vue +24 -0
  180. solara/website/components/algolia_api.vue +187 -0
  181. solara/website/components/docs.py +118 -0
  182. solara/website/components/header.py +72 -0
  183. solara/website/components/hero.py +15 -0
  184. solara/website/components/mailchimp.py +12 -0
  185. solara/website/components/mailchimp.vue +47 -0
  186. solara/website/components/markdown.py +30 -0
  187. solara/website/components/notebook.py +171 -0
  188. solara/website/pages/__init__.py +575 -0
  189. solara/website/pages/apps/__init__.py +16 -0
  190. solara/website/pages/apps/authorization/__init__.py +119 -0
  191. solara/website/pages/apps/authorization/admin.py +12 -0
  192. solara/website/pages/apps/authorization/users.py +12 -0
  193. solara/website/pages/apps/jupyter-dashboard-1.py +116 -0
  194. solara/website/pages/apps/layout-demo.py +40 -0
  195. solara/website/pages/apps/multipage/__init__.py +38 -0
  196. solara/website/pages/apps/multipage/page1.py +26 -0
  197. solara/website/pages/apps/multipage/page2.py +34 -0
  198. solara/website/pages/apps/scatter.py +136 -0
  199. solara/website/pages/apps/scrolling.py +63 -0
  200. solara/website/pages/apps/tutorial-streamlit.py +18 -0
  201. solara/website/pages/changelog/__init__.py +8 -0
  202. solara/website/pages/changelog/changelog.md +204 -0
  203. solara/website/pages/contact/__init__.py +8 -0
  204. solara/website/pages/contact/contact.md +17 -0
  205. solara/website/pages/doc_use_download.py +85 -0
  206. solara/website/pages/documentation/__init__.py +184 -0
  207. solara/website/pages/documentation/advanced/__init__.py +9 -0
  208. solara/website/pages/documentation/advanced/content/00-overview.md +1 -0
  209. solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +6 -0
  210. solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +196 -0
  211. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +125 -0
  212. solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +162 -0
  213. solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +69 -0
  214. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +49 -0
  215. solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +124 -0
  216. solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +3 -0
  217. solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +31 -0
  218. solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +36 -0
  219. solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +59 -0
  220. solara/website/pages/documentation/advanced/content/15-reference/70-search.md +34 -0
  221. solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +34 -0
  222. solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +7 -0
  223. solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +148 -0
  224. solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +10 -0
  225. solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +35 -0
  226. solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +42 -0
  227. solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +28 -0
  228. solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +108 -0
  229. solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +23 -0
  230. solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +7 -0
  231. solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +166 -0
  232. solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +18 -0
  233. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +240 -0
  234. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +97 -0
  235. solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +12 -0
  236. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -0
  237. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +171 -0
  238. solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
  239. solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +45 -0
  240. solara/website/pages/documentation/advanced/content/40-development/10-setup.md +76 -0
  241. solara/website/pages/documentation/api/__init__.py +19 -0
  242. solara/website/pages/documentation/api/cross_filter/__init__.py +9 -0
  243. solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +23 -0
  244. solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +22 -0
  245. solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +22 -0
  246. solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +22 -0
  247. solara/website/pages/documentation/api/hooks/__init__.py +9 -0
  248. solara/website/pages/documentation/api/hooks/use_cross_filter.py +25 -0
  249. solara/website/pages/documentation/api/hooks/use_dark_effective.py +12 -0
  250. solara/website/pages/documentation/api/hooks/use_effect.md +43 -0
  251. solara/website/pages/documentation/api/hooks/use_effect.py +9 -0
  252. solara/website/pages/documentation/api/hooks/use_exception.py +33 -0
  253. solara/website/pages/documentation/api/hooks/use_memo.md +16 -0
  254. solara/website/pages/documentation/api/hooks/use_memo.py +9 -0
  255. solara/website/pages/documentation/api/hooks/use_previous.py +33 -0
  256. solara/website/pages/documentation/api/hooks/use_reactive.py +16 -0
  257. solara/website/pages/documentation/api/hooks/use_state.py +10 -0
  258. solara/website/pages/documentation/api/hooks/use_state_or_update.py +69 -0
  259. solara/website/pages/documentation/api/hooks/use_thread.md +58 -0
  260. solara/website/pages/documentation/api/hooks/use_thread.py +44 -0
  261. solara/website/pages/documentation/api/hooks/use_trait_observe.py +12 -0
  262. solara/website/pages/documentation/api/routing/__init__.py +9 -0
  263. solara/website/pages/documentation/api/routing/generate_routes.py +10 -0
  264. solara/website/pages/documentation/api/routing/generate_routes_directory.py +10 -0
  265. solara/website/pages/documentation/api/routing/resolve_path.py +35 -0
  266. solara/website/pages/documentation/api/routing/route.py +31 -0
  267. solara/website/pages/documentation/api/routing/use_route.py +80 -0
  268. solara/website/pages/documentation/api/routing/use_router.py +16 -0
  269. solara/website/pages/documentation/api/utilities/__init__.py +9 -0
  270. solara/website/pages/documentation/api/utilities/component_vue.py +10 -0
  271. solara/website/pages/documentation/api/utilities/computed.py +16 -0
  272. solara/website/pages/documentation/api/utilities/display.py +16 -0
  273. solara/website/pages/documentation/api/utilities/get_kernel_id.py +16 -0
  274. solara/website/pages/documentation/api/utilities/get_session_id.py +16 -0
  275. solara/website/pages/documentation/api/utilities/memoize.py +35 -0
  276. solara/website/pages/documentation/api/utilities/on_kernel_start.py +27 -0
  277. solara/website/pages/documentation/api/utilities/reactive.py +16 -0
  278. solara/website/pages/documentation/api/utilities/widget.py +104 -0
  279. solara/website/pages/documentation/components/__init__.py +12 -0
  280. solara/website/pages/documentation/components/advanced/__init__.py +9 -0
  281. solara/website/pages/documentation/components/advanced/link.py +27 -0
  282. solara/website/pages/documentation/components/advanced/meta.py +20 -0
  283. solara/website/pages/documentation/components/advanced/style.py +45 -0
  284. solara/website/pages/documentation/components/common.py +9 -0
  285. solara/website/pages/documentation/components/data/__init__.py +9 -0
  286. solara/website/pages/documentation/components/data/dataframe.py +44 -0
  287. solara/website/pages/documentation/components/data/pivot_table.py +81 -0
  288. solara/website/pages/documentation/components/enterprise/__init__.py +9 -0
  289. solara/website/pages/documentation/components/enterprise/avatar.py +24 -0
  290. solara/website/pages/documentation/components/enterprise/avatar_menu.py +25 -0
  291. solara/website/pages/documentation/components/input/__init__.py +9 -0
  292. solara/website/pages/documentation/components/input/button.py +23 -0
  293. solara/website/pages/documentation/components/input/checkbox.py +10 -0
  294. solara/website/pages/documentation/components/input/file_browser.py +32 -0
  295. solara/website/pages/documentation/components/input/file_drop.py +76 -0
  296. solara/website/pages/documentation/components/input/input.py +19 -0
  297. solara/website/pages/documentation/components/input/select.py +22 -0
  298. solara/website/pages/documentation/components/input/slider.py +29 -0
  299. solara/website/pages/documentation/components/input/switch.py +10 -0
  300. solara/website/pages/documentation/components/input/togglebuttons.py +21 -0
  301. solara/website/pages/documentation/components/lab/__init__.py +9 -0
  302. solara/website/pages/documentation/components/lab/chat.py +109 -0
  303. solara/website/pages/documentation/components/lab/confirmation_dialog.py +55 -0
  304. solara/website/pages/documentation/components/lab/cookies_headers.py +48 -0
  305. solara/website/pages/documentation/components/lab/input_date.py +20 -0
  306. solara/website/pages/documentation/components/lab/menu.py +22 -0
  307. solara/website/pages/documentation/components/lab/tab.py +25 -0
  308. solara/website/pages/documentation/components/lab/tabs.py +45 -0
  309. solara/website/pages/documentation/components/lab/task.py +11 -0
  310. solara/website/pages/documentation/components/lab/theming.py +72 -0
  311. solara/website/pages/documentation/components/lab/use_task.py +11 -0
  312. solara/website/pages/documentation/components/layout/__init__.py +9 -0
  313. solara/website/pages/documentation/components/layout/app_bar.py +16 -0
  314. solara/website/pages/documentation/components/layout/app_bar_title.py +16 -0
  315. solara/website/pages/documentation/components/layout/app_layout.py +24 -0
  316. solara/website/pages/documentation/components/layout/card.py +15 -0
  317. solara/website/pages/documentation/components/layout/card_actions.py +16 -0
  318. solara/website/pages/documentation/components/layout/column.py +30 -0
  319. solara/website/pages/documentation/components/layout/columns.py +27 -0
  320. solara/website/pages/documentation/components/layout/columns_responsive.py +68 -0
  321. solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
  322. solara/website/pages/documentation/components/layout/gridfixed.py +21 -0
  323. solara/website/pages/documentation/components/layout/hbox.py +18 -0
  324. solara/website/pages/documentation/components/layout/row.py +30 -0
  325. solara/website/pages/documentation/components/layout/sidebar.py +24 -0
  326. solara/website/pages/documentation/components/layout/vbox.py +19 -0
  327. solara/website/pages/documentation/components/output/__init__.py +9 -0
  328. solara/website/pages/documentation/components/output/file_download.py +11 -0
  329. solara/website/pages/documentation/components/output/html.py +21 -0
  330. solara/website/pages/documentation/components/output/image.py +11 -0
  331. solara/website/pages/documentation/components/output/markdown.py +57 -0
  332. solara/website/pages/documentation/components/output/markdown_editor.py +51 -0
  333. solara/website/pages/documentation/components/output/sql_code.py +85 -0
  334. solara/website/pages/documentation/components/output/tooltip.py +11 -0
  335. solara/website/pages/documentation/components/page/__init__.py +9 -0
  336. solara/website/pages/documentation/components/page/head.py +18 -0
  337. solara/website/pages/documentation/components/page/title.py +27 -0
  338. solara/website/pages/documentation/components/status/__init__.py +9 -0
  339. solara/website/pages/documentation/components/status/error.py +40 -0
  340. solara/website/pages/documentation/components/status/info.py +40 -0
  341. solara/website/pages/documentation/components/status/progress.py +10 -0
  342. solara/website/pages/documentation/components/status/spinner.py +11 -0
  343. solara/website/pages/documentation/components/status/success.py +40 -0
  344. solara/website/pages/documentation/components/status/warning.py +47 -0
  345. solara/website/pages/documentation/components/viz/__init__.py +9 -0
  346. solara/website/pages/documentation/components/viz/altair.py +42 -0
  347. solara/website/pages/documentation/components/viz/echarts.py +75 -0
  348. solara/website/pages/documentation/components/viz/matplotlib.py +30 -0
  349. solara/website/pages/documentation/components/viz/plotly.py +63 -0
  350. solara/website/pages/documentation/components/viz/plotly_express.py +41 -0
  351. solara/website/pages/documentation/examples/__init__.py +52 -0
  352. solara/website/pages/documentation/examples/ai/__init__.py +11 -0
  353. solara/website/pages/documentation/examples/ai/chatbot.py +95 -0
  354. solara/website/pages/documentation/examples/ai/tokenizer.py +107 -0
  355. solara/website/pages/documentation/examples/basics/__init__.py +10 -0
  356. solara/website/pages/documentation/examples/basics/sine.py +28 -0
  357. solara/website/pages/documentation/examples/fullscreen/__init__.py +10 -0
  358. solara/website/pages/documentation/examples/fullscreen/authorization.py +3 -0
  359. solara/website/pages/documentation/examples/fullscreen/layout_demo.py +3 -0
  360. solara/website/pages/documentation/examples/fullscreen/multipage.py +3 -0
  361. solara/website/pages/documentation/examples/fullscreen/scatter.py +3 -0
  362. solara/website/pages/documentation/examples/fullscreen/scrolling.py +3 -0
  363. solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +3 -0
  364. solara/website/pages/documentation/examples/general/__init__.py +10 -0
  365. solara/website/pages/documentation/examples/general/custom_storage.py +70 -0
  366. solara/website/pages/documentation/examples/general/deploy_model.py +115 -0
  367. solara/website/pages/documentation/examples/general/live_update.py +38 -0
  368. solara/website/pages/documentation/examples/general/login_oauth.py +81 -0
  369. solara/website/pages/documentation/examples/general/mycard.vue +58 -0
  370. solara/website/pages/documentation/examples/general/pokemon_search.py +51 -0
  371. solara/website/pages/documentation/examples/general/vue_component.py +50 -0
  372. solara/website/pages/documentation/examples/ipycanvas.py +49 -0
  373. solara/website/pages/documentation/examples/libraries/__init__.py +10 -0
  374. solara/website/pages/documentation/examples/libraries/altair.py +64 -0
  375. solara/website/pages/documentation/examples/libraries/bqplot.py +39 -0
  376. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +33 -0
  377. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +66 -0
  378. solara/website/pages/documentation/examples/utilities/__init__.py +10 -0
  379. solara/website/pages/documentation/examples/utilities/calculator.py +157 -0
  380. solara/website/pages/documentation/examples/utilities/countdown_timer.py +64 -0
  381. solara/website/pages/documentation/examples/utilities/todo.py +196 -0
  382. solara/website/pages/documentation/examples/visualization/__init__.py +6 -0
  383. solara/website/pages/documentation/examples/visualization/annotator.py +69 -0
  384. solara/website/pages/documentation/examples/visualization/linked_views.py +84 -0
  385. solara/website/pages/documentation/examples/visualization/plotly.py +44 -0
  386. solara/website/pages/documentation/faq/__init__.py +12 -0
  387. solara/website/pages/documentation/faq/content/99-faq.md +76 -0
  388. solara/website/pages/documentation/getting_started/__init__.py +9 -0
  389. solara/website/pages/documentation/getting_started/content/00-quickstart.md +89 -0
  390. solara/website/pages/documentation/getting_started/content/01-introduction.md +125 -0
  391. solara/website/pages/documentation/getting_started/content/02-installing.md +134 -0
  392. solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +14 -0
  393. solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +13 -0
  394. solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +89 -0
  395. solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +124 -0
  396. solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +146 -0
  397. solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +144 -0
  398. solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +64 -0
  399. solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
  400. solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +445 -0
  401. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +1000 -0
  402. solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +11 -0
  403. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +223 -0
  404. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +88 -0
  405. solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +7 -0
  406. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +273 -0
  407. solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +80 -0
  408. solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +7 -0
  409. solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +26 -0
  410. solara/website/pages/docutils.py +38 -0
  411. solara/website/pages/showcase/__init__.py +105 -0
  412. solara/website/pages/showcase/domino_code_assist.py +60 -0
  413. solara/website/pages/showcase/planeto_tessa.py +19 -0
  414. solara/website/pages/showcase/solara_dev.py +54 -0
  415. solara/website/pages/showcase/solarathon_2023_team_2.py +22 -0
  416. solara/website/pages/showcase/solarathon_2023_team_4.py +22 -0
  417. solara/website/pages/showcase/solarathon_2023_team_5.py +23 -0
  418. solara/website/pages/showcase/solarathon_2023_team_6.py +34 -0
  419. solara/website/pages/showcase/wanderlust.py +27 -0
  420. solara/website/public/beach.jpeg +0 -0
  421. solara/website/public/logo.svg +6 -0
  422. solara/website/public/social/discord.svg +1 -0
  423. solara/website/public/social/github.svg +1 -0
  424. solara/website/public/social/twitter.svg +3 -0
  425. solara/website/public/success.html +25 -0
  426. solara/website/templates/index.html.j2 +117 -0
  427. solara/website/utils.py +51 -0
  428. solara/widgets/__init__.py +1 -0
  429. solara/widgets/vue/gridlayout.vue +110 -0
  430. solara/widgets/vue/html.vue +4 -0
  431. solara/widgets/vue/navigator.vue +104 -0
  432. solara/widgets/vue/vegalite.vue +115 -0
  433. solara/widgets/widgets.py +66 -0
  434. solara_ui-1.31.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  435. solara_ui-1.31.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  436. solara_ui-1.31.0.dist-info/METADATA +158 -0
  437. solara_ui-1.31.0.dist-info/RECORD +439 -0
  438. solara_ui-1.31.0.dist-info/WHEEL +5 -0
  439. solara_ui-1.31.0.dist-info/licenses/LICENSE +21 -0
solara/server/app.py ADDED
@@ -0,0 +1,491 @@
1
+ import dataclasses
2
+ import importlib.util
3
+ import logging
4
+ import os
5
+ import pickle
6
+ import sys
7
+ import threading
8
+ import traceback
9
+ import warnings
10
+ from enum import Enum
11
+ from pathlib import Path
12
+ from typing import Any, Dict, List, Optional, cast
13
+
14
+ import ipywidgets as widgets
15
+ import reacton
16
+ from reacton.core import Element, render
17
+
18
+ import solara
19
+ import solara.lifecycle
20
+ from solara.util import nested_get
21
+
22
+ from . import kernel_context, patch, reload, settings
23
+ from .kernel import Kernel
24
+ from .utils import pdb_guard
25
+
26
+ WebSocket = Any
27
+ apps: Dict[str, "AppScript"] = {}
28
+ thread_lock = threading.Lock()
29
+
30
+ logger = logging.getLogger("solara.server.app")
31
+
32
+ reload.reloader.start()
33
+
34
+
35
+ class AppType(str, Enum):
36
+ SCRIPT = "script"
37
+ NOTEBOOK = "notebook"
38
+ MODULE = "module"
39
+ DIRECTORY = "directory"
40
+
41
+
42
+ def display(*args, **kwargs):
43
+ print("display not implemented", args, kwargs) # noqa
44
+
45
+
46
+ class AppScript:
47
+ directory: Path
48
+ routes: List[solara.Route]
49
+
50
+ def __init__(self, name, default_app_name="Page"):
51
+ self.fullname = name
52
+ if reload.reloader.on_change:
53
+ raise RuntimeError("Previous reloader still had a on_change attached, no cleanup?")
54
+ reload.reloader.on_change = self.on_file_change
55
+
56
+ self.app_name = default_app_name
57
+ if ":" in self.fullname:
58
+ self.name, self.app_name = self.fullname.rsplit(":", 1)
59
+ if len(self.name) == 1: # a windows drive letter, restore
60
+ self.name = self.fullname
61
+ self.app_name = default_app_name
62
+ else:
63
+ self.name = name
64
+ self.path: Path = Path(self.name).resolve()
65
+ try:
66
+ context = kernel_context.get_current_context()
67
+ except RuntimeError:
68
+ context = None
69
+ if context is not None:
70
+ raise RuntimeError(f"We should not have an existing Solara app context when running an app for the first time: {context}")
71
+ dummy_kernel_context = kernel_context.create_dummy_context()
72
+ with dummy_kernel_context:
73
+ app = self._execute()
74
+
75
+ # We now ran the app, now we can check for patches that require heavy imports
76
+ patch.patch_heavy_imports()
77
+
78
+ self._first_execute_app = app
79
+ reload.reloader.root_path = self.directory
80
+ if self.type == AppType.MODULE:
81
+ package_name = self.name.split(".")[0]
82
+ mod = importlib.import_module(package_name)
83
+ if mod.__file__ is not None:
84
+ package_root_path = Path(mod.__file__).parent
85
+ reload.reloader.root_path = package_root_path
86
+ dummy_kernel_context.close()
87
+
88
+ def _execute(self):
89
+ logger.info("Executing %s", self.name)
90
+ app = None
91
+ routes: Optional[List[solara.Route]] = None
92
+
93
+ def add_path():
94
+ # this is not expected for modules, similar to `python script.py and python -m package.mymodule`
95
+ if self.type in [AppType.SCRIPT, AppType.NOTEBOOK]:
96
+ working_directory = str(self.path.parent)
97
+ if working_directory not in sys.path:
98
+ sys.path.insert(0, working_directory)
99
+
100
+ if self.path.is_dir():
101
+ self.type = AppType.DIRECTORY
102
+ # resolve the directory, because Path("file").parent.parent == "." != ".."
103
+ self.directory = self.path.resolve()
104
+ routes = solara.generate_routes_directory(self.path)
105
+
106
+ if any(name for name in sys.modules.keys() if name.startswith(self.name)):
107
+ logger.warn(
108
+ f"Directory {self.name} is also used as a package. This can cause modules to be loaded twice, and might "
109
+ "cause unexpected behavior. If you run solara from a different directory (e.g. the parent directory) you "
110
+ "can avoid this ambiguity."
111
+ )
112
+
113
+ elif self.name.endswith(".py"):
114
+ self.type = AppType.SCRIPT
115
+ add_path()
116
+ # manually add the script to the watcher
117
+ reload.reloader.watcher.add_file(self.path)
118
+ self.directory = self.path.parent.resolve()
119
+ initial_namespace = {
120
+ "__name__": "__main__",
121
+ }
122
+ with reload.reloader.watch():
123
+ routes = [solara.autorouting._generate_route_path(self.path, first=True, initial_namespace=initial_namespace)]
124
+ elif self.name.endswith(".ipynb"):
125
+ self.type = AppType.NOTEBOOK
126
+ add_path()
127
+ # manually add the notebook to the watcher
128
+ reload.reloader.watcher.add_file(self.path)
129
+ self.directory = self.path.parent.resolve()
130
+ with reload.reloader.watch():
131
+ routes = [solara.autorouting._generate_route_path(self.path, first=True)]
132
+ else:
133
+ # the module itself will be added by reloader
134
+ # automatically
135
+ with reload.reloader.watch():
136
+ self.type = AppType.MODULE
137
+ try:
138
+ spec = importlib.util.find_spec(self.name)
139
+ except ValueError:
140
+ if self.name not in sys.modules:
141
+ raise ImportError(f"Module {self.name} not found")
142
+ spec = importlib.util.spec_from_file_location(self.name, sys.modules[self.name].__file__)
143
+ if spec is None:
144
+ raise ImportError(f"Module {self.name} cannot be found")
145
+ assert spec is not None
146
+ if spec.origin is None:
147
+ raise ImportError(f"Module {self.name} cannot be found, or is a namespace package")
148
+ assert spec.origin is not None
149
+ self.path = Path(spec.origin)
150
+ self.directory = self.path.parent
151
+
152
+ mod = importlib.import_module(self.name)
153
+ routes = solara.generate_routes(mod)
154
+
155
+ app = solara.autorouting.RenderPage(self.app_name)
156
+
157
+ # when the root moduled defined routes, skip the enclosing route object
158
+ if len(routes) == 1 and routes[0].module and hasattr(routes[0].module, "routes"):
159
+ if routes[0].component:
160
+ warnings.warn(
161
+ f"{self.name} has a component defined, but you are also defining routes."
162
+ " To avoid confusing, consider renaming the {self.app_name} component."
163
+ )
164
+ routes = routes[0].children
165
+
166
+ if self.app_name != "Page":
167
+ # if we specified the app name, we replace the component
168
+ if len(routes) > 1:
169
+ raise ValueError(f"App {self.name} has multiple routes, but a default app name was given: {self.app_name}")
170
+ assert len(routes) == 1
171
+ component = nested_get(routes[0].module.__dict__, self.app_name, None)
172
+ routes = [dataclasses.replace(routes[0], component=component)]
173
+
174
+ if settings.ssg.build_path is None:
175
+ settings.ssg.build_path = self.directory.parent.resolve() / "build"
176
+
177
+ # auto enable search if search.json exists
178
+ search_index_file = self.directory.parent / "assets" / "search.json"
179
+ if search_index_file.exists():
180
+ settings.search.enabled = True
181
+
182
+ # this might be useful for development
183
+ # but requires reloading of react in solara itself
184
+ # for name, module in sys.modules.items():
185
+ # if name.startswith("reacton"):
186
+ # file = inspect.getfile(module)
187
+ # self.watcher.add_file(file)
188
+
189
+ # cgi vars: https://datatracker.ietf.org/doc/html/rfc3875
190
+ # we cannot set script name, because gunicorn uses it (and will crash)
191
+ # os.environ["SCRIPT_NAME"] = self.name
192
+ os.environ["PATH_TRANSLATED"] = str(self.path.resolve())
193
+
194
+ self.routes = routes
195
+
196
+ # this might be useful for development
197
+ # but requires reloading of react in solara itself
198
+ # for name, module in sys.modules.items():
199
+ # if name.startswith("reacton"):
200
+ # file = inspect.getfile(module)
201
+ # self.watcher.add_file(file)
202
+
203
+ # cgi vars: https://datatracker.ietf.org/doc/html/rfc3875
204
+ # we cannot set script name, because gunicorn uses it (and will crash)
205
+ # os.environ["SCRIPT_NAME"] = self.name
206
+ os.environ["PATH_TRANSLATED"] = str(self.path.resolve())
207
+ return app
208
+
209
+ def close(self):
210
+ reload.reloader.on_change = None
211
+ context_values = list(kernel_context.contexts.values())
212
+ kernel_context.contexts.clear()
213
+ for context in context_values:
214
+ context.close()
215
+
216
+ def run(self):
217
+ if reload.reloader.requires_reload or self._first_execute_app is None:
218
+ with thread_lock:
219
+ if reload.reloader.requires_reload or self._first_execute_app is None:
220
+ self._first_execute_app = None
221
+ self._first_execute_app = self._execute()
222
+ print("Re-executed app", self.name) # noqa
223
+ # We now ran the app again, might contain new imports
224
+ patch.patch_heavy_imports()
225
+
226
+ return self._first_execute_app
227
+
228
+ def on_file_change(self, name):
229
+ path = Path(name)
230
+ if path.suffix == ".vue":
231
+ logger.info("Vue file changed: %s", name)
232
+ template_content = path.read_text()
233
+ for context in list(kernel_context.contexts.values()):
234
+ with context:
235
+ for filepath, widget in context.templates.items():
236
+ if filepath == str(path):
237
+ widget.template = template_content
238
+ else:
239
+ logger.info("Reload requires due to change in module: %s", name)
240
+ self.reload()
241
+
242
+ def reload(self):
243
+ # if multiple files change in a short time, we want to do this
244
+ # not concurrently. Even better would be to do a debounce?
245
+ with thread_lock:
246
+ # TODO: clearing the type_counter is a bit of a hack
247
+ # and we should introduce reload 'hooks', so there is
248
+ # less interdependency between modules
249
+ import solara.lab.toestand
250
+
251
+ solara.lab.toestand.ConnectionStore._type_counter.clear()
252
+
253
+ # we need to remove callbacks that are added in the app code
254
+ # which will be re-executed after the reload and we do not
255
+ # want to keep executing the old ones.
256
+ for kc in solara.lifecycle._on_kernel_start_callbacks.copy():
257
+ callback, path, module, cleanup = kc
258
+ will_reload = False
259
+ if module is not None:
260
+ module_name = module.__name__
261
+ if module_name in reload.reloader.get_reload_module_names():
262
+ will_reload = True
263
+ elif path is not None:
264
+ if str(path.resolve()).startswith(str(self.directory)):
265
+ will_reload = True
266
+ else:
267
+ logger.warning(
268
+ "script %s is not in the same directory as the app %s but is using on_kernel_start, "
269
+ "this might lead to multiple entries, and might indicate a bug.",
270
+ path,
271
+ self.directory,
272
+ )
273
+
274
+ if will_reload:
275
+ logger.info("reload: Removing on_kernel_start callback: %s (since it will be added when reloaded)", callback)
276
+ cleanup()
277
+
278
+ context_values = list(kernel_context.contexts.values())
279
+ # save states into the context so the hot reload will
280
+ # keep the same state
281
+ for context in context_values:
282
+ render_context = cast(reacton.core._RenderContext, context.app_object)
283
+ if render_context:
284
+ with context:
285
+ # we save the state for when the app reruns, so we stay in the same state.
286
+ # (e.g. button clicks, chosen options etc)
287
+ # for instance a dataframe, needs to be pickled, because after the pandas
288
+ # module is reloaded, it's a different class type
289
+ logger.info("pickling state: %s", render_context.state_get())
290
+ try:
291
+ context.state = pickle.dumps(render_context.state_get())
292
+ except Exception as e:
293
+ logger.warning("Could not pickle state, next render the state will be lost: %s", e)
294
+ # clear/cleanup the render_context, so during reload we start
295
+ # from scratch
296
+ context.app_object = None
297
+ # we want to reuse the container
298
+ render_context.container = None
299
+ try:
300
+ render_context.close()
301
+ except Exception as e:
302
+ logger.exception("Could not close render context: %s", e)
303
+
304
+ # ask all contexts/users to reload
305
+ for context in context_values:
306
+ with context:
307
+ context.reload()
308
+
309
+
310
+ def _run_app(
311
+ app_state,
312
+ app_script: AppScript,
313
+ pathname: str,
314
+ render_context: reacton.core._RenderContext = None,
315
+ ):
316
+ # app.signal_hook_install()
317
+ main_object = app_script.run()
318
+ app_state = pickle.loads(app_state) if app_state is not None else None
319
+ if app_state:
320
+ logger.info("Restoring state: %r", app_state)
321
+
322
+ context = kernel_context.get_current_context()
323
+ container = context.container
324
+ if isinstance(main_object, widgets.Widget):
325
+ return main_object, render_context
326
+ elif isinstance(main_object, Element) or isinstance(main_object, reacton.core.Component):
327
+ if isinstance(main_object, Element):
328
+ children = [main_object]
329
+ else:
330
+ children = [main_object()]
331
+ solara_context = solara.RoutingProvider(children=children, routes=app_script.routes, pathname=pathname)
332
+ if render_context is None:
333
+ result = render(solara_context, container, handle_error=True, initial_state=app_state)
334
+ # support older versions of react
335
+ if isinstance(result, tuple):
336
+ container, render_context = result
337
+ else:
338
+ render_context = result
339
+ else:
340
+ if app_state:
341
+ render_context.state_set(render_context.context_root, app_state)
342
+ result = render_context.render(solara_context)
343
+ container = render_context.container
344
+ # return container, render_context
345
+ else:
346
+ extra = ""
347
+ dotted = []
348
+ for key, value in vars(main_object).items():
349
+ if isinstance(value, (Element, widgets.Widget)):
350
+ dotted.append(f"{app_script.app_name}.{key}")
351
+ if dotted:
352
+ extra = " We did find that sub objects that might work: " + ", ".join(dotted)
353
+ raise ValueError(
354
+ f"Main object (with name {app_script.app_name} in {app_script.path}) is not a Widget, Element or Component, but {type(main_object)}." + extra
355
+ )
356
+ return container, render_context
357
+
358
+
359
+ def load_app_widget(app_state, app_script: AppScript, pathname: str):
360
+ # load the app, and set it at the child of the context's container
361
+ app_state_initial = app_state
362
+ context = kernel_context.get_current_context()
363
+ container = context.container
364
+ assert container is not None
365
+ try:
366
+ import ipyreact
367
+
368
+ del ipyreact
369
+ except ModuleNotFoundError:
370
+ pass
371
+ else:
372
+ import solara.server.esm
373
+
374
+ # will create widgets, but will clean itself up when the kernel closes
375
+ solara.server.esm.create_modules()
376
+ solara.server.esm.create_import_map()
377
+
378
+ try:
379
+ render_context = context.app_object
380
+ app_state = app_state_initial
381
+ with pdb_guard():
382
+ widget, render_context = _run_app(
383
+ app_state,
384
+ app_script,
385
+ pathname,
386
+ render_context=render_context,
387
+ )
388
+ if render_context is None:
389
+ assert context.container is not None
390
+ context.container.children = [widget]
391
+
392
+ if render_context:
393
+ context.app_object = render_context
394
+
395
+ except BaseException as e:
396
+ error = ""
397
+ error = "".join(traceback.format_exception(None, e, e.__traceback__))
398
+ print(error, file=sys.stdout, flush=True) # noqa
399
+ # widget = widgets.Label(value="Error, see server logs")
400
+ import html
401
+
402
+ error = html.escape(error)
403
+ with context:
404
+ widget = widgets.HTML(f"<pre>{error}</pre>", layout=widgets.Layout(overflow="auto"))
405
+ container.children = [widget]
406
+
407
+
408
+ def load_themes(themes: Dict[str, Dict[str, str]], dark: bool):
409
+ # While these usually gets set from the frontend, in solara (server) we want to know theme information directly at the first
410
+ # render. Also, using the same trait allows us to write code which works on all widgets platforms, instead
411
+ # or using something different when running under solara server
412
+ from solara.lab.components.theming import _set_theme, theme
413
+
414
+ _set_theme(themes)
415
+ theme.dark_effective = dark
416
+
417
+
418
+ def solara_comm_target(comm, msg_first):
419
+ app: Optional[AppScript] = None
420
+
421
+ def on_msg(msg):
422
+ nonlocal app
423
+ data = msg["content"]["data"]
424
+ method = data["method"]
425
+ if method == "run":
426
+ args = data["args"]
427
+ path = args.get("path", "")
428
+ app_name = args.get("appName") or "__default__"
429
+ app = apps[app_name]
430
+ context = kernel_context.get_current_context()
431
+ import ipyvuetify
432
+
433
+ container = ipyvuetify.Html(tag="div")
434
+ context.container = container
435
+ themes = args.get("themes")
436
+ dark = args.get("dark")
437
+ load_themes(themes, dark)
438
+ load_app_widget(None, app, path)
439
+ comm.send({"method": "finished", "widget_id": context.container._model_id})
440
+ elif method == "app-status":
441
+ context = kernel_context.get_current_context()
442
+ # if there is no container, we never ran the app
443
+ if context.container is not None:
444
+ logger.info("app-status check: %s app started", context.id)
445
+ comm.send({"method": "app-status", "started": True})
446
+ else:
447
+ logger.info("app-status check: %s app not started", context.id)
448
+ comm.send({"method": "app-status", "started": False})
449
+
450
+ elif method == "reload":
451
+ from solara.lab.components.theming import _get_theme, theme
452
+
453
+ assert app is not None
454
+ context = kernel_context.get_current_context()
455
+ path = data.get("path", "")
456
+ current_theme = theme._instance.value
457
+ theme_dict = _get_theme(current_theme)
458
+
459
+ with context:
460
+ context.restart()
461
+ load_themes(theme_dict, current_theme.dark_effective)
462
+ load_app_widget(context.state, app, path)
463
+ comm.send({"method": "finished"})
464
+ else:
465
+ logger.error("Unknown comm method called on solara.control comm: %s", method)
466
+
467
+ comm.on_msg(on_msg)
468
+
469
+ def reload():
470
+ # we don't reload the app ourself, we send a message to the client
471
+ # this ensures that we don't run code of any client that for some reason is connected
472
+ # but not working anymore. And it indirectly passes a message from the current thread
473
+ # (which is that of the Reloader/watchdog), to the thread of the client
474
+ logger.debug(f"Send reload to client: {context.id}")
475
+ comm.send({"method": "reload"})
476
+
477
+ context = kernel_context.get_current_context()
478
+ context.reload = reload
479
+
480
+
481
+ def register_solara_comm_target(kernel: Kernel):
482
+ kernel.comm_manager.register_target("solara.control", solara_comm_target)
483
+
484
+
485
+ from . import patch # noqa
486
+
487
+ patch.patch()
488
+ # the default app (used in solara-server)
489
+ if "SOLARA_APP" in os.environ:
490
+ with pdb_guard():
491
+ apps["__default__"] = AppScript(os.environ.get("SOLARA_APP", "solara.website.pages:Page"))
@@ -0,0 +1 @@
1
+ /* not empty *
@@ -0,0 +1 @@
1
+ /* not empty */
Binary file
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="65" height="65"><svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M57.11 30.64L61.47 17.87L48.7 13.51L42.76 1.39999L30.65 7.34999L17.87 2.97999L13.51 15.75L1.40002 21.7L7.35002 33.81L2.99002 46.58L15.76 50.94L21.71 63.06L33.82 57.11L46.59 61.47L50.95 48.7L63.06 42.75L57.11 30.64ZM54.26 34.39L34.39 54.26C33.19 55.46 31.25 55.46 30.05 54.26L10.2 34.4C9.00002 33.2 9.00002 31.26 10.2 30.07L30.06 10.2C31.26 8.99999 33.2 8.99999 34.4 10.2L54.27 30.07C55.47 31.27 55.47 33.21 54.27 34.4L54.26 34.39Z" fill="#FFCF64"></path>
3
+ <path d="M53.62 19.42L51.65 6.07L38.3 8.04L27.46 0L19.42 10.84L6.07 12.82L8.04 26.17L0 37L10.84 45.04L12.81 58.39L26.16 56.42L37 64.46L45.04 53.62L58.39 51.64L56.42 38.29L64.46 27.45L53.62 19.4V19.42ZM52.8 24.06L44.24 50.82C43.72 52.43 42 53.32 40.39 52.81L13.63 44.25C12.02 43.74 11.13 42.01 11.64 40.4L20.21 13.64C20.72 12.03 22.45 11.14 24.06 11.65L50.82 20.21C52.43 20.72 53.32 22.45 52.81 24.06H52.8Z" fill="#FF8C3E"></path>
4
+ </svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
5
+ </style></svg>