@quenty/studio-bridge 0.1.1-canary.656.73a74af.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 (124) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +179 -0
  4. package/dist/src/cli/args/global-args.d.ts +10 -0
  5. package/dist/src/cli/args/global-args.d.ts.map +1 -0
  6. package/dist/src/cli/args/global-args.js +2 -0
  7. package/dist/src/cli/args/global-args.js.map +1 -0
  8. package/dist/src/cli/cli.d.ts +11 -0
  9. package/dist/src/cli/cli.d.ts.map +1 -0
  10. package/dist/src/cli/cli.js +65 -0
  11. package/dist/src/cli/cli.js.map +1 -0
  12. package/dist/src/cli/commands/exec-command.d.ts +15 -0
  13. package/dist/src/cli/commands/exec-command.d.ts.map +1 -0
  14. package/dist/src/cli/commands/exec-command.js +35 -0
  15. package/dist/src/cli/commands/exec-command.js.map +1 -0
  16. package/dist/src/cli/commands/run-command.d.ts +15 -0
  17. package/dist/src/cli/commands/run-command.d.ts.map +1 -0
  18. package/dist/src/cli/commands/run-command.js +47 -0
  19. package/dist/src/cli/commands/run-command.js.map +1 -0
  20. package/dist/src/cli/commands/terminal/terminal-command.d.ts +17 -0
  21. package/dist/src/cli/commands/terminal/terminal-command.d.ts.map +1 -0
  22. package/dist/src/cli/commands/terminal/terminal-command.js +41 -0
  23. package/dist/src/cli/commands/terminal/terminal-command.js.map +1 -0
  24. package/dist/src/cli/commands/terminal/terminal-editor.d.ts +43 -0
  25. package/dist/src/cli/commands/terminal/terminal-editor.d.ts.map +1 -0
  26. package/dist/src/cli/commands/terminal/terminal-editor.js +430 -0
  27. package/dist/src/cli/commands/terminal/terminal-editor.js.map +1 -0
  28. package/dist/src/cli/commands/terminal/terminal-mode.d.ts +13 -0
  29. package/dist/src/cli/commands/terminal/terminal-mode.d.ts.map +1 -0
  30. package/dist/src/cli/commands/terminal/terminal-mode.js +141 -0
  31. package/dist/src/cli/commands/terminal/terminal-mode.js.map +1 -0
  32. package/dist/src/cli/index.d.ts +2 -0
  33. package/dist/src/cli/index.d.ts.map +1 -0
  34. package/dist/src/cli/index.js +2 -0
  35. package/dist/src/cli/index.js.map +1 -0
  36. package/dist/src/cli/script-executor.d.ts +23 -0
  37. package/dist/src/cli/script-executor.d.ts.map +1 -0
  38. package/dist/src/cli/script-executor.js +112 -0
  39. package/dist/src/cli/script-executor.js.map +1 -0
  40. package/dist/src/index.d.ts +20 -0
  41. package/dist/src/index.d.ts.map +1 -0
  42. package/dist/src/index.js +18 -0
  43. package/dist/src/index.js.map +1 -0
  44. package/dist/src/plugin/index.d.ts +3 -0
  45. package/dist/src/plugin/index.d.ts.map +1 -0
  46. package/dist/src/plugin/index.js +2 -0
  47. package/dist/src/plugin/index.js.map +1 -0
  48. package/dist/src/plugin/plugin-injector.d.ts +19 -0
  49. package/dist/src/plugin/plugin-injector.d.ts.map +1 -0
  50. package/dist/src/plugin/plugin-injector.js +57 -0
  51. package/dist/src/plugin/plugin-injector.js.map +1 -0
  52. package/dist/src/plugin/plugin-injector.test.d.ts +2 -0
  53. package/dist/src/plugin/plugin-injector.test.d.ts.map +1 -0
  54. package/dist/src/plugin/plugin-injector.test.js +31 -0
  55. package/dist/src/plugin/plugin-injector.test.js.map +1 -0
  56. package/dist/src/process/index.d.ts +5 -0
  57. package/dist/src/process/index.d.ts.map +1 -0
  58. package/dist/src/process/index.js +3 -0
  59. package/dist/src/process/index.js.map +1 -0
  60. package/dist/src/process/place-builder.d.ts +16 -0
  61. package/dist/src/process/place-builder.d.ts.map +1 -0
  62. package/dist/src/process/place-builder.js +45 -0
  63. package/dist/src/process/place-builder.js.map +1 -0
  64. package/dist/src/process/studio-process-manager.d.ts +25 -0
  65. package/dist/src/process/studio-process-manager.d.ts.map +1 -0
  66. package/dist/src/process/studio-process-manager.js +121 -0
  67. package/dist/src/process/studio-process-manager.js.map +1 -0
  68. package/dist/src/process/studio-process-manager.test.d.ts +2 -0
  69. package/dist/src/process/studio-process-manager.test.d.ts.map +1 -0
  70. package/dist/src/process/studio-process-manager.test.js +42 -0
  71. package/dist/src/process/studio-process-manager.test.js.map +1 -0
  72. package/dist/src/server/index.d.ts +5 -0
  73. package/dist/src/server/index.d.ts.map +1 -0
  74. package/dist/src/server/index.js +3 -0
  75. package/dist/src/server/index.js.map +1 -0
  76. package/dist/src/server/studio-bridge-server.d.ts +67 -0
  77. package/dist/src/server/studio-bridge-server.d.ts.map +1 -0
  78. package/dist/src/server/studio-bridge-server.js +338 -0
  79. package/dist/src/server/studio-bridge-server.js.map +1 -0
  80. package/dist/src/server/studio-bridge-server.test.d.ts +9 -0
  81. package/dist/src/server/studio-bridge-server.test.d.ts.map +1 -0
  82. package/dist/src/server/studio-bridge-server.test.js +471 -0
  83. package/dist/src/server/studio-bridge-server.test.js.map +1 -0
  84. package/dist/src/server/web-socket-protocol.d.ts +48 -0
  85. package/dist/src/server/web-socket-protocol.d.ts.map +1 -0
  86. package/dist/src/server/web-socket-protocol.js +59 -0
  87. package/dist/src/server/web-socket-protocol.js.map +1 -0
  88. package/dist/src/server/web-socket-protocol.smoke.test.d.ts +6 -0
  89. package/dist/src/server/web-socket-protocol.smoke.test.d.ts.map +1 -0
  90. package/dist/src/server/web-socket-protocol.smoke.test.js +187 -0
  91. package/dist/src/server/web-socket-protocol.smoke.test.js.map +1 -0
  92. package/dist/src/server/web-socket-protocol.test.d.ts +2 -0
  93. package/dist/src/server/web-socket-protocol.test.d.ts.map +1 -0
  94. package/dist/src/server/web-socket-protocol.test.js +150 -0
  95. package/dist/src/server/web-socket-protocol.test.js.map +1 -0
  96. package/dist/tsconfig.tsbuildinfo +1 -0
  97. package/package.json +41 -0
  98. package/src/cli/args/global-args.ts +9 -0
  99. package/src/cli/cli.ts +78 -0
  100. package/src/cli/commands/exec-command.ts +48 -0
  101. package/src/cli/commands/run-command.ts +63 -0
  102. package/src/cli/commands/terminal/terminal-command.ts +54 -0
  103. package/src/cli/commands/terminal/terminal-editor.ts +500 -0
  104. package/src/cli/commands/terminal/terminal-mode.ts +184 -0
  105. package/src/cli/index.ts +1 -0
  106. package/src/cli/script-executor.ts +149 -0
  107. package/src/index.ts +43 -0
  108. package/src/plugin/index.ts +2 -0
  109. package/src/plugin/plugin-injector.test.ts +35 -0
  110. package/src/plugin/plugin-injector.ts +91 -0
  111. package/src/process/index.ts +9 -0
  112. package/src/process/place-builder.ts +63 -0
  113. package/src/process/studio-process-manager.test.ts +53 -0
  114. package/src/process/studio-process-manager.ts +143 -0
  115. package/src/server/index.ts +20 -0
  116. package/src/server/studio-bridge-server.test.ts +623 -0
  117. package/src/server/studio-bridge-server.ts +483 -0
  118. package/src/server/web-socket-protocol.smoke.test.ts +246 -0
  119. package/src/server/web-socket-protocol.test.ts +185 -0
  120. package/src/server/web-socket-protocol.ts +132 -0
  121. package/templates/default-test-place/default.project.json +11 -0
  122. package/templates/studio-bridge-plugin/default.project.json +6 -0
  123. package/templates/studio-bridge-plugin/plugin-template.server.lua +194 -0
  124. package/tsconfig.json +16 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## 0.1.1-canary.656.73a74af.0 (2026-02-17)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add a terminal mode to studio-bridge for easier debugging ([92cdca9](https://github.com/Quenty/NevermoreEngine/commit/92cdca97ee6ece9a8622559f8846f59b831788de))
