@elizaos/plugin-browser 2.0.0-alpha.9 → 2.0.3-beta.2

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 (256) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -83
  3. package/auto-enable.ts +24 -0
  4. package/dist/actions/browser-autofill-login.d.ts +43 -0
  5. package/dist/actions/browser-autofill-login.d.ts.map +1 -0
  6. package/dist/actions/browser-autofill-login.js +278 -0
  7. package/dist/actions/browser-autofill-login.js.map +1 -0
  8. package/dist/actions/browser.d.ts +11 -0
  9. package/dist/actions/browser.d.ts.map +1 -0
  10. package/dist/actions/browser.js +412 -0
  11. package/dist/actions/browser.js.map +1 -0
  12. package/dist/actions/manage-browser-bridge.d.ts +34 -0
  13. package/dist/actions/manage-browser-bridge.d.ts.map +1 -0
  14. package/dist/actions/manage-browser-bridge.js +572 -0
  15. package/dist/actions/manage-browser-bridge.js.map +1 -0
  16. package/dist/bridge-policy.d.ts +10 -0
  17. package/dist/bridge-policy.d.ts.map +1 -0
  18. package/dist/bridge-policy.js +37 -0
  19. package/dist/bridge-policy.js.map +1 -0
  20. package/dist/bridge-readiness.d.ts +16 -0
  21. package/dist/bridge-readiness.d.ts.map +1 -0
  22. package/dist/bridge-readiness.js +82 -0
  23. package/dist/bridge-readiness.js.map +1 -0
  24. package/dist/bridge-records.d.ts +9 -0
  25. package/dist/bridge-records.d.ts.map +1 -0
  26. package/dist/bridge-records.js +37 -0
  27. package/dist/bridge-records.js.map +1 -0
  28. package/dist/browser-capture-hooks.d.ts +9 -0
  29. package/dist/browser-capture-hooks.d.ts.map +1 -0
  30. package/dist/browser-capture-hooks.js +15 -0
  31. package/dist/browser-capture-hooks.js.map +1 -0
  32. package/dist/browser-service.d.ts +103 -0
  33. package/dist/browser-service.d.ts.map +1 -0
  34. package/dist/browser-service.js +186 -0
  35. package/dist/browser-service.js.map +1 -0
  36. package/dist/browser-workspace-hooks.d.ts +14 -0
  37. package/dist/browser-workspace-hooks.d.ts.map +1 -0
  38. package/dist/browser-workspace-hooks.js +15 -0
  39. package/dist/browser-workspace-hooks.js.map +1 -0
  40. package/dist/companion-auth.d.ts +34 -0
  41. package/dist/companion-auth.d.ts.map +1 -0
  42. package/dist/companion-auth.js +98 -0
  43. package/dist/companion-auth.js.map +1 -0
  44. package/dist/contracts.d.ts +284 -0
  45. package/dist/contracts.d.ts.map +1 -0
  46. package/dist/contracts.js +56 -0
  47. package/dist/contracts.js.map +1 -0
  48. package/dist/index.d.ts +30 -16
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +76 -90
  51. package/dist/index.js.map +1 -1
  52. package/dist/lifeops-session-contracts.d.ts +46 -0
  53. package/dist/lifeops-session-contracts.d.ts.map +1 -0
  54. package/dist/lifeops-session-contracts.js +1 -0
  55. package/dist/lifeops-session-contracts.js.map +1 -0
  56. package/dist/message-adapter.d.ts +9 -0
  57. package/dist/message-adapter.d.ts.map +1 -0
  58. package/dist/message-adapter.js +104 -0
  59. package/dist/message-adapter.js.map +1 -0
  60. package/dist/packaging.d.ts +27 -0
  61. package/dist/packaging.d.ts.map +1 -0
  62. package/dist/packaging.js +571 -0
  63. package/dist/packaging.js.map +1 -0
  64. package/dist/password-manager-bridge.d.ts +50 -0
  65. package/dist/password-manager-bridge.d.ts.map +1 -0
  66. package/dist/password-manager-bridge.js +437 -0
  67. package/dist/password-manager-bridge.js.map +1 -0
  68. package/dist/plugin.d.ts +10 -0
  69. package/dist/plugin.d.ts.map +1 -0
  70. package/dist/plugin.js +168 -0
  71. package/dist/plugin.js.map +1 -0
  72. package/dist/providers/workspace.d.ts +13 -0
  73. package/dist/providers/workspace.d.ts.map +1 -0
  74. package/dist/providers/workspace.js +64 -0
  75. package/dist/providers/workspace.js.map +1 -0
  76. package/dist/routes/bridge.d.ts +37 -0
  77. package/dist/routes/bridge.d.ts.map +1 -0
  78. package/dist/routes/bridge.js +844 -0
  79. package/dist/routes/bridge.js.map +1 -0
  80. package/dist/routes/workspace-account-gate.d.ts +29 -0
  81. package/dist/routes/workspace-account-gate.d.ts.map +1 -0
  82. package/dist/routes/workspace-account-gate.js +147 -0
  83. package/dist/routes/workspace-account-gate.js.map +1 -0
  84. package/dist/routes/workspace-setup.d.ts +10 -0
  85. package/dist/routes/workspace-setup.d.ts.map +1 -0
  86. package/dist/routes/workspace-setup.js +65 -0
  87. package/dist/routes/workspace-setup.js.map +1 -0
  88. package/dist/routes/workspace.d.ts +20 -0
  89. package/dist/routes/workspace.d.ts.map +1 -0
  90. package/dist/routes/workspace.js +276 -0
  91. package/dist/routes/workspace.js.map +1 -0
  92. package/dist/schema.d.ts +2326 -0
  93. package/dist/schema.d.ts.map +1 -0
  94. package/dist/schema.js +133 -0
  95. package/dist/schema.js.map +1 -0
  96. package/dist/service.d.ts +30 -0
  97. package/dist/service.d.ts.map +1 -0
  98. package/dist/service.js +5 -0
  99. package/dist/service.js.map +1 -0
  100. package/dist/targets/bridge-target.d.ts +31 -0
  101. package/dist/targets/bridge-target.d.ts.map +1 -0
  102. package/dist/targets/bridge-target.js +98 -0
  103. package/dist/targets/bridge-target.js.map +1 -0
  104. package/dist/targets/stagehand-target.d.ts +3 -0
  105. package/dist/targets/stagehand-target.d.ts.map +1 -0
  106. package/dist/targets/stagehand-target.js +187 -0
  107. package/dist/targets/stagehand-target.js.map +1 -0
  108. package/dist/workspace/browser-capture.d.ts +41 -0
  109. package/dist/workspace/browser-capture.d.ts.map +1 -0
  110. package/dist/workspace/browser-capture.js +159 -0
  111. package/dist/workspace/browser-capture.js.map +1 -0
  112. package/dist/workspace/browser-workspace-desktop.d.ts +19 -0
  113. package/dist/workspace/browser-workspace-desktop.d.ts.map +1 -0
  114. package/dist/workspace/browser-workspace-desktop.js +1578 -0
  115. package/dist/workspace/browser-workspace-desktop.js.map +1 -0
  116. package/dist/workspace/browser-workspace-elements.d.ts +42 -0
  117. package/dist/workspace/browser-workspace-elements.d.ts.map +1 -0
  118. package/dist/workspace/browser-workspace-elements.js +547 -0
  119. package/dist/workspace/browser-workspace-elements.js.map +1 -0
  120. package/dist/workspace/browser-workspace-forms.d.ts +19 -0
  121. package/dist/workspace/browser-workspace-forms.d.ts.map +1 -0
  122. package/dist/workspace/browser-workspace-forms.js +277 -0
  123. package/dist/workspace/browser-workspace-forms.js.map +1 -0
  124. package/dist/workspace/browser-workspace-helpers.d.ts +32 -0
  125. package/dist/workspace/browser-workspace-helpers.d.ts.map +1 -0
  126. package/dist/workspace/browser-workspace-helpers.js +232 -0
  127. package/dist/workspace/browser-workspace-helpers.js.map +1 -0
  128. package/dist/workspace/browser-workspace-jsdom.d.ts +16 -0
  129. package/dist/workspace/browser-workspace-jsdom.d.ts.map +1 -0
  130. package/dist/workspace/browser-workspace-jsdom.js +233 -0
  131. package/dist/workspace/browser-workspace-jsdom.js.map +1 -0
  132. package/dist/workspace/browser-workspace-network.d.ts +7 -0
  133. package/dist/workspace/browser-workspace-network.d.ts.map +1 -0
  134. package/dist/workspace/browser-workspace-network.js +145 -0
  135. package/dist/workspace/browser-workspace-network.js.map +1 -0
  136. package/dist/workspace/browser-workspace-snapshots.d.ts +14 -0
  137. package/dist/workspace/browser-workspace-snapshots.d.ts.map +1 -0
  138. package/dist/workspace/browser-workspace-snapshots.js +144 -0
  139. package/dist/workspace/browser-workspace-snapshots.js.map +1 -0
  140. package/dist/workspace/browser-workspace-state.d.ts +24 -0
  141. package/dist/workspace/browser-workspace-state.d.ts.map +1 -0
  142. package/dist/workspace/browser-workspace-state.js +155 -0
  143. package/dist/workspace/browser-workspace-state.js.map +1 -0
  144. package/dist/workspace/browser-workspace-types.d.ts +345 -0
  145. package/dist/workspace/browser-workspace-types.d.ts.map +1 -0
  146. package/dist/workspace/browser-workspace-types.js +11 -0
  147. package/dist/workspace/browser-workspace-types.js.map +1 -0
  148. package/dist/workspace/browser-workspace-web.d.ts +8 -0
  149. package/dist/workspace/browser-workspace-web.d.ts.map +1 -0
  150. package/dist/workspace/browser-workspace-web.js +1342 -0
  151. package/dist/workspace/browser-workspace-web.js.map +1 -0
  152. package/dist/workspace/browser-workspace.d.ts +39 -0
  153. package/dist/workspace/browser-workspace.d.ts.map +1 -0
  154. package/dist/workspace/browser-workspace.js +958 -0
  155. package/dist/workspace/browser-workspace.js.map +1 -0
  156. package/dist/workspace/index.d.ts +26 -0
  157. package/dist/workspace/index.d.ts.map +1 -0
  158. package/dist/workspace/index.js +3 -0
  159. package/dist/workspace/index.js.map +1 -0
  160. package/dist/workspace.d.ts +2 -0
  161. package/dist/workspace.d.ts.map +1 -0
  162. package/dist/workspace.js +2 -0
  163. package/dist/workspace.js.map +1 -0
  164. package/package.json +71 -110
  165. package/dist/actions/click.d.ts +0 -3
  166. package/dist/actions/click.d.ts.map +0 -1
  167. package/dist/actions/click.js +0 -158
  168. package/dist/actions/click.js.map +0 -1
  169. package/dist/actions/extract.d.ts +0 -3
  170. package/dist/actions/extract.d.ts.map +0 -1
  171. package/dist/actions/extract.js +0 -168
  172. package/dist/actions/extract.js.map +0 -1
  173. package/dist/actions/index.d.ts +0 -7
  174. package/dist/actions/index.d.ts.map +0 -1
  175. package/dist/actions/index.js +0 -7
  176. package/dist/actions/index.js.map +0 -1
  177. package/dist/actions/navigate.d.ts +0 -3
  178. package/dist/actions/navigate.d.ts.map +0 -1
  179. package/dist/actions/navigate.js +0 -187
  180. package/dist/actions/navigate.js.map +0 -1
  181. package/dist/actions/screenshot.d.ts +0 -3
  182. package/dist/actions/screenshot.d.ts.map +0 -1
  183. package/dist/actions/screenshot.js +0 -167
  184. package/dist/actions/screenshot.js.map +0 -1
  185. package/dist/actions/select.d.ts +0 -3
  186. package/dist/actions/select.d.ts.map +0 -1
  187. package/dist/actions/select.js +0 -167
  188. package/dist/actions/select.js.map +0 -1
  189. package/dist/actions/type.d.ts +0 -3
  190. package/dist/actions/type.d.ts.map +0 -1
  191. package/dist/actions/type.js +0 -167
  192. package/dist/actions/type.js.map +0 -1
  193. package/dist/cli/index.d.ts +0 -8
  194. package/dist/cli/index.d.ts.map +0 -1
  195. package/dist/cli/index.js +0 -13
  196. package/dist/cli/index.js.map +0 -1
  197. package/dist/cli/register.d.ts +0 -20
  198. package/dist/cli/register.d.ts.map +0 -1
  199. package/dist/cli/register.js +0 -403
  200. package/dist/cli/register.js.map +0 -1
  201. package/dist/providerRelevance.d.ts +0 -4
  202. package/dist/providerRelevance.d.ts.map +0 -1
  203. package/dist/providerRelevance.js +0 -33
  204. package/dist/providerRelevance.js.map +0 -1
  205. package/dist/providers/browser-state.d.ts +0 -3
  206. package/dist/providers/browser-state.d.ts.map +0 -1
  207. package/dist/providers/browser-state.js +0 -72
  208. package/dist/providers/browser-state.js.map +0 -1
  209. package/dist/providers/index.d.ts +0 -2
  210. package/dist/providers/index.d.ts.map +0 -1
  211. package/dist/providers/index.js +0 -2
  212. package/dist/providers/index.js.map +0 -1
  213. package/dist/services/browser-service.d.ts +0 -32
  214. package/dist/services/browser-service.d.ts.map +0 -1
  215. package/dist/services/browser-service.js +0 -213
  216. package/dist/services/browser-service.js.map +0 -1
  217. package/dist/services/index.d.ts +0 -4
  218. package/dist/services/index.d.ts.map +0 -1
  219. package/dist/services/index.js +0 -4
  220. package/dist/services/index.js.map +0 -1
  221. package/dist/services/process-manager.d.ts +0 -24
  222. package/dist/services/process-manager.d.ts.map +0 -1
  223. package/dist/services/process-manager.js +0 -270
  224. package/dist/services/process-manager.js.map +0 -1
  225. package/dist/services/websocket-client.d.ts +0 -35
  226. package/dist/services/websocket-client.d.ts.map +0 -1
  227. package/dist/services/websocket-client.js +0 -221
  228. package/dist/services/websocket-client.js.map +0 -1
  229. package/dist/types.d.ts +0 -101
  230. package/dist/types.d.ts.map +0 -1
  231. package/dist/types.js +0 -2
  232. package/dist/types.js.map +0 -1
  233. package/dist/utils/captcha.d.ts +0 -33
  234. package/dist/utils/captcha.d.ts.map +0 -1
  235. package/dist/utils/captcha.js +0 -219
  236. package/dist/utils/captcha.js.map +0 -1
  237. package/dist/utils/errors.d.ts +0 -37
  238. package/dist/utils/errors.d.ts.map +0 -1
  239. package/dist/utils/errors.js +0 -81
  240. package/dist/utils/errors.js.map +0 -1
  241. package/dist/utils/index.d.ts +0 -5
  242. package/dist/utils/index.d.ts.map +0 -1
  243. package/dist/utils/index.js +0 -5
  244. package/dist/utils/index.js.map +0 -1
  245. package/dist/utils/retry.d.ts +0 -26
  246. package/dist/utils/retry.d.ts.map +0 -1
  247. package/dist/utils/retry.js +0 -55
  248. package/dist/utils/retry.js.map +0 -1
  249. package/dist/utils/security.d.ts +0 -27
  250. package/dist/utils/security.d.ts.map +0 -1
  251. package/dist/utils/security.js +0 -139
  252. package/dist/utils/security.js.map +0 -1
  253. package/dist/utils/url.d.ts +0 -12
  254. package/dist/utils/url.d.ts.map +0 -1
  255. package/dist/utils/url.js +0 -39
  256. package/dist/utils/url.js.map +0 -1
