@linzumi/cli 0.0.20-beta → 0.0.22-beta

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.
package/README.md CHANGED
@@ -16,21 +16,21 @@
16
16
  ║║ \"/` ___ ;_________║║_.'
17
17
  ║║ ` ^^ ^^ ║║
18
18
  ──────────╨╨─────────────··────··────────╨╨──────────────
19
- your agent, your laptop, PRs in minutes
19
+ your agent, your laptop, coding live
20
20
  ```
21
21
 
22
- Copy this into your terminal from the repo you want changed:
22
+ Copy this into your terminal:
23
23
 
24
24
  ```bash
25
25
  codex --ask-for-approval never --sandbox danger-full-access -- 'Get me up and running with Linzumi from https://linzumi.com/agents.md. Read it with curl.'
26
26
  ```
27
27
 
28
28
  That's the launch path: the first Codex is only the bootstrapper. It
29
- opens the agent instructions, collects the email up front, asks you for
30
- the emailed code when it arrives, connects Linzumi to this repo, creates
31
- the shared support channel, starts a Linzumi Codex session in a work
32
- thread, and opens the browser editor. The Linzumi Codex session does the
33
- branch, test, push, and PR work.
29
+ opens the agent instructions, confirms your email and workspace details,
30
+ asks you for the emailed code when it arrives, creates `/tmp/hello_linzumi`,
31
+ starts that hot-reload app on your computer, creates the shared support
32
+ channel, starts a Linzumi Codex session in a work thread, and opens the
33
+ browser editor pointed at the demo app.
34
34
 
35
35
  The snippet uses automatic command approval and full local process access
36
36
  because the bootstrapper must start a real runner and browser editor on this
@@ -47,26 +47,27 @@ agent" rarely means "works on your laptop." You merge, pull, run the
47
47
  test suite, and find out at 4pm.
48
48
 
49
49
  Linzumi gives it a third home: **your real laptop, in a thread your
50
- team can watch live**. Real env vars, real branches, real dotfiles,
50
+ team can watch live**. Real processes, real env vars, real dotfiles,
51
51
  real teamwork. Diffs land in chat as the agent makes them. Your
52
52
  reviewer opens a browser VS Code pointed at *your folder* and has an
53
53
  opinion before the agent's even finished. You approve from your phone
54
54
  on the way to lunch.
55
55
 
56
- In three minutes from now you'll have it.
56
+ In three minutes from now you'll have it working end to end.
57
57
 
58
58
  ## What you'll have in three minutes
59
59
 
60
- - **An AI coding agent running on your real laptop**, in a thread
61
- your team can read along with.
62
- - **A browser VS Code editor** pointed at the same folder, share-able
63
- by link no clone, no deploy, no "let me push a branch real
64
- quick."
60
+ - **An AI coding agent running on your real laptop**, editing the
61
+ generated Hello Linzumi app in a thread your team can read along with.
62
+ - **A browser VS Code editor** pointed at `/tmp/hello_linzumi`,
63
+ share-able by link with no clone and no deploy.
64
+ - **A tunneled local preview** of the app running on your computer with
65
+ hot reload.
65
66
  - **A private support channel with the Linzumi team**, in case
66
67
  anything goes sideways.
67
68
 
68
- One pasted command. No cloud VM. Your code, your terminal, and your dev
69
- server stay on your laptop the whole time.
69
+ One pasted command. No cloud VM. The editor, agent, and dev server stay
70
+ on your laptop the whole time.
70
71
 
71
72
  ## Manual Runner Setup
72
73
 
@@ -74,9 +75,9 @@ The agent-first command above is the launch path. Use this manual path
74
75
  when you want to connect your laptop yourself before starting work from
75
76
  the browser.
76
77
 
77
- You'll need **Node.js 20+**, **Bun 1.2+**, the **Codex CLI**, and a
78
- Chromium-based browser (Chrome, Edge, Arc, or Brave). Safari mostly
79
- works; live collaboration is smoother in Chromium.
78
+ You'll need **Node.js 20+**, the **Codex CLI**, and a Chromium-based browser
79
+ (Chrome, Edge, Arc, or Brave). Safari mostly works; live collaboration is
80
+ smoother in Chromium.
80
81
 
81
82
  ```bash
82
83
  npm install -g @linzumi/cli@latest
@@ -99,72 +100,79 @@ That's it for manual setup. The rest of this README is detail.
99
100
 
100
101
  That one prompt is the launch path. The canonical agent instructions are
101
102
  hosted at `https://linzumi.com/agents.md`; `https://linzumi.com/skills.md`
