myjsbook 1.0.0

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 (242) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +263 -0
  3. package/package.json +38 -0
  4. package/public/app.js +6686 -0
  5. package/public/components/constants.js +421 -0
  6. package/public/components/elements.js +118 -0
  7. package/public/components/state.js +53 -0
  8. package/public/icons/audio.svg +1 -0
  9. package/public/icons/azure.svg +1 -0
  10. package/public/icons/babel.svg +1 -0
  11. package/public/icons/bun.svg +1 -0
  12. package/public/icons/bun_light.svg +1 -0
  13. package/public/icons/c.svg +1 -0
  14. package/public/icons/chrome.svg +1 -0
  15. package/public/icons/citation.svg +1 -0
  16. package/public/icons/claude.svg +1 -0
  17. package/public/icons/console.svg +1 -0
  18. package/public/icons/cpp.svg +1 -0
  19. package/public/icons/css-map.svg +1 -0
  20. package/public/icons/css.svg +1 -0
  21. package/public/icons/database.svg +1 -0
  22. package/public/icons/docker.svg +1 -0
  23. package/public/icons/document.svg +1 -0
  24. package/public/icons/ejs.svg +1 -0
  25. package/public/icons/exe.svg +1 -0
  26. package/public/icons/favicon.svg +1 -0
  27. package/public/icons/figma.svg +1 -0
  28. package/public/icons/firebase.svg +1 -0
  29. package/public/icons/folder-admin-open.svg +1 -0
  30. package/public/icons/folder-admin.svg +1 -0
  31. package/public/icons/folder-api-open.svg +1 -0
  32. package/public/icons/folder-api.svg +1 -0
  33. package/public/icons/folder-app-open.svg +1 -0
  34. package/public/icons/folder-app.svg +1 -0
  35. package/public/icons/folder-archive-open.svg +1 -0
  36. package/public/icons/folder-archive.svg +1 -0
  37. package/public/icons/folder-attachment-open.svg +1 -0
  38. package/public/icons/folder-attachment.svg +1 -0
  39. package/public/icons/folder-aws-open.svg +1 -0
  40. package/public/icons/folder-aws.svg +1 -0
  41. package/public/icons/folder-backup-open.svg +1 -0
  42. package/public/icons/folder-backup.svg +1 -0
  43. package/public/icons/folder-class-open.svg +1 -0
  44. package/public/icons/folder-class.svg +1 -0
  45. package/public/icons/folder-claude-open.svg +1 -0
  46. package/public/icons/folder-claude.svg +1 -0
  47. package/public/icons/folder-client-open.svg +1 -0
  48. package/public/icons/folder-client.svg +1 -0
  49. package/public/icons/folder-command-open.svg +1 -0
  50. package/public/icons/folder-command.svg +1 -0
  51. package/public/icons/folder-components-open.svg +1 -0
  52. package/public/icons/folder-components.svg +1 -0
  53. package/public/icons/folder-config-open.svg +1 -0
  54. package/public/icons/folder-config.svg +1 -0
  55. package/public/icons/folder-connection-open.svg +1 -0
  56. package/public/icons/folder-connection.svg +1 -0
  57. package/public/icons/folder-console-open.svg +1 -0
  58. package/public/icons/folder-console.svg +1 -0
  59. package/public/icons/folder-container-open.svg +1 -0
  60. package/public/icons/folder-container.svg +1 -0
  61. package/public/icons/folder-content-open.svg +1 -0
  62. package/public/icons/folder-content.svg +1 -0
  63. package/public/icons/folder-context-open.svg +1 -0
  64. package/public/icons/folder-context.svg +1 -0
  65. package/public/icons/folder-controller-open.svg +1 -0
  66. package/public/icons/folder-controller.svg +1 -0
  67. package/public/icons/folder-core-open.svg +1 -0
  68. package/public/icons/folder-core.svg +1 -0
  69. package/public/icons/folder-css-open.svg +1 -0
  70. package/public/icons/folder-css.svg +1 -0
  71. package/public/icons/folder-custom-open.svg +1 -0
  72. package/public/icons/folder-custom.svg +1 -0
  73. package/public/icons/folder-database-open.svg +1 -0
  74. package/public/icons/folder-database.svg +1 -0
  75. package/public/icons/folder-decorators-open.svg +1 -0
  76. package/public/icons/folder-decorators.svg +1 -0
  77. package/public/icons/folder-desktop-open.svg +1 -0
  78. package/public/icons/folder-desktop.svg +1 -0
  79. package/public/icons/folder-dist-open.svg +1 -0
  80. package/public/icons/folder-dist.svg +1 -0
  81. package/public/icons/folder-docs-open.svg +1 -0
  82. package/public/icons/folder-docs.svg +1 -0
  83. package/public/icons/folder-download-open.svg +1 -0
  84. package/public/icons/folder-download.svg +1 -0
  85. package/public/icons/folder-dtos-open.svg +1 -0
  86. package/public/icons/folder-dtos.svg +1 -0
  87. package/public/icons/folder-element-open.svg +1 -0
  88. package/public/icons/folder-element.svg +1 -0
  89. package/public/icons/folder-environment-open.svg +1 -0
  90. package/public/icons/folder-environment.svg +1 -0
  91. package/public/icons/folder-error-open.svg +1 -0
  92. package/public/icons/folder-error.svg +1 -0
  93. package/public/icons/folder-event-open.svg +1 -0
  94. package/public/icons/folder-event.svg +1 -0
  95. package/public/icons/folder-examples-open.svg +1 -0
  96. package/public/icons/folder-examples.svg +1 -0
  97. package/public/icons/folder-expo-open.svg +1 -0
  98. package/public/icons/folder-expo.svg +1 -0
  99. package/public/icons/folder-export-open.svg +1 -0
  100. package/public/icons/folder-export.svg +1 -0
  101. package/public/icons/folder-features-open.svg +1 -0
  102. package/public/icons/folder-features.svg +1 -0
  103. package/public/icons/folder-filter-open.svg +1 -0
  104. package/public/icons/folder-filter.svg +1 -0
  105. package/public/icons/folder-firebase-open.svg +1 -0
  106. package/public/icons/folder-firebase.svg +1 -0
  107. package/public/icons/folder-firestore-open.svg +1 -0
  108. package/public/icons/folder-firestore.svg +1 -0
  109. package/public/icons/folder-font-open.svg +1 -0
  110. package/public/icons/folder-font.svg +1 -0
  111. package/public/icons/folder-functions-open.svg +1 -0
  112. package/public/icons/folder-functions.svg +1 -0
  113. package/public/icons/folder-gemini-ai-open.svg +1 -0
  114. package/public/icons/folder-gemini-ai.svg +1 -0
  115. package/public/icons/folder-git-open.svg +1 -0
  116. package/public/icons/folder-git.svg +1 -0
  117. package/public/icons/folder-github-open.svg +1 -0
  118. package/public/icons/folder-github.svg +1 -0
  119. package/public/icons/folder-helper-open.svg +1 -0
  120. package/public/icons/folder-helper.svg +1 -0
  121. package/public/icons/folder-home-open.svg +1 -0
  122. package/public/icons/folder-home.svg +1 -0
  123. package/public/icons/folder-icons-open.svg +1 -0
  124. package/public/icons/folder-icons.svg +1 -0
  125. package/public/icons/folder-images-open.svg +1 -0
  126. package/public/icons/folder-images.svg +1 -0
  127. package/public/icons/folder-interface-open.svg +1 -0
  128. package/public/icons/folder-interface.svg +1 -0
  129. package/public/icons/folder-ios-open.svg +1 -0
  130. package/public/icons/folder-ios.svg +1 -0
  131. package/public/icons/folder-java-open.svg +1 -0
  132. package/public/icons/folder-java.svg +1 -0
  133. package/public/icons/folder-javascript-open.svg +1 -0
  134. package/public/icons/folder-javascript.svg +1 -0
  135. package/public/icons/folder-middleware-open.svg +1 -0
  136. package/public/icons/folder-middleware.svg +1 -0
  137. package/public/icons/folder-migrations-open.svg +1 -0
  138. package/public/icons/folder-migrations.svg +1 -0
  139. package/public/icons/folder-other-open.svg +1 -0
  140. package/public/icons/folder-other.svg +1 -0
  141. package/public/icons/folder-packages-open.svg +1 -0
  142. package/public/icons/folder-packages.svg +1 -0
  143. package/public/icons/folder-pdf-open.svg +1 -0
  144. package/public/icons/folder-pdf.svg +1 -0
  145. package/public/icons/folder-plugin-open.svg +1 -0
  146. package/public/icons/folder-plugin.svg +1 -0
  147. package/public/icons/folder-project-open.svg +1 -0
  148. package/public/icons/folder-project.svg +1 -0
  149. package/public/icons/folder-public-open.svg +1 -0
  150. package/public/icons/folder-public.svg +1 -0
  151. package/public/icons/folder-python-open.svg +1 -0
  152. package/public/icons/folder-python.svg +1 -0
  153. package/public/icons/folder-repository-open.svg +1 -0
  154. package/public/icons/folder-repository.svg +1 -0
  155. package/public/icons/folder-routes-open.svg +1 -0
  156. package/public/icons/folder-routes.svg +1 -0
  157. package/public/icons/folder-rules-open.svg +1 -0
  158. package/public/icons/folder-rules.svg +1 -0
  159. package/public/icons/folder-sass-open.svg +1 -0
  160. package/public/icons/folder-sass.svg +1 -0
  161. package/public/icons/folder-scripts-open.svg +1 -0
  162. package/public/icons/folder-scripts.svg +1 -0
  163. package/public/icons/folder-server-open.svg +1 -0
  164. package/public/icons/folder-server.svg +1 -0
  165. package/public/icons/folder-serverless-open.svg +1 -0
  166. package/public/icons/folder-serverless.svg +1 -0
  167. package/public/icons/folder-skills-open.svg +1 -0
  168. package/public/icons/folder-skills.svg +1 -0
  169. package/public/icons/folder-src-open.svg +1 -0
  170. package/public/icons/folder-src.svg +1 -0
  171. package/public/icons/folder-stack-open.svg +1 -0
  172. package/public/icons/folder-stack.svg +1 -0
  173. package/public/icons/folder-store-open.svg +1 -0
  174. package/public/icons/folder-store.svg +1 -0
  175. package/public/icons/folder-supabase-open.svg +1 -0
  176. package/public/icons/folder-supabase.svg +1 -0
  177. package/public/icons/folder-svg-open.svg +1 -0
  178. package/public/icons/folder-svg.svg +1 -0
  179. package/public/icons/folder-target-open.svg +1 -0
  180. package/public/icons/folder-target.svg +1 -0
  181. package/public/icons/folder-tasks-open.svg +1 -0
  182. package/public/icons/folder-tasks.svg +1 -0
  183. package/public/icons/folder-temp-open.svg +1 -0
  184. package/public/icons/folder-temp.svg +1 -0
  185. package/public/icons/folder-template-open.svg +1 -0
  186. package/public/icons/folder-template.svg +1 -0
  187. package/public/icons/folder-test-open.svg +1 -0
  188. package/public/icons/folder-test.svg +1 -0
  189. package/public/icons/folder-tools-open.svg +1 -0
  190. package/public/icons/folder-tools.svg +1 -0
  191. package/public/icons/folder-typescript-open.svg +1 -0
  192. package/public/icons/folder-typescript.svg +1 -0
  193. package/public/icons/folder-ui-open.svg +1 -0
  194. package/public/icons/folder-ui.svg +1 -0
  195. package/public/icons/folder-upload-open.svg +1 -0
  196. package/public/icons/folder-upload.svg +1 -0
  197. package/public/icons/folder-utils-open.svg +1 -0
  198. package/public/icons/folder-utils.svg +1 -0
  199. package/public/icons/folder-video-open.svg +1 -0
  200. package/public/icons/folder-video.svg +1 -0
  201. package/public/icons/folder-views-open.svg +1 -0
  202. package/public/icons/folder-views.svg +1 -0
  203. package/public/icons/font.svg +1 -0
  204. package/public/icons/gemini-ai.svg +1 -0
  205. package/public/icons/gemini.svg +1 -0
  206. package/public/icons/git.svg +1 -0
  207. package/public/icons/google.svg +1 -0
  208. package/public/icons/graphql.svg +1 -0
  209. package/public/icons/html.svg +1 -0
  210. package/public/icons/image.svg +1 -0
  211. package/public/icons/java.svg +1 -0
  212. package/public/icons/javaclass.svg +1 -0
  213. package/public/icons/javascript.svg +1 -0
  214. package/public/icons/jsconfig.svg +1 -0
  215. package/public/icons/json.svg +1 -0
  216. package/public/icons/markdown.svg +1 -0
  217. package/public/icons/nodejs.svg +1 -0
  218. package/public/icons/nodejs_alt.svg +1 -0
  219. package/public/icons/nodemon.svg +1 -0
  220. package/public/icons/npm.svg +1 -0
  221. package/public/icons/pdf.svg +1 -0
  222. package/public/icons/prettier.svg +1 -0
  223. package/public/icons/prisma.svg +1 -0
  224. package/public/icons/python.svg +1 -0
  225. package/public/icons/react.svg +1 -0
  226. package/public/icons/react_ts.svg +1 -0
  227. package/public/icons/readme.svg +1 -0
  228. package/public/icons/remark.svg +1 -0
  229. package/public/icons/sass.svg +1 -0
  230. package/public/icons/svg.svg +1 -0
  231. package/public/icons/tailwindcss.svg +1 -0
  232. package/public/icons/typescript-def.svg +1 -0
  233. package/public/icons/typescript.svg +1 -0
  234. package/public/icons/zip.svg +1 -0
  235. package/public/index.html +1342 -0
  236. package/public/styles.css +4736 -0
  237. package/src/cli.js +175 -0
  238. package/src/lib/files.js +143 -0
  239. package/src/lib/notebook.js +141 -0
  240. package/src/lib/package-exports.js +331 -0
  241. package/src/lib/session.js +1003 -0
  242. package/src/server.js +2232 -0