@@ -0,0 +1,276 @@
1
+ import { requestBrowserWorkspace } from "../workspace/browser-workspace-desktop.js";
2
+ import { assertBrowserWorkspaceUserScriptAllowed } from "../workspace/browser-workspace-helpers.js";
3
+ import {
4
+ closeBrowserWorkspaceTab,
5
+ evaluateBrowserWorkspaceTab,
6
+ executeBrowserWorkspaceCommand,
7
+ getBrowserWorkspaceSnapshot,
8
+ getBrowserWorkspaceUnavailableMessage,
9
+ hideBrowserWorkspaceTab,
10
+ isBrowserWorkspaceBridgeConfigured,
11
+ listBrowserWorkspaceTabs,
12
+ navigateBrowserWorkspaceTab,
13
+ openBrowserWorkspaceTab,
14
+ showBrowserWorkspaceTab,
15
+ snapshotBrowserWorkspaceTab
16
+ } from "../workspace/index.js";
17
+ import {
18
+ assertBrowserWorkspaceCommandConnectorAccountGate,
19
+ assertBrowserWorkspaceConnectorAccountGate
20
+ } from "./workspace-account-gate.js";
21
+ function statusFromBrowserWorkspaceError(error, message) {
22
+ if (error instanceof Error && "status" in error && typeof error.status === "number") {
23
+ return error.status;
24
+ }
25
+ if (message.includes(getBrowserWorkspaceUnavailableMessage())) {
26
+ return 503;
27
+ }
28
+ if (message.includes("only available in the desktop app")) {
29
+ return 409;
30
+ }
31
+ if (message.includes("failed (404)")) {
32
+ return 404;
33
+ }
34
+ if (message.includes("failed (409)")) {
35
+ return 409;
36
+ }
37
+ return 500;
38
+ }
39
+ function connectorReferenceFromSearchParams(url) {
40
+ return {
41
+ connectorProvider: url?.searchParams.get("connectorProvider"),
42
+ connectorAccountId: url?.searchParams.get("connectorAccountId"),
43
+ partition: url?.searchParams.get("partition")
44
+ };
45
+ }
46
+ function buildBrowserWorkspaceEventsBridgePath(url) {
47
+ const params = new URLSearchParams();
48
+ for (const key of ["after", "limit", "tabId", "type"]) {
49
+ const value = url?.searchParams.get(key)?.trim();
50
+ if (value) {
51
+ params.set(key, value);
52
+ }
53
+ }
54
+ const query = params.toString();
55
+ return query ? `/events?${query}` : "/events";
56
+ }
57
+ function isBrowserWorkspaceRouteBodyObject(value) {
58
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
59
+ }
60
+ function rejectMalformedBrowserWorkspacePayload(ctx) {
61
+ ctx.json(ctx.res, { error: "request body must be a JSON object" }, 400);
62
+ return true;
63
+ }
64
+ function decodeBrowserWorkspaceTabId(raw) {
65
+ if (typeof raw !== "string") return null;
66
+ try {
67
+ const decoded = decodeURIComponent(raw).trim();
68
+ return decoded ? decoded : null;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+ async function assertBrowserWorkspaceTabConnectorAccountGate(ctx, tabId, reference, operation) {
74
+ const tabs = await listBrowserWorkspaceTabs();
75
+ const tab = tabs.find((entry) => entry.id === tabId) ?? null;
76
+ await assertBrowserWorkspaceConnectorAccountGate({
77
+ runtime: ctx.state?.runtime ?? null,
78
+ connectorProvider: reference.connectorProvider,
79
+ connectorAccountId: reference.connectorAccountId,
80
+ partition: tab?.partition ?? reference.partition,
81
+ operation
82
+ });
83
+ }
84
+ async function handleBrowserWorkspaceRoutes(ctx) {
85
+ const { req, res, method, pathname, readJsonBody, json } = ctx;
86
+ if (pathname !== "/api/browser-workspace" && pathname !== "/api/browser-workspace/command" && pathname !== "/api/browser-workspace/events" && pathname !== "/api/browser-workspace/tabs" && !pathname.startsWith("/api/browser-workspace/tabs/")) {
87
+ return false;
88
+ }
89
+ try {
90
+ if (pathname === "/api/browser-workspace" && method === "GET") {
91
+ json(res, await getBrowserWorkspaceSnapshot());
92
+ return true;
93
+ }
94
+ if (pathname === "/api/browser-workspace/events" && method === "GET") {
95
+ if (!isBrowserWorkspaceBridgeConfigured()) {
96
+ throw new Error(getBrowserWorkspaceUnavailableMessage());
97
+ }
98
+ json(
99
+ res,
100
+ await requestBrowserWorkspace(
101
+ buildBrowserWorkspaceEventsBridgePath(ctx.url)
102
+ )
103
+ );
104
+ return true;
105
+ }
106
+ if (pathname === "/api/browser-workspace/command" && method === "POST") {
107
+ const body = await readJsonBody(req, res) ?? null;
108
+ if (!isBrowserWorkspaceRouteBodyObject(body)) {
109
+ return rejectMalformedBrowserWorkspacePayload(ctx);
110
+ }
111
+ if (!body?.subaction) {
112
+ json(res, { error: "subaction is required" }, 400);
113
+ return true;
114
+ }
115
+ await assertBrowserWorkspaceCommandConnectorAccountGate({
116
+ runtime: ctx.state?.runtime ?? null,
117
+ command: body,
118
+ operation: "browser workspace command"
119
+ });
120
+ json(res, await executeBrowserWorkspaceCommand(body));
121
+ return true;
122
+ }
123
+ if (pathname === "/api/browser-workspace/tabs" && method === "GET") {
124
+ json(res, { tabs: await listBrowserWorkspaceTabs() });
125
+ return true;
126
+ }
127
+ if (pathname === "/api/browser-workspace/tabs" && method === "POST") {
128
+ const body = await readJsonBody(req, res) ?? null;
129
+ if (!isBrowserWorkspaceRouteBodyObject(body)) {
130
+ return rejectMalformedBrowserWorkspacePayload(ctx);
131
+ }
132
+ const connectorGate = await assertBrowserWorkspaceConnectorAccountGate({
133
+ runtime: ctx.state?.runtime ?? null,
134
+ connectorProvider: body.connectorProvider,
135
+ connectorAccountId: body.connectorAccountId,
136
+ partition: body.partition,
137
+ operation: "open browser workspace tab"
138
+ });
139
+ json(res, {
140
+ tab: await openBrowserWorkspaceTab({
141
+ ...body,
142
+ partition: connectorGate?.expectedPartition ?? body.partition
143
+ })
144
+ });
145
+ return true;
146
+ }
147
+ const match = pathname.match(
148
+ /^\/api\/browser-workspace\/tabs\/([^/]+)(?:\/(navigate|eval|show|hide|snapshot))?$/
149
+ );
150
+ if (!match) {
151
+ return false;
152
+ }
153
+ const tabId = decodeBrowserWorkspaceTabId(match[1]);
154
+ if (!tabId) {
155
+ json(res, { error: "valid tab id is required" }, 400);
156
+ return true;
157
+ }
158
+ const action = match[2] ?? null;
159
+ if (!action && method === "DELETE") {
160
+ await assertBrowserWorkspaceTabConnectorAccountGate(
161
+ ctx,
162
+ tabId,
163
+ connectorReferenceFromSearchParams(ctx.url),
164
+ "close browser workspace tab"
165
+ );
166
+ const closed = await closeBrowserWorkspaceTab(tabId);
167
+ json(
168
+ res,
169
+ closed ? { closed: true } : { closed: false },
170
+ closed ? 200 : 404
171
+ );
172
+ return true;
173
+ }
174
+ if (action === "show" && method === "POST") {
175
+ await assertBrowserWorkspaceTabConnectorAccountGate(
176
+ ctx,
177
+ tabId,
178
+ connectorReferenceFromSearchParams(ctx.url),
179
+ "show browser workspace tab"
180
+ );
181
+ json(res, { tab: await showBrowserWorkspaceTab(tabId) });
182
+ return true;
183
+ }
184
+ if (action === "hide" && method === "POST") {
185
+ await assertBrowserWorkspaceTabConnectorAccountGate(
186
+ ctx,
187
+ tabId,
188
+ connectorReferenceFromSearchParams(ctx.url),
189
+ "hide browser workspace tab"
190
+ );
191
+ json(res, { tab: await hideBrowserWorkspaceTab(tabId) });
192
+ return true;
193
+ }
194
+ if (action === "snapshot" && method === "GET") {
195
+ await assertBrowserWorkspaceTabConnectorAccountGate(
196
+ ctx,
197
+ tabId,
198
+ connectorReferenceFromSearchParams(ctx.url),
199
+ "snapshot browser workspace tab"
200
+ );
201
+ json(res, await snapshotBrowserWorkspaceTab(tabId));
202
+ return true;
203
+ }
204
+ if (action === "navigate" && method === "POST") {
205
+ const body = await readJsonBody(req, res);
206
+ if (!isBrowserWorkspaceRouteBodyObject(body)) {
207
+ return rejectMalformedBrowserWorkspacePayload(ctx);
208
+ }
209
+ if (!body?.url?.trim()) {
210
+ json(res, { error: "url is required" }, 400);
211
+ return true;
212
+ }
213
+ await assertBrowserWorkspaceTabConnectorAccountGate(
214
+ ctx,
215
+ tabId,
216
+ body,
217
+ "navigate browser workspace tab"
218
+ );
219
+ json(res, {
220
+ tab: await navigateBrowserWorkspaceTab({
221
+ id: tabId,
222
+ url: body.url
223
+ })
224
+ });
225
+ return true;
226
+ }
227
+ if (action === "eval" && method === "POST") {
228
+ const body = await readJsonBody(req, res);
229
+ if (!isBrowserWorkspaceRouteBodyObject(body)) {
230
+ return rejectMalformedBrowserWorkspacePayload(ctx);
231
+ }
232
+ if (!body?.script?.trim()) {
233
+ json(res, { error: "script is required" }, 400);
234
+ return true;
235
+ }
236
+ await assertBrowserWorkspaceTabConnectorAccountGate(
237
+ ctx,
238
+ tabId,
239
+ body,
240
+ "evaluate browser workspace tab"
241
+ );
242
+ assertBrowserWorkspaceUserScriptAllowed(body.script, "eval", "desktop");
243
+ json(res, {
244
+ result: await evaluateBrowserWorkspaceTab({
245
+ id: tabId,
246
+ script: body.script
247
+ })
248
+ });
249
+ return true;
250
+ }
251
+ return false;
252
+ } catch (error) {
253
+ const message = error instanceof Error ? error.message : String(error);
254
+ const status = statusFromBrowserWorkspaceError(error, message);
255
+ json(res, { error: message }, status);
256
+ return true;
257
+ }
258
+ }
259
+ const BROWSER_WORKSPACE_ROUTE_PATHS = [
260
+ { type: "GET", path: "/api/browser-workspace" },
261
+ { type: "POST", path: "/api/browser-workspace/command" },
262
+ { type: "GET", path: "/api/browser-workspace/events" },
263
+ { type: "GET", path: "/api/browser-workspace/tabs" },
264
+ { type: "POST", path: "/api/browser-workspace/tabs" },
265
+ { type: "DELETE", path: "/api/browser-workspace/tabs/:tabId" },
266
+ { type: "POST", path: "/api/browser-workspace/tabs/:tabId/show" },
267
+ { type: "POST", path: "/api/browser-workspace/tabs/:tabId/hide" },
268
+ { type: "GET", path: "/api/browser-workspace/tabs/:tabId/snapshot" },
269
+ { type: "POST", path: "/api/browser-workspace/tabs/:tabId/navigate" },
270
+ { type: "POST", path: "/api/browser-workspace/tabs/:tabId/eval" }
271
+ ];
272
+ export {
273
+ BROWSER_WORKSPACE_ROUTE_PATHS,
274
+ handleBrowserWorkspaceRoutes
275
+ };
276
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/workspace.ts"],"sourcesContent":["/**\n * Browser workspace HTTP routes.\n *\n * The runtime mounts these via `Plugin.routes` with `rawPath: true` so the\n * legacy `/api/browser-workspace/*` paths are preserved. Implementation\n * lives in `@elizaos/plugin-browser/workspace`; this is the HTTP edge.\n */\n\nimport type { IAgentRuntime, RouteRequestContext } from \"@elizaos/core\";\nimport { requestBrowserWorkspace } from \"../workspace/browser-workspace-desktop.js\";\nimport { assertBrowserWorkspaceUserScriptAllowed } from \"../workspace/browser-workspace-helpers.js\";\nimport type { BrowserWorkspaceEventLogSnapshot } from \"../workspace/browser-workspace-types.js\";\nimport {\n type BrowserWorkspaceCommand,\n closeBrowserWorkspaceTab,\n evaluateBrowserWorkspaceTab,\n executeBrowserWorkspaceCommand,\n getBrowserWorkspaceSnapshot,\n getBrowserWorkspaceUnavailableMessage,\n hideBrowserWorkspaceTab,\n isBrowserWorkspaceBridgeConfigured,\n listBrowserWorkspaceTabs,\n navigateBrowserWorkspaceTab,\n openBrowserWorkspaceTab,\n showBrowserWorkspaceTab,\n snapshotBrowserWorkspaceTab,\n} from \"../workspace/index.js\";\nimport {\n assertBrowserWorkspaceCommandConnectorAccountGate,\n assertBrowserWorkspaceConnectorAccountGate,\n} from \"./workspace-account-gate.js\";\n\ntype OpenBrowserWorkspaceBody = {\n url?: string;\n title?: string;\n show?: boolean;\n partition?: string;\n connectorProvider?: string;\n connectorAccountId?: string;\n kind?: \"internal\" | \"standard\";\n width?: number;\n height?: number;\n};\n\ntype NavigateBrowserWorkspaceBody = {\n url?: string;\n partition?: string;\n connectorProvider?: string;\n connectorAccountId?: string;\n};\n\ntype EvaluateBrowserWorkspaceBody = {\n script?: string;\n partition?: string;\n connectorProvider?: string;\n connectorAccountId?: string;\n};\n\ntype BrowserWorkspaceCommandBody = BrowserWorkspaceCommand;\ntype BrowserWorkspaceConnectorReference = {\n partition?: string | null;\n connectorProvider?: string | null;\n connectorAccountId?: string | null;\n};\n\nexport interface BrowserWorkspaceRouteContext extends RouteRequestContext {\n url?: URL;\n state?: {\n runtime?: IAgentRuntime | null;\n };\n}\n\nfunction statusFromBrowserWorkspaceError(\n error: unknown,\n message: string,\n): number {\n if (\n error instanceof Error &&\n \"status\" in error &&\n typeof error.status === \"number\"\n ) {\n return error.status;\n }\n if (message.includes(getBrowserWorkspaceUnavailableMessage())) {\n return 503;\n }\n if (message.includes(\"only available in the desktop app\")) {\n return 409;\n }\n if (message.includes(\"failed (404)\")) {\n return 404;\n }\n if (message.includes(\"failed (409)\")) {\n return 409;\n }\n return 500;\n}\n\nfunction connectorReferenceFromSearchParams(\n url: URL | undefined,\n): BrowserWorkspaceConnectorReference {\n return {\n connectorProvider: url?.searchParams.get(\"connectorProvider\"),\n connectorAccountId: url?.searchParams.get(\"connectorAccountId\"),\n partition: url?.searchParams.get(\"partition\"),\n };\n}\n\nfunction buildBrowserWorkspaceEventsBridgePath(url: URL | undefined): string {\n const params = new URLSearchParams();\n for (const key of [\"after\", \"limit\", \"tabId\", \"type\"]) {\n const value = url?.searchParams.get(key)?.trim();\n if (value) {\n params.set(key, value);\n }\n }\n const query = params.toString();\n return query ? `/events?${query}` : \"/events\";\n}\n\nfunction isBrowserWorkspaceRouteBodyObject(\n value: unknown,\n): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\" && !Array.isArray(value));\n}\n\nfunction rejectMalformedBrowserWorkspacePayload(\n ctx: BrowserWorkspaceRouteContext,\n): true {\n ctx.json(ctx.res, { error: \"request body must be a JSON object\" }, 400);\n return true;\n}\n\nfunction decodeBrowserWorkspaceTabId(raw: string | undefined): string | null {\n if (typeof raw !== \"string\") return null;\n try {\n const decoded = decodeURIComponent(raw).trim();\n return decoded ? decoded : null;\n } catch {\n return null;\n }\n}\n\nasync function assertBrowserWorkspaceTabConnectorAccountGate(\n ctx: BrowserWorkspaceRouteContext,\n tabId: string,\n reference: BrowserWorkspaceConnectorReference,\n operation: string,\n): Promise<void> {\n const tabs = await listBrowserWorkspaceTabs();\n const tab = tabs.find((entry) => entry.id === tabId) ?? null;\n await assertBrowserWorkspaceConnectorAccountGate({\n runtime: ctx.state?.runtime ?? null,\n connectorProvider: reference.connectorProvider,\n connectorAccountId: reference.connectorAccountId,\n partition: tab?.partition ?? reference.partition,\n operation,\n });\n}\n\nexport async function handleBrowserWorkspaceRoutes(\n ctx: BrowserWorkspaceRouteContext,\n): Promise<boolean> {\n const { req, res, method, pathname, readJsonBody, json } = ctx;\n\n if (\n pathname !== \"/api/browser-workspace\" &&\n pathname !== \"/api/browser-workspace/command\" &&\n pathname !== \"/api/browser-workspace/events\" &&\n pathname !== \"/api/browser-workspace/tabs\" &&\n !pathname.startsWith(\"/api/browser-workspace/tabs/\")\n ) {\n return false;\n }\n\n try {\n if (pathname === \"/api/browser-workspace\" && method === \"GET\") {\n json(res, await getBrowserWorkspaceSnapshot());\n return true;\n }\n\n if (pathname === \"/api/browser-workspace/events\" && method === \"GET\") {\n if (!isBrowserWorkspaceBridgeConfigured()) {\n throw new Error(getBrowserWorkspaceUnavailableMessage());\n }\n json(\n res,\n await requestBrowserWorkspace<BrowserWorkspaceEventLogSnapshot>(\n buildBrowserWorkspaceEventsBridgePath(ctx.url),\n ),\n );\n return true;\n }\n\n if (pathname === \"/api/browser-workspace/command\" && method === \"POST\") {\n const body =\n (await readJsonBody<BrowserWorkspaceCommandBody>(req, res)) ?? null;\n if (!isBrowserWorkspaceRouteBodyObject(body)) {\n return rejectMalformedBrowserWorkspacePayload(ctx);\n }\n if (!body?.subaction) {\n json(res, { error: \"subaction is required\" }, 400);\n return true;\n }\n await assertBrowserWorkspaceCommandConnectorAccountGate({\n runtime: ctx.state?.runtime ?? null,\n command: body,\n operation: \"browser workspace command\",\n });\n json(res, await executeBrowserWorkspaceCommand(body));\n return true;\n }\n\n if (pathname === \"/api/browser-workspace/tabs\" && method === \"GET\") {\n json(res, { tabs: await listBrowserWorkspaceTabs() });\n return true;\n }\n\n if (pathname === \"/api/browser-workspace/tabs\" && method === \"POST\") {\n const body =\n (await readJsonBody<OpenBrowserWorkspaceBody>(req, res)) ?? null;\n if (!isBrowserWorkspaceRouteBodyObject(body)) {\n return rejectMalformedBrowserWorkspacePayload(ctx);\n }\n const connectorGate = await assertBrowserWorkspaceConnectorAccountGate({\n runtime: ctx.state?.runtime ?? null,\n connectorProvider: body.connectorProvider,\n connectorAccountId: body.connectorAccountId,\n partition: body.partition,\n operation: \"open browser workspace tab\",\n });\n json(res, {\n tab: await openBrowserWorkspaceTab({\n ...body,\n partition: connectorGate?.expectedPartition ?? body.partition,\n }),\n });\n return true;\n }\n\n const match = pathname.match(\n /^\\/api\\/browser-workspace\\/tabs\\/([^/]+)(?:\\/(navigate|eval|show|hide|snapshot))?$/,\n );\n if (!match) {\n return false;\n }\n\n const tabId = decodeBrowserWorkspaceTabId(match[1]);\n if (!tabId) {\n json(res, { error: \"valid tab id is required\" }, 400);\n return true;\n }\n const action = match[2] ?? null;\n\n if (!action && method === \"DELETE\") {\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n connectorReferenceFromSearchParams(ctx.url),\n \"close browser workspace tab\",\n );\n const closed = await closeBrowserWorkspaceTab(tabId);\n json(\n res,\n closed ? { closed: true } : { closed: false },\n closed ? 200 : 404,\n );\n return true;\n }\n\n if (action === \"show\" && method === \"POST\") {\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n connectorReferenceFromSearchParams(ctx.url),\n \"show browser workspace tab\",\n );\n json(res, { tab: await showBrowserWorkspaceTab(tabId) });\n return true;\n }\n\n if (action === \"hide\" && method === \"POST\") {\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n connectorReferenceFromSearchParams(ctx.url),\n \"hide browser workspace tab\",\n );\n json(res, { tab: await hideBrowserWorkspaceTab(tabId) });\n return true;\n }\n\n if (action === \"snapshot\" && method === \"GET\") {\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n connectorReferenceFromSearchParams(ctx.url),\n \"snapshot browser workspace tab\",\n );\n json(res, await snapshotBrowserWorkspaceTab(tabId));\n return true;\n }\n\n if (action === \"navigate\" && method === \"POST\") {\n const body = await readJsonBody<NavigateBrowserWorkspaceBody>(req, res);\n if (!isBrowserWorkspaceRouteBodyObject(body)) {\n return rejectMalformedBrowserWorkspacePayload(ctx);\n }\n if (!body?.url?.trim()) {\n json(res, { error: \"url is required\" }, 400);\n return true;\n }\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n body,\n \"navigate browser workspace tab\",\n );\n json(res, {\n tab: await navigateBrowserWorkspaceTab({\n id: tabId,\n url: body.url,\n }),\n });\n return true;\n }\n\n if (action === \"eval\" && method === \"POST\") {\n const body = await readJsonBody<EvaluateBrowserWorkspaceBody>(req, res);\n if (!isBrowserWorkspaceRouteBodyObject(body)) {\n return rejectMalformedBrowserWorkspacePayload(ctx);\n }\n if (!body?.script?.trim()) {\n json(res, { error: \"script is required\" }, 400);\n return true;\n }\n await assertBrowserWorkspaceTabConnectorAccountGate(\n ctx,\n tabId,\n body,\n \"evaluate browser workspace tab\",\n );\n assertBrowserWorkspaceUserScriptAllowed(body.script, \"eval\", \"desktop\");\n json(res, {\n result: await evaluateBrowserWorkspaceTab({\n id: tabId,\n script: body.script,\n }),\n });\n return true;\n }\n\n return false;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = statusFromBrowserWorkspaceError(error, message);\n json(res, { error: message }, status);\n return true;\n }\n}\n\nexport const BROWSER_WORKSPACE_ROUTE_PATHS: Array<{\n type: string;\n path: string;\n}> = [\n { type: \"GET\", path: \"/api/browser-workspace\" },\n { type: \"POST\", path: \"/api/browser-workspace/command\" },\n { type: \"GET\", path: \"/api/browser-workspace/events\" },\n { type: \"GET\", path: \"/api/browser-workspace/tabs\" },\n { type: \"POST\", path: \"/api/browser-workspace/tabs\" },\n { type: \"DELETE\", path: \"/api/browser-workspace/tabs/:tabId\" },\n { type: \"POST\", path: \"/api/browser-workspace/tabs/:tabId/show\" },\n { type: \"POST\", path: \"/api/browser-workspace/tabs/:tabId/hide\" },\n { type: \"GET\", path: \"/api/browser-workspace/tabs/:tabId/snapshot\" },\n { type: \"POST\", path: \"/api/browser-workspace/tabs/:tabId/navigate\" },\n { type: \"POST\", path: \"/api/browser-workspace/tabs/:tabId/eval\" },\n];\n"],"mappings":"AASA,SAAS,+BAA+B;AACxC,SAAS,+CAA+C;AAExD;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AA0CP,SAAS,gCACP,OACA,SACQ;AACR,MACE,iBAAiB,SACjB,YAAY,SACZ,OAAO,MAAM,WAAW,UACxB;AACA,WAAO,MAAM;AAAA,EACf;AACA,MAAI,QAAQ,SAAS,sCAAsC,CAAC,GAAG;AAC7D,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,SAAS,mCAAmC,GAAG;AACzD,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,SAAS,cAAc,GAAG;AACpC,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,SAAS,cAAc,GAAG;AACpC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mCACP,KACoC;AACpC,SAAO;AAAA,IACL,mBAAmB,KAAK,aAAa,IAAI,mBAAmB;AAAA,IAC5D,oBAAoB,KAAK,aAAa,IAAI,oBAAoB;AAAA,IAC9D,WAAW,KAAK,aAAa,IAAI,WAAW;AAAA,EAC9C;AACF;AAEA,SAAS,sCAAsC,KAA8B;AAC3E,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,OAAO,CAAC,SAAS,SAAS,SAAS,MAAM,GAAG;AACrD,UAAM,QAAQ,KAAK,aAAa,IAAI,GAAG,GAAG,KAAK;AAC/C,QAAI,OAAO;AACT,aAAO,IAAI,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AACA,QAAM,QAAQ,OAAO,SAAS;AAC9B,SAAO,QAAQ,WAAW,KAAK,KAAK;AACtC;AAEA,SAAS,kCACP,OACkC;AAClC,SAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,CAAC;AAC5E;AAEA,SAAS,uCACP,KACM;AACN,MAAI,KAAK,IAAI,KAAK,EAAE,OAAO,qCAAqC,GAAG,GAAG;AACtE,SAAO;AACT;AAEA,SAAS,4BAA4B,KAAwC;AAC3E,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,MAAI;AACF,UAAM,UAAU,mBAAmB,GAAG,EAAE,KAAK;AAC7C,WAAO,UAAU,UAAU;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,8CACb,KACA,OACA,WACA,WACe;AACf,QAAM,OAAO,MAAM,yBAAyB;AAC5C,QAAM,MAAM,KAAK,KAAK,CAAC,UAAU,MAAM,OAAO,KAAK,KAAK;AACxD,QAAM,2CAA2C;AAAA,IAC/C,SAAS,IAAI,OAAO,WAAW;AAAA,IAC/B,mBAAmB,UAAU;AAAA,IAC7B,oBAAoB,UAAU;AAAA,IAC9B,WAAW,KAAK,aAAa,UAAU;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,6BACpB,KACkB;AAClB,QAAM,EAAE,KAAK,KAAK,QAAQ,UAAU,cAAc,KAAK,IAAI;AAE3D,MACE,aAAa,4BACb,aAAa,oCACb,aAAa,mCACb,aAAa,iCACb,CAAC,SAAS,WAAW,8BAA8B,GACnD;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,QAAI,aAAa,4BAA4B,WAAW,OAAO;AAC7D,WAAK,KAAK,MAAM,4BAA4B,CAAC;AAC7C,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,mCAAmC,WAAW,OAAO;AACpE,UAAI,CAAC,mCAAmC,GAAG;AACzC,cAAM,IAAI,MAAM,sCAAsC,CAAC;AAAA,MACzD;AACA;AAAA,QACE;AAAA,QACA,MAAM;AAAA,UACJ,sCAAsC,IAAI,GAAG;AAAA,QAC/C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,oCAAoC,WAAW,QAAQ;AACtE,YAAM,OACH,MAAM,aAA0C,KAAK,GAAG,KAAM;AACjE,UAAI,CAAC,kCAAkC,IAAI,GAAG;AAC5C,eAAO,uCAAuC,GAAG;AAAA,MACnD;AACA,UAAI,CAAC,MAAM,WAAW;AACpB,aAAK,KAAK,EAAE,OAAO,wBAAwB,GAAG,GAAG;AACjD,eAAO;AAAA,MACT;AACA,YAAM,kDAAkD;AAAA,QACtD,SAAS,IAAI,OAAO,WAAW;AAAA,QAC/B,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AACD,WAAK,KAAK,MAAM,+BAA+B,IAAI,CAAC;AACpD,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,iCAAiC,WAAW,OAAO;AAClE,WAAK,KAAK,EAAE,MAAM,MAAM,yBAAyB,EAAE,CAAC;AACpD,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,iCAAiC,WAAW,QAAQ;AACnE,YAAM,OACH,MAAM,aAAuC,KAAK,GAAG,KAAM;AAC9D,UAAI,CAAC,kCAAkC,IAAI,GAAG;AAC5C,eAAO,uCAAuC,GAAG;AAAA,MACnD;AACA,YAAM,gBAAgB,MAAM,2CAA2C;AAAA,QACrE,SAAS,IAAI,OAAO,WAAW;AAAA,QAC/B,mBAAmB,KAAK;AAAA,QACxB,oBAAoB,KAAK;AAAA,QACzB,WAAW,KAAK;AAAA,QAChB,WAAW;AAAA,MACb,CAAC;AACD,WAAK,KAAK;AAAA,QACR,KAAK,MAAM,wBAAwB;AAAA,UACjC,GAAG;AAAA,UACH,WAAW,eAAe,qBAAqB,KAAK;AAAA,QACtD,CAAC;AAAA,MACH,CAAC;AACD,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,SAAS;AAAA,MACrB;AAAA,IACF;AACA,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,4BAA4B,MAAM,CAAC,CAAC;AAClD,QAAI,CAAC,OAAO;AACV,WAAK,KAAK,EAAE,OAAO,2BAA2B,GAAG,GAAG;AACpD,aAAO;AAAA,IACT;AACA,UAAM,SAAS,MAAM,CAAC,KAAK;AAE3B,QAAI,CAAC,UAAU,WAAW,UAAU;AAClC,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,mCAAmC,IAAI,GAAG;AAAA,QAC1C;AAAA,MACF;AACA,YAAM,SAAS,MAAM,yBAAyB,KAAK;AACnD;AAAA,QACE;AAAA,QACA,SAAS,EAAE,QAAQ,KAAK,IAAI,EAAE,QAAQ,MAAM;AAAA,QAC5C,SAAS,MAAM;AAAA,MACjB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,mCAAmC,IAAI,GAAG;AAAA,QAC1C;AAAA,MACF;AACA,WAAK,KAAK,EAAE,KAAK,MAAM,wBAAwB,KAAK,EAAE,CAAC;AACvD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,mCAAmC,IAAI,GAAG;AAAA,QAC1C;AAAA,MACF;AACA,WAAK,KAAK,EAAE,KAAK,MAAM,wBAAwB,KAAK,EAAE,CAAC;AACvD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,cAAc,WAAW,OAAO;AAC7C,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,mCAAmC,IAAI,GAAG;AAAA,QAC1C;AAAA,MACF;AACA,WAAK,KAAK,MAAM,4BAA4B,KAAK,CAAC;AAClD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,cAAc,WAAW,QAAQ;AAC9C,YAAM,OAAO,MAAM,aAA2C,KAAK,GAAG;AACtE,UAAI,CAAC,kCAAkC,IAAI,GAAG;AAC5C,eAAO,uCAAuC,GAAG;AAAA,MACnD;AACA,UAAI,CAAC,MAAM,KAAK,KAAK,GAAG;AACtB,aAAK,KAAK,EAAE,OAAO,kBAAkB,GAAG,GAAG;AAC3C,eAAO;AAAA,MACT;AACA,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,WAAK,KAAK;AAAA,QACR,KAAK,MAAM,4BAA4B;AAAA,UACrC,IAAI;AAAA,UACJ,KAAK,KAAK;AAAA,QACZ,CAAC;AAAA,MACH,CAAC;AACD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,YAAM,OAAO,MAAM,aAA2C,KAAK,GAAG;AACtE,UAAI,CAAC,kCAAkC,IAAI,GAAG;AAC5C,eAAO,uCAAuC,GAAG;AAAA,MACnD;AACA,UAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,aAAK,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAC9C,eAAO;AAAA,MACT;AACA,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,8CAAwC,KAAK,QAAQ,QAAQ,SAAS;AACtE,WAAK,KAAK;AAAA,QACR,QAAQ,MAAM,4BAA4B;AAAA,UACxC,IAAI;AAAA,UACJ,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH,CAAC;AACD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,SAAS,gCAAgC,OAAO,OAAO;AAC7D,SAAK,KAAK,EAAE,OAAO,QAAQ,GAAG,MAAM;AACpC,WAAO;AAAA,EACT;AACF;AAEO,MAAM,gCAGR;AAAA,EACH,EAAE,MAAM,OAAO,MAAM,yBAAyB;AAAA,EAC9C,EAAE,MAAM,QAAQ,MAAM,iCAAiC;AAAA,EACvD,EAAE,MAAM,OAAO,MAAM,gCAAgC;AAAA,EACrD,EAAE,MAAM,OAAO,MAAM,8BAA8B;AAAA,EACnD,EAAE,MAAM,QAAQ,MAAM,8BAA8B;AAAA,EACpD,EAAE,MAAM,UAAU,MAAM,qCAAqC;AAAA,EAC7D,EAAE,MAAM,QAAQ,MAAM,0CAA0C;AAAA,EAChE,EAAE,MAAM,QAAQ,MAAM,0CAA0C;AAAA,EAChE,EAAE,MAAM,OAAO,MAAM,8CAA8C;AAAA,EACnE,EAAE,MAAM,QAAQ,MAAM,8CAA8C;AAAA,EACpE,EAAE,MAAM,QAAQ,MAAM,0CAA0C;AAClE;","names":[]}