102
- stays available for compatibility. The bootstrap agent will collect your
103
- email up front, ask for the emailed code after signup sends it, say
104
- hello to `@sean` in the shared support channel, start the runner in the
105
- current folder, start a Linzumi Codex session in a work thread, and open
106
- the browser editor. The Linzumi Codex session then posts the PR or
107
- reviewable branch.
103
+ stays available for compatibility. The bootstrap agent will confirm your
104
+ email and workspace choice up front, ask for the emailed code after signup
105
+ sends it, say hello to `@sean` in the shared support channel,
106
+ generate `/tmp/hello_linzumi`, start its hot-reload Node server, start the
107
+ runner for that folder, start a Linzumi Codex session in a work thread, and
108
+ open the browser editor. The Linzumi Codex session then adds confetti to the
109
+ demo page while you watch. Workspace names are plain display names from 2 to
110
+ 100 characters; Linzumi generates the URL-safe workspace slug.
108
111
 
109
112
  Under the hood, the npm package exposes these commands for the bootstrap
110
113
  agent to run. They are not extra human setup steps after the one pasted
111
114
  Codex command.
112
115
 
113
116
  ```bash
114
- npx -y @linzumi/cli@latest signup --email alice@example.com --agent-name BuildBot
117
+ npx -y @linzumi/cli@latest signup --email alice@example.com --workspace-name "Alice's Linzumi" --agent-name BuildBot
115
118
  npx -y @linzumi/cli@latest claim --pending <pending_id> --code <XXXX-XXXX>
116
119
  npx -y @linzumi/cli@latest channel post <support_channel_id> "Hello @sean, starting this launch run."
117
- npx -y @linzumi/cli@latest thread new "Hello world PR" --message "Starting now."
118
- npx -y @linzumi/cli@latest agent runner "$PWD" \
119
- --runner-id hello-world-agent \
120
- --allowed-cwd "$PWD" \
121
- --sandbox workspace-write \
120
+ npx -y @linzumi/cli@latest hello
121
+ (cd /tmp/hello_linzumi && npm run dev > /tmp/hello_linzumi/dev.log 2>&1 &)
122
+ npx -y @linzumi/cli@latest thread new "Hello Linzumi confetti" --message "Please add confetti when the page loads."
123
+ npx -y @linzumi/cli@latest agent runner /tmp/hello_linzumi \
124
+ --runner-id hello-linzumi-agent \
125
+ --allowed-cwd /tmp/hello_linzumi \
126
+ --forward-port 8787 \
127
+ --sandbox danger-full-access \
122
128
  --approval-policy never
123
129
  ```
124
130
 
125
131
  The agent-owned runner reads `~/.linzumi/agent-token.json`, uses the
126
132
  workspace/channel scope from the approval flow, trusts only the selected
127
- folder, and listens only to the approving human unless `--listen-user` is
128
- explicitly passed. The bootstrap agent waits for `Runner connected:` before
129
- starting Codex in the Linzumi thread.
133
+ folder, advertises the explicit preview port, and listens only to the
134
+ approving human unless `--listen-user` is explicitly passed. The bootstrap
135
+ agent waits for `Runner connected:` before starting Codex in the Linzumi
136
+ thread.
130
137
 
131
138
  By default, the runner downloads the Linzumi-approved `code-server`
132
139
  runtime for your platform and verifies its checksum before enabling the
133
140
  browser editor. Linux editor launches are wrapped with `bubblewrap`
134
141
  (`bwrap`) for filesystem confinement.
135
142
 
136
- `linzumi claim` also prints `login_url`. That one-time link logs the human
137
- into `#general` in their own email-named workspace. The claim also provisions
138
- `#linzumi-support`, a shared channel with the Linzumi workspace; the bootstrap
139
- agent posts a hello there with the printed `support_channel_id`.
140
- Keep repository work in task threads; use the support channel when signup,
141
- runner, or browser-editor setup gets stuck.
143
+ `linzumi claim` also prints `workspace_name`, `workspace_id`, and `login_url`.
144
+ That one-time link logs the human into `#general` in their own selected
145
+ workspace. The claim also provisions `#linzumi-support`, a shared channel
146
+ connected to Linzumi's workspace so our team can see setup issues from our
147
+ side; the bootstrap agent posts a hello there with the printed
148
+ `support_channel_id`.
149
+ Keep demo work in task threads; use the support channel when signup, runner,
150
+ preview, or browser-editor setup gets stuck.
142
151
 