12
+ * Add initial studio-bridge package that can replace run-in-roblox ([aec737f](https://github.com/Quenty/NevermoreEngine/commit/aec737fd0eb3f2b045fc469a2b46f833de84a24b))
13
+ * Refactor studio bridge ([8afe642](https://github.com/Quenty/NevermoreEngine/commit/8afe6424b6635eaa0155734c085934051de88da6))
14
+ * Use reporting system for studio bridge too (a bit ugly) ([20b675c](https://github.com/Quenty/NevermoreEngine/commit/20b675cb22cb46c88b556f4afdda2700dd1258dd))
15
+ * Use yargs in studio-bridge cli ([2203601](https://github.com/Quenty/NevermoreEngine/commit/220360168e79d57cd576150134949d8f2325a38f))
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2014-2026 James Onnen (Quenty)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @quenty/studio-bridge
2
+
3
+ WebSocket-based bridge for running Luau scripts in Roblox Studio.
4
+
5
+ ## How It Works
6
+
7
+ ```
8
+ ┌─────────────┐ WebSocket ┌──────────────────┐
9
+ │ Node.js │◄───────────────►│ Studio Plugin │
10
+ │ Server │ ws://localhost │ (auto-injected) │
11
+ │ │ │ │
12
+ │ 1. Start WS │ │ 4. Connect + hello│
13
+ │ 2. Inject │ │ 5. Run script │
14
+ │ plugin │ │ 6. Stream output │
15
+ │ 3. Launch │ │ 7. scriptComplete │
16
+ │ Studio │ │ │
17
+ └─────────────┘ └──────────────────┘
18
+ ```
19
+
20
+ 1. Start WebSocket server on a random port
21
+ 2. Build a `.rbxm` plugin via `rojo build --plugin` with the port and session ID baked in
22
+ 3. Plugin is placed in Studio's plugins folder, launch Studio
23
+ 4. Plugin connects, handshakes with session ID
24
+ 5. Server sends `execute` with Luau script, plugin runs it via `loadstring()` + `xpcall()`
25
+ 6. Plugin streams `LogService` output back as batched messages
26
+ 7. Plugin sends `scriptComplete` — server can send another `execute` or `shutdown`
27
+
28
+ The session ID (random UUID) prevents stale plugins from previous runs from interfering.
29
+
30
+ ## CLI
31
+
32
+ ```bash
33
+ # Run a script file
34
+ studio-bridge run test.lua
35
+
36
+ # Run inline script
37
+ studio-bridge exec 'print("hello world")'
38
+
39
+ # With a specific place file (builds a minimal place via rojo if omitted)
40
+ studio-bridge run test.lua --place build/test.rbxl
41
+
42
+ # Interactive terminal mode (keeps Studio alive between executions)
43
+ studio-bridge terminal
44
+
45
+ # Terminal mode with initial script
46
+ studio-bridge terminal --place build/test.rbxl --script init.lua
47
+
48
+ # Debug output
49
+ studio-bridge run test.lua --verbose
50
+ ```
51
+
52
+ ### Global Options
53
+
54
+ | Option | Alias | Default | Description |
55
+ |--------|-------|---------|-------------|
56
+ | `--place` | `-p` | — | Path to a `.rbxl` place file (builds minimal place via rojo if omitted) |
57
+ | `--timeout` | — | `120000` | Timeout in milliseconds |
58
+ | `--verbose` | — | `false` | Show internal debug output |
59
+ | `--logs` / `--no-logs` | — | `true` | Show execution logs in spinner mode |
60
+
61
+ ### Terminal Mode
62
+
63
+ Keeps Studio alive and provides an interactive REPL. Type Luau, see results, repeat — no re-launch between executions.
64
+
65
+ ```
66
+ $ studio-bridge terminal --place build/test.rbxl
67
+ Studio connected.
68
+
69
+ ────────────────────────────────────────────────────────
70
+ ❯ print("hello")
71
+ ────────────────────────────────────────────────────────
72
+ ctrl+enter to run · ctrl+c to clear · .help for commands
73
+ ```
74
+
75
+ | Key | Action |
76
+ |-----|--------|
77
+ | Enter | New line |
78
+ | Ctrl+Enter | Execute buffer |
79
+ | Ctrl+C | Clear buffer (exit if empty) |
80
+ | Ctrl+D | Exit |
81
+
82
+ | Command | Description |
83
+ |---------|-------------|
84
+ | `.help` | Show keybindings and commands |
85
+ | `.exit` | Exit terminal mode |
86
+ | `.run <file>` | Execute a Luau file |
87
+ | `.clear` | Clear the editor buffer |
88
+
89
+ ## API
90
+
91
+ ```typescript
92
+ import { StudioBridge } from '@quenty/studio-bridge';
93
+
94
+ const bridge = new StudioBridge({ placePath: './build/test.rbxl' });
95
+ await bridge.startAsync();
96
+
97
+ const result = await bridge.executeAsync({
98
+ scriptContent: 'print("Hello from studio-bridge!")',
99
+ timeoutMs: 90_000,
100
+ onOutput: (level, body) => console.log(`[${level}] ${body}`),
101
+ });
102
+
103
+ console.log(result.success); // boolean
104
+ console.log(result.logs); // all captured output, newline-separated
105
+
106
+ // Can call executeAsync() again without relaunching Studio
107
+ await bridge.stopAsync();
108
+ ```
109
+
110
+ ### `StudioBridgeServerOptions`
111
+
112
+ | Field | Type | Default | Description |
113
+ |-------|------|---------|-------------|
114
+ | `placePath` | `string` | — | Path to `.rbxl` file (auto-builds via rojo if omitted) |
115
+ | `timeoutMs` | `number` | `120_000` | Default timeout for operations |
116
+ | `onPhase` | `(phase) => void` | — | Progress callback: `building`, `launching`, `connecting`, `executing`, `done` |
117
+ | `sessionId` | `string` | auto UUID | Session ID for concurrent isolation |
118
+
119
+ ### `ExecuteOptions`
120
+
121
+ | Field | Type | Default | Description |
122
+ |-------|------|---------|-------------|
123
+ | `scriptContent` | `string` | required | Luau source code to execute |
124
+ | `timeoutMs` | `number` | inherited | Timeout for this execution |
125
+ | `onOutput` | `(level, body) => void` | — | Called for each log message |
126
+
127
+ ### `StudioBridgeResult`
128
+
129
+ | Field | Type | Description |
130
+ |-------|------|-------------|
131
+ | `success` | `boolean` | `true` if the script ran without errors |
132
+ | `logs` | `string` | All captured output, newline-separated |
133
+
134
+ ## WebSocket Protocol
135
+
136
+ All messages are JSON: `{ "type": string, "payload": object }`.
137
+
138
+ **Plugin to Server:**
139
+
140
+ | Type | Payload | Description |
141
+ |------|---------|-------------|
142
+ | `hello` | `{ sessionId }` | Handshake |
143
+ | `output` | `{ messages: [{ level, body }] }` | Batched log output |
144
+ | `scriptComplete` | `{ success, error? }` | Script finished |
145
+
146
+ Output levels: `"Print"`, `"Info"`, `"Warning"`, `"Error"` (matches `Enum.MessageType`).
147
+
148
+ **Server to Plugin:**
149
+
150
+ | Type | Payload | Description |
151
+ |------|---------|-------------|
152
+ | `welcome` | `{ sessionId }` | Handshake accepted |
153
+ | `execute` | `{ script }` | Luau script to run |
154
+ | `shutdown` | `{}` | Disconnect |
155
+
156
+ ## Testing
157
+
158
+ ```bash
159
+ pnpm test # Unit tests (no Studio needed)
160
+ pnpm test:watch # Watch mode
161
+ pnpm test:integration # End-to-end (requires Studio)
162
+ ```
163
+
164
+ | Layer | What it tests | Studio? |
165
+ |-------|--------------|---------|
166
+ | Unit (`pnpm test`) | Protocol, template substitution, path resolution, WebSocket lifecycle | No |
167
+ | Integration (`pnpm test:integration`) | Full pipeline: rojo build, plugin injection, Studio launch, output capture | Yes |
168
+
169
+ ## Platform Support
170
+
171
+ | Platform | Studio Location | Plugins Folder |
172
+ |----------|----------------|----------------|
173
+ | Windows | `%LOCALAPPDATA%\Roblox\Versions\*\RobloxStudioBeta.exe` | `%LOCALAPPDATA%\Roblox\Plugins\` |
174
+ | macOS | `/Applications/RobloxStudio.app/Contents/MacOS/RobloxStudioBeta` | `~/Documents/Roblox/Plugins/` |
175
+
176
+ ## Future Plans
177
+
178
+ - **StudioTestService integration** — Use `ExecuteRunModeAsync()` / `EndTest()` for better isolation vs. `loadstring()`
179
+ - **Structured test results** — Protocol extension for typed result messages instead of log parsing
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Global arguments available to all studio-bridge commands.
3
+ */
4
+ export interface StudioBridgeGlobalArgs {
5
+ verbose: boolean;
6
+ place?: string;
7
+ timeout: number;
8
+ logs: boolean;
9
+ }
10
+ //# sourceMappingURL=global-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-args.d.ts","sourceRoot":"","sources":["../../../../src/cli/args/global-args.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=global-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-args.js","sourceRoot":"","sources":["../../../../src/cli/args/global-args.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for @quenty/studio-bridge.
4
+ *
5
+ * Usage:
6
+ * studio-bridge run <file.lua>
7
+ * studio-bridge exec 'print("hello")'
8
+ * studio-bridge terminal [--script <file.lua>]
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for @quenty/studio-bridge.
4
+ *
5
+ * Usage:
6
+ * studio-bridge run <file.lua>
7
+ * studio-bridge exec 'print("hello")'
8
+ * studio-bridge terminal [--script <file.lua>]
9
+ */
10
+ import yargs from 'yargs';
11
+ import { hideBin } from 'yargs/helpers';
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname, join } from 'path';
14
+ import { OutputHelper } from '@quenty/cli-output-helpers';
15
+ import { VersionChecker } from '@quenty/nevermore-cli-helpers';
16
+ import { RunCommand } from './commands/run-command.js';
17
+ import { ExecCommand } from './commands/exec-command.js';
18
+ import { TerminalCommand } from './commands/terminal/terminal-command.js';
19
+ const versionData = await VersionChecker.checkForUpdatesAsync({
20
+ humanReadableName: 'Studio Bridge',
21
+ packageName: '@quenty/studio-bridge',
22
+ registryUrl: 'https://registry.npmjs.org/',
23
+ packageJsonPath: join(dirname(fileURLToPath(import.meta.url)), '../../../package.json'),
24
+ });
25
+ yargs(hideBin(process.argv))
26
+ .scriptName('studio-bridge')
27
+ .version((versionData
28
+ ? VersionChecker.getVersionDisplayName(versionData)
29
+ : undefined))
30
+ .option('place', {
31
+ alias: 'p',
32
+ description: 'Path to a .rbxl place file (builds a minimal place via rojo if omitted)',
33
+ type: 'string',
34
+ global: true,
35
+ })
36
+ .option('timeout', {
37
+ description: 'Timeout in milliseconds',
38
+ type: 'number',
39
+ default: 120_000,
40
+ global: true,
41
+ })
42
+ .option('verbose', {
43
+ description: 'Show internal debug output',
44
+ type: 'boolean',
45
+ default: false,
46
+ global: true,
47
+ })
48
+ .option('logs', {
49
+ description: 'Show execution logs in spinner mode',
50
+ type: 'boolean',
51
+ default: true,
52
+ global: true,
53
+ })
54
+ .middleware((argv) => {
55
+ OutputHelper.setVerbose(argv.verbose);
56
+ })
57
+ .usage(OutputHelper.formatInfo('Usage: $0 <command> [options]'))
58
+ .command(new ExecCommand())
59
+ .command(new RunCommand())
60
+ .command(new TerminalCommand())
61
+ .recommendCommands()
62
+ .demandCommand(1, OutputHelper.formatHint("Hint: See 'studio-bridge help' for more help"))
63
+ .wrap(null)
64
+ .strict().argv;
65
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE1E,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,oBAAoB,CAAC;IAC5D,iBAAiB,EAAE,eAAe;IAClC,WAAW,EAAE,uBAAuB;IACpC,WAAW,EAAE,6BAA6B;IAC1C,eAAe,EAAE,IAAI,CACnB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,uBAAuB,CACxB;CACF,CAAC,CAAC;AAEH,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB,UAAU,CAAC,eAAe,CAAC;KAC3B,OAAO,CACN,CAAC,WAAW;IACV,CAAC,CAAC,cAAc,CAAC,qBAAqB,CAAC,WAAW,CAAC;IACnD,CAAC,CAAC,SAAS,CAAQ,CACtB;KACA,MAAM,CAAC,OAAO,EAAE;IACf,KAAK,EAAE,GAAG;IACV,WAAW,EACT,yEAAyE;IAC3E,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,IAAI;CACb,CAAC;KACD,MAAM,CAAC,SAAS,EAAE;IACjB,WAAW,EAAE,yBAAyB;IACtC,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,IAAI;CACb,CAAC;KACD,MAAM,CAAC,SAAS,EAAE;IACjB,WAAW,EAAE,4BAA4B;IACzC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,IAAI;CACb,CAAC;KACD,MAAM,CAAC,MAAM,EAAE;IACd,WAAW,EAAE,qCAAqC;IAClD,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;CACb,CAAC;KACD,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE;IACnB,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAkB,CAAC,CAAC;AACnD,CAAC,CAAC;KACD,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,+BAA+B,CAAC,CAAC;KAC/D,OAAO,CAAC,IAAI,WAAW,EAAS,CAAC;KACjC,OAAO,CAAC,IAAI,UAAU,EAAS,CAAC;KAChC,OAAO,CAAC,IAAI,eAAe,EAAS,CAAC;KACrC,iBAAiB,EAAE;KACnB,aAAa,CACZ,CAAC,EACD,YAAY,CAAC,UAAU,CAAC,8CAA8C,CAAC,CACxE;KACA,IAAI,CAAC,IAAI,CAAC;KACV,MAAM,EAAE,CAAC,IAAI,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `studio-bridge exec <code>` — execute inline Luau code in Roblox Studio.
3
+ */
4
+ import { Argv, CommandModule } from 'yargs';
5
+ import type { StudioBridgeGlobalArgs } from '../args/global-args.js';
6
+ export interface ExecArgs extends StudioBridgeGlobalArgs {
7
+ code: string;
8
+ }
9
+ export declare class ExecCommand<T> implements CommandModule<T, ExecArgs> {
10
+ command: string;
11
+ describe: string;
12
+ builder: (args: Argv<T>) => Argv<ExecArgs>;
13
+ handler: (args: ExecArgs) => Promise<void>;
14
+ }
15
+ //# sourceMappingURL=exec-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/exec-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAMrE,MAAM,WAAW,QAAS,SAAQ,sBAAsB;IACtD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC;IACxD,OAAO,SAAiB;IACxB,QAAQ,SAA+C;IAEvD,OAAO,GAAI,MAAM,IAAI,CAAC,CAAC,CAAC,KAOd,IAAI,CAAC,QAAQ,CAAC,CAC7B;IAEK,OAAO,GAAU,MAAM,QAAQ,mBAgBpC;CACH"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * `studio-bridge exec <code>` — execute inline Luau code in Roblox Studio.
3
+ */
4
+ import { OutputHelper } from '@quenty/cli-output-helpers';
5
+ import { executeScriptAsync, resolvePlacePathAsync, } from '../script-executor.js';
6
+ export class ExecCommand {
7
+ command = 'exec <code>';
8
+ describe = 'Execute inline Luau code in Roblox Studio';
9
+ builder = (args) => {
10
+ args.positional('code', {
11
+ describe: 'Luau code to execute',
12
+ type: 'string',
13
+ demandOption: true,
14
+ });
15
+ return args;
16
+ };
17
+ handler = async (args) => {
18
+ try {
19
+ const placePath = await resolvePlacePathAsync(args.place);
20
+ await executeScriptAsync({
21
+ scriptContent: args.code,
22
+ packageName: 'script',
23
+ placePath,
24
+ timeoutMs: args.timeout,
25
+ verbose: args.verbose,
26
+ showLogs: args.logs,
27
+ });
28
+ }
29
+ catch (err) {
30
+ OutputHelper.error(err instanceof Error ? err.message : String(err));
31
+ process.exit(1);
32
+ }
33
+ };
34
+ }
35
+ //# sourceMappingURL=exec-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-command.js","sourceRoot":"","sources":["../../../../src/cli/commands/exec-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,OAAO,WAAW;IACf,OAAO,GAAG,aAAa,CAAC;IACxB,QAAQ,GAAG,2CAA2C,CAAC;IAEvD,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YACtB,QAAQ,EAAE,sBAAsB;YAChC,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QAEH,OAAO,IAAsB,CAAC;IAChC,CAAC,CAAC;IAEK,OAAO,GAAG,KAAK,EAAE,IAAc,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE1D,MAAM,kBAAkB,CAAC;gBACvB,aAAa,EAAE,IAAI,CAAC,IAAI;gBACxB,WAAW,EAAE,QAAQ;gBACrB,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,OAAO;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,IAAI;aACpB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;CACH"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `studio-bridge run <file>` — execute a Luau script file in Roblox Studio.
3
+ */
4
+ import { Argv, CommandModule } from 'yargs';
5
+ import type { StudioBridgeGlobalArgs } from '../args/global-args.js';
6
+ export interface RunArgs extends StudioBridgeGlobalArgs {
7
+ file: string;
8
+ }
9
+ export declare class RunCommand<T> implements CommandModule<T, RunArgs> {
10
+ command: string;
11
+ describe: string;
12
+ builder: (args: Argv<T>) => Argv<RunArgs>;
13
+ handler: (args: RunArgs) => Promise<void>;
14
+ }
15
+ //# sourceMappingURL=run-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/run-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAMrE,MAAM,WAAW,OAAQ,SAAQ,sBAAsB;IACrD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC;IACtD,OAAO,SAAgB;IACvB,QAAQ,SAAiD;IAEzD,OAAO,GAAI,MAAM,IAAI,CAAC,CAAC,CAAC,KAOd,IAAI,CAAC,OAAO,CAAC,CAC5B;IAEK,OAAO,GAAU,MAAM,OAAO,mBA6BnC;CACH"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * `studio-bridge run <file>` — execute a Luau script file in Roblox Studio.
3
+ */
4
+ import * as fs from 'fs/promises';
5
+ import * as path from 'path';
6
+ import { OutputHelper } from '@quenty/cli-output-helpers';
7
+ import { executeScriptAsync, resolvePlacePathAsync, } from '../script-executor.js';
8
+ export class RunCommand {
9
+ command = 'run <file>';
10
+ describe = 'Execute a Luau script file in Roblox Studio';
11
+ builder = (args) => {
12
+ args.positional('file', {
13
+ describe: 'Path to a Luau script file',
14
+ type: 'string',
15
+ demandOption: true,
16
+ });
17
+ return args;
18
+ };
19
+ handler = async (args) => {
20
+ try {
21
+ const scriptPath = path.resolve(args.file);
22
+ let scriptContent;
23
+ try {
24
+ scriptContent = await fs.readFile(scriptPath, 'utf-8');
25
+ }
26
+ catch {
27
+ OutputHelper.error(`Could not read script file: ${scriptPath}`);
28
+ process.exit(1);
29
+ }
30
+ const placePath = await resolvePlacePathAsync(args.place);
31
+ const packageName = path.basename(args.file, path.extname(args.file));
32
+ await executeScriptAsync({
33
+ scriptContent,
34
+ packageName,
35
+ placePath,
36
+ timeoutMs: args.timeout,
37
+ verbose: args.verbose,
38
+ showLogs: args.logs,
39
+ });
40
+ }
41
+ catch (err) {
42
+ OutputHelper.error(err instanceof Error ? err.message : String(err));
43
+ process.exit(1);
44
+ }
45
+ };
46
+ }
47
+ //# sourceMappingURL=run-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../../../src/cli/commands/run-command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,OAAO,UAAU;IACd,OAAO,GAAG,YAAY,CAAC;IACvB,QAAQ,GAAG,6CAA6C,CAAC;IAEzD,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YACtB,QAAQ,EAAE,4BAA4B;YACtC,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QAEH,OAAO,IAAqB,CAAC;IAC/B,CAAC,CAAC;IAEK,OAAO,GAAG,KAAK,EAAE,IAAa,EAAE,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,aAAqB,CAAC;YAC1B,IAAI,CAAC;gBACH,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY,CAAC,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;gBAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAC/B,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CACxB,CAAC;YAEF,MAAM,kBAAkB,CAAC;gBACvB,aAAa;gBACb,WAAW;gBACX,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,OAAO;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,IAAI;aACpB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;CACH"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `studio-bridge terminal` — interactive REPL mode for executing Luau
3
+ * scripts repeatedly in a persistent Studio session.
4
+ */
5
+ import { Argv, CommandModule } from 'yargs';
6
+ import type { StudioBridgeGlobalArgs } from '../../args/global-args.js';
7
+ export interface TerminalArgs extends StudioBridgeGlobalArgs {
8
+ script?: string;
9
+ 'script-text'?: string;
10
+ }
11
+ export declare class TerminalCommand<T> implements CommandModule<T, TerminalArgs> {
12
+ command: string;
13
+ describe: string;
14
+ builder: (args: Argv<T>) => Argv<TerminalArgs>;
15
+ handler: (args: TerminalArgs) => Promise<void>;
16
+ }
17
+ //# sourceMappingURL=terminal-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-command.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/terminal/terminal-command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGxE,MAAM,WAAW,YAAa,SAAQ,sBAAsB;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,EAAE,YAAY,CAAC;IAChE,OAAO,SAAc;IACrB,QAAQ,SACgE;IAExE,OAAO,GAAI,MAAM,IAAI,CAAC,CAAC,CAAC,KAad,IAAI,CAAC,YAAY,CAAC,CACjC;IAEK,OAAO,GAAU,MAAM,YAAY,mBAgBxC;CACH"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * `studio-bridge terminal` — interactive REPL mode for executing Luau
3
+ * scripts repeatedly in a persistent Studio session.
4
+ */
5
+ import { OutputHelper } from '@quenty/cli-output-helpers';
6
+ import { resolvePlacePathAsync } from '../../script-executor.js';
7
+ export class TerminalCommand {
8
+ command = 'terminal';
9
+ describe = 'Interactive terminal mode — keep Studio alive and execute scripts via REPL';
10
+ builder = (args) => {
11
+ args.option('script', {
12
+ alias: 's',
13
+ describe: 'Path to a Luau script to run on connect',
14
+ type: 'string',
15
+ });
16
+ args.option('script-text', {
17
+ alias: 't',
18
+ describe: 'Inline Luau code to run on connect',
19
+ type: 'string',
20
+ });
21
+ return args;
22
+ };
23
+ handler = async (args) => {
24
+ try {
25
+ const placePath = await resolvePlacePathAsync(args.place);
26
+ const { runTerminalMode } = await import('./terminal-mode.js');
27
+ await runTerminalMode({
28
+ placePath,
29
+ scriptPath: args.script,
30
+ scriptText: args['script-text'],
31
+ timeoutMs: args.timeout,
32
+ verbose: args.verbose,
33
+ });
34
+ }
35
+ catch (err) {
36
+ OutputHelper.error(err instanceof Error ? err.message : String(err));
37
+ process.exit(1);
38
+ }
39
+ };
40
+ }
41
+ //# sourceMappingURL=terminal-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-command.js","sourceRoot":"","sources":["../../../../../src/cli/commands/terminal/terminal-command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAOjE,MAAM,OAAO,eAAe;IACnB,OAAO,GAAG,UAAU,CAAC;IACrB,QAAQ,GACb,4EAA4E,CAAC;IAExE,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;QACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YACpB,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,yCAAyC;YACnD,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE;YACzB,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,oCAAoC;YAC9C,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,OAAO,IAA0B,CAAC;IACpC,CAAC,CAAC;IAEK,OAAO,GAAG,KAAK,EAAE,IAAkB,EAAE,EAAE;QAC5C,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE1D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC/D,MAAM,eAAe,CAAC;gBACpB,SAAS;gBACT,UAAU,EAAE,IAAI,CAAC,MAAM;gBACvB,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC;gBAC/B,SAAS,EAAE,IAAI,CAAC,OAAO;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;CACH"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Raw-mode multi-line terminal editor with ANSI rendering.
3
+ *
4
+ * Provides a Claude Code-inspired input UI with:
5
+ * - Multi-line editing (Enter = newline, Ctrl+Enter = submit)
6
+ * - Cursor movement (arrows, Home/End)
7
+ * - Dot-commands (.help, .exit, .run <file>, .clear)
8
+ * - Status bar with keybinding hints
9
+ */
10
+ import { EventEmitter } from 'events';
11
+ export interface TerminalEditorEvents {
12
+ submit: [buffer: string];
13
+ exit: [];
14
+ }
15
+ export declare class TerminalEditor extends EventEmitter {
16
+ private _lines;
17
+ private _cursorRow;
18
+ private _cursorCol;
19
+ private _renderedLineCount;
20
+ /** Terminal row (0-indexed from top of rendered block) where the cursor sits */
21
+ private _cursorTerminalRow;
22
+ private _active;
23
+ private _onKeypress;
24
+ private _onResize;
25
+ constructor();
26
+ start(): void;
27
+ stop(): void;
28
+ private _handleInput;
29
+ private _bufferText;
30
+ private _insertText;
31
+ private _insertNewline;
32
+ private _deleteBackward;
33
+ private _deleteForward;
34
+ private _moveCursorHorizontal;
35
+ private _moveCursorVertical;
36
+ private _submit;
37
+ private _handleDotCommand;
38
+ private _runFile;
39
+ private _clearEditor;
40
+ private _eraseRendered;
41
+ _render(): void;
42
+ }
43
+ //# sourceMappingURL=terminal-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-editor.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/terminal/terminal-editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAQtC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,IAAI,EAAE,EAAE,CAAC;CACV;AA0BD,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,kBAAkB,CAAK;IAC/B,gFAAgF;IAChF,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,SAAS,CAA2B;;IAU5C,KAAK,IAAI,IAAI;IAkBb,IAAI,IAAI,IAAI;IAgCZ,OAAO,CAAC,YAAY;IA6HpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,iBAAiB;YA+DX,QAAQ;IAiBtB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,cAAc;IAqBtB,OAAO,IAAI,IAAI;CAgDhB"}