@adonis-agora/media 0.10.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +46 -6
- package/dist/assets/spa/assets/index--0MZJr6W.css +1 -0
- package/dist/assets/spa/assets/index-Dvw2uJpF.js +83 -0
- package/dist/assets/spa/assets/index-Dvw2uJpF.js.map +1 -0
- package/dist/assets/spa/index.html +20 -0
- package/dist/configure.d.ts +6 -2
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +8 -2
- package/dist/configure.js.map +1 -1
- package/dist/providers/dashboard_provider.d.ts +29 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -0
- package/dist/providers/dashboard_provider.js +520 -0
- package/dist/providers/dashboard_provider.js.map +1 -0
- package/dist/src/dashboard/auth.d.ts +76 -0
- package/dist/src/dashboard/auth.d.ts.map +1 -0
- package/dist/src/dashboard/auth.js +134 -0
- package/dist/src/dashboard/auth.js.map +1 -0
- package/dist/src/dashboard/cookie.d.ts +20 -0
- package/dist/src/dashboard/cookie.d.ts.map +1 -0
- package/dist/src/dashboard/cookie.js +44 -0
- package/dist/src/dashboard/cookie.js.map +1 -0
- package/dist/src/dashboard/define_config.d.ts +56 -0
- package/dist/src/dashboard/define_config.d.ts.map +1 -0
- package/dist/src/dashboard/define_config.js +5 -0
- package/dist/src/dashboard/define_config.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +10 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +9 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/dashboard/object_insights.d.ts +42 -0
- package/dist/src/dashboard/object_insights.d.ts.map +1 -0
- package/dist/src/dashboard/object_insights.js +42 -0
- package/dist/src/dashboard/object_insights.js.map +1 -0
- package/dist/src/dashboard/service.d.ts +215 -0
- package/dist/src/dashboard/service.d.ts.map +1 -0
- package/dist/src/dashboard/service.js +470 -0
- package/dist/src/dashboard/service.js.map +1 -0
- package/dist/src/dashboard/spa.d.ts +29 -0
- package/dist/src/dashboard/spa.d.ts.map +1 -0
- package/dist/src/dashboard/spa.js +47 -0
- package/dist/src/dashboard/spa.js.map +1 -0
- package/dist/src/dashboard/types.d.ts +201 -0
- package/dist/src/dashboard/types.d.ts.map +1 -0
- package/dist/src/dashboard/types.js +10 -0
- package/dist/src/dashboard/types.js.map +1 -0
- package/dist/stubs/config/media_dashboard.stub +39 -0
- package/package.json +15 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @adonis-agora/media
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`ad61387`](https://github.com/DavideCarvalho/adonis-agora-media/commit/ad61387aba714ba85ce6a6cf810b97259db46a93) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - The management console now ships **embedded** — `@adonis-agora/media/dashboard_provider` mounts the same React SPA + JSON API `@adonis-agora/media-dashboard` always has, straight from this package. `node ace configure @adonis-agora/media` registers it automatically (alongside publishing `config/media_dashboard.ts`); no separate `@adonis-agora/media-dashboard` install is required to get the console.
|
|
8
|
+
|
|
9
|
+
New subpath exports:
|
|
10
|
+
|
|
11
|
+
- `@adonis-agora/media/dashboard_provider` — the provider (routes: SPA + assets, JSON API, session auth). Reads the same `media_dashboard` config key `@adonis-agora/media-dashboard`'s provider always did, so an existing `config/media_dashboard.ts` keeps working unchanged if you switch to this provider.
|
|
12
|
+
- `@adonis-agora/media/dashboard` — `defineConfig`/`MediaDashboardConfig` for authoring `config/media_dashboard.ts`, `DashboardService`/`DashboardError`, the built-in session-auth helpers (`resolveConsoleAuth`, `signSessionCookie`, `verifySessionCookie`), `ObjectInsightProvider`/`sanitizeInsight`, and the dashboard's JSON API types.
|
|
13
|
+
|
|
14
|
+
`MediaDashboardConfig` also gains `enabled` (default `true`) — set `false` to register the provider without mounting any route.
|
|
15
|
+
|
|
16
|
+
At build time, `pnpm build` copies `@adonis-agora/media-dashboard`'s built SPA (`dist/spa`) into this package's own `dist/assets/spa`, mirroring `@adonis-agora/durable`'s embedded-dashboard pattern. `@adonis-agora/media-dashboard` remains published, standalone-installable, and its own provider (`@adonis-agora/media-dashboard/media_dashboard_provider`) still works — see that package's own changeset for what changed there. Register only one of the two dashboard providers in a given app.
|
|
17
|
+
|
|
3
18
|
## 0.10.4
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -9,11 +9,11 @@ you reuse your existing `local` / `s3` / `gcs` disks — this package never reim
|
|
|
9
9
|
|
|
10
10
|
This is the **core library**: `MediaLibrary`, `AttachmentManager`, the `MediaStore` SPI (in-memory +
|
|
11
11
|
Lucid), the `ImageProcessor` SPI (sharp), the bundled `disks.s3()` driver, proxy/direct/resumable
|
|
12
|
-
uploads, configurable delivery, the provider + `defineConfig`, and a testing kit.
|
|
12
|
+
uploads, configurable delivery, the provider + `defineConfig`, and a testing kit. The management
|
|
13
|
+
**console ships embedded** — registering `@adonis-agora/media/dashboard_provider` is all a consuming
|
|
14
|
+
app needs (see [Dashboard](#dashboard) below); no separate install. Pair it with
|
|
13
15
|
[`@adonis-agora/media-react`](https://github.com/DavideCarvalho/adonis-media/tree/master/packages/react)
|
|
14
|
-
for a browser upload client
|
|
15
|
-
[`@adonis-agora/media-dashboard`](https://github.com/DavideCarvalho/adonis-media/tree/master/packages/dashboard)
|
|
16
|
-
for a management console.
|
|
16
|
+
for a browser upload client.
|
|
17
17
|
|
|
18
18
|
## Subpath exports
|
|
19
19
|
|
|
@@ -23,6 +23,8 @@ The package uses **subpath exports** (the Agora idiom), so heavy backends stay o
|
|
|
23
23
|
|---|---|
|
|
24
24
|
| `@adonis-agora/media` | barrel — `defineConfig`, `stores`, `processors`, `disks`, `uploadSessions`, `MediaManager`, `MediaLibrary`, `AttachmentManager`, `UploadManager`, `ResumableUploadManager`, `MediaDeliveryHandler`, SPIs, errors |
|
|
25
25
|
| `@adonis-agora/media/media_provider` | the service provider (binds `MediaManager`, mounts optional upload/TUS routes) |
|
|
26
|
+
| `@adonis-agora/media/dashboard_provider` | the embedded management-console provider (React SPA + JSON API) |
|
|
27
|
+
| `@adonis-agora/media/dashboard` | `defineConfig` + types for `config/media_dashboard.ts`, `DashboardService`, the session-auth helpers, `ObjectInsightProvider` |
|
|
26
28
|
| `@adonis-agora/media/configure` | `node ace configure` hook |
|
|
27
29
|
| `@adonis-agora/media/single-file` | `storeSingleFile` / `removeSingleFile` / `isSingleFileStoreAvailable` — lets other packages delegate single-file uploads (e.g. avatars) to media without a hard dependency |
|
|
28
30
|
| `@adonis-agora/media/stores/lucid` | the Lucid `MediaStore` (`@adonisjs/lucid` peer) |
|
|
@@ -41,8 +43,10 @@ npm i @adonis-agora/media
|
|
|
41
43
|
node ace configure @adonis-agora/media
|
|
42
44
|
```
|
|
43
45
|
|
|
44
|
-
`configure` registers the provider
|
|
45
|
-
migration (delete it if you only use
|
|
46
|
+
`configure` registers the media provider **and the dashboard provider**, publishes `config/media.ts`
|
|
47
|
+
and `config/media_dashboard.ts`, and publishes the `media` table migration (delete it if you only use
|
|
48
|
+
the in-memory store; otherwise `node ace migration:run`). The management console is live at
|
|
49
|
+
`/media/dashboard` the moment your app boots — see [Dashboard](#dashboard).
|
|
46
50
|
|
|
47
51
|
Optional peers, loaded lazily only when selected:
|
|
48
52
|
|
|
@@ -167,6 +171,42 @@ The bundled `disks.s3()` driver adds extended operations (copy/move/deleteMany/l
|
|
|
167
171
|
native multipart over the optional AWS SDK peer. Drive it from the browser with
|
|
168
172
|
[`@adonis-agora/media-react`](https://github.com/DavideCarvalho/adonis-media/tree/master/packages/react).
|
|
169
173
|
|
|
174
|
+
## Dashboard
|
|
175
|
+
|
|
176
|
+
A management console — browse buckets, watch resumable uploads in progress, upload objects, and
|
|
177
|
+
copy/move/delete across buckets — ships **embedded** in this package: registering
|
|
178
|
+
`@adonis-agora/media/dashboard_provider` (done automatically by `node ace configure`) is all a
|
|
179
|
+
consuming app needs. No separate package install, no separate provider registration.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// adonisrc.ts
|
|
183
|
+
providers: [
|
|
184
|
+
() => import('@adonis-agora/media/media_provider'),
|
|
185
|
+
() => import('@adonis-agora/media/dashboard_provider'),
|
|
186
|
+
]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
// config/media_dashboard.ts
|
|
191
|
+
import { defineConfig } from '@adonis-agora/media/dashboard'
|
|
192
|
+
import { middleware } from '#start/kernel'
|
|
193
|
+
|
|
194
|
+
export default defineConfig({
|
|
195
|
+
basePath: '/media/dashboard', // where the SPA mounts (default)
|
|
196
|
+
actions: true, // enable copy/move/delete (default: false — read-only)
|
|
197
|
+
disks: ['s3', 'backups'], // browsable disks (default: derived from media config)
|
|
198
|
+
middleware: middleware.auth(), // gate the whole console — SPA + API
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The console reads/writes through the real `@adonis-agora/media` surface (disk
|
|
203
|
+
`list`/`stat`/`copy`/`move`/`deleteMany`, the resumable session store, the `MediaStore`) — nothing
|
|
204
|
+
about storage is reimplemented. Full config reference, routes, and folder-operations semantics are
|
|
205
|
+
documented in [`@adonis-agora/media-dashboard`](https://github.com/DavideCarvalho/adonis-media/tree/master/packages/dashboard),
|
|
206
|
+
which is now the **build-time source** of the console's SPA bundle (embedded here at build time) and
|
|
207
|
+
remains installable **standalone** — its own provider is a thin delegate to this one, kept for hosts
|
|
208
|
+
that already register it directly. Don't register both providers in the same app.
|
|
209
|
+
|
|
170
210
|
## Diagnostics
|
|
171
211
|
|
|
172
212
|
Lifecycle events (`attach`, `delete`, `conversion`, `attachment.create`, `attachment.delete`) are
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-4{bottom:1rem}.left-1\/2{left:50%}.right-4{right:1rem}.top-0{top:0}.top-1\/2{top:50%}.z-10{z-index:10}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-px{margin-top:1px}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1\.5{height:.375rem}.h-14{height:3.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-\[86vh\]{height:86vh}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-\[calc\(100vh-3rem\)\]{max-height:calc(100vh - 3rem)}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-\[320px\]{min-height:320px}.w-14{width:3.5rem}.w-28{width:7rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-56{min-width:14rem}.min-w-\[150px\]{min-width:150px}.min-w-\[5rem\]{min-width:5rem}.max-w-5xl{max-width:64rem}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[110px_1fr\]{grid-template-columns:110px 1fr}.grid-cols-\[120px_1fr\]{grid-template-columns:120px 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-2{row-gap:.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-line-soft>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:color-mix(in srgb,var(--line-soft) calc(var(--tw-divide-opacity, 1) * 100%),transparent)}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-accent\/30{border-color:color-mix(in srgb,var(--accent) 30%,transparent)}.border-accent\/40{border-color:color-mix(in srgb,var(--accent) 40%,transparent)}.border-accent\/50{border-color:color-mix(in srgb,var(--accent) 50%,transparent)}.border-accent\/60{border-color:color-mix(in srgb,var(--accent) 60%,transparent)}.border-bad\/30{border-color:color-mix(in srgb,var(--bad) 30%,transparent)}.border-bad\/40{border-color:color-mix(in srgb,var(--bad) 40%,transparent)}.border-border{--tw-border-opacity: 1;border-color:color-mix(in srgb,var(--line) calc(var(--tw-border-opacity, 1) * 100%),transparent)}.border-transparent{border-color:transparent}.border-warn\/30{border-color:color-mix(in srgb,var(--warn) 30%,transparent)}.border-zinc-600{--tw-border-opacity: 1;border-color:rgb(82 82 91 / var(--tw-border-opacity, 1))}.bg-accent\/10{background-color:color-mix(in srgb,var(--accent) 10%,transparent)}.bg-accent\/15{background-color:color-mix(in srgb,var(--accent) 15%,transparent)}.bg-accent\/5{background-color:color-mix(in srgb,var(--accent) 5%,transparent)}.bg-accent\/80{background-color:color-mix(in srgb,var(--accent) 80%,transparent)}.bg-bad\/10{background-color:color-mix(in srgb,var(--bad) 10%,transparent)}.bg-bad\/15{background-color:color-mix(in srgb,var(--bad) 15%,transparent)}.bg-black\/20{background-color:#0003}.bg-black\/30{background-color:#0000004d}.bg-black\/80{background-color:#000c}.bg-panel{--tw-bg-opacity: 1;background-color:color-mix(in srgb,var(--panel) calc(var(--tw-bg-opacity, 1) * 100%),transparent)}.bg-panel-2{--tw-bg-opacity: 1;background-color:color-mix(in srgb,var(--panel-2) calc(var(--tw-bg-opacity, 1) * 100%),transparent)}.bg-transparent{background-color:transparent}.bg-warn\/10{background-color:color-mix(in srgb,var(--warn) 10%,transparent)}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-zinc-800{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.bg-zinc-800\/40{background-color:#27272a66}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pr-1\.5{padding-right:.375rem}.pr-2{padding-right:.5rem}.text-left{text-align:left}.text-center{text-align:center}.align-top{vertical-align:top}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[9px\]{font-size:9px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.leading-none{line-height:1}.tracking-\[0\.2em\]{letter-spacing:.2em}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-accent{--tw-text-opacity: 1;color:color-mix(in srgb,var(--accent) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.text-accent\/80{color:color-mix(in srgb,var(--accent) 80%,transparent)}.text-bad{--tw-text-opacity: 1;color:color-mix(in srgb,var(--bad) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.text-foreground{--tw-text-opacity: 1;color:color-mix(in srgb,var(--text) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.text-sky-400{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.text-warn{--tw-text-opacity: 1;color:color-mix(in srgb,var(--warn) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.text-zinc-100{--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.text-zinc-300{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.text-zinc-400{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-zinc-500{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.text-zinc-600{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.text-zinc-700{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-accent\/50{--tw-ring-color: color-mix(in srgb, var(--accent) 50% , transparent)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{--bg: #09090b;--panel: #0c0c0f;--panel-2: #101017;--line: #1c1c22;--line-soft: #16161a;--text: #e7e7ea;--muted: #76767f;--good: #34d399;--warn: #fbbf24;--bad: #f87171;--accent: #22d3ee}*{box-sizing:border-box}html,body,#root{height:100%}body{margin:0;background:var(--bg);color:var(--text);font-family:Space Grotesk,ui-sans-serif,system-ui,sans-serif;-webkit-font-smoothing:antialiased}.app-bg{position:fixed;top:0;right:0;bottom:0;left:0;z-index:0;pointer-events:none;background-image:radial-gradient(900px 400px at 78% -8%,color-mix(in srgb,var(--accent) 8%,transparent),transparent 70%),linear-gradient(to right,var(--line-soft) 1px,transparent 1px),linear-gradient(to bottom,var(--line-soft) 1px,transparent 1px);background-size:100% 100%,44px 44px,44px 44px;-webkit-mask-image:linear-gradient(to bottom,black,black 60%,transparent);mask-image:linear-gradient(to bottom,black,black 60%,transparent);opacity:.5}.mono{font-family:JetBrains Mono,ui-monospace,monospace}.tnum{font-variant-numeric:tabular-nums}.s-ok{color:var(--good)}.s-live{color:#60a5fa}.s-warn{color:var(--warn)}.s-error{color:var(--bad)}.s-info{color:#a78bfa}.s-idle{color:#71717a}.dot{width:7px;height:7px;border-radius:999px;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 18%,transparent)}.pulse{animation:pulse 1.6s ease-in-out infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rise{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}.rise{animation:rise .32s cubic-bezier(.2,.7,.2,1) both}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:#26262c;border:3px solid var(--bg);border-radius:999px}.placeholder\:text-zinc-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.placeholder\:text-zinc-600::placeholder{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.placeholder\:text-zinc-700::-moz-placeholder{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.placeholder\:text-zinc-700::placeholder{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.hover\:bg-accent\/20:hover{background-color:color-mix(in srgb,var(--accent) 20%,transparent)}.hover\:bg-bad\/20:hover{background-color:color-mix(in srgb,var(--bad) 20%,transparent)}.hover\:bg-zinc-800:hover{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-800\/60:hover{background-color:#27272a99}.hover\:bg-zinc-900\/40:hover{background-color:#18181b66}.hover\:bg-zinc-900\/50:hover{background-color:#18181b80}.hover\:text-accent:hover{--tw-text-opacity: 1;color:color-mix(in srgb,var(--accent) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.hover\:text-bad:hover{--tw-text-opacity: 1;color:color-mix(in srgb,var(--bad) calc(var(--tw-text-opacity, 1) * 100%),transparent)}.hover\:text-sky-300:hover{--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.hover\:text-zinc-100:hover{--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.hover\:text-zinc-200:hover{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.hover\:text-zinc-300:hover{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.hover\:opacity-100:hover{opacity:1}.focus\:border-accent\/40:focus{border-color:color-mix(in srgb,var(--accent) 40%,transparent)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring\/40:focus-visible{--tw-ring-color: color-mix(in srgb, var(--accent) 40% , transparent)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-40:disabled{opacity:.4}@media(min-width:768px){.md\:grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}}
|