143
152
  Once the runner is online, the bootstrap agent can ask Linzumi to start
144
153
  Codex and open the browser editor for the same thread and folder:
145
154
 
146
155
  ```bash
147
156
  npx -y @linzumi/cli@latest codex start <thread_id> \
148
- --runner hello-world-agent \
149
- --cwd "$PWD" \
150
- --work-description "You are the Linzumi Codex agent running inside this Linzumi thread on the user's local runner. Create a small hello-world branch in the current repo, make the smallest reviewable change, run the nearest relevant local test or smoke check, push the branch or open a PR, and post the PR URL or exact review branch back in this Linzumi thread. Keep the human updated in the thread. If you are blocked, post the exact blocker instead of pretending the run succeeded."
157
+ --runner hello-linzumi-agent \
158
+ --cwd /tmp/hello_linzumi \
159
+ --work-description "Work only in /tmp/hello_linzumi. Add tasteful confetti when the Hello Linzumi page loads, keep the hot-reload app working on port 8787, and post the exact files changed."
151
160
 
152
161
  npx -y @linzumi/cli@latest editor open <thread_id> \
153
- --runner hello-world-agent \
154
- --cwd "$PWD"
162
+ --runner hello-linzumi-agent \
163
+ --cwd /tmp/hello_linzumi
155
164
  ```
156
165
 
157
- The launch target for this path is zero-to-hello-world-pr+editor in under
158
- 3 minutes, measured from `signup` through PR/reviewable change link plus
159
- browser VS Code readiness.
166
+ The launch target for this path is zero-to-Hello-Linzumi-editor+preview in
167
+ under 3 minutes, measured from `signup` through browser VS Code readiness,
168
+ forwarded preview readiness, and the first visible Codex edit.
160
169
 
161
170
  ## What just happened
162
171
 
163
172
  You now have:
164
173
 
165
- - **A runner.** Your laptop, listed in the workspace, advertising the
166
- folder you started in (and any others you've added to your trusted
167
- list).
174
+ - **A runner.** Your laptop, listed in the workspace, advertising
175
+ `/tmp/hello_linzumi` and the explicit preview port.
168
176
  - **A workspace** you can invite teammates into. They open the same
169
177
  browser app, see the same threads, and can start their own runners
170
178
  on their own machines.
@@ -172,18 +180,16 @@ You now have:
172
180
  **cannot** see your repo contents, your tokens, your Codex
173
181
  transcripts, your editor session, or your other threads. Stuck?
174
182
  Post there — we read it.
175
- - **A browser VS Code editor**, available on demand for any Codex
176
- session, posted into the thread when ready.
183
+ - **A browser VS Code editor**, opened against `/tmp/hello_linzumi` and
184
+ ready for shared editing.
177
185
 
178
186
  ## Three things to try first
179
187
 
180
- 1. **Onboard yourself to a new repo.** *"Explain this project and tell
181
- me how to run it."* Linzumi Codex maps the codebase before you've
182
- opened a single file. Days saved on day one.
188
+ 1. **Watch the demo change live.** The Linzumi Codex session edits the
189
+ generated page, and hot reload shows the change in the tunneled preview.
183
190
  2. **Make a real change without context-switching.** The Codex session
184
191
  running in Linzumi edits files on your disk. Watch the diff land in
185
- chat, or jump into the browser editor (it's VS Code in your browser,
186
- pointed at your folder) and shape it yourself.
192
+ chat, or jump into the browser editor and shape it yourself.
187
193
  3. **Show a teammate something on your screen.** Open the browser
188
194
  editor or share your local dev server through a normal HTTPS
189
195
  link. No exposing localhost, no copy-pasting IPs, no "screenshare
@@ -241,9 +247,6 @@ intentionally. Every action is auditable from the thread.
241
247
  - **`linzumi: command not found`** — your global npm bin folder isn't
242
248
  on `PATH`. Run `npm prefix -g`; add the printed path's `bin` folder
243
249
  to your shell.
244
- - **`bun: command not found`** — install Bun, then rerun
245
- `linzumi start`. The `linzumi` binary is a node shim that delegates
246
- to Bun for fast TypeScript startup.
247
250
  - **`codex: command not found`** — install the Codex CLI, or pass
248
251
  `--codex-bin <path>` to `linzumi start`.
249
252
  - **Browser sign-in opens but never returns to the CLI.** Your browser
@@ -258,7 +261,7 @@ intentionally. Every action is auditable from the thread.
258
261
  ## Pinning a version
