@rudderhq/server 0.6.1 → 0.6.2-canary.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 (298) hide show
  1. package/dist/bundled-plugins/plugin-linear/dist/worker.js +112 -4
  2. package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +2 -2
  3. package/dist/routes/access-onboarding.helpers.d.ts +0 -6
  4. package/dist/routes/access-onboarding.helpers.d.ts.map +1 -1
  5. package/dist/routes/access-onboarding.helpers.js +0 -7
  6. package/dist/routes/access-onboarding.helpers.js.map +1 -1
  7. package/dist/routes/access.d.ts +1 -1
  8. package/dist/routes/access.d.ts.map +1 -1
  9. package/dist/routes/access.js +2 -7
  10. package/dist/routes/access.js.map +1 -1
  11. package/dist/routes/agents.d.ts.map +1 -1
  12. package/dist/routes/agents.js +24 -49
  13. package/dist/routes/agents.js.map +1 -1
  14. package/dist/routes/agents.management-routes.d.ts.map +1 -1
  15. package/dist/routes/agents.management-routes.js +0 -1
  16. package/dist/routes/agents.management-routes.js.map +1 -1
  17. package/dist/routes/chats.d.ts.map +1 -1
  18. package/dist/routes/chats.js +77 -62
  19. package/dist/routes/chats.js.map +1 -1
  20. package/dist/routes/chats.preflight.d.ts +56 -0
  21. package/dist/routes/chats.preflight.d.ts.map +1 -0
  22. package/dist/routes/chats.preflight.js +72 -0
  23. package/dist/routes/chats.preflight.js.map +1 -0
  24. package/dist/routes/chats.runtime-controls.d.ts +62 -0
  25. package/dist/routes/chats.runtime-controls.d.ts.map +1 -0
  26. package/dist/routes/chats.runtime-controls.js +51 -0
  27. package/dist/routes/chats.runtime-controls.js.map +1 -0
  28. package/dist/routes/chats.stream-routes.d.ts.map +1 -1
  29. package/dist/routes/chats.stream-routes.js +22 -38
  30. package/dist/routes/chats.stream-routes.js.map +1 -1
  31. package/dist/routes/chats.stream-support.d.ts +6 -0
  32. package/dist/routes/chats.stream-support.d.ts.map +1 -1
  33. package/dist/routes/chats.stream-support.js.map +1 -1
  34. package/dist/routes/chats.user-state-routes.d.ts +3 -0
  35. package/dist/routes/chats.user-state-routes.d.ts.map +1 -0
  36. package/dist/routes/chats.user-state-routes.js +40 -0
  37. package/dist/routes/chats.user-state-routes.js.map +1 -0
  38. package/dist/routes/costs.d.ts.map +1 -1
  39. package/dist/routes/costs.js +11 -1
  40. package/dist/routes/costs.js.map +1 -1
  41. package/dist/routes/managed-mcp-agent-bindings.d.ts +1 -1
  42. package/dist/routes/managed-mcp-agent-bindings.d.ts.map +1 -1
  43. package/dist/routes/managed-mcp-agent-bindings.js +4 -0
  44. package/dist/routes/managed-mcp-agent-bindings.js.map +1 -1
  45. package/dist/routes/managed-mcp-connections.d.ts.map +1 -1
  46. package/dist/routes/managed-mcp-connections.js +33 -21
  47. package/dist/routes/managed-mcp-connections.js.map +1 -1
  48. package/dist/services/agent-run-context.d.ts.map +1 -1
  49. package/dist/services/agent-run-context.js +5 -1
  50. package/dist/services/agent-run-context.js.map +1 -1
  51. package/dist/services/agents.d.ts +5 -25
  52. package/dist/services/agents.d.ts.map +1 -1
  53. package/dist/services/agents.js +0 -72
  54. package/dist/services/agents.js.map +1 -1
  55. package/dist/services/approvals.d.ts.map +1 -1
  56. package/dist/services/approvals.js +0 -1
  57. package/dist/services/approvals.js.map +1 -1
  58. package/dist/services/chat-assistant.annotations.d.ts.map +1 -1
  59. package/dist/services/chat-assistant.annotations.js +3 -0
  60. package/dist/services/chat-assistant.annotations.js.map +1 -1
  61. package/dist/services/chat-assistant.d.ts +7 -0
  62. package/dist/services/chat-assistant.d.ts.map +1 -1
  63. package/dist/services/chat-assistant.helpers.d.ts +7 -0
  64. package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
  65. package/dist/services/chat-assistant.helpers.js +23 -3
  66. package/dist/services/chat-assistant.helpers.js.map +1 -1
  67. package/dist/services/chat-assistant.js +61 -4
  68. package/dist/services/chat-assistant.js.map +1 -1
  69. package/dist/services/chat-assistant.proposal-validation.d.ts +10 -0
  70. package/dist/services/chat-assistant.proposal-validation.d.ts.map +1 -0
  71. package/dist/services/chat-assistant.proposal-validation.js +65 -0
  72. package/dist/services/chat-assistant.proposal-validation.js.map +1 -0
  73. package/dist/services/chat-assistant.runtime-batch.d.ts +1 -1
  74. package/dist/services/chat-assistant.runtime-batch.d.ts.map +1 -1
  75. package/dist/services/chat-assistant.runtime-batch.js +6 -1
  76. package/dist/services/chat-assistant.runtime-batch.js.map +1 -1
  77. package/dist/services/chat-assistant.runtime-overrides.d.ts +6 -0
  78. package/dist/services/chat-assistant.runtime-overrides.d.ts.map +1 -0
  79. package/dist/services/chat-assistant.runtime-overrides.js +81 -0
  80. package/dist/services/chat-assistant.runtime-overrides.js.map +1 -0
  81. package/dist/services/chat-generation-protocol.d.ts.map +1 -1
  82. package/dist/services/chat-generation-protocol.js +2 -1
  83. package/dist/services/chat-generation-protocol.js.map +1 -1
  84. package/dist/services/chat-generation-protocol.test.js +89 -0
  85. package/dist/services/chat-generation-protocol.test.js.map +1 -1
  86. package/dist/services/chat-queued-message-materialization.d.ts +2 -0
  87. package/dist/services/chat-queued-message-materialization.d.ts.map +1 -1
  88. package/dist/services/chat-queued-message-materialization.js +12 -1
  89. package/dist/services/chat-queued-message-materialization.js.map +1 -1
  90. package/dist/services/chat-work-manifest.d.ts.map +1 -1
  91. package/dist/services/chat-work-manifest.js +189 -4
  92. package/dist/services/chat-work-manifest.js.map +1 -1
  93. package/dist/services/chats.create.d.ts +6 -0
  94. package/dist/services/chats.create.d.ts.map +1 -1
  95. package/dist/services/chats.create.js +10 -1
  96. package/dist/services/chats.create.js.map +1 -1
  97. package/dist/services/chats.d.ts +105 -10
  98. package/dist/services/chats.d.ts.map +1 -1
  99. package/dist/services/chats.helpers.d.ts +3 -1
  100. package/dist/services/chats.helpers.d.ts.map +1 -1
  101. package/dist/services/chats.helpers.js +4 -3
  102. package/dist/services/chats.helpers.js.map +1 -1
  103. package/dist/services/chats.js +21 -111
  104. package/dist/services/chats.js.map +1 -1
  105. package/dist/services/chats.queued-message-create.d.ts +20 -0
  106. package/dist/services/chats.queued-message-create.d.ts.map +1 -0
  107. package/dist/services/chats.queued-message-create.js +127 -0
  108. package/dist/services/chats.queued-message-create.js.map +1 -0
  109. package/dist/services/chats.runtime-controls.d.ts +53 -0
  110. package/dist/services/chats.runtime-controls.d.ts.map +1 -0
  111. package/dist/services/chats.runtime-controls.js +64 -0
  112. package/dist/services/chats.runtime-controls.js.map +1 -0
  113. package/dist/services/costs.d.ts +4 -2
  114. package/dist/services/costs.d.ts.map +1 -1
  115. package/dist/services/costs.js +59 -23
  116. package/dist/services/costs.js.map +1 -1
  117. package/dist/services/knowledge-portability/organization-portability.core.d.ts +0 -3
  118. package/dist/services/knowledge-portability/organization-portability.core.d.ts.map +1 -1
  119. package/dist/services/knowledge-portability/organization-portability.core.js +0 -44
  120. package/dist/services/knowledge-portability/organization-portability.core.js.map +1 -1
  121. package/dist/services/knowledge-portability/organization-portability.export.d.ts.map +1 -1
  122. package/dist/services/knowledge-portability/organization-portability.export.js +1 -20
  123. package/dist/services/knowledge-portability/organization-portability.export.js.map +1 -1
  124. package/dist/services/knowledge-portability/organization-portability.files.d.ts +1 -3
  125. package/dist/services/knowledge-portability/organization-portability.files.d.ts.map +1 -1
  126. package/dist/services/knowledge-portability/organization-portability.files.js +1 -26
  127. package/dist/services/knowledge-portability/organization-portability.files.js.map +1 -1
  128. package/dist/services/knowledge-portability/organization-portability.import.d.ts.map +1 -1
  129. package/dist/services/knowledge-portability/organization-portability.import.js +0 -19
  130. package/dist/services/knowledge-portability/organization-portability.import.js.map +1 -1
  131. package/dist/services/knowledge-portability/organization-portability.package.d.ts.map +1 -1
  132. package/dist/services/knowledge-portability/organization-portability.package.js +2 -1
  133. package/dist/services/knowledge-portability/organization-portability.package.js.map +1 -1
  134. package/dist/services/mcp/managed-bindings.d.ts +3 -1
  135. package/dist/services/mcp/managed-bindings.d.ts.map +1 -1
  136. package/dist/services/mcp/managed-bindings.js +254 -25
  137. package/dist/services/mcp/managed-bindings.js.map +1 -1
  138. package/dist/services/mcp/managed-connections.d.ts +4 -2
  139. package/dist/services/mcp/managed-connections.d.ts.map +1 -1
  140. package/dist/services/mcp/managed-connections.js +194 -22
  141. package/dist/services/mcp/managed-connections.js.map +1 -1
  142. package/dist/services/mcp/managed-runtime.d.ts +8 -3
  143. package/dist/services/mcp/managed-runtime.d.ts.map +1 -1
  144. package/dist/services/mcp/managed-runtime.js +175 -74
  145. package/dist/services/mcp/managed-runtime.js.map +1 -1
  146. package/dist/services/mcp/oauth-helpers.d.ts +53 -0
  147. package/dist/services/mcp/oauth-helpers.d.ts.map +1 -0
  148. package/dist/services/mcp/oauth-helpers.js +267 -0
  149. package/dist/services/mcp/oauth-helpers.js.map +1 -0
  150. package/dist/services/mcp/oauth.d.ts +13 -13
  151. package/dist/services/mcp/oauth.d.ts.map +1 -1
  152. package/dist/services/mcp/oauth.js +220 -307
  153. package/dist/services/mcp/oauth.js.map +1 -1
  154. package/dist/services/mcp/provider-registry.d.ts +1 -1
  155. package/dist/services/mcp/provider-registry.d.ts.map +1 -1
  156. package/dist/services/mcp/provider-registry.js +4 -6
  157. package/dist/services/mcp/provider-registry.js.map +1 -1
  158. package/dist/services/mcp/provider-registry.test.js +20 -8
  159. package/dist/services/mcp/provider-registry.test.js.map +1 -1
  160. package/dist/services/mcp/tool-discovery.d.ts +4 -0
  161. package/dist/services/mcp/tool-discovery.d.ts.map +1 -1
  162. package/dist/services/mcp/tool-discovery.js +29 -0
  163. package/dist/services/mcp/tool-discovery.js.map +1 -1
  164. package/dist/services/mcp/tool-discovery.test.js +34 -1
  165. package/dist/services/mcp/tool-discovery.test.js.map +1 -1
  166. package/dist/services/organization-export-readme.d.ts +0 -8
  167. package/dist/services/organization-export-readme.d.ts.map +1 -1
  168. package/dist/services/organization-export-readme.js +3 -43
  169. package/dist/services/organization-export-readme.js.map +1 -1
  170. package/dist/services/plugin-registry.d.ts +21 -21
  171. package/dist/services/postgres-json.d.ts +2 -0
  172. package/dist/services/postgres-json.d.ts.map +1 -0
  173. package/dist/services/postgres-json.js +33 -0
  174. package/dist/services/postgres-json.js.map +1 -0
  175. package/dist/services/postgres-json.test.d.ts +2 -0
  176. package/dist/services/postgres-json.test.d.ts.map +1 -0
  177. package/dist/services/postgres-json.test.js +25 -0
  178. package/dist/services/postgres-json.test.js.map +1 -0
  179. package/dist/services/run-events.d.ts.map +1 -1
  180. package/dist/services/run-events.js +6 -1
  181. package/dist/services/run-events.js.map +1 -1
  182. package/dist/services/runtime-kernel/heartbeat.core.d.ts +2 -2
  183. package/dist/services/runtime-kernel/heartbeat.d.ts +6 -3
  184. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  185. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
  186. package/dist/services/runtime-kernel/heartbeat.execute.js +2 -0
  187. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
  188. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  189. package/dist/services/runtime-kernel/heartbeat.misc.d.ts +3 -0
  190. package/dist/services/runtime-kernel/heartbeat.misc.d.ts.map +1 -1
  191. package/dist/services/runtime-kernel/heartbeat.misc.js +16 -4
  192. package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -1
  193. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +8 -9
  194. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -1
  195. package/dist/services/side-chats.d.ts +9 -0
  196. package/dist/services/side-chats.d.ts.map +1 -1
  197. package/dist/services/side-chats.js +18 -4
  198. package/dist/services/side-chats.js.map +1 -1
  199. package/package.json +14 -13
  200. package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +1 -1
  201. package/resources/bundled-skills/rudder-docs/references/agent-creation.md +1 -3
  202. package/resources/bundled-skills/rudder-docs/references/api-reference.md +3 -12
  203. package/resources/bundled-skills/rudder-docs/references/cli-reference.md +1 -1
  204. package/resources/bundled-skills/rudder-docs/references/operating-practices.md +2 -2
  205. package/skills/rudder-docs/evals/trigger-evals.json +1 -1
  206. package/skills/rudder-docs/references/agent-creation.md +1 -3
  207. package/skills/rudder-docs/references/api-reference.md +3 -12
  208. package/skills/rudder-docs/references/cli-reference.md +1 -1
  209. package/skills/rudder-docs/references/operating-practices.md +2 -2
  210. package/ui-dist/assets/{LibraryLiveSurface-C8ECMVFT.js → LibraryLiveSurface-CnZxAEHp.js} +1 -1
  211. package/ui-dist/assets/{abnfDiagram-VRR7QNED-BZHkBV8B.js → abnfDiagram-VRR7QNED-B208YmVN.js} +1 -1
  212. package/ui-dist/assets/{arc-DhnfBt9e.js → arc-_raxgt-X.js} +1 -1
  213. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BKHzH5qs.js → architectureDiagram-ZJ3FMSHR-y3eHT3Gk.js} +1 -1
  214. package/ui-dist/assets/{blockDiagram-677ZJIJ3--1g_r8lr.js → blockDiagram-677ZJIJ3-BT7LIBsS.js} +1 -1
  215. package/ui-dist/assets/{c4Diagram-LMCZKHZV-CnZQa_O3.js → c4Diagram-LMCZKHZV-w0r6PEZM.js} +1 -1
  216. package/ui-dist/assets/channel-NqK-mAXf.js +1 -0
  217. package/ui-dist/assets/{chunk-2Q5K7J3B-Cx1ETWPc.js → chunk-2Q5K7J3B-C3fuIoNI.js} +1 -1
  218. package/ui-dist/assets/{chunk-32BRIVSS-DwH6W0QD.js → chunk-32BRIVSS-DMb9Q2qh.js} +1 -1
  219. package/ui-dist/assets/{chunk-5VM5RSS4-DKjzajxX.js → chunk-5VM5RSS4-BqMkrxOv.js} +1 -1
  220. package/ui-dist/assets/{chunk-EX3LRPZG-DqPqTdiU.js → chunk-EX3LRPZG-D0uW7ZHY.js} +1 -1
  221. package/ui-dist/assets/{chunk-JWPE2WC7-BGZyFOPO.js → chunk-JWPE2WC7-_2Qhrxej.js} +1 -1
  222. package/ui-dist/assets/{chunk-MOJQB5TN-DWj-_Y-X.js → chunk-MOJQB5TN-Bx3r3XhP.js} +1 -1
  223. package/ui-dist/assets/{chunk-RYQCIY6F-Bp2OOi6q.js → chunk-RYQCIY6F-ryJ6ulQN.js} +1 -1
  224. package/ui-dist/assets/{chunk-V7JOEXUC-CxNGWU9-.js → chunk-V7JOEXUC-CpTtqgWd.js} +1 -1
  225. package/ui-dist/assets/{chunk-VR4S4FIN-rrwz8tGB.js → chunk-VR4S4FIN-C4qXyyxR.js} +1 -1
  226. package/ui-dist/assets/{chunk-XXDRQBXY-CuinF1_q.js → chunk-XXDRQBXY-CRPbq1d0.js} +1 -1
  227. package/ui-dist/assets/classDiagram-OUVF2IWQ-CRSBnWpX.js +1 -0
  228. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CRSBnWpX.js +1 -0
  229. package/ui-dist/assets/{cose-bilkent-JH36ORCC-BuP7WwKx.js → cose-bilkent-JH36ORCC-DClTXY3x.js} +1 -1
  230. package/ui-dist/assets/{cynefin-VYW2F7L2-Bdib4S1v.js → cynefin-VYW2F7L2-BqQy_6rq.js} +1 -1
  231. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-DuSsXSha.js → cynefinDiagram-TSTJHNR4-C_5uIlLF.js} +1 -1
  232. package/ui-dist/assets/{dagre-VKFMJZFB-Igot42Fe.js → dagre-VKFMJZFB-CvzApokN.js} +1 -1
  233. package/ui-dist/assets/{diagram-FQU43EPY-e8NWjImB.js → diagram-FQU43EPY-lsQoO58-.js} +1 -1
  234. package/ui-dist/assets/{diagram-G47NLZAW-BMQV4r9I.js → diagram-G47NLZAW-DJSeMnXd.js} +1 -1
  235. package/ui-dist/assets/{diagram-NH7WQ7WH-CPKOpfkM.js → diagram-NH7WQ7WH-Cfg6gXXN.js} +1 -1
  236. package/ui-dist/assets/{diagram-OA4YK3LP-C_fdlr3v.js → diagram-OA4YK3LP-DUS8ge-b.js} +1 -1
  237. package/ui-dist/assets/{diagram-WEI45ONY-Cu7lfxa2.js → diagram-WEI45ONY-Cp-l5tVI.js} +1 -1
  238. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-CN6-jt9d.js → ebnfDiagram-CCIWWBDH-BlRaFF_K.js} +1 -1
  239. package/ui-dist/assets/{erDiagram-Q63AITRT-D2z6C-we.js → erDiagram-Q63AITRT-BZwqidAe.js} +1 -1
  240. package/ui-dist/assets/{flowDiagram-23GEKE2U-CQlS5jRI.js → flowDiagram-23GEKE2U-BsfwK51N.js} +1 -1
  241. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-BuuHqPc8.js → ganttDiagram-NO4QXBWP-D7rDtE9-.js} +1 -1
  242. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-zmgrxxBX.js → gitGraphDiagram-IHSO6WYX-SI7fggdm.js} +1 -1
  243. package/ui-dist/assets/{graph-BJvZTk9a.js → graph-jB2l85dN.js} +1 -1
  244. package/ui-dist/assets/{index-D0VRM_9h.js → index-3UJgpZuo.js} +1 -1
  245. package/ui-dist/assets/{index-CLLpIiBV.js → index-BEtrDYuf.js} +1 -1
  246. package/ui-dist/assets/{index-HrYgeHT8.js → index-BXIRLNEz.js} +1 -1
  247. package/ui-dist/assets/{index-BkG5PUIN.js → index-BzZl24GX.js} +1 -1
  248. package/ui-dist/assets/{index-Cc-ewLqn.js → index-C2YHCs23.js} +1 -1
  249. package/ui-dist/assets/index-CFGCM2jL.css +1 -0
  250. package/ui-dist/assets/{index-DwCuHGmD.js → index-CMGFrbv8.js} +1 -1
  251. package/ui-dist/assets/{index-BUkyKZIq.js → index-CTAmMJYG.js} +1 -1
  252. package/ui-dist/assets/{index-DshvyEC6.js → index-CZoL7L4x.js} +1 -1
  253. package/ui-dist/assets/{index-DyfYslLG.js → index-C_i-wGZX.js} +1 -1
  254. package/ui-dist/assets/{index-B2ZiqwcG.js → index-CkjUvGSq.js} +1 -1
  255. package/ui-dist/assets/{index-8kxaiDPU.js → index-CuPTWos7.js} +1 -1
  256. package/ui-dist/assets/{index-B0Kc4Reu.js → index-D8o_GAok.js} +1 -1
  257. package/ui-dist/assets/{index-B-_jOiYM.js → index-DMFCHg9M.js} +1 -1
  258. package/ui-dist/assets/{index-Be6_jEMJ.js → index-DR1WCr91.js} +1 -1
  259. package/ui-dist/assets/{index-CagHzH_y.js → index-DV8jlH7u.js} +1 -1
  260. package/ui-dist/assets/{index-BYiU3CbU.js → index-DaC9LwaF.js} +1 -1
  261. package/ui-dist/assets/{index--DAOoBdz.js → index-DrRmkklS.js} +539 -541
  262. package/ui-dist/assets/{index-BoJ3Lpc0.js → index-gRrC-1Ro.js} +1 -1
  263. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-DcewEow-.js → infoDiagram-FWYZ7A6U-Dq_2Rg1m.js} +1 -1
  264. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-DDA-hStd.js → ishikawaDiagram-FXEZZL3T-uyywLhOx.js} +1 -1
  265. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-Di45AJjj.js → journeyDiagram-5HDEW3XC-BSdGAEe3.js} +1 -1
  266. package/ui-dist/assets/{kanban-definition-HUTT4EX6-BSCbVwWj.js → kanban-definition-HUTT4EX6-BeiytV3M.js} +1 -1
  267. package/ui-dist/assets/{layout-pITZAjqg.js → layout-kKtSz6Lw.js} +1 -1
  268. package/ui-dist/assets/{linear-Cu3rtYRt.js → linear-BNg7ltC5.js} +1 -1
  269. package/ui-dist/assets/{map-DYuY604Q.js → map-rBM_jVzN.js} +1 -1
  270. package/ui-dist/assets/{mermaid.core-DDOr0JGp.js → mermaid.core-B0lX_I1S.js} +4 -4
  271. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-D7XVVo_g.js → mindmap-definition-LN4V7U3C-6WrmM-3d.js} +1 -1
  272. package/ui-dist/assets/{pegDiagram-2B236MQR-BC1GaeL3.js → pegDiagram-2B236MQR-BJ0lR6j8.js} +1 -1
  273. package/ui-dist/assets/{pieDiagram-ENE6RG2P-dEClB4rW.js → pieDiagram-ENE6RG2P-Ch-KedEq.js} +1 -1
  274. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-DYEEk2Me.js → quadrantDiagram-ABIIQ3AL-BLnrHtbN.js} +1 -1
  275. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-DNsj-q9g.js → railroadDiagram-RFXS5EU6-u0KJZK8C.js} +1 -1
  276. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-BmkJ6fzV.js → requirementDiagram-TGXJPOKE-C1MzHKp-.js} +1 -1
  277. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-BsOkjZzG.js → sankeyDiagram-HTMAVEWB-UIufCGDd.js} +1 -1
  278. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-Bi3Z-JjU.js → sequenceDiagram-DBY2YBRQ-Cv8Fb7zZ.js} +1 -1
  279. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-BL5Nebl1.js → sizeCapture-X5ZJPWSS-9U-7wwO3.js} +1 -1
  280. package/ui-dist/assets/{stateDiagram-2N3HPSRC-Cq_vKfyy.js → stateDiagram-2N3HPSRC-BEOjkPpv.js} +1 -1
  281. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-BBO_VsOI.js +1 -0
  282. package/ui-dist/assets/{swimlanes-5IMT3BWC-2J5KFUSB.js → swimlanes-5IMT3BWC-BEwruQnI.js} +2 -2
  283. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-DjAl9cJv.js +8 -0
  284. package/ui-dist/assets/{timeline-definition-FHXFAJF6-D1ICgYtA.js → timeline-definition-FHXFAJF6-CfWC6EYo.js} +1 -1
  285. package/ui-dist/assets/{vennDiagram-L72KCM5P-D0Pe93oZ.js → vennDiagram-L72KCM5P-B2BPrj_n.js} +1 -1
  286. package/ui-dist/assets/{wardleyDiagram-EHGQE667-B7cKDg_l.js → wardleyDiagram-EHGQE667-Cx2wmgRm.js} +1 -1
  287. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-CpD2ZP52.js → xychartDiagram-FW5EYKEG-Due4dZhR.js} +1 -1
  288. package/ui-dist/index.html +2 -2
  289. package/dist/routes/org-chart-svg.d.ts +0 -25
  290. package/dist/routes/org-chart-svg.d.ts.map +0 -1
  291. package/dist/routes/org-chart-svg.js +0 -652
  292. package/dist/routes/org-chart-svg.js.map +0 -1
  293. package/ui-dist/assets/channel-DAg8UTDO.js +0 -1
  294. package/ui-dist/assets/classDiagram-OUVF2IWQ-BDDhIQB_.js +0 -1
  295. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-BDDhIQB_.js +0 -1
  296. package/ui-dist/assets/index-BnZ6czsu.css +0 -1
  297. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-BUOXYIgQ.js +0 -1
  298. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BCURODlK.js +0 -8
