@pb33f/cowboy-components 0.7.17 → 0.8.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 (540) hide show
  1. package/dist/_basePickBy-DtTwxTrV.js +151 -0
  2. package/dist/_baseUniq-C5Y4WFmx.js +614 -0
  3. package/dist/arc-a-7w7y90.js +83 -0
  4. package/dist/architecture-U656AL7Q-c_zxypEp.js +5 -0
  5. package/dist/architectureDiagram-VXUJARFQ-CIhQJ6xS.js +4661 -0
  6. package/dist/assets/elk-layout.worker-B71_NI2D.js +1 -0
  7. package/dist/assets/equalizer.worker-A8HFNy4g.js +1 -0
  8. package/dist/assets/graph-dependent.worker-BgWuMZsb.js +1 -0
  9. package/dist/assets/rule-documentation.worker-BCKuwSgZ.js +1 -0
  10. package/dist/assets/search-graph.worker-Cwqb-ecv.js +1 -0
  11. package/dist/assets/search-problems.worker-60kZqr0h.js +1 -0
  12. package/dist/blockDiagram-VD42YOAC-BLl5ID-l.js +2261 -0
  13. package/dist/c4Diagram-YG6GDRKO-BOGfb13x.js +1580 -0
  14. package/dist/channel-DYeI56io.js +5 -0
  15. package/dist/chunk-4BX2VUAB-BeHGB7ON.js +8 -0
  16. package/dist/chunk-55IACEB6-DgHUzWsw.js +8 -0
  17. package/dist/chunk-B4BG7PRW-Vs7GiQMf.js +1375 -0
  18. package/dist/chunk-DI55MBZ5-CHjdGXx0.js +1370 -0
  19. package/dist/chunk-FMBD7UC4-D-H9-bHN.js +19 -0
  20. package/dist/chunk-QN33PNHL-D7uE2r1Y.js +19 -0
  21. package/dist/chunk-QZHKN3VN-Cp3sUp7e.js +15 -0
  22. package/dist/chunk-TZMSLE5B-BmXGcXo9.js +64 -0
  23. package/dist/classDiagram-2ON5EDUG-9ilqiDEi.js +16 -0
  24. package/dist/classDiagram-v2-WZHVMYZB-9ilqiDEi.js +16 -0
  25. package/dist/clone-CybyMoa0.js +8 -0
  26. package/dist/components/attention-box/attention-box.css.js +8 -0
  27. package/dist/components/auth/login-button.js +1 -1
  28. package/dist/components/auth/login-panel.d.ts +4 -0
  29. package/dist/components/auth/login-panel.js +12 -4
  30. package/dist/components/auth/oauth-login.css.js +4 -0
  31. package/dist/components/auth/oauth-login.d.ts +2 -0
  32. package/dist/components/auth/oauth-login.js +12 -3
  33. package/dist/components/brokerable.d.ts +21 -0
  34. package/dist/components/brokerable.js +39 -0
  35. package/dist/components/bundle-toolbar/bundle-toolbar.css.js +110 -0
  36. package/dist/components/bundle-toolbar/bundle-toolbar.d.ts +21 -0
  37. package/dist/components/bundle-toolbar/bundle-toolbar.js +93 -0
  38. package/dist/components/changelog/changelog.css.js +2 -0
  39. package/dist/components/changelog/changelog.d.ts +2 -0
  40. package/dist/components/changelog/changelog.js +10 -1
  41. package/dist/components/changelog/release.css.js +5 -1
  42. package/dist/components/charts/beefy-chart.js +0 -2
  43. package/dist/components/charts/doughnut-chart.d.ts +5 -1
  44. package/dist/components/charts/doughnut-chart.js +20 -1
  45. package/dist/components/credit-ticker/credit-ticker.d.ts +3 -0
  46. package/dist/components/credit-ticker/credit-ticker.js +20 -4
  47. package/dist/components/details-drawer/details-drawer.css.d.ts +2 -0
  48. package/dist/components/{problem-list → details-drawer}/details-drawer.css.js +18 -3
  49. package/dist/components/details-drawer/generic-details-drawer.css.d.ts +1 -0
  50. package/dist/components/details-drawer/generic-details-drawer.css.js +219 -0
  51. package/dist/components/details-drawer/generic-details-drawer.d.ts +38 -0
  52. package/dist/components/details-drawer/generic-details-drawer.js +245 -0
  53. package/dist/components/details-drawer/handlers/diagram-handler.d.ts +35 -0
  54. package/dist/components/details-drawer/handlers/diagram-handler.js +248 -0
  55. package/dist/components/details-drawer/handlers/documentation-handler.d.ts +11 -0
  56. package/dist/components/details-drawer/handlers/documentation-handler.js +46 -0
  57. package/dist/components/details-drawer/handlers/example-handler.d.ts +18 -0
  58. package/dist/components/details-drawer/handlers/example-handler.js +146 -0
  59. package/dist/components/details-drawer/handlers/howto-handler.d.ts +11 -0
  60. package/dist/components/details-drawer/handlers/howto-handler.js +36 -0
  61. package/dist/components/details-drawer/handlers/markdown-handler.d.ts +12 -0
  62. package/dist/components/details-drawer/handlers/markdown-handler.js +54 -0
  63. package/dist/components/editor/editor-breadcrumb.css.js +1 -1
  64. package/dist/components/editor/editor.css.js +42 -0
  65. package/dist/components/editor/editor.d.ts +29 -3
  66. package/dist/components/editor/editor.js +495 -73
  67. package/dist/components/github/github-workspace-view.css.d.ts +2 -0
  68. package/dist/components/github/github-workspace-view.css.js +165 -0
  69. package/dist/components/github/github-workspace-view.d.ts +59 -0
  70. package/dist/components/github/github-workspace-view.js +525 -0
  71. package/dist/components/global-task/global-task-view.css.d.ts +2 -0
  72. package/dist/components/global-task/global-task-view.css.js +392 -0
  73. package/dist/components/global-task/global-task-view.d.ts +48 -0
  74. package/dist/components/global-task/global-task-view.js +359 -0
  75. package/dist/components/header/header.css.js +9 -1
  76. package/dist/components/http-method/http-method.css.js +5 -1
  77. package/dist/components/indeterminate-loader/indeterminate-loader.css.d.ts +2 -0
  78. package/dist/components/indeterminate-loader/indeterminate-loader.css.js +135 -0
  79. package/dist/components/indeterminate-loader/indeterminate-loader.d.ts +35 -0
  80. package/dist/components/indeterminate-loader/indeterminate-loader.js +201 -0
  81. package/dist/components/kv-view/kv-view.css.js +2 -0
  82. package/dist/components/kv-view/kv-view.js +0 -1
  83. package/dist/components/logo-wall/logo-wall.css.js +9 -0
  84. package/dist/components/manage-ruleset/manage-ruleset.css.js +14 -1
  85. package/dist/components/manage-ruleset/manage-ruleset.d.ts +1 -0
  86. package/dist/components/manage-ruleset/manage-ruleset.js +54 -22
  87. package/dist/components/manage-ruleset/rule-action.css.js +2 -0
  88. package/dist/components/manage-ruleset/rule-action.d.ts +10 -3
  89. package/dist/components/manage-ruleset/rule-action.js +118 -129
  90. package/dist/components/manage-ruleset/rule-input.d.ts +3 -1
  91. package/dist/components/manage-ruleset/rule-input.js +38 -34
  92. package/dist/components/manage-ruleset/rule.css.js +15 -1
  93. package/dist/components/manage-ruleset/rule.d.ts +4 -1
  94. package/dist/components/manage-ruleset/rule.js +44 -17
  95. package/dist/components/mermaid/mermaid-renderer.css.d.ts +1 -0
  96. package/dist/components/mermaid/mermaid-renderer.css.js +121 -0
  97. package/dist/components/mermaid/mermaid-renderer.d.ts +75 -0
  98. package/dist/components/mermaid/mermaid-renderer.js +485 -0
  99. package/dist/components/model-icon/doctor-icon.d.ts +9 -0
  100. package/dist/components/model-icon/doctor-icon.js +60 -0
  101. package/dist/components/model-icon/model-icon.d.ts +2 -1
  102. package/dist/components/model-icon/model-icon.js +13 -1
  103. package/dist/components/model-renderer/change.css.js +22 -8
  104. package/dist/components/model-renderer/changes.d.ts +1 -0
  105. package/dist/components/model-renderer/changes.js +47 -32
  106. package/dist/components/model-renderer/clickable-ref.d.ts +9 -3
  107. package/dist/components/model-renderer/clickable-ref.js +49 -10
  108. package/dist/components/model-renderer/components.d.ts +2 -0
  109. package/dist/components/model-renderer/components.js +196 -116
  110. package/dist/components/model-renderer/contact.js +2 -2
  111. package/dist/components/model-renderer/description.css.js +2 -0
  112. package/dist/components/model-renderer/document.d.ts +1 -0
  113. package/dist/components/model-renderer/document.js +14 -9
  114. package/dist/components/model-renderer/encoding.d.ts +2 -0
  115. package/dist/components/model-renderer/encoding.js +16 -7
  116. package/dist/components/model-renderer/example.css.js +5 -1
  117. package/dist/components/model-renderer/example.d.ts +4 -1
  118. package/dist/components/model-renderer/example.js +72 -118
  119. package/dist/components/model-renderer/extensions.d.ts +2 -0
  120. package/dist/components/model-renderer/extensions.js +11 -2
  121. package/dist/components/model-renderer/external-docs.d.ts +2 -0
  122. package/dist/components/model-renderer/external-docs.js +13 -4
  123. package/dist/components/model-renderer/has-changes.js +3 -3
  124. package/dist/components/model-renderer/header.d.ts +2 -0
  125. package/dist/components/model-renderer/header.js +27 -14
  126. package/dist/components/model-renderer/info.d.ts +2 -0
  127. package/dist/components/model-renderer/info.js +20 -7
  128. package/dist/components/model-renderer/link.d.ts +2 -0
  129. package/dist/components/model-renderer/link.js +27 -10
  130. package/dist/components/model-renderer/media-type.js +2 -2
  131. package/dist/components/model-renderer/model-badge.d.ts +11 -0
  132. package/dist/components/model-renderer/model-badge.js +59 -0
  133. package/dist/components/model-renderer/model-shared.css.js +14 -2
  134. package/dist/components/model-renderer/oauth-flows.js +4 -4
  135. package/dist/components/model-renderer/operation.d.ts +2 -1
  136. package/dist/components/model-renderer/operation.js +37 -16
  137. package/dist/components/model-renderer/param-location.js +3 -3
  138. package/dist/components/model-renderer/parameter.d.ts +2 -0
  139. package/dist/components/model-renderer/parameter.js +28 -15
  140. package/dist/components/model-renderer/path-item.d.ts +3 -0
  141. package/dist/components/model-renderer/path-item.js +52 -80
  142. package/dist/components/model-renderer/paths.d.ts +2 -0
  143. package/dist/components/model-renderer/paths.js +10 -3
  144. package/dist/components/model-renderer/problem-node.js +10 -10
  145. package/dist/components/model-renderer/rendered-node.css.js +35 -6
  146. package/dist/components/model-renderer/rendered-node.d.ts +14 -4
  147. package/dist/components/model-renderer/rendered-node.js +121 -58
  148. package/dist/components/model-renderer/rendered-property.js +4 -4
  149. package/dist/components/model-renderer/request-body.d.ts +2 -0
  150. package/dist/components/model-renderer/request-body.js +16 -9
  151. package/dist/components/model-renderer/response.d.ts +2 -0
  152. package/dist/components/model-renderer/response.js +35 -17
  153. package/dist/components/model-renderer/schema.css.js +10 -1
  154. package/dist/components/model-renderer/schema.d.ts +3 -2
  155. package/dist/components/model-renderer/schema.js +127 -129
  156. package/dist/components/model-renderer/security-scheme.js +3 -3
  157. package/dist/components/model-renderer/server.js +18 -8
  158. package/dist/components/model-renderer/tag.js +1 -1
  159. package/dist/components/model-tree/tree.css.js +21 -10
  160. package/dist/components/model-tree/tree.d.ts +39 -22
  161. package/dist/components/model-tree/tree.js +230 -167
  162. package/dist/components/paginator/paginator-navigator.css.js +9 -5
  163. package/dist/components/paginator/paginator-navigator.js +6 -6
  164. package/dist/components/paginator/paginator.css.js +2 -0
  165. package/dist/components/paginator/paginator.js +5 -8
  166. package/dist/components/percent-bar/percent-bar.css.js +133 -13
  167. package/dist/components/percent-bar/percent-bar.d.ts +2 -0
  168. package/dist/components/percent-bar/percent-bar.js +28 -24
  169. package/dist/components/premium-gate/premium-gate.css.d.ts +1 -0
  170. package/dist/components/premium-gate/premium-gate.css.js +117 -0
  171. package/dist/components/premium-gate/premium-gate.d.ts +49 -0
  172. package/dist/components/premium-gate/premium-gate.js +336 -0
  173. package/dist/components/problem-list/problem-list.css.js +72 -1
  174. package/dist/components/problem-list/problem-list.d.ts +17 -9
  175. package/dist/components/problem-list/problem-list.js +222 -226
  176. package/dist/components/problem-list/problem-mainview.css.js +12 -2
  177. package/dist/components/problem-list/problem-mainview.d.ts +3 -0
  178. package/dist/components/problem-list/problem-mainview.js +37 -17
  179. package/dist/components/problem-list/problem-toolbar.css.js +10 -7
  180. package/dist/components/problems-overview/diagnostic-evaluation.css.js +11 -1
  181. package/dist/components/problems-overview/diagnostic-evaluation.js +6 -7
  182. package/dist/components/problems-overview/document-statistic.css.js +6 -0
  183. package/dist/components/problems-overview/document-statistic.js +1 -1
  184. package/dist/components/problems-overview/problem-overview-group.js +5 -5
  185. package/dist/components/problems-overview/problem-statistic.css.js +24 -5
  186. package/dist/components/problems-overview/problem-statistic.js +15 -6
  187. package/dist/components/problems-overview/problem-statistics.css.js +4 -4
  188. package/dist/components/problems-overview/problem-statistics.js +29 -25
  189. package/dist/components/problems-overview/problems-overview.css.js +2 -2
  190. package/dist/components/property-view/property-view.css.js +2 -0
  191. package/dist/components/render-json-path/render-json-path.css.js +11 -3
  192. package/dist/components/render-json-path/render-json-path.js +3 -0
  193. package/dist/components/render-operation-path/render-operation-path.css.js +9 -0
  194. package/dist/components/render-operation-path/render-operation-path.js +7 -22
  195. package/dist/components/rodeo/rodeo.d.ts +1 -0
  196. package/dist/components/rodeo/rodeo.js +5 -0
  197. package/dist/components/rodeo/roundup.js +2 -2
  198. package/dist/components/rodeo/statistic.css.js +25 -2
  199. package/dist/components/rodeo/statistic.js +0 -4
  200. package/dist/components/shader-canvas/shader-canvas.css.d.ts +2 -0
  201. package/dist/components/shader-canvas/shader-canvas.css.js +66 -0
  202. package/dist/components/shader-canvas/shader-canvas.d.ts +36 -0
  203. package/dist/components/shader-canvas/shader-canvas.js +363 -0
  204. package/dist/components/shaders/flowing-waves-shader.d.ts +2 -0
  205. package/dist/components/shaders/flowing-waves-shader.js +70 -0
  206. package/dist/components/shaders/neon-canyon-shader.d.ts +2 -0
  207. package/dist/components/shaders/neon-canyon-shader.js +265 -0
  208. package/dist/components/shaders/neon-lines-shader.d.ts +2 -0
  209. package/dist/components/shaders/neon-lines-shader.js +181 -0
  210. package/dist/components/shaders/neon-squircles-shader.d.ts +2 -0
  211. package/dist/components/shaders/neon-squircles-shader.js +56 -0
  212. package/dist/components/shaders/retro-grid-shader.d.ts +2 -0
  213. package/dist/components/shaders/retro-grid-shader.js +53 -0
  214. package/dist/components/shaders/shader-base.d.ts +9 -0
  215. package/dist/components/shaders/shader-base.js +11 -0
  216. package/dist/components/terminal/terminal-example.css.js +4 -0
  217. package/dist/components/terminal/terminal-example.js +2 -3
  218. package/dist/components/terminal-emulator/terminal-emulator.css.js +12 -2
  219. package/dist/components/terminal-emulator/terminal-emulator.d.ts +7 -1
  220. package/dist/components/terminal-emulator/terminal-emulator.js +10 -5
  221. package/dist/components/the-doctor/doctor-controls-panel.css.d.ts +2 -0
  222. package/dist/components/the-doctor/doctor-controls-panel.css.js +53 -0
  223. package/dist/components/the-doctor/doctor-controls-panel.d.ts +20 -0
  224. package/dist/components/the-doctor/doctor-controls-panel.js +78 -0
  225. package/dist/components/the-doctor/doctor-editor-panel.css.d.ts +2 -0
  226. package/dist/components/the-doctor/doctor-editor-panel.css.js +209 -0
  227. package/dist/components/the-doctor/doctor-editor-panel.d.ts +41 -0
  228. package/dist/components/the-doctor/doctor-editor-panel.js +188 -0
  229. package/dist/components/the-doctor/doctor-navigator-panel.css.d.ts +2 -0
  230. package/dist/components/the-doctor/doctor-navigator-panel.css.js +134 -0
  231. package/dist/components/the-doctor/doctor-navigator-panel.d.ts +35 -0
  232. package/dist/components/the-doctor/doctor-navigator-panel.js +117 -0
  233. package/dist/components/the-doctor/doctor-sidebar-panel.css.d.ts +2 -0
  234. package/dist/components/the-doctor/doctor-sidebar-panel.css.js +143 -0
  235. package/dist/components/the-doctor/doctor-sidebar-panel.d.ts +31 -0
  236. package/dist/components/the-doctor/doctor-sidebar-panel.js +131 -0
  237. package/dist/components/the-doctor/doctor-url-overlay.css.d.ts +2 -0
  238. package/dist/components/the-doctor/doctor-url-overlay.css.js +59 -0
  239. package/dist/components/the-doctor/doctor-url-overlay.d.ts +23 -0
  240. package/dist/components/the-doctor/doctor-url-overlay.js +82 -0
  241. package/dist/components/the-doctor/nuke-workspace.js +4 -3
  242. package/dist/components/the-doctor/settings.css.js +2 -0
  243. package/dist/components/the-doctor/settings.js +5 -8
  244. package/dist/components/the-doctor/status-bar.d.ts +2 -2
  245. package/dist/components/the-doctor/status-bar.js +32 -31
  246. package/dist/components/the-doctor/the-doctor.css.js +47 -238
  247. package/dist/components/the-doctor/the-doctor.d.ts +149 -37
  248. package/dist/components/the-doctor/the-doctor.js +958 -528
  249. package/dist/components/the-doctor/upload-archive.css.js +8 -2
  250. package/dist/components/the-doctor/upload-archive.js +2 -2
  251. package/dist/components/theme-switcher/theme-switcher.js +5 -1
  252. package/dist/components/time-vortex/change-list-item.css.js +18 -4
  253. package/dist/components/time-vortex/change-list-item.d.ts +1 -0
  254. package/dist/components/time-vortex/change-list-item.js +4 -3
  255. package/dist/components/time-vortex/history-picker.css.js +60 -1
  256. package/dist/components/time-vortex/history-picker.d.ts +7 -1
  257. package/dist/components/time-vortex/history-picker.js +109 -5
  258. package/dist/components/time-vortex/tardis-control.css.js +339 -14
  259. package/dist/components/time-vortex/tardis-control.d.ts +31 -3
  260. package/dist/components/time-vortex/tardis-control.js +296 -58
  261. package/dist/components/time-vortex/time-vortex.d.ts +8 -2
  262. package/dist/components/time-vortex/time-vortex.js +54 -13
  263. package/dist/components/toast/toast-component.css.js +1 -0
  264. package/dist/components/toast/toast-component.d.ts +1 -0
  265. package/dist/components/toast/toast-component.js +23 -8
  266. package/dist/components/toast/toast-manager.d.ts +5 -0
  267. package/dist/components/toast/toast-manager.js +29 -7
  268. package/dist/components/visualizer/edge.d.ts +11 -1
  269. package/dist/components/visualizer/edge.js +27 -22
  270. package/dist/components/visualizer/equalizer.css.js +118 -76
  271. package/dist/components/visualizer/equalizer.d.ts +24 -45
  272. package/dist/components/visualizer/equalizer.js +262 -363
  273. package/dist/components/visualizer/explorer.d.ts +94 -14
  274. package/dist/components/visualizer/explorer.js +580 -393
  275. package/dist/components/visualizer/foreign-object.d.ts +12 -2
  276. package/dist/components/visualizer/foreign-object.js +21 -10
  277. package/dist/components/visualizer/key.js +12 -1
  278. package/dist/components/visualizer/nodes/callback.d.ts +2 -1
  279. package/dist/components/visualizer/nodes/callback.js +2 -2
  280. package/dist/components/visualizer/nodes/components.d.ts +2 -1
  281. package/dist/components/visualizer/nodes/components.js +2 -2
  282. package/dist/components/visualizer/nodes/contact.d.ts +2 -1
  283. package/dist/components/visualizer/nodes/contact.js +2 -2
  284. package/dist/components/visualizer/nodes/document.d.ts +2 -1
  285. package/dist/components/visualizer/nodes/document.js +2 -2
  286. package/dist/components/visualizer/nodes/graph-node.d.ts +14 -3
  287. package/dist/components/visualizer/nodes/graph-node.js +94 -43
  288. package/dist/components/visualizer/nodes/header.d.ts +2 -1
  289. package/dist/components/visualizer/nodes/header.js +2 -2
  290. package/dist/components/visualizer/nodes/info.d.ts +2 -1
  291. package/dist/components/visualizer/nodes/info.js +2 -2
  292. package/dist/components/visualizer/nodes/license.d.ts +2 -1
  293. package/dist/components/visualizer/nodes/license.js +2 -2
  294. package/dist/components/visualizer/nodes/link.d.ts +2 -1
  295. package/dist/components/visualizer/nodes/link.js +2 -2
  296. package/dist/components/visualizer/nodes/media-type.d.ts +2 -1
  297. package/dist/components/visualizer/nodes/media-type.js +2 -2
  298. package/dist/components/visualizer/nodes/operation.d.ts +2 -1
  299. package/dist/components/visualizer/nodes/operation.js +3 -4
  300. package/dist/components/visualizer/nodes/parameter.d.ts +3 -1
  301. package/dist/components/visualizer/nodes/parameter.js +3 -4
  302. package/dist/components/visualizer/nodes/path-item.d.ts +2 -1
  303. package/dist/components/visualizer/nodes/path-item.js +2 -2
  304. package/dist/components/visualizer/nodes/request-body.d.ts +2 -1
  305. package/dist/components/visualizer/nodes/request-body.js +2 -2
  306. package/dist/components/visualizer/nodes/response.d.ts +2 -1
  307. package/dist/components/visualizer/nodes/response.js +2 -2
  308. package/dist/components/visualizer/nodes/schema.d.ts +2 -1
  309. package/dist/components/visualizer/nodes/schema.js +64 -9
  310. package/dist/components/visualizer/nodes/security-scheme.d.ts +2 -1
  311. package/dist/components/visualizer/nodes/security-scheme.js +2 -2
  312. package/dist/components/visualizer/nodes/server.d.ts +2 -1
  313. package/dist/components/visualizer/nodes/server.js +3 -4
  314. package/dist/components/visualizer/nodes/tag.d.ts +2 -1
  315. package/dist/components/visualizer/nodes/tag.js +4 -5
  316. package/dist/components/visualizer/nodes/xml.d.ts +2 -1
  317. package/dist/components/visualizer/nodes/xml.js +2 -2
  318. package/dist/components/visualizer/orientation-controls.d.ts +6 -1
  319. package/dist/components/visualizer/orientation-controls.js +65 -7
  320. package/dist/components/visualizer/search.d.ts +2 -1
  321. package/dist/components/visualizer/search.js +22 -29
  322. package/dist/components/visualizer/shared.css.js +55 -18
  323. package/dist/components/visualizer/templates/svg-markers.d.ts +2 -0
  324. package/dist/components/visualizer/templates/svg-markers.js +73 -0
  325. package/dist/components/waiting-line/waiting-line.css.d.ts +2 -0
  326. package/dist/components/waiting-line/waiting-line.css.js +26 -0
  327. package/dist/components/waiting-line/waiting-line.d.ts +30 -0
  328. package/dist/components/waiting-line/waiting-line.js +424 -0
  329. package/dist/components/workspaces/workspace-view.css.js +89 -8
  330. package/dist/components/workspaces/workspace-view.d.ts +8 -1
  331. package/dist/components/workspaces/workspace-view.js +77 -25
  332. package/dist/controllers/auth-controller.d.ts +9 -0
  333. package/dist/controllers/auth-controller.js +12 -5
  334. package/dist/controllers/broker-controller.d.ts +30 -4
  335. package/dist/controllers/broker-controller.js +148 -25
  336. package/dist/controllers/bundle-controller.d.ts +21 -0
  337. package/dist/controllers/bundle-controller.js +122 -0
  338. package/dist/controllers/countdown-controller.d.ts +17 -0
  339. package/dist/controllers/countdown-controller.js +59 -0
  340. package/dist/controllers/diagnostic-controller.d.ts +18 -5
  341. package/dist/controllers/diagnostic-controller.js +206 -218
  342. package/dist/controllers/diagramatron-controller.d.ts +33 -0
  343. package/dist/controllers/diagramatron-controller.js +128 -0
  344. package/dist/controllers/docs-controller.d.ts +11 -5
  345. package/dist/controllers/docs-controller.js +97 -97
  346. package/dist/controllers/github-controller.d.ts +47 -0
  347. package/dist/controllers/github-controller.js +494 -0
  348. package/dist/controllers/global-task-controller.d.ts +46 -0
  349. package/dist/controllers/global-task-controller.js +352 -0
  350. package/dist/controllers/model-controller.d.ts +26 -4
  351. package/dist/controllers/model-controller.js +98 -62
  352. package/dist/controllers/node-clicker-controller.d.ts +121 -4
  353. package/dist/controllers/node-clicker-controller.js +526 -253
  354. package/dist/controllers/problem-controller.d.ts +11 -4
  355. package/dist/controllers/problem-controller.js +98 -39
  356. package/dist/controllers/rolodex-controller.d.ts +8 -3
  357. package/dist/controllers/rolodex-controller.js +117 -83
  358. package/dist/controllers/rule-controller.d.ts +12 -5
  359. package/dist/controllers/rule-controller.js +154 -161
  360. package/dist/controllers/spec-controller.d.ts +16 -4
  361. package/dist/controllers/spec-controller.js +91 -62
  362. package/dist/controllers/state-controller.d.ts +4 -3
  363. package/dist/controllers/state-controller.js +201 -154
  364. package/dist/controllers/tab-cache-controller.d.ts +29 -0
  365. package/dist/controllers/tab-cache-controller.js +68 -0
  366. package/dist/controllers/timeline-controller.d.ts +18 -0
  367. package/dist/controllers/timeline-controller.js +129 -0
  368. package/dist/controllers/wallet-controller.d.ts +3 -3
  369. package/dist/controllers/wallet-controller.js +22 -41
  370. package/dist/controllers/workspace-controller.d.ts +10 -4
  371. package/dist/controllers/workspace-controller.js +67 -22
  372. package/dist/cose-bilkent-S5V4N54A-2TG-C-n3.js +2608 -0
  373. package/dist/cowboy-components-BcyXo9oX.js +68425 -0
  374. package/dist/cowboy-components.css +1 -0
  375. package/dist/cowboy-components.umd.cjs +14050 -6577
  376. package/dist/css/alerts.css.js +2 -0
  377. package/dist/css/badges.css.js +2 -0
  378. package/dist/css/button.css.js +34 -1
  379. package/dist/css/cowboy-components.css +34 -0
  380. package/dist/css/dialog.css.js +11 -2
  381. package/dist/css/filter.css.js +17 -5
  382. package/dist/css/forms.css.js +14 -0
  383. package/dist/css/pb33f-theme.css +87 -16
  384. package/dist/css/syntax.css.js +5 -0
  385. package/dist/css/tabs.css.js +19 -2
  386. package/dist/css/tooltip.css.js +4 -0
  387. package/dist/cytoscape.esm-DfdJODL8.js +18735 -0
  388. package/dist/dagre-6UL2VRFP-BIlmTbhO.js +444 -0
  389. package/dist/defaultLocale-D7EN2tov.js +171 -0
  390. package/dist/diagram-PSM6KHXK-CeWby24E.js +531 -0
  391. package/dist/diagram-QEK2KX5R-DGonyVCK.js +217 -0
  392. package/dist/diagram-S2PKOQOG-mGn-y1uX.js +142 -0
  393. package/dist/erDiagram-Q2GNP2WA-BlBBw4Mz.js +841 -0
  394. package/dist/events/doctor.d.ts +63 -9
  395. package/dist/events/doctor.js +29 -1
  396. package/dist/events/drawer-events.d.ts +7 -0
  397. package/dist/events/drawer-events.js +3 -0
  398. package/dist/events/theme.d.ts +4 -0
  399. package/dist/events/theme.js +1 -0
  400. package/dist/factories/explorer-component-factory.d.ts +49 -0
  401. package/dist/factories/explorer-component-factory.js +205 -0
  402. package/dist/factories/state-controller-deps.factory.d.ts +88 -0
  403. package/dist/factories/state-controller-deps.factory.js +116 -0
  404. package/dist/flowDiagram-NV44I4VS-BlLzzy1C.js +1620 -0
  405. package/dist/ganttDiagram-LVOFAZNH-BoQtPC8k.js +2505 -0
  406. package/dist/gitGraph-F6HP7TQM-CShNSlrW.js +5 -0
  407. package/dist/gitGraphDiagram-NY62KEGX-BdpWBgHy.js +699 -0
  408. package/dist/graph-D9HS4Ahd.js +247 -0
  409. package/dist/helpers/event-wiring.d.ts +72 -0
  410. package/dist/helpers/event-wiring.js +58 -0
  411. package/dist/helpers/file-size-formatter.d.ts +3 -0
  412. package/dist/helpers/file-size-formatter.js +15 -0
  413. package/dist/helpers/filename-colorizer.d.ts +5 -0
  414. package/dist/helpers/filename-colorizer.js +30 -0
  415. package/dist/helpers/navigation-helper.d.ts +54 -0
  416. package/dist/helpers/navigation-helper.js +159 -0
  417. package/dist/helpers/typed-events.d.ts +1 -0
  418. package/dist/helpers/typed-events.js +3 -0
  419. package/dist/info-NVLQJR56-Bpi6I8up.js +5 -0
  420. package/dist/infoDiagram-F6ZHWCRC-DmhhbuMJ.js +24 -0
  421. package/dist/init-DjUOC4st.js +16 -0
  422. package/dist/interfaces/bundle-interfaces.d.ts +7 -0
  423. package/dist/interfaces/bundle-interfaces.js +1 -0
  424. package/dist/interfaces/doctor-interfaces.d.ts +506 -0
  425. package/dist/interfaces/doctor-interfaces.js +1 -0
  426. package/dist/journeyDiagram-XKPGCS4Q-CpkhK8vl.js +834 -0
  427. package/dist/kanban-definition-3W4ZIXB7-BFbucfYE.js +719 -0
  428. package/dist/katex-SsTUIUTC.js +11688 -0
  429. package/dist/layout-B8H1_UrM.js +1324 -0
  430. package/dist/linear-Bo0rJUSQ.js +259 -0
  431. package/dist/managers/drag-handler.d.ts +28 -0
  432. package/dist/managers/drag-handler.js +64 -0
  433. package/dist/managers/event-registration-manager.d.ts +17 -0
  434. package/dist/managers/event-registration-manager.js +34 -0
  435. package/dist/managers/expansion-manager.d.ts +58 -0
  436. package/dist/managers/expansion-manager.js +189 -0
  437. package/dist/managers/layout-filter-manager.d.ts +31 -0
  438. package/dist/managers/layout-filter-manager.js +109 -0
  439. package/dist/managers/panel-divider-manager.d.ts +33 -0
  440. package/dist/managers/panel-divider-manager.js +71 -0
  441. package/dist/managers/view-state-manager.d.ts +48 -0
  442. package/dist/managers/view-state-manager.js +101 -0
  443. package/dist/managers/viewport-manager.d.ts +53 -0
  444. package/dist/managers/viewport-manager.js +198 -0
  445. package/dist/mermaid-parser.core-BPror82d.js +12966 -0
  446. package/dist/mindmap-definition-VGOIOE7T-VAn-EShH.js +784 -0
  447. package/dist/mocks/task-mock-generator.d.ts +13 -0
  448. package/dist/mocks/task-mock-generator.js +200 -0
  449. package/dist/model/api-response.d.ts +2 -7
  450. package/dist/model/api-response.js +0 -2
  451. package/dist/model/bundle.d.ts +35 -0
  452. package/dist/model/bundle.js +1 -0
  453. package/dist/model/channels.d.ts +8 -1
  454. package/dist/model/channels.js +7 -0
  455. package/dist/model/drawer-content.d.ts +80 -0
  456. package/dist/model/drawer-content.js +14 -0
  457. package/dist/model/formable.js +22 -11
  458. package/dist/model/github.d.ts +125 -0
  459. package/dist/model/github.js +1 -0
  460. package/dist/model/graph.d.ts +15 -15
  461. package/dist/model/graph.js +24 -4
  462. package/dist/model/media-type.js +2 -2
  463. package/dist/model/node_type.d.ts +4 -0
  464. package/dist/model/node_type.js +4 -0
  465. package/dist/model/panel-state.d.ts +1 -0
  466. package/dist/model/rolodex.d.ts +3 -0
  467. package/dist/model/task.d.ts +50 -0
  468. package/dist/model/task.js +22 -0
  469. package/dist/model/timeline.d.ts +107 -1
  470. package/dist/model/tree-icon-config.d.ts +11 -0
  471. package/dist/model/tree-icon-config.js +46 -0
  472. package/dist/model/workspace.d.ts +2 -0
  473. package/dist/monacoeditorwork/css.worker.bundle.js +9 -7
  474. package/dist/monacoeditorwork/editor.worker.bundle.js +2 -0
  475. package/dist/monacoeditorwork/html.worker.bundle.js +9 -7
  476. package/dist/monacoeditorwork/json.worker.bundle.js +9 -7
  477. package/dist/monacoeditorwork/yaml.worker..bundle.js +72 -48
  478. package/dist/ordinal-DfAQgscy.js +61 -0
  479. package/dist/packet-BFZMPI3H-CXPCK9Q2.js +5 -0
  480. package/dist/pie-7BOR55EZ-CMcuUZ_S.js +5 -0
  481. package/dist/pieDiagram-ADFJNKIX-C0kdlQqn.js +161 -0
  482. package/dist/quadrantDiagram-AYHSOK5B-CRVq6wY3.js +1022 -0
  483. package/dist/radar-NHE76QYJ-CX_Gyp4h.js +5 -0
  484. package/dist/requirementDiagram-UZGBJVZJ-B8ZGgMKn.js +850 -0
  485. package/dist/sankeyDiagram-TZEHDZUN-CWAUJJue.js +810 -0
  486. package/dist/sequenceDiagram-WL72ISMW-nz81a4Cq.js +2511 -0
  487. package/dist/services/diagramatron-service.d.ts +20 -0
  488. package/dist/services/diagramatron-service.js +48 -0
  489. package/dist/services/doctor-events.d.ts +58 -0
  490. package/dist/services/doctor-events.js +33 -0
  491. package/dist/services/drawer-content-registry.d.ts +9 -0
  492. package/dist/services/drawer-content-registry.js +37 -0
  493. package/dist/services/github-service.d.ts +9 -0
  494. package/dist/services/github-service.js +166 -0
  495. package/dist/services/global-task-service.d.ts +6 -0
  496. package/dist/services/global-task-service.js +27 -0
  497. package/dist/services/header-service.d.ts +5 -3
  498. package/dist/services/header-service.js +13 -0
  499. package/dist/services/linting-service.d.ts +2 -0
  500. package/dist/services/linting-service.js +19 -2
  501. package/dist/services/mermaid-config-service.d.ts +53 -0
  502. package/dist/services/mermaid-config-service.js +519 -0
  503. package/dist/services/model-service.d.ts +12 -7
  504. package/dist/services/model-service.js +64 -11
  505. package/dist/services/rodeo-service.js +12 -12
  506. package/dist/services/timeline-service.d.ts +12 -2
  507. package/dist/services/timeline-service.js +329 -0
  508. package/dist/services/wallet-service.d.ts +1 -1
  509. package/dist/services/wallet-service.js +4 -1
  510. package/dist/services/workspace-service.js +16 -2
  511. package/dist/stateDiagram-FKZM4ZOC-3PFzJlcG.js +263 -0
  512. package/dist/stateDiagram-v2-4FDKWEC3-Bp46vM6_.js +16 -0
  513. package/dist/timeline-definition-IT6M3QCI-utm7jTLb.js +795 -0
  514. package/dist/treemap-KMMF4GRG-BvEKHn43.js +5 -0
  515. package/dist/utils/language-utils.d.ts +1 -0
  516. package/dist/utils/language-utils.js +23 -0
  517. package/dist/utils/lru-cache.d.ts +11 -0
  518. package/dist/utils/lru-cache.js +38 -0
  519. package/dist/utils/node-helpers.d.ts +6 -0
  520. package/dist/utils/node-helpers.js +62 -0
  521. package/dist/utils/path-utils.d.ts +5 -0
  522. package/dist/utils/path-utils.js +22 -0
  523. package/dist/workers/elk-layout.worker.d.ts +2 -0
  524. package/dist/workers/elk-layout.worker.js +31 -0
  525. package/dist/workers/equalizer.worker.d.ts +6 -1
  526. package/dist/workers/equalizer.worker.js +144 -195
  527. package/dist/workers/graph-dependent.worker.js +6 -6
  528. package/dist/workers/rule-documentation.worker.js +12 -48
  529. package/dist/workers/search-graph.worker.js +8 -23
  530. package/dist/xychartDiagram-PRI3JC2R-twqDKWMX.js +1340 -0
  531. package/package.json +17 -10
  532. package/dist/assets/equalizer.worker-DyLD5JTU.js +0 -1
  533. package/dist/assets/graph-dependent.worker-CpVhp0-T.js +0 -1
  534. package/dist/assets/rule-documentation.worker-B7xOWY5M.js +0 -1
  535. package/dist/assets/search-graph.worker-B9zqINrO.js +0 -1
  536. package/dist/assets/search-problems.worker-BAF8L2rX.js +0 -1
  537. package/dist/components/problem-list/details-drawer.d.ts +0 -34
  538. package/dist/components/problem-list/details-drawer.js +0 -200
  539. package/dist/style.css +0 -1
  540. /package/dist/components/{problem-list/details-drawer.css.d.ts → bundle-toolbar/bundle-toolbar.css.d.ts} +0 -0