259
262
 
260
263
  ```bash
261
- npm install -g @linzumi/cli@0.0.20-beta
264
+ npm install -g @linzumi/cli@0.0.22-beta
262
265
  linzumi --version
263
266
  ```
264
267
 
package/bin/linzumi.js CHANGED
@@ -1,23 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { spawnSync } from "node:child_process";
4
- import { dirname, join } from "node:path";
5
- import { fileURLToPath } from "node:url";
3
+ if (globalThis.WebSocket === undefined) {
4
+ const { WebSocket } = await import("ws");
5
+ globalThis.WebSocket = WebSocket;
6
+ }
6
7
 
7
- const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
- const entrypoint = join(packageRoot, "src", "index.ts");
9
- const result = spawnSync("bun", ["run", entrypoint, ...process.argv.slice(2)], {
10
- cwd: process.cwd(),
11
- env: process.env,
12
- stdio: "inherit",
13
- });
8
+ const { main } = await import("../dist/index.js");
14
9
 
15
- if (result.error !== undefined) {
16
- process.stderr.write(
17
- `failed to launch linzumi runner with bun: ${result.error.message}\n` +
18
- "Install Bun, then rerun the linzumi command.\n",
19
- );
20
- process.exit(127);
10
+ try {
11
+ await main(process.argv.slice(2));
12
+ } catch (error) {
13
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
14
+ process.exit(1);
21
15
  }
22
-
23
- process.exit(result.status ?? 1);
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="4096" height="4096" aria-label="Linzumi" color="#0e404b"><path fill="currentColor" fill-rule="evenodd" d="M2111 3966c-37 2-34 3-69 2l-141-7c-34-2-36-1-65-5l-107-15c-30-5-43-7-76-15a3031 3031 0 0 1-217-61l-84-31c-26-10-33-11-70-29a2233 2233 0 0 1-423-259 1796 1796 0 0 1-381-416 1962 1962 0 0 1-168-298c-25-57-54-131-74-191-19-59-35-127-45-168-11-40-11-45-16-76-5-30-11-58-16-107-6-48-13-132-16-183q-2-77 1-122c0-31 1-30 3-61 3-31 8-89 13-126 4-37 4-47 14-95a1863 1863 0 0 1 475-956q51-56 92-94c27-26 36-36 71-65s99-79 137-107 62-43 90-61a1539 1539 0 0 1 156-88c31-15 58-31 104-49a1697 1697 0 0 1 492-133c61-9 144-19 202-22s111 1 145 2c34 2 30 6 57 9s70 5 103 9 56 7 96 15q59 10 141 30c54 15 143 44 187 59s47 18 77 31 59 25 102 48 108 59 157 89a2162 2162 0 0 1 210 153c27 23 50 42 88 80s99 101 141 148c41 48 74 91 106 138 33 46 67 104 90 141a1170 1170 0 0 1 92 180c17 40 44 107 59 149 16 41 22 63 32 99a3000 3000 0 0 1 47 195c5 28 9 46 14 95s13 137 16 198c2 62-1 123-4 172-2 50-7 88-11 126l-16 103a3048 3048 0 0 1-62 248c-10 31-17 49-29 80-12 32-22 60-44 108-23 48-64 130-92 180s-57 90-77 121l-45 62a3211 3211 0 0 1-153 182q-32 35-76 76a2201 2201 0 0 1-349 260c-50 28-132 69-180 91-48 23-76 32-108 44-33 12-42 17-84 30-42 12-109 33-168 46-60 12-130 24-187 31-58 6-119 8-157 10m9-294c18-3 10-6 14-12 4-5 4-11 9-19 6-7 16-19 25-27 10-8 14-12 31-18 16-6 50-14 69-17 18-3 33-1 42-2 8-1 6-3 7-4 1-2 10 3 0-4-11-7-46-26-65-40s-37-32-50-44c-13-13-18-17-29-31-12-14-29-41-39-53s-11-17-19-19q-11-3-31 4c-14 3-40 9-53 14s-15 6-23 15c-8 8-20 28-27 35-6 7-5 5-11 7s-18 5-27 4q-15-2-27-9c-6-6-11-18-14-24-3-7-4-9-4-16l3-26q2-17 12-39c7-13 14-26 31-42 16-15 56-41 68-51s5-5 5-10c1-4 4-6-1-17a341 341 0 0 0-80-101c-18-14-41-24-58-32-16-9-15-9-43-18-28-8-98-27-125-36-27-8-21-7-38-15l-61-32c-13-7-10-4-20-12l-41-34a114 114 0 0 1-34-54q-5-17 0-30c3-10 0-9 15-27 16-18 54-59 76-80 23-21 37-30 58-45a1278 1278 0 0 1 126-78c18-9 40-15 53-20q18-9 23-14c4-3 5 4 3-7-3-11-14-37-17-57-3-21-3-46 0-65q4-27 15-50 13-25 29-46 15-19 35-30c13-8 32-15 46-18q18-5 34-3l34 2q15 2 27 7c8 4 19 11 23 15 3 5 5 1-2 12-8 11-31 34-43 53q-18 30-30 65c-7 24-14 65-15 80-2 16 2 9 5 12l12 8q5 2 8-3c3-2 10-4 13-13 4-8 2-19 8-38 6-18 18-54 29-73 10-19 21-28 34-41q20-21 42-35c14-9 24-13 42-17 18-3 46-5 65-5 18 0 29 1 46 7 16 6 39 20 53 30q20 17 32 35c9 12 14 22 19 38s10 38 10 57c0 20-4 45-9 61q-7 25-18 40c-5 10-7 12-16 21-9 10-24 24-37 34-13 9-33 17-41 24-7 6-5 12-4 15q-2 4 7 3c7 1 13 3 34-1 21-3 62-16 91-21a632 632 0 0 1 271 0c24 4 31 8 47 13l45 17c18 8 41 18 61 31a541 541 0 0 1 153 152q18 27 28 50a878 878 0 0 1 35 103c5 21 9 33 12 61s3 88 4 107c2 19 3 8 5 9 2 2-6 8 8 1 13-7 52-29 73-44s34-28 52-46 41-46 56-65q20-26 29-46c8-13 10-14 18-34s22-57 28-84c7-27 7-58 9-80 1-22 0-35-1-54a481 481 0 0 0-53-194c-13-24-31-52-47-73a530 530 0 0 0-114-99q-33-19-58-31a650 650 0 0 0-99-28l-46-3h-107c-20-2-9-5-11-9s-2-12 0-16q1-4 7-7l27-9 46-7 65-2q32-1 65 3c21 3 46 11 64 16a464 464 0 0 1 256 183c13 17 18 23 31 46 12 23 34 69 43 93 10 24 11 28 16 50l14 80c3 14 1 5 3 6q3 3 8 1c2-1 0 5 6-7q11-20 31-65l45-111a2679 2679 0 0 0 76-279 1612 1612 0 0 0 21-343c-1-36-1-62-7-111s-23-142-31-183c-7-40-7-34-14-61-8-27-16-57-31-99s-40-107-60-153-36-77-62-122a1923 1923 0 0 0-184-266c-38-43-90-98-133-138-44-41-96-81-127-106s-39-29-61-44-36-26-72-46c-37-21-97-55-145-78a1921 1921 0 0 0-245-90 1334 1334 0 0 0-336-55c-40-2-99-4-148-3a1957 1957 0 0 0-248 26c-30 6-35 6-73 16s-106 28-156 46a1494 1494 0 0 0-406 211c-40 31-93 73-133 108-39 36-78 77-106 106-27 29-40 46-58 67l-46 59-76 111q-30 47-48 80a2814 2814 0 0 0-75 153c-12 28-17 39-30 76s-33 96-46 145a1912 1912 0 0 0-48 267 2164 2164 0 0 0-4 233 1469 1469 0 0 0 51 328 1340 1340 0 0 0 62 183c12 32 22 59 45 103 22 45 73 138 89 166 17 29 5 6 8 5 2-1 6 1 7-10 2-12 0-33 3-58a1421 1421 0 0 1 30-145 837 837 0 0 1 59-164c13-26 28-59 46-88a1133 1133 0 0 1 242-274 1321 1321 0 0 1 170-106 890 890 0 0 1 229-76q45-11 80-15c25-4 43-4 69-7 26-4 69-10 88-15s21-11 27-14c5-4 5-3 7-8 1-5 2-16 0-21-2-6 8-7-11-13s-72-14-103-22c-31-9-65-21-84-28s-17-7-29-15l-44-30c-7-7-3-6-2-8s-8 1 6-7l76-41c15-8 8-3 12-3s1-2 11 2c10 5 32 18 50 25a340 340 0 0 0 168 18c10-2 10-4 12-9s6-7-1-20c-7-14-33-49-42-63l-9-17q-3-5 0-7c1-2-8-1 9-6 18-4 78-19 96-21s5 0 13 8 23 27 36 39c14 12 33 24 46 32a144 144 0 0 0 69 21c14 0 37-1 53-5 16-3 27-7 42-15s35-20 50-33 26-38 42-45c16-6 37 4 53 7 17 3 37 9 46 12s7 3 7 6c1 3 8-3-2 11l-60 77c-10 14-4 6-5 11s0 15 1 19q2 6 6 8c2 2-1 3 7 4l42 2c17-1 33 1 57-5 25-6 69-22 88-29 20-7 24-10 31-15q9-6 13-11 5-3 10-2c3 0-5-6 11 2s70 37 84 46c15 9 3 6 3 8s5-1-3 5l-41 29c-11 7-8 7-24 14-16 8-49 22-72 30s-30 13-65 20c-35 6-108 13-145 19s-59 10-77 15c-17 5-16 7-26 14-11 8-20 12-37 29s-44 51-65 73-48 45-62 58c-15 12-12 10-25 18l-52 30-30 15-50 16c-18 5-29 9-57 15l-111 21c-27 6-32 8-53 15q-33 12-73 31-36 16-80 45a709 709 0 0 0-238 270c-15 28-22 49-29 69-8 20-12 30-17 49-5 20-11 39-16 69-4 31-11 83-13 115-2 31-2 45 0 76l14 111c5 28 11 44 16 61l14 42q11 29 32 71c16 28 40 68 60 97a712 712 0 0 0 299 246c33 15 81 34 111 44s39 11 69 17q43 8 107 16c42 4 107 8 148 9s78-2 97-4m915-1801-54 1c-17 0-21 2-49-3-28-6-87-21-119-32-31-10-47-20-72-33-26-13-64-34-80-44-16-9 2-2-16-11a1748 1748 0 0 0-190-90c-32-13-69-24-88-30s-17-2-27-5c-9-3-12-7-30-11a914 914 0 0 0-191-30c-29-2-36-2-61-1q-41-1-92 3a1494 1494 0 0 0-175 28 1889 1889 0 0 0-184 60c-24 10-21 6-68 31s-164 91-214 116-65 26-88 33c-23 8-32 9-49 12a606 606 0 0 1-164 2c-19-4-43-12-58-17-15-4-16-5-30-13-15-8-42-24-58-35a286 286 0 0 1-64-58q-15-17-30-41-17-28-32-61a352 352 0 0 1-22-127c0-22 1-50 5-72q6-32 18-61a361 361 0 0 1 164-183 366 366 0 0 1 125-44c19-3 40-1 50-3s10 10 12-7c3-17 0-70 3-95 2-25 6-37 11-54a388 388 0 0 1 66-127 509 509 0 0 1 87-79 578 578 0 0 1 104-48c19-5 52-10 68-13 16-2 14-1 27-1q20-1 50 2 30 2 68 12c26 8 69 30 84 35s3 2 8-7l19-48 15-27c5-9 8-14 19-27 10-12 25-33 42-49q27-25 59-46a384 384 0 0 1 94-44q20-7 50-12a507 507 0 0 1 137-1q30 5 53 13c16 5 26 8 42 16a561 561 0 0 1 96 58c12 10 18 16 31 31l44 57c10 15 10 17 16 30l19 49c5 10-1 10 8 7 9-2 32-15 48-21a410 410 0 0 1 109-26c18-2 28-4 53-2s69 9 95 16c27 7 49 19 65 26 16 8 19 11 31 19a595 595 0 0 1 73 62q17 19 34 42a439 439 0 0 1 47 107c5 17 8 26 10 50s0 78 3 95c2 17 2 5 12 7 11 2 32 0 50 3q27 3 57 13a412 412 0 0 1 137 79c17 13 22 20 32 32a347 347 0 0 1 62 99c8 16 9 17 14 38 4 22 12 61 12 92s-6 72-10 95c-5 24-8 30-16 46a499 499 0 0 1-59 95q-14 18-30 31c-11 10-20 18-35 28a705 705 0 0 1-88 46l-49 16q-23 5-46 6m-1146 957q10-1 16-9c6-5 13-16 17-21 3-6 2-6 3-12 0-5 2-11-2-19-3-7-13-20-19-26q-12-9-22-10c-6-2-8-2-15 0s-21 7-28 13q-10 11-15 23-3 10-1 19c2 8 9 20 13 27q8 8 16 12c4 3 5 3 11 4s19 1 26-1"/></svg>