anhedral 0.3.0 → 0.4.1
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/CHANGELOG.md +35 -0
- package/CONTRIBUTING.md +4 -1
- package/LICENSE +201 -26
- package/README.md +79 -15
- package/SECURITY.md +4 -2
- package/SKILL.md +78 -11
- package/assets/anhedral-cli-init.svg +238 -0
- package/assets/images/svg/ably-symbol-color.svg +8 -0
- package/assets/images/svg/logo-white-subtract.svg +4 -0
- package/dist/architecture/contributions.js +7 -0
- package/dist/architecture/modules.d.ts +2 -2
- package/dist/architecture/modules.js +11 -3
- package/dist/bin.js +17 -5
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +4 -1
- package/dist/composers/root.js +1 -0
- package/dist/dependencies.d.ts +2 -0
- package/dist/dependencies.js +8 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/prompts.d.ts +1 -1
- package/dist/scaffold.d.ts +8 -0
- package/dist/scaffold.js +320 -38
- package/dist/templates/api.js +8 -0
- package/dist/templates/desktop.js +78 -11
- package/dist/templates/electron-updater.d.ts +3 -0
- package/dist/templates/electron-updater.js +358 -0
- package/dist/templates/shared.js +23 -6
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/conventions.md +4 -1
- package/docs/master-stack-map.md +199 -0
- package/docs/output-tree-contract.md +45 -5
- package/{references → docs/references}/manual-scaffolding.md +24 -7
- package/docs/references/provisioning.md +220 -0
- package/package.json +12 -5
- package/scripts/render-master-stack-map.mjs +510 -0
package/SKILL.md
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: anhedral-init
|
|
3
|
-
description:
|
|
3
|
+
description: Guide a user through creating, provisioning, extending, explaining, or diagnosing a complete Anhedral TypeScript stack. Use for skill-led new/init/add/ui/doctor workflows; Computer Use or subagent-assisted cloud setup; domains, DNS, Vercel, Cloudflare, Neon, Clerk, R2, billing, stores, and Electron updates; development inside a generated workspace; ownership interpretation; manual reproduction; or verification.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Anhedral Init
|
|
7
7
|
|
|
8
8
|
Anhedral is a stack generator, not an application runtime or programming language. Generated projects use ordinary framework source and expose the complete integration code. Do not invent Anhedral-specific models, routes, queries, components, or client hooks when the selected framework already has a documented convention.
|
|
9
9
|
|
|
10
|
+
For every new project or provisioning request, begin by asking for the project
|
|
11
|
+
name and whether the user already owns a custom domain for it. Do not run init
|
|
12
|
+
or create provider resources until those answers establish canonical names.
|
|
13
|
+
|
|
10
14
|
Use Node.js 20.19+ or 22.12+ and pnpm. `new` creates a destination directory; `init` works in an empty current directory where `.git`, `.gitignore`, and `.DS_Store` are allowed.
|
|
11
15
|
|
|
12
16
|
## Choose the construction path
|
|
13
17
|
|
|
14
18
|
- Use the manual path whenever the user asks to avoid the Anhedral CLI, the CLI is unavailable, or the task requires explaining/reproducing the scaffold itself.
|
|
15
|
-
- Before creating or changing files manually, read [references/manual-scaffolding.md](references/manual-scaffolding.md) completely and follow its ordered procedure. Treat it as the canonical manual checklist, including its source-file matrix and feature gates.
|
|
19
|
+
- Before creating or changing files manually, read [docs/references/manual-scaffolding.md](docs/references/manual-scaffolding.md) completely and follow its ordered procedure. Treat it as the canonical manual checklist, including its source-file matrix and feature gates.
|
|
16
20
|
- Use the CLI path only when the user permits it. Do not silently substitute `anhedral init`, `anhedral add`, imported generator code, or a generated demo for the manual path.
|
|
17
21
|
- For an exact-version scaffold inside the Anhedral source repository, render from the current `src/templates/*.ts`, `src/scaffold.ts`, and `src/dependencies.ts`; do not copy stale demo output. Outside that repository, implement the behavior and file contract in the manual reference and pin a mutually compatible toolchain.
|
|
18
22
|
|
|
@@ -22,7 +26,7 @@ The manual path must leave a complete working workspace, not merely a directory
|
|
|
22
26
|
|
|
23
27
|
Choose app surfaces from `web`, `mobile`, `api`, `desktop`, and `extension`.
|
|
24
28
|
|
|
25
|
-
Choose
|
|
29
|
+
Choose features from `db`, `auth`, `billing`, `storage`, `native-subscriptions`, and `electron-updater`.
|
|
26
30
|
|
|
27
31
|
Apply these dependency rules automatically:
|
|
28
32
|
|
|
@@ -31,10 +35,58 @@ auth -> api + db
|
|
|
31
35
|
billing -> auth
|
|
32
36
|
storage -> auth
|
|
33
37
|
native-subscriptions -> mobile + billing
|
|
38
|
+
electron-updater -> desktop
|
|
34
39
|
```
|
|
35
40
|
|
|
36
41
|
With no module flags, generate the full stack.
|
|
37
42
|
|
|
43
|
+
## Master stack map
|
|
44
|
+
|
|
45
|
+
Read [docs/master-stack-map.md](docs/master-stack-map.md) completely before
|
|
46
|
+
explaining the whole platform, selecting modules for a complete product, or
|
|
47
|
+
planning cross-provider provisioning. Treat it as the canonical map of the
|
|
48
|
+
stack, command surface, runtime connections, agent workflow, and release path.
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
project + domain intake
|
|
52
|
+
|
|
|
53
|
+
v
|
|
54
|
+
1 select + plan -> 2 generate safely -> 3 one pnpm/Turborepo workspace
|
|
55
|
+
|
|
|
56
|
+
v
|
|
57
|
+
4 connected product capabilities -> 5 provision cloud + DNS
|
|
58
|
+
|
|
|
59
|
+
v
|
|
60
|
+
6 generated package.json commands -> 7 developer/agent/Computer Use
|
|
61
|
+
|
|
|
62
|
+
v
|
|
63
|
+
8 verify, release, and operate
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use the full fixed-width ASCII map from the document when the user asks for the
|
|
67
|
+
master stack map. Do not redraw it from memory or omit unselected modules when
|
|
68
|
+
describing Anhedral's complete capability surface; mark modules as selected or
|
|
69
|
+
unselected separately.
|
|
70
|
+
|
|
71
|
+
## Run the guided init workflow
|
|
72
|
+
|
|
73
|
+
Read [docs/references/provisioning.md](docs/references/provisioning.md) completely before
|
|
74
|
+
starting a new project or provisioning any provider. Follow its intake,
|
|
75
|
+
capability discovery, Computer Use, subagent, authentication, secret-handling,
|
|
76
|
+
domain, provider-order, and verification gates.
|
|
77
|
+
|
|
78
|
+
The lead agent must:
|
|
79
|
+
|
|
80
|
+
1. Ask for project name and existing/custom-domain status first.
|
|
81
|
+
2. Discover whether Computer Use/browser control and subagents are available.
|
|
82
|
+
3. Resolve modules and show the user canonical project/resource names.
|
|
83
|
+
4. Run the explicit CLI command, then read the generated `PRODUCTION.md`.
|
|
84
|
+
5. Provision only selected providers, pausing for sign-in, MFA, secret
|
|
85
|
+
generation, purchases, and final submissions exactly as the reference says.
|
|
86
|
+
6. Keep secrets out of chat and tool output; have the user paste them directly
|
|
87
|
+
into uncommitted environment files and protected provider fields.
|
|
88
|
+
7. Verify code, cloud resources, DNS, TLS, and provider health before handoff.
|
|
89
|
+
|
|
38
90
|
## Initialize
|
|
39
91
|
|
|
40
92
|
```sh
|
|
@@ -74,23 +126,27 @@ Use the native source conventions:
|
|
|
74
126
|
|
|
75
127
|
- Next.js code belongs in `apps/web/app`, `apps/web/components`, and `apps/web/lib`.
|
|
76
128
|
- Expo Router code belongs in `apps/mobile/app` and `apps/mobile/components`.
|
|
77
|
-
- Fastify
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
- Drizzle
|
|
129
|
+
- Product Fastify route registration belongs in `apps/api/src/routes/app.ts`. Server-only feature modules live alongside the managed integrations in `apps/api/src`.
|
|
130
|
+
- Product Zod network schemas belong in `packages/contracts/src/app.ts`.
|
|
131
|
+
- Product client-safe HTTP methods belong in `packages/api-client/src/app.ts`.
|
|
132
|
+
- Product Drizzle tables belong in `packages/db/src/app-schema.ts`; generate and review SQL migrations.
|
|
81
133
|
|
|
82
134
|
Implement an end-to-end feature as `contracts -> database/service -> route -> API client -> frontend`. Frontends may import contracts and client-safe packages, never API services, database connections, or server environments. This stack uses managed Neon and intentionally has no local Postgres service.
|
|
83
135
|
|
|
84
136
|
## Add modules safely
|
|
85
137
|
|
|
86
|
-
Run `add` only from a project containing `anhedral.json` schema v5:
|
|
138
|
+
Run `add` only from a project containing `anhedral.json` schema v5 at the current generator version. If `doctor` identifies a supported older generator, preview and apply its transactional upgrade first:
|
|
87
139
|
|
|
88
140
|
```sh
|
|
141
|
+
pnpm dlx anhedral@latest upgrade --dry-run
|
|
142
|
+
pnpm dlx anhedral@latest upgrade
|
|
89
143
|
pnpm dlx anhedral@latest add desktop extension
|
|
90
144
|
pnpm dlx anhedral@latest add storage --dry-run
|
|
91
145
|
```
|
|
92
146
|
|
|
93
|
-
Use `--dry-run` before a consequential add. Use `--json` when another program needs the plan; JSON failures include a stable `code` and a human-readable `error`. Use `--verbose` for interactive child-command diagnostics.
|
|
147
|
+
Use `--dry-run` before a consequential add. Use `--json` when another program needs the plan; JSON failures include a stable `code` and a human-readable `error`. Use `--verbose` for interactive child-command diagnostics. Anhedral preserves recorded user-owned extension files and intentionally refuses modified managed files, symlinks, and unowned collisions; do not bypass those conflicts.
|
|
148
|
+
|
|
149
|
+
For a 0.3 upgrade blocked by a modified managed file, preserve the change in source control, restore that file to its recorded 0.3 content, apply the upgrade, and port the product behavior into the corresponding 0.4 user-owned extension seam. Never approve the upgrade by rewriting manifest hashes.
|
|
94
150
|
|
|
95
151
|
Require the manifest generator version to match the running CLI. Regenerate projects created by another version; do not add compatibility branches.
|
|
96
152
|
|
|
@@ -145,10 +201,16 @@ Common selected keys are:
|
|
|
145
201
|
- Ably billing synchronization: server-only `ABLY_API_KEY`; clients obtain scoped tokens from the API
|
|
146
202
|
- R2: `BASE_URL`, `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET_NAME`, `R2_PREFIX=storage`, `R2_PROXY_READ_URL_TTL_SECONDS=600`; keep `CLOUDFLARE_API_TOKEN` operations/CI-only
|
|
147
203
|
- Internal billing/storage jobs: high-entropy server-only `CRON_SECRET`
|
|
204
|
+
- Electron updates: `DESKTOP_UPDATE_BASE_URL` in `apps/desktop/electron-builder.env`; the private R2 binding needs no credential in the packaged application
|
|
148
205
|
|
|
149
206
|
Never commit real `.env` files. Keep `ANHEDRAL_DEMO=false` in production.
|
|
150
207
|
|
|
151
|
-
Run only scripts present for installed modules.
|
|
208
|
+
Run only scripts present for installed modules. `pnpm dev` starts the primary
|
|
209
|
+
product loop—web plus API when web is selected, otherwise the first selected
|
|
210
|
+
surface. A multi-surface project also exposes `pnpm dev:all`; use it only when
|
|
211
|
+
the user wants every selected development server. Typical focused commands
|
|
212
|
+
include `dev:web`, `dev:mobile`, `dev:api`, `dev:desktop`, `dev:extension`,
|
|
213
|
+
corresponding `verify:*` scripts, and database scripts for `db` projects.
|
|
152
214
|
|
|
153
215
|
## Understand deployment
|
|
154
216
|
|
|
@@ -158,6 +220,11 @@ For billing, keep Neon authoritative: RevenueCat reconciliation writes the subsc
|
|
|
158
220
|
|
|
159
221
|
Use `apps/mobile` for EAS, `pnpm desktop:build` for a current-host Electron artifact, matching platform-specific desktop scripts in CI, and `pnpm extension:zip` for the WXT archive.
|
|
160
222
|
|
|
223
|
+
For `electron-updater`, provision the generated private R2 bucket and
|
|
224
|
+
`desktop-updater` Worker at `updates.<domain>`. Keep the Worker custom domain and
|
|
225
|
+
`DESKTOP_UPDATE_BASE_URL` identical. Build signed artifacts on each native
|
|
226
|
+
platform and publish artifacts before mutable channel metadata.
|
|
227
|
+
|
|
161
228
|
For storage, generate `apps/assets-private-proxy` plus `cloudflare/r2-cors.template.json` and keep the R2 bucket private. The Worker must be named `assets-private-proxy`, bind the normalized `<project>-assets` bucket as `ASSETS`, disable `workers.dev`, and own `assets.<domain>` as a Worker Custom Domain. Presigned uploads continue on the R2 S3 API hostname. Root every key below `R2_PREFIX=storage`; expose only `storage/confirmed/` through the Worker and reject staging plus `generation-inputs`. Authenticated private reads must verify upload ownership and return a presigned GET URL bounded by `R2_PROXY_READ_URL_TTL_SECONDS`.
|
|
162
229
|
|
|
163
230
|
When explaining domains, distinguish DNS delegation from registrar transfer. A GoDaddy registration can use Cloudflare authoritative nameservers immediately; transferring registration/billing to Cloudflare Registrar is optional and subject to eligibility locks. Keep Vercel app/API A or CNAME records DNS-only in Cloudflare, while Worker Custom Domains stay Cloudflare-managed and proxied.
|
|
@@ -174,4 +241,4 @@ pnpm build
|
|
|
174
241
|
|
|
175
242
|
Use `pnpm --filter ./apps/api test` when the API exists. If verification fails, report the exact package and command rather than replacing generated ownership records manually.
|
|
176
243
|
|
|
177
|
-
For exact representative trees, consult `docs/output-tree-contract.md` in the Anhedral repository. During manual construction, also compare the finished workspace with the file matrix in [references/manual-scaffolding.md](references/manual-scaffolding.md); every selected conditional file must exist and every unselected provider integration must be absent.
|
|
244
|
+
For exact representative trees, consult `docs/output-tree-contract.md` in the Anhedral repository. During manual construction, also compare the finished workspace with the file matrix in [docs/references/manual-scaffolding.md](docs/references/manual-scaffolding.md); every selected conditional file must exist and every unselected provider integration must be absent.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1180" viewBox="0 0 1920 1180" role="img" aria-labelledby="title description">
|
|
2
|
+
<title id="title">Anhedral Init Stack</title>
|
|
3
|
+
<desc id="description">A simplified architecture diagram showing DX tools, deployment destinations, four generated client surfaces, their shared Fastify API, RevenueCat and Stripe billing, Ably realtime, backend services, and a dedicated private R2 updater Worker.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="card-fill" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#0d1b29"/>
|
|
7
|
+
<stop offset="1" stop-color="#07121d"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<linearGradient id="app-store-fill" x1="0" y1="0" x2="0" y2="1">
|
|
10
|
+
<stop offset="0" stop-color="#24c7fa"/>
|
|
11
|
+
<stop offset="1" stop-color="#0878f9"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
<filter id="endpoint-glow" x="-100%" y="-100%" width="300%" height="300%">
|
|
14
|
+
<feGaussianBlur in="SourceGraphic" stdDeviation="1.7"/>
|
|
15
|
+
</filter>
|
|
16
|
+
<marker id="arrow-white" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 Z" fill="#f7f5f0"/></marker>
|
|
17
|
+
<marker id="arrow-yellow" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 Z" fill="#e9f600"/></marker>
|
|
18
|
+
</defs>
|
|
19
|
+
<rect width="1920" height="1180" fill="#0c1117"/>
|
|
20
|
+
<g transform="translate(28 34) scale(0.0263756252842201)">
|
|
21
|
+
<path d="M1604.59 26.7414C1694.33 -39.6752 1821.31 25.3379 1819.89 136.971L1809.28 971.026C1774.28 969.39 1738.87 969.434 1703.15 971.237C1334.16 989.855 1017.8 1191.61 837.641 1484.06L122.496 1416.65C-0.793297 1405.03 -44.6847 1247.41 54.8543 1173.73L1604.59 26.7414Z" fill="#f7f5f0"/>
|
|
22
|
+
<path d="M1795.36 2064.84C1793.79 2188.66 1640.25 2245.21 1558.74 2151.98L1083.84 1608.79C1214.01 1305.09 1479.98 1071.11 1809.07 987.262L1795.36 2064.84Z" fill="#f7f5f0"/>
|
|
23
|
+
</g>
|
|
24
|
+
<path d="M 93.00363801728058 26 L 93.00363801728058 104" fill="none" stroke="#73777b" stroke-width="1.5" stroke-linecap="round"/>
|
|
25
|
+
<text x="115.00363801728058" y="80" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="27" font-weight="500" text-anchor="start" letter-spacing="1.3">ANHEDRAL</text>
|
|
26
|
+
<text x="32" y="176" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="78" font-weight="700" text-anchor="start" letter-spacing="0">Anhedral</text>
|
|
27
|
+
<path d="M 33 195 L 366 195" fill="none" stroke="#e9f600" stroke-width="6" stroke-linecap="round"/>
|
|
28
|
+
<text x="392" y="176" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="78" font-weight="700" text-anchor="start" letter-spacing="0">Init</text>
|
|
29
|
+
<path d="M 393 195 L 506 195" fill="none" stroke="#e9f600" stroke-width="6" stroke-linecap="round"/>
|
|
30
|
+
<text x="532" y="176" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="78" font-weight="700" text-anchor="start" letter-spacing="0">Stack</text>
|
|
31
|
+
<path d="M 533 195 L 747 195" fill="none" stroke="#e9f600" stroke-width="6" stroke-linecap="round"/>
|
|
32
|
+
<text x="34" y="240" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="24" font-weight="400" text-anchor="start" letter-spacing="0">One init flow for web, native apps, extensions, backend,</text>
|
|
33
|
+
<text x="34" y="274" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="24" font-weight="400" text-anchor="start" letter-spacing="0">storage, auth, subscriptions, and seamless desktop updates.</text>
|
|
34
|
+
<text x="1525" y="52" fill="#e9f600" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="600" text-anchor="middle" letter-spacing="3.2">DX TOOLS</text>
|
|
35
|
+
<rect x="1187" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
36
|
+
<g transform="translate(1214 90) scale(1.4166666666666667)"><path d="M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z" fill="#06b6d4"/></g>
|
|
37
|
+
<text x="1231" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">Tailwind</text>
|
|
38
|
+
<rect x="1285" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
39
|
+
<g transform="translate(1312 90) scale(1.4166666666666667)"><path d="M22.219 11.784 11.784 22.219c-.407.407-.407 1.068 0 1.476.407.407 1.068.407 1.476 0L23.695 13.26c.407-.408.407-1.069 0-1.476-.408-.407-1.069-.407-1.476 0ZM20.132.305.305 20.132c-.407.407-.407 1.068 0 1.476.408.407 1.069.407 1.476 0L21.608 1.781c.407-.407.407-1.068 0-1.476-.408-.407-1.069-.407-1.476 0Z" fill="#f7f5f0"/></g>
|
|
40
|
+
<text x="1329" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">shadcn/ui</text>
|
|
41
|
+
<rect x="1383" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
42
|
+
<g transform="translate(1410 90) scale(1.4166666666666667)"><path d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z" fill="#61dafb"/></g>
|
|
43
|
+
<text x="1427" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">RN Reusables</text>
|
|
44
|
+
<rect x="1481" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
45
|
+
<g transform="translate(1508 90) scale(1.4166666666666667)"><path d="M1.125 0C.502 0 0 .502 0 1.125v21.75C0 23.498.502 24 1.125 24h21.75c.623 0 1.125-.502 1.125-1.125V1.125C24 .502 23.498 0 22.875 0zm17.363 9.75c.612 0 1.154.037 1.627.111a6.38 6.38 0 0 1 1.306.34v2.458a3.95 3.95 0 0 0-.643-.361 5.093 5.093 0 0 0-.717-.26 5.453 5.453 0 0 0-1.426-.2c-.3 0-.573.028-.819.086a2.1 2.1 0 0 0-.623.242c-.17.104-.3.229-.393.374a.888.888 0 0 0-.14.49c0 .196.053.373.156.529.104.156.252.304.443.444s.423.276.696.41c.273.135.582.274.926.416.47.197.892.407 1.266.628.374.222.695.473.963.753.268.279.472.598.614.957.142.359.214.776.214 1.253 0 .657-.125 1.21-.373 1.656a3.033 3.033 0 0 1-1.012 1.085 4.38 4.38 0 0 1-1.487.596c-.566.12-1.163.18-1.79.18a9.916 9.916 0 0 1-1.84-.164 5.544 5.544 0 0 1-1.512-.493v-2.63a5.033 5.033 0 0 0 3.237 1.2c.333 0 .624-.03.872-.09.249-.06.456-.144.623-.25.166-.108.29-.234.373-.38a1.023 1.023 0 0 0-.074-1.089 2.12 2.12 0 0 0-.537-.5 5.597 5.597 0 0 0-.807-.444 27.72 27.72 0 0 0-1.007-.436c-.918-.383-1.602-.852-2.053-1.405-.45-.553-.676-1.222-.676-2.005 0-.614.123-1.141.369-1.582.246-.441.58-.804 1.004-1.089a4.494 4.494 0 0 1 1.47-.629 7.536 7.536 0 0 1 1.77-.201zm-15.113.188h9.563v2.166H9.506v9.646H6.789v-9.646H3.375z" fill="#3178c6"/></g>
|
|
46
|
+
<text x="1525" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">TypeScript</text>
|
|
47
|
+
<rect x="1579" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
48
|
+
<g transform="translate(1606 90) scale(1.4166666666666667)"><path d="M2.584 3.582a2.247 2.247 0 0 1 2.112-1.479h14.617c.948 0 1.794.595 2.115 1.487l2.44 6.777a2.248 2.248 0 0 1-.624 2.443l-9.61 8.52a2.247 2.247 0 0 1-2.963.018L.776 12.773a2.248 2.248 0 0 1-.64-2.467Zm12.038 4.887-9.11 5.537 5.74 5.007c.456.399 1.139.396 1.593-.006l5.643-5.001H14.4l6.239-3.957c.488-.328.69-.947.491-1.5l-1.24-3.446a1.535 1.535 0 0 0-1.456-1.015H5.545a1.535 1.535 0 0 0-1.431 1.01l-1.228 3.37z" fill="#3e67b1"/></g>
|
|
49
|
+
<text x="1623" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">Zod</text>
|
|
50
|
+
<rect x="1677" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
51
|
+
<g transform="translate(1704 90) scale(1.4166666666666667)"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" fill="#f7f5f0"/></g>
|
|
52
|
+
<text x="1721" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">GitHub</text>
|
|
53
|
+
<rect x="1775" y="76" width="88" height="92" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
54
|
+
<g transform="translate(1804.9299681673488 90) scale(0.015461573442473852)">
|
|
55
|
+
<path d="M1604.59 26.7414C1694.33 -39.6752 1821.31 25.3379 1819.89 136.971L1809.28 971.026C1774.28 969.39 1738.87 969.434 1703.15 971.237C1334.16 989.855 1017.8 1191.61 837.641 1484.06L122.496 1416.65C-0.793297 1405.03 -44.6847 1247.41 54.8543 1173.73L1604.59 26.7414Z" fill="#f7f5f0"/>
|
|
56
|
+
<path d="M1795.36 2064.84C1793.79 2188.66 1640.25 2245.21 1558.74 2151.98L1083.84 1608.79C1214.01 1305.09 1479.98 1071.11 1809.07 987.262L1795.36 2064.84Z" fill="#f7f5f0"/>
|
|
57
|
+
</g>
|
|
58
|
+
<text x="1819" y="148" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="11" font-weight="500" text-anchor="middle" letter-spacing="0">Anhedral Skills</text>
|
|
59
|
+
<text x="252" y="318" fill="#e9f600" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="600" text-anchor="middle" letter-spacing="3.2">DEPLOY & DISTRIBUTE</text>
|
|
60
|
+
<text x="805" y="318" fill="#e9f600" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="600" text-anchor="middle" letter-spacing="3.2">CLIENT SURFACES</text>
|
|
61
|
+
<text x="1497.5" y="318" fill="#e9f600" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="600" text-anchor="middle" letter-spacing="3.2">BACKEND + SERVICES</text>
|
|
62
|
+
<rect x="54" y="342" width="396" height="102" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
63
|
+
<rect x="70" y="354" width="78" height="78" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
64
|
+
<g fill="none" stroke="#f7f5f0" stroke-width="3">
|
|
65
|
+
<circle cx="109" cy="393" r="26.520000000000003"/>
|
|
66
|
+
<ellipse cx="109" cy="393" rx="11.934000000000001" ry="26.520000000000003"/>
|
|
67
|
+
<path d="M 82.47999999999999 393 H 135.52 M 86.72319999999999 379.74 H 131.2768 M 86.72319999999999 406.26 H 131.2768"/>
|
|
68
|
+
</g>
|
|
69
|
+
<path d="M 158 356 L 158 430" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
70
|
+
<text x="182" y="384" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Web</text>
|
|
71
|
+
<text x="182" y="412" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">Vercel preview + production</text>
|
|
72
|
+
<text x="182" y="433" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">hosts web + API</text>
|
|
73
|
+
<rect x="54" y="456" width="396" height="102" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
74
|
+
<rect x="70" y="468" width="78" height="78" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
75
|
+
<rect x="78" y="476" width="62" height="62" rx="11" fill="url(#app-store-fill)"/>
|
|
76
|
+
<g transform="translate(87 485) scale(1.8333333333333333)"><path d="M8.8086 14.9194l6.1107-11.0368c.0837-.1513.1682-.302.2437-.4584.0685-.142.1267-.2854.1646-.4403.0803-.3259.0588-.6656-.066-.9767-.1238-.3095-.3417-.5678-.6201-.7355a1.4175 1.4175 0 0 0-.921-.1924c-.3207.043-.6135.1935-.8443.4288-.1094.1118-.1996.2361-.2832.369-.092.1463-.175.2979-.259.4492l-.3864.6979-.3865-.6979c-.0837-.1515-.1667-.303-.2587-.4492-.0837-.1329-.1739-.2572-.2835-.369-.2305-.2353-.5233-.3857-.844-.429a1.4181 1.4181 0 0 0-.921.1926c-.2784.1677-.4964.426-.6203.7355-.1246.311-.1461.6508-.066.9767.038.155.0962.2984.1648.4403.0753.1564.1598.307.2437.4584l1.248 2.2543-4.8625 8.7825H2.0295c-.1676 0-.3351-.0007-.5026.0092-.1522.009-.3004.0284-.448.0714-.3108.0906-.5822.2798-.7783.548-.195.2665-.3006.5929-.3006.9279 0 .3352.1057.6612.3006.9277.196.2683.4675.4575.7782.548.1477.043.296.0623.4481.0715.1675.01.335.009.5026.009h13.0974c.0171-.0357.059-.1294.1-.2697.415-1.4151-.6156-2.843-2.0347-2.843zM3.113 18.5418l-.7922 1.5008c-.0818.1553-.1644.31-.2384.4705-.067.1458-.124.293-.1611.452-.0785.3346-.0576.6834.0645 1.0029.1212.3175.3346.583.607.7549.2727.172.5891.2416.9013.1975.3139-.044.6005-.1986.8263-.4402.1072-.1148.1954-.2424.2772-.3787.0902-.1503.1714-.3059.2535-.4612L6 19.4636c-.0896-.149-.9473-1.4704-2.887-.9218m20.5861-3.0056a1.4707 1.4707 0 0 0-.779-.5407c-.1476-.0425-.2961-.0616-.4483-.0705-.1678-.0099-.3352-.0091-.503-.0091H18.648l-4.3891-7.817c-.6655.7005-.9632 1.485-1.0773 2.1976-.1655 1.0333.0367 2.0934.546 3.0004l5.2741 9.3933c.084.1494.167.299.2591.4435.0837.131.1739.2537.2836.364.231.2323.5238.3809.8449.4232.3192.0424.643-.0244.9217-.1899.2784-.1653.4968-.4204.621-.7257.1246-.3072.146-.6425.0658-.9641-.0381-.1529-.0962-.2945-.165-.4346-.0753-.1543-.1598-.303-.2438-.4524l-1.216-2.1662h1.596c.1677 0 .3351.0009.5029-.009.1522-.009.3007-.028.4483-.0705a1.4707 1.4707 0 0 0 .779-.5407A1.5386 1.5386 0 0 0 24 16.452a1.539 1.539 0 0 0-.3009-.9158Z" fill="#f7f5f0"/></g>
|
|
77
|
+
<path d="M 158 470 L 158 544" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
78
|
+
<text x="182" y="498" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">App Store</text>
|
|
79
|
+
<text x="182" y="526" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">iOS distribution</text>
|
|
80
|
+
<text x="182" y="547" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">EAS signed release</text>
|
|
81
|
+
<rect x="54" y="570" width="396" height="102" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
82
|
+
<rect x="70" y="582" width="78" height="78" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
83
|
+
<g transform="translate(74 586) scale(1.09375)" stroke-linejoin="round">
|
|
84
|
+
<path d="M 9 6 L 39 32 L 9 58 Z" fill="#23d7f2"/>
|
|
85
|
+
<path d="M 9 6 L 44 24.5 L 39 32 Z" fill="#2bd66f"/>
|
|
86
|
+
<path d="M 39 32 L 44 24.5 L 56 30.5 Q 59 32 56 33.5 L 44 39.5 Z" fill="#ffd43b"/>
|
|
87
|
+
<path d="M 9 58 L 44 39.5 L 39 32 Z" fill="#f04b55"/>
|
|
88
|
+
</g>
|
|
89
|
+
<path d="M 158 584 L 158 658" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
90
|
+
<text x="182" y="612" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Google Play</text>
|
|
91
|
+
<text x="182" y="640" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">Android distribution</text>
|
|
92
|
+
<text x="182" y="661" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">EAS signed release</text>
|
|
93
|
+
<rect x="54" y="684" width="396" height="102" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
94
|
+
<rect x="70" y="696" width="78" height="78" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
95
|
+
<rect x="75" y="701" width="68" height="68" rx="11" fill="#f7f5f0"/>
|
|
96
|
+
<path d="M 109 735 L 96.76 713.7996981153569 A 24.48 24.48 0 0 1 133.48 735 Z" fill="#ea4335"/>
|
|
97
|
+
<path d="M 109 735 L 133.48 735 A 24.48 24.48 0 0 1 96.76 756.2003018846431 Z" fill="#fbbc04"/>
|
|
98
|
+
<path d="M 109 735 L 96.76 756.2003018846431 A 24.48 24.48 0 0 1 96.76 713.7996981153569 Z" fill="#34a853"/>
|
|
99
|
+
<circle cx="109" cy="735" r="11.750399999999999" fill="#f7f5f0"/>
|
|
100
|
+
<circle cx="109" cy="735" r="8.8128" fill="#4285f4"/>
|
|
101
|
+
<path d="M 158 698 L 158 772" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
102
|
+
<text x="182" y="726" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Browser Web Stores</text>
|
|
103
|
+
<text x="182" y="754" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">extension distribution</text>
|
|
104
|
+
<text x="182" y="775" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">reviewed WXT ZIP</text>
|
|
105
|
+
<rect x="54" y="798" width="396" height="102" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
106
|
+
<rect x="70" y="810" width="78" height="78" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
107
|
+
<g fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
108
|
+
<rect x="79" y="819" width="60" height="51" rx="3"/>
|
|
109
|
+
<path d="M 109 870 V 880 M 91.84 880 H 126.16"/>
|
|
110
|
+
</g>
|
|
111
|
+
<path d="M 158 812 L 158 886" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
112
|
+
<text x="182" y="840" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Desktop Releases</text>
|
|
113
|
+
<text x="182" y="868" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">macOS · Windows · Linux</text>
|
|
114
|
+
<text x="182" y="889" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">signed installers + seamless updates</text>
|
|
115
|
+
<rect x="620" y="342" width="370" height="112" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
116
|
+
<rect x="636" y="354" width="88" height="88" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
117
|
+
<g transform="translate(651 369) scale(2.4166666666666665)"><path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z" fill="#f7f5f0"/></g>
|
|
118
|
+
<path d="M 734 356 L 734 440" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
119
|
+
<text x="758" y="384" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Next.js</text>
|
|
120
|
+
<text x="758" y="412" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">shadcn/ui</text>
|
|
121
|
+
<text x="758" y="433" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">web product + server routes</text>
|
|
122
|
+
<g transform="translate(958 357) scale(0.7083333333333334)"><path d="m12 1.608 12 20.784H0Z" fill="#f7f5f0"/></g>
|
|
123
|
+
<rect x="620" y="494" width="370" height="112" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
124
|
+
<rect x="636" y="506" width="88" height="88" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
125
|
+
<g transform="translate(651 521) scale(2.4166666666666665)"><path d="M0 20.084c.043.53.23 1.063.718 1.778.58.849 1.576 1.315 2.303.567.49-.505 5.794-9.776 8.35-13.29a.761.761 0 011.248 0c2.556 3.514 7.86 12.785 8.35 13.29.727.748 1.723.282 2.303-.567.57-.835.728-1.42.728-2.046 0-.426-8.26-15.798-9.092-17.078-.8-1.23-1.044-1.498-2.397-1.542h-1.032c-1.353.044-1.597.311-2.398 1.542C8.267 3.991.33 18.758 0 19.77Z" fill="#f7f5f0"/></g>
|
|
126
|
+
<path d="M 734 508 L 734 592" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
127
|
+
<text x="758" y="536" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Expo Native</text>
|
|
128
|
+
<text x="758" y="564" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">React Native Reusables</text>
|
|
129
|
+
<text x="758" y="585" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">iOS + Android</text>
|
|
130
|
+
<rect x="620" y="646" width="370" height="112" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
131
|
+
<rect x="636" y="658" width="88" height="88" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
132
|
+
<g transform="translate(651 673) scale(2.4166666666666665)"><path d="M10.18 0c-2.081 0-3.807 1.608-4 3.64H4.019A4.033 4.033 0 0 0 0 7.66v4.017h1.498a2.13 2.13 0 0 1 2.143 2.144 2.13 2.13 0 0 1-2.143 2.143H0V24h8.036v-1.498a2.13 2.13 0 0 1 2.144-2.143 2.13 2.13 0 0 1 2.143 2.143V24h4.018a4.03 4.03 0 0 0 4.018-4.018v-2.163C22.392 17.627 24 15.901 24 13.821s-1.608-3.807-3.64-4V7.66a4.03 4.03 0 0 0-4.019-4.018h-2.162C13.986 1.608 12.26 0 10.179 0m0 1.875a2.13 2.13 0 0 1 2.143 2.143v1.498h4.018a2.13 2.13 0 0 1 2.143 2.143v4.018h1.498a2.13 2.13 0 0 1 2.143 2.144 2.13 2.13 0 0 1-2.143 2.143h-1.498v4.018a2.13 2.13 0 0 1-2.143 2.143h-2.162c-.193-2.033-1.919-3.64-4-3.64s-3.806 1.607-3.998 3.64H1.875V17.82c2.033-.192 3.64-1.918 3.64-3.998s-1.607-3.807-3.64-4V7.66a2.13 2.13 0 0 1 2.143-2.143h4.018V4.018a2.13 2.13 0 0 1 2.144-2.143" fill="#b9f500"/></g>
|
|
133
|
+
<path d="M 734 660 L 734 744" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
134
|
+
<text x="758" y="688" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">WXT Extension</text>
|
|
135
|
+
<text x="758" y="716" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">Chrome · Firefox · Edge</text>
|
|
136
|
+
<text x="758" y="737" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">MV3 background + side panel</text>
|
|
137
|
+
<rect x="620" y="798" width="370" height="112" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
138
|
+
<rect x="636" y="810" width="88" height="88" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
139
|
+
<g transform="translate(651 825) scale(2.4166666666666665)"><path d="M12.0111 0c-.85 0-1.5392.6891-1.5392 1.5392 0 .8501.6891 1.5393 1.5392 1.5393.595 0 1.11-.338 1.3662-.832 2.2208 1.2675 3.847 5.4728 3.847 10.3623 0 2.0715-.2891 4.056-.825 5.7685a.3215.3215 0 0 0 .2107.403.322.322 0 0 0 .4033-.2111c.5558-1.7763.8542-3.8251.8542-5.9604 0-5.1927-1.7717-9.686-4.3206-11.0027.001-.0223.0035-.0443.0035-.0669 0-.85-.6891-1.5392-1.5393-1.5392zm0 .6432a.896.896 0 1 1 0 1.792.896.896 0 1 1 0-1.792zm-5.486 4.3052c-2.067.0074-3.6473.6646-4.3885 1.9485-.7375 1.2774-.5267 2.971.5113 4.7813a.3217.3217 0 0 0 .558-.32C2.271 9.7274 2.089 8.266 2.6938 7.2185c.821-1.422 3.033-1.9552 5.9321-1.4271a.3216.3216 0 0 0 .1153-.6329c-.784-.1428-1.5271-.2125-2.216-.21zm11.0522.0176a.3216.3216 0 0 0-.0084.6432c1.8337.0239 3.1556.5956 3.7502 1.6256.8192 1.419.1798 3.5947-1.7182 5.837a.322.322 0 0 0 .0377.4535.3215.3215 0 0 0 .4532-.0377c2.0535-2.426 2.7708-4.8661 1.7845-6.5744-.7257-1.257-2.26-1.9207-4.299-1.9472zm-2.6984.2924a.3225.3225 0 0 0-.0647.0072c-1.8568.3979-3.8333 1.1755-5.7314 2.2714-4.5699 2.6384-7.5924 6.4948-7.3601 9.3717-.4726.2628-.7928.7664-.7928 1.3455 0 .85.6892 1.5392 1.5393 1.5392.85 0 1.5392-.6891 1.5392-1.5392 0-.8501-.6891-1.5393-1.5392-1.5393-.038 0-.0754.003-.1128.0057-.1002-2.5597 2.7434-6.1412 7.048-8.6265 1.8413-1.063 3.7551-1.8163 5.5445-2.1997a.3217.3217 0 0 0-.07-.636zm-2.8787 6.2364a1.1192 1.1192 0 0 0-.2243.0255c-.6012.1301-.983.7225-.8533 1.3238.1302.6012.7226.9832 1.3238.8533.6012-.1302.9832-.7226.8533-1.3238-.1139-.526-.5816-.8844-1.0995-.8788zM4.532 13.341a.321.321 0 0 0-.2318.0835.3214.3214 0 0 0-.0214.4542c1.2682 1.3936 2.9157 2.701 4.7946 3.7857 4.4146 2.5489 9.1056 3.2849 11.5608 1.8392a1.53 1.53 0 0 0 .8966.2899c.8501 0 1.5392-.6891 1.5392-1.5392 0-.8501-.689-1.5393-1.5392-1.5393-.85 0-1.5392.6892-1.5392 1.5393 0 .276.0737.5344.201.7584-2.2448 1.214-6.631.5002-10.7976-1.9054-1.8228-1.0524-3.418-2.3181-4.6404-3.6614a.3206.3206 0 0 0-.2226-.1049zm-2.0628 4.0172a.896.896 0 1 1 0 1.792.896.896 0 1 1 0-1.792zm19.0616 0a.896.896 0 1 1 0 1.792.891.891 0 0 1-.5864-.2194c-.0025-.004-.0039-.0083-.0066-.0123a.3195.3195 0 0 0-.0957-.0914.896.896 0 0 1 .6887-1.4689zm-14.0045 1.368a.3215.3215 0 0 0-.3207.4296C8.2793 22.154 10.036 24 12.0111 24c1.4406 0 2.7735-.9822 3.8128-2.711a.3215.3215 0 0 0-.11-.4413.3219.3219 0 0 0-.4415.11c-.934 1.5537-2.0812 2.399-3.2613 2.399-1.6407 0-3.2075-1.6465-4.2-4.4179a.3216.3216 0 0 0-.2848-.2126z" fill="#51dce9"/></g>
|
|
140
|
+
<path d="M 734 812 L 734 896" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
141
|
+
<text x="758" y="840" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="22" font-weight="500" text-anchor="start" letter-spacing="0">Electron Desktop</text>
|
|
142
|
+
<text x="758" y="868" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="16" font-weight="400" text-anchor="start" letter-spacing="0">macOS · Windows · Linux</text>
|
|
143
|
+
<text x="758" y="889" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="13" font-weight="400" text-anchor="start" letter-spacing="0">electron-updater enabled</text>
|
|
144
|
+
<rect x="1130" y="474" width="208" height="296" rx="14" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
145
|
+
<rect x="1190" y="490" width="88" height="88" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
146
|
+
<g transform="translate(1200 500) scale(2.8333333333333335)"><path d="M23.245 6.49L24 4.533l-.031-.121-7.473 1.967c.797-1.153.523-2.078.523-2.078s-2.387 1.524-4.193 1.485c-1.804-.04-2.387-.52-5.155.362-2.768.882-3.551 3.59-4.351 4.173-.804.583-3.32 2.477-3.32 2.477l.006.034 2.27-.724s-.622.585-1.945 2.37l-.062-.057.002.011s1.064 1.626 2.107 1.324a2.14 2.14 0 0 0 .353-.147c.419.234.967.463 1.572.525 0 0-.41-.475-.752-1.017l.238-.154.865.318-.096-.812c.003-.003.006-.003.008-.006l.849.311-.105-.738a5.65 5.65 0 0 1 .322-.158l.885-3.345 3.662-2.497-.291.733c-.741 1.826-2.135 2.256-2.135 2.256l-.582.22c-.433.512-.614.637-.764 2.353.348-.088.682-.107.984-.028 1.564.421 2.107 2.307 1.685 2.827-.104.13-.356.354-.673.617H7.77l-.008.514-.065.051h-.645l-.009.504-.17.127c-.607.011-1.373-.518-1.373-.518 0 .481.401 1.225.401 1.225l.07-.034-.061.045s1.625 1.083 2.646.681c.91-.356 3.263-2.213 5.296-3.093l6.15-1.62.811-2.1-4.688 1.235v-1.889l5.5-1.448.811-2.1-6.31 1.662V8.367zm-11.163 4l1.459-.384.02.074-.455 1.179-1.513.398zm.503 2.526l-1.512.398.489-1.266 1.459-.385.02.074zm1.971-.424l-1.513.398.49-1.266 1.459-.385.02.073Z" fill="#f7f5f0"/></g>
|
|
147
|
+
<g transform="translate(1306 490) scale(0.7083333333333334)"><path d="m12 1.608 12 20.784H0Z" fill="#f7f5f0"/></g>
|
|
148
|
+
<path d="M 1148 602 L 1320 602" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
149
|
+
<text x="1234" y="643" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="25" font-weight="500" text-anchor="middle" letter-spacing="0">Fastify Backend</text>
|
|
150
|
+
<text x="1234" y="675" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="400" text-anchor="middle" letter-spacing="0">API + business logic</text>
|
|
151
|
+
<rect x="1435" y="342" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
152
|
+
<rect x="1451" y="354" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
153
|
+
<g transform="translate(1456 373) scale(1.0833333333333333)"><path d="M24 0V24l-9.365-8.045V24H0V0ZM2.942 21.087h8.751V9.563l9.365 8.204V2.919L2.942 2.914Z" fill="#35d6a8"/></g>
|
|
154
|
+
<g transform="translate(1484 373) scale(1.0833333333333333)"><path d="M5.353 11.823a1.036 1.036 0 0 0-.395-1.422 1.063 1.063 0 0 0-1.437.399L.138 16.702a1.035 1.035 0 0 0 .395 1.422 1.063 1.063 0 0 0 1.437-.398l3.383-5.903Zm11.216 0a1.036 1.036 0 0 0-.394-1.422 1.064 1.064 0 0 0-1.438.399l-3.382 5.902a1.036 1.036 0 0 0 .394 1.422c.506.283 1.15.104 1.438-.398l3.382-5.903Zm7.293-4.525a1.036 1.036 0 0 0-.395-1.422 1.062 1.062 0 0 0-1.437.399l-3.383 5.902a1.036 1.036 0 0 0 .395 1.422 1.063 1.063 0 0 0 1.437-.399l3.383-5.902Zm-11.219 0a1.035 1.035 0 0 0-.394-1.422 1.064 1.064 0 0 0-1.438.398l-3.382 5.903a1.036 1.036 0 0 0 .394 1.422c.506.282 1.15.104 1.438-.399l3.382-5.902Z" fill="#e9f600"/></g>
|
|
155
|
+
<path d="M 1527 356 L 1527 416" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
156
|
+
<text x="1547" y="373" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Neon + Drizzle</text>
|
|
157
|
+
<text x="1547" y="397" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">Postgres + ORM</text>
|
|
158
|
+
<text x="1547" y="417" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">reviewed migrations</text>
|
|
159
|
+
<rect x="1435" y="438" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
160
|
+
<rect x="1451" y="450" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
161
|
+
<g transform="translate(1455 454) scale(2.3333333333333335)"><path d="m21.47 20.829-2.881-2.881a.572.572 0 0 0-.7-.084 6.854 6.854 0 0 1-7.081 0 .576.576 0 0 0-.7.084l-2.881 2.881a.576.576 0 0 0-.103.69.57.57 0 0 0 .166.186 12 12 0 0 0 14.113 0 .58.58 0 0 0 .239-.423.576.576 0 0 0-.172-.453Zm.002-17.668-2.88 2.88a.569.569 0 0 1-.701.084A6.857 6.857 0 0 0 8.724 8.08a6.862 6.862 0 0 0-1.222 3.692 6.86 6.86 0 0 0 .978 3.764.573.573 0 0 1-.083.699l-2.881 2.88a.567.567 0 0 1-.864-.063A11.993 11.993 0 0 1 6.771 2.7a11.99 11.99 0 0 1 14.637-.405.566.566 0 0 1 .232.418.57.57 0 0 1-.168.448Zm-7.118 12.261a3.427 3.427 0 1 0 0-6.854 3.427 3.427 0 0 0 0 6.854Z" fill="#f7f5f0"/></g>
|
|
162
|
+
<path d="M 1527 452 L 1527 512" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
163
|
+
<text x="1547" y="469" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Clerk Auth</text>
|
|
164
|
+
<text x="1547" y="493" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">identity + sessions</text>
|
|
165
|
+
<text x="1547" y="513" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">verified server-side</text>
|
|
166
|
+
<rect x="1435" y="534" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
167
|
+
<rect x="1451" y="546" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
168
|
+
<g transform="translate(1456 565) scale(1.0833333333333333)"><path d="M4.3036.3999c-1.5246 0-3.2129.1508-4.303.4136v14.9997c.3083.1722.8432.28 1.5632.28.7404 0 1.2553-.1072 1.5433-.28v-5.2323a14.8588 14.8588 0 0 0 2.121.1512h.3294l2.8604 5.0588c.432.195 1.0288.3024 1.9348.3024.8033 0 1.38-.1104 1.6476-.3024l-3.437-5.8358c1.4195-.8004 2.326-2.2698 2.326-4.4964C10.8894 1.827 8.4232.4 4.3037.4zm15.4543 0c-1.3788 0-2.624.2707-3.6901.7945-2.4552 1.203-3.9609 3.7376-3.9609 7.3627 0 4.8245 2.6552 7.7155 7.1659 7.7155.9 0 1.5868-.3014 2.005.2554.4194.5568-.3582 1.2165-.7746 1.5105-1.6338 1.1544-5.7217-.1024-9.4908-.4804C5.5994 17.015.9264 16.3009.146 19.1928c-.4104 1.5264.1225 2.5013.6421 3.0503 1.044 1.1046 2.882 1.357 4.344 1.357a13.959 13.959 0 0 0 2.0508-.1558 1.311 1.311 0 0 0 1.023-.8063c.1674-.4254.0861-.904-.212-1.2562a1.3464 1.3464 0 0 0-1.2352-.4523c-1.5012.2706-3.6213.8685-4.4343.0105-.2748-.291-.2268-1.0037 0-1.2257.6048-.8748 4.493-.5393 8.4127-.0293 4.329.4344 8.4023 1.8609 10.945.6351.9955-.48 2.318-1.1941 2.318-3.792h-.0012c0-1.1473-.1489-2.274-.4476-3.3797-1.3818.1872-2.4783.2857-3.2883.2941-2.845 0-4.869-1.4484-4.869-5.0963 0-3.648 2.0461-5.1573 5.0179-5.1573 1.2011 0 2.129.2512 3.1405.7336.1062-.9234-.1058-2.1605-.5906-2.8523-.78-.4608-2.0014-.6703-3.2038-.6703zM4.51 3.1889c2.0579 0 3.2108.7111 3.2108 2.4421 0 1.6824-1.0912 2.3554-2.8816 2.3554a10.2838 10.2838 0 0 1-1.7706-.1511V3.3166a7.7782 7.7782 0 0 1 1.4413-.1277z" fill="#ff3b3f"/></g>
|
|
169
|
+
<g transform="translate(1484 565) scale(1.0833333333333333)"><path d="M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z" fill="#635bff"/></g>
|
|
170
|
+
<path d="M 1527 548 L 1527 608" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
171
|
+
<text x="1547" y="565" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">RevenueCat + Stripe</text>
|
|
172
|
+
<text x="1547" y="589" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">subscriptions + payments</text>
|
|
173
|
+
<text x="1547" y="609" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">billing integration + shared entitlements</text>
|
|
174
|
+
<rect x="1435" y="630" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
175
|
+
<rect x="1451" y="642" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
176
|
+
<g transform="translate(1457 652.6666666666666) scale(0.6666666666666666)">
|
|
177
|
+
<path d="M38.5717 0L6.29575 59.0738L0 54.6586L29.8639 0H38.5717ZM39.0214 0L71.2973 59.0738L77.5931 54.6586L47.7292 0H39.0214Z" fill="url(#ably-symbol-a)"/>
|
|
178
|
+
<path d="M70.8477 59.4213L38.7966 34.3201L6.74548 59.4213L13.2865 64L38.7966 44.0294L64.3066 64L70.8477 59.4213Z" fill="url(#ably-symbol-b)"/>
|
|
179
|
+
<defs>
|
|
180
|
+
<linearGradient id="ably-symbol-a" x1="10.9472" y1="74.8439" x2="64.9206" y2="14.9005" gradientUnits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.461" stop-color="#FF4712"/><stop offset="1" stop-color="#FF0000"/></linearGradient>
|
|
181
|
+
<linearGradient id="ably-symbol-b" x1="21.4169" y1="78.7187" x2="53.3166" y2="43.2904" gradientUnits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.461" stop-color="#FF4712"/><stop offset="1" stop-color="#FF0000"/></linearGradient>
|
|
182
|
+
</defs>
|
|
183
|
+
</g>
|
|
184
|
+
<path d="M 1527 644 L 1527 704" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
185
|
+
<text x="1547" y="661" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Ably Realtime</text>
|
|
186
|
+
<text x="1547" y="685" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">scoped invalidations</text>
|
|
187
|
+
<text x="1547" y="705" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">outbox → event → client refetch</text>
|
|
188
|
+
<rect x="1435" y="726" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
189
|
+
<rect x="1451" y="738" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
190
|
+
<g transform="translate(1457 744) scale(2.1666666666666665)"><path d="m8.213.063 8.879 12.136-8.67 11.739h2.476l8.665-11.735-8.89-12.14Zm4.728 0 9.02 11.992-9.018 11.883h2.496L24 12.656v-1.199L15.434.063ZM7.178 2.02.01 11.398l-.01 1.2 7.203 9.644 1.238-1.676-6.396-8.556 6.361-8.313Z" fill="#f48120"/></g>
|
|
191
|
+
<path d="M 1527 740 L 1527 800" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
192
|
+
<text x="1547" y="757" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Assets Worker</text>
|
|
193
|
+
<text x="1547" y="781" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">PRIVATE R2 assets binding</text>
|
|
194
|
+
<text x="1547" y="801" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">assets.example.com · authorized reads</text>
|
|
195
|
+
<rect x="1435" y="822" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
196
|
+
<rect x="1451" y="834" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
197
|
+
<g transform="translate(1456 853) scale(1.0833333333333333)"><path d="m8.213.063 8.879 12.136-8.67 11.739h2.476l8.665-11.735-8.89-12.14Zm4.728 0 9.02 11.992-9.018 11.883h2.496L24 12.656v-1.199L15.434.063ZM7.178 2.02.01 11.398l-.01 1.2 7.203 9.644 1.238-1.676-6.396-8.556 6.361-8.313Z" fill="#f48120"/></g>
|
|
198
|
+
<g transform="translate(1484 853) scale(1.0833333333333333)"><path d="M12.0111 0c-.85 0-1.5392.6891-1.5392 1.5392 0 .8501.6891 1.5393 1.5392 1.5393.595 0 1.11-.338 1.3662-.832 2.2208 1.2675 3.847 5.4728 3.847 10.3623 0 2.0715-.2891 4.056-.825 5.7685a.3215.3215 0 0 0 .2107.403.322.322 0 0 0 .4033-.2111c.5558-1.7763.8542-3.8251.8542-5.9604 0-5.1927-1.7717-9.686-4.3206-11.0027.001-.0223.0035-.0443.0035-.0669 0-.85-.6891-1.5392-1.5393-1.5392zm0 .6432a.896.896 0 1 1 0 1.792.896.896 0 1 1 0-1.792zm-5.486 4.3052c-2.067.0074-3.6473.6646-4.3885 1.9485-.7375 1.2774-.5267 2.971.5113 4.7813a.3217.3217 0 0 0 .558-.32C2.271 9.7274 2.089 8.266 2.6938 7.2185c.821-1.422 3.033-1.9552 5.9321-1.4271a.3216.3216 0 0 0 .1153-.6329c-.784-.1428-1.5271-.2125-2.216-.21zm11.0522.0176a.3216.3216 0 0 0-.0084.6432c1.8337.0239 3.1556.5956 3.7502 1.6256.8192 1.419.1798 3.5947-1.7182 5.837a.322.322 0 0 0 .0377.4535.3215.3215 0 0 0 .4532-.0377c2.0535-2.426 2.7708-4.8661 1.7845-6.5744-.7257-1.257-2.26-1.9207-4.299-1.9472zm-2.6984.2924a.3225.3225 0 0 0-.0647.0072c-1.8568.3979-3.8333 1.1755-5.7314 2.2714-4.5699 2.6384-7.5924 6.4948-7.3601 9.3717-.4726.2628-.7928.7664-.7928 1.3455 0 .85.6892 1.5392 1.5393 1.5392.85 0 1.5392-.6891 1.5392-1.5392 0-.8501-.6891-1.5393-1.5392-1.5393-.038 0-.0754.003-.1128.0057-.1002-2.5597 2.7434-6.1412 7.048-8.6265 1.8413-1.063 3.7551-1.8163 5.5445-2.1997a.3217.3217 0 0 0-.07-.636zm-2.8787 6.2364a1.1192 1.1192 0 0 0-.2243.0255c-.6012.1301-.983.7225-.8533 1.3238.1302.6012.7226.9832 1.3238.8533.6012-.1302.9832-.7226.8533-1.3238-.1139-.526-.5816-.8844-1.0995-.8788zM4.532 13.341a.321.321 0 0 0-.2318.0835.3214.3214 0 0 0-.0214.4542c1.2682 1.3936 2.9157 2.701 4.7946 3.7857 4.4146 2.5489 9.1056 3.2849 11.5608 1.8392a1.53 1.53 0 0 0 .8966.2899c.8501 0 1.5392-.6891 1.5392-1.5392 0-.8501-.689-1.5393-1.5392-1.5393-.85 0-1.5392.6892-1.5392 1.5393 0 .276.0737.5344.201.7584-2.2448 1.214-6.631.5002-10.7976-1.9054-1.8228-1.0524-3.418-2.3181-4.6404-3.6614a.3206.3206 0 0 0-.2226-.1049zm-2.0628 4.0172a.896.896 0 1 1 0 1.792.896.896 0 1 1 0-1.792zm19.0616 0a.896.896 0 1 1 0 1.792.891.891 0 0 1-.5864-.2194c-.0025-.004-.0039-.0083-.0066-.0123a.3195.3195 0 0 0-.0957-.0914.896.896 0 0 1 .6887-1.4689zm-14.0045 1.368a.3215.3215 0 0 0-.3207.4296C8.2793 22.154 10.036 24 12.0111 24c1.4406 0 2.7735-.9822 3.8128-2.711a.3215.3215 0 0 0-.11-.4413.3219.3219 0 0 0-.4415.11c-.934 1.5537-2.0812 2.399-3.2613 2.399-1.6407 0-3.2075-1.6465-4.2-4.4179a.3216.3216 0 0 0-.2848-.2126z" fill="#51dce9"/></g>
|
|
199
|
+
<path d="M 1527 836 L 1527 896" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
200
|
+
<text x="1547" y="853" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Updater Worker</text>
|
|
201
|
+
<text x="1547" y="877" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">PRIVATE R2 updates binding</text>
|
|
202
|
+
<text x="1547" y="897" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">updates.example.com → electron-updater</text>
|
|
203
|
+
<rect x="1435" y="918" width="430" height="88" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
204
|
+
<rect x="1451" y="930" width="64" height="64" rx="11" fill="#07121d" stroke="#34424e" stroke-width="1.15"/>
|
|
205
|
+
<g transform="translate(1456 949) scale(1.0833333333333333)"><path d="M16.5088 16.8447c.1475-.5068.0908-.9707-.1553-1.3154-.2246-.3164-.6045-.499-1.0615-.5205l-8.6592-.1123a.1559.1559 0 0 1-.1333-.0713c-.0283-.042-.0351-.0986-.021-.1553.0278-.084.1123-.1484.2036-.1562l8.7359-.1123c1.0351-.0489 2.1601-.8868 2.5537-1.9136l.499-1.3013c.0215-.0561.0293-.1128.0147-.168-.5625-2.5463-2.835-4.4453-5.5499-4.4453-2.5039 0-4.6284 1.6177-5.3876 3.8614-.4927-.3658-1.1187-.5625-1.794-.499-1.2026.119-2.1665 1.083-2.2861 2.2856-.0283.31-.0069.6128.0635.894C1.5683 13.171 0 14.7754 0 16.752c0 .1748.0142.3515.0352.5273.0141.083.0844.1475.1689.1475h15.9814c.0909 0 .1758-.0645.2032-.1553l.12-.4268zm2.7568-5.5634c-.0771 0-.1611 0-.2383.0112-.0566 0-.1054.0415-.127.0976l-.3378 1.1744c-.1475.5068-.0918.9707.1543 1.3164.2256.3164.6055.498 1.0625.5195l1.8437.1133c.0557 0 .1055.0263.1329.0703.0283.043.0351.1074.0214.1562-.0283.084-.1132.1485-.204.1553l-1.921.1123c-1.041.0488-2.1582.8867-2.5527 1.914l-.1406.3585c-.0283.0713.0215.1416.0986.1416h6.5977c.0771 0 .1474-.0489.169-.126.1122-.4082.1757-.837.1757-1.2803 0-2.6025-2.125-4.727-4.7344-4.727" fill="#f48120"/></g>
|
|
206
|
+
<g transform="translate(1484 949) scale(1.0833333333333333)"><path d="m12 1.608 12 20.784H0Z" fill="#f7f5f0"/></g>
|
|
207
|
+
<path d="M 1527 932 L 1527 992" fill="none" stroke="#34424e" stroke-width="1" stroke-linecap="round"/>
|
|
208
|
+
<text x="1547" y="949" fill="#f7f5f0" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="18" font-weight="500" text-anchor="start" letter-spacing="0">Cloudflare DNS + Vercel</text>
|
|
209
|
+
<text x="1547" y="973" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="14" font-weight="400" text-anchor="start" letter-spacing="0">app domain: DNS-only → Vercel</text>
|
|
210
|
+
<text x="1547" y="993" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="12" font-weight="400" text-anchor="start" letter-spacing="0">DNSSEC · assets/updates Worker domains</text>
|
|
211
|
+
<path d="M 620 398 C 541.8 398 528.2 393 450 393" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
212
|
+
<path d="M 620 550 C 541.8 550 528.2 507 450 507" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
213
|
+
<path d="M 620 550 C 541.8 550 528.2 621 450 621" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
214
|
+
<path d="M 620 702 C 541.8 702 528.2 735 450 735" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
215
|
+
<path d="M 620 854 C 541.8 854 528.2 849 450 849" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
216
|
+
<path d="M 990 398 C 1054.4 398 1065.6 520 1130 520" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" marker-end="url(#arrow-white)"/>
|
|
217
|
+
<path d="M 990 550 C 1054.4 550 1065.6 590 1130 590" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" marker-end="url(#arrow-white)"/>
|
|
218
|
+
<path d="M 990 702 C 1054.4 702 1065.6 660 1130 660" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" marker-end="url(#arrow-white)"/>
|
|
219
|
+
<path d="M 990 854 C 1054.4 854 1065.6 730 1130 730" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" marker-end="url(#arrow-white)"/>
|
|
220
|
+
<path d="M 1338 500 C 1382.62 500 1390.38 386 1435 386" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
221
|
+
<circle cx="1435" cy="386" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
222
|
+
<path d="M 1338 555 C 1382.62 555 1390.38 482 1435 482" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
223
|
+
<circle cx="1435" cy="482" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
224
|
+
<path d="M 1338 610 C 1382.62 610 1390.38 578 1435 578" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
225
|
+
<circle cx="1435" cy="578" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
226
|
+
<path d="M 1338 665 C 1382.62 665 1390.38 674 1435 674" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
227
|
+
<circle cx="1435" cy="674" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
228
|
+
<path d="M 1338 720 C 1382.62 720 1390.38 770 1435 770" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
229
|
+
<circle cx="1435" cy="770" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
230
|
+
<rect x="126" y="1050" width="1668" height="86" rx="12" fill="url(#card-fill)" stroke="#73777b" stroke-width="1.15"/>
|
|
231
|
+
<path d="M 246 1093 L 350 1093" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round" marker-end="url(#arrow-white)"/>
|
|
232
|
+
<text x="374" y="1100" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="400" text-anchor="start" letter-spacing="0">runtime API flow</text>
|
|
233
|
+
<path d="M 720 1093 L 824 1093" fill="none" stroke="#e9f600" stroke-width="3" stroke-linecap="round" stroke-dasharray="10 8" marker-end="url(#arrow-yellow)"/>
|
|
234
|
+
<text x="848" y="1100" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="400" text-anchor="start" letter-spacing="0">deploy / publish</text>
|
|
235
|
+
<path d="M 1198 1093 L 1302 1093" fill="none" stroke="#f7f5f0" stroke-width="3" stroke-linecap="round"/>
|
|
236
|
+
<circle cx="1302" cy="1093" r="8.5" fill="#b9f500" filter="url(#endpoint-glow)"/>
|
|
237
|
+
<text x="1332" y="1100" fill="#c4c7ca" font-family="Inter, Helvetica Neue, Arial, sans-serif" font-size="17" font-weight="400" text-anchor="start" letter-spacing="0">backend service connection</text>
|
|
238
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="78" height="64" viewBox="0 0 78 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M38.5717 0L6.29575 59.0738L0 54.6586L29.8639 0H38.5717ZM39.0214 0L71.2973 59.0738L77.5931 54.6586L47.7292 0H39.0214Z" fill="url(#ably-symbol-a)"/>
|
|
3
|
+
<path d="M70.8477 59.4213L38.7966 34.3201L6.74548 59.4213L13.2865 64L38.7966 44.0294L64.3066 64L70.8477 59.4213Z" fill="url(#ably-symbol-b)"/>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="ably-symbol-a" x1="10.9472" y1="74.8439" x2="64.9206" y2="14.9005" gradientUnits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.461" stop-color="#FF4712"/><stop offset="1" stop-color="#FF0000"/></linearGradient>
|
|
6
|
+
<linearGradient id="ably-symbol-b" x1="21.4169" y1="78.7187" x2="53.3166" y2="43.2904" gradientUnits="userSpaceOnUse"><stop stop-color="#FF5416"/><stop offset="0.461" stop-color="#FF4712"/><stop offset="1" stop-color="#FF0000"/></linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="1820" height="2199" viewBox="0 0 1820 2199" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M1604.59 26.7414C1694.33 -39.6752 1821.31 25.3379 1819.89 136.971L1809.28 971.026C1774.28 969.39 1738.87 969.434 1703.15 971.237C1334.16 989.855 1017.8 1191.61 837.641 1484.06L122.496 1416.65C-0.793297 1405.03 -44.6847 1247.41 54.8543 1173.73L1604.59 26.7414Z" fill="white"/>
|
|
3
|
+
<path d="M1795.36 2064.84C1793.79 2188.66 1640.25 2245.21 1558.74 2151.98L1083.84 1608.79C1214.01 1305.09 1479.98 1071.11 1809.07 987.262L1795.36 2064.84Z" fill="white"/>
|
|
4
|
+
</svg>
|
|
@@ -71,6 +71,13 @@ const MODULE_CONTRIBUTIONS = Object.freeze({
|
|
|
71
71
|
environment: EMPTY,
|
|
72
72
|
crons: EMPTY,
|
|
73
73
|
}),
|
|
74
|
+
'electron-updater': Object.freeze({
|
|
75
|
+
module: 'electron-updater',
|
|
76
|
+
environment: Object.freeze([
|
|
77
|
+
{ name: 'DESKTOP_UPDATE_BASE_URL', defaultValue: 'https://updates.example.com' },
|
|
78
|
+
]),
|
|
79
|
+
crons: EMPTY,
|
|
80
|
+
}),
|
|
74
81
|
});
|
|
75
82
|
function collectEnvironmentFromRegistry(modules, registry) {
|
|
76
83
|
const byName = new Map();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const MODULE_IDS: readonly ["web", "mobile", "api", "desktop", "extension", "db", "auth", "billing", "storage", "native-subscriptions"];
|
|
1
|
+
export declare const MODULE_IDS: readonly ["web", "mobile", "api", "desktop", "extension", "db", "auth", "billing", "storage", "native-subscriptions", "electron-updater"];
|
|
2
2
|
export type ModuleId = (typeof MODULE_IDS)[number];
|
|
3
3
|
export type ModuleKind = 'app' | 'feature';
|
|
4
4
|
export type ModuleDefinition = {
|
|
@@ -33,5 +33,5 @@ export declare class ModuleResolutionError extends Error {
|
|
|
33
33
|
export declare function isModuleId(value: unknown): value is ModuleId;
|
|
34
34
|
export declare function createModuleRegistry(definitions: readonly ModuleDefinition[]): ModuleRegistry;
|
|
35
35
|
export declare const DEFAULT_MODULE_DEFINITIONS: readonly ModuleDefinition[];
|
|
36
|
-
export declare const DEFAULT_MODULE_REGISTRY: Readonly<Record<"auth" | "billing" | "storage" | "api" | "desktop" | "web" | "mobile" | "extension" | "db" | "native-subscriptions", ModuleDefinition>>;
|
|
36
|
+
export declare const DEFAULT_MODULE_REGISTRY: Readonly<Record<"electron-updater" | "auth" | "billing" | "storage" | "api" | "desktop" | "web" | "mobile" | "extension" | "db" | "native-subscriptions", ModuleDefinition>>;
|
|
37
37
|
export declare function resolveModules(requested: readonly string[], registry?: ModuleRegistry): ModuleResolution;
|
|
@@ -9,6 +9,7 @@ export const MODULE_IDS = [
|
|
|
9
9
|
'billing',
|
|
10
10
|
'storage',
|
|
11
11
|
'native-subscriptions',
|
|
12
|
+
'electron-updater',
|
|
12
13
|
];
|
|
13
14
|
export class ModuleRegistryError extends Error {
|
|
14
15
|
code;
|
|
@@ -119,6 +120,7 @@ const DEFAULT_MODULE_DEFINITION_INPUTS = [
|
|
|
119
120
|
{ id: 'billing', kind: 'feature', requires: ['auth'], conflicts: [] },
|
|
120
121
|
{ id: 'storage', kind: 'feature', requires: ['auth'], conflicts: [] },
|
|
121
122
|
{ id: 'native-subscriptions', kind: 'feature', requires: ['mobile', 'billing'], conflicts: [] },
|
|
123
|
+
{ id: 'electron-updater', kind: 'feature', requires: ['desktop'], conflicts: [] },
|
|
122
124
|
];
|
|
123
125
|
export const DEFAULT_MODULE_DEFINITIONS = Object.freeze(DEFAULT_MODULE_DEFINITION_INPUTS.map(freezeDefinition));
|
|
124
126
|
export const DEFAULT_MODULE_REGISTRY = createModuleRegistry(DEFAULT_MODULE_DEFINITIONS);
|
|
@@ -162,14 +164,20 @@ export function resolveModules(requested, registry = DEFAULT_MODULE_REGISTRY) {
|
|
|
162
164
|
const modules = Object.freeze([...new Set(conflicts.flat())].sort(compareModules));
|
|
163
165
|
throw new ModuleResolutionError('MODULE_CONFLICT', `Conflicting modules: ${conflicts.map(([left, right]) => `${left} + ${right}`).join(', ')}`, modules);
|
|
164
166
|
}
|
|
167
|
+
// Resolution must have one stable representation regardless of whether a
|
|
168
|
+
// dependency was requested directly or discovered while walking another
|
|
169
|
+
// module. Without this final normalization, adding a module to an existing
|
|
170
|
+
// project could produce a different manifest order than creating the same
|
|
171
|
+
// topology directly (for example, adding electron-updater after db/auth).
|
|
172
|
+
const resolvedModules = normalizeModuleList(ordered);
|
|
165
173
|
const requestedSet = new Set(requestedModules);
|
|
166
|
-
const dependencyAddedModules =
|
|
167
|
-
const dependencyEdges =
|
|
174
|
+
const dependencyAddedModules = resolvedModules.filter((moduleId) => !requestedSet.has(moduleId));
|
|
175
|
+
const dependencyEdges = resolvedModules.flatMap((moduleId) => registry[moduleId].requires
|
|
168
176
|
.filter((required) => resolved.has(required))
|
|
169
177
|
.map((required) => Object.freeze({ module: moduleId, requires: required })));
|
|
170
178
|
return Object.freeze({
|
|
171
179
|
requestedModules,
|
|
172
|
-
resolvedModules
|
|
180
|
+
resolvedModules,
|
|
173
181
|
dependencyAddedModules: Object.freeze(dependencyAddedModules),
|
|
174
182
|
dependencyEdges: Object.freeze(dependencyEdges),
|
|
175
183
|
});
|