@@ -14,10 +14,10 @@ import '@shoelace-style/shoelace/dist/components/alert/alert.js';
14
14
  import '@shoelace-style/shoelace/dist/components/badge/badge.js';
15
15
  import '@shoelace-style/shoelace/dist/components/avatar/avatar.js';
16
16
  import { customElement, property, query, state } from "lit/decorators.js";
17
- import { html, LitElement } from "lit";
17
+ import { html, LitElement, nothing } from "lit";
18
+ import { ref, createRef } from "lit/directives/ref.js";
18
19
  import { SpecEditor } from "../editor/editor.js";
19
- import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CreditEmpty, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerNodeClicked, ExportRuleset, LoadRenderedNodeIntoInspector, ModelTreeNodeClicked, NodeReferenceClicked, NukeWorkspaceEvent, OpenProblemDrawer, OpenSettings, ProblemClicked, Reboot, RolodexRootFileSelected, RolodexTreeNodeClicked, RuleClicked, RulesetSaved, RuleViolationClicked, StartSessionFailed, CreditStreamUpdated, } from "../../events/doctor.js";
20
- import { ProblemDetailsDrawer } from "../problem-list/details-drawer.js";
20
+ import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CreditEmpty, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerPovModeExit, ExplorerNodeClicked, ExportRuleset, LoadRenderedNodeIntoInspector, ModelTreeNodeClicked, NodeReferenceClicked, NukeWorkspaceEvent, OpenDrawer, OpenSettings, ProblemClicked, Reboot, RolodexRootFileSelected, RolodexTreeNodeClicked, RuleClicked, RulesetSaved, RuleViolationClicked, StartSessionFailed, CreditStreamUpdated, SocketDisconnected, DiagramRequested, TimelineViolationsLoaded, BundleRequested, BundleDownloadRequested, BundleCopyRequested, } from "../../events/doctor.js";
21
21
  import { CreateBagManager } from "@pb33f/saddlebag";