@@ -0,0 +1,1342 @@
1
+ <!doctype html>
2
+ <html lang="en" data-theme="obsidian">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>MarsBook - Run JS</title>
7
+ <link
8
+ rel="icon"
9
+ href='data:image/svg+xml,%3Csvg width="75" height="63" viewBox="0 0 75 63" fill="none" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath opacity="0.2" d="M37.3616 61.5C53.9301 61.5 67.3616 48.0685 67.3616 31.5C67.3616 14.9315 53.9301 1.5 37.3616 1.5C20.793 1.5 7.36157 14.9315 7.36157 31.5C7.36157 48.0685 20.793 61.5 37.3616 61.5Z" stroke="%23C1440E" stroke-width="3"/%3E%3Cpath opacity="0.15" d="M39.9497 41.1592C59.1545 36.0133 73.5643 27.5172 72.1348 22.1825C70.7054 16.8478 53.9781 16.6948 34.7733 21.8407C15.5685 26.9866 1.15873 35.4828 2.58815 40.8175C4.01757 46.1521 20.7449 46.3051 39.9497 41.1592Z" stroke="%23C1440E" stroke-width="2.8"/%3E%3Cpath d="M37.3616 51.5C48.4073 51.5 57.3616 42.5457 57.3616 31.5C57.3616 20.4543 48.4073 11.5 37.3616 11.5C26.3159 11.5 17.3616 20.4543 17.3616 31.5C17.3616 42.5457 26.3159 51.5 37.3616 51.5Z" fill="%23C1440E"/%3E%3Cpath opacity="0.45" d="M29.3616 29.5C32.123 29.5 34.3616 27.2614 34.3616 24.5C34.3616 21.7386 32.123 19.5 29.3616 19.5C26.6001 19.5 24.3616 21.7386 24.3616 24.5C24.3616 27.2614 26.6001 29.5 29.3616 29.5Z" fill="%239E360A"/%3E%3Cpath opacity="0.35" d="M43.3616 38C45.2946 38 46.8616 36.433 46.8616 34.5C46.8616 32.567 45.2946 31 43.3616 31C41.4286 31 39.8616 32.567 39.8616 34.5C39.8616 36.433 41.4286 38 43.3616 38Z" fill="%239E360A"/%3E%3Cpath opacity="0.3" d="M42.8407 25.6721C46.3445 24.0382 48.5226 21.2936 47.7057 19.5417C46.8888 17.7898 43.3861 17.6941 39.8824 19.3279C36.3786 20.9618 34.2005 23.7064 35.0174 25.4583C35.8343 27.2102 39.3369 27.3059 42.8407 25.6721Z" fill="%23D45A28"/%3E%3Cpath opacity="0.5" d="M26.3616 38.5C27.4661 38.5 28.3616 37.6046 28.3616 36.5C28.3616 35.3954 27.4661 34.5 26.3616 34.5C25.257 34.5 24.3616 35.3954 24.3616 36.5C24.3616 37.6046 25.257 38.5 26.3616 38.5Z" fill="%238B2E08"/%3E%3Cpath d="M28.409 25.425C28.409 25.5883 28.3927 25.768 28.36 25.964C28.3273 26.16 28.2527 26.3443 28.136 26.517C28.0193 26.685 27.8513 26.8273 27.632 26.944C27.4127 27.056 27.1163 27.112 26.743 27.112C26.533 27.112 26.33 27.0817 26.134 27.021C25.938 26.965 25.763 26.8763 25.609 26.755C25.455 26.629 25.3313 26.4703 25.238 26.279C25.1447 26.083 25.098 25.8473 25.098 25.572V25.138H26.092V25.362C26.092 25.4833 26.1013 25.5953 26.12 25.698C26.1387 25.8007 26.1713 25.8893 26.218 25.964C26.2647 26.034 26.3277 26.09 26.407 26.132C26.491 26.174 26.5983 26.195 26.729 26.195C26.8737 26.195 26.9857 26.1693 27.065 26.118C27.1443 26.0667 27.2003 26.0013 27.233 25.922C27.2703 25.838 27.2913 25.7493 27.296 25.656C27.3053 25.558 27.31 25.4647 27.31 25.376V22.002H28.409V25.425ZM30.1216 25.341C30.1216 25.509 30.152 25.6513 30.2126 25.768C30.2733 25.8847 30.3526 25.9803 30.4506 26.055C30.5533 26.125 30.6723 26.1787 30.8076 26.216C30.943 26.2487 31.083 26.265 31.2276 26.265C31.3256 26.265 31.4306 26.258 31.5426 26.244C31.6546 26.2253 31.7596 26.1927 31.8576 26.146C31.9556 26.0993 32.0373 26.0363 32.1026 25.957C32.168 25.873 32.2006 25.768 32.2006 25.642C32.2006 25.5067 32.1563 25.397 32.0676 25.313C31.9836 25.229 31.8716 25.159 31.7316 25.103C31.5916 25.047 31.433 24.998 31.2556 24.956C31.0783 24.914 30.8986 24.8673 30.7166 24.816C30.53 24.7693 30.348 24.7133 30.1706 24.648C29.9933 24.578 29.8346 24.4893 29.6946 24.382C29.5546 24.2747 29.4403 24.1417 29.3516 23.983C29.2676 23.8197 29.2256 23.6237 29.2256 23.395C29.2256 23.1383 29.2793 22.9167 29.3866 22.73C29.4986 22.5387 29.6433 22.38 29.8206 22.254C29.998 22.128 30.1986 22.0347 30.4226 21.974C30.6466 21.9133 30.8706 21.883 31.0946 21.883C31.356 21.883 31.6056 21.9133 31.8436 21.974C32.0863 22.03 32.301 22.1233 32.4876 22.254C32.6743 22.3847 32.8213 22.5527 32.9286 22.758C33.0406 22.9587 33.0966 23.2037 33.0966 23.493H32.0326C32.0233 23.3437 31.9906 23.22 31.9346 23.122C31.8833 23.024 31.8133 22.947 31.7246 22.891C31.636 22.835 31.5333 22.7953 31.4166 22.772C31.3046 22.7487 31.181 22.737 31.0456 22.737C30.957 22.737 30.8683 22.7463 30.7796 22.765C30.691 22.7837 30.6093 22.8163 30.5346 22.863C30.4646 22.9097 30.4063 22.968 30.3596 23.038C30.313 23.108 30.2896 23.1967 30.2896 23.304C30.2896 23.402 30.3083 23.4813 30.3456 23.542C30.383 23.6027 30.4553 23.6587 30.5626 23.71C30.6746 23.7613 30.8263 23.8127 31.0176 23.864C31.2136 23.9153 31.468 23.9807 31.7806 24.06C31.874 24.0787 32.0023 24.1137 32.1656 24.165C32.3336 24.2117 32.4993 24.2887 32.6626 24.396C32.826 24.5033 32.966 24.648 33.0826 24.83C33.204 25.0073 33.2646 25.236 33.2646 25.516C33.2646 25.7447 33.2203 25.957 33.1316 26.153C33.043 26.349 32.91 26.5193 32.7326 26.664C32.56 26.804 32.343 26.9137 32.0816 26.993C31.825 27.0723 31.5263 27.112 31.1856 27.112C30.9103 27.112 30.642 27.077 30.3806 27.007C30.124 26.9417 29.8953 26.8367 29.6946 26.692C29.4986 26.5473 29.3423 26.363 29.2256 26.139C29.109 25.915 29.053 25.649 29.0576 25.341H30.1216Z" fill="%23E8E8F0"/%3E%3C/svg%3E'
10
+ />
11
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
12
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
13
+ <link
14
+ href="https://fonts.googleapis.com/css2?family=Chivo+Mono:wght@400;500&family=Chivo:wght@400;500&family=JetBrains+Mono:wght@400;500&family=Poppins:wght@400;500&display=swap"
15
+ rel="stylesheet"
16
+ />
17
+ <link rel="stylesheet" href="/vendor/monaco/vs/editor/editor.main.css" />
18
+ <link rel="stylesheet" href="/styles.css" />
19
+ </head>
20
+ <body>
21
+ <!-- ═══════════════════════════════════════════════════════════
22
+ APP SHELL
23
+ ═══════════════════════════════════════════════════════════ -->
24
+ <div class="app-shell" id="app-shell">
25
+ <!-- ── LEFT SIDEBAR ── -->
26
+ <aside class="sidebar" id="sidebar">
27
+ <!-- Brand -->
28
+ <div class="sidebar-brand">
29
+ <div class="brand-logo marsbook-logo-mark">
30
+ <!-- Light logo: shown on dark themes -->
31
+ <svg
32
+ class="brand-logo-dark-theme"
33
+ width="75"
34
+ height="63"
35
+ viewBox="0 0 75 63"
36
+ fill="none"
37
+ xmlns="http://www.w3.org/2000/svg"
38
+ >
39
+ <path
40
+ opacity="0.2"
41
+ d="M37.3616 61.5C53.9301 61.5 67.3616 48.0685 67.3616 31.5C67.3616 14.9315 53.9301 1.5 37.3616 1.5C20.793 1.5 7.36157 14.9315 7.36157 31.5C7.36157 48.0685 20.793 61.5 37.3616 61.5Z"
42
+ stroke="#E8E4DC"
43
+ stroke-width="3"
44
+ />
45
+ <path
46
+ opacity="0.15"
47
+ d="M39.9497 41.1592C59.1545 36.0133 73.5643 27.5172 72.1348 22.1825C70.7054 16.8478 53.9781 16.6948 34.7733 21.8407C15.5685 26.9866 1.15877 35.4828 2.58819 40.8175C4.01761 46.1521 20.7449 46.3051 39.9497 41.1592Z"
48
+ stroke="#E8E4DC"
49
+ stroke-width="2.8"
50
+ />
51
+ <path
52
+ d="M37.3616 51.5C48.4073 51.5 57.3616 42.5457 57.3616 31.5C57.3616 20.4543 48.4073 11.5 37.3616 11.5C26.3159 11.5 17.3616 20.4543 17.3616 31.5C17.3616 42.5457 26.3159 51.5 37.3616 51.5Z"
53
+ fill="#E8E4DC"
54
+ />
55
+ <path
56
+ opacity="0.45"
57
+ d="M29.3616 29.5C32.123 29.5 34.3616 27.2614 34.3616 24.5C34.3616 21.7386 32.123 19.5 29.3616 19.5C26.6001 19.5 24.3616 21.7386 24.3616 24.5C24.3616 27.2614 26.6001 29.5 29.3616 29.5Z"
58
+ fill="#B8B4AC"
59
+ />
60
+ <path
61
+ opacity="0.35"
62
+ d="M43.3616 38C45.2946 38 46.8616 36.433 46.8616 34.5C46.8616 32.567 45.2946 31 43.3616 31C41.4286 31 39.8616 32.567 39.8616 34.5C39.8616 36.433 41.4286 38 43.3616 38Z"
63
+ fill="#B8B4AC"
64
+ />
65
+ <path
66
+ opacity="0.3"
67
+ d="M42.8407 25.6721C46.3445 24.0382 48.5226 21.2936 47.7057 19.5417C46.8888 17.7898 43.3861 17.6941 39.8824 19.3279C36.3786 20.9618 34.2005 23.7064 35.0174 25.4583C35.8343 27.2102 39.3369 27.3059 42.8407 25.6721Z"
68
+ fill="#D0CCC4"
69
+ />
70
+ <path
71
+ opacity="0.5"
72
+ d="M26.3616 38.5C27.4661 38.5 28.3616 37.6046 28.3616 36.5C28.3616 35.3954 27.4661 34.5 26.3616 34.5C25.257 34.5 24.3616 35.3954 24.3616 36.5C24.3616 37.6046 25.257 38.5 26.3616 38.5Z"
73
+ fill="#908C84"
74
+ />
75
+ </svg>
76
+ <!-- Dark logo: shown on light themes -->
77
+ <svg
78
+ class="brand-logo-light-theme"
79
+ width="75"
80
+ height="63"
81
+ viewBox="0 0 75 63"
82
+ fill="none"
83
+ xmlns="http://www.w3.org/2000/svg"
84
+ >
85
+ <path
86
+ opacity="0.2"
87
+ d="M37.3616 61.5C53.9301 61.5 67.3616 48.0685 67.3616 31.5C67.3616 14.9315 53.9301 1.5 37.3616 1.5C20.793 1.5 7.36157 14.9315 7.36157 31.5C7.36157 48.0685 20.793 61.5 37.3616 61.5Z"
88
+ stroke="#C1440E"
89
+ stroke-width="3"
90
+ />
91
+ <path
92
+ opacity="0.15"
93
+ d="M39.9497 41.1592C59.1545 36.0133 73.5643 27.5172 72.1348 22.1825C70.7054 16.8478 53.9781 16.6948 34.7733 21.8407C15.5685 26.9866 1.15873 35.4828 2.58815 40.8175C4.01757 46.1521 20.7449 46.3051 39.9497 41.1592Z"
94
+ stroke="#C1440E"
95
+ stroke-width="2.8"
96
+ />
97
+ <path
98
+ d="M37.3616 51.5C48.4073 51.5 57.3616 42.5457 57.3616 31.5C57.3616 20.4543 48.4073 11.5 37.3616 11.5C26.3159 11.5 17.3616 20.4543 17.3616 31.5C17.3616 42.5457 26.3159 51.5 37.3616 51.5Z"
99
+ fill="#C1440E"
100
+ />
101
+ <path
102
+ opacity="0.45"
103
+ d="M29.3616 29.5C32.123 29.5 34.3616 27.2614 34.3616 24.5C34.3616 21.7386 32.123 19.5 29.3616 19.5C26.6001 19.5 24.3616 21.7386 24.3616 24.5C24.3616 27.2614 26.6001 29.5 29.3616 29.5Z"
104
+ fill="#9E360A"
105
+ />
106
+ <path
107
+ opacity="0.35"
108
+ d="M43.3616 38C45.2946 38 46.8616 36.433 46.8616 34.5C46.8616 32.567 45.2946 31 43.3616 31C41.4286 31 39.8616 32.567 39.8616 34.5C39.8616 36.433 41.4286 38 43.3616 38Z"
109
+ fill="#9E360A"
110
+ />
111
+ <path
112
+ opacity="0.3"
113
+ d="M42.8407 25.6721C46.3445 24.0382 48.5226 21.2936 47.7057 19.5417C46.8888 17.7898 43.3861 17.6941 39.8824 19.3279C36.3786 20.9618 34.2005 23.7064 35.0174 25.4583C35.8343 27.2102 39.3369 27.3059 42.8407 25.6721Z"
114
+ fill="#D45A28"
115
+ />
116
+ <path
117
+ opacity="0.5"
118
+ d="M26.3616 38.5C27.4661 38.5 28.3616 37.6046 28.3616 36.5C28.3616 35.3954 27.4661 34.5 26.3616 34.5C25.257 34.5 24.3616 35.3954 24.3616 36.5C24.3616 37.6046 25.257 38.5 26.3616 38.5Z"
119
+ fill="#8B2E08"
120
+ />
121
+ </svg>
122
+ </div>
123
+ <div class="">
124
+ <span class="brand-name marsbook-name">
125
+ <span class="marsbook-mars">Mars </span
126
+ ><span class="marsbook-book">Book</span>
127
+ </span>
128
+ <span class="brand-version">JS Notebook</span>
129
+ </div>
130
+ </div>
131
+
132
+ <!-- Primary Navigation -->
133
+ <nav class="sidebar-nav" aria-label="Main navigation">
134
+ <a href="/" class="nav-item" data-page="dashboard" id="nav-dashboard">
135
+ <svg
136
+ width="16"
137
+ height="16"
138
+ viewBox="0 0 24 24"
139
+ fill="none"
140
+ stroke="currentColor"
141
+ stroke-width="2"
142
+ >
143
+ <rect x="3" y="3" width="7" height="7" />
144
+ <rect x="14" y="3" width="7" height="7" />
145
+ <rect x="14" y="14" width="7" height="7" />
146
+ <rect x="3" y="14" width="7" height="7" />
147
+ </svg>
148
+ Dashboard
149
+ </a>
150
+ <a
151
+ href="/notebooks"
152
+ class="nav-item"
153
+ data-page="notebooks"
154
+ id="nav-notebooks"
155
+ >
156
+ <svg
157
+ width="16"
158
+ height="16"
159
+ viewBox="0 0 24 24"
160
+ fill="none"
161
+ stroke="currentColor"
162
+ stroke-width="2"
163
+ >
164
+ <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
165
+ <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
166
+ </svg>
167
+ Notebooks
168
+ </a>
169
+ <a
170
+ href="/packages"
171
+ class="nav-item"
172
+ data-page="packages"
173
+ id="nav-packages"
174
+ >
175
+ <svg
176
+ width="16"
177
+ height="16"
178
+ viewBox="0 0 24 24"
179
+ fill="none"
180
+ stroke="currentColor"
181
+ stroke-width="2"
182
+ >
183
+ <path
184
+ d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
185
+ />
186
+ <polyline points="3.27 6.96 12 12.01 20.73 6.96" />
187
+ <line x1="12" y1="22.08" x2="12" y2="12" />
188
+ </svg>
189
+ Packages
190
+ </a>
191
+ </nav>
192
+
193
+ <!-- Spacer -->
194
+ <div class="sidebar-spacer"></div>
195
+
196
+ <!-- Env variables shortcut -->
197
+ <button class="sidebar-env-btn" id="env-toggle" type="button">
198
+ <svg
199
+ width="13"
200
+ height="13"
201
+ viewBox="0 0 24 24"
202
+ fill="none"
203
+ stroke="currentColor"
204
+ stroke-width="2"
205
+ >
206
+ <path
207
+ d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"
208
+ />
209
+ <line x1="8" y1="12" x2="16" y2="12" />
210
+ </svg>
211
+ Env Variables
212
+ </button>
213
+ </aside>
214
+
215
+ <!-- ── MAIN CONTENT ── -->
216
+ <div class="main-content" id="main-content">
217
+ <!-- ══════════════════════════════════════════════
218
+ PAGE: DASHBOARD
219
+ ══════════════════════════════════════════════ -->
220
+ <div class="page-view hidden" id="page-dashboard">
221
+ <header class="page-header">
222
+ <div class="page-header-left">
223
+ <h1 class="page-greeting" id="dashboard-greeting">
224
+ Good morning 👋
225
+ </h1>
226
+ </div>
227
+ <div class="page-header-right">
228
+ <div class="search-bar">
229
+ <svg
230
+ width="14"
231
+ height="14"
232
+ viewBox="0 0 24 24"
233
+ fill="none"
234
+ stroke="currentColor"
235
+ stroke-width="2"
236
+ >
237
+ <circle cx="11" cy="11" r="8" />
238
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
239
+ </svg>
240
+ <input
241
+ type="text"
242
+ id="dashboard-search"
243
+ placeholder="Search notebooks..."
244
+ />
245
+ </div>
246
+ <button
247
+ class="btn-terminal terminal-open-btn"
248
+ type="button"
249
+ title="Open terminal"
250
+ >
251
+ <svg
252
+ width="14"
253
+ height="14"
254
+ viewBox="0 0 24 24"
255
+ fill="none"
256
+ stroke="currentColor"
257
+ stroke-width="2"
258
+ stroke-linecap="round"
259
+ stroke-linejoin="round"
260
+ >
261
+ <polyline points="4 17 10 11 4 5" />
262
+ <line x1="12" y1="19" x2="20" y2="19" />
263
+ </svg>
264
+ Terminal
265
+ </button>
266
+ <select
267
+ class="theme-select"
268
+ title="Choose theme"
269
+ aria-label="Choose theme"
270
+ >
271
+ <optgroup label="Light Themes">
272
+ <option value="champa">Champa</option>
273
+ <option value="varuna">Varuna</option>
274
+ <option value="haritha">Haritha</option>
275
+ </optgroup>
276
+ <optgroup label="Dark Themes">
277
+ <option value="obsidian">Obsidian</option>
278
+ <option value="antariksha">Antariksha</option>
279
+ <option value="vriksha">Vriksha</option>
280
+ </optgroup>
281
+ </select>
282
+ <button class="btn-primary" id="new-notebook-btn" type="button">
283
+ + New Notebook
284
+ </button>
285
+ </div>
286
+ </header>
287
+
288
+ <!-- Stat Cards -->
289
+ <div class="stat-grid" id="stat-grid">
290
+ <div class="stat-card stat-card--green">
291
+ <div class="stat-value" id="stat-notebooks">—</div>
292
+ <div class="stat-label">Notebooks</div>
293
+ <div class="stat-sub" id="stat-notebooks-sub">In your workspace</div>
294
+ </div>
295
+ <div class="stat-card stat-card--blue">
296
+ <div class="stat-header-row">
297
+ <div class="stat-value" id="stat-executions">—</div>
298
+ <button
299
+ class="stat-reset-btn"
300
+ id="reset-executions-btn"
301
+ type="button"
302
+ >
303
+ Reset
304
+ </button>
305
+ </div>
306
+ <div class="stat-label">Total Executions</div>
307
+ <div class="stat-sub" id="stat-executions-sub">
308
+ Across all notebooks
309
+ </div>
310
+ </div>
311
+ <div class="stat-card stat-card--orange">
312
+ <div class="stat-value" id="stat-packages">—</div>
313
+ <div class="stat-label">npm Packages</div>
314
+ <div class="stat-sub">Across notebooks</div>
315
+ </div>
316
+ <div class="stat-card stat-card--pink">
317
+ <div class="stat-header-row">
318
+ <div class="stat-value" id="metric-lines">—</div>
319
+ </div>
320
+ <div class="stat-label">Total Code Cells</div>
321
+ <div class="stat-sub" id="stat-tokens-sub">Across all notebooks</div>
322
+ </div>
323
+ </div>
324
+
325
+ <!-- Recent Notebooks -->
326
+ <section class="dashboard-section">
327
+ <div class="section-header">
328
+ <h2 class="section-title">Recent Notebooks</h2>
329
+ <div class="filter-tabs" id="notebook-filter-tabs">
330
+ <button class="filter-tab is-active" data-filter="all">
331
+ All
332
+ </button>
333
+ <button class="filter-tab" data-filter="typescript">
334
+ TypeScript
335
+ </button>
336
+ <button class="filter-tab" data-filter="javascript">
337
+ JavaScript
338
+ </button>
339
+ <!-- <button class="filter-tab" data-filter="prompt">AI/LLM</button> -->
340
+ </div>
341
+ <a href="/notebooks" class="view-all-link" data-page="notebooks"
342
+ >View all →</a
343
+ >
344
+ </div>
345
+ <div class="notebook-grid" id="notebook-grid">
346
+ <div class="notebook-grid-empty">Scanning your workspace…</div>
347
+ </div>
348
+ </section>
349
+
350
+ <!-- Activity Feed -->
351
+ <section class="dashboard-section">
352
+ <h2 class="section-title">Activity Feed</h2>
353
+ <div class="activity-layout">
354
+ <div class="activity-feed" id="activity-feed">
355
+ <div class="activity-empty">No recent activity</div>
356
+ </div>
357
+ </div>
358
+ </section>
359
+ </div>
360
+
361
+ <!-- ══════════════════════════════════════════════
362
+ PAGE: NOTEBOOK EDITOR
363
+ ══════════════════════════════════════════════ -->
364
+ <div class="page-view hidden" id="page-notebook">
365
+ <!-- Notebook Top Bar -->
366
+ <header class="notebook-header">
367
+ <div class="notebook-header-left">
368
+ <!-- Explorer panel toggle -->
369
+ <button
370
+ class="explorer-toggle-btn"
371
+ id="explorer-toggle-btn"
372
+ type="button"
373
+ title="Toggle Explorer"
374
+ >
375
+ <svg
376
+ width="14"
377
+ height="14"
378
+ viewBox="0 0 24 24"
379
+ fill="none"
380
+ stroke="currentColor"
381
+ stroke-width="2"
382
+ >
383
+ <rect x="3" y="3" width="6" height="18" rx="1" />
384
+ <path d="M13 7h8M13 12h8M13 17h8" />
385
+ </svg>
386
+ </button>
387
+ <div class="notebook-header-left-col">
388
+ <div class="breadcrumb" id="nb-breadcrumb">
389
+ <span
390
+ class="breadcrumb-item crumb-link"
391
+ data-page="notebooks"
392
+ id="breadcrumb-notebooks"
393
+ >Notebooks</span
394
+ >
395
+ <span class="breadcrumb-sep">/</span>
396
+ <span
397
+ class="breadcrumb-item crumb-current"
398
+ id="breadcrumb-title"
399
+ >Untitled</span
400
+ >
401
+ </div>
402
+ <div class="notebook-meta-row">
403
+ <h1 class="notebook-title-display" id="nb-title-display">
404
+ Untitled Nodebook
405
+ </h1>
406
+ <input
407
+ class="notebook-title-input hidden"
408
+ id="nb-title-input"
409
+ type="text"
410
+ value="Untitled Nodebook"
411
+ aria-label="Notebook title"
412
+ />
413
+ <!-- Global language toggle -->
414
+ <button
415
+ class="nb-lang-toggle"
416
+ id="nb-lang-toggle"
417
+ type="button"
418
+ title="Toggle notebook language"
419
+ >
420
+ TypeScript
421
+ </button>
422
+ <span class="nb-meta-text" id="nb-cell-count">0 cells</span>
423
+ <span class="nb-meta-sep">·</span>
424
+ <span class="nb-meta-text" id="nb-save-state">Saved</span>
425
+ </div>
426
+ </div>
427
+ </div>
428
+ <div class="notebook-header-right">
429
+ <div class="kernel-pill" id="kernel-pill">
430
+ <span class="kernel-dot"></span>
431
+ <span class="btn-label" id="kernel-pill-label">Connected</span>
432
+ </div>
433
+ <button class="btn-ai-assist" id="ai-assist-btn" type="button">
434
+ <svg
435
+ width="13"
436
+ height="13"
437
+ viewBox="0 0 24 24"
438
+ fill="none"
439
+ stroke="currentColor"
440
+ stroke-width="2"
441
+ >
442
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
443
+ </svg>
444
+ <span class="btn-label">AI Assist</span>
445
+ </button>
446
+ <button class="btn-run-all" id="run-all-btn" type="button">
447
+ <svg
448
+ width="13"
449
+ height="13"
450
+ viewBox="0 0 24 24"
451
+ fill="currentColor"
452
+ >
453
+ <polygon points="5 3 19 12 5 21 5 3" />
454
+ </svg>
455
+ <span class="btn-label">Run All</span>
456
+ </button>
457
+ <button
458
+ class="btn-clear-outputs"
459
+ id="clear-outputs-btn"
460
+ type="button"
461
+ title="Clear all cell outputs"
462
+ >
463
+ <svg
464
+ width="13"
465
+ height="13"
466
+ viewBox="0 0 24 24"
467
+ fill="none"
468
+ stroke="currentColor"
469
+ stroke-width="2"
470
+ stroke-linecap="round"
471
+ stroke-linejoin="round"
472
+ >
473
+ <polyline points="3 6 5 6 21 6" />
474
+ <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
475
+ <path d="M10 11v6M14 11v6" />
476
+ </svg>
477
+ <span class="btn-label">Clear Output</span>
478
+ </button>
479
+ <button
480
+ class="btn-terminal terminal-open-btn"
481
+ type="button"
482
+ title="Open terminal"
483
+ >
484
+ <svg
485
+ width="14"
486
+ height="14"
487
+ viewBox="0 0 24 24"
488
+ fill="none"
489
+ stroke="currentColor"
490
+ stroke-width="2"
491
+ stroke-linecap="round"
492
+ stroke-linejoin="round"
493
+ >
494
+ <polyline points="4 17 10 11 4 5" />
495
+ <line x1="12" y1="19" x2="20" y2="19" />
496
+ </svg>
497
+ <span class="btn-label">Terminal</span>
498
+ </button>
499
+ <!-- Settings button -->
500
+ <button
501
+ class="btn-settings"
502
+ id="settings-btn"
503
+ type="button"
504
+ title="Editor settings"
505
+ >
506
+ <svg
507
+ width="14"
508
+ height="14"
509
+ viewBox="0 0 24 24"
510
+ fill="none"
511
+ stroke="currentColor"
512
+ stroke-width="2"
513
+ stroke-linecap="round"
514
+ stroke-linejoin="round"
515
+ >
516
+ <circle cx="12" cy="12" r="3" />
517
+ <path
518
+ d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"
519
+ />
520
+ </svg>
521
+ </button>
522
+ </div>
523
+ </header>
524
+
525
+ <!-- Settings Modal (font size, etc.) -->
526
+ <div
527
+ id="settings-modal-scrim"
528
+ class="settings-modal-scrim hidden"
529
+ ></div>
530
+ <div
531
+ id="settings-modal"
532
+ class="settings-modal hidden"
533
+ role="dialog"
534
+ aria-label="Editor Settings"
535
+ >
536
+ <div class="settings-modal-header">
537
+ <span class="settings-modal-title">Editor Settings</span>
538
+ <button id="settings-close-btn" class="icon-button" type="button">
539
+ <svg
540
+ width="12"
541
+ height="12"
542
+ viewBox="0 0 24 24"
543
+ fill="none"
544
+ stroke="currentColor"
545
+ stroke-width="2"
546
+ >
547
+ <line x1="18" y1="6" x2="6" y2="18" />
548
+ <line x1="6" y1="6" x2="18" y2="18" />
549
+ </svg>
550
+ </button>
551
+ </div>
552
+ <div class="settings-modal-body">
553
+ <div class="settings-row">
554
+ <label class="settings-label" for="font-size-select"
555
+ >Font Size</label
556
+ >
557
+ <div class="settings-control">
558
+ <button
559
+ class="font-size-step"
560
+ id="font-size-dec"
561
+ type="button"
562
+ >
563
+
564
+ </button>
565
+ <span class="font-size-display" id="font-size-display"
566
+ >13px</span
567
+ >
568
+ <button
569
+ class="font-size-step"
570
+ id="font-size-inc"
571
+ type="button"
572
+ >
573
+ +
574
+ </button>
575
+ </div>
576
+ </div>
577
+ <div class="settings-row">
578
+ <label class="settings-label" for="font-family-select"
579
+ >Font Family</label
580
+ >
581
+
582
+ <select
583
+ class="font-family-select"
584
+ id="font-family-select"
585
+ title="Choose editor font"
586
+ aria-label="Choose editor font"
587
+ >
588
+ <option value="default">Default (Menlo / Consolas)</option>
589
+ <option value="'Chivo Mono', monospace">Chivo Mono</option>
590
+ <option value="'JetBrains Mono', monospace">JetBrains Mono</option>
591
+ <option value="'Chivo', sans-serif">Chivo</option>
592
+ <option value="'Poppins', sans-serif">Poppins</option>
593
+ </select>
594
+ </div>
595
+ <div class="settings-row">
596
+ <label class="settings-label" for="font-family-select">
597
+ Theme</label
598
+ >
599
+ <select
600
+ class="theme-select font-family-select"
601
+ title="Choose theme"
602
+ aria-label="Choose theme"
603
+ >
604
+ <optgroup label="Light Themes">
605
+ <option value="champa">Champa</option>
606
+ <option value="varuna">Varuna</option>
607
+ <option value="haritha">Haritha</option>
608
+ </optgroup>
609
+ <optgroup label="Dark Themes">
610
+ <option value="obsidian">Obsidian</option>
611
+ <option value="antariksha">Antariksha</option>
612
+ <option value="vriksha">Vriksha</option>
613
+ </optgroup>
614
+ </select>
615
+ </div>
616
+ <div class="settings-row">
617
+ <label class="settings-label">Preview</label>
618
+ <pre class="settings-preview" id="font-size-preview">
619
+ const hello = "world"; // editor preview</pre
620
+ >
621
+ </div>
622
+ </div>
623
+ </div>
624
+
625
+ <!-- Notebook Body (left panel + editor canvas) -->
626
+ <div class="notebook-body">
627
+ <!-- Left: Workspace Explorer Panel (toggleable) -->
628
+ <aside class="notebook-list-panel" id="notebook-list-panel">
629
+ <div class="nlp-header">
630
+ <span class="nlp-title">Explorer</span>
631
+ <button
632
+ class="icon-button"
633
+ id="nlp-new-btn"
634
+ type="button"
635
+ title="New notebook"
636
+ >
637
+ <svg
638
+ width="14"
639
+ height="14"
640
+ viewBox="0 0 24 24"
641
+ fill="none"
642
+ stroke="currentColor"
643
+ stroke-width="2"
644
+ >
645
+ <line x1="12" y1="5" x2="12" y2="19" />
646
+ <line x1="5" y1="12" x2="19" y2="12" />
647
+ </svg>
648
+ </button>
649
+ </div>
650
+ <div class="nlp-search">
651
+ <svg
652
+ width="12"
653
+ height="12"
654
+ viewBox="0 0 24 24"
655
+ fill="none"
656
+ stroke="currentColor"
657
+ stroke-width="2"
658
+ >
659
+ <circle cx="11" cy="11" r="8" />
660
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
661
+ </svg>
662
+ <input
663
+ type="text"
664
+ id="nlp-search-input"
665
+ placeholder="Filter files…"
666
+ />
667
+ </div>
668
+ <div class="nlp-list" id="nlp-list">
669
+ <div class="nlp-empty">Loading…</div>
670
+ </div>
671
+ </aside>
672
+
673
+ <!-- Center: Cell Canvas -->
674
+ <div class="notebook-canvas-wrap">
675
+ <!-- Add cell bar (TOP) -->
676
+ <div class="add-cell-bar" id="add-cell-bar">
677
+ <span class="add-cell-label">+ Add cell</span>
678
+ <button
679
+ class="add-cell-type-btn"
680
+ id="add-code-button"
681
+ type="button"
682
+ >
683
+ Code
684
+ </button>
685
+ <span class="add-cell-dot">·</span>
686
+ <button
687
+ class="add-cell-type-btn"
688
+ id="add-markdown-button"
689
+ type="button"
690
+ >
691
+ Markdown
692
+ </button>
693
+ <span class="add-cell-dot">·</span>
694
+ <button
695
+ class="add-cell-type-btn"
696
+ id="add-prompt-btn"
697
+ type="button"
698
+ >
699
+ AI Prompt
700
+ </button>
701
+ </div>
702
+
703
+ <!-- Notebook cells -->
704
+ <section id="notebook-cells" class="notebook-canvas"></section>
705
+
706
+ <!-- File preview (for non-notebook files) -->
707
+ <section id="file-preview" class="file-preview hidden"></section>
708
+ </div>
709
+ </div>
710
+ </div>
711
+
712
+ <!-- ══════════════════════════════════════════════
713
+ PAGE: PACKAGE MANAGER
714
+ ══════════════════════════════════════════════ -->
715
+ <div class="page-view hidden" id="page-packages">
716
+ <header class="page-header">
717
+ <div class="page-header-left">
718
+ <h1 class="page-title">Package Manager</h1>
719
+ <p class="page-subtitle">
720
+ Manage npm packages across all notebooks · esm.sh powered
721
+ imports
722
+ </p>
723
+ </div>
724
+ <div class="page-header-right">
725
+ <button
726
+ class="btn-terminal terminal-open-btn"
727
+ type="button"
728
+ title="Open terminal"
729
+ >
730
+ <svg
731
+ width="14"
732
+ height="14"
733
+ viewBox="0 0 24 24"
734
+ fill="none"
735
+ stroke="currentColor"
736
+ stroke-width="2"
737
+ stroke-linecap="round"
738
+ stroke-linejoin="round"
739
+ >
740
+ <polyline points="4 17 10 11 4 5" />
741
+ <line x1="12" y1="19" x2="20" y2="19" />
742
+ </svg>
743
+ Terminal
744
+ </button>
745
+ <select
746
+ class="theme-select"
747
+ title="Choose theme"
748
+ aria-label="Choose theme"
749
+ >
750
+ <optgroup label="Light Themes">
751
+ <option value="champa">Champa</option>
752
+ <option value="varuna">Varuna</option>
753
+ <option value="haritha">Haritha</option>
754
+ </optgroup>
755
+ <optgroup label="Dark Themes">
756
+ <option value="obsidian">Obsidian</option>
757
+ <option value="antariksha">Antariksha</option>
758
+ <option value="vriksha">Vriksha</option>
759
+ </optgroup>
760
+ </select>
761
+ </div>
762
+ </header>
763
+
764
+ <!-- Search + Install -->
765
+ <div class="pkg-search-row">
766
+ <div class="pkg-search-bar">
767
+ <svg
768
+ width="14"
769
+ height="14"
770
+ viewBox="0 0 24 24"
771
+ fill="none"
772
+ stroke="currentColor"
773
+ stroke-width="2"
774
+ >
775
+ <circle cx="11" cy="11" r="8" />
776
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
777
+ </svg>
778
+ <input
779
+ type="text"
780
+ id="pkg-search-input"
781
+ placeholder="Search npm packages… e.g. 'openai', 'zod', 'langchain'"
782
+ />
783
+ </div>
784
+ <button class="btn-pkg-install" id="pkg-install-btn" type="button">
785
+ + Install
786
+ </button>
787
+ </div>
788
+
789
+ <!-- Suggestions section -->
790
+ <div id="pkg-suggestions-section" class="pkg-suggestions-section">
791
+ <h2 class="pkg-list-title">Suggested for AI Developers</h2>
792
+ <div class="pkg-suggestions-grid" id="pkg-suggestions-grid"></div>
793
+ </div>
794
+
795
+ <!-- Package list (full width, no sidebar) -->
796
+ <div class="pkg-main-solo">
797
+ <div class="pkg-list-header">
798
+ <h2 class="pkg-list-title" id="pkg-list-title">
799
+ Installed Packages
800
+ </h2>
801
+ </div>
802
+ <div class="pkg-list" id="pkg-list">
803
+ <div class="pkg-loading">Loading packages…</div>
804
+ </div>
805
+ </div>
806
+ </div>
807
+ </div>
808
+ <!-- /.main-content -->
809
+ </div>
810
+ <!-- /.app-shell -->
811
+
812
+ <!-- ══════════════════════════════════════════════
813
+ OVERLAYS & MODALS
814
+ ══════════════════════════════════════════════ -->
815
+
816
+ <!-- Terminal Bottom Sheet -->
817
+ <div id="terminal-scrim" class="bottom-sheet-scrim"></div>
818
+ <section
819
+ id="terminal-sheet"
820
+ class="bottom-sheet terminal-sheet"
821
+ aria-label="Terminal"
822
+ >
823
+ <div class="bottom-sheet-handle"></div>
824
+ <div class="terminal-header">
825
+ <div class="terminal-header-left">
826
+ <svg
827
+ width="14"
828
+ height="14"
829
+ viewBox="0 0 24 24"
830
+ fill="none"
831
+ stroke="currentColor"
832
+ stroke-width="2"
833
+ stroke-linecap="round"
834
+ stroke-linejoin="round"
835
+ >
836
+ <polyline points="4 17 10 11 4 5" />
837
+ <line x1="12" y1="19" x2="20" y2="19" />
838
+ </svg>
839
+ <span class="terminal-title">Terminal</span>
840
+ <span id="terminal-cwd-label" class="terminal-cwd-label"></span>
841
+ </div>
842
+ <div class="terminal-header-right">
843
+ <button id="terminal-clear-btn" class="btn-ghost small" type="button">
844
+ Clear
845
+ </button>
846
+ <button
847
+ id="terminal-close-btn"
848
+ class="icon-button"
849
+ type="button"
850
+ title="Close"
851
+ >
852
+ <svg
853
+ width="12"
854
+ height="12"
855
+ viewBox="0 0 24 24"
856
+ fill="none"
857
+ stroke="currentColor"
858
+ stroke-width="2"
859
+ >
860
+ <line x1="18" y1="6" x2="6" y2="18" />
861
+ <line x1="6" y1="6" x2="18" y2="18" />
862
+ </svg>
863
+ </button>
864
+ </div>
865
+ </div>
866
+ <div id="terminal-history" class="terminal-history">
867
+ <div class="terminal-welcome">
868
+ Type a command and press Enter or Run
869
+ </div>
870
+ </div>
871
+ <div class="terminal-input-row">
872
+ <span class="terminal-prompt-symbol">$</span>
873
+ <input
874
+ id="terminal-input"
875
+ type="text"
876
+ class="terminal-input"
877
+ placeholder="npm install … · node script.js · ls -la"
878
+ spellcheck="false"
879
+ autocomplete="off"
880
+ autocorrect="off"
881
+ autocapitalize="off"
882
+ />
883
+ <button id="terminal-run-btn" class="terminal-run-btn" type="button">
884
+ Run
885
+ </button>
886
+ </div>
887
+ </section>
888
+
889
+ <!-- Toast notifications -->
890
+ <div
891
+ id="toast-region"
892
+ class="toast-region"
893
+ aria-live="polite"
894
+ aria-atomic="true"
895
+ ></div>
896
+
897
+ <!-- Env Variables Bottom Sheet -->
898
+ <div id="env-modal-scrim" class="bottom-sheet-scrim"></div>
899
+ <section
900
+ id="env-panel"
901
+ class="bottom-sheet env-sheet"
902
+ aria-label="Environment variables"
903
+ >
904
+ <div class="bottom-sheet-handle"></div>
905
+ <div class="env-header">
906
+ <div>
907
+ <p class="env-title">Environment Variables</p>
908
+ <p class="sheet-subtitle">
909
+ Injected into process.env at execution time
910
+ </p>
911
+ </div>
912
+ <div class="bottom-sheet-actions">
913
+ <button id="add-env-button" class="btn-ghost small" type="button">
914
+ + Variable
915
+ </button>
916
+ <button id="env-save-button" class="btn-env-save" type="button">
917
+ Save
918
+ </button>
919
+ <button id="env-close-button" class="icon-button" type="button">
920
+ <svg
921
+ width="12"
922
+ height="12"
923
+ viewBox="0 0 24 24"
924
+ fill="none"
925
+ stroke="currentColor"
926
+ stroke-width="2"
927
+ >
928
+ <line x1="18" y1="6" x2="6" y2="18" />
929
+ <line x1="6" y1="6" x2="18" y2="18" />
930
+ </svg>
931
+ </button>
932
+ </div>
933
+ </div>
934
+ <!-- Table header for set variables -->
935
+
936
+ <div id="env-list" class="env-list"></div>
937
+ </section>
938
+
939
+ <!-- AI Assistant Bottom Sheet -->
940
+ <div id="ai-modal-scrim" class="bottom-sheet-scrim"></div>
941
+ <section
942
+ id="ai-assistant-sheet"
943
+ class="bottom-sheet ai-sheet"
944
+ aria-label="AI assistant"
945
+ >
946
+ <div class="bottom-sheet-handle"></div>
947
+ <div class="env-header">
948
+ <div class="ai-header-left">
949
+ <p class="env-title">AI Assistant</p>
950
+ <p id="ai-sheet-subtitle" class="sheet-subtitle">
951
+ Ask about the active cell
952
+ </p>
953
+ </div>
954
+ <div class="bottom-sheet-actions">
955
+ <div class="ai-model-wrap">
956
+ <label class="ai-model-label">Model</label>
957
+ <select id="ai-model-select" class="ai-model-select"></select>
958
+ </div>
959
+ <button
960
+ id="ai-close-button"
961
+ class="icon-button"
962
+ type="button"
963
+ title="Close"
964
+ >
965
+ <svg
966
+ width="12"
967
+ height="12"
968
+ viewBox="0 0 24 24"
969
+ fill="none"
970
+ stroke="currentColor"
971
+ stroke-width="2"
972
+ >
973
+ <line x1="18" y1="6" x2="6" y2="18" />
974
+ <line x1="6" y1="6" x2="18" y2="18" />
975
+ </svg>
976
+ </button>
977
+ </div>
978
+ </div>
979
+ <div id="ai-missing-key" class="ai-missing-key hidden">
980
+ <div class="ai-key-hero">
981
+ <svg
982
+ class="ai-key-icon"
983
+ width="32"
984
+ height="32"
985
+ viewBox="0 0 24 24"
986
+ fill="none"
987
+ stroke="currentColor"
988
+ stroke-width="1.5"
989
+ stroke-linecap="round"
990
+ stroke-linejoin="round"
991
+ >
992
+ <path
993
+ d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"
994
+ />
995
+ </svg>
996
+ <p class="ai-key-title">Groq API Key Required</p>
997
+ <p class="ai-key-sub">
998
+ Connect a free Groq key to unlock the AI assistant — fast LLM
999
+ inference at no cost.
1000
+ </p>
1001
+ </div>
1002
+
1003
+ <ol class="ai-key-steps">
1004
+ <li>
1005
+ <span class="ai-step-num">1</span>
1006
+ <div class="ai-step-body">
1007
+ <strong>Create a free Groq account</strong>
1008
+ <span
1009
+ >Visit
1010
+ <a
1011
+ href="https://console.groq.com"
1012
+ target="_blank"
1013
+ rel="noopener"
1014
+ class="ai-step-link"
1015
+ >console.groq.com</a
1016
+ >
1017
+ and sign up — it's free, no credit card needed.</span
1018
+ >
1019
+ </div>
1020
+ </li>
1021
+ <li>
1022
+ <span class="ai-step-num">2</span>
1023
+ <div class="ai-step-body">
1024
+ <strong>Generate an API key</strong>
1025
+ <span
1026
+ >In the Groq console, go to <em>API Keys</em> →
1027
+ <em>Create API Key</em>. Copy the key shown — you won't see it
1028
+ again.</span
1029
+ >
1030
+ </div>
1031
+ </li>
1032
+ <li>
1033
+ <span class="ai-step-num">3</span>
1034
+ <div class="ai-step-body">
1035
+ <strong>Add it to Environment Variables</strong>
1036
+ <span
1037
+ >Click the <em>🔑 Env</em> button in the left sidebar, add a
1038
+ variable named <code>GROQ_API_KEY</code>, paste your key as the
1039
+ value, then click <strong>Save</strong>.</span
1040
+ >
1041
+ </div>
1042
+ </li>
1043
+ <li>
1044
+ <span class="ai-step-num">4</span>
1045
+ <div class="ai-step-body">
1046
+ <strong>Reopen this panel</strong>
1047
+ <span
1048
+ >Close and reopen the AI Assistant — it will detect your key
1049
+ automatically and be ready to use.</span
1050
+ >
1051
+ </div>
1052
+ </li>
1053
+ </ol>
1054
+
1055
+ <button class="ai-key-env-btn" id="ai-open-env-btn" type="button">
1056
+ <svg
1057
+ width="13"
1058
+ height="13"
1059
+ viewBox="0 0 24 24"
1060
+ fill="none"
1061
+ stroke="currentColor"
1062
+ stroke-width="2"
1063
+ >
1064
+ <circle cx="12" cy="12" r="3" />
1065
+ <path
1066
+ d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"
1067
+ />
1068
+ </svg>
1069
+ Open Environment Variables
1070
+ </button>
1071
+ </div>
1072
+ <div id="ai-chat-list" class="ai-chat-list"></div>
1073
+ <form id="ai-chat-form" class="ai-chat-form">
1074
+ <textarea
1075
+ id="ai-chat-input"
1076
+ class="ai-input"
1077
+ rows="2"
1078
+ placeholder="Ask the assistant… (Enter to send, Shift+Enter for new line)"
1079
+ ></textarea>
1080
+ <button id="ai-send-button" class="btn-primary" type="submit">
1081
+ Send ↑
1082
+ </button>
1083
+ </form>
1084
+ </section>
1085
+
1086
+ <!-- Package Docs Drawer -->
1087
+ <div id="package-docs-scrim" class="pkg-docs-scrim"></div>
1088
+ <aside
1089
+ id="package-docs-drawer"
1090
+ class="pkg-docs-drawer"
1091
+ aria-label="Package documentation"
1092
+ >
1093
+ <div class="pkg-docs-header">
1094
+ <div>
1095
+ <p class="pkg-docs-label">Package docs</p>
1096
+ <h2 id="package-docs-title" class="pkg-docs-title">
1097
+ Select a package
1098
+ </h2>
1099
+ <p id="package-docs-version" class="pkg-docs-version hidden"></p>
1100
+ </div>
1101
+ <button id="package-docs-close" class="icon-button" type="button">
1102
+ <svg
1103
+ width="14"
1104
+ height="14"
1105
+ viewBox="0 0 24 24"
1106
+ fill="none"
1107
+ stroke="currentColor"
1108
+ stroke-width="2"
1109
+ >
1110
+ <line x1="18" y1="6" x2="6" y2="18" />
1111
+ <line x1="6" y1="6" x2="18" y2="18" />
1112
+ </svg>
1113
+ </button>
1114
+ </div>
1115
+ <div id="package-docs-status" class="pkg-docs-status">
1116
+ Click a package to load its README.
1117
+ </div>
1118
+ <div id="package-docs-content" class="pkg-docs-content hidden"></div>
1119
+ </aside>
1120
+
1121
+ <!-- New Notebook Filename Dialog -->
1122
+ <div id="new-nb-scrim" class="modal-scrim"></div>
1123
+ <div
1124
+ id="new-nb-modal"
1125
+ class="confirm-modal"
1126
+ role="dialog"
1127
+ aria-modal="true"
1128
+ >
1129
+ <div class="confirm-card">
1130
+ <h3>New Notebook</h3>
1131
+ <p style="margin-bottom: 8px; font-size: 13px; opacity: 0.7">
1132
+ Enter a file name or path (e.g. <code>notes.ijsnb</code> or
1133
+ <code>courses/basic</code>)
1134
+ </p>
1135
+ <input
1136
+ id="new-nb-input"
1137
+ type="text"
1138
+ placeholder="my_notebook or courses/basic"
1139
+ style="
1140
+ width: 100%;
1141
+ box-sizing: border-box;
1142
+ padding: 8px 10px;
1143
+ border-radius: 6px;
1144
+ border: 1px solid var(--border);
1145
+ background: var(--bg-input, var(--bg));
1146
+ color: var(--text);
1147
+ font-size: 14px;
1148
+ outline: none;
1149
+ margin-bottom: 4px;
1150
+ "
1151
+ />
1152
+ <p
1153
+ id="new-nb-error"
1154
+ style="
1155
+ color: var(--color-error, #f56565);
1156
+ font-size: 12px;
1157
+ min-height: 16px;
1158
+ margin: 4px 0 8px;
1159
+ "
1160
+ ></p>
1161
+ <div class="confirm-actions">
1162
+ <button id="new-nb-cancel" class="btn-ghost" type="button">
1163
+ Cancel
1164
+ </button>
1165
+ <button id="new-nb-confirm" class="btn-primary" type="button">
1166
+ Create
1167
+ </button>
1168
+ </div>
1169
+ </div>
1170
+ </div>
1171
+
1172
+ <!-- Confirm Modal -->
1173
+ <div id="confirm-scrim" class="modal-scrim"></div>
1174
+ <div
1175
+ id="confirm-modal"
1176
+ class="confirm-modal"
1177
+ role="dialog"
1178
+ aria-modal="true"
1179
+ >
1180
+ <div class="confirm-card">
1181
+ <h3 id="confirm-title">Are you sure?</h3>
1182
+ <p id="confirm-message">This action cannot be undone.</p>
1183
+ <div class="confirm-actions">
1184
+ <button id="confirm-cancel" class="btn-ghost" type="button">
1185
+ Cancel
1186
+ </button>
1187
+ <button id="confirm-confirm" class="btn-danger" type="button">
1188
+ Delete
1189
+ </button>
1190
+ </div>
1191
+ </div>
1192
+ </div>
1193
+
1194
+ <!-- ══════════════════════════════════════════════
1195
+ CELL TEMPLATE
1196
+ ══════════════════════════════════════════════ -->
1197
+ <template id="cell-template">
1198
+ <article class="notebook-cell">
1199
+ <div class="cell-content">
1200
+ <div class="cell-frame">
1201
+ <div class="cell-topbar">
1202
+ <div class="cell-topbar-left">
1203
+ <span class="execution-count">[ ]</span>
1204
+ <span class="cell-status-badge"></span>
1205
+ <span class="cell-timing"></span>
1206
+ </div>
1207
+ <div class="cell-tools">
1208
+ <button
1209
+ class="cell-tool-btn move-up"
1210
+ type="button"
1211
+ title="Move up"
1212
+ >
1213
+ <svg
1214
+ width="12"
1215
+ height="12"
1216
+ viewBox="0 0 24 24"
1217
+ fill="none"
1218
+ stroke="currentColor"
1219
+ stroke-width="2.5"
1220
+ >
1221
+ <polyline points="18 15 12 9 6 15" />
1222
+ </svg>
1223
+ </button>
1224
+ <button
1225
+ class="cell-tool-btn move-down"
1226
+ type="button"
1227
+ title="Move down"
1228
+ >
1229
+ <svg
1230
+ width="12"
1231
+ height="12"
1232
+ viewBox="0 0 24 24"
1233
+ fill="none"
1234
+ stroke="currentColor"
1235
+ stroke-width="2.5"
1236
+ >
1237
+ <polyline points="6 9 12 15 18 9" />
1238
+ </svg>
1239
+ </button>
1240
+
1241
+ <button
1242
+ class="cell-tool-btn ai-assist-button"
1243
+ type="button"
1244
+ title="AI assist"
1245
+ >
1246
+ <svg
1247
+ width="12"
1248
+ height="12"
1249
+ viewBox="0 0 24 24"
1250
+ fill="none"
1251
+ stroke="currentColor"
1252
+ stroke-width="2"
1253
+ >
1254
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
1255
+ </svg>
1256
+ </button>
1257
+ <button
1258
+ class="cell-tool-btn delete-cell"
1259
+ type="button"
1260
+ title="Delete cell"
1261
+ >
1262
+ <svg
1263
+ width="12"
1264
+ height="12"
1265
+ viewBox="0 0 24 24"
1266
+ fill="none"
1267
+ stroke="currentColor"
1268
+ stroke-width="2"
1269
+ >
1270
+ <polyline points="3 6 5 6 21 6" />
1271
+ <path
1272
+ d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
1273
+ />
1274
+ </svg>
1275
+ </button>
1276
+ <button class="cell-run-button" type="button" title="Run cell">
1277
+ <svg
1278
+ width="12"
1279
+ height="12"
1280
+ viewBox="0 0 24 24"
1281
+ fill="currentColor"
1282
+ >
1283
+ <polygon points="5 3 19 12 5 21 5 3" />
1284
+ </svg>
1285
+ Run
1286
+ </button>
1287
+ </div>
1288
+ </div>
1289
+
1290
+ <div class="cell-body">
1291
+ <div class="editor-host"></div>
1292
+ <textarea
1293
+ class="markdown-editor hidden"
1294
+ spellcheck="false"
1295
+ ></textarea>
1296
+ <div class="prompt-panel hidden">
1297
+ <div class="prompt-toolbar">
1298
+ <select class="prompt-model-select select-sm"></select>
1299
+ <label class="prompt-temp-label">
1300
+ Temp
1301
+ <input
1302
+ class="prompt-temperature-input"
1303
+ type="number"
1304
+ min="0"
1305
+ max="2"
1306
+ step="0.1"
1307
+ value="0.7"
1308
+ />
1309
+ </label>
1310
+ <span class="prompt-token-count">0 tokens</span>
1311
+ </div>
1312
+ <textarea
1313
+ class="prompt-system-input"
1314
+ spellcheck="false"
1315
+ placeholder="System prompt (optional)…"
1316
+ ></textarea>
1317
+ <textarea
1318
+ class="prompt-editor"
1319
+ spellcheck="false"
1320
+ placeholder="Write your prompt here…"
1321
+ ></textarea>
1322
+ </div>
1323
+ <div class="markdown-preview rendered-markdown hidden"></div>
1324
+ <div class="output-panel hidden"></div>
1325
+ </div>
1326
+ </div>
1327
+
1328
+ <!-- Fixed-height insert row — no flicker -->
1329
+ <div class="insert-row">
1330
+ <button class="insert-btn insert-code" type="button">+ Code</button>
1331
+ <button class="insert-btn insert-markdown" type="button">
1332
+ + Text
1333
+ </button>
1334
+ </div>
1335
+ </div>
1336
+ </article>
1337
+ </template>
1338
+
1339
+ <script src="/vendor/monaco/vs/loader.js"></script>
1340
+ <script type="module" src="/app.js"></script>
1341
+ </body>
1342
+ </html>