@@ -1,652 +0,0 @@
1
- /**
2
- * Server-side SVG renderer for Rudder org charts.
3
- * Supports 5 visual styles: monochrome, nebula, circuit, warmth, schematic.
4
- * Pure SVG output — no browser/Playwright needed. PNG via sharp.
5
- */
6
- import { ORG_CHART_LOGO_DATA_URI } from "./org-chart-logo.js";
7
- export const ORG_CHART_STYLES = ["monochrome", "nebula", "circuit", "warmth", "schematic"];
8
- // ── Role config with Twemoji SVG inlines (viewBox 0 0 36 36) ─────
9
- //
10
- // Each `emojiSvg` contains the inner SVG paths from Twemoji (CC-BY 4.0).
11
- // These render as colorful emoji-style icons inside the avatar circle,
12
- // without needing a browser or emoji font.
13
- const ROLE_ICONS = {
14
- ceo: {
15
- bg: "#fef3c7", roleLabel: "Chief Executive", accentColor: "#f0883e", iconColor: "#92400e",
16
- iconPath: "M8 1l2.2 4.5L15 6.2l-3.5 3.4.8 4.9L8 12.2 3.7 14.5l.8-4.9L1 6.2l4.8-.7z",
17
- // 👑 Crown
18
- emojiSvg: `<path fill="#F4900C" d="M14.174 17.075L6.75 7.594l-3.722 9.481z"/><path fill="#F4900C" d="M17.938 5.534l-6.563 12.389H24.5z"/><path fill="#F4900C" d="M21.826 17.075l7.424-9.481 3.722 9.481z"/><path fill="#FFCC4D" d="M28.669 15.19L23.887 3.523l-5.88 11.668-.007.003-.007-.004-5.88-11.668L7.331 15.19C4.197 10.833 1.28 8.042 1.28 8.042S3 20.75 3 33h30c0-12.25 1.72-24.958 1.72-24.958s-2.917 2.791-6.051 7.148z"/><circle fill="#5C913B" cx="17.957" cy="22" r="3.688"/><circle fill="#981CEB" cx="26.463" cy="22" r="2.412"/><circle fill="#DD2E44" cx="32.852" cy="22" r="1.986"/><circle fill="#981CEB" cx="9.45" cy="22" r="2.412"/><circle fill="#DD2E44" cx="3.061" cy="22" r="1.986"/><path fill="#FFAC33" d="M33 34H3c-.552 0-1-.447-1-1s.448-1 1-1h30c.553 0 1 .447 1 1s-.447 1-1 1zm0-3.486H3c-.552 0-1-.447-1-1s.448-1 1-1h30c.553 0 1 .447 1 1s-.447 1-1 1z"/><circle fill="#FFCC4D" cx="1.447" cy="8.042" r="1.407"/><circle fill="#F4900C" cx="6.75" cy="7.594" r="1.192"/><circle fill="#FFCC4D" cx="12.113" cy="3.523" r="1.784"/><circle fill="#FFCC4D" cx="34.553" cy="8.042" r="1.407"/><circle fill="#F4900C" cx="29.25" cy="7.594" r="1.192"/><circle fill="#FFCC4D" cx="23.887" cy="3.523" r="1.784"/><circle fill="#F4900C" cx="17.938" cy="5.534" r="1.784"/>`,
19
- },
20
- cto: {
21
- bg: "#dbeafe", roleLabel: "Technology", accentColor: "#58a6ff", iconColor: "#1e40af",
22
- iconPath: "M2 3l5 5-5 5M9 13h5",
23
- // 💻 Laptop
24
- emojiSvg: `<path fill="#CCD6DD" d="M34 29.096c-.417-.963-.896-2.008-2-2.008h-1c1.104 0 2-.899 2-2.008V8.008C33 6.899 32.104 6 31 6H5c-1.104 0-2 .899-2 2.008V25.08c0 1.109.896 2.008 2 2.008H4c-1.104 0-1.667 1.004-2 2.008l-2 4.895C0 35.101.896 36 2 36h32c1.104 0 2-.899 2-2.008l-2-4.896z"/><path fill="#9AAAB4" d="M.008 34.075l.006.057.17.692C.5 35.516 1.192 36 2 36h32c1.076 0 1.947-.855 1.992-1.925H.008z"/><path fill="#5DADEC" d="M31 24.075c0 .555-.447 1.004-1 1.004H6c-.552 0-1-.449-1-1.004V9.013c0-.555.448-1.004 1-1.004h24c.553 0 1 .45 1 1.004v15.062z"/><path fill="#AEBBC1" d="M32.906 31.042l-.76-2.175c-.239-.46-.635-.837-1.188-.837H5.11c-.552 0-.906.408-1.156 1.036l-.688 1.977c-.219.596.448 1.004 1 1.004h7.578s.937-.047 1.103-.608c.192-.648.415-1.624.463-1.796.074-.264.388-.531.856-.531h8.578c.5 0 .746.253.811.566.042.204.312 1.141.438 1.782.111.571 1.221.586 1.221.586h6.594c.551 0 1.217-.471.998-1.004z"/><path fill="#9AAAB4" d="M22.375 33.113h-7.781c-.375 0-.538-.343-.484-.675.054-.331.359-1.793.383-1.963.023-.171.274-.375.524-.375h7.015c.297 0 .49.163.55.489.059.327.302 1.641.321 1.941.019.301-.169.583-.528.583z"/>`,
25
- },
26
- cmo: {
27
- bg: "#dcfce7", roleLabel: "Marketing", accentColor: "#3fb950", iconColor: "#166534",
28
- iconPath: "M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zM1 8h14M8 1c-2 2-3 4.5-3 7s1 5 3 7c2-2 3-4.5 3-7s-1-5-3-7z",
29
- // 🌐 Globe with meridians
30
- emojiSvg: `<path fill="#3B88C3" d="M18 0C8.059 0 0 8.059 0 18s8.059 18 18 18 18-8.059 18-18S27.941 0 18 0zM2.05 19h3.983c.092 2.506.522 4.871 1.229 7H4.158c-1.207-2.083-1.95-4.459-2.108-7zM19 8V2.081c2.747.436 5.162 2.655 6.799 5.919H19zm7.651 2c.754 2.083 1.219 4.46 1.317 7H19v-7h7.651zM17 2.081V8h-6.799C11.837 4.736 14.253 2.517 17 2.081zM17 10v7H8.032c.098-2.54.563-4.917 1.317-7H17zM6.034 17H2.05c.158-2.54.901-4.917 2.107-7h3.104c-.705 2.129-1.135 4.495-1.227 7zm1.998 2H17v7H9.349c-.754-2.083-1.219-4.459-1.317-7zM17 28v5.919c-2.747-.437-5.163-2.655-6.799-5.919H17zm2 5.919V28h6.8c-1.637 3.264-4.053 5.482-6.8 5.919zM19 26v-7h8.969c-.099 2.541-.563 4.917-1.317 7H19zm10.967-7h3.982c-.157 2.541-.9 4.917-2.107 7h-3.104c.706-2.129 1.136-4.494 1.229-7zm0-2c-.093-2.505-.523-4.871-1.229-7h3.104c1.207 2.083 1.95 4.46 2.107 7h-3.982zm.512-9h-2.503c-.717-1.604-1.606-3.015-2.619-4.199C27.346 4.833 29.089 6.267 30.479 8zM10.643 3.801C9.629 4.985 8.74 6.396 8.023 8H5.521c1.39-1.733 3.133-3.166 5.122-4.199zM5.521 28h2.503c.716 1.604 1.605 3.015 2.619 4.198C8.654 31.166 6.911 29.733 5.521 28zm19.836 4.198c1.014-1.184 1.902-2.594 2.619-4.198h2.503c-1.39 1.733-3.133 3.166-5.122 4.198z"/>`,
31
- },
32
- cfo: {
33
- bg: "#fef3c7", roleLabel: "Finance", accentColor: "#f0883e", iconColor: "#92400e",
34
- iconPath: "M8 1v14M5 4.5C5 3.1 6.3 2 8 2s3 1.1 3 2.5S9.7 7 8 7 5 8.1 5 9.5 6.3 12 8 12s3-1.1 3-2.5",
35
- // 📊 Bar chart
36
- emojiSvg: `<path fill="#CCD6DD" d="M31 2H5C3.343 2 2 3.343 2 5v26c0 1.657 1.343 3 3 3h26c1.657 0 3-1.343 3-3V5c0-1.657-1.343-3-3-3z"/><path fill="#E1E8ED" d="M31 1H5C2.791 1 1 2.791 1 5v26c0 2.209 1.791 4 4 4h26c2.209 0 4-1.791 4-4V5c0-2.209-1.791-4-4-4zm0 2c1.103 0 2 .897 2 2v4h-6V3h4zm-4 16h6v6h-6v-6zm0-2v-6h6v6h-6zM25 3v6h-6V3h6zm-6 8h6v6h-6v-6zm0 8h6v6h-6v-6zM17 3v6h-6V3h6zm-6 8h6v6h-6v-6zm0 8h6v6h-6v-6zM3 5c0-1.103.897-2 2-2h4v6H3V5zm0 6h6v6H3v-6zm0 8h6v6H3v-6zm2 14c-1.103 0-2-.897-2-2v-4h6v6H5zm6 0v-6h6v6h-6zm8 0v-6h6v6h-6zm12 0h-4v-6h6v4c0 1.103-.897 2-2 2z"/><path fill="#5C913B" d="M13 33H7V16c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v17z"/><path fill="#3B94D9" d="M29 33h-6V9c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v24z"/><path fill="#DD2E44" d="M21 33h-6V23c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v10z"/>`,
37
- },
38
- coo: {
39
- bg: "#e0f2fe", roleLabel: "Operations", accentColor: "#58a6ff", iconColor: "#075985",
40
- iconPath: "M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5z",
41
- // ⚙️ Gear
42
- emojiSvg: `<path fill="#66757F" d="M34 15h-3.362c-.324-1.369-.864-2.651-1.582-3.814l2.379-2.379c.781-.781.781-2.048 0-2.829l-1.414-1.414c-.781-.781-2.047-.781-2.828 0l-2.379 2.379C23.65 6.225 22.369 5.686 21 5.362V2c0-1.104-.896-2-2-2h-2c-1.104 0-2 .896-2 2v3.362c-1.369.324-2.651.864-3.814 1.582L8.808 4.565c-.781-.781-2.048-.781-2.828 0L4.565 5.979c-.781.781-.781 2.048-.001 2.829l2.379 2.379C6.225 12.35 5.686 13.632 5.362 15H2c-1.104 0-2 .896-2 2v2c0 1.104.896 2 2 2h3.362c.324 1.368.864 2.65 1.582 3.813l-2.379 2.379c-.78.78-.78 2.048.001 2.829l1.414 1.414c.78.78 2.047.78 2.828 0l2.379-2.379c1.163.719 2.445 1.258 3.814 1.582V34c0 1.104.896 2 2 2h2c1.104 0 2-.896 2-2v-3.362c1.368-.324 2.65-.864 3.813-1.582l2.379 2.379c.781.781 2.047.781 2.828 0l1.414-1.414c.781-.781.781-2.048 0-2.829l-2.379-2.379c.719-1.163 1.258-2.445 1.582-3.814H34c1.104 0 2-.896 2-2v-2C36 15.896 35.104 15 34 15zM18 26c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8z"/>`,
43
- },
44
- engineer: {
45
- bg: "#f3e8ff", roleLabel: "Engineering", accentColor: "#bc8cff", iconColor: "#6b21a8",
46
- iconPath: "M5 3L1 8l4 5M11 3l4 5-4 5",
47
- // ⌨️ Keyboard
48
- emojiSvg: `<path fill="#99AAB5" d="M36 28c0 1.104-.896 2-2 2H2c-1.104 0-2-.896-2-2V12c0-1.104.896-2 2-2h32c1.104 0 2 .896 2 2v16z"/><path d="M5.5 19c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm-26 4c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.448 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.552 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zm4 0c0 .553-.447 1-1 1h-1c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h1c.553 0 1 .447 1 1v1zM10 27c0 .553-.448 1-1 1H7c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h2c.552 0 1 .447 1 1v1zm20 0c0 .553-.447 1-1 1h-2c-.553 0-1-.447-1-1v-1c0-.553.447-1 1-1h2c.553 0 1 .447 1 1v1zm-5 0c0 .553-.447 1-1 1H12c-.552 0-1-.447-1-1v-1c0-.553.448-1 1-1h12c.553 0 1 .447 1 1v1zM5.5 13.083c0 .552-.448 1-1 1h-1c-.552 0-1-.448-1-1s.448-1 1-1h1c.552 0 1 .448 1 1zm4 0c0 .552-.448 1-1 1h-1c-.552 0-1-.448-1-1s.448-1 1-1h1c.552 0 1 .448 1 1zm4 0c0 .552-.448 1-1 1h-1c-.552 0-1-.448-1-1s.448-1 1-1h1c.552 0 1 .448 1 1zm4 0c0 .552-.448 1-1 1h-1c-.552 0-1-.448-1-1s.448-1 1-1h1c.552 0 1 .448 1 1zm4 0c0 .552-.447 1-1 1h-1c-.553 0-1-.448-1-1s.447-1 1-1h1c.553 0 1 .448 1 1zm4 0c0 .552-.447 1-1 1h-1c-.553 0-1-.448-1-1s.447-1 1-1h1c.553 0 1 .448 1 1zm4 0c0 .552-.447 1-1 1h-1c-.553 0-1-.448-1-1s.447-1 1-1h1c.553 0 1 .448 1 1zm4 0c0 .552-.447 1-1 1h-1c-.553 0-1-.448-1-1s.447-1 1-1h1c.553 0 1 .448 1 1z" fill="#292F33"/>`,
49
- },
50
- quality: {
51
- bg: "#ffe4e6", roleLabel: "Quality", accentColor: "#f778ba", iconColor: "#9f1239",
52
- iconPath: "M4 8l3 3 5-6M8 1L2 4v4c0 3.5 2.6 6.8 6 8 3.4-1.2 6-4.5 6-8V4z",
53
- // 🔬 Microscope
54
- emojiSvg: `<g fill="#66757F"><path d="M19.78 21.345l-6.341-6.342-.389 4.38 2.35 2.351z"/><path d="M15.4 22.233c-.132 0-.259-.053-.354-.146l-2.351-2.351c-.104-.104-.158-.25-.145-.397l.389-4.38c.017-.193.145-.359.327-.425.182-.067.388-.021.524.116l6.341 6.342c.138.138.183.342.116.524s-.232.31-.426.327l-4.379.389-.042.001zm-1.832-3.039l2.021 2.021 3.081-.273-4.828-4.828-.274 3.08z"/></g><path fill="#8899A6" d="M31 32h-3c0-3.314-2.63-6-5.875-6-3.244 0-5.875 2.686-5.875 6H8.73c0-1.104-.895-2-2-2-1.104 0-2 .896-2 2-1.104 0-2 .896-2 2s.896 2 2 2H31c1.104 0 2-.896 2-2s-.896-2-2-2z"/><path fill="#8899A6" d="M20 10v4c3.866 0 7 3.134 7 7s-3.134 7-7 7h-8.485c2.018 2.443 5.069 4 8.485 4 6.075 0 11-4.925 11-11s-4.925-11-11-11z"/><path fill="#67757F" d="M16.414 30.414c-.781.781-2.047.781-2.828 0l-9.899-9.9c-.781-.781-.781-2.047 0-2.828.781-.781 2.047-.781 2.829 0l9.899 9.9c.78.781.78 2.047-.001 2.828zm-7.225-1.786c.547-.077 1.052.304 1.129.851.077.547-.305 1.053-.851 1.129l-5.942.834c-.547.077-1.052-.305-1.129-.851-.077-.547.305-1.053.852-1.13l5.941-.833z"/><path fill="#66757F" d="M27.341 2.98l4.461 4.461-3.806 3.807-4.461-4.461z"/><path fill="#AAB8C2" d="M34.037 7.083c-.827.827-2.17.827-2.997 0l-3.339-3.34c-.827-.826-.827-2.169 0-2.996.827-.826 2.17-.826 2.995 0l3.342 3.34c.826.827.826 2.168-.001 2.996zm-14.56 15.026l-6.802-6.803c-.389-.389-.389-1.025 0-1.414l9.858-9.858c.389-.389 1.025-.389 1.414 0l6.801 6.803c.389.389.389 1.025 0 1.414l-9.858 9.858c-.388.389-1.024.389-1.413 0z"/><path fill="#E1E8ED" d="M13.766 12.8l1.638-1.637 8.216 8.216-1.638 1.637z"/>`,
55
- },
56
- design: {
57
- bg: "#fce7f3", roleLabel: "Design", accentColor: "#79c0ff", iconColor: "#9d174d",
58
- iconPath: "M12 2l2 2-9 9H3v-2zM9.5 4.5l2 2",
59
- // 🪄 Magic wand
60
- emojiSvg: `<path fill="#292F33" d="M3.651 29.852L29.926 3.576c.391-.391 2.888 2.107 2.497 2.497L6.148 32.349c-.39.391-2.888-2.107-2.497-2.497z"/><path fill="#66757F" d="M30.442 4.051L4.146 30.347l.883.883L31.325 4.934z"/><path fill="#E1E8ED" d="M34.546 2.537l-.412-.412-.671-.671c-.075-.075-.165-.123-.255-.169-.376-.194-.844-.146-1.159.169l-2.102 2.102.495.495.883.883 1.119 1.119 2.102-2.102c.391-.391.391-1.024 0-1.414zM5.029 31.23l-.883-.883-.495-.495-2.209 2.208c-.315.315-.363.783-.169 1.159.046.09.094.18.169.255l.671.671.412.412c.391.391 1.024.391 1.414 0l2.208-2.208-1.118-1.119z"/><path fill="#F5F8FA" d="M31.325 4.934l2.809-2.809-.671-.671c-.075-.075-.165-.123-.255-.169l-2.767 2.767.884.882zM4.146 30.347L1.273 33.22c.046.09.094.18.169.255l.671.671 2.916-2.916-.883-.883z"/><path d="M28.897 14.913l1.542-.571.6-2.2c.079-.29.343-.491.644-.491.3 0 .564.201.643.491l.6 2.2 1.542.571c.262.096.435.346.435.625s-.173.529-.435.625l-1.534.568-.605 2.415c-.074.296-.341.505-.646.505-.306 0-.573-.209-.647-.505l-.605-2.415-1.534-.568c-.262-.096-.435-.346-.435-.625 0-.278.173-.528.435-.625M11.961 5.285l2.61-.966.966-2.61c.16-.433.573-.72 1.035-.72.461 0 .874.287 1.035.72l.966 2.61 2.609.966c.434.161.721.573.721 1.035 0 .462-.287.874-.721 1.035l-2.609.966-.966 2.61c-.161.433-.574.72-1.035.72-.462 0-.875-.287-1.035-.72l-.966-2.61-2.61-.966c-.433-.161-.72-.573-.72-1.035.001-.462.288-.874.72-1.035M24.13 20.772l1.383-.512.512-1.382c.085-.229.304-.381.548-.381.244 0 .463.152.548.381l.512 1.382 1.382.512c.23.085.382.304.382.548 0 .245-.152.463-.382.548l-1.382.512-.512 1.382c-.085.229-.304.381-.548.381-.245 0-.463-.152-.548-.381l-.512-1.382-1.383-.512c-.229-.085-.381-.304-.381-.548 0-.245.152-.463.381-.548" fill="#FFAC33"/>`,
61
- },
62
- finance: {
63
- bg: "#fef3c7", roleLabel: "Finance", accentColor: "#f0883e", iconColor: "#92400e",
64
- iconPath: "M8 1v14M5 4.5C5 3.1 6.3 2 8 2s3 1.1 3 2.5S9.7 7 8 7 5 8.1 5 9.5 6.3 12 8 12s3-1.1 3-2.5",
65
- // 📊 Bar chart (same as CFO)
66
- emojiSvg: `<path fill="#CCD6DD" d="M31 2H5C3.343 2 2 3.343 2 5v26c0 1.657 1.343 3 3 3h26c1.657 0 3-1.343 3-3V5c0-1.657-1.343-3-3-3z"/><path fill="#E1E8ED" d="M31 1H5C2.791 1 1 2.791 1 5v26c0 2.209 1.791 4 4 4h26c2.209 0 4-1.791 4-4V5c0-2.209-1.791-4-4-4zm0 2c1.103 0 2 .897 2 2v4h-6V3h4zm-4 16h6v6h-6v-6zm0-2v-6h6v6h-6zM25 3v6h-6V3h6zm-6 8h6v6h-6v-6zm0 8h6v6h-6v-6zM17 3v6h-6V3h6zm-6 8h6v6h-6v-6zm0 8h6v6h-6v-6zM3 5c0-1.103.897-2 2-2h4v6H3V5zm0 6h6v6H3v-6zm0 8h6v6H3v-6zm2 14c-1.103 0-2-.897-2-2v-4h6v6H5zm6 0v-6h6v6h-6zm8 0v-6h6v6h-6zm12 0h-4v-6h6v4c0 1.103-.897 2-2 2z"/><path fill="#5C913B" d="M13 33H7V16c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v17z"/><path fill="#3B94D9" d="M29 33h-6V9c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v24z"/><path fill="#DD2E44" d="M21 33h-6V23c0-1.104.896-2 2-2h2c1.104 0 2 .896 2 2v10z"/>`,
67
- },
68
- operations: {
69
- bg: "#e0f2fe", roleLabel: "Operations", accentColor: "#58a6ff", iconColor: "#075985",
70
- iconPath: "M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5z",
71
- // ⚙️ Gear (same as COO)
72
- emojiSvg: `<path fill="#66757F" d="M34 15h-3.362c-.324-1.369-.864-2.651-1.582-3.814l2.379-2.379c.781-.781.781-2.048 0-2.829l-1.414-1.414c-.781-.781-2.047-.781-2.828 0l-2.379 2.379C23.65 6.225 22.369 5.686 21 5.362V2c0-1.104-.896-2-2-2h-2c-1.104 0-2 .896-2 2v3.362c-1.369.324-2.651.864-3.814 1.582L8.808 4.565c-.781-.781-2.048-.781-2.828 0L4.565 5.979c-.781.781-.781 2.048-.001 2.829l2.379 2.379C6.225 12.35 5.686 13.632 5.362 15H2c-1.104 0-2 .896-2 2v2c0 1.104.896 2 2 2h3.362c.324 1.368.864 2.65 1.582 3.813l-2.379 2.379c-.78.78-.78 2.048.001 2.829l1.414 1.414c.78.78 2.047.78 2.828 0l2.379-2.379c1.163.719 2.445 1.258 3.814 1.582V34c0 1.104.896 2 2 2h2c1.104 0 2-.896 2-2v-3.362c1.368-.324 2.65-.864 3.813-1.582l2.379 2.379c.781.781 2.047.781 2.828 0l1.414-1.414c.781-.781.781-2.048 0-2.829l-2.379-2.379c.719-1.163 1.258-2.445 1.582-3.814H34c1.104 0 2-.896 2-2v-2C36 15.896 35.104 15 34 15zM18 26c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8z"/>`,
73
- },
74
- default: {
75
- bg: "#f3e8ff", roleLabel: "Agent", accentColor: "#bc8cff", iconColor: "#6b21a8",
76
- iconPath: "M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM2 14c0-3.3 2.7-4 6-4s6 .7 6 4",
77
- // 👤 Person silhouette
78
- emojiSvg: `<path fill="#269" d="M24 26.799v-2.566c2-1.348 4.08-3.779 4.703-6.896.186.103.206.17.413.17.991 0 1.709-1.287 1.709-2.873 0-1.562-.823-2.827-1.794-2.865.187-.674.293-1.577.293-2.735C29.324 5.168 26 .527 18.541.527c-6.629 0-10.777 4.641-10.777 8.507 0 1.123.069 2.043.188 2.755-.911.137-1.629 1.352-1.629 2.845 0 1.587.804 2.873 1.796 2.873.206 0 .025-.067.209-.17C8.952 20.453 11 22.885 13 24.232v2.414c-5 .645-12 3.437-12 6.23v1.061C1 35 2.076 35 3.137 35h29.725C33.924 35 35 35 35 33.938v-1.061c0-2.615-6-5.225-11-6.078z"/>`,
79
- },
80
- };
81
- function guessRoleTag(node) {
82
- const name = node.name.toLowerCase();
83
- const role = node.role.toLowerCase();
84
- if (name === "ceo" || role.includes("chief executive"))
85
- return "ceo";
86
- if (name === "cto" || role.includes("chief technology") || role.includes("technology"))
87
- return "cto";
88
- if (name === "cmo" || role.includes("chief marketing") || role.includes("marketing"))
89
- return "cmo";
90
- if (name === "cfo" || role.includes("chief financial"))
91
- return "cfo";
92
- if (name === "coo" || role.includes("chief operating"))
93
- return "coo";
94
- if (role.includes("engineer") || role.includes("eng"))
95
- return "engineer";
96
- if (role.includes("quality") || role.includes("qa"))
97
- return "quality";
98
- if (role.includes("design"))
99
- return "design";
100
- if (role.includes("finance"))
101
- return "finance";
102
- if (role.includes("operations") || role.includes("ops"))
103
- return "operations";
104
- return "default";
105
- }
106
- function getRoleInfo(node) {
107
- const tag = guessRoleTag(node);
108
- return { tag, ...(ROLE_ICONS[tag] || ROLE_ICONS.default) };
109
- }
110
- // ── Style themes ─────────────────────────────────────────────────
111
- const THEMES = {
112
- // 01 — Monochrome (Vercel-inspired, dark minimal)
113
- monochrome: {
114
- bgColor: "#18181b",
115
- cardBg: "#18181b",
116
- cardBorder: "#27272a",
117
- cardRadius: 6,
118
- cardShadow: null,
119
- lineColor: "#3f3f46",
120
- lineWidth: 1.5,
121
- nameColor: "#fafafa",
122
- roleColor: "#71717a",
123
- font: "'Inter', system-ui, sans-serif",
124
- watermarkColor: "rgba(255,255,255,0.25)",
125
- defs: () => "",
126
- bgExtras: () => "",
127
- renderCard: null,
128
- cardAccent: null,
129
- },
130
- // 02 — Nebula (glassmorphism on cosmic gradient)
131
- nebula: {
132
- bgColor: "#0f0c29",
133
- cardBg: "rgba(255,255,255,0.07)",
134
- cardBorder: "rgba(255,255,255,0.12)",
135
- cardRadius: 6,
136
- cardShadow: null,
137
- lineColor: "rgba(255,255,255,0.25)",
138
- lineWidth: 1.5,
139
- nameColor: "#ffffff",
140
- roleColor: "rgba(255,255,255,0.45)",
141
- font: "'Inter', system-ui, sans-serif",
142
- watermarkColor: "rgba(255,255,255,0.2)",
143
- defs: (_w, _h) => `
144
- <linearGradient id="nebula-bg" x1="0" y1="0" x2="1" y2="1">
145
- <stop offset="0%" stop-color="#0f0c29"/>
146
- <stop offset="50%" stop-color="#302b63"/>
147
- <stop offset="100%" stop-color="#24243e"/>
148
- </linearGradient>
149
- <radialGradient id="nebula-glow1" cx="25%" cy="30%" r="40%">
150
- <stop offset="0%" stop-color="rgba(99,102,241,0.12)"/>
151
- <stop offset="100%" stop-color="transparent"/>
152
- </radialGradient>
153
- <radialGradient id="nebula-glow2" cx="75%" cy="65%" r="35%">
154
- <stop offset="0%" stop-color="rgba(168,85,247,0.08)"/>
155
- <stop offset="100%" stop-color="transparent"/>
156
- </radialGradient>`,
157
- bgExtras: (w, h) => `
158
- <rect width="${w}" height="${h}" fill="url(#nebula-bg)" rx="6"/>
159
- <rect width="${w}" height="${h}" fill="url(#nebula-glow1)"/>
160
- <rect width="${w}" height="${h}" fill="url(#nebula-glow2)"/>`,
161
- renderCard: null,
162
- cardAccent: null,
163
- },
164
- // 03 — Circuit (Linear/Raycast — indigo traces, amethyst CEO)
165
- circuit: {
166
- bgColor: "#0c0c0e",
167
- cardBg: "rgba(99,102,241,0.04)",
168
- cardBorder: "rgba(99,102,241,0.18)",
169
- cardRadius: 5,
170
- cardShadow: null,
171
- lineColor: "rgba(99,102,241,0.35)",
172
- lineWidth: 1.5,
173
- nameColor: "#e4e4e7",
174
- roleColor: "#6366f1",
175
- font: "'Inter', system-ui, sans-serif",
176
- watermarkColor: "rgba(99,102,241,0.3)",
177
- defs: () => "",
178
- bgExtras: () => "",
179
- renderCard: (ln, theme) => {
180
- const { tag, roleLabel, emojiSvg } = getRoleInfo(ln.node);
181
- const cx = ln.x + ln.width / 2;
182
- const isCeo = tag === "ceo";
183
- const borderColor = isCeo ? "rgba(168,85,247,0.35)" : theme.cardBorder;
184
- const bgColor = isCeo ? "rgba(168,85,247,0.06)" : theme.cardBg;
185
- const avatarCY = ln.y + 27;
186
- const nameY = ln.y + 66;
187
- const roleY = ln.y + 82;
188
- return `<g>
189
- <rect x="${ln.x}" y="${ln.y}" width="${ln.width}" height="${ln.height}" rx="${theme.cardRadius}" fill="${bgColor}" stroke="${borderColor}" stroke-width="1"/>
190
- ${renderEmojiAvatar(cx, avatarCY, 17, "rgba(99,102,241,0.08)", emojiSvg, "rgba(99,102,241,0.15)")}
191
- <text x="${cx}" y="${nameY}" text-anchor="middle" font-family="${theme.font}" font-size="13" font-weight="600" fill="${theme.nameColor}" letter-spacing="-0.005em">${escapeXml(ln.node.name)}</text>
192
- <text x="${cx}" y="${roleY}" text-anchor="middle" font-family="${theme.font}" font-size="10" font-weight="500" fill="${theme.roleColor}" letter-spacing="0.07em">${escapeXml(roleLabel).toUpperCase()}</text>
193
- </g>`;
194
- },
195
- cardAccent: null,
196
- },
197
- // 04 — Warmth (Airbnb — light, colored avatars, soft shadows)
198
- warmth: {
199
- bgColor: "#fafaf9",
200
- cardBg: "#ffffff",
201
- cardBorder: "#e7e5e4",
202
- cardRadius: 6,
203
- cardShadow: "rgba(0,0,0,0.05)",
204
- lineColor: "#d6d3d1",
205
- lineWidth: 2,
206
- nameColor: "#1c1917",
207
- roleColor: "#78716c",
208
- font: "'Inter', -apple-system, BlinkMacSystemFont, sans-serif",
209
- watermarkColor: "rgba(0,0,0,0.25)",
210
- defs: () => "",
211
- bgExtras: () => "",
212
- renderCard: null,
213
- cardAccent: null,
214
- },
215
- // 05 — Schematic (Blueprint — grid bg, monospace, colored top-bars)
216
- schematic: {
217
- bgColor: "#0d1117",
218
- cardBg: "rgba(13,17,23,0.92)",
219
- cardBorder: "#30363d",
220
- cardRadius: 4,
221
- cardShadow: null,
222
- lineColor: "#30363d",
223
- lineWidth: 1.5,
224
- nameColor: "#c9d1d9",
225
- roleColor: "#8b949e",
226
- font: "'JetBrains Mono', 'SF Mono', monospace",
227
- watermarkColor: "rgba(139,148,158,0.3)",
228
- defs: (w, h) => `
229
- <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
230
- <path d="M 20 0 L 0 0 0 20" fill="none" stroke="rgba(48,54,61,0.25)" stroke-width="1"/>
231
- </pattern>`,
232
- bgExtras: (w, h) => `<rect width="${w}" height="${h}" fill="url(#grid)"/>`,
233
- renderCard: (ln, theme) => {
234
- const { tag, accentColor, emojiSvg } = getRoleInfo(ln.node);
235
- const cx = ln.x + ln.width / 2;
236
- // Schematic uses monospace role labels
237
- const schemaRoles = {
238
- ceo: "chief_executive", cto: "chief_technology", cmo: "chief_marketing",
239
- cfo: "chief_financial", coo: "chief_operating", engineer: "engineer",
240
- quality: "quality_assurance", design: "designer", finance: "finance",
241
- operations: "operations", default: "agent",
242
- };
243
- const roleText = schemaRoles[tag] || schemaRoles.default;
244
- const avatarCY = ln.y + 27;
245
- const nameY = ln.y + 66;
246
- const roleY = ln.y + 82;
247
- return `<g>
248
- <rect x="${ln.x}" y="${ln.y}" width="${ln.width}" height="${ln.height}" rx="${theme.cardRadius}" fill="${theme.cardBg}" stroke="${theme.cardBorder}" stroke-width="1"/>
249
- <rect x="${ln.x}" y="${ln.y}" width="${ln.width}" height="2" rx="${theme.cardRadius} ${theme.cardRadius} 0 0" fill="${accentColor}"/>
250
- ${renderEmojiAvatar(cx, avatarCY, 17, "rgba(48,54,61,0.3)", emojiSvg, theme.cardBorder)}
251
- <text x="${cx}" y="${nameY}" text-anchor="middle" font-family="${theme.font}" font-size="12" font-weight="600" fill="${theme.nameColor}">${escapeXml(ln.node.name)}</text>
252
- <text x="${cx}" y="${roleY}" text-anchor="middle" font-family="${theme.font}" font-size="10" fill="${theme.roleColor}" letter-spacing="0.02em">${escapeXml(roleText)}</text>
253
- </g>`;
254
- },
255
- cardAccent: null,
256
- },
257
- };
258
- // ── Layout constants ─────────────────────────────────────────────
259
- const CARD_H = 96;
260
- const CARD_MIN_W = 150;
261
- const CARD_PAD_X = 22;
262
- const AVATAR_SIZE = 34;
263
- const GAP_X = 24;
264
- const GAP_Y = 56;
265
- // ── Collapsed avatar grid constants ─────────────────────────────
266
- const MINI_AVATAR_SIZE = 14;
267
- const MINI_AVATAR_GAP = 6;
268
- const MINI_AVATAR_PADDING = 10;
269
- const MINI_AVATAR_MAX_COLS = 8; // max avatars per row in the grid
270
- const PADDING = 48;
271
- const LOGO_PADDING = 16;
272
- // ── Text measurement ─────────────────────────────────────────────
273
- function measureText(text, fontSize) {
274
- return text.length * fontSize * 0.58;
275
- }
276
- /** Calculate how many rows the avatar grid needs. */
277
- function avatarGridRows(count) {
278
- return Math.ceil(count / MINI_AVATAR_MAX_COLS);
279
- }
280
- /** Width needed for the avatar grid. */
281
- function avatarGridWidth(count) {
282
- const cols = Math.min(count, MINI_AVATAR_MAX_COLS);
283
- return cols * (MINI_AVATAR_SIZE + MINI_AVATAR_GAP) - MINI_AVATAR_GAP + MINI_AVATAR_PADDING * 2;
284
- }
285
- /** Height of the avatar grid area. */
286
- function avatarGridHeight(count) {
287
- if (count === 0)
288
- return 0;
289
- const rows = avatarGridRows(count);
290
- return rows * (MINI_AVATAR_SIZE + MINI_AVATAR_GAP) - MINI_AVATAR_GAP + MINI_AVATAR_PADDING * 2;
291
- }
292
- function cardWidth(node) {
293
- const { roleLabel: defaultRoleLabel } = getRoleInfo(node);
294
- const roleLabel = node.role.startsWith("×") ? node.role : defaultRoleLabel;
295
- const nameW = measureText(node.name, 14) + CARD_PAD_X * 2;
296
- const roleW = measureText(roleLabel, 11) + CARD_PAD_X * 2;
297
- let w = Math.max(CARD_MIN_W, Math.max(nameW, roleW));
298
- // Widen for avatar grid if needed
299
- if (node.collapsedReports && node.collapsedReports.length > 0) {
300
- w = Math.max(w, avatarGridWidth(node.collapsedReports.length));
301
- }
302
- return w;
303
- }
304
- function cardHeight(node) {
305
- if (node.collapsedReports && node.collapsedReports.length > 0) {
306
- return CARD_H + avatarGridHeight(node.collapsedReports.length);
307
- }
308
- return CARD_H;
309
- }
310
- // ── Tree layout (top-down, centered) ─────────────────────────────
311
- function subtreeWidth(node) {
312
- const cw = cardWidth(node);
313
- if (!node.reports || node.reports.length === 0)
314
- return cw;
315
- const childrenW = node.reports.reduce((sum, child, i) => sum + subtreeWidth(child) + (i > 0 ? GAP_X : 0), 0);
316
- return Math.max(cw, childrenW);
317
- }
318
- function layoutTree(node, x, y) {
319
- const w = cardWidth(node);
320
- const sw = subtreeWidth(node);
321
- const cardX = x + (sw - w) / 2;
322
- const h = cardHeight(node);
323
- const layoutNode = {
324
- node,
325
- x: cardX,
326
- y,
327
- width: w,
328
- height: h,
329
- children: [],
330
- };
331
- if (node.reports && node.reports.length > 0) {
332
- let childX = x;
333
- const childY = y + h + GAP_Y;
334
- for (let i = 0; i < node.reports.length; i++) {
335
- const child = node.reports[i];
336
- const childSW = subtreeWidth(child);
337
- layoutNode.children.push(layoutTree(child, childX, childY));
338
- childX += childSW + GAP_X;
339
- }
340
- }
341
- return layoutNode;
342
- }
343
- // ── SVG rendering ────────────────────────────────────────────────
344
- function escapeXml(s) {
345
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
346
- }
347
- /** Render a colorful Twemoji inside a circle at (cx, cy) with given radius */
348
- function renderEmojiAvatar(cx, cy, radius, bgFill, emojiSvg, bgStroke) {
349
- const emojiSize = radius * 1.3; // emoji fills most of the circle
350
- const emojiX = cx - emojiSize / 2;
351
- const emojiY = cy - emojiSize / 2;
352
- const stroke = bgStroke ? `stroke="${bgStroke}" stroke-width="1"` : "";
353
- return `<circle cx="${cx}" cy="${cy}" r="${radius}" fill="${bgFill}" ${stroke}/>
354
- <svg x="${emojiX}" y="${emojiY}" width="${emojiSize}" height="${emojiSize}" viewBox="0 0 36 36">${emojiSvg}</svg>`;
355
- }
356
- function defaultRenderCard(ln, theme) {
357
- // Overflow placeholder card: just shows "+N more" text, no avatar
358
- if (ln.node.role === "overflow") {
359
- const cx = ln.x + ln.width / 2;
360
- const cy = ln.y + ln.height / 2;
361
- return `<g>
362
- <rect x="${ln.x}" y="${ln.y}" width="${ln.width}" height="${ln.height}" rx="${theme.cardRadius}" fill="${theme.bgColor}" stroke="${theme.cardBorder}" stroke-width="1" stroke-dasharray="4,3"/>
363
- <text x="${cx}" y="${cy + 5}" text-anchor="middle" font-family="${theme.font}" font-size="13" font-weight="600" fill="${theme.roleColor}">${escapeXml(ln.node.name)}</text>
364
- </g>`;
365
- }
366
- const { roleLabel: defaultRoleLabel, bg, emojiSvg } = getRoleInfo(ln.node);
367
- // Use node.role directly when it's a collapse badge (e.g. "×15 reports")
368
- const roleLabel = ln.node.role.startsWith("×") ? ln.node.role : defaultRoleLabel;
369
- const cx = ln.x + ln.width / 2;
370
- const avatarCY = ln.y + 27;
371
- const nameY = ln.y + 66;
372
- const roleY = ln.y + 82;
373
- const filterId = `shadow-${ln.node.id}`;
374
- const shadowFilter = theme.cardShadow
375
- ? `filter="url(#${filterId})"`
376
- : "";
377
- const shadowDef = theme.cardShadow
378
- ? `<filter id="${filterId}" x="-4" y="-2" width="${ln.width + 8}" height="${ln.height + 6}">
379
- <feDropShadow dx="0" dy="1" stdDeviation="2" flood-color="${theme.cardShadow}"/>
380
- <feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="rgba(0,0,0,0.03)"/>
381
- </filter>`
382
- : "";
383
- // For dark themes without avatars, use a subtle circle
384
- const isLight = theme.bgColor === "#fafaf9" || theme.bgColor === "#ffffff";
385
- const avatarBg = isLight ? bg : "rgba(255,255,255,0.06)";
386
- const avatarStroke = isLight ? undefined : "rgba(255,255,255,0.08)";
387
- // Render collapsed avatar grid if this node has hidden reports
388
- let avatarGridSvg = "";
389
- const collapsed = ln.node.collapsedReports;
390
- if (collapsed && collapsed.length > 0) {
391
- const gridTop = ln.y + CARD_H + MINI_AVATAR_PADDING;
392
- const cols = Math.min(collapsed.length, MINI_AVATAR_MAX_COLS);
393
- const gridTotalW = cols * (MINI_AVATAR_SIZE + MINI_AVATAR_GAP) - MINI_AVATAR_GAP;
394
- const gridStartX = ln.x + (ln.width - gridTotalW) / 2;
395
- for (let i = 0; i < collapsed.length; i++) {
396
- const col = i % MINI_AVATAR_MAX_COLS;
397
- const row = Math.floor(i / MINI_AVATAR_MAX_COLS);
398
- const dotCx = gridStartX + col * (MINI_AVATAR_SIZE + MINI_AVATAR_GAP) + MINI_AVATAR_SIZE / 2;
399
- const dotCy = gridTop + row * (MINI_AVATAR_SIZE + MINI_AVATAR_GAP) + MINI_AVATAR_SIZE / 2;
400
- const { bg: dotBg } = getRoleInfo(collapsed[i]);
401
- const dotFill = isLight ? dotBg : "rgba(255,255,255,0.1)";
402
- avatarGridSvg += `<circle cx="${dotCx}" cy="${dotCy}" r="${MINI_AVATAR_SIZE / 2}" fill="${dotFill}" stroke="${theme.cardBorder}" stroke-width="0.5"/>`;
403
- }
404
- }
405
- return `<g>
406
- ${shadowDef}
407
- <rect x="${ln.x}" y="${ln.y}" width="${ln.width}" height="${ln.height}" rx="${theme.cardRadius}" fill="${theme.cardBg}" stroke="${theme.cardBorder}" stroke-width="1" ${shadowFilter}/>
408
- ${renderEmojiAvatar(cx, avatarCY, AVATAR_SIZE / 2, avatarBg, emojiSvg, avatarStroke)}
409
- <text x="${cx}" y="${nameY}" text-anchor="middle" font-family="${theme.font}" font-size="14" font-weight="600" fill="${theme.nameColor}">${escapeXml(ln.node.name)}</text>
410
- <text x="${cx}" y="${roleY}" text-anchor="middle" font-family="${theme.font}" font-size="11" font-weight="500" fill="${theme.roleColor}">${escapeXml(roleLabel)}</text>
411
- ${avatarGridSvg}
412
- </g>`;
413
- }
414
- function renderConnectors(ln, theme) {
415
- if (ln.children.length === 0)
416
- return "";
417
- const parentCx = ln.x + ln.width / 2;
418
- const parentBottom = ln.y + ln.height;
419
- const midY = parentBottom + GAP_Y / 2;
420
- const lc = theme.lineColor;
421
- const lw = theme.lineWidth;
422
- let svg = "";
423
- svg += `<line x1="${parentCx}" y1="${parentBottom}" x2="${parentCx}" y2="${midY}" stroke="${lc}" stroke-width="${lw}"/>`;
424
- if (ln.children.length === 1) {
425
- const childCx = ln.children[0].x + ln.children[0].width / 2;
426
- svg += `<line x1="${childCx}" y1="${midY}" x2="${childCx}" y2="${ln.children[0].y}" stroke="${lc}" stroke-width="${lw}"/>`;
427
- }
428
- else {
429
- const leftCx = ln.children[0].x + ln.children[0].width / 2;
430
- const rightCx = ln.children[ln.children.length - 1].x + ln.children[ln.children.length - 1].width / 2;
431
- svg += `<line x1="${leftCx}" y1="${midY}" x2="${rightCx}" y2="${midY}" stroke="${lc}" stroke-width="${lw}"/>`;
432
- for (const child of ln.children) {
433
- const childCx = child.x + child.width / 2;
434
- svg += `<line x1="${childCx}" y1="${midY}" x2="${childCx}" y2="${child.y}" stroke="${lc}" stroke-width="${lw}"/>`;
435
- }
436
- }
437
- for (const child of ln.children) {
438
- svg += renderConnectors(child, theme);
439
- }
440
- return svg;
441
- }
442
- function renderCards(ln, theme) {
443
- const render = theme.renderCard || defaultRenderCard;
444
- let svg = render(ln, theme);
445
- for (const child of ln.children) {
446
- svg += renderCards(child, theme);
447
- }
448
- return svg;
449
- }
450
- function treeBounds(ln) {
451
- let minX = ln.x;
452
- let minY = ln.y;
453
- let maxX = ln.x + ln.width;
454
- let maxY = ln.y + ln.height;
455
- for (const child of ln.children) {
456
- const cb = treeBounds(child);
457
- minX = Math.min(minX, cb.minX);
458
- minY = Math.min(minY, cb.minY);
459
- maxX = Math.max(maxX, cb.maxX);
460
- maxY = Math.max(maxY, cb.maxY);
461
- }
462
- return { minX, minY, maxX, maxY };
463
- }
464
- // Rudder watermark mark rendered as an embedded PNG so exported charts stay self-contained.
465
- const RUDDER_LOGO_SVG = `<image href="${ORG_CHART_LOGO_DATA_URI}" width="28" height="28" preserveAspectRatio="xMidYMid meet"/>`;
466
- // ── Public API ───────────────────────────────────────────────────
467
- // GitHub recommended social media preview dimensions
468
- const TARGET_W = 1280;
469
- const TARGET_H = 640;
470
- /** Count total nodes in a tree. */
471
- function countNodes(nodes) {
472
- let count = 0;
473
- for (const n of nodes) {
474
- count += 1 + countNodes(n.reports ?? []);
475
- }
476
- return count;
477
- }
478
- /** Threshold: auto-collapse orgs larger than this. */
479
- const COLLAPSE_THRESHOLD = 20;
480
- /** Max cards that can fit across the 1280px image. */
481
- const MAX_LEVEL_WIDTH = 8;
482
- /** Max children shown per parent before truncation with "and N more". */
483
- const MAX_CHILDREN_SHOWN = 6;
484
- /** Flatten all descendants of a node into a single list. */
485
- function flattenDescendants(nodes) {
486
- const result = [];
487
- for (const n of nodes) {
488
- result.push(n);
489
- result.push(...flattenDescendants(n.reports ?? []));
490
- }
491
- return result;
492
- }
493
- /** Collect all nodes at a given depth in the tree. */
494
- function nodesAtDepth(nodes, depth) {
495
- if (depth === 0)
496
- return nodes;
497
- const result = [];
498
- for (const n of nodes) {
499
- result.push(...nodesAtDepth(n.reports ?? [], depth - 1));
500
- }
501
- return result;
502
- }
503
- /**
504
- * Estimate how many cards would be shown at the next level if we expand,
505
- * considering truncation (each parent shows at most MAX_CHILDREN_SHOWN + 1 placeholder).
506
- */
507
- function estimateNextLevelWidth(parentNodes) {
508
- let total = 0;
509
- for (const p of parentNodes) {
510
- const childCount = (p.reports ?? []).length;
511
- if (childCount === 0)
512
- continue;
513
- total += Math.min(childCount, MAX_CHILDREN_SHOWN + 1); // +1 for "and N more" placeholder
514
- }
515
- return total;
516
- }
517
- /**
518
- * Collapse a node's children to avatar dots (for wide levels that can't expand).
519
- */
520
- function collapseToAvatars(node) {
521
- const childCount = countNodes(node.reports ?? []);
522
- if (childCount === 0)
523
- return node;
524
- return {
525
- ...node,
526
- role: `×${childCount} reports`,
527
- collapsedReports: flattenDescendants(node.reports ?? []),
528
- reports: [],
529
- };
530
- }
531
- /**
532
- * Truncate a node's children: keep first MAX_CHILDREN_SHOWN, replace rest with
533
- * a summary "and N more" placeholder node (rendered as a count card).
534
- */
535
- function truncateChildren(node) {
536
- const children = node.reports ?? [];
537
- if (children.length <= MAX_CHILDREN_SHOWN)
538
- return node;
539
- const kept = children.slice(0, MAX_CHILDREN_SHOWN);
540
- const hiddenCount = children.length - MAX_CHILDREN_SHOWN;
541
- const placeholder = {
542
- id: `${node.id}-more`,
543
- name: `+${hiddenCount} more`,
544
- role: "overflow",
545
- status: "active",
546
- reports: [],
547
- };
548
- return { ...node, reports: [...kept, placeholder] };
549
- }
550
- /**
551
- * Adaptive collapse: expands levels as long as they fit, truncates or collapses
552
- * when a level is too wide.
553
- */
554
- function smartCollapseTree(roots) {
555
- // Deep clone so we can mutate
556
- const clone = (nodes) => nodes.map((n) => ({ ...n, reports: clone(n.reports ?? []) }));
557
- const tree = clone(roots);
558
- // Walk levels from root down
559
- for (let depth = 0; depth < 10; depth++) {
560
- const parents = nodesAtDepth(tree, depth);
561
- const parentsWithChildren = parents.filter((p) => (p.reports ?? []).length > 0);
562
- if (parentsWithChildren.length === 0)
563
- break;
564
- const nextWidth = estimateNextLevelWidth(parentsWithChildren);
565
- if (nextWidth <= MAX_LEVEL_WIDTH) {
566
- // Next level fits with truncation — truncate oversized parents, then continue deeper
567
- for (const p of parentsWithChildren) {
568
- if ((p.reports ?? []).length > MAX_CHILDREN_SHOWN) {
569
- const truncated = truncateChildren(p);
570
- p.reports = truncated.reports;
571
- }
572
- }
573
- continue;
574
- }
575
- // Next level is too wide — collapse all children at this level to avatars
576
- for (const p of parentsWithChildren) {
577
- const collapsed = collapseToAvatars(p);
578
- p.role = collapsed.role;
579
- p.collapsedReports = collapsed.collapsedReports;
580
- p.reports = [];
581
- }
582
- break;
583
- }
584
- return tree;
585
- }
586
- export function renderOrgChartSvg(orgTree, style = "warmth", overlay) {
587
- const theme = THEMES[style] || THEMES.warmth;
588
- // Auto-collapse large orgs to keep the chart readable
589
- const totalNodes = countNodes(orgTree);
590
- const effectiveTree = totalNodes > COLLAPSE_THRESHOLD ? smartCollapseTree(orgTree) : orgTree;
591
- let root;
592
- if (effectiveTree.length === 1) {
593
- root = effectiveTree[0];
594
- }
595
- else {
596
- root = {
597
- id: "virtual-root",
598
- name: "Organization",
599
- role: "Root",
600
- status: "active",
601
- reports: effectiveTree,
602
- };
603
- }
604
- const layout = layoutTree(root, PADDING, PADDING + 24);
605
- const bounds = treeBounds(layout);
606
- const contentW = bounds.maxX + PADDING;
607
- const contentH = bounds.maxY + PADDING;
608
- // Scale content to fit within the fixed target dimensions
609
- const scale = Math.min(TARGET_W / contentW, TARGET_H / contentH, 1);
610
- const scaledW = contentW * scale;
611
- const scaledH = contentH * scale;
612
- // Center the scaled content within the target frame
613
- const offsetX = (TARGET_W - scaledW) / 2;
614
- const offsetY = (TARGET_H - scaledH) / 2;
615
- const logoX = TARGET_W - 28 - LOGO_PADDING;
616
- const logoY = LOGO_PADDING;
617
- // Optional overlay elements
618
- const overlayNameSvg = overlay?.organizationName
619
- ? `<text x="${LOGO_PADDING}" y="${LOGO_PADDING + 16}" font-family="'Inter', -apple-system, BlinkMacSystemFont, sans-serif" font-size="22" font-weight="700" fill="${theme.nameColor}">${svgEscape(overlay.organizationName)}</text>`
620
- : "";
621
- const overlayStatsSvg = overlay?.stats
622
- ? `<text x="${TARGET_W - LOGO_PADDING}" y="${TARGET_H - LOGO_PADDING}" text-anchor="end" font-family="'Inter', -apple-system, BlinkMacSystemFont, sans-serif" font-size="13" font-weight="500" fill="${theme.roleColor}">${svgEscape(overlay.stats)}</text>`
623
- : "";
624
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${TARGET_W}" height="${TARGET_H}" viewBox="0 0 ${TARGET_W} ${TARGET_H}">
625
- <defs>${theme.defs(TARGET_W, TARGET_H)}</defs>
626
- <rect width="100%" height="100%" fill="${theme.bgColor}" rx="6"/>
627
- ${theme.bgExtras(TARGET_W, TARGET_H)}
628
- <g transform="translate(${logoX}, ${logoY})" opacity="0.32">
629
- ${RUDDER_LOGO_SVG}
630
- </g>
631
- ${overlayNameSvg}
632
- ${overlayStatsSvg}
633
- <g transform="translate(${offsetX}, ${offsetY}) scale(${scale})">
634
- ${renderConnectors(layout, theme)}
635
- ${renderCards(layout, theme)}
636
- </g>
637
- </svg>`;
638
- }
639
- function svgEscape(s) {
640
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
641
- }
642
- export async function renderOrgChartPng(orgTree, style = "warmth", overlay) {
643
- const svg = renderOrgChartSvg(orgTree, style, overlay);
644
- const sharpModule = await import("sharp");
645
- const sharp = sharpModule.default;
646
- // Render at 2x density for retina quality, resize to exact target dimensions
647
- return sharp(Buffer.from(svg), { density: 144 })
648
- .resize(TARGET_W, TARGET_H)
649
- .png()
650
- .toBuffer();
651
- }
652
- //# sourceMappingURL=org-chart-svg.js.map