22
22
  import { LintingService } from "../../services/linting-service.js";
23
23
  import { ProblemList } from "../problem-list/problem-list.js";
@@ -43,13 +43,16 @@ import { ExplorerComponent } from "../visualizer/explorer.js";
43
43
  import { RenderedNodeComponent } from "../model-renderer/rendered-node.js";
44
44
  import tabsCss from "../../css/tabs.css.js";
45
45
  import { CreateBus } from "@pb33f/ranch";
46
+ import { createDoctorEventChannels } from "../../services/doctor-events.js";
46
47
  import formsCss from "../../css/forms.css.js";
47
48
  import spinnerCss from "../../css/spinner.css.js";
49
+ import { resolveNodeIdFromHash } from "../../utils/node-helpers.js";
48
50
  import { UploadArchiveComponent } from "./upload-archive.js";
51
+ import '../premium-gate/premium-gate.js';
49
52
  import tooltipCss from "../../css/tooltip.css.js";
50
53
  import { NukeWorkspaceComponent } from "./nuke-workspace.js";
51
54
  import { CreditTicker } from "../credit-ticker/credit-ticker.js";
52
- import { AuthController } from "../../controllers/auth-controller";
55
+ import { AuthController } from "../../controllers/auth-controller.js";
53
56
  import { AuthService } from "../../services/auth-service.js";
54
57
  import { TimeVortex } from "../time-vortex/time-vortex.js";
55
58
  import { TimelineService } from "../../services/timeline-service.js";
@@ -66,10 +69,37 @@ import { DocsController } from '../../controllers/docs-controller.js';
66
69
  import { ModelController } from '../../controllers/model-controller.js';
67
70
  import { DiagnosticController } from '../../controllers/diagnostic-controller.js';
68
71
  import { StateController } from '../../controllers/state-controller.js';
69
- import { WorkspaceController } from "../../controllers/workspace-controller";
72
+ import { WorkspaceController } from "../../controllers/workspace-controller.js";
70
73
  import { WalletController } from "../../controllers/wallet-controller.js";
74
+ import { GlobalTaskController } from "../../controllers/global-task-controller.js";
75
+ import { GitHubController } from "../../controllers/github-controller.js";
76
+ import { DiagramatronController } from "../../controllers/diagramatron-controller.js";
77
+ import { TimelineController } from "../../controllers/timeline-controller.js";
78
+ import { BundleController } from "../../controllers/bundle-controller.js";
79
+ import '../bundle-toolbar/bundle-toolbar.js';
71
80
  import { WorkspaceService } from '../../services/workspace-service.js';
72
81
  import { WalletService } from '../../services/wallet-service.js';
82
+ import { GlobalTaskService } from '../../services/global-task-service.js';
83
+ import { GitHubService } from '../../services/github-service.js';
84
+ import { GenericDetailsDrawer } from '../details-drawer/generic-details-drawer.js';
85
+ import { DrawerContentRegistry } from '../../services/drawer-content-registry.js';
86
+ import { TabCacheController } from '../../controllers/tab-cache-controller.js';
87
+ import { DocumentationHandler } from '../details-drawer/handlers/documentation-handler.js';
88
+ import { HowToFixHandler } from '../details-drawer/handlers/howto-handler.js';
89
+ import { ExampleHandler } from '../details-drawer/handlers/example-handler.js';
90
+ import { MarkdownHandler } from '../details-drawer/handlers/markdown-handler.js';
91
+ import { DiagramHandler } from '../details-drawer/handlers/diagram-handler.js';
92
+ import { GlobalTaskView } from '../global-task/global-task-view.js';
93
+ import "../time-vortex/tardis-control.js"; // Ensure the custom element is registered
94
+ import { ImportRequested, NukeRequested } from './doctor-controls-panel.js';
95
+ import { UrlOverlayDismissed } from './doctor-url-overlay.js';
96
+ import { SidebarTabChanged, SidebarCollapseToggled } from './doctor-sidebar-panel.js';
97
+ import { NavigatorTabChanged, NavigatorRolodexDividerChanged } from './doctor-navigator-panel.js';
98
+ import { EditorTabChanged, DiagnoseRequested, MinimapToggled, SettingsRequested } from './doctor-editor-panel.js';
99
+ import { createStateControllerDeps } from '../../factories/state-controller-deps.factory.js';
100
+ import { EventRegistrationManager } from '../../managers/event-registration-manager.js';
101
+ import { ViewStateManager } from '../../managers/view-state-manager.js';
102
+ import { PanelDividerManager } from '../../managers/panel-divider-manager.js';
73
103
  export const GraphBag = "pb33f-doctor-graph";
74
104
  export const PanelStateBag = "pb33f-doctor-panel-state";
75
105
  export const RolodexResponseBag = "pb33f-doctor-rolodex-response";
@@ -90,19 +120,34 @@ export const FunctionsSchemaBag = "pb33f-doctor-function-schema";
90
120
  export const CustomRulesetBag = "pb33f-doctor-custom-ruleset";
91
121
  export const RuleConfigurationBag = "pb33f-doctor-rule-configuration";
92
122
  export const SessionRulesetMapBag = "pb33f-doctor-session-rulesetmap";
123
+ export const SessionRulesetYamlBag = "pb33f-doctor-session-ruleset-yaml";
93
124
  export const SettingsBag = "pb33f-doctor-settings";
125
+ export const GitHubStateBag = "pb33f-doctor-github-state";
94
126
  export const DefaultDocument = "pb33f-doctor-document";
95
127
  export const DocumentProblems = "pb33f-doctor-problems";
96
128
  export const DoctorEndpoint = "doctor-endpoint";
