@owlmeans/web-client 0.1.18-rc.6 → 0.1.18-rc.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +247 -43
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-client/SKILL.md +71 -47
- package/build/components/dispatcher/component.d.ts.map +1 -1
- package/build/components/dispatcher/component.js +55 -9
- package/build/components/dispatcher/component.js.map +1 -1
- package/build/components/dispatcher/parametrise.d.ts.map +1 -1
- package/build/components/dispatcher/parametrise.js +0 -3
- package/build/components/dispatcher/parametrise.js.map +1 -1
- package/build/components/dispatcher/types.d.ts +2 -2
- package/build/components/dispatcher/types.d.ts.map +1 -1
- package/build/context.d.ts.map +1 -1
- package/build/context.js +2 -1
- package/build/context.js.map +1 -1
- package/build/entrypoints.d.ts +16 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +20 -0
- package/build/entrypoints.js.map +1 -0
- package/build/exports.d.ts +4 -2
- package/build/exports.d.ts.map +1 -1
- package/build/exports.js +2 -2
- package/build/exports.js.map +1 -1
- package/build/i18n/auth-be.json +32 -0
- package/build/i18n/auth-de.json +32 -0
- package/build/i18n/auth-en.json +32 -0
- package/build/i18n/auth-es.json +32 -0
- package/build/i18n/auth-fr.json +38 -0
- package/build/i18n/auth-pl.json +32 -0
- package/build/i18n/auth-ru.json +32 -0
- package/build/i18n/auth-uk.json +32 -0
- package/build/i18n.js +10 -8
- package/build/i18n.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/login/consts.d.ts +47 -0
- package/build/login/consts.d.ts.map +1 -0
- package/build/login/consts.js +49 -0
- package/build/login/consts.js.map +1 -0
- package/build/login/consts.local.d.ts +22 -0
- package/build/login/consts.local.d.ts.map +1 -0
- package/build/login/consts.local.js +48 -0
- package/build/login/consts.local.js.map +1 -0
- package/build/login/index.d.ts +9 -0
- package/build/login/index.d.ts.map +1 -0
- package/build/login/index.js +8 -0
- package/build/login/index.js.map +1 -0
- package/build/login/pump.d.ts +20 -0
- package/build/login/pump.d.ts.map +1 -0
- package/build/login/pump.js +46 -0
- package/build/login/pump.js.map +1 -0
- package/build/login/redirect.d.ts +9 -0
- package/build/login/redirect.d.ts.map +1 -0
- package/build/login/redirect.js +47 -0
- package/build/login/redirect.js.map +1 -0
- package/build/login/screen.d.ts +19 -0
- package/build/login/screen.d.ts.map +1 -0
- package/build/login/screen.js +119 -0
- package/build/login/screen.js.map +1 -0
- package/build/login/service.d.ts +10 -0
- package/build/login/service.d.ts.map +1 -0
- package/build/login/service.js +17 -0
- package/build/login/service.js.map +1 -0
- package/build/login/surrogate.d.ts +37 -0
- package/build/login/surrogate.d.ts.map +1 -0
- package/build/login/surrogate.js +173 -0
- package/build/login/surrogate.js.map +1 -0
- package/build/login/types.d.ts +10 -0
- package/build/login/types.d.ts.map +1 -0
- package/build/login/types.js +2 -0
- package/build/login/types.js.map +1 -0
- package/build/login/view.d.ts +4 -0
- package/build/login/view.d.ts.map +1 -0
- package/build/login/view.js +12 -0
- package/build/login/view.js.map +1 -0
- package/build/main.d.ts +9 -1
- package/build/main.d.ts.map +1 -1
- package/build/main.js +18 -5
- package/build/main.js.map +1 -1
- package/build/middleware.d.ts +1 -1
- package/build/middleware.d.ts.map +1 -1
- package/build/middleware.js +7 -6
- package/build/middleware.js.map +1 -1
- package/build/service.js +1 -1
- package/build/service.js.map +1 -1
- package/build/types.d.ts +2 -1
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +5 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/package.json +21 -20
- package/src/components/dispatcher/component.tsx +71 -8
- package/src/components/dispatcher/parametrise.tsx +0 -3
- package/src/components/dispatcher/types.ts +2 -2
- package/src/context.ts +2 -2
- package/src/entrypoints.ts +20 -0
- package/src/exports.ts +8 -2
- package/src/i18n/auth-be.json +32 -0
- package/src/i18n/auth-de.json +32 -0
- package/src/i18n/auth-en.json +32 -0
- package/src/i18n/auth-es.json +32 -0
- package/src/i18n/auth-fr.json +38 -0
- package/src/i18n/auth-pl.json +32 -0
- package/src/i18n/auth-ru.json +32 -0
- package/src/i18n/auth-uk.json +32 -0
- package/src/i18n.ts +10 -8
- package/src/index.ts +2 -1
- package/src/login/consts.local.ts +52 -0
- package/src/login/consts.ts +50 -0
- package/src/login/index.ts +8 -0
- package/src/login/pump.ts +53 -0
- package/src/login/redirect.ts +59 -0
- package/src/login/screen.tsx +141 -0
- package/src/login/service.ts +19 -0
- package/src/login/surrogate.ts +207 -0
- package/src/login/types.ts +10 -0
- package/src/login/view.tsx +22 -0
- package/src/main.tsx +19 -6
- package/src/middleware.ts +9 -12
- package/src/service.ts +1 -1
- package/src/types.local.ts +5 -0
- package/src/types.ts +2 -1
- package/tests/surrogate.spec.ts +74 -0
- package/tsconfig.json +1 -1
- package/build/modules.d.ts +0 -2
- package/build/modules.d.ts.map +0 -1
- package/build/modules.js +0 -8
- package/build/modules.js.map +0 -1
- package/src/modules.ts +0 -9
package/README.md
CHANGED
|
@@ -1,81 +1,285 @@
|
|
|
1
1
|
# @owlmeans/web-client
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
- Re-exports route constants: `BASE`, `HOME`, `ROOT`, `GUEST`
|
|
11
|
-
- `Module<T>` — typed client module interface for `.call()` API requests
|
|
3
|
+
Browser application bootstrap for OwlMeans: the web context factory (auth service, IndexedDB, the
|
|
4
|
+
default OwlMeans router and the login host already appended), the React mount helpers, the
|
|
5
|
+
framework entrypoint list (dispatcher, login surrogate) and the browser login plugins. An app uses
|
|
6
|
+
it directly when it renders its own UI and wants only the framework plumbing. An app that wants the
|
|
7
|
+
shadcn panel shell, forms, the styled sign-in screen and the socket reload prompt builds on
|
|
8
|
+
[`@owlmeans/web-panel`](../web-panel), whose `makeContext` composes this one. `@owlmeans/mui-panel`
|
|
9
|
+
is the legacy MUI layer — start nothing new there. React Native apps use the `native` monorepo.
|
|
12
10
|
|
|
13
11
|
## Installation
|
|
14
12
|
|
|
15
13
|
```bash
|
|
16
|
-
bun add @owlmeans/web-client
|
|
14
|
+
bun add @owlmeans/web-client@^0.1.18-rc.61
|
|
17
15
|
```
|
|
18
16
|
|
|
17
|
+
## Concepts
|
|
18
|
+
|
|
19
|
+
- **Web context** — `makeContext(cfg)` builds the page's one client context: `makeClientContext`,
|
|
20
|
+
`extractPrimaryHost` (host and port from `window.location`), the web auth service
|
|
21
|
+
(`context.auth()`), the IndexedDB service, the `AUTH_RESOURCE` client resource, the default router
|
|
22
|
+
plugin from `@owlmeans/web-router`, and the login host (`context.login()`) with the redirect and
|
|
23
|
+
surrogate plugins. An app factory calls it and appends its own idempotent `append*` mixins.
|
|
24
|
+
- **Framework entrypoints** — `entrypoints` is `@owlmeans/client-auth`'s list plus the
|
|
25
|
+
`authProtocols.dispatcher` screen (`Dispatcher`) and the `authProtocols.surrogate` screen
|
|
26
|
+
(`SurrogateScreen`). Every app spreads it into the one list it registers.
|
|
27
|
+
- **Dispatcher** — the return leg of authentication. It adopts a token carried in `AUTH_QUERY`,
|
|
28
|
+
lets the login plugin `resume` an existing session, or renders the registered sign-in screen
|
|
29
|
+
(`context.login().screen()`, falling back to `FallbackLoginScreen`). It never starts a flow itself.
|
|
30
|
+
- **Login plugins** — `makeRedirectLoginPlugin` (every ordinary tab, priority 0) and
|
|
31
|
+
`makeSurrogateLoginPlugin` (a framed app or the surrogate window itself,
|
|
32
|
+
`SURROGATE_LOGIN_PRIORITY`) decide *where* the sign-in round trip runs.
|
|
33
|
+
- **Session loss** — `appendWebAuthService` wraps every guarded backend entrypoint: an `AuthUnknown`
|
|
34
|
+
ending in `:invalid` clears the token, and clearing the token sends the document to the
|
|
35
|
+
dispatcher URL.
|
|
36
|
+
- **Global overlay slot** — `children` of `renderApp` / `WebApp` render inside the context provider
|
|
37
|
+
and before the router, so a dialog or toast surface mounted there survives navigation.
|
|
38
|
+
|
|
19
39
|
## Usage
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
### 1. Config, types and the context factory
|
|
22
42
|
|
|
23
|
-
```
|
|
24
|
-
|
|
43
|
+
```ts
|
|
44
|
+
// src/types.ts
|
|
45
|
+
import type { AppConfig, AppContext } from '@owlmeans/web-client'
|
|
25
46
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
export interface Config extends AppConfig {}
|
|
48
|
+
export interface Context<C extends Config = Config> extends AppContext<C> {}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// src/config.ts
|
|
53
|
+
import { config } from '@owlmeans/web-client'
|
|
54
|
+
import { commonConfig, MY_APP_WEB } from 'my-app-common'
|
|
55
|
+
import type { Config } from './types.js'
|
|
56
|
+
|
|
57
|
+
export default config<Config>(MY_APP_WEB, commonConfig as Partial<Config>)
|
|
30
58
|
```
|
|
31
59
|
|
|
32
|
-
|
|
60
|
+
```ts
|
|
61
|
+
// src/context.ts
|
|
62
|
+
import { makeContext as makeWebContext, useContext as useWebContext } from '@owlmeans/web-client'
|
|
63
|
+
import { appendStateResource } from '@owlmeans/state'
|
|
64
|
+
import { PROJECT_STATE } from './consts.js'
|
|
65
|
+
import type { Config, Context } from './types.js'
|
|
66
|
+
|
|
67
|
+
export const useContext = (): Context => useWebContext<Config, Context>()
|
|
33
68
|
|
|
34
|
-
|
|
35
|
-
|
|
69
|
+
export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T => {
|
|
70
|
+
// Router, auth service, IndexedDB and the login host are already on the context.
|
|
71
|
+
const context = makeWebContext<C, T>(cfg)
|
|
72
|
+
appendStateResource<C, T>(context, PROJECT_STATE)
|
|
36
73
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
elevate(modules, manager.back.account.base)
|
|
74
|
+
return context
|
|
75
|
+
}
|
|
40
76
|
```
|
|
41
77
|
|
|
42
|
-
|
|
78
|
+
### 2. Shared screen declarations and the entrypoint list
|
|
79
|
+
|
|
80
|
+
Screens are declared once in the shared package, next to the API protocols:
|
|
43
81
|
|
|
44
|
-
```
|
|
45
|
-
|
|
82
|
+
```ts
|
|
83
|
+
// my-app-common/src/protocols/web.ts
|
|
84
|
+
import { DEFAULT_GUARD } from '@owlmeans/auth-common'
|
|
85
|
+
import { BASE, HOME } from '@owlmeans/context'
|
|
86
|
+
import { openProtocol } from '@owlmeans/entrypoint'
|
|
87
|
+
import { frontend, route } from '@owlmeans/route'
|
|
46
88
|
|
|
47
|
-
const
|
|
48
|
-
|
|
89
|
+
const aliases = { projects: 'my-app-web:projects', project: 'my-app-web:project' } as const
|
|
90
|
+
|
|
91
|
+
const base = openProtocol(route(BASE, '/', frontend()))
|
|
92
|
+
const projects = openProtocol(route(aliases.projects, '/projects', frontend({ parent: base })), {
|
|
93
|
+
guards: DEFAULT_GUARD,
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
export const webProtocols = {
|
|
97
|
+
base,
|
|
98
|
+
// A parent frontend route needs a `default: true` child, or it renders blank at its own path.
|
|
99
|
+
home: openProtocol(route(HOME, '/', frontend({ parent: base, default: true }))),
|
|
100
|
+
projects,
|
|
101
|
+
project: openProtocol(route(aliases.project, '/:id', frontend({ parent: projects }))),
|
|
102
|
+
}
|
|
49
103
|
```
|
|
50
104
|
|
|
51
|
-
|
|
105
|
+
The browser binds the whole API tree and attaches a component to each screen:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// src/entrypoints.ts
|
|
109
|
+
import { bindAll, bindScreen, entrypoints as frameworkEntrypoints, handler } from '@owlmeans/web-client'
|
|
110
|
+
import { apiProtocols, webProtocols } from 'my-app-common'
|
|
111
|
+
import { PublicLayout } from './layout/public.js'
|
|
112
|
+
import { HomeScreen } from './screens/home.js'
|
|
113
|
+
import { ProjectsScreen } from './screens/projects.js'
|
|
114
|
+
import { ProjectScreen } from './screens/project.js'
|
|
115
|
+
|
|
116
|
+
export const appEntrypoints = [
|
|
117
|
+
...frameworkEntrypoints,
|
|
118
|
+
...bindAll(apiProtocols),
|
|
119
|
+
bindScreen(webProtocols.base, handler(PublicLayout)),
|
|
120
|
+
bindScreen(webProtocols.home, handler(HomeScreen)),
|
|
121
|
+
bindScreen(webProtocols.projects, handler(ProjectsScreen)),
|
|
122
|
+
bindScreen(webProtocols.project, handler(ProjectScreen)),
|
|
123
|
+
]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 3. Boot
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
// src/index.tsx
|
|
130
|
+
import './index.css'
|
|
131
|
+
import { renderApp } from '@owlmeans/web-client'
|
|
132
|
+
import { MY_APP_API, MY_APP_WEB } from 'my-app-common'
|
|
133
|
+
import config from './config.js'
|
|
134
|
+
import { makeContext } from './context.js'
|
|
135
|
+
import { appEntrypoints } from './entrypoints.js'
|
|
136
|
+
import { AppOverlays } from './components/overlays.js'
|
|
137
|
+
|
|
138
|
+
const context = makeContext(config)
|
|
139
|
+
|
|
140
|
+
// Before the first render: the router builds its route table once, from what is registered.
|
|
141
|
+
context.registerEntrypoints(appEntrypoints)
|
|
142
|
+
context.serviceRoute(MY_APP_WEB, true)
|
|
143
|
+
context.serviceRoute(MY_APP_API, true)
|
|
52
144
|
|
|
53
|
-
|
|
145
|
+
// The third argument is the global overlay slot — rendered above the router, never torn down.
|
|
146
|
+
renderApp(context, undefined, <AppOverlays />)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`renderApp(context, opts?, children?)` mounts `WebApp` (i18n provider, context provider, router)
|
|
150
|
+
into `#root` (`DEFAULT_ROOT`) once `DOMContentLoaded` fires. `RenderOptions` changes that:
|
|
151
|
+
`domId`, `onReady: false` (mount immediately), `hydrate: true` (`hydrateRoot` instead of
|
|
152
|
+
`createRoot`) and `debug`.
|
|
153
|
+
|
|
154
|
+
### 4. Calling protocols from a view model
|
|
54
155
|
|
|
55
|
-
|
|
156
|
+
```ts
|
|
157
|
+
// src/screens/project.vm.ts
|
|
158
|
+
import { EntrypointOutcome } from '@owlmeans/entrypoint'
|
|
159
|
+
import { apiProtocols, webProtocols } from 'my-app-common'
|
|
160
|
+
import type { Context } from '../types.js'
|
|
56
161
|
|
|
57
|
-
|
|
162
|
+
export const loadProject = async (ctx: Context, id: string) => {
|
|
163
|
+
// Value only — an error in the reply is thrown.
|
|
164
|
+
const project = await ctx.entrypoint(apiProtocols.project.get).call({ params: { id } })
|
|
58
165
|
|
|
59
|
-
|
|
166
|
+
// Value plus outcome, when the outcome decides what happens next.
|
|
167
|
+
const { value: slot, outcome } = await ctx.entrypoint(apiProtocols.project.slot)
|
|
168
|
+
.invoke({ params: { id } })
|
|
169
|
+
if (outcome !== EntrypointOutcome.Ok) {
|
|
170
|
+
return { project, slot: null }
|
|
171
|
+
}
|
|
60
172
|
|
|
61
|
-
|
|
173
|
+
// A screen is addressed, never called.
|
|
174
|
+
const shareUrl = await ctx.entrypoint(webProtocols.project).url({ params: { id } }, { absolute: true })
|
|
62
175
|
|
|
63
|
-
|
|
176
|
+
return { project, slot, shareUrl }
|
|
177
|
+
}
|
|
178
|
+
```
|
|
64
179
|
|
|
65
|
-
###
|
|
180
|
+
### 5. File drop target
|
|
66
181
|
|
|
67
|
-
|
|
182
|
+
`Uploader` wraps `react-dropzone`; its props are `DropzoneOptions` plus an optional `Root`
|
|
183
|
+
component and `rootProps`. `ImageUploader` is the same control with `maxSize` defaulted to 5 MB.
|
|
68
184
|
|
|
69
|
-
|
|
185
|
+
```tsx
|
|
186
|
+
import type { FC } from 'react'
|
|
187
|
+
import { ImageUploader } from '@owlmeans/web-client'
|
|
70
188
|
|
|
71
|
-
|
|
189
|
+
export const LogoDrop: FC<{ onFile: (file: File) => void }> = ({ onFile }) =>
|
|
190
|
+
<ImageUploader maxFiles={1} accept={{ 'image/*': [] }} onDrop={files => onFile(files[0])}>
|
|
191
|
+
<span>Drop a logo here or click to choose one</span>
|
|
192
|
+
</ImageUploader>
|
|
193
|
+
```
|
|
72
194
|
|
|
73
|
-
##
|
|
195
|
+
## API
|
|
74
196
|
|
|
197
|
+
### Context, rendering and services
|
|
198
|
+
|
|
199
|
+
| Symbol | Kind | Purpose |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| `makeContext<C, T>(cfg)` | function | Web context factory — see *Concepts* |
|
|
202
|
+
| `useContext<C, T>()` | hook | The current context, from React |
|
|
203
|
+
| `renderApp<C, T>(context, opts?, children?)` | function | Mount `WebApp` for a context; `children` are the global overlay slot |
|
|
204
|
+
| `render(node, opts?)` | function | Mount any React node with the same readiness, root and hydration handling |
|
|
205
|
+
| `WebApp` | component | `I18nContext` + `@owlmeans/client`'s `App` (context provider and router) |
|
|
206
|
+
| `RenderOptions` | type | `domId?`, `onReady?`, `hydrate?`, `debug?` |
|
|
207
|
+
| `AppConfig`, `AppContext` | type | Web config and context; the context carries `auth()` and `login()` |
|
|
208
|
+
| `DEFAULT_ROOT` | const | `'root'` — the default mount element id |
|
|
209
|
+
| `extractPrimaryHost(context)` | function | Copy `window.location` host and port into `cfg.primaryHost` / `cfg.primaryPort` |
|
|
210
|
+
| `makeAuthWebService(alias?)` | function | `@owlmeans/client-auth`'s service whose `update(undefined)` redirects to the dispatcher |
|
|
211
|
+
| `appendWebAuthService(ctx, alias?)` | function | Register that service, `authMiddleware` and the session-loss middleware; expose `context.auth()` |
|
|
212
|
+
| `provide` | const | Deprecated, always `undefined`; routing resolves its compiler from the active router plugin |
|
|
213
|
+
| `UploaderError`, `FileUploadingError` | class | Uploader errors registered with `ResilientError` |
|
|
214
|
+
|
|
215
|
+
### Entrypoints and authentication screens
|
|
216
|
+
|
|
217
|
+
| Symbol | Kind | Purpose |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| `entrypoints` | const | Framework bindings: client-auth's list, the dispatcher screen, the surrogate screen |
|
|
220
|
+
| `Dispatcher` | component | The dispatcher screen, built on `DispatcherHOC` |
|
|
221
|
+
| `parametriseDispatcher(defaults, Component?)` | function | A dispatcher with default props (`payload`, `alias`, ...) merged under the routed ones |
|
|
222
|
+
| `ParametrisedProps` | type | Routed entrypoint params plus `DispatcherProps` |
|
|
223
|
+
| `SurrogateScreen` | component | The screen the surrogate login window renders |
|
|
224
|
+
| `LoginSurrogateView`, `SurrogateStage`, `SurrogateViewProps` | component, enum, type | The surrogate window's status panel |
|
|
225
|
+
| `appendWebLogin(ctx)` | function | `appendLogin` plus the redirect and surrogate plugins |
|
|
226
|
+
| `makeRedirectLoginPlugin()`, `makeSurrogateLoginPlugin()` | function | The two shipped `LoginPlugin`s |
|
|
227
|
+
| `awaitSurrogate(...)` | function | The single waiter for a surrogate window's hand-back |
|
|
228
|
+
| `REDIRECT_LOGIN`, `SURROGATE_LOGIN`, `SURROGATE_LOGIN_PRIORITY` | const | Plugin aliases and the surrogate plugin's priority |
|
|
229
|
+
|
|
230
|
+
### Components
|
|
231
|
+
|
|
232
|
+
| Symbol | Kind | Purpose |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| `Uploader` | component | `react-dropzone` root with a hidden input |
|
|
235
|
+
| `ImageUploader` | component | `Uploader` with a 5 MB `maxSize` default |
|
|
236
|
+
| `UploaderProps`, `UploaderRootProps` | type | Uploader props |
|
|
237
|
+
|
|
238
|
+
### Re-exports
|
|
239
|
+
|
|
240
|
+
| Symbol | From |
|
|
241
|
+
|---|---|
|
|
242
|
+
| `handler` | `@owlmeans/client` |
|
|
243
|
+
| `config` | `@owlmeans/client-context` |
|
|
244
|
+
| `service` | `@owlmeans/config` |
|
|
245
|
+
| `AppType`, `HOME`, `ROOT`, `BASE`, `GUEST` | `@owlmeans/context` |
|
|
246
|
+
| `bind`, `bindAll`, `bindScreen`, `clientRequestHelper`, `provideRequest` (deprecated, use `clientRequestHelper.provideRequest`), `stab`; types `ClientEntrypoint`, `Module` | `@owlmeans/client-entrypoint` |
|
|
247
|
+
| `route`, `frontend` | `@owlmeans/route` |
|
|
248
|
+
| type `Route` (`ClientRoute`) | `@owlmeans/client-route` |
|
|
249
|
+
|
|
250
|
+
Importing the package also registers the `auth` library i18n namespace in all seven supported
|
|
251
|
+
languages.
|
|
252
|
+
|
|
253
|
+
## Common pitfalls
|
|
254
|
+
|
|
255
|
+
- **Register entrypoints before rendering.** The router builds its route table once, from the
|
|
256
|
+
entrypoints the context knows about at mount.
|
|
257
|
+
- **Spread the framework `entrypoints`.** Without them there is no dispatcher and no surrogate
|
|
258
|
+
screen, and `useLogin` throws `Entrypoint dispatcher not found`.
|
|
259
|
+
- **Bind every API declaration the browser calls, including route parents.** An unbound protocol
|
|
260
|
+
throws "entrypoint not found" before any network call — `bindAll` over the whole tree avoids it.
|
|
261
|
+
- **A parent frontend route needs a `default: true` child**, or it renders blank at its own path.
|
|
262
|
+
- **Do not pass `provide`.** Routing comes from the router plugin (`@owlmeans/web-router` by
|
|
263
|
+
default); react-router is only available through the opt-in `@owlmeans/web-router-react-router`.
|
|
264
|
+
- **Mount dialogs and toast surfaces in the overlay slot**, not inside a route — a dialog inside a
|
|
265
|
+
route closes itself on the first navigation.
|
|
266
|
+
- **Use `renderApp`, not a hand-rolled `createRoot` in `StrictMode`.** The readiness handling is
|
|
267
|
+
lost, and `StrictMode` double-invokes effects the router is not written for.
|
|
268
|
+
- **`onReady` waits for `DOMContentLoaded`.** A script that runs after the event has fired must pass
|
|
269
|
+
`{ onReady: false }`, or nothing mounts.
|
|
270
|
+
- **One context per page, from one factory.** Build it with `makeContext` plus `append*` mixins;
|
|
271
|
+
never create a second context for a component tree.
|
|
272
|
+
|
|
273
|
+
## Related packages
|
|
274
|
+
|
|
275
|
+
- [`@owlmeans/web-panel`](../web-panel) — shadcn/Tailwind panel layer built on this context
|
|
75
276
|
- [`@owlmeans/client-context`](../client-context) — `ClientContext` base extended by `makeContext`
|
|
76
|
-
- [`@owlmeans/
|
|
277
|
+
- [`@owlmeans/client-entrypoint`](../client-entrypoint) — protocol binding and `call` / `invoke` / `url`
|
|
278
|
+
- [`@owlmeans/client-auth`](../client-auth) — auth service, dispatcher HOC and login host
|
|
279
|
+
- [`@owlmeans/web-router`](../web-router) — default OwlMeans browser routing plugin
|
|
280
|
+
- [`@owlmeans/web-router-react-router`](../web-router-react-router) — opt-in react-router plugin
|
|
77
281
|
- [`@owlmeans/web-db`](../web-db) — IndexedDB service registered by `makeContext`
|
|
78
|
-
- [`@owlmeans/
|
|
282
|
+
- [`@owlmeans/web-oidc-rp`](../web-oidc-rp) — OIDC relying party with its own dispatcher
|
|
79
283
|
|
|
80
284
|
<!-- owlmeans:agent-guidance:start -->
|
|
81
285
|
## Agent guidance
|
|
@@ -85,7 +289,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
85
289
|
your project's skill store (`.agents/skills/`):
|
|
86
290
|
|
|
87
291
|
```sh
|
|
88
|
-
npx @owlmeans/agent-skills
|
|
292
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.49
|
|
89
293
|
```
|
|
90
294
|
|
|
91
295
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/web-client",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.61",
|
|
5
|
+
"generatedAt": "2026-10-05T21:03:06.394Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,59 +1,83 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: web-client
|
|
3
|
-
description:
|
|
4
|
-
user-invocable: false
|
|
3
|
+
description: Bind OwlMeans shared entrypoint protocols in a browser application. Use when registering client routes, attaching React screens (including lazily-loaded ones), calling API protocols, or configuring the browser context.
|
|
5
4
|
---
|
|
6
5
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
6
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## Usage
|
|
26
|
-
|
|
27
|
-
### Entry point
|
|
28
|
-
```typescript
|
|
29
|
-
// index.tsx
|
|
30
|
-
import { renderApp } from '@owlmeans/web-client'
|
|
31
|
-
import { makeContext } from './context.js'
|
|
32
|
-
import { appModules } from './modules.js'
|
|
33
|
-
import { MANAGER, MANAGER_API } from 'my-common'
|
|
34
|
-
import config from './config.js'
|
|
35
|
-
|
|
36
|
-
const context = makeContext(config)
|
|
37
|
-
context.registerEntrypoints(appModules)
|
|
38
|
-
context.serviceRoute(MANAGER, true)
|
|
39
|
-
context.serviceRoute(MANAGER_API, true)
|
|
40
|
-
renderApp<Config, Context>(context)
|
|
7
|
+
# Browser protocol entrypoints
|
|
8
|
+
|
|
9
|
+
**Install:** `bun add @owlmeans/web-client@^0.1.18-rc.61`
|
|
10
|
+
|
|
11
|
+
Shared protocol declarations are immutable. Bind a complete protocol tree for callable API routes,
|
|
12
|
+
then bind frontend declarations to screens.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { bindAll, bindScreen, entrypoints as frameworkEntrypoints, handler } from '@owlmeans/web-panel'
|
|
16
|
+
import { projectProtocols, webProtocols } from 'project-common'
|
|
17
|
+
import { ProjectScreen } from './screens/project.js'
|
|
18
|
+
|
|
19
|
+
export const clientBindings = [
|
|
20
|
+
...frameworkEntrypoints,
|
|
21
|
+
...bindAll(projectProtocols),
|
|
22
|
+
bindScreen(webProtocols.project, handler(ProjectScreen)),
|
|
23
|
+
]
|
|
41
24
|
```
|
|
42
25
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
26
|
+
Call a protocol directly. Its request and response types come from its shared contract.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const project = await context.entrypoint(projectProtocols.get).call({
|
|
30
|
+
params: { id: projectId },
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Lazily-loaded screens
|
|
35
|
+
|
|
36
|
+
`lazyHandler` and `lazyComponent` (from `@owlmeans/client`) are re-exported here and by
|
|
37
|
+
`@owlmeans/web-panel`, next to `handler`; so are, here only, the chunk-failure tools of
|
|
38
|
+
`lazyRetryHelper` — `retryImport`, `isChunkLoadError`, `reloadOnce` and `recoverFromChunkError` (types
|
|
39
|
+
`LazyErrorRenderer`, `RetryImportOptions`). A `lazyHandler(...)` result binds exactly like
|
|
40
|
+
`handler(Component)`; declare it at module scope, where the bindings live — never inside a render.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { bindScreen, lazyHandler } from '@owlmeans/web-client'
|
|
44
|
+
|
|
45
|
+
const reportsScreen = lazyHandler(() => import('./screens/reports.js'), 'ReportsScreen', {
|
|
46
|
+
fallback: <Spinner />,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
export const clientBindings = [
|
|
50
|
+
bindScreen(webProtocols.reports, reportsScreen),
|
|
51
|
+
]
|
|
52
|
+
// reportsScreen.preload() on hover/focus of a link renders the screen without its fallback.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The fallback renders inside the screen's own `Suspense` boundary, so the layout around it stays
|
|
56
|
+
mounted while the chunk loads, and the screen's own error boundary keeps a failed chunk from
|
|
57
|
+
unmounting it: a fetch failure is retried, then `error` renders — or, without one, the guarded
|
|
58
|
+
reload starts. Rules and options: the `client` skill, Code-splitting and Chunk failures.
|
|
59
|
+
|
|
60
|
+
## Rendering after an async boot
|
|
61
|
+
|
|
62
|
+
If your app awaits something (e.g. `i18nInstanceHelper.prepareI18n`) before calling `render()`, this is handled
|
|
63
|
+
correctly — the render helper checks `document.readyState` rather than unconditionally waiting for
|
|
64
|
+
an event that may already have fired. It waits for `DOMContentLoaded` only while the document is
|
|
65
|
+
still `loading` and mounts at once otherwise; `renderApp` and `@owlmeans/web-panel`'s `render` both
|
|
66
|
+
go through it.
|
|
47
67
|
|
|
48
|
-
|
|
68
|
+
```ts
|
|
69
|
+
import { i18nInstanceHelper } from '@owlmeans/client-i18n'
|
|
49
70
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)
|
|
71
|
+
await i18nInstanceHelper.prepareI18n(context.cfg)
|
|
72
|
+
renderApp(context) // or @owlmeans/web-panel's render(context)
|
|
53
73
|
```
|
|
54
74
|
|
|
55
|
-
##
|
|
75
|
+
## Rules
|
|
56
76
|
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
77
|
+
- Declare paths, guards, gates and contracts once in the shared protocol tree.
|
|
78
|
+
- Bind every API declaration the browser calls, including route parents.
|
|
79
|
+
- Use `bindScreen(protocol, handler(Component))` — or `lazyHandler(...)` — only for frontend route
|
|
80
|
+
declarations.
|
|
81
|
+
- Do not replace request/response typing at a call site; update the shared contract instead.
|
|
82
|
+
- Keep framework entrypoints and application entrypoints in one registered array, without mutating a
|
|
83
|
+
shared declaration collection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"AASA,eAAO,MAAM,UAAU,6FA+FrB,CAAA"}
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { DispatcherHOC } from '@owlmeans/client-auth';
|
|
3
|
-
import { useEffect } from 'react';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
4
|
import { useI18nLib } from '@owlmeans/client-i18n';
|
|
5
5
|
import { AUTH_QUERY } from '@owlmeans/auth';
|
|
6
|
+
import { FallbackLoginScreen, LoginIntent, LoginOutcome, ResumeAction, loginResumeHelper } from '@owlmeans/client-auth/login';
|
|
7
|
+
import { LoginSurrogateView } from '../../login/view.js';
|
|
8
|
+
import { SurrogateStage } from '../../login/consts.js';
|
|
6
9
|
import { useContext } from '../../context.js';
|
|
7
|
-
export const Dispatcher = DispatcherHOC(({ provideToken }) => {
|
|
10
|
+
export const Dispatcher = DispatcherHOC(({ provideToken, navigate }) => {
|
|
8
11
|
const context = useContext();
|
|
9
12
|
const [query] = context.router().useSearchParams();
|
|
10
13
|
const t = useI18nLib('auth', 'dispatcher');
|
|
14
|
+
const tAuth = useI18nLib('auth');
|
|
15
|
+
// Read in the component body, not in the effect: `window.name` is set by `window.open` before
|
|
16
|
+
// this document loads and `sessionStorage` carries the marker across the provider round trip, so
|
|
17
|
+
// the answer is already correct at first paint — and a first paint that showed the application
|
|
18
|
+
// before an effect corrected it is the defect this exists to prevent.
|
|
19
|
+
const [env] = useState(() => context.login().env());
|
|
20
|
+
const [outcome, setOutcome] = useState(null);
|
|
21
|
+
// Nothing to return from and nobody signed in: offer the choice rather than starting a flow.
|
|
22
|
+
const [choose, setChoose] = useState(false);
|
|
11
23
|
useEffect(() => {
|
|
24
|
+
// First statement of the effect on purpose: everything below can navigate this window away.
|
|
25
|
+
context.login().enter();
|
|
12
26
|
const token = query.get(AUTH_QUERY);
|
|
13
27
|
if (token != null) {
|
|
14
28
|
const params = {};
|
|
@@ -18,15 +32,47 @@ export const Dispatcher = DispatcherHOC(({ provideToken }) => {
|
|
|
18
32
|
}
|
|
19
33
|
});
|
|
20
34
|
provideToken({ token }, params);
|
|
35
|
+
return;
|
|
21
36
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
void context.auth().authenticated().then(async (authzToken) => {
|
|
38
|
+
if (authzToken == null || authzToken === '') {
|
|
39
|
+
setChoose(true);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// A session already exists in THIS document. Whether it is useful here, or belongs to the
|
|
43
|
+
// window that opened this one, is the plugin's call — the dispatcher reads no environment.
|
|
44
|
+
const settled = await context.login().resume(authzToken);
|
|
45
|
+
switch (loginResumeHelper.resumeAction(settled)) {
|
|
46
|
+
case ResumeAction.Stop:
|
|
47
|
+
return;
|
|
48
|
+
case ResumeAction.Render:
|
|
49
|
+
setOutcome(settled);
|
|
50
|
+
return;
|
|
51
|
+
default:
|
|
52
|
+
await navigate();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
29
55
|
}, []);
|
|
56
|
+
// A surrogate window never renders the application, whatever else is true. Checked ahead of
|
|
57
|
+
// every other return for exactly that reason.
|
|
58
|
+
//
|
|
59
|
+
// `choose` is the one state this must NOT mask, and it is not an exception to the rule: the
|
|
60
|
+
// login chooser is not the application. A login window with nothing to return from and nobody
|
|
61
|
+
// signed in has exactly one thing left that can move it forward, and that is asking which
|
|
62
|
+
// provider. The surrogate URL normally carries `?method=` so the question is already settled,
|
|
63
|
+
// but a window opened from a bare "Log in" — the framed application's own header button — has no
|
|
64
|
+
// method to send. Returning the "working" panel there left the popup on "Signing you in…"
|
|
65
|
+
// permanently, because nothing was ever going to start.
|
|
66
|
+
if (env.surrogate && !choose) {
|
|
67
|
+
return _jsx(LoginSurrogateView, { intent: LoginIntent.Login, stage: outcome === LoginOutcome.Orphaned ? SurrogateStage.Orphaned
|
|
68
|
+
: outcome === LoginOutcome.Failed ? SurrogateStage.Failed
|
|
69
|
+
: outcome === LoginOutcome.Gesture ? SurrogateStage.Gesture
|
|
70
|
+
: SurrogateStage.Working, onAction: () => window.close(), translate: (key, defaultValue) => tAuth(key, { defaultValue }) });
|
|
71
|
+
}
|
|
72
|
+
if (choose) {
|
|
73
|
+
const Screen = context.login().screen() ?? FallbackLoginScreen;
|
|
74
|
+
return _jsx(Screen, { translate: (key, defaultValue) => tAuth(key, { defaultValue }) });
|
|
75
|
+
}
|
|
30
76
|
return query.has(AUTH_QUERY) ? _jsx("div", { style: {
|
|
31
77
|
width: '100%', // Makes the div occupy the full width
|
|
32
78
|
display: 'flex', // Enables flexbox layout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrise.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/parametrise.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAI5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,eAAO,MAAM,qBAAqB,QAAS,OAAO,CAAC,iBAAiB,CAAC,QAAQ,eAAe,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"parametrise.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/parametrise.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAI5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE9C,eAAO,MAAM,qBAAqB,QAAS,OAAO,CAAC,iBAAiB,CAAC,QAAQ,eAAe,CAAC,eAAe,CAAC,aAC5F,iBAAiB,gCAejC,CAAA"}
|
|
@@ -2,9 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { Dispatcher } from "./component.js";
|
|
4
4
|
export const parametriseDispatcher = (def, Com) => {
|
|
5
|
-
console.log('Parametrising dispatcher with', def);
|
|
6
5
|
return (props) => {
|
|
7
|
-
console.log('Rendering parametrised dispatcher with', props);
|
|
8
6
|
const _props = useMemo(() => {
|
|
9
7
|
let payload = undefined;
|
|
10
8
|
if (def.payload != null) {
|
|
@@ -16,7 +14,6 @@ export const parametriseDispatcher = (def, Com) => {
|
|
|
16
14
|
}
|
|
17
15
|
return { ...def, ...props, payload };
|
|
18
16
|
}, [props]);
|
|
19
|
-
console.log('Computed dispatcher props', _props);
|
|
20
17
|
Com ??= Dispatcher;
|
|
21
18
|
return _jsx(Com, { ..._props });
|
|
22
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrise.js","sourceRoot":"","sources":["../../../src/components/dispatcher/parametrise.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAA+B,EAAE,GAAsC,EAAG,EAAE;IAChH,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"parametrise.js","sourceRoot":"","sources":["../../../src/components/dispatcher/parametrise.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAA+B,EAAE,GAAsC,EAAG,EAAE;IAChH,OAAO,CAAC,KAAwB,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;YAC1B,IAAI,OAAO,GAA4B,SAAS,CAAA;YAChD,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBACxB,OAAO,GAAG,GAAG,CAAC,OAAO,CAAA;YACvB,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBAC1B,OAAO,KAAK,EAAE,CAAA;gBACd,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;YACvC,CAAC;YACD,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAA;QACtC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;QACX,GAAG,KAAK,UAAU,CAAA;QAClB,OAAO,KAAC,GAAG,OAAK,MAAM,GAAI,CAAA;IAC5B,CAAC,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntrypointContextParams } from "@owlmeans/client";
|
|
2
2
|
import type { DispatcherProps } from "@owlmeans/client-auth";
|
|
3
3
|
import type { PropsWithChildren } from "react";
|
|
4
|
-
export interface ParametrisedProps extends PropsWithChildren<
|
|
4
|
+
export interface ParametrisedProps extends PropsWithChildren<EntrypointContextParams & DispatcherProps> {
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAE9C,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB,CAAC,uBAAuB,GAAG,eAAe,CAAC;CACtG"}
|