97
129
  let TheDoctor = class TheDoctor extends LitElement {
98
130
  constructor(doctorEndpoint = "https://doctor.pb33f.io") {
99
131
  super();
132
+ this.toolsEditorHasContent = false;
133
+ this.editorDirty = false;
134
+ this.bundleLoading = false;
135
+ this.isBundled = false;
136
+ // Use ref directives instead of @query for better control
137
+ this.tardisControlRef = createRef();
138
+ this.editorRef = createRef();
139
+ this.rulesetEditorRef = createRef();
140
+ this.changeDiffEditorRef = createRef();
141
+ this.eventManager = new EventRegistrationManager();
100
142
  this.debounceTime = 1000;
101
143
  this.debounceTimeRuleset = 900;
102
144
  this.bounceId = 0;
145
+ this.tabCache = new TabCacheController(this);
103
146
  this.firstRun = true;
104
- // rolodex divider state (because it may not exist)
105
147
  this.rolodexDividerPosition = 40;
148
+ this.currentViewName = '';
149
+ this.isRebooting = false;
150
+ this._editorOpsCache = new Map();
106
151
  // extract the doctor endpoint from session storage.
107
152
  const sessionEndpoint = sessionStorage.getItem(DoctorEndpoint);
108
153
  if (sessionEndpoint) {
@@ -119,30 +164,42 @@ let TheDoctor = class TheDoctor extends LitElement {
119
164
  TimelineService.doctorEndpoint = this.doctorEndpoint;
120
165
  WorkspaceService.doctorEndpoint = this.doctorEndpoint;
121
166
  WalletService.doctorEndpoint = this.doctorEndpoint;
122
- this.timeVortex = new TimeVortex();
167
+ GlobalTaskService.doctorEndpoint = this.doctorEndpoint;
168
+ GitHubService.doctorEndpoint = this.doctorEndpoint;
123
169
  // bus it up
124
170
  this.bus = CreateBus();
171
+ this.events = createDoctorEventChannels(this.bus);
125
172
  this.bagManager = CreateBagManager(true);
126
- this.graphBag = this.bagManager.getBag(GraphBag);
127
- this.docBag = this.bagManager.getBag(DoctorDocumentBag);
128
- this.rolodexResponseBag = this.bagManager.getBag(RolodexResponseBag);
129
- this.rolodexFilesBag = this.bagManager.getBag(RolodexFilesBag);
130
- this.rolodexStateBag = this.bagManager.getBag(RolodexStateBag);
131
- this.referenceMapBag = this.bagManager.getBag(ReferenceMapBag);
132
- this.docExpirationBag = this.bagManager.getBag(DocumentationExpirationBag);
133
- this.panelStateBag = this.bagManager.getBag(PanelStateBag);
134
- this.settingsBag = this.bagManager.getBag(SettingsBag);
173
+ this.graphBag = this.bagManager.createBag(GraphBag);
174
+ this.docBag = this.bagManager.createBag(DoctorDocumentBag);
175
+ this.rolodexResponseBag = this.bagManager.createBag(RolodexResponseBag);
176
+ this.rolodexFilesBag = this.bagManager.createBag(RolodexFilesBag);
177
+ this.rolodexStateBag = this.bagManager.createBag(RolodexStateBag);
178
+ this.referenceMapBag = this.bagManager.createBag(ReferenceMapBag);
179
+ this.docExpirationBag = this.bagManager.createBag(DocumentationExpirationBag);
180
+ this.panelStateBag = this.bagManager.createBag(PanelStateBag);
181
+ this.settingsBag = this.bagManager.createBag(SettingsBag);
182
+ this.githubStateBag = this.bagManager.createBag(GitHubStateBag);
183
+ // initialize properties needed by StateController factory
184
+ this.rolodexProblemMap = new Map();
185
+ this.rolodexRootHash = "";
186
+ this.rolodexRootPath = "";
187
+ this.rolodexNeedsReset = false;
188
+ this.rolodexDividerPosition = 40;
189
+ this.references = [];
190
+ this.problems = [];
135
191
  // create a stateful bag manager
136
192
  this.modelController = new ModelController(this);
137
- this.stateController = new StateController(this);
138
- // boot state.
139
- this.bagManager.loadStatefulBags().then(this.stateController.loadState.bind(this.stateController));
193
+ this.stateController = new StateController(createStateControllerDeps(this));
194
+ this.timeVortex = new TimeVortex(this);
140
195
  this.editor = new SpecEditor();
196
+ this.changeDiffEditor = new SpecEditor();
141
197
  this.uploadArchive = new UploadArchiveComponent();
142
198
  this.nukeWorkspace = new NukeWorkspaceComponent();
143
199
  this.rulesetEditor = new SpecEditor('ruleset-editor');
144
200
  this.problemList = new ProblemList();
145
- this.detailsDrawer = new ProblemDetailsDrawer();
201
+ this.genericDrawer = new GenericDetailsDrawer();
202
+ this.setupDrawerHandlers();
146
203
  this.problemsOverview = new ProblemsOverview();
147
204
  this.errorBanner = new ErrorBanner();
148
205
  this.statusBar = new StatusBar();
@@ -164,36 +221,88 @@ let TheDoctor = class TheDoctor extends LitElement {
164
221
  this.diagnosticController = new DiagnosticController(this);
165
222
  this.walletController = new WalletController(this);
166
223
  this.workspaceController = new WorkspaceController(this);
224
+ this.globalTaskController = new GlobalTaskController(this);
225
+ this.githubController = new GitHubController(this, this.globalTaskController, this.workspaceController);
226
+ this.diagramatronController = new DiagramatronController(this);
227
+ this.diagramatronController.setDrawer(this.genericDrawer);
228
+ this.timelineController = new TimelineController(this);
229
+ this.bundleController = new BundleController({
230
+ getBrokerId: () => this.brokerController?.brokerConnectionId,
231
+ sendToast: (toast) => this.sendToast(toast),
232
+ requestUpdate: () => this.requestUpdate(),
233
+ getOriginalFileName: () => this.rolodexRootPath || 'openapi'
234
+ });
235
+ // Initialize workspace view after GitHub controller is created
236
+ this.workspaceController.initializeView(this.githubController);
237
+ this.globalTaskView = new GlobalTaskView();
238
+ //this.globalTaskView.mockMode = true; // Enable mock mode for demo
239
+ this.globalTaskView.setController(this.globalTaskController);
240
+ // Initialize the controller immediately for mock mode
241
+ //this.globalTaskController.enableMockMode();
167
242
  this.settingsComponent = new DoctorSettings();
168
243
  this.editorMap = new Map();
169
244
  this.editorMap.set("spec", this.editor);
170
245
  this.editorMap.set("ruleset-editor", this.rulesetEditor);
246
+ this.editorMap.set("diff-editor", this.changeDiffEditor);
171
247
  this.selectedEditorTab = "spec";
172
248
  this.sidebarClosed = false;
173
249
  this.explorerVisible = false;
174
250
  this.explorerBooted = false;
175
- this.rolodexNeedsReset = false;
176
- this.rolodexProblemMap = new Map();
177
- this.rolodexRootHash = "";
178
- this.rolodexRootPath = "";
179
251
  this.importDisabled = false;
180
252
  this.pendingLine = 0;
181
- this.autoDiagnose = true;
253
+ this.autoDiagnose = false;
182
254
  this.skipTimeline = false;
183
- this.nodeMap = new Map();
184
- this.nodeIdMap = new Map();
185
- this.nodeIdHashMap = new Map();
186
- this.renderedNodeMap = new Map();
187
255
  this.filteredNodes = new Map();
188
- this.modelTree = new ModelTree(this.nodeMap, this.nodeIdMap, this.nodeIdHashMap);
189
- this.rolodexTree = new ModelTree(this.nodeMap, this.nodeIdMap, this.nodeIdHashMap);
256
+ this.modelTree = new ModelTree();
257
+ this.rolodexTree = new ModelTree();
190
258
  this.rolodexActiveHash = "";
191
- this.explorer = new ExplorerComponent();
192
- this.renderedNode = new RenderedNodeComponent();
259
+ this.explorer = new ExplorerComponent(this);
260
+ this.modelController.renderedNodeComponent = new RenderedNodeComponent();
193
261
  this.references = [];
194
262
  this.minimapVisible = true;
195
263
  this.minimapIconVisible = true;
196
264
  this.showDiagnosisButton = false;
265
+ this.workspaceReadOnly = false;
266
+ this.viewingHistoricalViolations = false;
267
+ // Initialize view state manager
268
+ this.viewStateManager = new ViewStateManager({
269
+ getExplorerVisible: () => this.explorerVisible,
270
+ setExplorerVisible: (v) => { this.explorerVisible = v; },
271
+ getMinimapIconVisible: () => this.minimapIconVisible,
272
+ setMinimapIconVisible: (v) => { this.minimapIconVisible = v; },
273
+ getShowDiagnosisButton: () => this.showDiagnosisButton,
274
+ setShowDiagnosisButton: (v) => { this.showDiagnosisButton = v; },
275
+ getExplorerBooted: () => this.explorerBooted,
276
+ setExplorerBooted: (v) => { this.explorerBooted = v; },
277
+ getAutoDiagnose: () => this.autoDiagnose,
278
+ getPendingLine: () => this.pendingLine,
279
+ setPendingLine: (v) => { this.pendingLine = v; },
280
+ getActiveNode: () => this.modelController.activeNode,
281
+ hasGraphNodes: () => (this.explorer.graphResponse?.nodes?.length ?? 0) > 0,
282
+ isNodeCurrentlyVisible: (id) => this.explorer.isNodeCurrentlyVisible(id),
283
+ revealPathToNode: (id) => this.explorer.revealPathToNode(id),
284
+ buildGraph: () => this.explorer.buildGraph(),
285
+ moveToNode: (node) => this.explorer.moveToNode(node),
286
+ centerOnRoot: () => this.explorer.centerOnRoot(),
287
+ setEditorPosition: (line, col) => this.editor.editor?.setPosition({ lineNumber: line, column: col }),
288
+ revealLineInCenter: (line) => this.editor.editor?.revealLineInCenter(line),
289
+ setWorkspaceViewActive: (active) => { this.workspaceController.workspaceView.active = active; },
290
+ sendToast: (toast) => this.sendToast(toast),
291
+ requestUpdate: () => this.requestUpdate()
292
+ });
293
+ // Initialize panel divider manager
294
+ this.panelDividerManager = new PanelDividerManager({
295
+ getPanelStateBag: () => this.panelStateBag,
296
+ getPanelStateBagKey: () => PanelStateBag,
297
+ getSplitPanel: () => this.splitPanel,
298
+ getSplitDivider: () => this.splitDivider,
299
+ getSplitPanelInspector: () => this.splitPanelInspector,
300
+ getSplitPanelExplorer: () => this.splitPanelExplorer,
301
+ getRolodexDividerPosition: () => this.rolodexDividerPosition,
302
+ setRolodexDividerPosition: (pos) => { this.rolodexDividerPosition = pos; },
303
+ setSidebarClosed: (closed) => { this.sidebarClosed = closed; }
304
+ });
305
+ // TODO: come back and check this.
197
306
  this.nodeLimit = 150;
198
307
  // session call back for when we're online.
199
308
  const sessionCallback = (session) => {
@@ -204,6 +313,7 @@ let TheDoctor = class TheDoctor extends LitElement {
204
313
  this.creditTicker.credits = session.creditsRemaining;
205
314
  }
206
315
  this.creditTicker.visible = true;
316
+ this.statusBar.callsRemaining = session.creditsRemaining;
207
317
  this.brokerController.connectToBroker();
208
318
  // if the session is authenticated, then fetch a list of workspaces for the user.
209
319
  if (this.authController.authenticated) {
@@ -212,71 +322,76 @@ let TheDoctor = class TheDoctor extends LitElement {
212
322
  // update workspace view to reflect new credit balance
213
323
  this.workspaceController.workspaceView.requestUpdate();
214
324
  };
215
- // create auth controller
325
+ // boot state.
326
+ // STRIPPED FOR PERF TESTING - this loads from IndexedDB and renders graph
327
+ this.bagManager.loadStatefulBags().then(() => {
328
+ this.stateController.loadState();
329
+ this.loadMinimapState();
330
+ });
331
+ // create auth controller & listen for auth state changes.
216
332
  this.authController = new AuthController(this, sessionCallback, true);
217
333
  this.authController.start();
218
- // listen for auth state changes.
219
- //@ts-ignore
220
- this.addEventListener(EditorUpdated, this.specController.specChanged.bind(this.specController));
221
- //@ts-ignore
222
- this.addEventListener(EditorClicked, this.specController.specClicked.bind(this.specController));
223
- //@ts-ignore
224
- this.addEventListener(ProblemClicked, this.problemController.problemClicked.bind(this.problemController));
225
- // @ts-ignore
226
- this.addEventListener(OpenProblemDrawer, this.docsController.ruleDocsClicked.bind(this.docsController));
227
- // @ts-ignore
228
- this.addEventListener(RuleViolationClicked, this.ruleController.ruleGroupClicked.bind(this.ruleController));
229
- // @ts-ignore
230
- this.addEventListener(CustomRulesetEnabled, this.ruleController.customRulesetEnabled.bind(this.ruleController));
231
- // @ts-ignore
232
- this.addEventListener(RulesetSaved, this.ruleController.rulesetSaved.bind(this.ruleController));
233
- // @ts-ignore
234
- this.addEventListener(AddToast, this.addToastEvent);
235
- // @ts-ignore
236
- this.addEventListener(CreditStreamUpdated, this.creditStreamUpdated.bind(this));
237
- this.addEventListener(ExportRuleset, this.exportRuleset);
238
- // @ts-ignore
239
- this.addEventListener(RuleClicked, this.ruleController.ruleClicked.bind(this.ruleController));
240
- // @ts-ignore
241
- this.addEventListener(BuiltInRulesetChanged, this.builtInRulesetSelected);
242
- // @ts-ignore
243
- this.addEventListener(ModelTreeNodeClicked, this.nodeClickerController.modelTreeNodeClicked.bind(this.nodeClickerController));
244
- // @ts-ignore
245
- this.addEventListener(RolodexTreeNodeClicked, this.nodeClickerController.rolodexTreeNodeClicked.bind(this.nodeClickerController));
246
- // @ts-ignore
247
- this.addEventListener(NodeReferenceClicked, this.nodeClickerController.explorerReferenceClicked.bind(this.nodeClickerController));
248
- // @ts-ignore
249
- this.addEventListener(ExplorerNodeClicked, this.nodeClickerController.explorerNodeClicked.bind(this.nodeClickerController));
250
- // @ts-ignore
251
- this.addEventListener(DocumentReferenceClicked, this.nodeClickerController.documentReferenceClicked.bind(this.nodeClickerController));
252
- // @ts-ignore
253
- this.addEventListener(RolodexRootFileSelected, this.rolodexController.rolodexRootFileSelected.bind(this.rolodexController));
254
- // @ts-ignore
255
- this.addEventListener(ArchiveURLRequested, this.fetchUrl.bind(this));
256
- //@ts-ignore
257
- this.explorer.equalizer.addEventListener(ExplorerEqualizerChanged, this.filterTreeModel.bind(this));
258
- //@ts-ignore
259
- this.explorer.equalizer.addEventListener(ExplorerEqualizerFiltered, this.filterTreeModel.bind(this));
260
- // @ts-ignore
261
- this.nukeWorkspace.addEventListener(NukeWorkspaceEvent, this.nukeWorkspaceHandler.bind(this));
262
- // on logout, nuke it all.
263
- // @ts-ignore
264
- this.authController.addEventListener(NukeWorkspaceEvent, this.nukeWorkspaceHandler.bind(this));
265
- // @ts-ignore
266
- this.authController.addEventListener(StartSessionFailed, this.platformUnavailable.bind(this));
267
- this.timeVortex.historyPicker.addEventListener(OpenSettings, this.openSettings.bind(this));
268
- // @ts-ignore
269
- this.authController.addEventListener(CreditEmpty, this.creditEmpty.bind(this));
270
- //@ts-ignore
271
- this.addEventListener(LoadRenderedNodeIntoInspector, this.loadRenderedNodeIntoInspector.bind(this));
272
- this.addEventListener(Reboot, this.reboot.bind(this));
273
- // hijack navigation buttons.
274
- window.addEventListener('popstate', (e) => {
334
+ // Register all event listeners with tracking for proper cleanup
335
+ // Note: using 'as EventListener' to handle CustomEvent handler types
336
+ this.addTrackedListener(this, EditorUpdated, this.specController.specChanged.bind(this.specController));
337
+ this.addTrackedListener(this, EditorUpdated, this.handleEditorUpdatedForBundle.bind(this));
338
+ this.addTrackedListener(this, EditorClicked, this.specController.specClicked.bind(this.specController));
339
+ this.addTrackedListener(this, ProblemClicked, this.problemController.problemClicked.bind(this.problemController));
340
+ this.addTrackedListener(this, OpenDrawer, this.docsController.handleDrawerRequest.bind(this.docsController));
341
+ this.addTrackedListener(this, DiagramRequested, this.diagramatronController.handleDiagramRequest.bind(this.diagramatronController));
342
+ this.addTrackedListener(this, RuleViolationClicked, this.ruleController.ruleGroupClicked.bind(this.ruleController));
343
+ this.addTrackedListener(this, CustomRulesetEnabled, this.ruleController.customRulesetEnabled.bind(this.ruleController));
344
+ this.addTrackedListener(this, RulesetSaved, this.ruleController.rulesetSaved.bind(this.ruleController));
345
+ this.addTrackedListener(this, AddToast, this.addToastEvent.bind(this));
346
+ this.addTrackedListener(this, CreditStreamUpdated, this.creditStreamUpdated.bind(this));
347
+ this.addTrackedListener(this, TimelineViolationsLoaded, this.handleTimelineViolationsLoaded.bind(this));
348
+ this.addTrackedListener(this, ExportRuleset, this.exportRuleset.bind(this));
349
+ this.addTrackedListener(this, RuleClicked, this.ruleController.ruleClicked.bind(this.ruleController));
350
+ this.addTrackedListener(this, BuiltInRulesetChanged, this.builtInRulesetSelected.bind(this));
351
+ this.addTrackedListener(this, ModelTreeNodeClicked, this.nodeClickerController.modelTreeNodeClicked.bind(this.nodeClickerController));
352
+ this.addTrackedListener(this, RolodexTreeNodeClicked, this.nodeClickerController.rolodexTreeNodeClicked.bind(this.nodeClickerController));
353
+ this.addTrackedListener(this, NodeReferenceClicked, this.nodeClickerController.explorerReferenceClicked.bind(this.nodeClickerController));
354
+ this.addTrackedListener(this, ExplorerNodeClicked, this.nodeClickerController.explorerNodeClicked.bind(this.nodeClickerController));
355
+ this.addTrackedListener(this, DocumentReferenceClicked, this.nodeClickerController.documentReferenceClicked.bind(this.nodeClickerController));
356
+ this.addTrackedListener(this, RolodexRootFileSelected, this.rolodexController.rolodexRootFileSelected.bind(this.rolodexController));
357
+ this.addTrackedListener(this, ArchiveURLRequested, this.fetchUrl.bind(this));
358
+ this.addTrackedListener(this.explorer.equalizer, ExplorerEqualizerChanged, this.filterTreeModel.bind(this));
359
+ this.addTrackedListener(this.explorer.equalizer, ExplorerEqualizerFiltered, this.filterTreeModel.bind(this));
360
+ this.addTrackedListener(this.explorer.equalizer, ExplorerPovModeExit, this.restoreFullTree.bind(this));
361
+ this.addTrackedListener(this.nukeWorkspace, NukeWorkspaceEvent, this.nukeWorkspaceHandler.bind(this));
362
+ this.addTrackedListener(this.authController, NukeWorkspaceEvent, this.nukeWorkspaceHandler.bind(this));
363
+ this.addTrackedListener(this.authController, StartSessionFailed, this.platformUnavailable.bind(this));
364
+ this.addTrackedListener(this.timeVortex.historyPicker, OpenSettings, this.openSettings.bind(this));
365
+ this.addTrackedListener(this.authController, CreditEmpty, this.creditEmpty.bind(this));
366
+ this.addTrackedListener(this, SocketDisconnected, this.socketDisconnected.bind(this));
367
+ this.addTrackedListener(this, LoadRenderedNodeIntoInspector, this.loadRenderedNodeIntoInspector.bind(this));
368
+ this.addTrackedListener(this, Reboot, this.reboot.bind(this));
369
+ this.addTrackedListener(this, ImportRequested, this.handleImportRequested.bind(this));
370
+ this.addTrackedListener(this, NukeRequested, this.handleNukeRequested.bind(this));
371
+ this.addTrackedListener(this, UrlOverlayDismissed, this.handleUrlOverlayDismissed.bind(this));
372
+ this.addTrackedListener(this, SidebarTabChanged, this.handleSidebarTabChanged.bind(this));
373
+ this.addTrackedListener(this, SidebarCollapseToggled, this.handleSidebarCollapseToggled.bind(this));
374
+ this.addTrackedListener(this, 'doctor-tools-compare', this.handleToolsCompare.bind(this));
375
+ this.addTrackedListener(this, NavigatorTabChanged, this.handleNavigatorTabChanged.bind(this));
376
+ this.addTrackedListener(this, NavigatorRolodexDividerChanged, this.handleNavigatorRolodexDivider.bind(this));
377
+ this.addTrackedListener(this, EditorTabChanged, this.handleEditorTabChanged.bind(this));
378
+ this.addTrackedListener(this, DiagnoseRequested, this.runDiagnostics.bind(this));
379
+ this.addTrackedListener(this, MinimapToggled, this.minimapToggled.bind(this));
380
+ this.addTrackedListener(this, SettingsRequested, this.openSettings.bind(this));
381
+ this.addTrackedListener(this, BundleRequested, this.handleBundleRequested.bind(this));
382
+ this.addTrackedListener(this, BundleDownloadRequested, this.handleBundleDownload.bind(this));
383
+ this.addTrackedListener(this, BundleCopyRequested, this.handleBundleCopy.bind(this));
384
+ // hijack navigation buttons - store reference for cleanup
385
+ this.popstateHandler = (e) => {
275
386
  const state = e.state;
276
387
  if (state) {
277
- if (state.activeNode) {
388
+ if (state.activeNodeId || state.activeNode) {
389
+ const nodeMap = this.modelController?.nodeMap ?? this.rolodexTree?.nodeMap;
390
+ const resolvedId = state.activeNodeId
391
+ ?? (state.activeNode && nodeMap ? resolveNodeIdFromHash(state.activeNode, nodeMap) : undefined);
278
392
  this.nodeClickerController.modelTreeNodeClicked(new CustomEvent(ExplorerNodeClicked, {
279
393
  detail: {
394
+ nodeId: resolvedId,
280
395
  nodeHashId: state.activeNode,
281
396
  noState: true
282
397
  }
@@ -291,11 +406,123 @@ let TheDoctor = class TheDoctor extends LitElement {
291
406
  }));
292
407
  }
293
408
  }
294
- });
409
+ };
410
+ window.addEventListener('popstate', this.popstateHandler);
411
+ }
412
+ addTrackedListener(target, event, handler) {
413
+ this.eventManager.add(target, event, handler);
295
414
  }
296
415
  openSettings() {
297
416
  this.settingsComponent.open();
298
417
  }
418
+ handleImportRequested() {
419
+ this.uploadArchive.show();
420
+ }
421
+ handleNukeRequested() {
422
+ this.nukeWorkspace.show();
423
+ }
424
+ handleUrlOverlayDismissed() {
425
+ this.editor.toggleMinimap();
426
+ }
427
+ handleSidebarTabChanged(event) {
428
+ const tabName = event.detail.name;
429
+ this.selectControlTab(new CustomEvent('sl-tab-show', {
430
+ detail: { name: tabName }
431
+ }));
432
+ // Update view name for screen reader announcement
433
+ const viewNames = {
434
+ 'overview': 'Problems Overview',
435
+ 'viewer': 'Objects',
436
+ 'problems': 'Problems',
437
+ 'tools': 'Tools',
438
+ 'ruleset': 'Rules',
439
+ 'feedback': 'Feedback'
440
+ };
441
+ this.currentViewName = viewNames[tabName] || tabName;
442
+ this.managePanelFocus(this.sidebarPanel, tabName);
443
+ }
444
+ openSidebar() {
445
+ if (this.sidebarClosed && this.sidebarPanel) {
446
+ this.sidebarPanel.collapsed = false;
447
+ this.handleSidebarCollapseToggled(new CustomEvent('', {
448
+ detail: { collapsed: false }
449
+ }));
450
+ }
451
+ }
452
+ markEditorTabLoaded(tabName) {
453
+ this.tabCache.markEditorTabLoaded(tabName);
454
+ }
455
+ managePanelFocus(panelHost, tabName) {
456
+ this.updateComplete.then(() => {
457
+ const panel = panelHost?.shadowRoot?.querySelector(`sl-tab-panel[name="${tabName}"]`);
458
+ if (panel) {
459
+ panel.setAttribute('tabindex', '-1');
460
+ panel.focus({ preventScroll: true });
461
+ }
462
+ });
463
+ }
464
+ handleSidebarCollapseToggled(event) {
465
+ this.panelDividerManager.handleSidebarCollapseToggled(event.detail.collapsed);
466
+ }
467
+ handleNavigatorTabChanged(event) {
468
+ this.selectEditorTab(new CustomEvent('sl-tab-show', {
469
+ detail: { name: event.detail.name }
470
+ }));
471
+ }
472
+ handleNavigatorRolodexDivider(event) {
473
+ this.panelDividerManager.handleRolodexDividerChanged(event.detail.position);
474
+ }
475
+ handleEditorTabChanged(event) {
476
+ const tabName = event.detail.name;
477
+ this.selectedEditorTab = tabName;
478
+ this.tabCache.markEditorTabLoaded(tabName);
479
+ // Update view name for screen reader announcement
480
+ const viewNames = {
481
+ 'spec': 'Specification Editor',
482
+ 'explorer': 'Explorer',
483
+ 'tardis': 'Timeline',
484
+ 'workspaces': 'Workspaces'
485
+ };
486
+ this.currentViewName = viewNames[tabName] || tabName;
487
+ this.managePanelFocus(this.editorPanel, tabName);
488
+ if (this.viewingHistoricalViolations &&
489
+ (tabName === 'spec' || tabName === 'explorer')) {
490
+ this.timelineController.restoreLiveViolations();
491
+ this.navigatorPanel?.showTab('model-tree');
492
+ }
493
+ switch (tabName) {
494
+ case 'spec':
495
+ this.closeExplorer();
496
+ this.enableDiagnosisButton();
497
+ break;
498
+ case 'explorer':
499
+ this.toggleExplorer();
500
+ this.hideDiagnosisButton();
501
+ break;
502
+ case 'workspaces':
503
+ this.toggleExplorer();
504
+ this.hideDiagnosisButton();
505
+ this.workspaceController.workspaceView.active = true;
506
+ break;
507
+ case 'tardis':
508
+ this.showHistory();
509
+ this.hideDiagnosisButton();
510
+ this.ensureTardisControlInitialized();
511
+ break;
512
+ case 'ruleset':
513
+ this.closeExplorer();
514
+ this.hideDiagnosisButton();
515
+ if (this.rulesetPulse) {
516
+ this.rulesetPulse = false;
517
+ }
518
+ this.controlTabs.showTab(ActiveView.Ruleset);
519
+ break;
520
+ case 'docs':
521
+ this.hideMinimapIcon();
522
+ this.hideDiagnosisButton();
523
+ break;
524
+ }
525
+ }
299
526
  settingsChanged(_, config) {
300
527
  if (config) {
301
528
  this.autoDiagnose = config.autoDiagnose;
@@ -322,12 +549,22 @@ let TheDoctor = class TheDoctor extends LitElement {
322
549
  loadRenderedNodeIntoInspector(evt) {
323
550
  const rn = new RenderedNodeComponent();
324
551
  rn.node = evt.detail.renderedNode;
325
- this.renderedNode = rn;
552
+ this.modelController.renderedNodeComponent = rn;
326
553
  this.requestUpdate();
327
- this.viewerPanel.click();
554
+ this.sidebarPanel?.showTab('viewer');
328
555
  }
329
556
  nukeWorkspaceHandler(e) {
330
- this.bagManager.resetBags();
557
+ // Only reset workspace/document-specific state, preserve user-level state
558
+ // (GitHub installations, rulesets, functions, documentation, settings, UI preferences)
559
+ this.docBag?.reset();
560
+ this.problemBag?.reset();
561
+ this.diagnosticBag?.reset();
562
+ this.graphBag?.reset();
563
+ this.rolodexResponseBag?.reset();
564
+ this.rolodexFilesBag?.reset();
565
+ this.rolodexStateBag?.reset();
566
+ this.referenceMapBag?.reset();
567
+ this.docExpirationBag?.reset();
331
568
  localStorage.removeItem("pb33f-doctor-version");
332
569
  if (!e || !e.detail || e.detail.resetFiles) {
333
570
  ModelService.resetWorkspace().then(() => {
@@ -343,16 +580,112 @@ let TheDoctor = class TheDoctor extends LitElement {
343
580
  }
344
581
  minimapToggled() {
345
582
  this.minimapVisible = !this.minimapVisible;
346
- this.editor.toggleMinimap();
347
- this.rulesetEditor.toggleMinimap();
583
+ this.applyMinimapState();
584
+ this.saveMinimapState();
585
+ }
586
+ saveMinimapState() {
587
+ if (!this.panelStateBag || !this.panelStateBag.db)
588
+ return;
589
+ const panelState = this.panelStateBag.get(PanelStateBag) || {};
590
+ panelState.minimapVisible = this.minimapVisible;
591
+ this.panelStateBag.set(PanelStateBag, panelState);
592
+ }
593
+ loadMinimapState() {
594
+ if (!this.panelStateBag)
595
+ return;
596
+ const panelState = this.panelStateBag.get(PanelStateBag);
597
+ if (panelState && panelState.minimapVisible !== undefined) {
598
+ this.minimapVisible = panelState.minimapVisible;
599
+ }
348
600
  }
349
- firstUpdated() {
601
+ applyMinimapState() {
602
+ if (this.editor?.editor) {
603
+ this.editor.minimapVisible = this.minimapVisible;
604
+ this.editor.editor.updateOptions({ minimap: { enabled: this.minimapVisible } });
605
+ }
606
+ if (this.rulesetEditor?.editor) {
607
+ this.rulesetEditor.minimapVisible = this.minimapVisible;
608
+ this.rulesetEditor.editor.updateOptions({ minimap: { enabled: this.minimapVisible } });
609
+ }
610
+ }
611
+ async firstUpdated() {
350
612
  // https://github.com/microsoft/monaco-editor/issues/3409
613
+ // Query for the light DOM Monaco editors
351
614
  this.editor = this.querySelector('pb33f-editor#spec-editor');
352
615
  this.rulesetEditor = this.querySelector('pb33f-editor#ruleset-editor');
616
+ this.changeDiffEditor = this.querySelector('pb33f-editor#diff-editor');
617
+ this.toolsEditor = this.querySelector('pb33f-editor#tools-editor');
618
+ // Apply minimap state after editors are ready
619
+ setTimeout(() => this.applyMinimapState(), 150);
620
+ if (this.toolsEditor) {
621
+ this.toolsEditor.minimapVisible = false;
622
+ setTimeout(() => {
623
+ this.toolsEditor.editor?.updateOptions({
624
+ minimap: { enabled: false },
625
+ overviewRulerLanes: 0,
626
+ hideCursorInOverviewRuler: true,
627
+ overviewRulerBorder: false,
628
+ scrollbar: {
629
+ vertical: 'auto',
630
+ verticalScrollbarSize: 8
631
+ }
632
+ });
633
+ }, 100);
634
+ this.toolsEditorListener = (e) => {
635
+ const event = e;
636
+ if (event.detail.id === 'tools-editor') {
637
+ this.toolsEditorHasContent = event.detail.content?.trim().length > 0;
638
+ }
639
+ };
640
+ this.toolsEditor.addEventListener(EditorUpdated, this.toolsEditorListener);
641
+ }
642
+ // Wait for the tardis-control custom element to be defined
643
+ await customElements.whenDefined('pb33f-tardis-control');
644
+ // Use ref to get the tardis control component and set up references
645
+ requestAnimationFrame(() => {
646
+ const tardisControl = this.tardisControlRef.value;
647
+ if (tardisControl) {
648
+ // Set the diff editor reference
649
+ tardisControl.diffEditor = this.changeDiffEditor;
650
+ // Register with time vortex - it will store the reference
651
+ this.timeVortex.setTardisControl(tardisControl);
652
+ // Don't fetch history here - wait until doctor is fully booted
653
+ }
654
+ });
655
+ }
656
+ disconnectedCallback() {
657
+ super.disconnectedCallback();
658
+ this.nodeClickerController?.destroy();
659
+ this.panelDividerManager?.destroy();
660
+ this.specController?.destroy();
661
+ this.ruleController?.destroy();
662
+ this.githubController?.destroy();
663
+ this.brokerController?.destroy();
664
+ this.globalTaskController?.destroy();
665
+ this.timelineController?.destroy();
666
+ if (this.toolsEditor && this.toolsEditorListener) {
667
+ this.toolsEditor.removeEventListener(EditorUpdated, this.toolsEditorListener);
668
+ }
669
+ this.ruleDocsWorker?.terminate();
670
+ this.ruleDocsWorker = undefined;
671
+ // Clean up all tracked event listeners
672
+ this.eventManager.removeAll();
673
+ // Clean up window popstate listener
674
+ if (this.popstateHandler) {
675
+ window.removeEventListener('popstate', this.popstateHandler);
676
+ this.popstateHandler = undefined;
677
+ }
678
+ }
679
+ setupDrawerHandlers() {
680
+ const registry = DrawerContentRegistry.getInstance();
681
+ registry.registerHandler(new DocumentationHandler());
682
+ registry.registerHandler(new HowToFixHandler());
683
+ registry.registerHandler(new ExampleHandler());
684
+ registry.registerHandler(new MarkdownHandler());
685
+ registry.registerHandler(new DiagramHandler());
353
686
  }
354
687
  addClickTrack(node) {
355
- history.pushState({ activeNode: node.idHash }, "", `?view=explore&node=${node.idHash}`);
688
+ history.pushState({ activeNodeId: node.id, activeNode: node.idHash }, "", `?view=explore&node=${node.idHash}`);
356
689
  }
357
690
  addRefTrack(ref) {
358
691
  history.pushState({ ref: ref }, "", `?view=spec&ref=${ref}`);
@@ -362,8 +695,12 @@ let TheDoctor = class TheDoctor extends LitElement {
362
695
  event.detail.graph.nodes.forEach((node) => {
363
696
  this.filteredNodes.set(node.id, node);
364
697
  });
365
- this.modelTree.filteredNodes = this.filteredNodes;
366
- this.modelTree.renderedNodes = this.renderedNodeMap;
698
+ this.modelTree.nodeMap = this.filteredNodes;
699
+ this.modelTree.violationMap = this.modelController.violationMap;
700
+ }
701
+ restoreFullTree() {
702
+ this.modelTree.nodeMap = this.modelController.nodeMap;
703
+ this.modelTree.violationMap = this.modelController.violationMap;
367
704
  }
368
705
  exportRuleset() {
369
706
  this.exportRulesetDialog.show();
@@ -376,46 +713,19 @@ let TheDoctor = class TheDoctor extends LitElement {
376
713
  if (this.authController?.session) {
377
714
  this.authController.session.creditsRemaining = event.detail.credits;
378
715
  }
716
+ // Sync status bar credits
717
+ this.statusBar.callsRemaining = event.detail.credits;
379
718
  // Trigger workspace view update directly
380
719
  this.workspaceController.workspaceView.requestUpdate();
381
720
  }
382
721
  sendToast(toast) {
383
722
  this.toastManager.addToastManually(toast);
384
723
  }
385
- updateInspectorDivider() {
386
- const panelState = this.panelStateBag?.get(PanelStateBag);
387
- if (panelState) {
388
- panelState.inspectorPanel = this.splitPanelInspector.position;
389
- this.panelStateBag?.set(PanelStateBag, panelState);
390
- }
391
- else {
392
- this.panelStateBag?.set(PanelStateBag, { inspectorPanel: this.splitPanelInspector.position });
393
- }
394
- }
395
- updateExplorerDivider() {
396
- const panelState = this.panelStateBag?.get(PanelStateBag);
397
- if (panelState) {
398
- panelState.explorerPanel = this.splitPanelExplorer.position;
399
- this.panelStateBag?.set(PanelStateBag, panelState);
400
- }
401
- else {
402
- this.panelStateBag?.set(PanelStateBag, { explorerPanel: this.splitPanelExplorer.position });
403
- }
404
- }
405
- updateRolodexDivider() {
406
- const panelState = this.panelStateBag?.get(PanelStateBag);
407
- if (panelState) {
408
- panelState.rolodexPanel = this.splitPanelRolodex.position;
409
- this.panelStateBag?.set(PanelStateBag, panelState);
410
- }
411
- else {
412
- this.panelStateBag?.set(PanelStateBag, { rolodexPanel: this.splitPanelRolodex.position });
413
- }
414
- this.rolodexDividerPosition = this.splitPanelRolodex.position;
415
- }
724
+ updateInspectorDivider() { this.panelDividerManager.updateInspectorDivider(); }
725
+ updateExplorerDivider() { this.panelDividerManager.updateExplorerDivider(); }
416
726
  updateRefmapBag(currentPath, result) {
417
727
  let refMap = this.referenceMapBag?.get(ReferenceMapBag);
418
- let cp = currentPath;
728
+ let cp = currentPath ?? "";
419
729
  if (refMap) {
420
730
  refMap.references[cp] = result;
421
731
  }
@@ -429,6 +739,33 @@ let TheDoctor = class TheDoctor extends LitElement {
429
739
  creditEmpty(e) {
430
740
  this.platformUnavailable(e.detail.error);
431
741
  }
742
+ socketDisconnected(event) {
743
+ // Hide loading overlay immediately
744
+ this.loadingOverlay?.hide();
745
+ this.activitySpinner?.hide();
746
+ // Extract error message from socket error
747
+ const frame = event.detail?.frame;
748
+ const errorMessage = frame?.body || frame?.headers?.message || 'Socket connection terminated unexpectedly';
749
+ // Show error toast with socket message
750
+ const toast = {
751
+ id: 'socket-error-' + Date.now(),
752
+ title: 'Connection Lost',
753
+ type: ToastType.ERROR,
754
+ body: errorMessage
755
+ };
756
+ this.sendToast(toast);
757
+ // Shut down UI completely for IP blocking errors
758
+ const platformError = {
759
+ detail: errorMessage,
760
+ instance: 'websocket-connection',
761
+ status: 403,
762
+ title: 'Connection Blocked',
763
+ type: 'socket-error',
764
+ body: frame
765
+ };
766
+ this.platformUnavailable(platformError);
767
+ console.warn('🛑 Socket disconnected with error:', errorMessage);
768
+ }
432
769
  platformUnavailable(error) {
433
770
  if (!this.unavailable) {
434
771
  this.loadingOverlay?.hide();
@@ -446,32 +783,94 @@ let TheDoctor = class TheDoctor extends LitElement {
446
783
  this.errorBanner.visible = true;
447
784
  this.unavailable = true;
448
785
  this.problemsOverview.unavailable = true;
449
- this.controlTabGroup.show(ActiveView.Overview);
786
+ this.controlTabs.showTab(ActiveView.Overview);
450
787
  }
451
788
  }
452
789
  builtInRulesetSelected() {
453
790
  // todo
454
791
  }
455
792
  runDiagnostics() {
793
+ if (this.workspaceReadOnly) {
794
+ this.sendToast({
795
+ id: crypto.randomUUID(),
796
+ type: ToastType.WARNING,
797
+ title: "Read-only workspace",
798
+ body: "This workspace is attached to a github repo, it can't be edited here yet."
799
+ });
800
+ return;
801
+ }
456
802
  if (!this.autoDiagnose) {
803
+ this.editorDirty = false;
457
804
  this.diagnosticController.lintSpec(this.editor.getValue());
458
805
  }
459
806
  }
807
+ async handleBundleRequested() {
808
+ this.bundleLoading = true;
809
+ this.modelController.captureOriginalGraph();
810
+ await this.bundleController.bundleSpec();
811
+ this.bundleLoading = false;
812
+ this.isBundled = this.bundleController.isBundled;
813
+ this.modelTree.isBundled = this.isBundled;
814
+ const bundleResponse = this.bundleController.getBundleResponse();
815
+ if (bundleResponse?.graph) {
816
+ this.modelController.extractGraph(bundleResponse.graph);
817
+ }
818
+ }
819
+ handleBundleDownload() {
820
+ this.bundleController.downloadBundledSpec();
821
+ }
822
+ handleBundleCopy() {
823
+ this.bundleController.copyToClipboard();
824
+ }
825
+ handleEditorUpdatedForBundle(event) {
826
+ if (event.detail.id === 'spec' && this.isBundled) {
827
+ this.bundleController.reset();
828
+ this.isBundled = false;
829
+ this.modelTree.isBundled = false;
830
+ }
831
+ }
460
832
  reboot() {
833
+ if (this.isRebooting)
834
+ return;
835
+ this.isRebooting = true;
461
836
  // for when we need to switch workspaces, and everything needs an update.
837
+ // Clear all rolodex-related state to prevent stale paths from causing 404s
838
+ this.rolodexActivePath = "";
839
+ this.rolodexActiveHash = "";
840
+ this.rolodexRootPath = "";
841
+ this.rolodexRootHash = "";
842
+ this.rolodexProblemMap.clear();
843
+ this.rolodexFilesBag?.reset();
844
+ this.rolodexStateBag?.reset();
845
+ this.rolodexResponseBag?.reset();
846
+ this.referenceMapBag?.reset();
847
+ this.editor.clearDecorations();
848
+ this.editor.clearAllMarkers();
849
+ // Re-initialize GitHub controller to restore cached state to UI
850
+ this.githubController.reinitialize();
462
851
  ModelService.getCurrentSpec().then((result) => {
463
852
  this.rolodexController.queryRolodex();
464
- this.timeVortex.checkHistory();
853
+ this.timeVortex.getHistorySummary();
465
854
  this.editor.setValue(result, true);
466
- this.rolodexActivePath = "";
467
855
  this.specController.specChanged(new CustomEvent(EditorUpdated, {
468
856
  detail: {
469
857
  content: result,
470
858
  id: "spec"
471
859
  }
472
860
  }));
861
+ // lintSpec must run BEFORE setting read-only, otherwise Monaco won't render markers
862
+ this.diagnosticController.lintSpec(result);
863
+ this.updateWorkspaceReadOnlyState();
864
+ }).finally(() => {
865
+ this.isRebooting = false;
473
866
  });
474
867
  }
868
+ updateWorkspaceReadOnlyState() {
869
+ this.workspaceReadOnly = this.workspaceController.activeWorkspace?.readOnly ?? false;
870
+ if (this.editor) {
871
+ this.editor.setReadOnly(this.workspaceReadOnly);
872
+ }
873
+ }
475
874
  boostrap() {
476
875
  // if the url is set in the query string, fetch it and run a lint with the URL
477
876
  const url = new URL(window.location.href);
@@ -482,40 +881,51 @@ let TheDoctor = class TheDoctor extends LitElement {
482
881
  this.diagnosticController.lintSpec('', urlParam);
483
882
  return;
484
883
  }
485
- // todo: this needs work man. I want to see all these settimeouts gone brother.
486
- setTimeout(() => {
487
- // check for a history
488
- this.timeVortex.doctor = this;
489
- this.timeVortex.checkHistory();
490
- const editorValue = this.docBag?.get(DefaultDocument);
491
- if (!editorValue) {
492
- LintingService.bootstrapEditor().then((result) => {
493
- this.loadingOverlay.hide();
884
+ const editorValue = this.docBag?.get(DefaultDocument);
885
+ if (!editorValue) {
886
+ LintingService.bootstrapEditor().then((result) => {
887
+ this.loadingOverlay.hide();
888
+ this.editor.setValue(result, true);
889
+ this.rolodexActivePath = "";
890
+ this.specController.specChanged(new CustomEvent(EditorUpdated, {
891
+ detail: {
892
+ content: result,
893
+ id: "spec"
894
+ }
895
+ }));
896
+ this.diagnosticController.lintSpec(result);
897
+ });
898
+ }
899
+ else {
900
+ ModelService.getCurrentSpec().then((result) => {
901
+ this.loadingOverlay.hide();
902
+ if (result != editorValue) {
494
903
  this.editor.setValue(result, true);
495
- this.rolodexActivePath = "";
496
- this.specController.specChanged(new CustomEvent(EditorUpdated, {
497
- detail: {
498
- content: result,
499
- id: "spec"
500
- }
501
- }));
502
- });
503
- }
504
- else {
505
- ModelService.getCurrentSpec().then((result) => {
506
- this.loadingOverlay.hide();
507
- this.rolodexController.queryRolodex();
508
- if (result != editorValue) {
509
- this.editor.setValue(result, true);
510
- this.rolodexActivePath = "";
511
- this.specController.specChanged(new CustomEvent(EditorUpdated, {
512
- detail: {
513
- content: result,
514
- id: "spec"
515
- }
516
- }));
904
+ }
905
+ this.rolodexActivePath = "";
906
+ this.rolodexController.queryRolodex();
907
+ this.specController.specChanged(new CustomEvent(EditorUpdated, {
908
+ detail: {
909
+ content: result,
910
+ id: "spec"
517
911
  }
912
+ }));
913
+ this.diagnosticController.lintSpec(result);
914
+ }).catch(() => {
915
+ this.loadingOverlay.hide();
916
+ this.sendToast({
917
+ id: crypto.randomUUID(),
918
+ type: ToastType.WARNING,
919
+ body: "Could not fetch latest specification, session must have expired.",
920
+ title: "Session reset warning"
518
921
  });
922
+ });
923
+ }
924
+ this.loadingOverlay.hide();
925
+ setTimeout(() => {
926
+ this.timeVortex.getHistorySummary();
927
+ if (this.timeVortex.tardisControl) {
928
+ this.timeVortex.tardisControl.fetchHistory();
519
929
  }
520
930
  }, 50);
521
931
  }
@@ -529,22 +939,57 @@ let TheDoctor = class TheDoctor extends LitElement {
529
939
  break;
530
940
  }
531
941
  }
532
- closeWelcome() {
533
- this.welcomeBox.hide();
534
- localStorage.setItem("pb33f-doctor-welcome", "closed");
942
+ handleTimelineViolationsLoaded(evt) {
943
+ const { violations, statistics } = evt.detail;
944
+ this.problemList.problems = violations;
945
+ this.problems = violations;
946
+ if (this.changeDiffEditor) {
947
+ this.changeDiffEditor.setMarkers(violations);
948
+ }
949
+ this.problemsOverview.statistics = statistics.statistics;
950
+ this.problemsOverview.problems = this.problemList.problemItems;
951
+ this.viewingHistoricalViolations = true;
535
952
  }
536
953
  selectEditorTab(event) {
537
954
  this.selectedEditorTab = event.detail.name;
955
+ this.tabCache.markEditorTabLoaded(event.detail.name);
956
+ if (this.viewingHistoricalViolations &&
957
+ (event.detail.name === 'spec' || event.detail.name === 'explorer')) {
958
+ this.timelineController.restoreLiveViolations();
959
+ this.navigatorPanel?.showTab('model-tree');
960
+ }
961
+ if (event.detail.name === 'explorer') {
962
+ this.explorerVisible = true;
963
+ }
964
+ else {
965
+ this.explorerVisible = false;
966
+ }
538
967
  switch (event.detail.name) {
539
968
  case ActiveView.Ruleset:
540
969
  if (this.rulesetPulse) {
541
970
  this.rulesetPulse = false;
542
971
  }
543
- this.controlTabGroup.show(ActiveView.Ruleset);
972
+ this.controlTabs.showTab(ActiveView.Ruleset);
973
+ break;
974
+ case ActiveView.Tardis:
975
+ this.ensureTardisControlInitialized();
544
976
  break;
545
977
  }
546
978
  }
979
+ ensureTardisControlInitialized() {
980
+ if (this.timeVortex.tardisControl)
981
+ return;
982
+ this.updateComplete.then(() => {
983
+ const tardisControl = this.tardisControlRef.value;
984
+ if (tardisControl && !this.timeVortex.tardisControl) {
985
+ tardisControl.diffEditor = this.changeDiffEditor;
986
+ this.timeVortex.setTardisControl(tardisControl);
987
+ tardisControl.fetchHistory();
988
+ }
989
+ });
990
+ }
547
991
  selectControlTab(event) {
992
+ this.tabCache.markControlTabLoaded(event.detail.name);
548
993
  switch (event.detail.name) {
549
994
  case ActiveView.Problems:
550
995
  case ActiveView.Overview:
@@ -555,91 +1000,227 @@ let TheDoctor = class TheDoctor extends LitElement {
555
1000
  break;
556
1001
  case ActiveView.Ruleset:
557
1002
  if (this.selectedEditorTab != ActiveView.Ruleset) {
558
- this.editorTabGroup.show(ActiveView.Ruleset);
1003
+ this.editorPanel?.showTab(ActiveView.Ruleset);
559
1004
  this.selectedEditorTab = ActiveView.Ruleset;
560
1005
  }
561
1006
  break;
562
1007
  }
563
1008
  }
564
- toggleSidebar() {
565
- const splitPanel = this.shadowRoot?.querySelector('sl-split-panel.split-panel');
566
- if (!this.sidebarClosed) {
567
- if (splitPanel) {
568
- this.collapseButton.name = "chevron-bar-left";
569
- this.problemsDataDiv.style.display = "none";
570
- splitPanel.style.setProperty('--min', '40px');
571
- splitPanel.style.setProperty('--max', 'calc(100vw - 40px)');
572
- splitPanel.position = 99;
573
- splitPanel.disabled = true;
574
- this.splitDivider.style.display = "none";
575
- this.activitySpinner.classList.add('spinner-draw-closed');
576
- }
1009
+ async handleToolsCompare() {
1010
+ if (!this.toolsEditor || this.toolsCompareLoading) {
1011
+ return;
577
1012
  }
578
- else {
579
- if (splitPanel) {
580
- this.collapseButton.name = "chevron-bar-right";
581
- splitPanel.style.setProperty('--min', '600px');
582
- splitPanel.style.setProperty('--max', 'calc(100vw - 600px)');
583
- splitPanel.position = 60;
584
- splitPanel.disabled = false;
585
- this.problemsDataDiv.style.display = "block";
586
- this.splitDivider.style.display = "block";
587
- this.activitySpinner.classList.remove('spinner-draw-closed');
588
- }
1013
+ const specContent = this.toolsEditor.getValue();
1014
+ this.toolsCompareLoading = true;
1015
+ try {
1016
+ await this.timelineController.toolsCompare(specContent);
1017
+ }
1018
+ finally {
1019
+ this.toolsCompareLoading = false;
589
1020
  }
590
- this.sidebarClosed = !this.sidebarClosed;
591
1021
  }
592
- showHistory() {
593
- this.closeExplorer();
594
- this.hideMinimapIcon();
595
- this.requestUpdate();
1022
+ showHistory() { this.viewStateManager.showHistory(); }
1023
+ toggleExplorer() { this.viewStateManager.toggleExplorer(); }
1024
+ hideMinimapIcon() { this.viewStateManager.hideMinimapIcon(); }
1025
+ hideDiagnosisButton() { this.viewStateManager.hideDiagnosisButton(); }
1026
+ enableDiagnosisButton() { this.viewStateManager.enableDiagnosisButton(); }
1027
+ showMinimapIcon() { this.viewStateManager.showMinimapIcon(); }
1028
+ closeExplorer() { this.viewStateManager.closeExplorer(); }
1029
+ // DoctorContext interface implementation
1030
+ get activity() {
1031
+ return this.activitySpinner;
1032
+ }
1033
+ createEditorOps(editor) {
1034
+ return {
1035
+ setValue: (value, fireEvent) => editor.setValue(value, fireEvent),
1036
+ getValue: () => editor.getValue(),
1037
+ setMarkers: (problems) => editor.setMarkers(problems),
1038
+ clearAllMarkers: () => editor.clearAllMarkers(),
1039
+ setReadOnly: (readOnly) => editor.setReadOnly(readOnly),
1040
+ revealLineInCenter: (line) => editor.editor?.revealLineInCenter(line),
1041
+ toggleMinimap: () => editor.toggleMinimap(),
1042
+ clearDecorations: () => editor.clearDecorations(),
1043
+ applyLinkDecorations: () => editor.applyLinkDecorations(),
1044
+ switchLanguage: (language) => editor.switchLanguage(language),
1045
+ get links() { return editor.links; },
1046
+ set links(value) { editor.links = value; },
1047
+ get breadcumb() { return editor.breadcumb; }
1048
+ };
596
1049
  }
597
- toggleExplorer() {
598
- this.explorerVisible = !this.explorerVisible;
599
- if (this.explorerVisible && this.activeNode) {
600
- this.explorer.moveToNode(this.activeNode);
1050
+ get editorHost() {
1051
+ if (!this._editorHost) {
1052
+ this._editorHost = {
1053
+ getEditor: this._getEditorOps.bind(this),
1054
+ getDefaultEditor: this._getDefaultEditorOps.bind(this)
1055
+ };
601
1056
  }
602
- this.hideMinimapIcon();
603
- this.showDiagnosisButton = false;
604
- this.explorerBooted = true;
605
- // check if ths is safari and fire a warning toast!
606
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
607
- if (isSafari) {
608
- this.sendToast({
609
- id: crypto.randomUUID(),
610
- type: ToastType.WARNING,
611
- body: "Safari is not supported by the explorer. Please use Chrome, Firefox or Edge. As you can see the icons are all messed up.",
612
- title: "Safari Warning"
613
- });
1057
+ return this._editorHost;
1058
+ }
1059
+ _getEditorOps(id) {
1060
+ const editorKey = id ?? 'default';
1061
+ const cached = this._editorOpsCache.get(editorKey);
1062
+ if (cached)
1063
+ return cached;
1064
+ const editor = id ? this.editorMap.get(id) : this.editor;
1065
+ if (!editor)
1066
+ return undefined;
1067
+ const ops = this.createEditorOps(editor);
1068
+ if (this._editorOpsCache.size >= 10) {
1069
+ const firstKey = this._editorOpsCache.keys().next().value;
1070
+ if (firstKey)
1071
+ this._editorOpsCache.delete(firstKey);
614
1072
  }
615
- this.workspaceController.workspaceView.active = false;
1073
+ this._editorOpsCache.set(editorKey, ops);
1074
+ return ops;
616
1075
  }
617
- hideMinimapIcon() {
618
- this.minimapIconVisible = false;
1076
+ _getDefaultEditorOps() {
1077
+ return this._getEditorOps();
619
1078
  }
620
- hideDiagnosisButton() {
621
- this.showDiagnosisButton = false;
622
- this.workspaceController.workspaceView.active = false;
1079
+ get controlTabs() {
1080
+ if (!this._controlTabs) {
1081
+ this._controlTabs = {
1082
+ showTab: this._showControlTab.bind(this),
1083
+ getSelectedTab: this._getSelectedControlTab.bind(this)
1084
+ };
1085
+ }
1086
+ return this._controlTabs;
623
1087
  }
624
- enableDiagnosisButton() {
625
- if (!this.autoDiagnose) {
626
- this.showDiagnosisButton = true;
1088
+ _showControlTab(panel) {
1089
+ this.sidebarPanel?.showTab(panel);
1090
+ }
1091
+ _getSelectedControlTab() {
1092
+ const activeTab = this.sidebarPanel?.tabGroup?.querySelector('sl-tab[active]');
1093
+ return activeTab?.getAttribute('panel') ?? '';
1094
+ }
1095
+ get editorTabs() {
1096
+ if (!this._editorTabs) {
1097
+ this._editorTabs = {
1098
+ showTab: this._showEditorTab.bind(this),
1099
+ getSelectedTab: this._getSelectedEditorTab.bind(this)
1100
+ };
627
1101
  }
1102
+ return this._editorTabs;
628
1103
  }
629
- showMinimapIcon() {
630
- this.minimapIconVisible = true;
1104
+ _showEditorTab(panel) {
1105
+ this.editorPanel?.showTab(panel);
631
1106
  }
632
- closeExplorer() {
633
- this.explorerVisible = false;
634
- this.showMinimapIcon();
635
- this.showDiagnosisButton = true;
636
- setTimeout(() => {
637
- if (this.pendingLine > 0) {
638
- this.editor.editor?.setPosition({ lineNumber: this.pendingLine, column: 1 });
639
- this.editor.editor?.revealLineInCenter(this.pendingLine);
640
- this.pendingLine = 0;
641
- }
642
- }, 20);
1107
+ _getSelectedEditorTab() {
1108
+ return this.selectedEditorTab;
1109
+ }
1110
+ get navigatorTabs() {
1111
+ if (!this._navigatorTabs) {
1112
+ this._navigatorTabs = {
1113
+ showTab: this._showNavigatorTab.bind(this),
1114
+ getSelectedTab: this._getSelectedNavigatorTab.bind(this)
1115
+ };
1116
+ }
1117
+ return this._navigatorTabs;
1118
+ }
1119
+ _showNavigatorTab(panel) {
1120
+ this.navigatorPanel?.showTab(panel);
1121
+ }
1122
+ _getSelectedNavigatorTab() {
1123
+ return '';
1124
+ }
1125
+ get taskSubscription() {
1126
+ if (!this._taskSubscription) {
1127
+ this._taskSubscription = {
1128
+ subscribeToTaskType: this._subscribeToTaskType.bind(this)
1129
+ };
1130
+ }
1131
+ return this._taskSubscription;
1132
+ }
1133
+ _subscribeToTaskType(taskType, callback, actions) {
1134
+ return this.globalTaskController.subscribeToTaskType(taskType, callback, actions);
1135
+ }
1136
+ getActiveWorkspaceId() {
1137
+ return this.workspaceController?.activeWorkspace?.workspaceId;
1138
+ }
1139
+ get rolodex() {
1140
+ if (!this._rolodexAccess) {
1141
+ const self = this;
1142
+ this._rolodexAccess = {
1143
+ get activePath() { return self.rolodexActivePath; },
1144
+ get activeHash() { return self.rolodexActiveHash; },
1145
+ get rootPath() { return self.rolodexRootPath; },
1146
+ get rootHash() { return self.rolodexRootHash; },
1147
+ get needsReset() { return self.rolodexNeedsReset; },
1148
+ set needsReset(value) { self.rolodexNeedsReset = value; }
1149
+ };
1150
+ }
1151
+ return this._rolodexAccess;
1152
+ }
1153
+ get isAuthenticated() {
1154
+ return this.authController?.authenticated ?? false;
1155
+ }
1156
+ get host() {
1157
+ return this;
1158
+ }
1159
+ setViewingHistoricalViolations(viewing) {
1160
+ this.viewingHistoricalViolations = viewing;
1161
+ }
1162
+ setProblems(problems) {
1163
+ this.problems = problems;
1164
+ }
1165
+ lintSpec(spec, url) {
1166
+ this.diagnosticController.lintSpec(spec, url);
1167
+ }
1168
+ setExplorerActiveNode(node) {
1169
+ this.explorer.activeNode = node;
1170
+ this.explorer.equalizer.activeNode = node;
1171
+ }
1172
+ setEditorDirty(dirty) {
1173
+ this.editorDirty = dirty;
1174
+ }
1175
+ rulesetManuallyChanged() {
1176
+ this.ruleController.rulesetManuallyChanged();
1177
+ }
1178
+ getSessionId() {
1179
+ return this.authController?.session?.sessionId ?? '';
1180
+ }
1181
+ getBag(key) {
1182
+ return this.bagManager?.getBag(key);
1183
+ }
1184
+ setBagValue(bagKey, valueKey, value) {
1185
+ const bag = this.bagManager?.getBag(bagKey);
1186
+ bag?.set(valueKey, value);
1187
+ }
1188
+ getBagValue(bagKey, valueKey) {
1189
+ const bag = this.bagManager?.getBag(bagKey);
1190
+ return bag?.get(valueKey);
1191
+ }
1192
+ getBrokerId() {
1193
+ return this.brokerController?.brokerConnectionId ?? '';
1194
+ }
1195
+ get diagnosticEditor() {
1196
+ return this.editor;
1197
+ }
1198
+ get diagnosticProblemList() {
1199
+ return this.problemList;
1200
+ }
1201
+ get diagnosticProblemsOverview() {
1202
+ return this.problemsOverview;
1203
+ }
1204
+ get diagnosticExplorer() {
1205
+ return this.explorer;
1206
+ }
1207
+ get brokerConnectionId() {
1208
+ return this.brokerController.brokerConnectionId;
1209
+ }
1210
+ buildRolodexResultMap(problems) {
1211
+ return this.rolodexController.buildRolodexResultMap(problems);
1212
+ }
1213
+ queryRolodex(path) {
1214
+ this.rolodexController.queryRolodex(path);
1215
+ }
1216
+ fetchRefMap(path) {
1217
+ this.modelController.fetchRefMap(path);
1218
+ }
1219
+ extractGraph(graph) {
1220
+ this.modelController.extractGraph(graph);
1221
+ }
1222
+ updateSpecProblems(problems) {
1223
+ this.specController.updateProblems(problems);
643
1224
  }
644
1225
  render() {
645
1226
  let overlay = html ``;
@@ -647,109 +1228,33 @@ let TheDoctor = class TheDoctor extends LitElement {
647
1228
  overlay = html `
648
1229
  <div class="overlay" @click="return false"></div>`;
649
1230
  }
650
- let welcomeBox = html `
651
- <pb33f-attention-box id="welcome" type="success"
652
- headerText="Welcome to the clinic, I am the OpenAPI doctor." closeable>
653
- This is an <strong>early preview</strong> of a new <a href="https://pb33f.io">pb33f</a> product,
654
- built on top of our very own open source and free software.
655
- If you find a bug, please let us know in the <strong>feedback</strong> tab. <br/><br/>
656
- <a href="#" @click="${this.closeWelcome}">[Close this message]</a>
657
- </pb33f-attention-box>`;
658
- const welcomeClosed = localStorage.getItem("pb33f-doctor-welcome");
659
- if (welcomeClosed) {
660
- welcomeBox = html ``;
661
- }
662
- let rulesetPulsePill = html ``;
663
- if (this.rulesetPulse) {
664
- rulesetPulsePill = html `
665
- <sl-badge pulse></sl-badge>`;
666
- }
667
- let mainPanelView = html `
668
-
669
- <div class="problems" slot="end">
670
- <div class="problems-data">
671
- <sl-tab-group class="tab-group" id="manager-controls"
672
- @sl-tab-show="${this.selectControlTab}">
673
- <sl-tab slot="nav" panel="overview" class="tab" id="overviewPanel" active>Overview
674
- </sl-tab>
675
- <sl-tab slot="nav" panel="viewer" class="tab" id="viewerPanel">Objects</sl-tab>
676
- <sl-tab slot="nav" panel="problems" class="tab" id="problemsPanel">Problems</sl-tab>
677
- <sl-tab slot="nav" panel="ruleset" class="tab" id="rulesetPanel">Rules</sl-tab>
678
- <sl-tab slot="nav" panel="feedback" class="tab" id="feedbackPanel">Feedback</sl-tab>
679
- <sl-tab-panel name="overview" class="tab-panel">${this.problemsOverview}</sl-tab-panel>
680
- <sl-tab-panel name="problems" class="tab-panel">${this.problemList}</sl-tab-panel>
681
- <sl-tab-panel name="ruleset" class="tab-panel">${this.manageRuleset}</sl-tab-panel>
682
- <sl-tab-panel name="feedback" class="tab-panel">${this.feedback}</sl-tab-panel>
683
- <sl-tab-panel name="viewer" class="tab-panel">${this.renderedNode}</sl-tab-panel>
684
- </sl-tab-group>
685
- </div>
686
- <sl-icon-button class="collapse-side" name="chevron-bar-right"
687
- @click="${this.toggleSidebar}"></sl-icon-button>
688
- </div>`;
689
- let modelTree = html `${this.modelTree}`;
690
- if (this.rolodexTree.node && this.rolodexTree.node.nodes?.length > 0) {
691
- modelTree = html `
692
- <sl-split-panel id="rolodex-split-panel" vertical class="split-panel-rolodex"
693
- position="${this.rolodexDividerPosition}" @sl-reposition="${this.updateRolodexDivider}"
694
- style="height: calc(100% - 60px);">
695
- <sl-icon id="split-rolodex-tree" slot="divider" name="grip-horizontal"
696
- class="divider-horiz"></sl-icon>
697
- <div slot="start" class="model-tree">
698
- ${this.modelTree}
699
- </div>
700
- <div slot="end" class="model-tree">
701
- ${this.rolodexTree}
702
- </div>
703
- </sl-split-panel>`;
704
- }
705
- // if the timeVortex is on and the picker is visible, we need to wrap the model tree in a tab view.
706
- if (this.timeVortex.pickerVisible) {
707
- modelTree = html `
708
- <sl-tab-group class="tab-group timevortex" @sl-tab-show="${this.selectEditorTab}">
709
- <sl-tab slot="nav" panel="model-tree" class="tab" id="model-tree">
710
- Document
711
- </sl-tab>
712
- <sl-tab slot="nav" panel="timeline" class="tab" id="timeline-view">
713
- Timeline
714
- </sl-tab>
715
- <sl-tab-panel name="model-tree" class="tab-panel model-tree-panel">
716
- ${modelTree}
717
- </sl-tab-panel>
718
- <sl-tab-panel name="timeline" class="tab-panel">
719
- ${this.timeVortex.historyPicker}
720
- </sl-tab-panel>
721
- </sl-tab-group>
722
- `;
723
- }
724
- const controls = html `
725
- <div class="controls">
726
- <sl-tooltip content="Upload zip file or tar.gz (tarball)" placement="top">
727
- <sl-button ?disabled=${this.importDisabled} class="import-button" variant="text"
728
- size="small" @click="${() => {
729
- this.uploadArchive.show();
730
- }}">
731
- Import
732
- </sl-button>
733
- </sl-tooltip>
734
- <sl-tooltip content="Nuke / reset workspace" placement="top">
735
- <sl-icon-button class="nuke-session-button" name="radioactive" @click="${() => {
736
- this.nukeWorkspace.show();
737
- }}">
738
- </sl-icon-button>
739
- </sl-tooltip>
740
- </div>`;
741
- let navigatorView = html `
742
- ${controls}
743
- ${modelTree}
744
- `;
1231
+ const mainPanelView = html `
1232
+ <pb33f-doctor-sidebar-panel
1233
+ slot="end"
1234
+ role="complementary"
1235
+ aria-label="Problems and diagnostics"
1236
+ ?unavailable=${this.unavailable}
1237
+ ?toolsCompareLoading=${this.toolsCompareLoading}
1238
+ ?toolsEditorHasContent=${this.toolsEditorHasContent}>
1239
+ <div slot="problems-overview" class="sidebar-slot-content">${this.problemsOverview}</div>
1240
+ <div slot="problem-list" class="sidebar-slot-content">${this.tabCache.shouldRenderControlTab('problems') ? this.problemList : nothing}</div>
1241
+ <div slot="tools-editor" class="sidebar-slot-content"><slot name="tools-editor"></slot></div>
1242
+ <div slot="manage-ruleset" class="sidebar-slot-content">${this.tabCache.shouldRenderControlTab('ruleset') ? this.manageRuleset : nothing}</div>
1243
+ <div slot="feedback" class="sidebar-slot-content">${this.tabCache.shouldRenderControlTab('feedback') ? this.feedback : nothing}</div>
1244
+ <div slot="rendered-node" class="sidebar-slot-content">${this.tabCache.shouldRenderControlTab('viewer') ? this.modelController.renderedNodeComponent : nothing}</div>
1245
+ </pb33f-doctor-sidebar-panel>`;
1246
+ const rolodexVisible = this.rolodexTree.node && this.rolodexTree.node.nodes?.length > 0;
745
1247
  if (this.authController.state && this.authController.state.authenticated) {
746
1248
  this.statusBar.authenticated = true;
747
1249
  }
748
1250
  return html `
1251
+ <div role="status" aria-live="polite" aria-atomic="true" class="sr-only">
1252
+ ${this.currentViewName ? `Now viewing ${this.currentViewName}` : ''}
1253
+ </div>
749
1254
  ${this.uploadArchive}
750
1255
  ${this.nukeWorkspace}
751
- ${welcomeBox}
752
1256
  ${this.toastManager}
1257
+ ${this.globalTaskView}
753
1258
  <sl-dialog open id="loading-overlay" class="dialog-overview"
754
1259
  style="--width: 30vw" no-header>
755
1260
  <h3 class="loading">OpenAPI Doctor is booting...</h3>
@@ -774,159 +1279,72 @@ let TheDoctor = class TheDoctor extends LitElement {
774
1279
  </div>
775
1280
  </sl-dialog>
776
1281
  <div class="doctor">
777
- ${this.activitySpinner}
778
1282
  ${this.errorBanner}
779
1283
  ${overlay}
780
1284
  <sl-split-panel id="explorer-split-panel" class="split-panel-explorer" position="12"
781
1285
  @sl-reposition="${this.updateExplorerDivider}">
782
- <sl-icon id="split-divider-tree" slot="divider" name="grip-vertical" class="divider-vert"></sl-icon>
783
- <div slot="start" class="model-tree">
784
- ${navigatorView}
785
- ${this.creditTicker}
1286
+ <sl-icon id="split-divider-tree" slot="divider" name="grip-vertical" class="divider-vert" aria-hidden="true"></sl-icon>
1287
+ <div slot="start" class="model-tree" role="navigation" aria-label="Document navigation">
1288
+ <pb33f-doctor-navigator-panel
1289
+ ?importDisabled=${this.importDisabled}
1290
+ ?workspaceReadOnly=${this.workspaceReadOnly}
1291
+ ?timeVortexVisible=${this.timeVortex.pickerVisible}
1292
+ ?rolodexVisible=${rolodexVisible}
1293
+ .rolodexDividerPosition=${this.rolodexDividerPosition}>
1294
+ <pb33f-doctor-controls-panel slot="controls"
1295
+ ?importDisabled=${this.importDisabled}
1296
+ ?workspaceReadOnly=${this.workspaceReadOnly}>
1297
+ </pb33f-doctor-controls-panel>
1298
+ <div slot="model-tree" class="tree-slot-container">${this.modelTree}</div>
1299
+ ${rolodexVisible ? html `
1300
+ <pb33f-bundle-toolbar
1301
+ slot="bundle-toolbar"
1302
+ ?isBundled=${this.isBundled}
1303
+ ?loading=${this.bundleLoading}>
1304
+ </pb33f-bundle-toolbar>
1305
+ ` : nothing}
1306
+ <div slot="rolodex-tree" class="tree-slot-container">${this.rolodexTree}</div>
1307
+ <div slot="history-picker">${this.timeVortex.historyPicker}</div>
1308
+ <div slot="credit-ticker">${this.creditTicker}</div>
1309
+ </pb33f-doctor-navigator-panel>
786
1310
  </div>
787
1311
  <div slot="end">
788
1312
  <sl-split-panel id="inspector-split-panel"
789
1313
  @sl-reposition="${this.updateInspectorDivider}"
790
1314
  class="split-panel ${this.unavailable ? 'unavailable' : ''}">
791
1315
  <sl-icon id="split-divider" slot="divider" name="grip-vertical"
792
- class="divider-vert"></sl-icon>
793
- <div class="editor" slot="start">
794
-
795
- ${this.settingsComponent}
796
-
797
- <sl-tooltip class="minimap-tip" content="Toggle source mini-map" hoist
798
- style="${!this.minimapIconVisible ? 'display: none' : ''}">
799
- <sl-icon-button @click="${this.minimapToggled}"
800
- name="map"
801
- class="minimap-toggle ${this.minimapVisible ? 'active' : ''}"
802
- style="${!this.minimapIconVisible ? 'display: none' : ''}"></sl-icon-button>
803
- </sl-tooltip>
804
-
805
- <sl-tooltip class="settings-tip" content="Open settings for the doctor" hoist>
806
- <sl-icon-button @click="${() => {
807
- this.settingsComponent.open();
808
- }}"
809
- name="gear"
810
- class="settings-toggle ${!this.settingsComponent.opened ? 'active' : ''}"></sl-icon-button>
811
- </sl-tooltip>
812
-
813
- <sl-button class="diagnose-button" @click="${this.runDiagnostics}"
814
- size="small"
815
- style="${(this.autoDiagnose || !this.showDiagnosisButton) ? 'display: none' : ''}">
816
- make diagnosis
817
- </sl-button>
818
-
819
-
820
- ${this.detailsDrawer}
821
- <sl-tab-group class="tab-group" @sl-tab-show="${this.selectEditorTab}"
822
- id="editor-controls">
823
-
824
- <sl-tab slot="nav" panel="workspaces" class="tab ${!this.authController.authenticated ? 'hidden' : ''}" id="workspaces"
825
- @click="${() => {
826
- this.selectedEditorTab = 'workspaces';
827
- this.toggleExplorer();
828
- this.hideDiagnosisButton();
829
- this.workspaceController.workspaceView.active = true;
830
- }}">
831
- <sl-icon-button name="person-workspace"
832
- class="workspace-icon ${this.selectedEditorTab === 'workspaces' ? 'active' : ''}"></sl-icon-button>
833
- </sl-tab>
834
-
835
- <sl-tab slot="nav" panel="spec" class="tab" id="spec" active
836
- @click="${() => {
837
- this.selectedEditorTab = 'spec';
838
- this.closeExplorer();
839
- this.enableDiagnosisButton();
840
- }}">
841
- OpenAPI Spec
842
- </sl-tab>
843
- <sl-tab slot="nav" panel="explorer" class="tab" id="explorer"
844
- @click="${() => {
845
- this.selectedEditorTab = 'explorer';
846
- this.toggleExplorer();
847
- this.hideDiagnosisButton();
848
- }}">Explorer
849
- </sl-tab>
850
-
851
-
852
- <sl-tab slot="nav" panel="tardis" class="tab" id="history"
853
- @click="${() => {
854
- this.showHistory();
855
- this.hideDiagnosisButton();
856
- }}">History
857
- </sl-tab>
858
-
859
- <sl-tab slot="nav" panel="ruleset" class="tab" id="ruleset"
860
- @click="${() => {
861
- this.closeExplorer();
862
- this.hideDiagnosisButton();
863
- }}">
864
- Ruleset ${rulesetPulsePill}
865
- </sl-tab>
866
-
867
- <sl-tab slot="nav" panel="docs" class="tab" id="docs"
868
- @click="${() => {
869
- this.hideMinimapIcon();
870
- this.hideDiagnosisButton();
871
- }}">
872
- API Docs
873
- </sl-tab>
874
-
875
-
876
- <sl-tab-panel name="spec" class="tab-panel">
877
- <div class="main-view">
878
- ${this.statusBar}
879
- <div id="editor-url-overlay" class="editor-url-overlay">
880
-
881
-
882
- <div id="url-spinner">
883
- <sl-icon name="arrow-repeat" class="url-spinner-icon"></sl-icon>
884
- <h3>Fetching URL</h3>
885
- <p>${this.activeURL}</p>
886
- </div>
887
-
888
-
889
- <div id="url-problem" class="url-problem">
890
- <pb33f-attention-box type="warning" headerText="Problem with URL">
891
- <h4>Error: ${this.urlErrorCode}</h4>
892
- <p>${this.urlErrorMessage}</p>
893
- <sl-button @click="${this.hideUrlError}">OK</sl-button>
894
- <p></p>
895
- </pb33f-attention-box>
896
- </div>
1316
+ class="divider-vert" aria-hidden="true"></sl-icon>
1317
+ <div class="editor" slot="start" role="main" aria-label="API specification editor">
1318
+ <pb33f-doctor-editor-panel
1319
+ ?authenticated=${this.authController.authenticated}
1320
+ ?minimapVisible=${this.minimapVisible}
1321
+ ?minimapIconVisible=${this.minimapIconVisible}
1322
+ ?showDiagnosisButton=${this.showDiagnosisButton}
1323
+ ?autoDiagnose=${this.autoDiagnose}
1324
+ ?editorDirty=${this.editorDirty}
1325
+ .selectedEditorTab=${this.selectedEditorTab}
1326
+ ?rulesetPulse=${this.rulesetPulse}>
1327
+ <div slot="settings">${this.settingsComponent}</div>
1328
+ <div slot="activity-spinner">${this.activitySpinner}</div>
1329
+ <div slot="generic-drawer">${this.genericDrawer}</div>
1330
+ <div slot="status-bar">${this.statusBar}</div>
1331
+ <pb33f-doctor-url-overlay slot="url-overlay"
1332
+ .activeURL=${this.activeURL}
1333
+ .errorCode=${this.urlErrorCode}
1334
+ .errorMessage=${this.urlErrorMessage}>
1335
+ </pb33f-doctor-url-overlay>
1336
+ <slot name="spec-editor" slot="spec-editor"></slot>
1337
+ <slot name="ruleset-editor" slot="ruleset-editor"></slot>
1338
+ <div slot="explorer" @mouseleave="${this.ungrabExplorer}">${this.tabCache.shouldRenderEditorTab('explorer') ? this.explorer : nothing}</div>
1339
+ <div slot="tardis-control">${this.tabCache.shouldRenderEditorTab('tardis') ? html `
1340
+ <pb33f-tardis-control .doc=${this} ${ref(this.tardisControlRef)}>
1341
+ <div slot="diff-editor">
1342
+ <slot name="diff-editor"></slot>
897
1343
  </div>
898
-
899
- <!-- EDITOR -->
900
- <slot name="spec-editor"></slot>
901
- <!-- EDITOR -->
902
- </div>
903
- </sl-tab-panel>
904
- <sl-tab-panel name="ruleset" class="tab-panel">
905
-
906
- <!-- RULESET EDITOR -->
907
- <slot name="ruleset-editor"></slot>
908
- <!-- RULESET EDITOR -->
909
- </sl-tab-panel>
910
- <sl-tab-panel name="explorer" class="tab-panel"
911
- @mouseleave="${this.ungrabExplorer}">${this.explorer}
912
- </sl-tab-panel>
913
-
914
- <sl-tab-panel name="tardis" class="tab-panel">
915
- ${this.timeVortex.tardisControl}
916
- </sl-tab-panel>
917
-
918
- <sl-tab-panel name="docs" class="tab-panel" style="height: calc(100vh - 100px)">
919
- <iframe src="${this.doctorEndpoint}/model/scalar-template?z=${this.randomTicker}" width="100%" height="100%" style="border: none"></iframe>
920
- </sl-tab-panel>
921
-
922
- ${this.authController.authenticated ? html `
923
-
924
- <sl-tab-panel name="workspaces" class="tab-panel">
925
- ${this.workspaceController.workspaceView}
926
- </sl-tab-panel>
927
- ` : ''}
928
-
929
- </sl-tab-group>
1344
+ </pb33f-tardis-control>
1345
+ ` : nothing}</div>
1346
+ <div slot="workspaces">${this.tabCache.shouldRenderEditorTab('workspaces') ? this.workspaceController.workspaceView : nothing}</div>
1347
+ </pb33f-doctor-editor-panel>
930
1348
  </div>
931
1349
  ${mainPanelView}
932
1350
  </sl-split-panel>
@@ -934,9 +1352,6 @@ let TheDoctor = class TheDoctor extends LitElement {
934
1352
  </sl-split-panel>
935
1353
  </div>`;
936
1354
  }
937
- randomTicker() {
938
- return crypto.randomUUID().toString();
939
- }
940
1355
  // <iframe src="${this.doctorEndpoint}/model/scalar-template?z=${this.randomTicker}" width="100%" height="100%" style="border: none"></iframe>
941
1356
  fetchUrl(event) {
942
1357
  this.activeURL = event.detail.url;
@@ -945,53 +1360,44 @@ let TheDoctor = class TheDoctor extends LitElement {
945
1360
  this.diagnosticController.lintSpec('', event.detail.url);
946
1361
  }
947
1362
  hideUrlError() {
948
- this.urlProblem.style.display = 'none';
949
- this.urlOverlay.style.display = 'none';
950
- this.urlSpinner.style.display = 'none';
1363
+ if (this.urlOverlayComponent) {
1364
+ this.urlOverlayComponent.hide();
1365
+ }
951
1366
  this.editor.toggleMinimap();
952
1367
  }
953
1368
  showUrlError(e) {
954
1369
  this.urlErrorCode = e.status;
955
1370
  this.urlErrorMessage = e.detail;
956
- this.urlSpinner.style.display = 'none';
957
- this.urlOverlay.style.display = 'block';
958
- this.urlProblem.style.display = 'block';
1371
+ if (this.urlOverlayComponent) {
1372
+ this.urlOverlayComponent.showError(e.status, e.detail);
1373
+ }
959
1374
  this.editor.toggleMinimap();
960
1375
  this.requestUpdate();
961
1376
  }
1377
+ showUrlLoading() {
1378
+ if (this.urlOverlayComponent) {
1379
+ this.urlOverlayComponent.show();
1380
+ }
1381
+ }
962
1382
  ungrabExplorer() {
963
1383
  this.explorer.grabbed = false;
964
1384
  }
965
1385
  selectTardis() {
966
1386
  this.closeExplorer();
967
- this.historyPanel.click();
1387
+ this.editorPanel?.showTab('tardis');
968
1388
  }
969
1389
  };
970
- TheDoctor.styles = [theDoctorCss, linksCss, dialogCss, buttonCss, radioGroupsCss, tabsCss, formsCss, spinnerCss, tooltipCss, panelsCss, nukeCss];
971
- __decorate([
972
- query('#overviewPanel')
973
- ], TheDoctor.prototype, "overviewPanel", void 0);
974
- __decorate([
975
- query('#problemsPanel')
976
- ], TheDoctor.prototype, "problemsPanel", void 0);
977
- __decorate([
978
- query('#viewerPanel')
979
- ], TheDoctor.prototype, "viewerPanel", void 0);
980
- __decorate([
981
- query('#explorer')
982
- ], TheDoctor.prototype, "explorerPanel", void 0);
983
- __decorate([
984
- query('#history')
985
- ], TheDoctor.prototype, "historyPanel", void 0);
986
- __decorate([
987
- query('sl-tab-group#manager-controls')
988
- ], TheDoctor.prototype, "controlTabGroup", void 0);
989
- __decorate([
990
- query('sl-tab-group#editor-controls')
991
- ], TheDoctor.prototype, "editorTabGroup", void 0);
992
- __decorate([
993
- query('pb33f-attention-box#welcome')
994
- ], TheDoctor.prototype, "welcomeBox", void 0);
1390
+ TheDoctor.styles = [theDoctorCss,
1391
+ linksCss,
1392
+ dialogCss,
1393
+ buttonCss,
1394
+ radioGroupsCss,
1395
+ tabsCss,
1396
+ formsCss,
1397
+ spinnerCss,
1398
+ tooltipCss,
1399
+ panelsCss,
1400
+ nukeCss];
995
1401
  __decorate([
996
1402
  query('sl-radio-group#export-ruleset-radio')
997
1403
  ], TheDoctor.prototype, "exportSelection", void 0);
@@ -1001,9 +1407,6 @@ __decorate([
1001
1407
  __decorate([
1002
1408
  query('sl-dialog#loading-overlay')
1003
1409
  ], TheDoctor.prototype, "loadingOverlay", void 0);
1004
- __decorate([
1005
- query('div.problems-data')
1006
- ], TheDoctor.prototype, "problemsDataDiv", void 0);
1007
1410
  __decorate([
1008
1411
  query('#url-input-button')
1009
1412
  ], TheDoctor.prototype, "urlInputButton", void 0);
@@ -1014,23 +1417,26 @@ __decorate([
1014
1417
  property({ type: Boolean })
1015
1418
  ], TheDoctor.prototype, "unavailable", void 0);
1016
1419
  __decorate([
1017
- query('#editor-url-overlay')
1018
- ], TheDoctor.prototype, "urlOverlay", void 0);
1420
+ query('pb33f-doctor-controls-panel')
1421
+ ], TheDoctor.prototype, "controlsPanel", void 0);
1422
+ __decorate([
1423
+ query('pb33f-doctor-url-overlay')
1424
+ ], TheDoctor.prototype, "urlOverlayComponent", void 0);
1019
1425
  __decorate([
1020
- query('#url-problem')
1021
- ], TheDoctor.prototype, "urlProblem", void 0);
1426
+ query('pb33f-doctor-sidebar-panel')
1427
+ ], TheDoctor.prototype, "sidebarPanel", void 0);
1022
1428
  __decorate([
1023
- query('#url-spinner')
1024
- ], TheDoctor.prototype, "urlSpinner", void 0);
1429
+ query('pb33f-doctor-navigator-panel')
1430
+ ], TheDoctor.prototype, "navigatorPanel", void 0);
1431
+ __decorate([
1432
+ query('pb33f-doctor-editor-panel')
1433
+ ], TheDoctor.prototype, "editorPanel", void 0);
1025
1434
  __decorate([
1026
1435
  property()
1027
1436
  ], TheDoctor.prototype, "doctorEndpoint", void 0);
1028
1437
  __decorate([
1029
1438
  query('sl-dialog#export-ruleset')
1030
1439
  ], TheDoctor.prototype, "exportRulesetDialog", void 0);
1031
- __decorate([
1032
- query('sl-icon-button.collapse-side')
1033
- ], TheDoctor.prototype, "collapseButton", void 0);
1034
1440
  __decorate([
1035
1441
  query('sl-icon#split-divider')
1036
1442
  ], TheDoctor.prototype, "splitDivider", void 0);
@@ -1040,9 +1446,6 @@ __decorate([
1040
1446
  __decorate([
1041
1447
  query('#explorer-split-panel')
1042
1448
  ], TheDoctor.prototype, "splitPanelExplorer", void 0);
1043
- __decorate([
1044
- query('#rolodex-split-panel')
1045
- ], TheDoctor.prototype, "splitPanelRolodex", void 0);
1046
1449
  __decorate([
1047
1450
  query('#inspector-split-panel')
1048
1451
  ], TheDoctor.prototype, "splitPanelInspector", void 0);
@@ -1070,6 +1473,33 @@ __decorate([
1070
1473
  __decorate([
1071
1474
  state()
1072
1475
  ], TheDoctor.prototype, "showDiagnosisButton", void 0);
1476
+ __decorate([
1477
+ state()
1478
+ ], TheDoctor.prototype, "workspaceReadOnly", void 0);
1479
+ __decorate([
1480
+ state()
1481
+ ], TheDoctor.prototype, "viewingHistoricalViolations", void 0);
1482
+ __decorate([
1483
+ state()
1484
+ ], TheDoctor.prototype, "toolsCompareLoading", void 0);
1485
+ __decorate([
1486
+ state()
1487
+ ], TheDoctor.prototype, "toolsEditorHasContent", void 0);
1488
+ __decorate([
1489
+ state()
1490
+ ], TheDoctor.prototype, "editorDirty", void 0);
1491
+ __decorate([
1492
+ state()
1493
+ ], TheDoctor.prototype, "bundleLoading", void 0);
1494
+ __decorate([
1495
+ state()
1496
+ ], TheDoctor.prototype, "isBundled", void 0);
1497
+ __decorate([
1498
+ state()
1499
+ ], TheDoctor.prototype, "rolodexDividerPosition", void 0);
1500
+ __decorate([
1501
+ state()
1502
+ ], TheDoctor.prototype, "currentViewName", void 0);
1073
1503
  TheDoctor = __decorate([
1074
1504
  customElement("pb33f-doctor")
1075
1505
  ], TheDoctor);