From b0c5f6307aabc58d5b2db94fb630df5cff859514 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 09:09:09 +0100 Subject: [PATCH 01/32] updated adapters to automatically verify auth --- app/src/adapter/astro/astro.adapter.ts | 6 ++-- app/src/adapter/nextjs/nextjs.adapter.ts | 6 ++-- app/src/adapter/remix/AdminPage.tsx | 4 ++- app/src/adapter/remix/remix.adapter.ts | 17 ++++++++++ docs/integration/astro.mdx | 6 ++-- docs/integration/remix.mdx | 34 ++++++------------- .../astro/src/pages/admin/[...admin].astro | 3 +- examples/astro/src/pages/index.astro | 3 +- examples/astro/src/pages/ssr.astro | 3 +- examples/remix/app/root.tsx | 28 ++++++--------- examples/remix/app/routes/_index.tsx | 7 ++-- 11 files changed, 60 insertions(+), 57 deletions(-) diff --git a/app/src/adapter/astro/astro.adapter.ts b/app/src/adapter/astro/astro.adapter.ts index 479b873..fccfd7d 100644 --- a/app/src/adapter/astro/astro.adapter.ts +++ b/app/src/adapter/astro/astro.adapter.ts @@ -13,11 +13,13 @@ export type Options = { host?: string; }; -export function getApi(Astro: TAstro, options: Options = { mode: "static" }) { - return new Api({ +export async function getApi(Astro: TAstro, options: Options = { mode: "static" }) { + const api = new Api({ host: new URL(Astro.request.url).origin, headers: options.mode === "dynamic" ? Astro.request.headers : undefined }); + await api.verifyAuth(); + return api; } let app: App; diff --git a/app/src/adapter/nextjs/nextjs.adapter.ts b/app/src/adapter/nextjs/nextjs.adapter.ts index 65d5ffa..7e30d26 100644 --- a/app/src/adapter/nextjs/nextjs.adapter.ts +++ b/app/src/adapter/nextjs/nextjs.adapter.ts @@ -29,8 +29,10 @@ export function createApi({ req }: GetServerSidePropsContext) { } export function withApi(handler: (ctx: GetServerSidePropsContext & { api: Api }) => T) { - return (ctx: GetServerSidePropsContext & { api: Api }) => { - return handler({ ...ctx, api: createApi(ctx) }); + return async (ctx: GetServerSidePropsContext & { api: Api }) => { + const api = createApi(ctx); + await api.verifyAuth(); + return handler({ ...ctx, api }); }; } diff --git a/app/src/adapter/remix/AdminPage.tsx b/app/src/adapter/remix/AdminPage.tsx index 9361cc2..5c9e90b 100644 --- a/app/src/adapter/remix/AdminPage.tsx +++ b/app/src/adapter/remix/AdminPage.tsx @@ -1,9 +1,11 @@ +import { useAuth } from "bknd/client"; import type { BkndAdminProps } from "bknd/ui"; import { Suspense, lazy, useEffect, useState } from "react"; export function adminPage(props?: BkndAdminProps) { const Admin = lazy(() => import("bknd/ui").then((mod) => ({ default: mod.Admin }))); return () => { + const auth = useAuth(); const [loaded, setLoaded] = useState(false); useEffect(() => { if (typeof window === "undefined") return; @@ -13,7 +15,7 @@ export function adminPage(props?: BkndAdminProps) { return ( - + ); }; diff --git a/app/src/adapter/remix/remix.adapter.ts b/app/src/adapter/remix/remix.adapter.ts index c3d0c78..ed2818b 100644 --- a/app/src/adapter/remix/remix.adapter.ts +++ b/app/src/adapter/remix/remix.adapter.ts @@ -1,5 +1,6 @@ import { type FrameworkBkndConfig, createFrameworkApp } from "adapter"; import type { App } from "bknd"; +import { Api } from "bknd/client"; export type RemixBkndConfig = FrameworkBkndConfig; @@ -12,3 +13,19 @@ export function serve(config: RemixBkndConfig = {}) { return app.fetch(args.request); }; } + +export function withApi( + handler: (args: Args, api: Api) => Promise +) { + return async (args: Args) => { + if (!args.context.api) { + args.context.api = new Api({ + host: new URL(args.request.url).origin, + headers: args.request.headers + }); + await args.context.api.verifyAuth(); + } + + return handler(args, args.context.api); + }; +} diff --git a/docs/integration/astro.mdx b/docs/integration/astro.mdx index 63c2f31..057e0b1 100644 --- a/docs/integration/astro.mdx +++ b/docs/integration/astro.mdx @@ -65,7 +65,7 @@ import "bknd/dist/styles.css"; import { getApi } from "bknd/adapter/astro"; -const api = getApi(Astro, { mode: "dynamic" }); +const api = await getApi(Astro, { mode: "dynamic" }); const user = api.getUser(); export const prerender = false; @@ -94,7 +94,7 @@ Here is an example of using the API in static context: ```jsx --- import { getApi } from "bknd/adapter/astro"; -const api = getApi(Astro); +const api = await getApi(Astro); const { data } = await api.data.readMany("todos"); --- @@ -109,7 +109,7 @@ On SSR pages, you can also access the authenticated user: ```jsx --- import { getApi } from "bknd/adapter/astro"; -const api = getApi(Astro, { mode: "dynamic" }); +const api = await getApi(Astro, { mode: "dynamic" }); const user = api.getUser(); const { data } = await api.data.readMany("todos"); diff --git a/docs/integration/remix.mdx b/docs/integration/remix.mdx index 3aaadc6..d89c888 100644 --- a/docs/integration/remix.mdx +++ b/docs/integration/remix.mdx @@ -32,6 +32,9 @@ Now make sure that you wrap your root layout with the `ClientProvider` so that a share the same context: ```tsx // app/root.tsx +import { withApi } from "bknd/adapter/remix" +import { type Api, ClientProvider } from "bknd/client"; + export function Layout(props) { // nothing to change here, just for orientation return ( @@ -48,21 +51,12 @@ declare module "@remix-run/server-runtime" { } // export a loader that initiates the API -// and pass it through the context -export const loader = async (args: LoaderFunctionArgs) => { - const api = new Api({ - host: new URL(args.request.url).origin, - headers: args.request.headers - }); - - // get the user from the API - const user = api.getUser(); - - // add api to the context - args.context.api = api; - - return { user }; -}; +// and passes it down to args.context.api +export const loader = withApi(async (args: LoaderFunctionArgs, api: Api) => { + return { + user: api.getUser() + }; +}); export default function App() { const { user } = useLoaderData(); @@ -93,15 +87,9 @@ Since the API has already been constructed in the root layout, you can now use i import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; import { useLoaderData } from "@remix-run/react"; -export const loader = async (args: LoaderFunctionArgs) => { - const { api } = args.context; - - // get the authenticated user - const user = api.getAuthState().user; - - // get the data from the API +export const loader = async ({ context: { api } }: LoaderFunctionArgs) => { const { data } = await api.data.readMany("todos"); - return { data, user }; + return { data, user: api.getUser() }; }; export default function Index() { diff --git a/examples/astro/src/pages/admin/[...admin].astro b/examples/astro/src/pages/admin/[...admin].astro index 612b801..8d34e21 100644 --- a/examples/astro/src/pages/admin/[...admin].astro +++ b/examples/astro/src/pages/admin/[...admin].astro @@ -4,8 +4,7 @@ import "bknd/dist/styles.css"; import { getApi } from "bknd/adapter/astro"; -const api = getApi(Astro, { mode: "dynamic" }); -await api.verifyAuth(); +const api = await getApi(Astro, { mode: "dynamic" }); const user = api.getUser(); export const prerender = false; diff --git a/examples/astro/src/pages/index.astro b/examples/astro/src/pages/index.astro index 4c2f31b..854df7f 100644 --- a/examples/astro/src/pages/index.astro +++ b/examples/astro/src/pages/index.astro @@ -2,7 +2,8 @@ import { getApi } from "bknd/adapter/astro"; import Card from "../components/Card.astro"; import Layout from "../layouts/Layout.astro"; -const api = getApi(Astro); + +const api = await getApi(Astro); const { data } = await api.data.readMany("todos"); --- diff --git a/examples/astro/src/pages/ssr.astro b/examples/astro/src/pages/ssr.astro index 726076d..ca8f380 100644 --- a/examples/astro/src/pages/ssr.astro +++ b/examples/astro/src/pages/ssr.astro @@ -2,8 +2,7 @@ import { getApi } from "bknd/adapter/astro"; import Card from "../components/Card.astro"; import Layout from "../layouts/Layout.astro"; -const api = getApi(Astro, { mode: "dynamic" }); -await api.verifyAuth(); +const api = await getApi(Astro, { mode: "dynamic" }); const { data } = await api.data.readMany("todos"); const user = api.getUser(); diff --git a/examples/remix/app/root.tsx b/examples/remix/app/root.tsx index 8930b4f..004ec11 100644 --- a/examples/remix/app/root.tsx +++ b/examples/remix/app/root.tsx @@ -1,12 +1,7 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; import { Links, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData } from "@remix-run/react"; -import { Api, ClientProvider } from "bknd/client"; - -declare module "@remix-run/server-runtime" { - export interface AppLoadContext { - api: Api; - } -} +import { withApi } from "bknd/adapter/remix"; +import { type Api, ClientProvider } from "bknd/client"; export function Layout({ children }: { children: React.ReactNode }) { return ( @@ -26,20 +21,17 @@ export function Layout({ children }: { children: React.ReactNode }) { ); } -export const loader = async (args: LoaderFunctionArgs) => { - const api = new Api({ - host: new URL(args.request.url).origin, - headers: args.request.headers - }); +declare module "@remix-run/server-runtime" { + export interface AppLoadContext { + api: Api; + } +} - // add api to the context - args.context.api = api; - - await api.verifyAuth(); +export const loader = withApi(async (args: LoaderFunctionArgs, api: Api) => { return { - user: api.getAuthState()?.user + user: api.getUser() }; -}; +}); export default function App() { const data = useLoaderData(); diff --git a/examples/remix/app/routes/_index.tsx b/examples/remix/app/routes/_index.tsx index eef795d..1cbbe19 100644 --- a/examples/remix/app/routes/_index.tsx +++ b/examples/remix/app/routes/_index.tsx @@ -1,19 +1,20 @@ import { type MetaFunction, useLoaderData } from "@remix-run/react"; import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; +import { useAuth } from "bknd/client"; export const meta: MetaFunction = () => { return [{ title: "Remix & bknd" }, { name: "description", content: "Welcome to Remix & bknd!" }]; }; -export const loader = async (args: LoaderFunctionArgs) => { - const api = args.context.api; - await api.verifyAuth(); +export const loader = async ({ context: { api } }: LoaderFunctionArgs) => { const { data } = await api.data.readMany("todos"); return { data, user: api.getUser() }; }; export default function Index() { const { data, user } = useLoaderData(); + const auth = useAuth(); + console.log("auth", auth); return (
From 9ddacb7ae568270d0c7d0d5493ecb8513d1637eb Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 11:54:19 +0100 Subject: [PATCH 02/32] added adapter exports, generalized env-depending config construction --- app/build.ts | 8 +++++++ app/package.json | 4 ++++ app/src/adapter/astro/astro.adapter.ts | 9 ++++---- .../cloudflare/cloudflare-workers.adapter.ts | 14 +++++------- app/src/adapter/cloudflare/modes/cached.ts | 4 ++-- app/src/adapter/cloudflare/modes/durable.ts | 4 ++-- app/src/adapter/cloudflare/modes/fresh.ts | 4 ++-- app/src/adapter/index.ts | 22 +++++++++---------- app/src/adapter/remix/remix.adapter.ts | 14 ++++++++---- examples/astro/src/pages/api/[...api].ts | 3 ++- examples/cloudflare-worker/src/index.ts | 2 +- 11 files changed, 53 insertions(+), 35 deletions(-) diff --git a/app/build.ts b/app/build.ts index e931021..3c37c6e 100644 --- a/app/build.ts +++ b/app/build.ts @@ -180,6 +180,14 @@ function baseConfig(adapter: string): tsup.Options { }; } +// base adapter handles +await tsup.build({ + ...baseConfig(""), + entry: ["src/adapter/index.ts"], + outDir: "dist/adapter" +}); + +// specific adatpers await tsup.build(baseConfig("remix")); await tsup.build(baseConfig("bun")); await tsup.build(baseConfig("astro")); diff --git a/app/package.json b/app/package.json index a04b686..a2c0893 100644 --- a/app/package.json +++ b/app/package.json @@ -148,6 +148,10 @@ "import": "./dist/adapter/cloudflare/index.js", "require": "./dist/adapter/cloudflare/index.cjs" }, + "./adapter": { + "types": "./dist/types/adapter/index.d.ts", + "import": "./dist/adapter/index.js" + }, "./adapter/vite": { "types": "./dist/types/adapter/vite/index.d.ts", "import": "./dist/adapter/vite/index.js", diff --git a/app/src/adapter/astro/astro.adapter.ts b/app/src/adapter/astro/astro.adapter.ts index 479b873..764e100 100644 --- a/app/src/adapter/astro/astro.adapter.ts +++ b/app/src/adapter/astro/astro.adapter.ts @@ -1,7 +1,7 @@ import { type FrameworkBkndConfig, createFrameworkApp } from "adapter"; import { Api, type ApiOptions, type App } from "bknd"; -export type AstroBkndConfig = FrameworkBkndConfig; +export type AstroBkndConfig = FrameworkBkndConfig; type TAstro = { request: Request; @@ -21,10 +21,11 @@ export function getApi(Astro: TAstro, options: Options = { mode: "static" }) { } let app: App; -export function serve(config: AstroBkndConfig = {}) { - return async (args: TAstro) => { +export function serve(config: AstroBkndConfig = {}) { + return async (args: Context) => { + console.log("args", Object.keys(args)); if (!app) { - app = await createFrameworkApp(config); + app = await createFrameworkApp(config, args); } return app.fetch(args.request); }; diff --git a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts index da3c762..cfcba5d 100644 --- a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts +++ b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts @@ -1,4 +1,3 @@ -import type { CreateAppConfig } from "bknd"; import { Hono } from "hono"; import { serveStatic } from "hono/cloudflare-workers"; import type { FrameworkBkndConfig } from "../index"; @@ -6,10 +5,9 @@ import { getCached } from "./modes/cached"; import { getDurable } from "./modes/durable"; import { getFresh, getWarm } from "./modes/fresh"; -export type CloudflareBkndConfig = Omit & { - app: CreateAppConfig | ((env: Env) => CreateAppConfig); +export type CloudflareBkndConfig = FrameworkBkndConfig> & { mode?: "warm" | "fresh" | "cache" | "durable"; - bindings?: (env: Env) => { + bindings?: (args: Context) => { kv?: KVNamespace; dobj?: DurableObjectNamespace; }; @@ -21,15 +19,15 @@ export type CloudflareBkndConfig = Omit & html?: string; }; -export type Context = { +export type Context = { request: Request; - env: any; + env: Env; ctx: ExecutionContext; }; -export function serve(config: CloudflareBkndConfig) { +export function serve(config: CloudflareBkndConfig) { return { - async fetch(request: Request, env: any, ctx: ExecutionContext) { + async fetch(request: Request, env: Env, ctx: ExecutionContext) { const url = new URL(request.url); const manifest = config.manifest; diff --git a/app/src/adapter/cloudflare/modes/cached.ts b/app/src/adapter/cloudflare/modes/cached.ts index a238ae0..2c04f51 100644 --- a/app/src/adapter/cloudflare/modes/cached.ts +++ b/app/src/adapter/cloudflare/modes/cached.ts @@ -2,7 +2,7 @@ import { createRuntimeApp } from "adapter"; import { App } from "bknd"; import type { CloudflareBkndConfig, Context } from "../index"; -export async function getCached(config: CloudflareBkndConfig, { env, ctx }: Context) { +export async function getCached(config: CloudflareBkndConfig, { env, ctx, ...args }: Context) { const { kv } = config.bindings?.(env)!; if (!kv) throw new Error("kv namespace is not defined in cloudflare.bindings"); const key = config.key ?? "app"; @@ -37,7 +37,7 @@ export async function getCached(config: CloudflareBkndConfig, { env, ctx }: Cont }, adminOptions: { html: config.html } }, - env + { env, ctx, ...args } ); if (!cachedConfig) { diff --git a/app/src/adapter/cloudflare/modes/durable.ts b/app/src/adapter/cloudflare/modes/durable.ts index 3787b5c..4c7233b 100644 --- a/app/src/adapter/cloudflare/modes/durable.ts +++ b/app/src/adapter/cloudflare/modes/durable.ts @@ -1,5 +1,5 @@ import { DurableObject } from "cloudflare:workers"; -import { createRuntimeApp } from "adapter"; +import { createRuntimeApp, makeConfig } from "adapter"; import type { CloudflareBkndConfig, Context } from "adapter/cloudflare"; import type { App, CreateAppConfig } from "bknd"; @@ -17,7 +17,7 @@ export async function getDurable(config: CloudflareBkndConfig, ctx: Context) { const id = dobj.idFromName(key); const stub = dobj.get(id) as unknown as DurableBkndApp; - const create_config = typeof config.app === "function" ? config.app(ctx.env) : config.app; + const create_config = makeConfig(config, ctx); const res = await stub.fire(ctx.request, { config: create_config, diff --git a/app/src/adapter/cloudflare/modes/fresh.ts b/app/src/adapter/cloudflare/modes/fresh.ts index cb5ece7..30272bf 100644 --- a/app/src/adapter/cloudflare/modes/fresh.ts +++ b/app/src/adapter/cloudflare/modes/fresh.ts @@ -2,13 +2,13 @@ import { createRuntimeApp } from "adapter"; import type { App } from "bknd"; import type { CloudflareBkndConfig, Context } from "../index"; -export async function makeApp(config: CloudflareBkndConfig, { env }: Context) { +export async function makeApp(config: CloudflareBkndConfig, ctx: Context) { return await createRuntimeApp( { ...config, adminOptions: config.html ? { html: config.html } : undefined }, - env + ctx ); } diff --git a/app/src/adapter/index.ts b/app/src/adapter/index.ts index 19bcdef..492f55e 100644 --- a/app/src/adapter/index.ts +++ b/app/src/adapter/index.ts @@ -5,16 +5,16 @@ import type { MiddlewareHandler } from "hono"; import { StorageLocalAdapter } from "media/storage/adapters/StorageLocalAdapter"; import type { AdminControllerOptions } from "modules/server/AdminController"; -export type BkndConfig = CreateAppConfig & { - app?: CreateAppConfig | ((env: Env) => CreateAppConfig); +export type BkndConfig = CreateAppConfig & { + app?: CreateAppConfig | ((args: Args) => CreateAppConfig); onBuilt?: (app: App) => Promise; beforeBuild?: (app: App) => Promise; buildConfig?: Parameters[0]; }; -export type FrameworkBkndConfig = BkndConfig; +export type FrameworkBkndConfig = BkndConfig; -export type RuntimeBkndConfig = BkndConfig & { +export type RuntimeBkndConfig = BkndConfig & { distPath?: string; }; @@ -46,14 +46,14 @@ export function registerLocalMediaAdapter() { registries.media.register("local", StorageLocalAdapter); } -export function makeConfig(config: BkndConfig, env?: Env): CreateAppConfig { +export function makeConfig(config: BkndConfig, args?: Args): CreateAppConfig { let additionalConfig: CreateAppConfig = {}; if ("app" in config && config.app) { if (typeof config.app === "function") { - if (!env) { - throw new Error("env is required when config.app is a function"); + if (!args) { + throw new Error("args is required when config.app is a function"); } - additionalConfig = config.app(env); + additionalConfig = config.app(args); } else { additionalConfig = config.app; } @@ -62,11 +62,11 @@ export function makeConfig(config: BkndConfig, env?: Env): Creat return { ...config, ...additionalConfig }; } -export async function createFrameworkApp( +export async function createFrameworkApp( config: FrameworkBkndConfig, - env?: Env + args?: Args ): Promise { - const app = App.create(makeConfig(config, env)); + const app = App.create(makeConfig(config, args)); if (config.onBuilt) { app.emgr.onEvent( diff --git a/app/src/adapter/remix/remix.adapter.ts b/app/src/adapter/remix/remix.adapter.ts index c3d0c78..7681fd4 100644 --- a/app/src/adapter/remix/remix.adapter.ts +++ b/app/src/adapter/remix/remix.adapter.ts @@ -1,13 +1,19 @@ import { type FrameworkBkndConfig, createFrameworkApp } from "adapter"; import type { App } from "bknd"; -export type RemixBkndConfig = FrameworkBkndConfig; +export type RemixBkndConfig = FrameworkBkndConfig; + +type RemixContext = { + request: Request; +}; let app: App; -export function serve(config: RemixBkndConfig = {}) { - return async (args: { request: Request }) => { +export function serve( + config: RemixBkndConfig = {} +) { + return async (args: Args) => { if (!app) { - app = await createFrameworkApp(config); + app = await createFrameworkApp(config, args); } return app.fetch(args.request); }; diff --git a/examples/astro/src/pages/api/[...api].ts b/examples/astro/src/pages/api/[...api].ts index abbcca7..82d3c4e 100644 --- a/examples/astro/src/pages/api/[...api].ts +++ b/examples/astro/src/pages/api/[...api].ts @@ -1,3 +1,4 @@ +import type { APIContext } from "astro"; import { App } from "bknd"; import { serve } from "bknd/adapter/astro"; import { registerLocalMediaAdapter } from "bknd/adapter/node"; @@ -23,7 +24,7 @@ declare module "bknd/core" { interface DB extends Database {} } -export const ALL = serve({ +export const ALL = serve({ // we can use any libsql config, and if omitted, uses in-memory connection: { type: "libsql", diff --git a/examples/cloudflare-worker/src/index.ts b/examples/cloudflare-worker/src/index.ts index e7a0f5e..dbb2e9b 100644 --- a/examples/cloudflare-worker/src/index.ts +++ b/examples/cloudflare-worker/src/index.ts @@ -3,7 +3,7 @@ import { serve } from "bknd/adapter/cloudflare"; import manifest from "__STATIC_CONTENT_MANIFEST"; export default serve({ - app: (env: Env) => ({ + app: (args) => ({ connection: { type: "libsql", config: { From 1beac5043be234c26edcb56b2ddfce10f0c60134 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 12:33:05 +0100 Subject: [PATCH 03/32] updated cloudflare adapter docs to match new args --- app/src/adapter/astro/astro.adapter.ts | 1 - docs/integration/cloudflare.mdx | 35 +++++++++++++------------- docs/integration/remix.mdx | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/adapter/astro/astro.adapter.ts b/app/src/adapter/astro/astro.adapter.ts index b608419..e8cb58a 100644 --- a/app/src/adapter/astro/astro.adapter.ts +++ b/app/src/adapter/astro/astro.adapter.ts @@ -25,7 +25,6 @@ export async function getApi(Astro: TAstro, options: Options = { mode: "static" let app: App; export function serve(config: AstroBkndConfig = {}) { return async (args: Context) => { - console.log("args", Object.keys(args)); if (!app) { app = await createFrameworkApp(config, args); } diff --git a/docs/integration/cloudflare.mdx b/docs/integration/cloudflare.mdx index 22785f8..6cf92ee 100644 --- a/docs/integration/cloudflare.mdx +++ b/docs/integration/cloudflare.mdx @@ -16,11 +16,11 @@ and then install bknd as a dependency: If you don't choose anything specific, the following code will use the `warm` mode. See the chapter [Using a different mode](#using-a-different-mode) for available modes. -``` ts +```ts import { serve } from "bknd/adapter/cloudflare"; -export default serve({ - app: (env: Env) => ({ +export default serve({ + app: ({ env }) => ({ connection: { type: "libsql", config: { @@ -50,12 +50,12 @@ bucket = "node_modules/bknd/dist/static" ``` And then modify the worker entry as follows: -``` ts {2, 14, 15} +```ts {2, 14, 15} import { serve } from "bknd/adapter/cloudflare"; import manifest from "__STATIC_CONTENT_MANIFEST"; -export default serve({ - app: (env: Env) => ({ +export default serve({ + app: ({ env }) => ({ connection: { type: "libsql", config: { @@ -75,8 +75,8 @@ You can also add custom routes by defining them after the app has been built, li import { serve } from "bknd/adapter/cloudflare"; import manifest from "__STATIC_CONTENT_MANIFEST"; -export default serve({ - app: (env: Env) => ({ +export default serve({ + app: ({ env }) => ({ connection: { type: "libsql", config: { @@ -111,7 +111,7 @@ mode`, like so: import { serve } from "bknd/adapter/cloudflare"; export default serve({ - /* ... */, + // ... mode: "fresh" // mode: "fresh" | "warm" | "cache" | "durable" }); ``` @@ -119,13 +119,14 @@ export default serve({ ### Mode: `cache` For the cache mode to work, you also need to specify the KV to be used. For this, use the `bindings` property: + ```ts import { serve } from "bknd/adapter/cloudflare"; -export default serve({ - /* ... */, +export default serve({ + // ... mode: "cache", - bindings: (env: Env) => ({ kv: env.KV }) + bindings: ({ env }) => ({ kv: env.KV }) }); ``` @@ -136,10 +137,10 @@ environment, and additionally export the `DurableBkndApp` class: import { serve, DurableBkndApp } from "bknd/adapter/cloudflare"; export { DurableBkndApp }; -export default serve({ - /* ... */, +export default serve({ + // ... mode: "durable", - bindings: (env: Env) => ({ dobj: env.DOBJ }), + bindings: ({ env }) => ({ dobj: env.DOBJ }), keepAliveSeconds: 60 // optional }); ``` @@ -164,9 +165,9 @@ import type { App } from "bknd"; import { serve, DurableBkndApp } from "bknd/adapter/cloudflare"; export default serve({ - /* ... */, + // ... mode: "durable", - bindings: (env: Env) => ({ dobj: env.DOBJ }), + bindings: ({ env }) => ({ dobj: env.DOBJ }), keepAliveSeconds: 60 // optional }); diff --git a/docs/integration/remix.mdx b/docs/integration/remix.mdx index d89c888..5029859 100644 --- a/docs/integration/remix.mdx +++ b/docs/integration/remix.mdx @@ -10,7 +10,7 @@ Install bknd as a dependency: ## Serve the API Create a new api splat route file at `app/routes/api.$.ts`: -``` tsx +```ts // app/routes/api.$.ts import { serve } from "bknd/adapter/remix"; From aa7eac258bbaa9ab7c891f42626c80f1eafb9860 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 13:40:28 +0100 Subject: [PATCH 04/32] adapter(cloudflare): add supports for the new assets feature --- .../cloudflare/cloudflare-workers.adapter.ts | 14 +++-- app/src/core/utils/typebox/index.ts | 3 +- docs/integration/cloudflare.mdx | 55 ++++++++++--------- examples/cloudflare-worker/src/index.ts | 5 +- examples/cloudflare-worker/wrangler.toml | 5 +- 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts index cfcba5d..e666cf6 100644 --- a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts +++ b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts @@ -11,6 +11,7 @@ export type CloudflareBkndConfig = FrameworkBkndConfig> kv?: KVNamespace; dobj?: DurableObjectNamespace; }; + static?: "kv" | "assets"; key?: string; keepAliveSeconds?: number; forceHttps?: boolean; @@ -29,18 +30,23 @@ export function serve(config: CloudflareBkndConfig) { return { async fetch(request: Request, env: Env, ctx: ExecutionContext) { const url = new URL(request.url); - const manifest = config.manifest; - if (manifest) { + if (config.manifest && config.static === "assets") { + console.warn("manifest is not useful with static 'assets'"); + } else if (!config.manifest && config.static === "kv") { + throw new Error("manifest is required with static 'kv'"); + } + + if (config.manifest && config.static !== "assets") { const pathname = url.pathname.slice(1); - const assetManifest = JSON.parse(manifest); + const assetManifest = JSON.parse(config.manifest); if (pathname && pathname in assetManifest) { const hono = new Hono(); hono.all("*", async (c, next) => { const res = await serveStatic({ path: `./${pathname}`, - manifest + manifest: config.manifest! })(c as any, next); if (res instanceof Response) { const ttl = 60 * 60 * 24 * 365; diff --git a/app/src/core/utils/typebox/index.ts b/app/src/core/utils/typebox/index.ts index a793e33..9e6f2d6 100644 --- a/app/src/core/utils/typebox/index.ts +++ b/app/src/core/utils/typebox/index.ts @@ -21,7 +21,6 @@ import { type ValueErrorIterator } from "@sinclair/typebox/errors"; import { Check, Default, Value, type ValueError } from "@sinclair/typebox/value"; -import { cloneDeep } from "lodash-es"; export type RecursivePartial = { [P in keyof T]?: T[P] extends (infer U)[] @@ -73,7 +72,7 @@ export class TypeInvalidError extends Error { } export function stripMark(obj: O) { - const newObj = cloneDeep(obj); + const newObj = structuredClone(obj); mark(newObj, false); return newObj as O; } diff --git a/docs/integration/cloudflare.mdx b/docs/integration/cloudflare.mdx index 6cf92ee..04926be 100644 --- a/docs/integration/cloudflare.mdx +++ b/docs/integration/cloudflare.mdx @@ -16,7 +16,7 @@ and then install bknd as a dependency: If you don't choose anything specific, the following code will use the `warm` mode. See the chapter [Using a different mode](#using-a-different-mode) for available modes. -```ts +```ts src/index.ts import { serve } from "bknd/adapter/cloudflare"; export default serve({ @@ -42,32 +42,37 @@ And confirm it works by opening [http://localhost:8787](http://localhost:8787) i your browser. ## Serve the Admin UI -Now in order to also server the static admin files, you have to modify the `wrangler.toml` to -include the static assets: -```toml -[site] -bucket = "node_modules/bknd/dist/static" -``` +Now in order to also server the static admin files, you have to modify the `wrangler.toml` to include the static assets. You can do so by either serving the static using the new [Assets feature](https://developers.cloudflare.com/workers/static-assets/), or the deprecated [Workers Site](https://developers.cloudflare.com/workers/configuration/sites/configuration/). -And then modify the worker entry as follows: -```ts {2, 14, 15} -import { serve } from "bknd/adapter/cloudflare"; -import manifest from "__STATIC_CONTENT_MANIFEST"; + + + Make sure your assets point to the static assets included in the bknd package: -export default serve({ - app: ({ env }) => ({ - connection: { - type: "libsql", - config: { - url: env.DB_URL, - authToken: env.DB_TOKEN - } - } - }), - manifest, - setAdminHtml: true -}); -``` + ```toml wrangler.toml + assets = { directory = "node_modules/bknd/dist/static" } + ``` + + + + Make sure your site points to the static assets included in the bknd package: + + ```toml wrangler.toml + [site] + bucket = "node_modules/bknd/dist/static" + ``` + + And then modify the worker entry as follows: + ```ts {2, 6} src/index.ts + import { serve } from "bknd/adapter/cloudflare"; + import manifest from "__STATIC_CONTENT_MANIFEST"; + + export default serve({ + app: () => ({/* ... */}), + manifest + }); + ``` + + ## Adding custom routes You can also add custom routes by defining them after the app has been built, like so: diff --git a/examples/cloudflare-worker/src/index.ts b/examples/cloudflare-worker/src/index.ts index dbb2e9b..628c490 100644 --- a/examples/cloudflare-worker/src/index.ts +++ b/examples/cloudflare-worker/src/index.ts @@ -1,7 +1,5 @@ import { serve } from "bknd/adapter/cloudflare"; -import manifest from "__STATIC_CONTENT_MANIFEST"; - export default serve({ app: (args) => ({ connection: { @@ -13,6 +11,5 @@ export default serve({ }), onBuilt: async (app) => { app.modules.server.get("/custom", (c) => c.json({ hello: "world" })); - }, - manifest + } }); diff --git a/examples/cloudflare-worker/wrangler.toml b/examples/cloudflare-worker/wrangler.toml index 86fe17d..27157d0 100644 --- a/examples/cloudflare-worker/wrangler.toml +++ b/examples/cloudflare-worker/wrangler.toml @@ -5,9 +5,10 @@ compatibility_date = "2024-11-06" compatibility_flags = ["nodejs_compat"] workers_dev = true minify = true +assets = { directory = "../../app/dist/static" } [observability] enabled = true -[site] -bucket = "../../app/dist/static" \ No newline at end of file +#[site] +#bucket = "../../app/dist/static" \ No newline at end of file From 5b40d5eaf426f94ec8cad897298aa9a49858e6bf Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 14:13:34 +0100 Subject: [PATCH 05/32] optimize adapter imports to deduplicate --- app/build.ts | 1 - app/src/adapter/astro/astro.adapter.ts | 2 +- app/src/adapter/astro/index.ts | 1 + app/src/adapter/bun/bun.adapter.ts | 7 ++-- .../cloudflare/cloudflare-workers.adapter.ts | 2 +- app/src/adapter/cloudflare/modes/cached.ts | 2 +- app/src/adapter/cloudflare/modes/durable.ts | 4 +- app/src/adapter/cloudflare/modes/fresh.ts | 2 +- app/src/adapter/index.ts | 40 +----------------- app/src/adapter/nextjs/index.ts | 1 + app/src/adapter/nextjs/nextjs.adapter.ts | 3 +- app/src/adapter/node/index.ts | 41 ++++++++++++++++--- app/src/adapter/node/node.adapter.ts | 7 ++-- app/src/adapter/remix/index.ts | 1 + app/src/adapter/remix/remix.adapter.ts | 2 +- app/src/adapter/vite/index.ts | 1 + app/src/adapter/vite/vite.adapter.ts | 5 ++- examples/astro/src/pages/api/[...api].ts | 3 +- examples/remix/app/routes/api.$.ts | 3 +- 19 files changed, 64 insertions(+), 64 deletions(-) diff --git a/app/build.ts b/app/build.ts index 3c37c6e..ebbf33a 100644 --- a/app/build.ts +++ b/app/build.ts @@ -173,7 +173,6 @@ function baseConfig(adapter: string): tsup.Options { ], metafile: true, splitting: false, - treeshake: true, onSuccess: async () => { delayTypes(); } diff --git a/app/src/adapter/astro/astro.adapter.ts b/app/src/adapter/astro/astro.adapter.ts index e8cb58a..a4886c4 100644 --- a/app/src/adapter/astro/astro.adapter.ts +++ b/app/src/adapter/astro/astro.adapter.ts @@ -1,5 +1,5 @@ -import { type FrameworkBkndConfig, createFrameworkApp } from "adapter"; import { Api, type ApiOptions, type App } from "bknd"; +import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter"; export type AstroBkndConfig = FrameworkBkndConfig; diff --git a/app/src/adapter/astro/index.ts b/app/src/adapter/astro/index.ts index d5010a5..818174e 100644 --- a/app/src/adapter/astro/index.ts +++ b/app/src/adapter/astro/index.ts @@ -1 +1,2 @@ export * from "./astro.adapter"; +export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/bun/bun.adapter.ts b/app/src/adapter/bun/bun.adapter.ts index 390ac3a..05eec3c 100644 --- a/app/src/adapter/bun/bun.adapter.ts +++ b/app/src/adapter/bun/bun.adapter.ts @@ -2,10 +2,11 @@ import path from "node:path"; import type { App } from "bknd"; +import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter"; +import { registerLocalMediaAdapter } from "bknd/adapter/node"; +import { config } from "bknd/core"; import type { ServeOptions } from "bun"; -import { config } from "core"; import { serveStatic } from "hono/bun"; -import { type RuntimeBkndConfig, createRuntimeApp } from "../index"; let app: App; @@ -15,9 +16,9 @@ export async function createApp({ distPath, ...config }: RuntimeBkndConfig = {}) const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static"); if (!app) { + registerLocalMediaAdapter(); app = await createRuntimeApp({ ...config, - registerLocalMedia: true, serveStatic: serveStatic({ root }) }); } diff --git a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts index e666cf6..3a4044b 100644 --- a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts +++ b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts @@ -1,6 +1,6 @@ +import type { FrameworkBkndConfig } from "bknd/adapter"; import { Hono } from "hono"; import { serveStatic } from "hono/cloudflare-workers"; -import type { FrameworkBkndConfig } from "../index"; import { getCached } from "./modes/cached"; import { getDurable } from "./modes/durable"; import { getFresh, getWarm } from "./modes/fresh"; diff --git a/app/src/adapter/cloudflare/modes/cached.ts b/app/src/adapter/cloudflare/modes/cached.ts index 2c04f51..a367e5d 100644 --- a/app/src/adapter/cloudflare/modes/cached.ts +++ b/app/src/adapter/cloudflare/modes/cached.ts @@ -1,5 +1,5 @@ -import { createRuntimeApp } from "adapter"; import { App } from "bknd"; +import { createRuntimeApp } from "bknd/adapter"; import type { CloudflareBkndConfig, Context } from "../index"; export async function getCached(config: CloudflareBkndConfig, { env, ctx, ...args }: Context) { diff --git a/app/src/adapter/cloudflare/modes/durable.ts b/app/src/adapter/cloudflare/modes/durable.ts index 4c7233b..bd58f85 100644 --- a/app/src/adapter/cloudflare/modes/durable.ts +++ b/app/src/adapter/cloudflare/modes/durable.ts @@ -1,7 +1,7 @@ import { DurableObject } from "cloudflare:workers"; -import { createRuntimeApp, makeConfig } from "adapter"; -import type { CloudflareBkndConfig, Context } from "adapter/cloudflare"; import type { App, CreateAppConfig } from "bknd"; +import { createRuntimeApp, makeConfig } from "bknd/adapter"; +import type { CloudflareBkndConfig, Context } from "../index"; export async function getDurable(config: CloudflareBkndConfig, ctx: Context) { const { dobj } = config.bindings?.(ctx.env)!; diff --git a/app/src/adapter/cloudflare/modes/fresh.ts b/app/src/adapter/cloudflare/modes/fresh.ts index 30272bf..ef40987 100644 --- a/app/src/adapter/cloudflare/modes/fresh.ts +++ b/app/src/adapter/cloudflare/modes/fresh.ts @@ -1,5 +1,5 @@ -import { createRuntimeApp } from "adapter"; import type { App } from "bknd"; +import { createRuntimeApp } from "bknd/adapter"; import type { CloudflareBkndConfig, Context } from "../index"; export async function makeApp(config: CloudflareBkndConfig, ctx: Context) { diff --git a/app/src/adapter/index.ts b/app/src/adapter/index.ts index 492f55e..1c48f8b 100644 --- a/app/src/adapter/index.ts +++ b/app/src/adapter/index.ts @@ -1,8 +1,6 @@ -import type { IncomingMessage } from "node:http"; -import { App, type CreateAppConfig, registries } from "bknd"; -import { config as $config } from "core"; +import { App, type CreateAppConfig } from "bknd"; +import { config as $config } from "bknd/core"; import type { MiddlewareHandler } from "hono"; -import { StorageLocalAdapter } from "media/storage/adapters/StorageLocalAdapter"; import type { AdminControllerOptions } from "modules/server/AdminController"; export type BkndConfig = CreateAppConfig & { @@ -18,34 +16,6 @@ export type RuntimeBkndConfig = BkndConfig & { distPath?: string; }; -export function nodeRequestToRequest(req: IncomingMessage): Request { - let protocol = "http"; - try { - protocol = req.headers["x-forwarded-proto"] as string; - } catch (e) {} - const host = req.headers.host; - const url = `${protocol}://${host}${req.url}`; - const headers = new Headers(); - - for (const [key, value] of Object.entries(req.headers)) { - if (Array.isArray(value)) { - headers.append(key, value.join(", ")); - } else if (value) { - headers.append(key, value); - } - } - - const method = req.method || "GET"; - return new Request(url, { - method, - headers - }); -} - -export function registerLocalMediaAdapter() { - registries.media.register("local", StorageLocalAdapter); -} - export function makeConfig(config: BkndConfig, args?: Args): CreateAppConfig { let additionalConfig: CreateAppConfig = {}; if ("app" in config && config.app) { @@ -87,20 +57,14 @@ export async function createFrameworkApp( export async function createRuntimeApp( { serveStatic, - registerLocalMedia, adminOptions, ...config }: RuntimeBkndConfig & { serveStatic?: MiddlewareHandler | [string, MiddlewareHandler]; - registerLocalMedia?: boolean; adminOptions?: AdminControllerOptions | false; }, env?: Env ): Promise { - if (registerLocalMedia) { - registerLocalMediaAdapter(); - } - const app = App.create(makeConfig(config, env)); app.emgr.onEvent( diff --git a/app/src/adapter/nextjs/index.ts b/app/src/adapter/nextjs/index.ts index 957fa9e..e691401 100644 --- a/app/src/adapter/nextjs/index.ts +++ b/app/src/adapter/nextjs/index.ts @@ -1 +1,2 @@ export * from "./nextjs.adapter"; +export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/nextjs/nextjs.adapter.ts b/app/src/adapter/nextjs/nextjs.adapter.ts index 7e30d26..7310727 100644 --- a/app/src/adapter/nextjs/nextjs.adapter.ts +++ b/app/src/adapter/nextjs/nextjs.adapter.ts @@ -1,6 +1,7 @@ import type { IncomingMessage, ServerResponse } from "node:http"; import { Api, type App } from "bknd"; -import { type FrameworkBkndConfig, createFrameworkApp, nodeRequestToRequest } from "../index"; +import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter"; +import { nodeRequestToRequest } from "bknd/adapter/node"; export type NextjsBkndConfig = FrameworkBkndConfig & { cleanSearch?: string[]; diff --git a/app/src/adapter/node/index.ts b/app/src/adapter/node/index.ts index bc5b7e5..41c6aaf 100644 --- a/app/src/adapter/node/index.ts +++ b/app/src/adapter/node/index.ts @@ -1,6 +1,37 @@ -export * from "./node.adapter"; -export { - StorageLocalAdapter, - type LocalAdapterConfig +import type { IncomingMessage } from "node:http"; +import { registries } from "bknd"; +import { + type LocalAdapterConfig, + StorageLocalAdapter } from "../../media/storage/adapters/StorageLocalAdapter"; -export { registerLocalMediaAdapter } from "../index"; + +export * from "./node.adapter"; +export { StorageLocalAdapter, type LocalAdapterConfig }; + +export function nodeRequestToRequest(req: IncomingMessage): Request { + let protocol = "http"; + try { + protocol = req.headers["x-forwarded-proto"] as string; + } catch (e) {} + const host = req.headers.host; + const url = `${protocol}://${host}${req.url}`; + const headers = new Headers(); + + for (const [key, value] of Object.entries(req.headers)) { + if (Array.isArray(value)) { + headers.append(key, value.join(", ")); + } else if (value) { + headers.append(key, value); + } + } + + const method = req.method || "GET"; + return new Request(url, { + method, + headers + }); +} + +export function registerLocalMediaAdapter() { + registries.media.register("local", StorageLocalAdapter); +} diff --git a/app/src/adapter/node/node.adapter.ts b/app/src/adapter/node/node.adapter.ts index 4f98466..326ab92 100644 --- a/app/src/adapter/node/node.adapter.ts +++ b/app/src/adapter/node/node.adapter.ts @@ -1,9 +1,10 @@ import path from "node:path"; import { serve as honoServe } from "@hono/node-server"; import { serveStatic } from "@hono/node-server/serve-static"; +import { registerLocalMediaAdapter } from "adapter/node/index"; import type { App } from "bknd"; -import { config as $config } from "core"; -import { type RuntimeBkndConfig, createRuntimeApp } from "../index"; +import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter"; +import { config as $config } from "bknd/core"; export type NodeBkndConfig = RuntimeBkndConfig & { port?: number; @@ -37,9 +38,9 @@ export function serve({ hostname, fetch: async (req: Request) => { if (!app) { + registerLocalMediaAdapter(); app = await createRuntimeApp({ ...config, - registerLocalMedia: true, serveStatic: serveStatic({ root }) }); } diff --git a/app/src/adapter/remix/index.ts b/app/src/adapter/remix/index.ts index e02c2c0..6c9f7db 100644 --- a/app/src/adapter/remix/index.ts +++ b/app/src/adapter/remix/index.ts @@ -1,2 +1,3 @@ export * from "./remix.adapter"; export * from "./AdminPage"; +export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/remix/remix.adapter.ts b/app/src/adapter/remix/remix.adapter.ts index 2a267f2..22470bb 100644 --- a/app/src/adapter/remix/remix.adapter.ts +++ b/app/src/adapter/remix/remix.adapter.ts @@ -1,5 +1,5 @@ -import { type FrameworkBkndConfig, createFrameworkApp } from "adapter"; import type { App } from "bknd"; +import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter"; import { Api } from "bknd/client"; export type RemixBkndConfig = FrameworkBkndConfig; diff --git a/app/src/adapter/vite/index.ts b/app/src/adapter/vite/index.ts index 832bcde..0519488 100644 --- a/app/src/adapter/vite/index.ts +++ b/app/src/adapter/vite/index.ts @@ -1 +1,2 @@ export * from "./vite.adapter"; +export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/vite/vite.adapter.ts b/app/src/adapter/vite/vite.adapter.ts index c8cb43d..dee0603 100644 --- a/app/src/adapter/vite/vite.adapter.ts +++ b/app/src/adapter/vite/vite.adapter.ts @@ -1,7 +1,8 @@ import { serveStatic } from "@hono/node-server/serve-static"; import { type DevServerOptions, default as honoViteDevServer } from "@hono/vite-dev-server"; -import { type RuntimeBkndConfig, createRuntimeApp } from "adapter"; import type { App } from "bknd"; +import { type RuntimeBkndConfig, createRuntimeApp } from "bknd/adapter"; +import { registerLocalMediaAdapter } from "bknd/adapter/node"; import { devServerConfig } from "./dev-server-config"; export type ViteBkndConfig = RuntimeBkndConfig & { @@ -28,10 +29,10 @@ ${addBkndContext ? "" : ""} } async function createApp(config: ViteBkndConfig = {}, env?: any) { + registerLocalMediaAdapter(); return await createRuntimeApp( { ...config, - registerLocalMedia: true, adminOptions: config.setAdminHtml === false ? undefined diff --git a/examples/astro/src/pages/api/[...api].ts b/examples/astro/src/pages/api/[...api].ts index 82d3c4e..e42c3dc 100644 --- a/examples/astro/src/pages/api/[...api].ts +++ b/examples/astro/src/pages/api/[...api].ts @@ -1,7 +1,6 @@ import type { APIContext } from "astro"; import { App } from "bknd"; -import { serve } from "bknd/adapter/astro"; -import { registerLocalMediaAdapter } from "bknd/adapter/node"; +import { registerLocalMediaAdapter, serve } from "bknd/adapter/astro"; import { boolean, em, entity, text } from "bknd/data"; import { secureRandomString } from "bknd/utils"; diff --git a/examples/remix/app/routes/api.$.ts b/examples/remix/app/routes/api.$.ts index 6bd0452..881ac60 100644 --- a/examples/remix/app/routes/api.$.ts +++ b/examples/remix/app/routes/api.$.ts @@ -1,6 +1,5 @@ import { App } from "bknd"; -import { registerLocalMediaAdapter } from "bknd/adapter/node"; -import { serve } from "bknd/adapter/remix"; +import { registerLocalMediaAdapter, serve } from "bknd/adapter/remix"; import { boolean, em, entity, text } from "bknd/data"; import { secureRandomString } from "bknd/utils"; From 123389786d0e83189562b40c25115a6e6593df59 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 14:19:23 +0100 Subject: [PATCH 06/32] bump 0.7 rc version --- app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/package.json b/app/package.json index a2c0893..09fd7d8 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,7 @@ "type": "module", "sideEffects": false, "bin": "./dist/cli/index.js", - "version": "0.6.2", + "version": "0.7.0-rc.1", "description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, Remix, Astro, Cloudflare, Bun, Node, AWS Lambda & more.", "homepage": "https://bknd.io", "repository": { From ba1eb5fe0818631329a171f90c9bf2005824d9e7 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 19:28:39 +0100 Subject: [PATCH 07/32] remove adapter re-exports --- app/src/adapter/astro/index.ts | 1 - app/src/adapter/nextjs/index.ts | 1 - app/src/adapter/remix/index.ts | 1 - app/src/adapter/vite/index.ts | 1 - app/src/index.ts | 1 - 5 files changed, 5 deletions(-) diff --git a/app/src/adapter/astro/index.ts b/app/src/adapter/astro/index.ts index 818174e..d5010a5 100644 --- a/app/src/adapter/astro/index.ts +++ b/app/src/adapter/astro/index.ts @@ -1,2 +1 @@ export * from "./astro.adapter"; -export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/nextjs/index.ts b/app/src/adapter/nextjs/index.ts index e691401..957fa9e 100644 --- a/app/src/adapter/nextjs/index.ts +++ b/app/src/adapter/nextjs/index.ts @@ -1,2 +1 @@ export * from "./nextjs.adapter"; -export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/remix/index.ts b/app/src/adapter/remix/index.ts index 6c9f7db..e02c2c0 100644 --- a/app/src/adapter/remix/index.ts +++ b/app/src/adapter/remix/index.ts @@ -1,3 +1,2 @@ export * from "./remix.adapter"; export * from "./AdminPage"; -export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/adapter/vite/index.ts b/app/src/adapter/vite/index.ts index 0519488..832bcde 100644 --- a/app/src/adapter/vite/index.ts +++ b/app/src/adapter/vite/index.ts @@ -1,2 +1 @@ export * from "./vite.adapter"; -export { registerLocalMediaAdapter } from "bknd/adapter/node"; diff --git a/app/src/index.ts b/app/src/index.ts index 44b1ca5..bedbe45 100644 --- a/app/src/index.ts +++ b/app/src/index.ts @@ -12,7 +12,6 @@ export { export * as middlewares from "modules/middlewares"; export { registries } from "modules/registries"; -export type * from "./adapter"; export { Api, type ApiOptions } from "./Api"; export type { MediaFieldSchema } from "media/AppMedia"; From 2d6d83ccb287f3e7f42e8e44087e7219b97659eb Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 19:29:36 +0100 Subject: [PATCH 08/32] add fetcher option to api to allow local calls --- app/__test__/api/ModuleApi.spec.ts | 10 ++-------- app/src/Api.ts | 19 ++++++++++++------- app/src/modules/ModuleApi.ts | 7 ++++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/__test__/api/ModuleApi.spec.ts b/app/__test__/api/ModuleApi.spec.ts index 5fb6976..9577fd1 100644 --- a/app/__test__/api/ModuleApi.spec.ts +++ b/app/__test__/api/ModuleApi.spec.ts @@ -27,10 +27,7 @@ describe("ModuleApi", () => { it("fetches endpoint", async () => { const app = new Hono().get("/endpoint", (c) => c.json({ foo: "bar" })); - const api = new Api({ host }); - - // @ts-expect-error it's protected - api.fetcher = app.request as typeof fetch; + const api = new Api({ host }, app.request as typeof fetch); const res = await api.get("/endpoint"); expect(res.res.ok).toEqual(true); @@ -41,10 +38,7 @@ describe("ModuleApi", () => { it("has accessible request", async () => { const app = new Hono().get("/endpoint", (c) => c.json({ foo: "bar" })); - const api = new Api({ host }); - - // @ts-expect-error it's protected - api.fetcher = app.request as typeof fetch; + const api = new Api({ host }, app.request as typeof fetch); const promise = api.get("/endpoint"); expect(promise.request).toBeDefined(); diff --git a/app/src/Api.ts b/app/src/Api.ts index 835ff14..2310c0f 100644 --- a/app/src/Api.ts +++ b/app/src/Api.ts @@ -23,6 +23,7 @@ export type ApiOptions = { headers?: Headers; key?: string; localStorage?: boolean; + fetcher?: typeof fetch; }; export type AuthState = { @@ -163,14 +164,18 @@ export class Api { headers: this.options.headers, token_transport: this.token_transport }; + const fetcher = this.options.fetcher; - this.system = new SystemApi(baseParams); - this.data = new DataApi(baseParams); - this.auth = new AuthApi({ - ...baseParams, - onTokenUpdate: (token) => this.updateToken(token, true) - }); - this.media = new MediaApi(baseParams); + this.system = new SystemApi(baseParams, fetcher); + this.data = new DataApi(baseParams, fetcher); + this.auth = new AuthApi( + { + ...baseParams, + onTokenUpdate: (token) => this.updateToken(token, true) + }, + fetcher + ); + this.media = new MediaApi(baseParams, fetcher); } } diff --git a/app/src/modules/ModuleApi.ts b/app/src/modules/ModuleApi.ts index 882cb90..a088170 100644 --- a/app/src/modules/ModuleApi.ts +++ b/app/src/modules/ModuleApi.ts @@ -23,9 +23,10 @@ export type ApiResponse = { export type TInput = string | (string | number | PrimaryFieldType)[]; export abstract class ModuleApi { - protected fetcher?: typeof fetch; - - constructor(protected readonly _options: Partial = {}) {} + constructor( + protected readonly _options: Partial = {}, + protected fetcher?: typeof fetch + ) {} protected getDefaultOptions(): Partial { return {}; From 39c419c3202ca8381b1142c53b4f7ce0eeb116a2 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 25 Jan 2025 19:30:03 +0100 Subject: [PATCH 09/32] add built state and skip auth cookie if not signed in for local calls --- app/src/App.ts | 7 ++++++- app/src/auth/authenticate/Authenticator.ts | 2 +- app/src/modules/ModuleManager.ts | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/App.ts b/app/src/App.ts index b98fc67..d32d57c 100644 --- a/app/src/App.ts +++ b/app/src/App.ts @@ -1,6 +1,7 @@ import type { CreateUserPayload } from "auth/AppAuth"; import { Event } from "core/events"; import { Connection, type LibSqlCredentials, LibsqlConnection } from "data"; +import type { Hono } from "hono"; import { type InitialModuleConfigs, ModuleManager, @@ -132,7 +133,7 @@ export class App { return this.modules.ctx().em; } - get fetch(): any { + get fetch(): Hono["fetch"] { return this.server.fetch; } @@ -155,6 +156,10 @@ export class App { return this.modules.version(); } + isBuilt(): boolean { + return this.modules.isBuilt(); + } + registerAdminController(config?: AdminControllerOptions) { // register admin this.adminController = new AdminController(this, config); diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 7b81ed7..19088d9 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -259,7 +259,7 @@ export class Authenticator = Record< } async requestCookieRefresh(c: Context) { - if (this.config.cookie.renew) { + if (this.config.cookie.renew && this.isUserLoggedIn()) { const token = await this.getAuthCookie(c); if (token) { await this.setAuthCookie(c, token); diff --git a/app/src/modules/ModuleManager.ts b/app/src/modules/ModuleManager.ts index efe7a09..b1868fb 100644 --- a/app/src/modules/ModuleManager.ts +++ b/app/src/modules/ModuleManager.ts @@ -171,6 +171,10 @@ export class ModuleManager { } } + isBuilt(): boolean { + return this._built; + } + /** * This is set through module's setListener * It's called everytime a module's config is updated in SchemaObject From 86ba055f5eb4125ebdc7a0b389294f3428cea12b Mon Sep 17 00:00:00 2001 From: dswbx Date: Tue, 28 Jan 2025 09:10:38 +0100 Subject: [PATCH 10/32] fix entity table select --- app/src/ui/routes/data/data.$entity.index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/routes/data/data.$entity.index.tsx b/app/src/ui/routes/data/data.$entity.index.tsx index 960a4b6..7837785 100644 --- a/app/src/ui/routes/data/data.$entity.index.tsx +++ b/app/src/ui/routes/data/data.$entity.index.tsx @@ -40,7 +40,7 @@ export function DataEntityList({ params }) { useBrowserTitle(["Data", entity?.label ?? params.entity]); const [navigate] = useNavigate(); const search = useSearch(searchSchema, { - select: entity.getSelect(undefined, "form"), + select: entity.getSelect(undefined, "table"), sort: entity.getDefaultSort() }); From c2b3316fcbb63ac141893dd06960b0c53600b195 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 29 Jan 2025 14:44:32 +0100 Subject: [PATCH 11/32] updated API instantiation, and update user on verify --- app/__test__/api/Api.spec.ts | 71 +++++++++++++++++++ app/package.json | 2 +- app/src/Api.ts | 78 +++++++++++++++------ app/src/adapter/astro/astro.adapter.ts | 3 +- app/src/adapter/nextjs/nextjs.adapter.ts | 3 +- app/src/auth/api/AuthController.ts | 14 +++- app/src/index.ts | 2 - app/src/modules/ModuleManager.ts | 42 +++++++---- app/src/ui/client/ClientProvider.tsx | 2 +- app/src/ui/client/index.ts | 2 +- docs/usage/sdk.mdx | 88 +++++++++++++++++++----- 11 files changed, 250 insertions(+), 57 deletions(-) create mode 100644 app/__test__/api/Api.spec.ts diff --git a/app/__test__/api/Api.spec.ts b/app/__test__/api/Api.spec.ts new file mode 100644 index 0000000..85f144d --- /dev/null +++ b/app/__test__/api/Api.spec.ts @@ -0,0 +1,71 @@ +import { describe, expect, it } from "bun:test"; +import { sign } from "hono/jwt"; +import { Api } from "../../src/Api"; + +describe("Api", async () => { + it("should construct without options", () => { + const api = new Api(); + expect(api.baseUrl).toBe("http://localhost"); + expect(api.isAuthVerified()).toBe(false); + }); + + it("should ignore force verify if no claims given", () => { + const api = new Api({ verified: true }); + expect(api.baseUrl).toBe("http://localhost"); + expect(api.isAuthVerified()).toBe(false); + }); + + it("should construct from request (token)", async () => { + const token = await sign({ foo: "bar" }, "1234"); + const request = new Request("http://example.com/test", { + headers: { + Authorization: `Bearer ${token}` + } + }); + const api = new Api({ request }); + expect(api.isAuthVerified()).toBe(false); + + const params = api.getParams(); + expect(params.token).toBe(token); + expect(params.token_transport).toBe("header"); + expect(params.host).toBe("http://example.com"); + }); + + it("should construct from request (cookie)", async () => { + const token = await sign({ foo: "bar" }, "1234"); + const request = new Request("http://example.com/test", { + headers: { + Cookie: `auth=${token}` + } + }); + const api = new Api({ request }); + expect(api.isAuthVerified()).toBe(false); + + const params = api.getParams(); + console.log(params); + expect(params.token).toBe(token); + expect(params.token_transport).toBe("cookie"); + expect(params.host).toBe("http://example.com"); + }); + + it("should construct from token", async () => { + const token = await sign({ foo: "bar" }, "1234"); + const api = new Api({ token }); + expect(api.isAuthVerified()).toBe(false); + + const params = api.getParams(); + expect(params.token).toBe(token); + expect(params.token_transport).toBe("header"); + expect(params.host).toBe("http://localhost"); + }); + + it("should prefer host when request is given", async () => { + const request = new Request("http://example.com/test"); + const api = new Api({ request, host: "http://another.com" }); + + const params = api.getParams(); + expect(params.token).toBeUndefined(); + expect(params.token_transport).toBe("header"); + expect(params.host).toBe("http://another.com"); + }); +}); diff --git a/app/package.json b/app/package.json index 09fd7d8..9baffe0 100644 --- a/app/package.json +++ b/app/package.json @@ -3,7 +3,7 @@ "type": "module", "sideEffects": false, "bin": "./dist/cli/index.js", - "version": "0.7.0-rc.1", + "version": "0.7.0-rc.4", "description": "Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, Remix, Astro, Cloudflare, Bun, Node, AWS Lambda & more.", "homepage": "https://bknd.io", "repository": { diff --git a/app/src/Api.ts b/app/src/Api.ts index 2310c0f..f0946f0 100644 --- a/app/src/Api.ts +++ b/app/src/Api.ts @@ -17,14 +17,21 @@ declare global { } export type ApiOptions = { - host: string; - user?: TApiUser; - token?: string; + host?: string; headers?: Headers; key?: string; localStorage?: boolean; fetcher?: typeof fetch; -}; + verified?: boolean; +} & ( + | { + token?: string; + user?: TApiUser; + } + | { + request: Request; + } +); export type AuthState = { token?: string; @@ -43,14 +50,26 @@ export class Api { public auth!: AuthApi; public media!: MediaApi; - constructor(private readonly options: ApiOptions) { - if (options.user) { - this.user = options.user; - this.token_transport = "none"; - this.verified = true; - } else if (options.token) { + constructor(private options: ApiOptions = {}) { + // only mark verified if forced + this.verified = options.verified === true; + + // prefer request if given + if ("request" in options) { + this.options.host = options.host ?? new URL(options.request.url).origin; + this.options.headers = options.headers ?? options.request.headers; + this.extractToken(); + + // then check for a token + } else if ("token" in options) { this.token_transport = "header"; this.updateToken(options.token); + + // then check for an user object + } else if ("user" in options) { + this.token_transport = "none"; + this.user = options.user; + this.verified = options.verified !== false; } else { this.extractToken(); } @@ -59,7 +78,7 @@ export class Api { } get baseUrl() { - return this.options.host; + return this.options.host ?? "http://localhost"; } get tokenKey() { @@ -67,13 +86,15 @@ export class Api { } private extractToken() { + // if token has to be extracted, it's never verified + this.verified = false; + if (this.options.headers) { // try cookies const cookieToken = getCookieValue(this.options.headers.get("cookie"), "auth"); if (cookieToken) { - this.updateToken(cookieToken); this.token_transport = "cookie"; - this.verified = true; + this.updateToken(cookieToken); return; } @@ -97,6 +118,8 @@ export class Api { updateToken(token?: string, rebuild?: boolean) { this.token = token; + this.verified = false; + if (token) { this.user = omit(decode(token).payload as any, ["iat", "iss", "exp"]) as any; } else { @@ -116,11 +139,15 @@ export class Api { if (rebuild) this.buildApis(); } - markAuthVerified(verfied: boolean) { + private markAuthVerified(verfied: boolean) { this.verified = verfied; return this; } + isAuthVerified(): boolean { + return this.verified; + } + getAuthState(): AuthState { return { token: this.token, @@ -129,6 +156,11 @@ export class Api { }; } + isAuthenticated(): boolean { + const { token, user } = this.getAuthState(); + return !!token && !!user; + } + async getVerifiedAuthState(): Promise { await this.verifyAuth(); return this.getAuthState(); @@ -141,11 +173,13 @@ export class Api { } try { - const res = await this.auth.me(); - if (!res.ok || !res.body.user) { + const { ok, data } = await this.auth.me(); + const user = data?.user; + if (!ok || !user) { throw new Error(); } + this.user = user; this.markAuthVerified(true); } catch (e) { this.markAuthVerified(false); @@ -157,13 +191,17 @@ export class Api { return this.user || null; } - private buildApis() { - const baseParams = { - host: this.options.host, + getParams() { + return Object.freeze({ + host: this.baseUrl, token: this.token, headers: this.options.headers, token_transport: this.token_transport - }; + }); + } + + private buildApis() { + const baseParams = this.getParams(); const fetcher = this.options.fetcher; this.system = new SystemApi(baseParams, fetcher); diff --git a/app/src/adapter/astro/astro.adapter.ts b/app/src/adapter/astro/astro.adapter.ts index a4886c4..c15d570 100644 --- a/app/src/adapter/astro/astro.adapter.ts +++ b/app/src/adapter/astro/astro.adapter.ts @@ -1,5 +1,6 @@ -import { Api, type ApiOptions, type App } from "bknd"; +import type { App } from "bknd"; import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter"; +import { Api, type ApiOptions } from "bknd/client"; export type AstroBkndConfig = FrameworkBkndConfig; diff --git a/app/src/adapter/nextjs/nextjs.adapter.ts b/app/src/adapter/nextjs/nextjs.adapter.ts index 7310727..f674eb1 100644 --- a/app/src/adapter/nextjs/nextjs.adapter.ts +++ b/app/src/adapter/nextjs/nextjs.adapter.ts @@ -1,7 +1,8 @@ import type { IncomingMessage, ServerResponse } from "node:http"; -import { Api, type App } from "bknd"; +import type { App } from "bknd"; import { type FrameworkBkndConfig, createFrameworkApp } from "bknd/adapter"; import { nodeRequestToRequest } from "bknd/adapter/node"; +import { Api } from "bknd/client"; export type NextjsBkndConfig = FrameworkBkndConfig & { cleanSearch?: string[]; diff --git a/app/src/auth/api/AuthController.ts b/app/src/auth/api/AuthController.ts index 82b50e1..2ba24a5 100644 --- a/app/src/auth/api/AuthController.ts +++ b/app/src/auth/api/AuthController.ts @@ -21,6 +21,15 @@ export class AuthController extends Controller { return this.auth.ctx.guard; } + get em() { + return this.auth.ctx.em; + } + + get userRepo() { + const entity_name = this.auth.config.entity_name; + return this.em.repo(entity_name as "users"); + } + private registerStrategyActions(strategy: Strategy, mainHono: Hono) { const actions = strategy.getActions?.(); if (!actions) { @@ -96,7 +105,10 @@ export class AuthController extends Controller { hono.get("/me", auth(), async (c) => { if (this.auth.authenticator.isUserLoggedIn()) { - return c.json({ user: this.auth.authenticator.getUser() }); + const claims = this.auth.authenticator.getUser()!; + const { data: user } = await this.userRepo.findId(claims.id); + + return c.json({ user }); } return c.json({ user: null }, 403); diff --git a/app/src/index.ts b/app/src/index.ts index bedbe45..9593e7c 100644 --- a/app/src/index.ts +++ b/app/src/index.ts @@ -12,7 +12,5 @@ export { export * as middlewares from "modules/middlewares"; export { registries } from "modules/registries"; -export { Api, type ApiOptions } from "./Api"; - export type { MediaFieldSchema } from "media/AppMedia"; export type { UserFieldSchema } from "auth/AppAuth"; diff --git a/app/src/modules/ModuleManager.ts b/app/src/modules/ModuleManager.ts index b1868fb..8019c50 100644 --- a/app/src/modules/ModuleManager.ts +++ b/app/src/modules/ModuleManager.ts @@ -68,6 +68,12 @@ export type InitialModuleConfigs = } & ModuleConfigs) | PartialRec; +enum Verbosity { + silent = 0, + error = 1, + log = 2 +} + export type ModuleManagerOptions = { initial?: InitialModuleConfigs; eventManager?: EventManager; @@ -85,6 +91,8 @@ export type ModuleManagerOptions = { trustFetched?: boolean; // runs when initial config provided on a fresh database seed?: (ctx: ModuleBuildContext) => Promise; + // wether + verbosity?: Verbosity; }; type ConfigTable = { @@ -135,7 +143,7 @@ export class ModuleManager { private _built = false; private readonly _booted_with?: "provided" | "partial"; - private logger = new DebugLogger(false); + private logger: DebugLogger; constructor( private readonly connection: Connection, @@ -144,6 +152,7 @@ export class ModuleManager { this.__em = new EntityManager([__bknd], this.connection); this.modules = {} as Modules; this.emgr = new EventManager(); + this.logger = new DebugLogger(this.verbosity === Verbosity.log); const context = this.ctx(true); let initial = {} as Partial; @@ -171,6 +180,10 @@ export class ModuleManager { } } + private get verbosity() { + return this.options?.verbosity ?? Verbosity.silent; + } + isBuilt(): boolean { return this._built; } @@ -245,20 +258,23 @@ export class ModuleManager { const startTime = performance.now(); // disabling console log, because the table might not exist yet - const result = await withDisabledConsole(async () => { - const { data: result } = await this.repo().findOne( - { type: "config" }, - { - sort: { by: "version", dir: "desc" } + const result = await withDisabledConsole( + async () => { + const { data: result } = await this.repo().findOne( + { type: "config" }, + { + sort: { by: "version", dir: "desc" } + } + ); + + if (!result) { + throw BkndError.with("no config"); } - ); - if (!result) { - throw BkndError.with("no config"); - } - - return result as unknown as ConfigTable; - }, ["log", "error", "warn"]); + return result as unknown as ConfigTable; + }, + this.verbosity > Verbosity.silent ? [] : ["log", "error", "warn"] + ); this.logger .log("took", performance.now() - startTime, "ms", { diff --git a/app/src/ui/client/ClientProvider.tsx b/app/src/ui/client/ClientProvider.tsx index f456f94..f5027e0 100644 --- a/app/src/ui/client/ClientProvider.tsx +++ b/app/src/ui/client/ClientProvider.tsx @@ -30,7 +30,7 @@ export const ClientProvider = ({ children, baseUrl, user }: ClientProviderProps) console.error("error .....", e); } - console.log("api init", { host: actualBaseUrl, user: user ?? winCtx.user }); + //console.log("api init", { host: actualBaseUrl, user: user ?? winCtx.user }); const api = new Api({ host: actualBaseUrl, user: user ?? winCtx.user }); return ( diff --git a/app/src/ui/client/index.ts b/app/src/ui/client/index.ts index 9367294..168d127 100644 --- a/app/src/ui/client/index.ts +++ b/app/src/ui/client/index.ts @@ -9,4 +9,4 @@ export { export * from "./api/use-api"; export * from "./api/use-entity"; export { useAuth } from "./schema/auth/use-auth"; -export { Api } from "../../Api"; +export { Api, type TApiUser, type AuthState, type ApiOptions } from "../../Api"; diff --git a/docs/usage/sdk.mdx b/docs/usage/sdk.mdx index ccb5cb2..919a8ee 100644 --- a/docs/usage/sdk.mdx +++ b/docs/usage/sdk.mdx @@ -5,19 +5,74 @@ description: 'Use the bknd SDK in TypeScript' To start using the bknd API, start by creating a new API instance: ```ts -import { Api } from "bknd"; +import { Api } from "bknd/client"; -const api = new Api({ - host: "..." // point to your bknd instance -}); +const api = new Api(); -// make sure to verify auth +// always make sure to verify auth await api.verifyAuth(); ``` The `Api` class is the main entry point for interacting with the bknd API. It provides methods for all available modules described below. +## Setup +You can initialize an API instance by providing the `Request` object, or manually specifying the details such as `host` and `token`. + +### Using the `Request` object +The recommended way to create an API instance is by passing the current `Request` object. This will automatically point the API to your current instance and extract the token from the headers (either from cookies or `Authorization` header): + +```ts +import { Api } from "bknd/client"; + +// replace this with the actual request +let request: Request; + +const api = new Api({ request }); +``` + +If the authentication details are contained in the current request, but you're hosting your bknd instance somewhere else, you can specify a `host` option: + +```ts +import { Api } from "bknd/client"; + +// replace this with the actual request +let request: Request; + +const api = new Api({ + host: "https://", + request, +}); +``` + +### Using the `token` option +If you want to have an API instance that is using a different token, e.g. an admin token, you can create it by specifying the `host` and `token` option: + +```ts +import { Api } from "bknd/client"; +const api = new Api({ + host: "https://", + token: "" +}); +``` + +### Using a local API +In case the place where you're using the API is the same as your bknd instance (e.g. when using it embedded in a React framework), you can specify a `fetcher` option to point to your bknd app. This way, requests won't travel over the network and instead processed locally: + +```ts +import type { App } from "bknd"; +import { Api } from "bknd/client"; + +// replace this with your actual `App` instance +let app: App; + +const api = new Api({ + fetcher: app.server.request as typeof fetch, + // specify `host` and `token` or `request` +}); +``` + + ## Data (`api.data`) Access the `Data` specific API methods at `api.data`. @@ -79,19 +134,25 @@ const { data } = await api.data.deleteOne("posts", 1); Access the `Auth` specific API methods at `api.auth`. If there is successful authentication, the API will automatically save the token and use it for subsequent requests. -### `auth.loginWithPassword([input])` -To log in with a password, use the `loginWithPassword` method: +### `auth.strategies()` +To retrieve the available authentication strategies, use the `strategies` method: ```ts -const { data } = await api.auth.loginWithPassword({ +const { data } = await api.auth.strategies(); +``` + +### `auth.login([strategy], [input])` +To log in with a password, use the `login` method: +```ts +const { data } = await api.auth.login("password", { email: "...", password: "..." }); ``` -### `auth.registerWithPassword([input])` -To register with a password, use the `registerWithPassword` method: +### `auth.register([strategy], [input])` +To register with a password, use the `register` method: ```ts -const { data } = await api.auth.registerWithPassword({ +const { data } = await api.auth.register("password", { email: "...", password: "..." }); @@ -103,8 +164,3 @@ To retrieve the current user, use the `me` method: const { data } = await api.auth.me(); ``` -### `auth.strategies()` -To retrieve the available authentication strategies, use the `strategies` method: -```ts -const { data } = await api.auth.strategies(); -``` \ No newline at end of file From 10db26716451832c6a01d894715f6b1d3b465cc5 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 29 Jan 2025 20:26:06 +0100 Subject: [PATCH 12/32] added a `redirect` param to password strategy --- app/src/auth/authenticate/Authenticator.ts | 9 ++- .../strategies/PasswordStrategy.ts | 61 ++++++++++++++----- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 19088d9..63f4f22 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -299,8 +299,8 @@ export class Authenticator = Record< } } - private getSuccessPath(c: Context) { - const p = (this.config.cookie.pathSuccess ?? "/").replace(/\/+$/, "/"); + private getSafeUrl(c: Context, path: string) { + const p = path.replace(/\/+$/, "/"); // nextjs doesn't support non-fq urls // but env could be proxied (stackblitz), so we shouldn't fq every url @@ -316,7 +316,10 @@ export class Authenticator = Record< return c.json(data); } - const successUrl = this.getSuccessPath(c); + const successUrl = this.getSafeUrl( + c, + redirect ? redirect : (this.config.cookie.pathSuccess ?? "/") + ); const referer = redirect ?? c.req.header("Referer") ?? successUrl; //console.log("auth respond", { redirect, successUrl, successPath }); diff --git a/app/src/auth/authenticate/strategies/PasswordStrategy.ts b/app/src/auth/authenticate/strategies/PasswordStrategy.ts index d8f8a23..c6a9a37 100644 --- a/app/src/auth/authenticate/strategies/PasswordStrategy.ts +++ b/app/src/auth/authenticate/strategies/PasswordStrategy.ts @@ -1,4 +1,5 @@ import type { Authenticator, Strategy } from "auth"; +import { isDebug, tbValidator as tb } from "core"; import { type Static, StringEnum, Type, parse } from "core/utils"; import { hash } from "core/utils"; import { type Context, Hono } from "hono"; @@ -56,26 +57,56 @@ export class PasswordStrategy implements Strategy { const hono = new Hono(); return hono - .post("/login", async (c) => { - const body = await authenticator.getBody(c); + .post( + "/login", + tb( + "query", + Type.Object({ + redirect: Type.Optional(Type.String()) + }) + ), + async (c) => { + const body = await authenticator.getBody(c); + const { redirect } = c.req.valid("query"); - try { - const payload = await this.login(body); - const data = await authenticator.resolve("login", this, payload.password, payload); + try { + const payload = await this.login(body); + const data = await authenticator.resolve( + "login", + this, + payload.password, + payload + ); - return await authenticator.respond(c, data); - } catch (e) { - return await authenticator.respond(c, e); + return await authenticator.respond(c, data, redirect); + } catch (e) { + return await authenticator.respond(c, e); + } } - }) - .post("/register", async (c) => { - const body = await authenticator.getBody(c); + ) + .post( + "/register", + tb( + "query", + Type.Object({ + redirect: Type.Optional(Type.String()) + }) + ), + async (c) => { + const body = await authenticator.getBody(c); + const { redirect } = c.req.valid("query"); - const payload = await this.register(body); - const data = await authenticator.resolve("register", this, payload.password, payload); + const payload = await this.register(body); + const data = await authenticator.resolve( + "register", + this, + payload.password, + payload + ); - return await authenticator.respond(c, data); - }); + return await authenticator.respond(c, data, redirect); + } + ); } getActions(): StrategyActions { From 4755288fedd93a12825d5c9bf0157014a4784177 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 29 Jan 2025 20:30:27 +0100 Subject: [PATCH 13/32] improve fallbacks for redirection --- app/src/auth/authenticate/Authenticator.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 63f4f22..13fa6bc 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -316,10 +316,7 @@ export class Authenticator = Record< return c.json(data); } - const successUrl = this.getSafeUrl( - c, - redirect ? redirect : (this.config.cookie.pathSuccess ?? "/") - ); + const successUrl = this.getSafeUrl(c, redirect ?? this.config.cookie.pathSuccess ?? "/"); const referer = redirect ?? c.req.header("Referer") ?? successUrl; //console.log("auth respond", { redirect, successUrl, successPath }); From db476080ad776a2c1ea0511bbdf5b15a6e84e37a Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 1 Feb 2025 09:13:42 +0100 Subject: [PATCH 14/32] also sending cookies on json auth requests --- app/src/auth/api/AuthApi.ts | 10 ++++++++-- app/src/auth/authenticate/Authenticator.ts | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/src/auth/api/AuthApi.ts b/app/src/auth/api/AuthApi.ts index d02a258..f5ba882 100644 --- a/app/src/auth/api/AuthApi.ts +++ b/app/src/auth/api/AuthApi.ts @@ -15,7 +15,10 @@ export class AuthApi extends ModuleApi { } async login(strategy: string, input: any) { - const res = await this.post([strategy, "login"], input); + const res = await this.post([strategy, "login"], input, { + credentials: "include" + }); + if (res.ok && res.body.token) { await this.options.onTokenUpdate?.(res.body.token); } @@ -23,7 +26,10 @@ export class AuthApi extends ModuleApi { } async register(strategy: string, input: any) { - const res = await this.post([strategy, "register"], input); + const res = await this.post([strategy, "register"], input, { + credentials: "include" + }); + if (res.ok && res.body.token) { await this.options.onTokenUpdate?.(res.body.token); } diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 19088d9..96a2806 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -312,21 +312,26 @@ export class Authenticator = Record< } async respond(c: Context, data: AuthResponse | Error | any, redirect?: string) { - if (this.isJsonRequest(c)) { - return c.json(data); - } - const successUrl = this.getSuccessPath(c); const referer = redirect ?? c.req.header("Referer") ?? successUrl; //console.log("auth respond", { redirect, successUrl, successPath }); if ("token" in data) { await this.setAuthCookie(c, data.token); + + if (this.isJsonRequest(c)) { + return c.json(data); + } + // can't navigate to "/" – doesn't work on nextjs //console.log("auth success, redirecting to", successUrl); return c.redirect(successUrl); } + if (this.isJsonRequest(c)) { + return c.json(data, 400); + } + let message = "An error occured"; if (data instanceof Exception) { message = data.message; From a8e78f984d0f46366cab2d1d9a1bd7a492e5cc1d Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 1 Feb 2025 12:12:22 +0100 Subject: [PATCH 15/32] fix repo stringified string parsing --- app/__test__/data/data-query-impl.spec.ts | 17 +++++++ app/src/data/server/data-query-impl.ts | 59 +++++++++++++++++------ 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/app/__test__/data/data-query-impl.spec.ts b/app/__test__/data/data-query-impl.spec.ts index c03b1fe..d219bcc 100644 --- a/app/__test__/data/data-query-impl.spec.ts +++ b/app/__test__/data/data-query-impl.spec.ts @@ -123,6 +123,23 @@ describe("data-query-impl", () => { } } ); + + // over http + { + const output = { with: { images: {} } }; + decode({ with: "images" }, output); + decode({ with: '["images"]' }, output); + decode({ with: ["images"] }, output); + decode({ with: { images: {} } }, output); + } + + { + const output = { with: { images: {}, comments: {} } }; + decode({ with: "images,comments" }, output); + decode({ with: ["images", "comments"] }, output); + decode({ with: '["images", "comments"]' }, output); + decode({ with: { images: {}, comments: {} } }, output); + } }); }); diff --git a/app/src/data/server/data-query-impl.ts b/app/src/data/server/data-query-impl.ts index 8abf02e..13028df 100644 --- a/app/src/data/server/data-query-impl.ts +++ b/app/src/data/server/data-query-impl.ts @@ -5,7 +5,8 @@ import { type StaticDecode, StringEnum, Type, - Value + Value, + isObject } from "core/utils"; import { WhereBuilder, type WhereQuery } from "../entities"; @@ -71,22 +72,52 @@ export type RepoWithSchema = Record< >; export const withSchema = (Self: TSelf) => - Type.Transform(Type.Union([stringArray, Type.Record(Type.String(), Self)])) + Type.Transform( + Type.Union([Type.String(), Type.Array(Type.String()), Type.Record(Type.String(), Self)]) + ) .Decode((value) => { - let _value = typeof value === "string" ? [value] : value; + console.log("value:in", value); + // images + // images,comments + // ["images","comments"] + // { "images": {} } - if (Array.isArray(value)) { - if (!value.every((v) => typeof v === "string")) { - throw new Error("Invalid 'with' schema"); - } - - _value = value.reduce((acc, v) => { - acc[v] = {}; - return acc; - }, {} as RepoWithSchema); + if (!Array.isArray(value) && isObject(value)) { + console.log("is object"); + return value as RepoWithSchema; } - return _value as RepoWithSchema; + let _value: any = null; + if (typeof value === "string") { + // if stringified object + if (value.match(/^\{/)) { + return JSON.parse(value) as RepoWithSchema; + } + + // if stringified array + if (value.match(/^\[/)) { + _value = JSON.parse(value) as string[]; + + // if comma-separated string + } else if (value.includes(",")) { + _value = value.split(","); + + // if single string + } else { + _value = [value]; + } + } else if (Array.isArray(value)) { + _value = value; + } + + if (!_value || !Array.isArray(_value) || !_value.every((v) => typeof v === "string")) { + throw new Error("Invalid 'with' schema"); + } + + return _value.reduce((acc, v) => { + acc[v] = {}; + return acc; + }, {} as RepoWithSchema); }) .Encode((value) => value); @@ -117,7 +148,7 @@ export type RepoQueryIn = { offset?: number; sort?: string | { by: string; dir: "asc" | "desc" }; select?: string[]; - with?: string[] | Record; + with?: string | string[] | Record; join?: string[]; where?: WhereQuery; }; From 8f0cef1f37d5e33d747579fffba446fbc18a16e0 Mon Sep 17 00:00:00 2001 From: dswbx Date: Sat, 1 Feb 2025 12:15:48 +0100 Subject: [PATCH 16/32] clear console log --- app/src/data/server/data-query-impl.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/data/server/data-query-impl.ts b/app/src/data/server/data-query-impl.ts index 13028df..5507c3c 100644 --- a/app/src/data/server/data-query-impl.ts +++ b/app/src/data/server/data-query-impl.ts @@ -76,7 +76,6 @@ export const withSchema = (Self: TSelf) => Type.Union([Type.String(), Type.Array(Type.String()), Type.Record(Type.String(), Self)]) ) .Decode((value) => { - console.log("value:in", value); // images // images,comments // ["images","comments"] From f432473ed95503eb830c92f917132cf751c92907 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 5 Feb 2025 10:31:08 +0100 Subject: [PATCH 17/32] initial json schema form implementation --- app/__test__/core/object/utils.spec.ts | 27 ++ app/__test__/ui/json-form.spec.ts | 146 ++++++++ app/package.json | 21 +- app/src/core/utils/objects.ts | 23 ++ app/src/core/utils/strings.ts | 3 + .../ui/client/schema/media/use-bknd-media.ts | 33 ++ .../form/Formy/BooleanInputMantine.tsx | 3 +- .../ui/components/form/Formy/components.tsx | 109 ++++-- .../json-schema-form/components/Field.tsx | 98 ++++++ .../components/form/json-schema-form/index.ts | 2 + .../validators/cf-validator.ts | 11 + .../validators/tb-validator.ts | 11 + .../form/json-schema-form2/Form.tsx | 192 ++++++++++ .../form/json-schema-form2/utils.ts | 198 +++++++++++ .../form/json-schema-form3/AnyOfField.tsx | 115 ++++++ .../form/json-schema-form3/ArrayField.tsx | 101 ++++++ .../form/json-schema-form3/Field.tsx | 93 +++++ .../form/json-schema-form3/FieldWrapper.tsx | 89 +++++ .../form/json-schema-form3/Form.tsx | 196 +++++++++++ .../form/json-schema-form3/ObjectField.tsx | 46 +++ .../form/json-schema-form3/utils.ts | 202 +++++++++++ app/src/ui/elements/auth/AuthForm.tsx | 13 +- app/src/ui/routes/media/_media.root.tsx | 18 +- app/src/ui/routes/media/index.tsx | 7 +- app/src/ui/routes/media/media.index.tsx | 15 + app/src/ui/routes/media/media.settings.tsx | 126 +++++++ app/src/ui/routes/test/index.tsx | 6 +- .../routes/test/tests/json-schema-form2.tsx | 287 +++++++++++++++ .../routes/test/tests/json-schema-form3.tsx | 328 ++++++++++++++++++ bun.lockb | Bin 1068368 -> 1076264 bytes 30 files changed, 2453 insertions(+), 66 deletions(-) create mode 100644 app/__test__/core/object/utils.spec.ts create mode 100644 app/__test__/ui/json-form.spec.ts create mode 100644 app/src/ui/client/schema/media/use-bknd-media.ts create mode 100644 app/src/ui/components/form/json-schema-form/components/Field.tsx create mode 100644 app/src/ui/components/form/json-schema-form/index.ts create mode 100644 app/src/ui/components/form/json-schema-form/validators/cf-validator.ts create mode 100644 app/src/ui/components/form/json-schema-form/validators/tb-validator.ts create mode 100644 app/src/ui/components/form/json-schema-form2/Form.tsx create mode 100644 app/src/ui/components/form/json-schema-form2/utils.ts create mode 100644 app/src/ui/components/form/json-schema-form3/AnyOfField.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/ArrayField.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/Field.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/FieldWrapper.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/Form.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/ObjectField.tsx create mode 100644 app/src/ui/components/form/json-schema-form3/utils.ts create mode 100644 app/src/ui/routes/media/media.index.tsx create mode 100644 app/src/ui/routes/media/media.settings.tsx create mode 100644 app/src/ui/routes/test/tests/json-schema-form2.tsx create mode 100644 app/src/ui/routes/test/tests/json-schema-form3.tsx diff --git a/app/__test__/core/object/utils.spec.ts b/app/__test__/core/object/utils.spec.ts new file mode 100644 index 0000000..03a572f --- /dev/null +++ b/app/__test__/core/object/utils.spec.ts @@ -0,0 +1,27 @@ +import { describe, expect, test } from "bun:test"; +import * as utils from "../../../src/core/utils/objects"; + +describe("object utils", () => { + test("flattenObject", () => { + const obj = { + a: { + b: { + c: 1, + a: ["a", "b", "c"] + } + }, + d: [1, 2, { e: 3 }] + }; + + console.log("flat", utils.flattenObject2(obj)); + expect(utils.flattenObject2(obj)).toEqual({ + "a.b.c": 1, + "a.b.a[0]": "a", + "a.b.a[1]": "b", + "a.b.a[2]": "c", + "d[0]": 1, + "d[1]": 2, + "d[2].e": 3 + }); + }); +}); diff --git a/app/__test__/ui/json-form.spec.ts b/app/__test__/ui/json-form.spec.ts new file mode 100644 index 0000000..16998ca --- /dev/null +++ b/app/__test__/ui/json-form.spec.ts @@ -0,0 +1,146 @@ +import { describe, expect, test } from "bun:test"; +import { Draft2019 } from "json-schema-library"; +import type { JSONSchema } from "json-schema-to-ts"; +import * as utils from "../../src/ui/components/form/json-schema-form2/utils"; + +describe("json form", () => { + test("normalize path", () => { + const examples = [ + ["description", "#/description"], + ["/description", "#/description"], + ["nested/property", "#/nested/property"], + ["nested.property", "#/nested/property"], + ["nested.property[0]", "#/nested/property/0"], + ["nested.property[0].name", "#/nested/property/0/name"] + ]; + + for (const [input, output] of examples) { + expect(utils.normalizePath(input)).toBe(output); + } + }); + + test("coerse", () => { + const examples = [ + ["test", { type: "string" }, "test"], + ["1", { type: "integer" }, 1], + ["1", { type: "number" }, 1], + ["true", { type: "boolean" }, true], + ["false", { type: "boolean" }, false], + ["1", { type: "boolean" }, true], + ["0", { type: "boolean" }, false], + ["on", { type: "boolean" }, true], + ["off", { type: "boolean" }, false], + ["null", { type: "null" }, null] + ] satisfies [string, Exclude, any][]; + + for (const [input, schema, output] of examples) { + expect(utils.coerce(input, schema)).toBe(output); + } + }); + + test("getParentPointer", () => { + const examples = [ + ["#/nested/property/0/name", "#/nested/property/0"], + ["#/nested/property/0", "#/nested/property"], + ["#/nested/property", "#/nested"], + ["#/nested", "#"] + ]; + + for (const [input, output] of examples) { + expect(utils.getParentPointer(input)).toBe(output); + } + }); + + test("isRequired", () => { + const examples = [ + [ + "#/description", + { type: "object", properties: { description: { type: "string" } } }, + false + ], + [ + "#/description", + { + type: "object", + required: ["description"], + properties: { description: { type: "string" } } + }, + true + ], + [ + "#/nested/property", + { + type: "object", + properties: { + nested: { + type: "object", + properties: { property: { type: "string" } } + } + } + }, + false + ], + [ + "#/nested/property", + { + type: "object", + properties: { + nested: { + type: "object", + required: ["property"], + properties: { property: { type: "string" } } + } + } + }, + true + ] + ] satisfies [string, Exclude, boolean][]; + + for (const [pointer, schema, output] of examples) { + expect(utils.isRequired(pointer, schema)).toBe(output); + } + }); + + test("unflatten", () => { + const examples = [ + [ + { "#/description": "test" }, + { + type: "object", + properties: { + description: { type: "string" } + } + }, + { + description: "test" + } + ] + ] satisfies [Record, Exclude, object][]; + + for (const [input, schema, output] of examples) { + expect(utils.unflatten(input, schema)).toEqual(output); + } + }); + + test.only("...", () => { + const schema = { + type: "object", + properties: { + name: { type: "string", maxLength: 2 }, + description: { type: "string", maxLength: 2 }, + age: { type: "number", description: "Age of you" }, + deep: { + type: "object", + properties: { + nested: { type: "string", maxLength: 2 } + } + } + }, + required: ["description"] + }; + + const lib = new Draft2019(schema); + + lib.eachSchema(console.log); + }); +}); diff --git a/app/package.json b/app/package.json index 9baffe0..4373a2a 100644 --- a/app/package.json +++ b/app/package.json @@ -33,26 +33,28 @@ "license": "FSL-1.1-MIT", "dependencies": { "@cfworker/json-schema": "^2.0.1", + "@codemirror/lang-html": "^6.4.9", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-liquid": "^6.2.1", + "@hello-pangea/dnd": "^17.0.0", "@libsql/client": "^0.14.0", + "@mantine/core": "^7.13.4", "@sinclair/typebox": "^0.32.34", "@tanstack/react-form": "0.19.2", + "@uiw/react-codemirror": "^4.23.6", + "@xyflow/react": "^12.3.2", "aws4fetch": "^1.0.18", "dayjs": "^1.11.13", "fast-xml-parser": "^4.4.0", "hono": "^4.6.12", + "json-schema-form-react": "link:json-schema-form-react", + "json-schema-library": "^10.0.0-rc7", "kysely": "^0.27.4", "liquidjs": "^10.15.0", "lodash-es": "^4.17.21", "oauth4webapi": "^2.11.1", - "swr": "^2.2.5", - "json-schema-form-react": "^0.0.2", - "@uiw/react-codemirror": "^4.23.6", - "@codemirror/lang-html": "^6.4.9", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-liquid": "^6.2.1", - "@xyflow/react": "^12.3.2", - "@mantine/core": "^7.13.4", - "@hello-pangea/dnd": "^17.0.0" + "object-path-immutable": "^4.1.2", + "swr": "^2.2.5" }, "devDependencies": { "@aws-sdk/client-s3": "^3.613.0", @@ -73,6 +75,7 @@ "clsx": "^2.1.1", "esbuild-postcss": "^0.0.4", "jotai": "^2.10.1", + "json-schema-to-ts": "^3.1.1", "open": "^10.1.0", "openapi-types": "^12.1.3", "postcss": "^8.4.47", diff --git a/app/src/core/utils/objects.ts b/app/src/core/utils/objects.ts index ab5b807..ce37261 100644 --- a/app/src/core/utils/objects.ts +++ b/app/src/core/utils/objects.ts @@ -166,6 +166,29 @@ export function flattenObject(obj: any, parentKey = "", result: any = {}): any { return result; } +export function flattenObject2(obj: any, parentKey = "", result: any = {}): any { + for (const key in obj) { + if (key in obj) { + const newKey = parentKey ? `${parentKey}.${key}` : key; + if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) { + flattenObject2(obj[key], newKey, result); + } else if (Array.isArray(obj[key])) { + obj[key].forEach((item, index) => { + const arrayKey = `${newKey}[${index}]`; + if (typeof item === "object" && item !== null) { + flattenObject2(item, arrayKey, result); + } else { + result[arrayKey] = item; + } + }); + } else { + result[newKey] = obj[key]; + } + } + } + return result; +} + export function objectDepth(object: object): number { let level = 1; for (const key in object) { diff --git a/app/src/core/utils/strings.ts b/app/src/core/utils/strings.ts index c7789dd..fc268e4 100644 --- a/app/src/core/utils/strings.ts +++ b/app/src/core/utils/strings.ts @@ -84,6 +84,9 @@ export function identifierToHumanReadable(str: string) { return str; } } +export function autoFormatString(str: string) { + return identifierToHumanReadable(str); +} export function kebabToPascalWithSpaces(str: string): string { return str.split("-").map(ucFirst).join(" "); diff --git a/app/src/ui/client/schema/media/use-bknd-media.ts b/app/src/ui/client/schema/media/use-bknd-media.ts new file mode 100644 index 0000000..4d8dbd1 --- /dev/null +++ b/app/src/ui/client/schema/media/use-bknd-media.ts @@ -0,0 +1,33 @@ +import { useBknd } from "ui/client/BkndProvider"; + +export function useBkndMedia() { + const { config, schema, actions: bkndActions } = useBknd(); + + const actions = { + /*roles: { + add: async (name: string, data: any = {}) => { + console.log("add role", name, data); + return await bkndActions.add("auth", `roles.${name}`, data); + }, + patch: async (name: string, data: any) => { + console.log("patch role", name, data); + return await bkndActions.patch("auth", `roles.${name}`, data); + }, + delete: async (name: string) => { + console.log("delete role", name); + if (window.confirm(`Are you sure you want to delete the role "${name}"?`)) { + return await bkndActions.remove("auth", `roles.${name}`); + } + return false; + } + }*/ + }; + const $media = {}; + + return { + $media, + config: config.media, + schema: schema.media, + actions + }; +} diff --git a/app/src/ui/components/form/Formy/BooleanInputMantine.tsx b/app/src/ui/components/form/Formy/BooleanInputMantine.tsx index 3f3c77a..48bd5e5 100644 --- a/app/src/ui/components/form/Formy/BooleanInputMantine.tsx +++ b/app/src/ui/components/form/Formy/BooleanInputMantine.tsx @@ -3,9 +3,10 @@ import { forwardRef, useEffect, useState } from "react"; export const BooleanInputMantine = forwardRef>( (props, ref) => { - const [checked, setChecked] = useState(Boolean(props.value)); + const [checked, setChecked] = useState(Boolean(props.value ?? props.defaultValue)); useEffect(() => { + console.log("value change", props.value); setChecked(Boolean(props.value)); }, [props.value]); diff --git a/app/src/ui/components/form/Formy/components.tsx b/app/src/ui/components/form/Formy/components.tsx index d725238..7bf691f 100644 --- a/app/src/ui/components/form/Formy/components.tsx +++ b/app/src/ui/components/form/Formy/components.tsx @@ -1,25 +1,37 @@ import { getBrowser } from "core/utils"; import type { Field } from "data"; -import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react"; +import { + type ElementType, + forwardRef, + useEffect, + useImperativeHandle, + useRef, + useState +} from "react"; import { TbCalendar, TbChevronDown, TbInfoCircle } from "react-icons/tb"; import { twMerge } from "tailwind-merge"; import { IconButton } from "ui/components/buttons/IconButton"; import { useEvent } from "ui/hooks/use-event"; -export const Group: React.FC & { error?: boolean }> = ({ +export const Group = ({ error, + as, ...props -}) => ( -
& { error?: boolean; as?: E }) => { + const Tag = as || "div"; - error && "text-red-500", - props.className - )} - /> -); + return ( + + ); +}; export const formElementFactory = (element: string, props: any) => { switch (element) { @@ -34,7 +46,21 @@ export const formElementFactory = (element: string, props: any) => { } }; -export const Label: React.FC> = (props) =>
@@ -57,16 +60,3 @@ export function MediaRoot({ children }) { ); } - -// @todo: add infinite load -export function MediaEmpty() { - useBrowserTitle(["Media"]); - - return ( - -
- -
-
- ); -} diff --git a/app/src/ui/routes/media/index.tsx b/app/src/ui/routes/media/index.tsx index 3949258..12259d7 100644 --- a/app/src/ui/routes/media/index.tsx +++ b/app/src/ui/routes/media/index.tsx @@ -1,10 +1,13 @@ import { Route } from "wouter"; -import { MediaEmpty, MediaRoot } from "./_media.root"; +import { MediaRoot } from "./_media.root"; +import { MediaIndex } from "./media.index"; +import { MediaSettings } from "./media.settings"; export default function MediaRoutes() { return ( - + + ); } diff --git a/app/src/ui/routes/media/media.index.tsx b/app/src/ui/routes/media/media.index.tsx new file mode 100644 index 0000000..44ed644 --- /dev/null +++ b/app/src/ui/routes/media/media.index.tsx @@ -0,0 +1,15 @@ +import { Media } from "ui/elements"; +import { useBrowserTitle } from "ui/hooks/use-browser-title"; +import * as AppShell from "ui/layouts/AppShell/AppShell"; + +export function MediaIndex() { + useBrowserTitle(["Media"]); + + return ( + +
+ +
+
+ ); +} diff --git a/app/src/ui/routes/media/media.settings.tsx b/app/src/ui/routes/media/media.settings.tsx new file mode 100644 index 0000000..7b63900 --- /dev/null +++ b/app/src/ui/routes/media/media.settings.tsx @@ -0,0 +1,126 @@ +import { Form, useFormContext } from "json-schema-form-react"; +import { omit } from "lodash-es"; +import { useState } from "react"; +import { useBknd } from "ui/client/BkndProvider"; +import { useBkndMedia } from "ui/client/schema/media/use-bknd-media"; +import { Button } from "ui/components/buttons/Button"; +import { JsonViewer } from "ui/components/code/JsonViewer"; +import { Message } from "ui/components/display/Message"; +import * as Formy from "ui/components/form/Formy"; +import { BooleanInputMantine } from "ui/components/form/Formy/BooleanInputMantine"; +import { JsonSchemaForm } from "ui/components/form/json-schema"; +import { TypeboxValidator } from "ui/components/form/json-schema-form"; +import { AutoForm, Field } from "ui/components/form/json-schema-form/components/Field"; +import { Media } from "ui/elements"; +import { useBrowserTitle } from "ui/hooks/use-browser-title"; +import * as AppShell from "ui/layouts/AppShell/AppShell"; + +const validator = new TypeboxValidator(); + +export function MediaSettings(props) { + useBrowserTitle(["Media", "Settings"]); + + const { hasSecrets } = useBknd({ withSecrets: true }); + if (!hasSecrets) { + return ; + } + + return ; +} + +function MediaSettingsInternal() { + const { config, schema } = useBkndMedia(); + const [data, setData] = useState(config); + //console.log("schema", schema); + + return ( + <> +
+ {({ errors, submitting, dirty }) => ( + <> + + Update + + } + > + Settings + + +
+ +
+ + + +
+
+
+ + +
+ +
+ + )} +
+ + ); +} + +function Adapters() { + const { config, schema } = useBkndMedia(); + const ctx = useFormContext(); + const current = config.adapter; + const schemas = schema.properties.adapter.anyOf; + const types = schemas.map((s) => s.properties.type.const) as string[]; + const currentType = current?.type ?? (types[0] as string); + const [selected, setSelected] = useState(currentType); + const $schema = schemas.find((s) => s.properties.type.const === selected); + console.log("$schema", $schema); + + function onChangeSelect(e) { + setSelected(e.target.value); + + // wait quickly for the form to update before triggering a change + setTimeout(() => { + ctx.setValue("adapter.type", e.target.value); + }, 10); + } + + return ( +
+ + {types.map((type) => ( + + ))} + +
current: {selected}
+
options: {schemas.map((s) => s.title).join(", ")}
+
+ ); +} + +const Overlay = ({ visible = false }) => + visible && ( +
+ ); diff --git a/app/src/ui/routes/test/index.tsx b/app/src/ui/routes/test/index.tsx index da6c0cd..9f1fd76 100644 --- a/app/src/ui/routes/test/index.tsx +++ b/app/src/ui/routes/test/index.tsx @@ -1,5 +1,6 @@ import AppShellAccordionsTest from "ui/routes/test/tests/appshell-accordions-test"; import JsonSchemaFormReactTest from "ui/routes/test/tests/json-schema-form-react-test"; +import JsonSchemaForm2 from "ui/routes/test/tests/json-schema-form2"; import SwaggerTest from "ui/routes/test/tests/swagger-test"; import SWRAndAPI from "ui/routes/test/tests/swr-and-api"; import SwrAndDataApi from "ui/routes/test/tests/swr-and-data-api"; @@ -15,6 +16,7 @@ import DropdownTest from "./tests/dropdown-test"; import DropzoneElementTest from "./tests/dropzone-element-test"; import EntityFieldsForm from "./tests/entity-fields-form"; import FlowsTest from "./tests/flows-test"; +import JsonSchemaForm3 from "./tests/json-schema-form3"; import JsonFormTest from "./tests/jsonform-test"; import { LiquidJsTest } from "./tests/liquid-js-test"; import MantineTest from "./tests/mantine-test"; @@ -45,7 +47,9 @@ const tests = { SWRAndAPI, SwrAndDataApi, DropzoneElementTest, - JsonSchemaFormReactTest + JsonSchemaFormReactTest, + JsonSchemaForm2, + JsonSchemaForm3 } as const; export default function TestRoutes() { diff --git a/app/src/ui/routes/test/tests/json-schema-form2.tsx b/app/src/ui/routes/test/tests/json-schema-form2.tsx new file mode 100644 index 0000000..c137091 --- /dev/null +++ b/app/src/ui/routes/test/tests/json-schema-form2.tsx @@ -0,0 +1,287 @@ +import { Popover } from "@mantine/core"; +import { IconBug } from "@tabler/icons-react"; +import { autoFormatString } from "core/utils"; +import type { JSONSchema } from "json-schema-to-ts"; +import { type ChangeEvent, type ComponentPropsWithoutRef, useState } from "react"; +import { IconButton } from "ui/components/buttons/IconButton"; +import { JsonViewer } from "ui/components/code/JsonViewer"; +import * as Formy from "ui/components/form/Formy"; +import { ErrorMessage } from "ui/components/form/Formy"; +import { + Form, + useFieldContext, + useFormContext, + usePrefixContext +} from "ui/components/form/json-schema-form2/Form"; +import { isType } from "ui/components/form/json-schema-form2/utils"; + +const schema = { + type: "object", + properties: { + name: { type: "string", maxLength: 2 }, + description: { type: "string", maxLength: 2 }, + age: { type: "number", description: "Age of you" }, + deep: { + type: "object", + properties: { + nested: { type: "string", maxLength: 2 } + } + } + } + //required: ["description"] +} as const satisfies JSONSchema; + +const simpleSchema = { + type: "object", + properties: { + tags: { + type: "array", + items: { + type: "string" + } + } + } +} as const satisfies JSONSchema; + +export default function JsonSchemaForm2() { + return ( +
+

Form

+ + {/*
+ + + + + +
+ +
+ + +
*/} + + {/*
+ + */} + {/*
+ + */} + +
+ + + + {/*
+ + */} +
+ ); +} + +const Field = ({ + name = "", + schema: _schema +}: { name?: string; schema?: Exclude }) => { + const { value, errors, pointer, required, ...ctx } = useFieldContext(name); + const schema = _schema ?? ctx.schema; + if (!schema) return `"${name}" (${pointer}) has no schema`; + + if (isType(schema.type, ["object", "array"])) { + return null; + } + + const label = schema.title ?? name; //autoFormatString(name.split("/").pop()); + + return ( + 0}> + + {label} {required ? "*" : ""} + +
+
+ +
+ + + + + + + + +
+ {schema.description && {schema.description}} + {errors.length > 0 && ( + {errors.map((e) => e.message).join(", ")} + )} +
+ ); +}; + +const FieldComponent = ({ + schema, + ...props +}: { schema: JSONSchema } & ComponentPropsWithoutRef<"input">) => { + if (!schema || typeof schema === "boolean") return null; + + const common = {}; + + if (schema.enum) { + if (!Array.isArray(schema.enum)) return null; + + return ; + } + + if (isType(schema.type, ["number", "integer"])) { + return ; + } + + return ; +}; + +const ObjectField = ({ path = "" }: { path?: string }) => { + const { schema } = usePrefixContext(path); + if (!schema) return null; + const properties = schema.properties ?? {}; + const label = schema.title ?? path; + console.log("object", { path, schema, properties }); + + return ( +
+ Object: {label} + {Object.keys(properties).map((prop) => { + const schema = properties[prop]; + const pointer = `${path}/${prop}`; + + console.log("--", prop, pointer, schema); + if (schema.anyOf || schema.oneOf) { + return ; + } + + if (isType(schema.type, "object")) { + console.log("object", { prop, pointer, schema }); + return ; + } + + if (isType(schema.type, "array")) { + return ; + } + + return ; + })} +
+ ); +}; + +const AnyOfField = ({ path = "" }: { path?: string }) => { + const [selected, setSelected] = useState(null); + const { schema, select } = usePrefixContext(path); + if (!schema) return null; + const schemas = schema.anyOf ?? schema.oneOf ?? []; + const options = schemas.map((s, i) => ({ + value: i, + label: s.title ?? `Option ${i + 1}` + })); + const selectSchema = { + enum: options + }; + + function handleSelect(e: ChangeEvent) { + const i = e.target.value ? Number(e.target.value) : null; + setSelected(i); + select(path, i !== null ? i : undefined); + } + console.log("options", options, schemas, selected !== null && schemas[selected]); + + return ( + <> +
+ anyOf: {path} ({selected}) +
+ + + {selected !== null && ( + + )} + + ); +}; + +const ArrayField = ({ path = "" }: { path?: string }) => { + return "array: " + path; +}; + +const AutoForm = ({ prefix = "" }: { prefix?: string }) => { + const { schema } = usePrefixContext(prefix); + if (!schema) return null; + + if (isType(schema.type, "object")) { + return ; + } + + if (isType(schema.type, "array")) { + return ; + } + + return ; +}; diff --git a/app/src/ui/routes/test/tests/json-schema-form3.tsx b/app/src/ui/routes/test/tests/json-schema-form3.tsx new file mode 100644 index 0000000..cb5e2f9 --- /dev/null +++ b/app/src/ui/routes/test/tests/json-schema-form3.tsx @@ -0,0 +1,328 @@ +import { useBknd } from "ui/client/bknd"; +import { Button } from "ui/components/buttons/Button"; +import { AnyOf, useAnyOfContext } from "ui/components/form/json-schema-form3/AnyOfField"; +import { Field } from "ui/components/form/json-schema-form3/Field"; +import { Form, FormContextOverride } from "ui/components/form/json-schema-form3/Form"; +import { ObjectField } from "ui/components/form/json-schema-form3/ObjectField"; +import { removeKeyRecursively } from "ui/components/form/json-schema-form3/utils"; +import { Scrollable } from "ui/layouts/AppShell/AppShell"; + +const mediaSchema = { + additionalProperties: false, + type: "object", + properties: { + enabled: { + default: false, + type: "boolean" + }, + basepath: { + default: "/api/media", + type: "string" + }, + entity_name: { + default: "media", + type: "string" + }, + storage: { + default: {}, + type: "object", + properties: { + body_max_size: { + description: "Max size of the body in bytes. Leave blank for unlimited.", + type: "number" + } + } + }, + adapter: { + anyOf: [ + { + title: "s3", + additionalProperties: false, + type: "object", + properties: { + type: { + default: "s3", + const: "s3", + readOnly: true, + type: "string" + }, + config: { + title: "S3", + type: "object", + properties: { + access_key: { + type: "string" + }, + secret_access_key: { + type: "string" + }, + url: { + pattern: "^https?://[^/]+", + description: "URL to S3 compatible endpoint without trailing slash", + examples: [ + "https://{account_id}.r2.cloudflarestorage.com/{bucket}", + "https://{bucket}.s3.{region}.amazonaws.com" + ], + type: "string" + } + }, + required: ["access_key", "secret_access_key", "url"] + } + }, + required: ["type", "config"] + }, + { + title: "cloudinary", + additionalProperties: false, + type: "object", + properties: { + type: { + default: "cloudinary", + const: "cloudinary", + readOnly: true, + type: "string" + }, + config: { + title: "Cloudinary", + type: "object", + properties: { + cloud_name: { + type: "string" + }, + api_key: { + type: "string" + }, + api_secret: { + type: "string" + }, + upload_preset: { + type: "string" + } + }, + required: ["cloud_name", "api_key", "api_secret"] + } + }, + required: ["type", "config"] + }, + { + title: "local", + additionalProperties: false, + type: "object", + properties: { + type: { + default: "local", + const: "local", + readOnly: true, + type: "string" + }, + config: { + title: "Local", + type: "object", + properties: { + path: { + default: "./", + type: "string" + } + }, + required: ["path"] + } + }, + required: ["type", "config"] + } + ] + } + }, + required: ["enabled", "basepath", "entity_name", "storage"] +}; + +export default function JsonSchemaForm3() { + const { schema, config } = useBknd(); + + return ( + +
+ {/*
+ + + + + */} + + {/*
+ + */} + + {/*
+ + */} + {/*
+ + */} + + {/*
*/} + + + + + {/* + + */} + + {/*
+ + */} +
+
+ ); +} + +function CustomMediaForm() { + const { schema, config } = useBknd(); + return ( +
+ + + + + + + + + ); +} + +function CustomMediaFormAdapter() { + const ctx = useAnyOfContext(); + + return ( + <> +
+ {ctx.schemas?.map((schema: any, i) => ( + + ))} +
+ + {ctx.selected !== null && ( + + + )} + + ); +} diff --git a/bun.lockb b/bun.lockb index 1b049f9ee0e966f175a07d48305d9c1f53aab433..4d841b488bbb2824a016bd6a42c5f44b9c030336 100755 GIT binary patch delta 186103 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%0AfFJn0gxyKgpln3`;CCj61ov!n*t~!B#B)j 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�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 GQP+P$?DYQt From 4b3493a6f52bc2bfc20a2df5a4cbd2df68bbaace Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 5 Feb 2025 11:04:37 +0100 Subject: [PATCH 18/32] changed media settings to new form --- .../AnyOfField.tsx | 18 +- .../ArrayField.tsx | 0 .../Field.tsx | 0 .../FieldWrapper.tsx | 0 .../Form.tsx | 23 +- .../ObjectField.tsx | 4 +- .../json-schema-form/components/Field.tsx | 98 ------ .../components/form/json-schema-form/index.ts | 8 +- .../utils.ts | 2 +- .../validators/cf-validator.ts | 11 - .../validators/tb-validator.ts | 11 - .../form/json-schema-form2/Form.tsx | 192 ------------ .../form/json-schema-form2/utils.ts | 198 ------------ app/src/ui/elements/auth/AuthForm.tsx | 13 +- app/src/ui/routes/media/media.settings.tsx | 130 ++++---- app/src/ui/routes/test/index.tsx | 3 +- .../routes/test/tests/json-schema-form2.tsx | 287 ------------------ .../routes/test/tests/json-schema-form3.tsx | 143 +-------- 18 files changed, 110 insertions(+), 1031 deletions(-) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/AnyOfField.tsx (87%) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/ArrayField.tsx (100%) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/Field.tsx (100%) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/FieldWrapper.tsx (100%) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/Form.tsx (89%) rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/ObjectField.tsx (88%) delete mode 100644 app/src/ui/components/form/json-schema-form/components/Field.tsx rename app/src/ui/components/form/{json-schema-form3 => json-schema-form}/utils.ts (98%) delete mode 100644 app/src/ui/components/form/json-schema-form/validators/cf-validator.ts delete mode 100644 app/src/ui/components/form/json-schema-form/validators/tb-validator.ts delete mode 100644 app/src/ui/components/form/json-schema-form2/Form.tsx delete mode 100644 app/src/ui/components/form/json-schema-form2/utils.ts delete mode 100644 app/src/ui/routes/test/tests/json-schema-form2.tsx diff --git a/app/src/ui/components/form/json-schema-form3/AnyOfField.tsx b/app/src/ui/components/form/json-schema-form/AnyOfField.tsx similarity index 87% rename from app/src/ui/components/form/json-schema-form3/AnyOfField.tsx rename to app/src/ui/components/form/json-schema-form/AnyOfField.tsx index 4844c46..87670cf 100644 --- a/app/src/ui/components/form/json-schema-form3/AnyOfField.tsx +++ b/app/src/ui/components/form/json-schema-form/AnyOfField.tsx @@ -2,7 +2,7 @@ import type { JSONSchema } from "json-schema-to-ts"; import { type ChangeEvent, type ReactNode, createContext, useContext, useState } from "react"; import * as Formy from "ui/components/form/Formy"; import { FieldComponent, Field as FormField, type FieldProps as FormFieldProps } from "./Field"; -import { useFieldContext } from "./Form"; +import { FormContextOverride, useFieldContext } from "./Form"; import { getLabel, getMultiSchemaMatched } from "./utils"; export type AnyOfFieldRootProps = { @@ -30,7 +30,7 @@ export const useAnyOfContext = () => { return ctx; }; -export const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) => { +const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) => { const { setValue, pointer, lib, value, ...ctx } = useFieldContext(path); const schema = _schema ?? ctx.schema; if (!schema) return `AnyOfField(${path}): no schema ${pointer}`; @@ -58,7 +58,7 @@ export const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootPro ); }; -export const Select = () => { +const Select = () => { const { selected, select, path, schema, selectSchema } = useAnyOfContext(); function handleSelect(e: ChangeEvent) { @@ -80,17 +80,13 @@ export const Select = () => { ); }; -export const Field = ({ name, label, ...props }: Partial) => { +const Field = ({ name, label, ...props }: Partial) => { const { selected, selectedSchema, path } = useAnyOfContext(); if (selected === null) return null; return ( - + + + ); }; diff --git a/app/src/ui/components/form/json-schema-form3/ArrayField.tsx b/app/src/ui/components/form/json-schema-form/ArrayField.tsx similarity index 100% rename from app/src/ui/components/form/json-schema-form3/ArrayField.tsx rename to app/src/ui/components/form/json-schema-form/ArrayField.tsx diff --git a/app/src/ui/components/form/json-schema-form3/Field.tsx b/app/src/ui/components/form/json-schema-form/Field.tsx similarity index 100% rename from app/src/ui/components/form/json-schema-form3/Field.tsx rename to app/src/ui/components/form/json-schema-form/Field.tsx diff --git a/app/src/ui/components/form/json-schema-form3/FieldWrapper.tsx b/app/src/ui/components/form/json-schema-form/FieldWrapper.tsx similarity index 100% rename from app/src/ui/components/form/json-schema-form3/FieldWrapper.tsx rename to app/src/ui/components/form/json-schema-form/FieldWrapper.tsx diff --git a/app/src/ui/components/form/json-schema-form3/Form.tsx b/app/src/ui/components/form/json-schema-form/Form.tsx similarity index 89% rename from app/src/ui/components/form/json-schema-form3/Form.tsx rename to app/src/ui/components/form/json-schema-form/Form.tsx index d7816b2..07b3846 100644 --- a/app/src/ui/components/form/json-schema-form3/Form.tsx +++ b/app/src/ui/components/form/json-schema-form/Form.tsx @@ -2,7 +2,7 @@ import { Draft2019, type JsonError } from "json-schema-library"; import type { TemplateOptions as LibTemplateOptions } from "json-schema-library/dist/lib/getTemplate"; import type { JsonSchema as LibJsonSchema } from "json-schema-library/dist/lib/types"; import type { JSONSchema as $JSONSchema, FromSchema } from "json-schema-to-ts"; -import { get } from "lodash-es"; +import { get, isEqual } from "lodash-es"; import * as immutable from "object-path-immutable"; import { type ComponentPropsWithoutRef, @@ -37,6 +37,7 @@ export type FormContext = { setValue: (pointer: string, value: any) => void; deleteValue: (pointer: string) => void; errors: JsonError[]; + dirty: boolean; schema: JSONSchema; lib: Draft2019; }; @@ -48,7 +49,7 @@ export function Form< Data = Schema extends JSONSchema ? FromSchema : any >({ schema, - initialValues, + initialValues: _initialValues, initialOpts, children, onChange, @@ -57,9 +58,9 @@ export function Form< ...props }: FormProps) { const lib = new Draft2019(schema); - const [data, setData] = useState>( - initialValues ?? lib.getTemplate(undefined, schema, initialOpts) - ); + const initialValues = _initialValues ?? lib.getTemplate(undefined, schema, initialOpts); + const [data, setData] = useState>(initialValues); + const [dirty, setDirty] = useState(false); const formRef = useRef(null); const [errors, setErrors] = useState([]); @@ -72,10 +73,11 @@ export function Form< function setValue(pointer: string, value: any) { const normalized = normalizePath(pointer); - console.log("setValue", { pointer, normalized, value }); + //console.log("setValue", { pointer, normalized, value }); const key = normalized.substring(2).replace(/\//g, "."); setData((prev) => { const changed = immutable.set(prev, key, value); + onChange?.(changed, key, value); //console.log("changed", prev, changed, { key, value }); return changed; }); @@ -86,12 +88,15 @@ export function Form< const key = normalized.substring(2).replace(/\//g, "."); setData((prev) => { const changed = immutable.del(prev, key); + onChange?.(changed, key, undefined); //console.log("changed", prev, changed, { key }); return changed; }); } useEffect(() => { + setDirty(!isEqual(initialValues, data)); + if (validateOn === "change") { validate(); } @@ -107,6 +112,7 @@ export function Form< const context = { data: data ?? {}, + dirty, setData, setValue, deleteValue, @@ -194,3 +200,8 @@ export function useFieldContext(name: string) { required }; } + +export function Subscribe({ children }: { children: (ctx: FormContext) => ReactNode }) { + const ctx = useFormContext(); + return children(ctx); +} diff --git a/app/src/ui/components/form/json-schema-form3/ObjectField.tsx b/app/src/ui/components/form/json-schema-form/ObjectField.tsx similarity index 88% rename from app/src/ui/components/form/json-schema-form3/ObjectField.tsx rename to app/src/ui/components/form/json-schema-form/ObjectField.tsx index f363ff6..0113789 100644 --- a/app/src/ui/components/form/json-schema-form3/ObjectField.tsx +++ b/app/src/ui/components/form/json-schema-form/ObjectField.tsx @@ -36,10 +36,10 @@ export const ObjectField = ({ if (!schema) return; if (schema.anyOf || schema.oneOf) { - return ; + return ; } - return ; + return ; })} ); diff --git a/app/src/ui/components/form/json-schema-form/components/Field.tsx b/app/src/ui/components/form/json-schema-form/components/Field.tsx deleted file mode 100644 index 2e70f44..0000000 --- a/app/src/ui/components/form/json-schema-form/components/Field.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Switch } from "@mantine/core"; -import { autoFormatString } from "core/utils"; -import { type JSONSchema, useFieldContext, useFormContext } from "json-schema-form-react"; -import type { ComponentPropsWithoutRef } from "react"; -import * as Formy from "ui/components/form/Formy"; - -// make a local version of JSONSchema that is always an object -export type FieldProps = JSONSchema & { - name: string; - defaultValue?: any; - hidden?: boolean; - overrides?: ComponentPropsWithoutRef<"input">; -}; - -export function Field(p: FieldProps) { - const { schema, defaultValue, required } = useFieldContext(p.name); - const props = { - ...(typeof schema === "object" ? schema : {}), - defaultValue, - required, - ...p - } as FieldProps; - console.log("schema", p.name, schema, defaultValue); - - const field = renderField(props); - const label = props.title - ? props.title - : autoFormatString( - props.name?.includes(".") ? (props.name.split(".").pop() as string) : props.name - ); - - return p.hidden ? ( - field - ) : ( - - - {label} - {props.required ? " *" : ""} - - {field} - {props.description ? {props.description} : null} - - ); -} - -function isType(_type: JSONSchema["type"], _compare: JSONSchema["type"]) { - if (!_type || !_compare) return false; - const type = Array.isArray(_type) ? _type : [_type]; - const compare = Array.isArray(_compare) ? _compare : [_compare]; - return compare.some((t) => type.includes(t)); -} - -function renderField(props: FieldProps) { - //console.log("renderField", props.name, props); - const common = { - name: props.name, - defaultValue: typeof props.defaultValue !== "undefined" ? props.defaultValue : props.default - } as any; - - if (props.hidden) { - common.type = "hidden"; - } - - if (isType(props.type, "boolean")) { - return ( -

- -
- ); - } else if (isType(props.type, ["number", "integer"])) { - return ; - } - - return ; -} - -export function AutoForm({ schema, prefix = "" }: { schema: JSONSchema; prefix?: string }) { - const required = schema.required ?? []; - const properties = schema.properties ?? {}; - - return ( - <> - {/*
{JSON.stringify(schema, null, 2)}
;*/} -
- {Object.keys(properties).map((name) => { - const field = properties[name]; - const _name = `${prefix ? prefix + "." : ""}${name}`; - return ; - })} -
- - ); -} diff --git a/app/src/ui/components/form/json-schema-form/index.ts b/app/src/ui/components/form/json-schema-form/index.ts index 0a7fb1a..60907f6 100644 --- a/app/src/ui/components/form/json-schema-form/index.ts +++ b/app/src/ui/components/form/json-schema-form/index.ts @@ -1,2 +1,6 @@ -export { TypeboxValidator, type ValueError } from "./validators/tb-validator"; -export { CfValidator, type OutputUnit } from "./validators/cf-validator"; +export * from "./Field"; +export * from "./Form"; +export * from "./ObjectField"; +export * from "./ArrayField"; +export * from "./AnyOfField"; +export * from "./FieldWrapper"; diff --git a/app/src/ui/components/form/json-schema-form3/utils.ts b/app/src/ui/components/form/json-schema-form/utils.ts similarity index 98% rename from app/src/ui/components/form/json-schema-form3/utils.ts rename to app/src/ui/components/form/json-schema-form/utils.ts index 45c1563..532684b 100644 --- a/app/src/ui/components/form/json-schema-form3/utils.ts +++ b/app/src/ui/components/form/json-schema-form/utils.ts @@ -122,7 +122,7 @@ export function normalizePath(path: string) { } export function prefixPointer(pointer: string, prefix: string) { - return pointer.replace("#/", `#/${prefix}/`); + return pointer.replace("#/", `#/${prefix}/`).replace(/\/\//g, "/"); } export function getParentPointer(pointer: string) { diff --git a/app/src/ui/components/form/json-schema-form/validators/cf-validator.ts b/app/src/ui/components/form/json-schema-form/validators/cf-validator.ts deleted file mode 100644 index a25889e..0000000 --- a/app/src/ui/components/form/json-schema-form/validators/cf-validator.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type Schema as JsonSchema, type OutputUnit, Validator } from "@cfworker/json-schema"; -import type { Validator as TValidator } from "json-schema-form-react"; - -export class CfValidator implements TValidator { - async validate(schema: JsonSchema, data: any) { - const result = new Validator(schema).validate(data); - return result.errors; - } -} - -export type { OutputUnit }; diff --git a/app/src/ui/components/form/json-schema-form/validators/tb-validator.ts b/app/src/ui/components/form/json-schema-form/validators/tb-validator.ts deleted file mode 100644 index 2ddef5b..0000000 --- a/app/src/ui/components/form/json-schema-form/validators/tb-validator.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ValueError } from "@sinclair/typebox/value"; -import { type TSchema, Value } from "core/utils"; -import type { Validator } from "json-schema-form-react"; - -export class TypeboxValidator implements Validator { - async validate(schema: TSchema, data: any) { - return Value.Check(schema, data) ? [] : [...Value.Errors(schema, data)]; - } -} - -export type { ValueError }; diff --git a/app/src/ui/components/form/json-schema-form2/Form.tsx b/app/src/ui/components/form/json-schema-form2/Form.tsx deleted file mode 100644 index bf0bf08..0000000 --- a/app/src/ui/components/form/json-schema-form2/Form.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { Draft2019, type JsonError, type JsonSchema as LibJsonSchema } from "json-schema-library"; -import type { JSONSchema as $JSONSchema, FromSchema } from "json-schema-to-ts"; -import { - type ComponentPropsWithoutRef, - type FormEvent, - createContext, - startTransition, - useContext, - useEffect, - useMemo, - useRef, - useState -} from "react"; -import { flatten, getFormTarget, isRequired, normalizePath, unflatten } from "./utils"; - -type JSONSchema = Exclude<$JSONSchema, boolean>; -type TFormData = Record; - -export type FormProps< - Schema extends JSONSchema = JSONSchema, - Data = Schema extends JSONSchema ? FromSchema : any -> = Omit, "onChange"> & { - schema: Schema; - validateOn?: "change" | "submit"; - initialValues?: Partial; - onChange?: (data: Partial, name: string, value: any) => void; - hiddenSubmit?: boolean; -}; - -export type FormContext = { - data: TFormData; - setData: (data: TFormData) => void; - errors: JsonError[]; - schema: JSONSchema; - lib: Draft2019; - select: (pointer: string, choice: number | undefined) => void; - selections: Record; -}; - -const FormContext = createContext(undefined!); - -export function Form< - Schema extends JSONSchema = JSONSchema, - Data = Schema extends JSONSchema ? FromSchema : any ->({ - schema: _schema, - initialValues: _initialValues, - children, - onChange, - validateOn = "submit", - hiddenSubmit = true, - ...props -}: FormProps) { - const schema = useMemo(() => _schema, [JSON.stringify(_schema)]); - const initialValues = useMemo( - () => (_initialValues ? flatten(_initialValues) : {}), - [JSON.stringify(_initialValues)] - ); - - const [data, setData] = useState(initialValues); - const [errors, setErrors] = useState([]); - const [selections, setSelections] = useState>({}); - const lib = new Draft2019(schema); - const formRef = useRef(null); - - useEffect(() => { - console.log("setting", initialValues); - if (formRef.current) { - Object.entries(initialValues).forEach(([name, value]) => { - const pointer = normalizePath(name); - const input = formRef.current?.elements.namedItem(pointer); - if (input && "value" in input) { - input.value = value as any; - } - }); - } - }, [initialValues]); - - async function handleChange(e: FormEvent) { - const target = getFormTarget(e); - if (!target) return; - const name = normalizePath(target.name); - - startTransition(() => { - const newData = { ...data, [name]: target.value }; - setData(newData); - - const actual = unflatten(newData, schema, selections); - if (validateOn === "change") { - validate(actual); - } - - onChange?.(actual, name, target.value); - }); - } - - async function handleSubmit(e: FormEvent) { - e.preventDefault(); - const actual = unflatten(data, schema, selections); - const { data: newData, errors } = validate(actual); - setData(newData); - console.log("submit", newData, errors); - return false; - } - - function validate(_data?: object) { - const actual = _data ?? unflatten(data, schema, selections); - const errors = lib.validate(actual); - console.log("validate", actual, errors); - setErrors(errors); - return { - data: actual, - errors - }; - } - - function select(pathOrPointer: string, choice: number | undefined) { - setSelections((prev) => ({ ...prev, [normalizePath(pathOrPointer)]: choice })); - } - - const context = { - data, - setData, - select, - selections, - errors, - schema, - lib - }; - - return ( - <> -
- {children} - {hiddenSubmit && ( - - )} -
-
{JSON.stringify(data, null, 2)}
-
{JSON.stringify(unflatten(data, schema, selections), null, 2)}
-
{JSON.stringify(errors, null, 2)}
-
{JSON.stringify(selections, null, 2)}
- - ); -} - -export function useFormContext() { - return useContext(FormContext); -} - -export function useFieldContext(name: string) { - const { data, setData, lib, schema, errors: formErrors, select, selections } = useFormContext(); - const pointer = normalizePath(name); - //console.log("pointer", pointer); - const value = data[pointer]; - const errors = formErrors.filter((error) => error.data.pointer === pointer); - const fieldSchema = pointer === "#/" ? (schema as LibJsonSchema) : lib.getSchema({ pointer }); - const required = isRequired(pointer, schema); - - return { - value, - setValue: (value: any) => setData({ ...data, [name]: value }), - errors, - schema: fieldSchema, - pointer, - required, - select, - selections - }; -} - -export function usePrefixContext(prefix: string) { - const { data, setData, lib, schema, errors: formErrors, select, selections } = useFormContext(); - const pointer = normalizePath(prefix); - const value = Object.fromEntries(Object.entries(data).filter(([key]) => key.startsWith(prefix))); - const errors = formErrors.filter((error) => error.data.pointer.startsWith(pointer)); - const fieldSchema = pointer === "#/" ? (schema as LibJsonSchema) : lib.getSchema({ pointer }); - const required = isRequired(pointer, schema); - - return { - value, - //setValue: (value: any) => setData({ ...data, [name]: value }), - errors, - schema: fieldSchema, - pointer, - required, - select, - selections - }; -} diff --git a/app/src/ui/components/form/json-schema-form2/utils.ts b/app/src/ui/components/form/json-schema-form2/utils.ts deleted file mode 100644 index 90bc89d..0000000 --- a/app/src/ui/components/form/json-schema-form2/utils.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { autoFormatString } from "core/utils"; -import { Draft2019, type JsonSchema } from "json-schema-library"; -import type { JSONSchema } from "json-schema-to-ts"; -import type { JSONSchemaType } from "json-schema-to-ts/lib/types/definitions/jsonSchema"; -import { set } from "lodash-es"; -import type { FormEvent } from "react"; - -export function getFormTarget(e: FormEvent) { - const form = e.currentTarget; - const target = e.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null; - - // check if target has attribute "data-ignore" set - // also check if target is within a "data-ignore" element - - if ( - !target || - !form.contains(target) || - !target.name || - target.hasAttribute("data-ignore") || - target.closest("[data-ignore]") - ) { - return; // Ignore events from outside the form - } - return target; -} - -export function flatten(obj: any, parentKey = "", result: any = {}): any { - for (const key in obj) { - if (key in obj) { - const newKey = parentKey ? `${parentKey}/${key}` : "#/" + key; - if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) { - flatten(obj[key], newKey, result); - } else if (Array.isArray(obj[key])) { - obj[key].forEach((item, index) => { - const arrayKey = `${newKey}.${index}`; - if (typeof item === "object" && item !== null) { - flatten(item, arrayKey, result); - } else { - result[arrayKey] = item; - } - }); - } else { - result[newKey] = obj[key]; - } - } - } - return result; -} - -// @todo: make sure it's in the right order -export function unflatten( - obj: Record, - schema: JSONSchema, - selections?: Record -) { - const result = {}; - const lib = new Draft2019(schema as any); - for (const pointer in obj) { - const required = isRequired(pointer, schema); - let subschema = lib.getSchema({ pointer }); - console.log("subschema", pointer, subschema, selections); - if (!subschema) { - throw new Error(`"${pointer}" not found in schema`); - } - - // if subschema starts with "anyOf" or "oneOf" - if (subschema.anyOf || subschema.oneOf) { - const selected = selections?.[pointer]; - if (selected !== undefined) { - subschema = subschema.anyOf ? subschema.anyOf[selected] : subschema.oneOf![selected]; - } - } - - const value = coerce(obj[pointer], subschema as any, { required }); - - set(result, pointer.substring(2).replace(/\//g, "."), value); - } - return result; -} - -export function coerce( - value: any, - schema: Exclude, - opts?: { required?: boolean } -) { - if (!value && typeof opts?.required === "boolean" && !opts.required) { - return undefined; - } - - switch (schema.type) { - case "string": - return String(value); - case "integer": - case "number": - return Number(value); - case "boolean": - return ["true", "1", 1, "on"].includes(value); - case "null": - return null; - } - - return value; -} - -/** - * normalizes any path to a full json pointer - * - * examples: in -> out - * description -> #/description - * #/description -> #/description - * /description -> #/description - * nested/property -> #/nested/property - * nested.property -> #/nested/property - * nested.property[0] -> #/nested/property/0 - * nested.property[0].name -> #/nested/property/0/name - * @param path - */ -export function normalizePath(path: string) { - return path.startsWith("#/") - ? path - : `#/${path.replace(/#?\/?/, "").replace(/\./g, "/").replace(/\[/g, "/").replace(/\]/g, "")}`; -} - -export function getParentPointer(pointer: string) { - return pointer.substring(0, pointer.lastIndexOf("/")); -} - -export function isRequired(pointer: string, schema: JSONSchema, data?: any) { - if (pointer === "#/") { - return false; - } - const lib = new Draft2019(schema as any); - - const childSchema = lib.getSchema({ pointer, data }); - if (typeof childSchema === "object" && ("const" in childSchema || "enum" in childSchema)) { - return true; - } - - const parentPointer = getParentPointer(pointer); - const parentSchema = lib.getSchema({ pointer: parentPointer, data }); - const required = parentSchema?.required?.includes(pointer.split("/").pop()!); - - console.log("isRequired", { - pointer, - parentPointer, - parent: parentSchema ? JSON.parse(JSON.stringify(parentSchema)) : null, - required - }); - - return !!required; -} - -type TType = JSONSchemaType | JSONSchemaType[] | readonly JSONSchemaType[] | undefined; -export function isType(_type: TType, _compare: TType) { - if (!_type || !_compare) return false; - const type = Array.isArray(_type) ? _type : [_type]; - const compare = Array.isArray(_compare) ? _compare : [_compare]; - return compare.some((t) => type.includes(t)); -} - -export function getLabel(name: string, schema: JSONSchema) { - if (typeof schema === "object" && "title" in schema) return schema.title; - const label = name.includes("/") ? (name.split("/").pop() ?? "") : name; - return autoFormatString(label); -} - -export function getMultiSchema(schema: JSONSchema): Exclude[] | undefined { - if (!schema || typeof schema !== "object") return; - return (schema.anyOf ?? schema.oneOf) as any; -} - -export function getMultiSchemaMatched( - schema: JsonSchema, - data: any -): [number, Exclude[], Exclude | undefined] { - const multiSchema = getMultiSchema(schema); - if (!multiSchema) return [-1, [], undefined]; - const index = multiSchema.findIndex((subschema) => { - const lib = new Draft2019(subschema as any); - return lib.validate(data, subschema).length === 0; - }); - if (index === -1) return [-1, multiSchema, undefined]; - - return [index, multiSchema, multiSchema[index]]; -} - -export function removeKeyRecursively(obj: Given, keyToRemove: string): Given { - if (Array.isArray(obj)) { - return obj.map((item) => removeKeyRecursively(item, keyToRemove)) as any; - } else if (typeof obj === "object" && obj !== null) { - return Object.fromEntries( - Object.entries(obj) - .filter(([key]) => key !== keyToRemove) - .map(([key, value]) => [key, removeKeyRecursively(value, keyToRemove)]) - ) as any; - } - return obj; -} diff --git a/app/src/ui/elements/auth/AuthForm.tsx b/app/src/ui/elements/auth/AuthForm.tsx index 1142188..fb5e806 100644 --- a/app/src/ui/elements/auth/AuthForm.tsx +++ b/app/src/ui/elements/auth/AuthForm.tsx @@ -6,9 +6,18 @@ import { transform } from "lodash-es"; import type { ComponentPropsWithoutRef } from "react"; import { Button } from "ui/components/buttons/Button"; import { Group, Input, Label } from "ui/components/form/Formy/components"; -import { TypeboxValidator } from "ui/components/form/json-schema-form"; import { SocialLink } from "./SocialLink"; +import type { ValueError } from "@sinclair/typebox/value"; +import { type TSchema, Value } from "core/utils"; +import type { Validator } from "json-schema-form-react"; + +class TypeboxValidator implements Validator { + async validate(schema: TSchema, data: any) { + return Value.Check(schema, data) ? [] : [...Value.Errors(schema, data)]; + } +} + export type LoginFormProps = Omit, "onSubmit" | "action"> & { className?: string; formData?: any; @@ -75,7 +84,7 @@ export function AuthForm({
(config); - //console.log("schema", schema); + console.log("data", data); return ( <> - - {({ errors, submitting, dirty }) => ( - <> + + + {({ dirty }) => ( + } > Settings - -
- -
- - - -
-
-
- - -
- -
- - )} + )} +
+ +
+ +
+ + + +
+
+
+ + + + +
+ +
); } function Adapters() { - const { config, schema } = useBkndMedia(); - const ctx = useFormContext(); - const current = config.adapter; - const schemas = schema.properties.adapter.anyOf; - const types = schemas.map((s) => s.properties.type.const) as string[]; - const currentType = current?.type ?? (types[0] as string); - const [selected, setSelected] = useState(currentType); - const $schema = schemas.find((s) => s.properties.type.const === selected); - console.log("$schema", $schema); - - function onChangeSelect(e) { - setSelected(e.target.value); - - // wait quickly for the form to update before triggering a change - setTimeout(() => { - ctx.setValue("adapter.type", e.target.value); - }, 10); - } + const ctx = AnyOf.useContext(); return ( -
- - {types.map((type) => ( - + <> +
+ {ctx.schemas?.map((schema: any, i) => ( + ))} - -
current: {selected}
-
options: {schemas.map((s) => s.title).join(", ")}
-
+
+ + {ctx.selected !== null && ( + + + )} + ); } diff --git a/app/src/ui/routes/test/index.tsx b/app/src/ui/routes/test/index.tsx index 9f1fd76..adaf354 100644 --- a/app/src/ui/routes/test/index.tsx +++ b/app/src/ui/routes/test/index.tsx @@ -1,6 +1,6 @@ import AppShellAccordionsTest from "ui/routes/test/tests/appshell-accordions-test"; import JsonSchemaFormReactTest from "ui/routes/test/tests/json-schema-form-react-test"; -import JsonSchemaForm2 from "ui/routes/test/tests/json-schema-form2"; + import SwaggerTest from "ui/routes/test/tests/swagger-test"; import SWRAndAPI from "ui/routes/test/tests/swr-and-api"; import SwrAndDataApi from "ui/routes/test/tests/swr-and-data-api"; @@ -48,7 +48,6 @@ const tests = { SwrAndDataApi, DropzoneElementTest, JsonSchemaFormReactTest, - JsonSchemaForm2, JsonSchemaForm3 } as const; diff --git a/app/src/ui/routes/test/tests/json-schema-form2.tsx b/app/src/ui/routes/test/tests/json-schema-form2.tsx deleted file mode 100644 index c137091..0000000 --- a/app/src/ui/routes/test/tests/json-schema-form2.tsx +++ /dev/null @@ -1,287 +0,0 @@ -import { Popover } from "@mantine/core"; -import { IconBug } from "@tabler/icons-react"; -import { autoFormatString } from "core/utils"; -import type { JSONSchema } from "json-schema-to-ts"; -import { type ChangeEvent, type ComponentPropsWithoutRef, useState } from "react"; -import { IconButton } from "ui/components/buttons/IconButton"; -import { JsonViewer } from "ui/components/code/JsonViewer"; -import * as Formy from "ui/components/form/Formy"; -import { ErrorMessage } from "ui/components/form/Formy"; -import { - Form, - useFieldContext, - useFormContext, - usePrefixContext -} from "ui/components/form/json-schema-form2/Form"; -import { isType } from "ui/components/form/json-schema-form2/utils"; - -const schema = { - type: "object", - properties: { - name: { type: "string", maxLength: 2 }, - description: { type: "string", maxLength: 2 }, - age: { type: "number", description: "Age of you" }, - deep: { - type: "object", - properties: { - nested: { type: "string", maxLength: 2 } - } - } - } - //required: ["description"] -} as const satisfies JSONSchema; - -const simpleSchema = { - type: "object", - properties: { - tags: { - type: "array", - items: { - type: "string" - } - } - } -} as const satisfies JSONSchema; - -export default function JsonSchemaForm2() { - return ( -
-

Form

- - {/*
- - - - - -
- -
- - -
*/} - - {/*
- - */} - {/*
- - */} - -
- - - - {/*
- - */} -
- ); -} - -const Field = ({ - name = "", - schema: _schema -}: { name?: string; schema?: Exclude }) => { - const { value, errors, pointer, required, ...ctx } = useFieldContext(name); - const schema = _schema ?? ctx.schema; - if (!schema) return `"${name}" (${pointer}) has no schema`; - - if (isType(schema.type, ["object", "array"])) { - return null; - } - - const label = schema.title ?? name; //autoFormatString(name.split("/").pop()); - - return ( - 0}> - - {label} {required ? "*" : ""} - -
-
- -
- - - - - - - - -
- {schema.description && {schema.description}} - {errors.length > 0 && ( - {errors.map((e) => e.message).join(", ")} - )} -
- ); -}; - -const FieldComponent = ({ - schema, - ...props -}: { schema: JSONSchema } & ComponentPropsWithoutRef<"input">) => { - if (!schema || typeof schema === "boolean") return null; - - const common = {}; - - if (schema.enum) { - if (!Array.isArray(schema.enum)) return null; - - return ; - } - - if (isType(schema.type, ["number", "integer"])) { - return ; - } - - return ; -}; - -const ObjectField = ({ path = "" }: { path?: string }) => { - const { schema } = usePrefixContext(path); - if (!schema) return null; - const properties = schema.properties ?? {}; - const label = schema.title ?? path; - console.log("object", { path, schema, properties }); - - return ( -
- Object: {label} - {Object.keys(properties).map((prop) => { - const schema = properties[prop]; - const pointer = `${path}/${prop}`; - - console.log("--", prop, pointer, schema); - if (schema.anyOf || schema.oneOf) { - return ; - } - - if (isType(schema.type, "object")) { - console.log("object", { prop, pointer, schema }); - return ; - } - - if (isType(schema.type, "array")) { - return ; - } - - return ; - })} -
- ); -}; - -const AnyOfField = ({ path = "" }: { path?: string }) => { - const [selected, setSelected] = useState(null); - const { schema, select } = usePrefixContext(path); - if (!schema) return null; - const schemas = schema.anyOf ?? schema.oneOf ?? []; - const options = schemas.map((s, i) => ({ - value: i, - label: s.title ?? `Option ${i + 1}` - })); - const selectSchema = { - enum: options - }; - - function handleSelect(e: ChangeEvent) { - const i = e.target.value ? Number(e.target.value) : null; - setSelected(i); - select(path, i !== null ? i : undefined); - } - console.log("options", options, schemas, selected !== null && schemas[selected]); - - return ( - <> -
- anyOf: {path} ({selected}) -
- - - {selected !== null && ( - - )} - - ); -}; - -const ArrayField = ({ path = "" }: { path?: string }) => { - return "array: " + path; -}; - -const AutoForm = ({ prefix = "" }: { prefix?: string }) => { - const { schema } = usePrefixContext(prefix); - if (!schema) return null; - - if (isType(schema.type, "object")) { - return ; - } - - if (isType(schema.type, "array")) { - return ; - } - - return ; -}; diff --git a/app/src/ui/routes/test/tests/json-schema-form3.tsx b/app/src/ui/routes/test/tests/json-schema-form3.tsx index cb5e2f9..9faf8b8 100644 --- a/app/src/ui/routes/test/tests/json-schema-form3.tsx +++ b/app/src/ui/routes/test/tests/json-schema-form3.tsx @@ -1,140 +1,14 @@ import { useBknd } from "ui/client/bknd"; import { Button } from "ui/components/buttons/Button"; -import { AnyOf, useAnyOfContext } from "ui/components/form/json-schema-form3/AnyOfField"; -import { Field } from "ui/components/form/json-schema-form3/Field"; -import { Form, FormContextOverride } from "ui/components/form/json-schema-form3/Form"; -import { ObjectField } from "ui/components/form/json-schema-form3/ObjectField"; -import { removeKeyRecursively } from "ui/components/form/json-schema-form3/utils"; +import { + AnyOf, + Field, + Form, + FormContextOverride, + ObjectField +} from "ui/components/form/json-schema-form"; import { Scrollable } from "ui/layouts/AppShell/AppShell"; -const mediaSchema = { - additionalProperties: false, - type: "object", - properties: { - enabled: { - default: false, - type: "boolean" - }, - basepath: { - default: "/api/media", - type: "string" - }, - entity_name: { - default: "media", - type: "string" - }, - storage: { - default: {}, - type: "object", - properties: { - body_max_size: { - description: "Max size of the body in bytes. Leave blank for unlimited.", - type: "number" - } - } - }, - adapter: { - anyOf: [ - { - title: "s3", - additionalProperties: false, - type: "object", - properties: { - type: { - default: "s3", - const: "s3", - readOnly: true, - type: "string" - }, - config: { - title: "S3", - type: "object", - properties: { - access_key: { - type: "string" - }, - secret_access_key: { - type: "string" - }, - url: { - pattern: "^https?://[^/]+", - description: "URL to S3 compatible endpoint without trailing slash", - examples: [ - "https://{account_id}.r2.cloudflarestorage.com/{bucket}", - "https://{bucket}.s3.{region}.amazonaws.com" - ], - type: "string" - } - }, - required: ["access_key", "secret_access_key", "url"] - } - }, - required: ["type", "config"] - }, - { - title: "cloudinary", - additionalProperties: false, - type: "object", - properties: { - type: { - default: "cloudinary", - const: "cloudinary", - readOnly: true, - type: "string" - }, - config: { - title: "Cloudinary", - type: "object", - properties: { - cloud_name: { - type: "string" - }, - api_key: { - type: "string" - }, - api_secret: { - type: "string" - }, - upload_preset: { - type: "string" - } - }, - required: ["cloud_name", "api_key", "api_secret"] - } - }, - required: ["type", "config"] - }, - { - title: "local", - additionalProperties: false, - type: "object", - properties: { - type: { - default: "local", - const: "local", - readOnly: true, - type: "string" - }, - config: { - title: "Local", - type: "object", - properties: { - path: { - default: "./", - type: "string" - } - }, - required: ["path"] - } - }, - required: ["type", "config"] - } - ] - } - }, - required: ["enabled", "basepath", "entity_name", "storage"] -}; - export default function JsonSchemaForm3() { const { schema, config } = useBknd(); @@ -287,6 +161,7 @@ export default function JsonSchemaForm3() { function CustomMediaForm() { const { schema, config } = useBknd(); + return (
@@ -301,7 +176,7 @@ function CustomMediaForm() { } function CustomMediaFormAdapter() { - const ctx = useAnyOfContext(); + const ctx = AnyOf.useContext(); return ( <> From 8418231c43938b43d3046607f6609c4b73649e65 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 5 Feb 2025 16:11:53 +0100 Subject: [PATCH 19/32] improved media settings implementation --- app/package.json | 2 +- app/src/core/utils/strings.ts | 2 +- app/src/media/media-schema.ts | 4 +- .../adapters/StorageCloudinaryAdapter.ts | 2 +- .../StorageLocalAdapter.ts | 2 +- .../storage/adapters/StorageS3Adapter.ts | 3 +- app/src/ui/components/buttons/Button.tsx | 9 +- .../ui/components/form/Formy/components.tsx | 37 ++++++ .../form/json-schema-form/AnyOfField.tsx | 31 +++-- .../form/json-schema-form/Field.tsx | 22 ++-- .../form/json-schema-form/FieldWrapper.tsx | 8 +- .../components/form/json-schema-form/Form.tsx | 68 ++++++---- .../form/json-schema-form/ObjectField.tsx | 7 +- .../components/form/json-schema-form/utils.ts | 29 ++++- app/src/ui/components/modal/Modal2.tsx | 2 +- app/src/ui/components/radix/ScrollArea.tsx | 22 ---- app/src/ui/components/radix/extend.tsx | 86 ------------- app/src/ui/layouts/AppShell/AppShell.tsx | 16 ++- app/src/ui/routes/media/_media.root.tsx | 2 +- app/src/ui/routes/media/media.settings.tsx | 118 ++++++++++++------ app/src/ui/routes/test/index.tsx | 4 +- app/src/ui/routes/test/tests/formy-test.tsx | 17 +++ .../routes/test/tests/json-schema-form3.tsx | 2 +- app/src/ui/styles.css | 6 +- bun.lockb | Bin 1076264 -> 1110728 bytes 25 files changed, 291 insertions(+), 210 deletions(-) delete mode 100644 app/src/ui/components/radix/ScrollArea.tsx delete mode 100644 app/src/ui/components/radix/extend.tsx create mode 100644 app/src/ui/routes/test/tests/formy-test.tsx diff --git a/app/package.json b/app/package.json index 4373a2a..1e9f061 100644 --- a/app/package.json +++ b/app/package.json @@ -54,6 +54,7 @@ "lodash-es": "^4.17.21", "oauth4webapi": "^2.11.1", "object-path-immutable": "^4.1.2", + "radix-ui": "^1.1.2", "swr": "^2.2.5" }, "devDependencies": { @@ -64,7 +65,6 @@ "@hono/zod-validator": "^0.4.1", "@hookform/resolvers": "^3.9.1", "@libsql/kysely-libsql": "^0.4.1", - "@radix-ui/react-scroll-area": "^1.2.0", "@rjsf/core": "^5.22.2", "@tabler/icons-react": "3.18.0", "@types/node": "^22.10.0", diff --git a/app/src/core/utils/strings.ts b/app/src/core/utils/strings.ts index fc268e4..a28d7ea 100644 --- a/app/src/core/utils/strings.ts +++ b/app/src/core/utils/strings.ts @@ -81,7 +81,7 @@ export function identifierToHumanReadable(str: string) { case "SCREAMING_SNAKE_CASE": return snakeToPascalWithSpaces(str.toLowerCase()); case "unknown": - return str; + return ucFirst(str); } } export function autoFormatString(str: string) { diff --git a/app/src/media/media-schema.ts b/app/src/media/media-schema.ts index 64a52ba..f1d793f 100644 --- a/app/src/media/media-schema.ts +++ b/app/src/media/media-schema.ts @@ -16,7 +16,8 @@ export function buildMediaSchema() { config: adapter.schema }, { - title: name, + title: adapter.schema.title ?? name, + description: adapter.schema.description, additionalProperties: false } ); @@ -32,6 +33,7 @@ export function buildMediaSchema() { { body_max_size: Type.Optional( Type.Number({ + minimum: 0, description: "Max size of the body in bytes. Leave blank for unlimited." }) ) diff --git a/app/src/media/storage/adapters/StorageCloudinaryAdapter.ts b/app/src/media/storage/adapters/StorageCloudinaryAdapter.ts index 771b389..cfb4100 100644 --- a/app/src/media/storage/adapters/StorageCloudinaryAdapter.ts +++ b/app/src/media/storage/adapters/StorageCloudinaryAdapter.ts @@ -9,7 +9,7 @@ export const cloudinaryAdapterConfig = Type.Object( api_secret: Type.String(), upload_preset: Type.Optional(Type.String()) }, - { title: "Cloudinary" } + { title: "Cloudinary", description: "Cloudinary media storage" } ); export type CloudinaryConfig = Static; diff --git a/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts b/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts index b6c2650..2c142ff 100644 --- a/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts +++ b/app/src/media/storage/adapters/StorageLocalAdapter/StorageLocalAdapter.ts @@ -7,7 +7,7 @@ export const localAdapterConfig = Type.Object( { path: Type.String({ default: "./" }) }, - { title: "Local" } + { title: "Local", description: "Local file system storage" } ); export type LocalAdapterConfig = Static; diff --git a/app/src/media/storage/adapters/StorageS3Adapter.ts b/app/src/media/storage/adapters/StorageS3Adapter.ts index 90c3cb2..b330d64 100644 --- a/app/src/media/storage/adapters/StorageS3Adapter.ts +++ b/app/src/media/storage/adapters/StorageS3Adapter.ts @@ -25,7 +25,8 @@ export const s3AdapterConfig = Type.Object( }) }, { - title: "S3" + title: "AWS S3", + description: "AWS S3 or compatible storage" } ); diff --git a/app/src/ui/components/buttons/Button.tsx b/app/src/ui/components/buttons/Button.tsx index a9a55e2..eb5ad35 100644 --- a/app/src/ui/components/buttons/Button.tsx +++ b/app/src/ui/components/buttons/Button.tsx @@ -1,4 +1,5 @@ import type React from "react"; +import { Children } from "react"; import { forwardRef } from "react"; import { twMerge } from "tailwind-merge"; import { Link } from "ui/components/wouter/Link"; @@ -19,7 +20,7 @@ const styles = { default: "bg-primary/5 hover:bg-primary/10 link text-primary/70", primary: "bg-primary hover:bg-primary/80 link text-background", ghost: "bg-transparent hover:bg-primary/5 link text-primary/70", - outline: "border border-primary/70 bg-transparent hover:bg-primary/5 link text-primary/70", + outline: "border border-primary/50 bg-transparent hover:bg-primary/5 link text-primary/80", red: "dark:bg-red-950 dark:hover:bg-red-900 bg-red-100 hover:bg-red-200 link text-primary/70", subtlered: "dark:text-red-950 text-red-700 dark:hover:bg-red-900 bg-transparent hover:bg-red-50 link" @@ -58,7 +59,11 @@ const Base = ({ children: ( <> {IconLeft && } - {children && {children}} + {children && Children.count(children) === 1 ? ( + {children} + ) : ( + children + )} {IconRight && } ) diff --git a/app/src/ui/components/form/Formy/components.tsx b/app/src/ui/components/form/Formy/components.tsx index 7bf691f..74d4717 100644 --- a/app/src/ui/components/form/Formy/components.tsx +++ b/app/src/ui/components/form/Formy/components.tsx @@ -1,6 +1,9 @@ import { getBrowser } from "core/utils"; import type { Field } from "data"; +import { Switch as RadixSwitch } from "radix-ui"; import { + type ChangeEventHandler, + type ComponentPropsWithoutRef, type ElementType, forwardRef, useEffect, @@ -26,6 +29,7 @@ export const Group = ({ className={twMerge( "flex flex-col gap-1.5", as === "fieldset" && "border border-primary/10 p-3 rounded-md", + as === "fieldset" && error && "border-red-500", error && "text-red-500", props.className )} @@ -171,6 +175,39 @@ export const BooleanInput = forwardRef, + "name" | "required" | "disabled" | "checked" | "defaultChecked" | "id" | "type" + > & { + value?: SwitchValue; + onChange?: (e: { target: { value: boolean } }) => void; + onCheckedChange?: (checked: boolean) => void; + } +>(({ type, ...props }, ref) => { + return ( + { + props.onChange?.({ target: { value: bool } }); + }} + {...(props as any)} + checked={ + typeof props.checked !== "undefined" + ? props.checked + : typeof props.value !== "undefined" + ? Boolean(props.value) + : undefined + } + ref={ref} + > + + + ); +}); + export const Select = forwardRef< HTMLSelectElement, React.ComponentProps<"select"> & { diff --git a/app/src/ui/components/form/json-schema-form/AnyOfField.tsx b/app/src/ui/components/form/json-schema-form/AnyOfField.tsx index 87670cf..2a526bd 100644 --- a/app/src/ui/components/form/json-schema-form/AnyOfField.tsx +++ b/app/src/ui/components/form/json-schema-form/AnyOfField.tsx @@ -1,5 +1,7 @@ +import type { JsonError } from "json-schema-library"; import type { JSONSchema } from "json-schema-to-ts"; import { type ChangeEvent, type ReactNode, createContext, useContext, useState } from "react"; +import { twMerge } from "tailwind-merge"; import * as Formy from "ui/components/form/Formy"; import { FieldComponent, Field as FormField, type FieldProps as FormFieldProps } from "./Field"; import { FormContextOverride, useFieldContext } from "./Form"; @@ -19,19 +21,18 @@ export type AnyOfFieldContext = { selected: number | null; select: (index: number | null) => void; options: string[]; + errors: JsonError[]; selectSchema: any; }; const AnyOfContext = createContext(undefined!); export const useAnyOfContext = () => { - const ctx = useContext(AnyOfContext); - if (!ctx) throw new Error("useAnyOfContext: no context"); - return ctx; + return useContext(AnyOfContext); }; const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) => { - const { setValue, pointer, lib, value, ...ctx } = useFieldContext(path); + const { setValue, pointer, lib, value, errors, ...ctx } = useFieldContext(path); const schema = _schema ?? ctx.schema; if (!schema) return `AnyOfField(${path}): no schema ${pointer}`; const [matchedIndex, schemas = []] = getMultiSchemaMatched(schema, value); @@ -40,6 +41,7 @@ const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) => const selectSchema = { enum: options }; + //console.log("AnyOf:root", { value, matchedIndex, selected, schema }); const selectedSchema = selected !== null ? (schemas[selected] as Exclude) : undefined; @@ -51,8 +53,19 @@ const Root = ({ path = "", schema: _schema, children }: AnyOfFieldRootProps) => return ( + {/*
{JSON.stringify({ value, selected, errors: errors.length }, null, 2)}
*/} {children}
); @@ -62,7 +75,7 @@ const Select = () => { const { selected, select, path, schema, selectSchema } = useAnyOfContext(); function handleSelect(e: ChangeEvent) { - console.log("selected", e.target.value); + //console.log("selected", e.target.value); const i = e.target.value ? Number(e.target.value) : null; select(i); } @@ -81,11 +94,13 @@ const Select = () => { }; const Field = ({ name, label, ...props }: Partial) => { - const { selected, selectedSchema, path } = useAnyOfContext(); + const { selected, selectedSchema, path, errors } = useAnyOfContext(); if (selected === null) return null; return ( - +
0 && "bg-red-500/10")}> + +
); }; diff --git a/app/src/ui/components/form/json-schema-form/Field.tsx b/app/src/ui/components/form/json-schema-form/Field.tsx index 755f93a..904a1a5 100644 --- a/app/src/ui/components/form/json-schema-form/Field.tsx +++ b/app/src/ui/components/form/json-schema-form/Field.tsx @@ -5,7 +5,7 @@ import { ArrayField } from "./ArrayField"; import { FieldWrapper } from "./FieldWrapper"; import { useFieldContext } from "./Form"; import { ObjectField } from "./ObjectField"; -import { coerce, isType } from "./utils"; +import { coerce, isType, isTypeSchema } from "./utils"; export type FieldProps = { name: string; @@ -18,7 +18,8 @@ export type FieldProps = { export const Field = ({ name, schema: _schema, onChange, label: _label, hidden }: FieldProps) => { const { pointer, value, errors, setValue, required, ...ctx } = useFieldContext(name); const schema = _schema ?? ctx.schema; - if (!schema) return `"${name}" (${pointer}) has no schema`; + if (!isTypeSchema(schema)) return
{pointer} has no schema
; + //console.log("field", name, schema); if (isType(schema.type, "object")) { return ; @@ -38,7 +39,7 @@ export const Field = ({ name, schema: _schema, onChange, label: _label, hidden } const value = coerce(e.target.value, schema as any, { required }); //console.log("handleChange", pointer, e.target.value, { value }); - if (!value && !required) { + if (typeof value === "undefined" && !required) { ctx.deleteValue(pointer); } else { setValue(pointer, value); @@ -58,7 +59,6 @@ export const Field = ({ name, schema: _schema, onChange, label: _label, hidden }
- + +
+
- + {/* + {({ data, errors }) => ( + + )} + */} ); } +const Icons = [IconBrandAws, IconCloud, IconServer]; + +const AdapterIcon = ({ index }: { index: number }) => { + const Icon = Icons[index]; + if (!Icon) return null; + return ; +}; + function Adapters() { const ctx = AnyOf.useContext(); return ( - <> -
+ + + Media Adapter: + {!ctx.selected && (Choose one)} + +
{ctx.schemas?.map((schema: any, i) => ( ))}
- {ctx.selected !== null && ( - - + 0}> + + {autoFormatString(ctx.selectedSchema!.title!)} + + + + )} - +
); } -const Overlay = ({ visible = false }) => - visible && ( -
- ); +const Overlay = () => ( + + {({ data }) => + !data.enabled && ( +
+ ) + } + +); diff --git a/app/src/ui/routes/test/index.tsx b/app/src/ui/routes/test/index.tsx index adaf354..44342a2 100644 --- a/app/src/ui/routes/test/index.tsx +++ b/app/src/ui/routes/test/index.tsx @@ -1,6 +1,7 @@ import AppShellAccordionsTest from "ui/routes/test/tests/appshell-accordions-test"; import JsonSchemaFormReactTest from "ui/routes/test/tests/json-schema-form-react-test"; +import FormyTest from "ui/routes/test/tests/formy-test"; import SwaggerTest from "ui/routes/test/tests/swagger-test"; import SWRAndAPI from "ui/routes/test/tests/swr-and-api"; import SwrAndDataApi from "ui/routes/test/tests/swr-and-data-api"; @@ -48,7 +49,8 @@ const tests = { SwrAndDataApi, DropzoneElementTest, JsonSchemaFormReactTest, - JsonSchemaForm3 + JsonSchemaForm3, + FormyTest } as const; export default function TestRoutes() { diff --git a/app/src/ui/routes/test/tests/formy-test.tsx b/app/src/ui/routes/test/tests/formy-test.tsx new file mode 100644 index 0000000..d2b3fa1 --- /dev/null +++ b/app/src/ui/routes/test/tests/formy-test.tsx @@ -0,0 +1,17 @@ +import * as Formy from "ui/components/form/Formy"; + +export default function FormyTest() { + return ( +
+ formy + + label + + + + label + + +
+ ); +} diff --git a/app/src/ui/routes/test/tests/json-schema-form3.tsx b/app/src/ui/routes/test/tests/json-schema-form3.tsx index 9faf8b8..dad5d8d 100644 --- a/app/src/ui/routes/test/tests/json-schema-form3.tsx +++ b/app/src/ui/routes/test/tests/json-schema-form3.tsx @@ -138,7 +138,7 @@ export default function JsonSchemaForm3() { initialValues={{ tags: [0, 1] }} />*/} - + {/**/}
{/* div:first-child { - display: block !important; - min-width: 100% !important; - max-width: 100%; -} +/*div[data-radix-scroll-area-viewport] > div:first-child {}*/ /* hide calendar icon on inputs */ input[type="datetime-local"]::-webkit-calendar-picker-indicator, diff --git a/bun.lockb b/bun.lockb index 4d841b488bbb2824a016bd6a42c5f44b9c030336..1dae5fd370a81340384da04b7a713002d571509a 100755 GIT binary patch delta 203976 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 delta 182342 zcmce<33ydS_U^sU2?x#&M2w&!(m0|xpa{r8!XT4q5H$)YI1xgCFeI3SNz?=f&KQSFKvLYSpUR zJLz?w_PhJdK35)g@WPAMCg$#XT+4y&au0fM`OuZmevx?Z${~9e&3opJie6cr`d>F; z=RiMShYL)amb3xE72&(hI-NBAvQ}CNrL9i>ByV`ghY!3g3eARz5 zebDZERjq-wfR(H@90`W-Q$3#Gu?M&d`NgA3$4G|u@Rsll-a$LN!N--AmZ|()xO%Io zEH9lhDG1JitKHFH4!G)R$E&J?S}R!bVi4@43Y|NgTUItH*y|;$xSDc_OMYd^q~h{i z@_oIcvWaEo94s#$S6DQmGB|FL33`}UeUmq>y{(&rph_0=AQ|fTE>I&G@KzAC z0pFv78XWYtjr?j*g5-g!e*h>AEq=#FxX@#B^3`swe|{w>+Zptp*~s0XoLaq zWaOsj?XhRo-pHsfYCbR}PAnN!an8gbSoEPOcP^-=r-CxKksb$u5+wynH|;>R+zQlW zF(&@YiS7@fz~mQeIv-rb9*1xY6JH{LerM_{--S_yiKq+6Z3(HKLYZ zngAiF5q$ea5YTt^dvJC5He4gw;_E;8mDPL9^J!&MDvQfmkY8InlS(Qp1AZ2#bNAf6 z^?YhMeU?-fD|d2PMP*S%MX>DK^y67iU)834)of}=V{iUs&$s>AYj6hZgeTr)lq#>F zo{VK2C^?`1#agDd;)D?W;88L( zz`0aV!`J`A@Its|=GZ?>gVTQr(i_{ftI7y40zuU9gqW2d16MnFpxQYU)H2xvl;ByQ zOltdfd#+;2*urvD@zXQ*eA(pU(tw|miVo8%7((k<%sux2CPsw+S> zIEM$@gTp`x@>jE1un%}mPRv>KMLFqn+qSLxfb6}`Q%h#2yYiy5EVy}|UA zRXw{!y7gXdtLDHpof})4_~*l=HAG0hhe{gHlZSA;#YZC3mi`f61XX-ab61aeUC;_@y1p@O}kV{}=K# zt|tz36J1rkod?wM(TB%^{lU-Ss<;8vLVcbGq`1u;%@CgkHFFPBz89DSs=<4yCqYMo znvlcESG&VHn?iWoxq-ii$3oovQBQlO4cKhio}K!ttbqspdL$hB6&aZ1%Q zeM3{Gl#Iq=gWhnhlp{cy^zNWccsuP$pl?BGZWAcMyB=lj?g{Q$MTS>J^+GCW^LV~{ zEZ7emoM#WL1l7Rf2UrJ9dYFm)w<)Qlor9=<3Mj$afU@Q7Jg)(q4yvDZpofq61ZLT9w9o)}z68NX%to{~I z#&{X|vaJ$dek`bd+8UdlBbJDi$l~jx>t0ez^^0hkKonRwq z;qeOcKA$EKjX?RLs#gk7uR=C^htLvu8#d=lYr5M%<6zY1)` zpMlcAfv4Dm6`<-*sVtd@TtUYn*3s>t1Q}CSPQY9=?(m^Dkh$b*HN6a%=JtilSP#x2 zA(h5JNwkrUq_Sr{9@pI*aQwvdx%(ebRePHG!G&HCbBCKkP8w{FFMihi^7NREtD1W1 zC+Cb<&1>Fm3* zfNMOL`u55}=B287Bms;n3;^Z6PFiU0y|T;#sk5l4@vgm^O%mJ-)Px=tS$y-$L>oX+ zsm>+ zOu$RwN5Frfo-}u+7w}WKEIc;T1la_y(ul7kLmj?AhHUoSX(g4?VNXUZRh@diskjd) z0XCjzwtOgD0yhICz>}8@&gr-L;@b{5H-;Hg%Y9Z!eFzr{f0I;ZN13y2cbJ==gP( zHI%W9PvGjPg4WdFO>oU^9jFmK?Xl@4#{an31b@i$&)^b#11OC=?Xk(6oo(dRbIcD< zo0DGB{;;a#WoGr0cD#{gOXz-sKv1mlslaaY6m?Pl=quF&t~RCQ01LHZv(1c z!sF+2%`^t_oD}ree5Z%1>Y)fIMcfIh!3AF6sh|WI32H$1GjJ)Qkb8)d(y_sOxD>ST zDl>)FX{*;5)WH8BUtZ`U>Z!vSp!khfTR)}ONFWx)Hzc$wXI^U^l!1C+2>BZMQJ@5Q zF^ajV-yJS@uoI|7FpmZ`vqP^pK{kSVZk6Zv-(VeH1IqLsCSUcxyAd2f;&T#`Y%{14 z*4|`O`XpQ(7ZsIFky|VCBlu>a3HZkdd+y5-=^GC2S~c`mdwfz!X~|?RJ_f*Lnq5Je z_SD-<(a(5nPrl^%2dD{X0ZNR?9VQh{W-)KQ-JTn;$jU1!%1g)&Dhta6LFPI2ckaZJ z^ofV;Q#JTb6K&K)S0xxVWy~1GRgz;WEx+mzsQAX-9MXIb60grF2ZO{K#A6 z%j#bQrTeza4DW&O9R%qWhaOS2`y(dWY*2ciJYj5y(Iw?U4qUSISYdsA`KakX0%ho@ ztu*^O<97251IX9&!ydC0*c(*etsghpI>V)c)o_iaXk6jM3CJ+E!yfs2(1*r5{z+@| zY*1}2%(A2Aar7md>F#k1eW|T>Pup|9df9e+I$hhLZPmdvw+qFU(M(pTGc-m4;z?D%W=ErFx5cs~0TtDm_Mo(`8>A5pIHya7s_ zmqFRq6s}kGv&U<${i^CI}XJx;WKTIP!={>W_QRRh2 z#TBUeeH-c79{-?R0&WAPnf?f*k=208FaN+amsxb*El$@Q(e>cWnoE6X@@3Xu#)YbS zhl+8*IWMKZJfdyY_ATah3K3t!eAzF#(VtrD4}i#g>K6r;N{+XE{tF)KK-C{zTs*l$Nkvdxp#y0} zFwK{b@$D6kDwOX`&+l?v)x+pW(c>+k#&WvX-RFPW7_K5;I!XU!W2*txM^Tw12!eO0 zr}C?|o9$mped%nUAnwL~HMlqY%6Qzx|0BVU@FT%PWKBDfaMu*ExI3FY=W!v}j*8Pg zo(k>*Pl0N%4XBvwd^*rZkqOslu%l?6rX}NUU}Hc{!l|Gp=f)fDC^rb+ENB!|_fDqY zKC)NeTiCI*NUs4kfVrRs`tHMqS2v5h{EBhK6DN+Z2zJhiyYlj4LL`EM=O0dw=z7>L zKa;IyMm4wMPjb>XbZuMp0If*9ycTf#%%3~Q9bb|gcP5b8jpp28CONLKqQjVpg<~V0 z(_;18K>houOURdrZEs;xU3rgiI^X=J*@x%fjFAxEdtCs(J|t#kOM)vW{+{V>NU*`D)-Q zP{wmUC;>`AEdh20x8a=$SN)O-w!Fd_!9ciTm|u>t{8Kuak#;9vYrGw(rP0{cBP95V zjx~ZWLCwTFUXWKnJ+K%TET z4QShem=Mtm*C7>U6Q>pjo5@gzYd|%$0@Ny8;`1Lo%0{wlcQd(8zI+a-sY~YBb7MdW z`mX04holeAYg<**)8t*(&z8b7{q1`GHL7XcM^LVDP3&Rv7WB4p5A=w_E3lscbSJjI zTg2ZdraSFOZ{AX>s{fm*45gwv&M2}!Tr-+6!GjT4dKg_+q_cQ&8RL}#PXqPb(Vn-$ zgf;G211$erP^K7n`ONgo$GAmX{R}8Y-!;%0x(_Y|-VCav!s*4_OO+R2>G^C>Bl-3r za~9mLxO#K*O>>zyO(9&*|8$(SH@bM#l(9IOci`??{%I1rX_KlCeXQds^9s)nvHIaqo0>t?lPwtSEtWG*H5Hu#N}z}eQhhZj4P-7GCc@>HPX}cSmlnl?!C*ev3p~8o z?Yz|+KxyopF}4Ap1Zn__#>Uphi*w9tfU|;xNp8v=IRQ|Fb$Rdwb z1wL^QsMoSFk8ho6{2@>=%;g?Od+h0PcTo4v+s-h2$>W_Kt2~YX74sbFac9G->aR|> zg0&uR2W4~@cpTxetH&0gUf~26nnT^nNX6HCyv&dM??zifzKk*-)TQa6U|Svjc5(?u zFx=+;I#BENbEJ%k9oWal+jj$x}P5HF&~s4 z=mg3$?g?r&B|!D}uX*vHN{P2gXoPD#J_t&Xg&r^SI33iod-NLHGjcw(J;QxCg}@cp z+Om5Flm^eg#>%HLFfGRk9t%OOuG21ypY7Ir<};B|Q+WL~BM4r-&K_t&MfriVuD8wS zV~>x58tDel|9OM$anmZ0f}hQBw|QThZr%5Q?gMTzTDj2rT@A|3j4CUesJjA=Q0_GG zxG%rtW|M!~&FORd_8QUdR-=jf(RV^H3Dz{94ALqHjL%jLFnPo@Le=PJ1D`F>D#Jd%8AWYr^9p1G}euP?L$ zGw&NRZ-g@M9Wrl*GH;A#K58@C2GmG0uL)ki%QSH^9m(*y|Erk9Q6lqtAaniSgx4OL zs?6&Ty-})iZ|O*AUzkP(S?1qgi2UDv0g`!Db?g#$V9nXxt4u|icU_rxR}09O&$#1x zbMF^{`@qM5@;QA#x%GX(y}@6fvu)!do|7gTzhL#gTWeFX39kG%;2QWdYpbk-Tgi}H z?)Rc?h`msy1p5W9sBB=Z8EM71k_jcOjsst^x!(g+gYQr-)m{Tv{C&~OhHrXwK@iVP zfvbK%J*}qit9Vcy9Kte^vFz^glN{e6g(^>wuQ~soxfV8l&7R9#507?Xa1eYjkAU$-gi z4r)aAkT2VrR5-STQ*Y(u4qOFIDGu)0WcfFN8pve47+>uL{!MiH=Yjjgr)^HRKK6jB zRd1ROj+$j%_JFI)&Y+t1xA#FNKs<Xqa}8epLrqjUyks>{CC|D zs;b8_292f7d)DD_&%cFhb}#$DIxGbhL6&@ITjU9#cwbPuJA-mf(t97-fF|QoDocvX zGhYivA6q*Yg7OrvZt=lDrlFHRF+s*sK@AsvY7LKoONpK7;2>~MP=amv%a#`)6^XcqbE@YrwdxohBRN1CWoN0||R4Yto7q_5=+RZWu?Ws5LlRCbnxsC0 zu|=aDuKV6pJCJe-P&mD$O#A(>KN$ZCloYai{}rDXIT zKbrtePvW(?RClC2VU!$z;2880)^=34+spvng8+O3(qI zrf$UVCSVu11liByiGP@ljVSaL`jR0*-u=~#?nh7~n@~Jss#Nj&pC)k&-$9ng 9 zlH2XMD{e7Oyyn}vXH&ZM@olTxF+R6y{THbIOVjFBUeSeEnYb3ySSE6YvDzv5X= z?z2IO^9A`bowwk^Ya3-bZ}B2r<8GU<`j2_O7(@?M)tLsC(}6aT%Nkq7>)~2#r!sR| zy<-ZemhhcU#q>!NJLzIBJDKGKuPB@@H3V~;WVw3W&`s6lW4kcR#RLEOEqmrO2Lg`2 zzit0-Z`m{7LuB5zXWp`BzGuk1ZO?o*umu6-CxjC<{OH9yGf=Jain5{! zvfVv%vz))m1vMp^SB2v%MwM!Wi^kg`o5F)~E6aAV`n-9bR9G<~_yewnGuP=eTbKaH z@|;YpnCCPVV~Z<0@RrSe?Nue!u4-u&7tnyV-DkXnpYLiN%qX04?nDF_znk$wP$R=+ z+-l_gdxtTMVCe3aKdP|2xC6`4Aq9^) z_1vLjnk+awckazQO{}{#|B0&#FMfW|UFB!*w&%{L{BrR_i!Ocm*~!U`Vf?wk-7CeT zf=01aI2qcRf$S3HW@UA21UovteoJ1sozyV$W9foLsj&R{z+JBe=>?Cc!ey|NDQlE2 zSeA;nSsi7c8taujeRU8VLvFO~p+v{@v$rSXx2=w9C`o)wNssirHF@D7YxsQz>SU+u z9!-VCuspG7!B6pSu{BZ6X|Z1MO=}`P{p=M#Z*7!49DHeQln*8nFYs(SXGvbzTPf>* zX)2rn>kn(3E_gJRSO@EvUjI&B_zS6H$xlQD<*{zDby4jITDfBtA2UWD4Q$d`B8Hc) z3*51*QItCvZM*>07#gK>m!%RpFLDKwp0_D4>_bYD#?p0Pq{8z&YnHCNHx;h&Y?pMw z(o{UGjcNuUb${>-`g^UGNG`p8MP7L5OF__=HnOC{L@5kSlfRTyw@iNc8BC*bwZem6 z&Xg5Am+6~g<3NUo=C;lyb{%njP(kCCs)EI(hD}F;+}gjnl+JsGp~0sc^F|Y@E(z)^@GKCTOU!v=P6hE~*(t1HY1MdR}mED&A#7 zlwE`luiAi(rq_R!7p@`Iho_i_ds1QJjhUHW@NFudzcI=lP3;zgzZ%^Mrbix<2Z zWsjqmRb;7`SUUIqR2aTxy|`f}3SlFo!6(OhBuSk>t$2FDic~o4ZPPYO6!ks>li|do zf~RBM8ofh%>3Q4o!a=08SmRD*55P1f@pSImRQQEwF}JMud)JnHJYDcT%L=Bx66w0H zy2aj&YR4mH;d^{j;~sa4doRi!Om5q;oOw2&N^11ox%Fw_sghIGy#W@QDv?&Wttv$fPqi9Cmzt%{%{% zZG+|4m*st&nN78M5llL>R$hP|B^Ko-vbrU=cw0{AE=k3EZHa12nY!uZ9-AI~UtahP zDcO+OMbA&_dtv_Oz+`wVtZk|AeVCRYK1K`cpieV}_^Yr6re?CzxrDlrt+DLwD;yl@UF`H9e( z$rjj|FlU*Gqd#Yg((6~|h0{r?R%6%Jqp-fNEw|3T@TMgh!+e-zq~<-TtgF8WqNbIx zo>^_b45C3woI>Jq65-`vn&mP7i&9zNlHGJltY^H_SLy8gdxcZKvIXNDK==YIe=9sU|4sc9(mBhu+9?sJ}OG>6>zH%$f8EjOyd%Ronn~dkoeLfXl0+Z)t zvREolz=pZz(OXuVZxL)dg3ll^h(!3*w>ykJYdhI5k)7!JFFJ_UPmkp#E+%=rC0}bu zw%J;rJFX$QoMgV${fp$WmON%#ee#NiB4RKbXoo{U_$X z3Vkjl@e+yfW6HH0uuLZRz@N!@Ft zn_0B=_AfSf7!^Bo_g}R`YZomgrP*iarjI9K9Zfz~#@Dbuu!JInu)}X=&CV@_=fDO~ z);!G)n|vK6N!|K$0m9C|XIjEBCys`llpg$OUgAnpy#fwD`;|<8Yd12@NajPAUzWO{GuB?r-g4-R=Jh zf_|{(5f}EUa02wC`c9vKNj&^G%k|g4=w=QroUz^X)x<5aC9t7XibV@frG=az=9&+q zx;q&XOpC{cGzX^6n#s+CwXh>#*-~HFAr^BUJIg7v5T+@qS7u@*Io+kS#CN2Qb?WOL zkGYN0$(LLRJ6_Kyh>WV2;{eH#`~;iy&^60yH*s$2JeXV&4q$mId=1tE#!j~)6>ruk zs=b{3rgtNIf~8LYbO}r{;clN##WyyJYUZ*rw@gH}V0cZUzAnb~4y;#t@I!g=JsL+f z^Qbqnaa0S2pEiyKLuiFLqTjwvVm^RV0D3O0AHT|)7k{crRC@)rcSpGgVl2tic#g5M13i-+)m%yaoTf4N#+%&L zsYDs9N3?z~s^3epJX1Z9YKBnO&R#jOV03-K!?3fW^=o528tuer?b%aF$`%t*T^~=CNQzeY@9Y&UwvXZ5qJ-P z4a@W&-UutLXJHFufLTyJs6~_=q4TIkln;jQQtAhY4e!!2=3Luu>D-@E@j)%4?CYpA zm)wE0kmZglAHwo7EWYQiQ7v^6vv=jmX#I8U2p^H`rTsRs*KUZFp7%grB2DUqDCb_r zOiD)VLbc?$-A!=~3u6;GI66)mN47Ez5c;i5C1%0$T`c<&DJ^OOMEu*Hdt}lGuhtopm62Y!C$pFy{9s<~-mMXAnAQ4+EudJG`!iuC41dVe?~~HZxh0V}xGfIEwO>k#MMRDJNNKSW z>S0Ge!8j8>kQa8^%a#Wb$;YYiT$sigxZ`P}7TPUZe^abSZ11RcAv#a(9SaJg^$XGY zr6f%1h@wpBL`De=N`j3J*i;vXIy<=;+O$3w7B=Lu^_o#ay6NS)w(V(&vu`G|E-DseOHWLIOW@?ENH z2lAr9jTplsl3E5-{w|f+`LIkQXOWV=aoen{yJ2!!jhy5B1Lnug8FBRCv0z-Lh45vV zxk#NKTX)Q?NX1cOU~)-WQGs@vAE9S7(1Ifn%C(dGNGiVQh$#Cm>~P;s87E!$RVtha z)BHMV!zW>0cI~vE=(foIup)_LQT$y{ zZ8j#|7FfNkiBvaDDH9*gAtg8DY9(HTo$T^YJIY+LMXpc6qy?LsUAkx5%H4{_VP`gU z`x$g>Jxz?s%e43+Dcj~*-|^jhL^Vs%{g56erA0nh!Ymq*uiXHXM$sWr(Y`%x){RYu zX)m$SeGGF$*F8aEKrgMNc}v;huILrjEW?_=AnVL%-ZIwYF}}6OwW! z?0}r14?a4xA1-*XTO&xJtCiSDvN)P|8?AKf6AOk~@=lTkR^ca-XIpY;-}>CeB+D#! z*M9CXL`#e(>2u#A=^yLXKNd`Kf`%(dDui{aN&E~O8x3BD*aMW(@DgiC7TK_VIwlrW zSZ>KcHU`UGMiSW=cNja?hG?1|2$OED@jBS4?%}ZgapwB1;6fOKm)>^DuOHCaBz*^q zNtRf*%?H)jolFwBB;rQP)ns%zKFWVAc0qF8@n#9pgLgHyd$=A$ApubmQQKf_r23}Iui=a0mXJqUH1o!eZ0 zhABYdkwx8NL!<0xG4bg`S(Q49BtIi1r`Mp1zQaszqG!%9i8;_yqMYGa#oHvkCI}Q; zpK77A$$93#v0GuV05yAxnmrun{Uc$B@G5q(N-pD1TFVjeKU7C&1B_Z5{eO+6jp7?#28n8L$} zPG{g4((AcbT1QGT6b^&9{4bblp)-PwK4%)UYr2`Rj+8Nxw0AE|&r$P{RQM5WB+SLQ zVV|=s7UqhO`1`=K@dqw+m`kdm*4HraxE|zkZDf?aj^S(?iAlInsZC*hD8k^!d4^)R z1Y8a~HX2;Xp#LDLxE324hYj=_WojkNrPZ0EqS_ZRlvU(vT*!{`{th$Q7krjV9#Leh z{=z#POO6!nE>V(q!ZcA0U4MQaE^gwXo<20SV`Mqng}}-PA@g@gV_)pzXIz-neDAX znUy7@x^*ZSHX>7&cpr9rI_Lhp@ZibjPuwv!Q3D&{V);)em^U@uM5qCL%ys zmuUSr93)6-aO@wPTn?*5Uof`mm8tMbn1pg?+i(L+_7snDXEX3AW)0Z!@>Jp;n1$`X zlF}UFx?ZH#RI?zQ5G!>NOnt=(_Lv)3m-OI8d0{xs=7wilkuR3cS(cY*KV4y%LjAW$ zDWGKDnUGUvm=0_O-U6#}wGKMh)-kJr-e$nG(z2qu&Me1=p%#To-#g8;p}9+f@FbWs z8mGo(u+w;u#eqta=Vf9@xuxS_TI0+GhyQAr*$@{5;i&U%`Job?yA>vbvl#3Ln7Kf; z((wXQk_mbtOoL-eH!+DYEi+rv`hdhFQ-pOLOcP>leg@NYQLxhP`{I!8{0 z^@|37OADl=S2Khr7sJvyOlsRp{1y-`Sj?otIB2Zqjf>A`_h#L-m~C2eQyGqh$q}2o zULlqqyp$9090lA;Eh1IwCOh|1KfRjl#J-osg2ST0P4HnSk(8Yx&;v}73dEwiPq0T{ zmWUS2XPbw)$&3ox@~W~1pQxr2rKEVqZ;tEnDT-CYrY^!lgAn`R!Rr3$Aw3M_%);g$Xc5 zxG6931*vh-U}B_1!F91}E*k&~IRxP`m9t z?uLw$WtAt^!rWOd-1|oJ47NU|!}_~tIT|J#c4LdG-zP32M_tCFx)<3tKZiOqj0!$y0+(3ztSI+nI)$kl zTg~^ux}^uN&P#kks*_Uj-R_NQx5qAspMLK(`SD)i8TZ*d;`<*@C2xSK>3Y4!-?%Tz zj!|#d`@Pea>xuWfKdMpgB65d0$@D!z{MY-V>^Rv&mu57^_8E_sMm5T9{6Hr1&~|ke ztgAM`_|*?Y`C0K^@edz}YQV%{%P{Kn;B7r(%cAT?@e9JN2hF-TDe=<&(}$zlMpWB( zIT2ZU@Q-=nP*Peid+4Spd>1BL+#|gJYd_`@(;WfRx^9gi?uAa`RZ_0^F!5;SVO1Zx zA{Lxp|L`)Hj-WL4BcD>h~lep!Rb_CudD!7T7FqN5Ytb%cwji=vE%61Mdxf7pqPGn17{F51M!+gv3X`!WqPnSAKFlq*Xu%Z5y2|UpMh39LZ}xzF3yWFBD>OhK7Dwj`Rb&O{{Vkdj&A zFtMIZFtz7S35lj_^j5*$ADlo^!*Fi{!Wx(+9a~3P8(>;r78CbeYaP+xqEt8^Ca-`m zYmW!^%--!cf58GS-u&I0O6J4lBSzxDiW(xR!V%rO0W=vXF ze|gr(?uGlkm{}XS7;+7)H_h0rz6eu?b{c3>EBC9Irw=I&m8+mFsl@p(UhEPSJWfhB z%%XTCmH5%>W0^<1WW%u2)A=yX8=}6J3R}ILu{@nWCcwS$OL=Y)SLE)9nmq2-FGe#J|B8S~&7L%odThv9mW@qYVNr zBuCx>5jdEA1Z&uS_jt2@jM@QU=0|dWK|GjEqwH#Zrc9e<*y63s)}p0)3ar2DfeBAW zFtt)IL9&h*hktbIh%%^Nl74gtV+&+$^PrxOguqO zH@69XPfCh$t|oc-$A43CvgB_$VIyTk>u2H^NJ(#I-YvFd#AH^(Q(#)1jiLqm689pg zNv$b=0@h!OOSJkVb2cp}B_|h)a+~4RVGY~PIiH&R=Hs7&Nn)FlUtu;Sx@hU}naR)Q z#c^#cOl9VaZiJoYM5^13BQ|W9`#S8nf7&MLCNGR&^`?<{6^5ku<|SHu?t(MkdyOU4 zFduipG?kpzFqf}j(sVp3xSU1wg)v*IGhvdONEk_1c*eH4JeB+&rZ(LSMb+JjeZTbX z(8WtdFxPH6_r-21vY1Od(C0Ai-quO$uQG~LS!q2}jQ1JLwl$UY_b{pfgOqf_(S@DnZkV*| z!j`O0w#A~R-Fdjhceb%}1jPRp!DJ9j7A%6fiHz!+vxC6QtazCc{^NU7e^ykt8)YyZ zvKrfU`V6R@KAF43D%eTxFqQj*#VOcuYwnp~xCbr-?jd!&3t@jGW!DKPHthYQ2@s3w z4#ehRTC;XNu?D8mp=-j;CO?^QT;O9n{a~6N)&uX7roc1|v)@Nxw$kLBzk!(>$L%Hi z{A?jWy&nj#AxGt$61dOx#Cg-K9>1W%qvJiZE+;XFMEJumHf#&%d;FR)P;K-RVSZ6= zV=_Er${6M+FqsD1nS4Rp-!g7PD`tpi%o`y~4NT22L41+67S=tQcMLZdzguV4bw`*R zW0b317A9@r58h3MH^4N-T&r;%7XKY1>WA!Ef0&tNMFowKp)1sD>CseH=^wH5ORIZ^ zx00)t_^O1jI5xlzb@yX`kvb(>ewh~ zuza^$v=8I@sB07UKuY@qzuA$)%7K|j)}HvUdZvx&@ND}VCAN1I!qlr1!#-C8i4g6VV> zv(Fhzp|a$p&P|EMFz)7l>yh-?rrx&AO;lV2t8)U(ug5o8J}`@2XdwPu^Qh(&`aFE+ zxN|=)@`|6cbCf-V-22JZiJ2`-*ZjHm=U~{vxZNHBQxdDeEjc`J+R zo!zW;R=bjZUI3=D+G~Qj)pg`;xQZgB;eU(Z~hw*(CC%ko}WIVX3BiUbC znYNJO9)8)QRg`}^+MY|UgkcUIN+sTc@jYJCcwSr;V8kR|TJ?!b$&#yH~r;xWW%$s%h+~w(-on zG0tjpJY(y)3^l>D@5ZA7zT|AQ7tH+@Kp80;x7Po?FzJN70xf(5bMax6+Y(Q)x5;RC z4g+CkINHLl_RI|Ub(qFyQth^n)nr4%4-E5+3z$~436lZ2Ju7?*CRq|u?x{$;uQ5Vo zOtS!HyN>p{%RFPZS(FMthBYk1_WMP(qcMSz`}w7+u_SJQad~%NUg9<7r*n7X1rMbB`_Z-!5;IB zwuq{~foYzJyVmm?9|y#}4z;tDz_jdnZO#bqg4w*twQM;c$}WlbN*>qVR!+U;#Ghy% z)ld?)JH&M00+8@>*vU>JjeX}sHBMdW=DQSMt0XQag#|p37rsoYA+Fl3gV$P=`z}@t ztB-*aSHQRdLSJu_8kT84?08s)$%babbT{E7No;_fp$nVjVTYT9K2G0-dwX)MXX)l? znDwQ|@DCUt=W)?9q+|V9wx+_xFwM1D;ny%(1#7Mk7IQ?VJ%vuCFtcU7kG%sn#MN|P zb%dR)su}uNm=-G&NWi!PCi7+SW7@yMG!b<18Vc#`n{ktL8O$vz$Le5O5{S0GTe3^N zP4e#PR9Ii9?dwVT=CmqdPAa$F4m#57(e5s)pnj-)?YR-gaSH#pdskC1esLwQLtvWf zdXoqr@j15qnxsrdV<*DSG8r*4ZspysVP%PKad(f+xIawAM|O*9D>1BvwFq{4dTBt9Ug zS2XW<)^M*(yI5_q1g6RJ*7-WtNsigLta>}l&Moqcr}xgRPOa6bo~djj%y~^`6itra zfhF=_e4hIb8!st&K2(pjzX0QtU_Oz^>EkWh`HKNCZ!NdSyT$v&(}N!D89qU-lg0f? zU$Sq;>a~gn!(6-3f^YEiuwm}PK`Hm;b+}KzjOnva$0ziQ@-HANUD7YA0mFY$YJL{K zlQ^)yR-vwAsz~wmI++*~Fx-%z+0QgEDd)_N=Y_wMlsUQ>Fp+m6JzBx_B<%&kf>(K`d6M-}ukOTBa)w#e zMg==;YKiW!)6?@l%nP3&CBcXxFXBkE^T{?rF3L~j!?^Y%{F+Bf{up;a2=$U`xo@Hp zr^JKFPBcyE6xeteyEIW$Vu&4pm z$HjvSXwr@?Pr`HrAeO`$e}_pMoY{#7JD1ogl5Yd>pVz|p9Y}s7dIPDOGeU)v$H#-p z3`=|hyD7@K4lgtz9$cNt4_i)*2Updz#ju)s)^XB~>~YwonX*LR(s(dC%DI~Ml&a4^ zp^TGsH27M4EveE>emHBgc@U?t_CLaIQ(55t@8O#4f$m%|j;|-rOCT7E?NAnh1{?vN8 zDyP`g*wbIa#zZ++@!{fB@@=lyDp~(Pk7+xoHC(nMOYA?LvS=PcH6m4Rk7v)Y=v_T@ zOYT7UDgdTsWu2dOF3f%{N~uhKyw}Vq{{~#e(wQhU8hj;#KToL~_2W`fw@>jYXkyIy zu40-@QWK+j3mEkUq%uv0_x&4dRkdT;#XGXZR@iuF+R17&TN8G*STyf?M407L5{A^c zXx=OIdtp2{B|Yy`e!ZTQ*0*~qd~HXT=ys8`y`DCbq|Bq}D7(+a8IK}%1#DENg~V1E z{*oC=USeU5$+J|<&3kNiRC_Bvzif7teH*xZc9ajcKX^_&IGc84X)*rSSP6c1C%*;x zGwrtz5>isXSO? zw>ZXcz^^{mO<9oYz2fy$z~MjV-7a#8l&Z!jI69g7c`7iHgxbqt#y z55~HH|0z;M(clS8$d&P+(B;h{b+$`=SfA>>ARe5lyznMcr_&yS^ zkR)I`gh{^ET)B&T!#*%=%4|>frV>>!z9D`mFR`8!fevpub0e#dqvYo1M3_RUAX?Ci z$m4RT?hz^EE6=sQFkzAR;n&$rn^s3(7uDRy+}=p80y{!BeDympey?#ezkzmrlz%_v zrPtdAfkfQtd{@u-1S`?~24>q`JIp7g;EmT#81%0&+st$kHsD77hHrZC%XwirDb*r` z;SXMXdt;RU06h%7$*%fx-52wh!W2a88r2<6$O4l-lI}g@@34;Uc^9WIjJscUAnMXD zQ(pj;D%i=0@z%q*b6cL5Y;v>hEcMYu*xToDN5VNf4YTJI^}Y)0Pb=}LAV&AMc;-HY zI2EQniXEPl*nHTbFm3?Y@}BTzTy%2k{T}AU=FXz?t(oVv9ZrCCiENKS_S+N4YyKW;I%J0!eyR_xNx+DmWnCtqDv@YnaZP$&n`^kl+sT zUod$RJ|W}n^J7amsH=A7&-5gBz1NQ~lM|jv&S}))DvBe~BQUAdg1Vn!ipcGPx8r?w zDzLJPVJ=#CLE=*|eOY7E*YtjQg~5Af^+=LZdoC;tm%&CkhAD)*EHyKsJxs4ZOe+z0 zPhd73b~4N?e=E$)vTh?m_yfiWyE!XQhsl8Je+4RhnH-JCF0S@pmIJoD{VbkO%{POJhqra`GN-K-tZ;bJ(dx13Mn^<&YL_2ldrZnIX}SsCBA+k;E>1d zFu{!AKuTfqiA~*u55Puprcgm;xJFKa@={1-qupv!ArR-Sm7tOj?ig8=g2H z*pT|?j(f_Nx&H2iDRi+Onm=tv6UP$8un|$tU{)!qhMxC&#y=C~)-fBfhO#eU!|L1X z{p^nH8kp9H_4PAMF3cnzxXSF@*h-k@+jJ6pE+fA#$%euj*5V=<=6;hYzBZnIX+_U)zZWvkYn@yIljJsz zEig?yNA1JW#=0G~F$dP5jrU+<+;j3pXT4~KX|EfeglU~OiE^9JO0BJvFe>N}>(&J3 zj9R}2X`jlHqhHfuUuTo+^OEVu*c~vnWb8wjJSKntVm}P`W!Ag`$mcm7ITTJN$$kAFC4> z9Ja}a3GSXU90QdaZ2Nc!rmAdl==E!u)WEBz4UGE@tBJeExJSd}q?r$9=XPIa>`l*@ z9ex*cr_J2k@s7OjW(zBG+~MFNm~x~O_Ql%^O!}Bp7rq% zOiPISRSd4(Tc#-fmfjY=42MZd=fk6;+r-00h zhr=`rZp#Z7X3C=6b7%=>{$C+;>3b$8wy59Fd>HBi`Kaz_J}2LuKPUDnLDAhGNcMSm zbN4_>dzQPm2`~T9&XdHV{4IiCK8*4|!{|=^$TsWXnp~Q^5~lSN@OR5tKjFs~HPIpW zW%1iSj`IJ>GjEZt1%r!Zt%h4{eDs2eoe$Hhw$Xe8D~93J*3taPPwepN=`&F2$#j_Y zsY#0~;dXoyO!LgrU7CvD|7le71wH?Z+?nKh`Nn@1cOQ#;`Ym*%E7di8c)~x;QDB(3 zjjLfgb^5wLLU$Nx-_Omz`O@`JZ5+<75(j*NUAZG-F)8IUvmfzEHB2(12ZG9PVRELp z{3`BBPy7rmOQ(ZudsUA;wlS;M!+qszC&&(FG! zMAPs1Am}Tf2yfbEE6T=F3zIiDCG7m2otJE7^nhsv8#@=Kb!1!nqc90#tl9VV9*JEb zA10}=bpFg*_4kPK17GuOCRFF|y?+h}TME zsjTov2J=(AXX4}^>D@W!Ye~s#Hi~jL@Z}H{UZO(S=O>@-PQ=&1O!W&!qWTYfA$HH( z^ZkD|r|i5%))_z3#V@pQHQ8=;yA#W+p5fY7q>?Ru@eZs0d~zx|rW`HFg`VMrQO8!8 zelH{LBKOpa%D2xupD5nqW#$( zmAUxumHPYzpJ5k4mNNh|v+gi$RW|BUn6#CnIY}&p^>8Ppw@69Yr2Eh=jAePfDdsDH zX;xcAx!+?6KS4{N?l%v@N%1UySk&*Xwd7BUYfrHw=V+KIRc`{8!qg1Qa~p5yV7f}# z#qGy~_><%IRY~1sh6&ReG9UE;OrZoXK;$70=dY3L%)rM4$Tk_KLN-O%12Fk2=9KCB z0Vex$_7`^KkCP9Fv4n}FZ-A*4_mVU54vhOAes`*4lPEut)hoQ2KQ}EK320(K7e&}-m5u(>Rh$3KO(t7FgZcY0o^MGMAaW4}TrFU=rGKmNwLEmn1LIZTZ*GVV5NVKQUx z2PxZ)zq;-hGQSmf(ymd>&P@Iia?PA2)DON6+mB-P!}x>jZU@$%Eeof@WR^ixcR)Oq zwPLp{_X>F%*;<`=fg(ibZ?(%Bd55d}1{fED59Ni|k+R{|q2*UH%;M(e{2_NQ1aDaf zw~A_7AlgE5r9GR?a4Xbr(u8gU_*3pWKbil&8m0zZSQ{NZf>-Y3mBeLl3R7$D$Phjb)2MJ*{3YVH`$XBTvwFo( z+b7Bg!@2vIo|10AS__lPT~wH}IuFJ# zaPw8r`=rXKrU&z*!R)Wl*~8*TZ!^9`$h z987a+E@nAQmS&qs)A2~7@r`hl~nC(~cto`}(_YDFsh7HNI6#fR2 zY2bCa(j3m8k(c+xjQK|6o(@s%eoXrT{PB5vUZHZiXNf5HKokX&5nxQ5&>9`i9_nKC zo}?tb`^Ggq2PVg3A20X?b8ydVTW@RKq1=V~=dxB{L9B(L|VbQ+7;#!8mabw7YF6q|9+J8}TEKT#9k7b*|5)G}{MbLRBPOW- zPx4jtCI6`7uRsa%9jNl3!N%a9pni5l)&I-q|Hc37hWlyA2m(nOG%}2XdLRqb&yJ}4 zM!q}&s!HhV2}AfUp!(X?=l^e5MS&!51FFv6zM@bgH~>^f2YPG|@?UT$|ES@^MLddk zf~&owKo#}mA3fho#G^FS&zDyX^aVmyJl1oeG?DMQP$N18RJ|dfica%xkdwvEe zL5e{B3&!dnj}mk|96_prG7@TVvacXivXXz);8ai&&jj`01wOwT)Q?cl&+_~~p`M@Z z%Y_=qe8-u8OZ?wKwVC!E2{nLgKnZ>wC_%6H`8R@$KL}jnZ>WklQ9+X4=^tFI2lx?c zME83BpHR===gWmj_;OI~Jq1djXTd5Zo+qKXs`UlyL3OYJ)CgYp`I|xg2$g)t^BqxH zAMlR^_|TUN)!wIIGjJQIet&4>#_tmPzm5u;s@DIn=-2=MjgB>-2Y{_x$v?w}g#;md{6>d~I>h^p7ummdSFoq@jIe?pa49ZLm0 znC~n8e?bX2(myAZ28uv6JlbQi$1xtqf~q$jFaKOd9;)u6M#i+u&5R>9?-|0k4S^C?#YSNVGX2{qT(`EsF>3;9O^ z-V92RTa_vMQ$hu|`GQ5B-{JXUusP+AfczIcu7Cc9dj1KYzavWEXUJEFt3VBK9jL17 z`N!G65*pEK%JrxRHh3-+f8F!{gerf7atX58*MG~`-w{>*w$BHvT*L4B451|40!oEn z_IXYHsYw!8NpxW!u#4o19$&iRg zg8Ucs;2(8xG}sgz1ge4KK`CsAFFy^`b7z4&ffGU1o8Kn(qs)0+oL)$bZ2?{?Vp*52y|w0NaC`J#GipQ5@+=1|cXxvOP8h`7da}KYD%- z@BpxPmCqOeYBiq>YEhj5O7(@ld@QIDP67EZIA8z#4V85X|7a@afD)(%RQ^@^$D@)r zcwUuB{7RkcqN2vPqeSX^K z|L@57HNtCrg&k21UQfORy49EePpJBLP){A-398+@{BuH;-|KljYGkT-Kd1+n`U*lB z*Mp!&{1~VPo&r_xX;42x@n<|f>v0vRcAxirHK_Jp@cA!-`l-q!gv#6C3xsOmbx<8_ z@_aKWLEiEC?}GXfs@{8^|0k3HANq1(uI%rBv3LLRUC#gi_xGb$+xopSR!LUIl4O_` zl9g$dFigwu#aIX{V<9t)g)rXpSQ3W4n;&5@EhLL+NwOGAlEt)2m@Er%-tO!1{(Sa5 zFV4^9b6(E#&m9-X?#J_bJdfw`Jf6q#I$p1B9oFI-{^Bc?s@Uqj$MZK|uhd7&uG}WI z!!XZq-8Py2DfKGp$$H(w`+NNXWTdXY;VkHgM*50lNKOBgs&~BCOCZ(JM6a(@henec zxsyD{kbNjmAvGzr-PvRpz5dSA0-5f4kyp5sRD+k1nv^PMkUF9(-IemIysXp?uJ*E0 z?O#XgTDr;C&mr4i|60(b)P}c_I)d9tZEz2%(SOLx=Ia-b+VSI_3rYS9D&vc`TjE(s zs@@xJ%*;l9)J2hUxeKYIQ|YEo)PKYO-#{^Gft)B&{Sv7o8dSL`8m3;xr~ z`$$#%o7B`XbxuS1)S@8`*QXax9Y}Y|+ODT(Z(rXrbxQN1eMQGq&-=UoQ)>MHU$0a{ zL%rNFRqrrd9XXs-`3TRr{q^&Lw4e${lIr;gQtJ}+<^PtdcOtHaP9ik|W4(N;XA-GN zse0o)$Ga=lPBN))=7J{q3Z*ufOzMcvBl!hz&;!1{W9phH!PVh~q#9gAYWpWWpCS*Y z{1&Nt?~t05x`C}D+h6~6S^(-jHi6)nQvK@VWu>m! zD9-_;>JRkwO5HGrdzs8@-{2TP8zzuC@KIhtsRk0g+%Z*ujC;q_0i25KfKK=I9a9~i zgsa`j`k1DVa_J7!JTD;Ck&C>1vF9bECZ!s<)blcTr3QKisdjH7)lROjSE_sqsqJsg z^M%_y=aQO~s`#Jvcli2zU*9p+(4Dw0iTixLQX}+`m;awK@1Itv!H0cArOHL5I`k;1 z4^EH!dZqjcFDq4lk(ZSk@={Xuo+WjP{!LOZFK96fn*J#@l&|`ROMS!2{Tl|o;oEgg z?dVNh`Ht6H>G>|H9luAaBQ@>L`TxKxto9Xay!@f(TK9Ec{+QJ3XCtW{Z6-B!Or44* zTqE^^uUG2Tw1-qj_L9MRoBG`=bWAn;7p|VRUrC;7FpMipLmaLv%v0yOr+Y8Y-oCzL zYP&w}O6~vufd7KiDvgK=I~s$R1D1kZ`2b~K69^gpHU3uk-1vwL#!$MF#a2Q4e6x|j#I zeF(|7F+n3qP0IFb+snuI;@Z`Y5*(DeU!6i~fRaePu&0n}@GQ?%&vQM~Jg0h2^SsdW zV$VxGGdwTv#qn!LR|1-px-VsW`JYl9neFR4rrNm)SI+VEN*&-Wq^OWD+WtNjlzIPI z=#bjrey=#+U8#m2_Oep-ib&nhO5Bz51*Gaf;jWY~a(~)APYZf+Jm)JG`-+aKbG*dY zze=j13eTmaj_7qSSCX2P?XOZ_|CYN_zLKPac|ogug;EW_N2c|Q&ze{R=tK2{6-F~~}~U)a0K6SXh%Ifdz0EhKQABX ztm)2RNhWtEIlTtfKC-s4Ey8Az+I+n?Lb@(dZ z?iw%8^zA(Jf;xhBIExBuAjdP8)Q)c>)!^-(cX;0Ec{iyeEbzR?z0k|^NL`%ENKMM% zpus^wRV--7D@g6An$!@jCPQsR1}_qpf;Op0eobmWTZI2FQ=g7@vz>PHn{TgFdu^oJ z|HI3FdhYAPi$p8*&aHlR)jPPS1|*!a&PZQUx3~VJj^_~1p`>vcaJN2=q=q&hUow^OP^lReLHS8Dq+No|)(>VVSo zyh1vu4X1fosSPe9b?sj6>#rcS!x`l1N|jf6S*Zp;Ahm-vo*$8F@MAC6d4A^pxn~2Z?Z5K!*IwSbKl6gVXF&~bC$-}p zq#FLg{UKEiXD=Wx#vo+C-Mf2@~}C)9OHCDrguQbU&Qnd9qoef=C# zJGzzBtKx1_|E}k8Qq%t;_rL!BsiGQs)f@W%k~)wI+EFg`e9iOqzU*HsDt$*vmEZ8P zQsrfyRi4W|-y}6DH4<-ozT@jx`g*0>dDqKI)nAq8u!__vs3BGH19zp$t4W=TwWKy& z=j)ZaST}fCsr8?ES*cUAnbbM|&Rwbf!RsgVgM)sgP*JxEPTy@wn~ zs@?!HiX2IX@ct7N&w@U8j3IU8<48^aZ&Eu>W;=E0bW$BpAvN@=6~6u*FTd;MYEu8~A!rQ? znv~jLEvb?Cgwzh}JU4iLN@^&-AazlFO{yb}zJ9Ccx1{QA^YuGCcaiGg?tUD)f5x5FbEleH5wn(WIu1srCoB|95KqeT5nr=oOSI zAM9nNMkIz*$6`rcGx4PA9qWFAmq(Gj4+W*TpW!~m^Gs45Iy=u7&LR0!6f~XGq|}jQ zlG@=6&zYXtzWzp19mpXyq_?`?PHJTCCAFh@q)v4asRMb8)OLC1@C2y_o*`B71yVbH znbbM1^zw324ZK5YQmUiX?jLxrCAIx}U%!FWhwm+<+WVele|bSac!i%x^|Xc5q*TMd zlIm%zyHe#nURG+mHc|)hmwU%lM?&2b{@>p#DAm9~&q1Vic&L|$keWKCb}-capHk}&W4$^WN2hxaiuGEoT=jDG&9dS16b-%dH>-~57>tCP_%q7*KJg?X>)q%U+JErR2gR8^y zNwxE!*HfwkMWi}fOsbv7N!45UpB*gp6;G3zlxp}HulTIzbMF5pHFZqw;00XyvaeUF zyp&XXue&SNfxJowrOw?uzG9`jQb(|g)XS^ZU8x4vcz)=)mgHwlK^sZ6x7GbyQtfi zpu_Y@lS!!^#d=w(p&Lf3p`(2L2+yNQO-gMy(#uL+Y$v*(zQc)XBCe`!vN$p@NsUyFD)TGpiTtce;Wu!WO zm9OuZ+CIx&sdldMvQpPl_JNGQR@~?nZuSaFHIVCmtGiNu8>u&wdA|MuQXP7b)YLKg z$PiTO^`0ZO;}^XCO9wLkdbfKW(ABzv)DGSuh-;Y z)Q)~8^*P~BFNg4?ibk+2srtS0SWwUVI7E{gk%8`mNKH!B8|>wdsSY2CtHC(0ccj-- zs=X1Ub{tQt{;{Om%RAl|PVfpRlA8W0)xasNR|8{xyCko#l#lbWQuR-FpWv=khbHa! zyr9XxLaCuUo79Hqxhv(Ah)!|o3y&9I0nv`m%%F9Y^{}!qGE6H%Z{#Uc0Bm9We z2J5`MfmFvDNS)hnNNxBXsU7Vkb;P^eTfDrR)Qew-)rjDr&9*?U7qeyLcvX{q_T0h=%LNw3#Y6lYmH9U#b zk8Y=tYTzQTc$u%y@SN^`C8>HdRJOS{`49cGDXQ7or208WtI4_Ud0xKD%LShIlA4sN zf4`TNYNv?Q?*8SjRM|*%za*O7hA*3YWa!k+hhrHJrp||BJ0Fhy|KlN9y&O9qj_rIn zw)5fG&WB?=ACB$#P^{i%Rn`ZP&WB?=ACB#OIF@f+^r^h_;n>cHWA%`%Zj7A|$96s( z+xc+p)BMO%-$->n9Q#iX#WFDM56$Ym;~V{O*OTAlc0L@-&tv&V6uNjiACB$#P^>Nz zmG$%4jt|AkRo0Io|LLJvt(WU!>wGx2^WoUehhsY*j@2&;nZ|TT-5yS*tlvI#d?;4+ zRMri-^WoV4JQLgbaBSzpv7Hacc0L^2`EV@%Fhc+CrSsv~&WB?=ACA>Svij#Noe#%$ zJ{-IMBXj4&v7Hacc0L@-4>t9EWygnNDYlpOW2?@GV>=&??R+>ksPp02&WB?=ACB#O zIJWcQ*v^MzJ0Fhi=1oF1z)k(EGO7%=f!Y4!+-(zu#r5mA}-brwytB=G%-KAbkn2PVkWR{{RSo8JPP4 zP-JTaRe}+#fk$o5Y9Q+sV6&juhSdVmuLARH0ke&QTEUn#zyh1M2FR@db^##^LoDWu zu*o*&wLo`^TM94wka~-3`-jwP5KLJMJY@^k0)?*u`vj$y`Vx@%I#Br%@T^Vz2xt~8 z`3NYpy@HZT;No?_Vtalakn#r5^JCz7oAxo#CRibO(IVCZ<;#GX>wzVNg`VhN%6B7PDvQAPLVgtTHsw8v2LOu<#4<%VO$cW8IeTdz%8HxS? z*^C5#VG+wUI)a3+sj@M|?);i6xvP;TBzTiWzDbq1T42l;s%&Pwwos)(vI_~`Vx@0T zrEm=pSOzp&>M|hl!!AAS^<`bo2>F%~{f2FtKcvc{Z)l~75tWpzMW!?&+ZfTtF6W0d zhuAO5?TqJEaz}_gquj}8Dt`#EbG{{aF_y|7LoDPw@+U@;wD9$`xZ*onY+)pukSfW{ zCS*4wDarZ-8T38U%1C~XMAsqfB)>6|+mKqx+-=BSMpBZy0U6PZ{J}^zBXOT1n>y%T5_EZPYKY`dW3b70C3K$tD~ z0Z91**e8gviMxO{!IE7-ciSr{ZvZa-5$I{p{|KaS1bY4i^tNd~0pVW)D+G}i@iR~* znE5l%&z1|aHUWcLfGC^M0z`iWtP>n${eJ;!1#^D^`r8^o?q*=bZeXCz+1+Jo@WEE6 z7-YkKB@VHC#bDd0IMm`>i5Q!w7-Efzp*DICahMe;Vr{$Pa7+4)IKmbv;;cn6%qF%G zM_Q?3xb0OOWvP3K5%#>|Xbb+G7-`cK$5@3T-Xi{>t5r>Ob><&*^*CED$od`_^e2#D zGyVjkw*l(}qpbfvpjI$__e+Qd+x zO|T>sm~49m~W+Z4r?=)<1Ntk#u~vEf-|{sblR695Izn_j(Ft;Bt z$JPjP{{luF0NiSG4gli*1~v=k+OQ~~K`=iG$g_<=abbX${ehJ8ZQg-YNDKyc3GTAd z2La83MF#-|wp~yX0!)bp?zIKcKuRdEPcY9W_6OPoOZo%%+g?F=7vSOnz@UFlLL6Joq3{(kb9t=Ec%LQ3sz@R}uvCS9+M27?G1ZMpY0cr(v4*?d~ z8bNLZFk&#U(B=#V;<^Ew1&eIhp+JLR{-MBAwoy>n9T*b>l-j%)Ah8FqOYp3X9s)EA z77YQ)Y`dVOCop9wu-Fz11yXte`+zCW>j!W?b$K!Cqrj$!-;TNU)aw@Kht3`qasB(R zADQ^o{oCFj*yq}#*Bm(Q`ky1mM~qq?xG?;Z4^{-uti0szbAKQIeveV>4qkJ`{GDaC zt5+b}qF&~v{bHzHu!Ng-dGA2ayv!q$7oPRwpjVDN^OyWy$JV63dGbw@+Kw4Gq{rL8 z-j&5|h{KBQX}sW|zk2^g zF6r3cs8gS6nmu^Ib%QGB-Ll8d`R0U{;UkZD=&q9{F0Q^~Z{~*|U752u=EK>S_WxJd zjK6|jT2wH!(Q+y~2Uis^mzO`pxb>h|~NjjpzPulcBW)zxdh{OyvL2d)fs-`#C#%7)a>DaxP#;NBY9Xv{XC z{*QjJ@a=bQ?SAjbEj@ayNIE|8x)n+5)SZmD2At0DtEr!+n_ z=&7<{k4}2-o4?xLkDk_ibKZLsAL@79gCh^F`e5i6qi=ckpsJ0NlTSVJ%)eK+{C?2k zCww$4`tZdM<)tn^a>n7uKN;DjLx*1rwL4ePZdPBeh_u7FL@KTHFfNhken21=SZ1lQ zK&_xsu-t+V=dSRkO;fyO6^gel;s|1eWhmaU<%*RS8ArTpGZfWUO<3YVG!#3GhTgO6 zVL-E>UQlB(M*=0$K*5o~YO52Z^am1#18XdQIM60&60EiOqk!@OK=DxlKIDbk)}sP^ z$Qy_xk3iOk+9M;7@Pm<7NnNOoI~u8ylpT$H8fw2tvIZe(Ba!-0duAjOeFzdb2Kge? z&N&9Dl~hVLhFVBGk~dP!5L4M{*sh9U(C$hJ`1AW1n4NjL%7&e=QxX_GWbc81!q zqmc4gq<9pvi}681ehjq}6Um<#9p%rVwnN#%*o-EB3AM+SyBQhfuc0>SM6#7}AuW0s zEe1}a#orj0laN|TrDQMTax#*8B$9bD@(1H0i5reY@irc^k8v4;G)QVBe={zpAcaRE zIj3-PgRS}$PHy4|Aa*PeYT09fW|C0@Sh9|N=s;w|Ycph{477I2)k2(nHA(#{4F ztn_RkdMpq~1x8tFDo`t^6pXgubAa4afy{G&ldM7zmjpze3yiUhbAbjyjbN-ro(B|; z19Hv-lB`;gI39>i1IAl+8qh4L7bIKE`9R5OK*9OI1gjIIBm)Ukfr*ws6=)MQ2_{>7 zI#7N(P@E1-u|`4q1R!}DaF!KK1Hw~)Rza#IT>w-G$}RxTwH86vL?G=#Ak9iI1fnMa zfs25tmU}9~^mVFt}ET|V`T1*B|au!gK0bFHuf|Rp?gz3Nx%byOk37Q1g zSp4Ncc`8tRIWW^21?lGi$yWf^ThSFj__;uLYk`srfP!m*d#z58av_i~6PRcDGl4cili+@fzYZwB z2q?Y|m~V}O^oxPy>w$-?=z1Xh5};L3WJxywRf4h`fJd!Gkaa1LmJJkJX*Ljj84#ES zn5E7FY6X>o1r|IT$jtyUX9EkZLJ&6{h`JG2WEnRC4T2iMQx=&66kZPGRg~! zP$^h$!M6js*8-Wh18-S{AZ{iQl?SY_j69%0P$O7rk#_)v*8w?q0M%A4NW311%?IAI z?0leEP%o&lm^*=z8-Rj4fz?(gNXZ5g?gG|W{#`(uph>XS;_n8^X92}`^X9g$i*3D| zH@EcJNOA$PzKcClfP~+Ov`Xr_*tmO;DoNQr$fsTG7fDtQl6Egr-^HG}7m2^ky=TmWMdZ#nTO=wjAYJ3Hg&P3lDJ$X>ON$17n^<`(jcjkZ0TZs??(#fAUXFV zja_V&B=Hs`_5tMEE;j1{q*+ogY3gD_<|8GyA_eo2ZCz}GB;__F;X!137rXO8q)pN! z+1bU8eF!O^ixfYE>|%T*>9-@v441fN0C}drDQMT^DiX#P9*bR$RCW4BaaJg7kj@$^QmMTG79O@M54<5N}C~fhs}SV&FJy5oA3Eq?H2+R$2~38xVLN z7-gx?1GR!m!DtJ90mv-@GG72rvI;@m0wC%|V2owF2s8+41Y<4oC7|$eAm=3@$*Kj3 z3wiVYb184$<1Kp$(7ccu^-HLcY%wnbB~JhaF9Q>-PLQ$)NO%R9X!)-IZGtAjWQ%_l zD1QyDanAu!ZvYot#v4F`phj@1MJ@vh%Yd9^K!#Nd z68{avRsok=b`{Vps25~f%yOV)F;K7^xXS7TDdj-Io4^dqe-mgEGzqS;__u)a=Yit4 zfSJ}PNPhuHejB*nirxmoUj$kO*_N~ds1lT|0A^c@AnPR{?HwS;O5XvZmvH8~tmMqy zY^f`O+9lMeTuF^N7W^)d`!bOEE^w<=2;yD=qN;(pmQf8f2x{?` zAh807eGjQgc@L;<<|ghf+oTJ7XJZI{yI?n z0WjYh1?iPQ@@n8AD_RYNzX7xgiY%!Xs1lUb0*_jYAZr*N0JY|vVfWo(coOM8{RSOc|24X)3 zp0(_cfo4Iypv+>{10^efg7v^+s}rQW10;L`Ja74*0BwRM!HX7O2b8Y_itB(S)+k7S z7f9X!ykbQgfbeRdRZw9`p8{2avQL56tVNKu3P}45sI=10fav#tKs~U`QtN?QL8V~1 z1%D3Yz7J%64!mU*g18zW>I-0nWqbiN2xXJ{Bw6c_v@J+|z@FKHM1PC~zCpeS@IyJI zR#GY17_g8=BzHZM*@$ck*iuQ{CrH#*WOKl#Z$%m;HIgj>>-#NIScl|%i!=sol_YTk z68jzUZNO%Ihcrv-B~1Yv(u9<+XA*hlJXgn@IA6UV0V6xv`LyII|Fv?Hl(~B zDc*+cVtgd&pCif5$WM$B(M|t zjq%xu)JiHPdl{b}klZhk%pZ_H7#~U8CM0SXvXAlEg)~TNB!4qLKO%)+Avr&Cl7p@K zM^19$W+3(_Ak?yd0-6Q&f`G;R43vBg6#NW?S)Cwd3y{zPL|A?c&?aaSbhr3lfbwsE z;$MKC)+k7C1d?|Hy{%|B5WW>?6+~LnuRxWc>{p+JHfp(FQaKY6OEVaxYN04anIG#8|Z;u^EW{ z9T;lazXQ#JdO@tk`~j3~2MYcGj<7mG$_^mmPhgnk{|U4SngqiwejiZ26DZyXjIc&Q z`VTKJUaGbRWvVIKoEKcjn2b1E`u8hV{tPccJ9%ZS) zK&_xsFxrAcfZU&f%n;xts}RJs08yd97|RF+8U!_hu@>0{DEtM;=>jBKwIFdf5E}r- zTXq0w7Ss!pEv73_@+(l#6_{Xkf|OPuAq<#k`C&ktph+;<;=_URJwS0dFvS`L>AwNV z5x`ki6aj>{0j+{mOX>zx3Cg+w=UR&(YcG)29Z0j%?m+bKK%fUO)lz!^wSr2)Gz;zt z7}8L;_b?9Z;OomEq`1d4}cprQAljN#$!Sz8@Qu2Lr|ZfSJ}PNDl#$4*;&W zq62{NP@q+iZAno;m7pvNm~AbBtS&&>fk2Lx9tcDSfWSe(&6au)P%Eeu%(38TAh#=! z84cWO6@s`hAgVtw*E0G84T2g$o<$A-3d4b%0YJW03lbxM*nz-ZmOT(?7Ssz0EaqUK zq#IChFmSKc2~xTP34?%nmOlt+6Eq3#xA;SV@*Y6(A;5fV6r}eAk_Q71S=3PApJr)q=zWfY`%0yH@i1VCH44(Bf#f5BSFGqrAiO`&DyXoe;Xsw3 zY&h_mwFt5X0BJ`7l~#Hb5IqnGi~yEd>Ik4#P$^h$!AAqR2LqW$18-S{AZ`#4H4<21 z86$xPL5*OgMIHkb9s=YX15{hJAaO7d8xOo^+3`TLpk7d8F~vN-8BAyIRO-B=-m; zb2PH4t1Xqp#UW8ABAdI~^b?T=NsVMnSL=HcQaB9BISFa(YO5rPM&oaDp=Aa()} zYS|NjWf|OA}!bBj#@+Sgqf+j(Ci=PCPCj!NjfS%SUNFNO( zPX>Bh(PSX}M4(j=X-Q`QRf4iJfPU5@$T|r~n*u~x=@cOPWFT-RaFC^*3DgQI1^q4f zEFgCbka-p`&?*FRrvOoB1A{E%Y@k6z*$z50fe6o zv3bHL} zCQv0Pn+eRe7D3iUK-zUcj+I^qL|+U9t_NXSVUIJv^0NiR7g1Ae8 zsBB=aWn=>lf*L`dMa}{WF9ULB0r^%fNX!6YX9IUx_H3Y8P%kL3m>YqT=|I7az`a%{ zNVyzH$N}bAeh$zkXcF9S@izhGR{+H~0rRa|)3&h?IJZssv1I>bZL7Bzm0VOkmf;?cc)d^Cr0}}24 zp11rvfHpys;6;ni2g-#AAO_*J+Yz(ti%B^8G;9umoVKz(oU6_5SYzng>#pL&4c8hXb zm~ButhuM*jk=w)UPSV=$)*w7a4|j&yv4)fvXcP?D#VAP9??IAFke?Wb5+wXyq*cc5F-dtTAsf)^75Y?@-ARVWU&h;m|(Wf0czn2xlZ?hI~U zZH3mghrPYH>lylB@jNvWOQ;e10yTzO_6tC>pk5GbF)z~8;WkHcgw-kHY}iZ0Fv};b z?QtFMOH>}dzy0!sK=Be_#C}MB;y*haX+a5@;6G3z9A74WQ&Xpx_N)g4GF9%7BDrz(mVm2DAy9 z1d}bk3Ml_KP+SE}u|`4qVjy`raF!J<2g1vNRza#Iy$Mta%H9OdwH86v^9OMM%t6;ukQS?~%@&jmJ3aiLWxF0zPsh>I( zK;aS~XC;tf)q=#A+2LXDvctoITlSx_%1u$Yg4k~e{ZkAQovPLT2zkgyJzXZh=ZHbIl% zevAJYD1RF${ur2Vje_(QK=OLvAuC!Bguer{3W_Z06QD{^_6hK)wFt6S0%>(Xv6a>V z(eDC*4S-qd2B20@DOg~^p8~nnK<1~wLaPwOtpcJx0~T4vXF!9XM(~tH)&qs_0Xg+R zsZ|RS-v?qp2cEU;&w*w^y`aouz5q&UfPyc8#a1Us`2a|00G_w}2B1yQBzV!{Hv;9W zf#Qw85^EHs*8<630)%McXW4``uV;0ABdcpHW-Czg2~e;VSZ#HJlsX{cTVRdle+#q;ngnYt{yU(215o@O z?@;T)ZR>ZuL#2O;BsU@J!|jnKB>Xd^RZ;WIvKC}F<0HxX z21)w`X=QwVL82Rxz;5I>#%DKDE2)(1Wqf``aE1^q4fZyIJbD6AF~H00p7I5mqNi`2|Sm0t~bK zEw1pf~`Gutq`puRwBFV5Ajw1;Sf_RzbWag#lH9vM}H{YY}Aa0n);O z1S<^(qJIMd5x^)*jR0x|m4eY0+zrTW12Ve-Cs~CcZZ8nk9T;O7-GK%{jbN-r_5cch z2XcAVwo;n>d0~0O3H_#?%5=^%E zK0x_jKye>niZu$-{|1sHfwQbAGHhybco@T>a;hcurCde1tS{wrt%b5>1p{gQfHW)Z z2SkSefdhc4mU;kCE2tDqv*0KoHx$U!rEsBD2;#Z`Q3nDSTgHJvgP=xmsYMWj25JSBf;kp^D3IF=$UGFd)hYyWy@9A0V6J7v01bi~L7qhp0Sfy7IYWSas}>|i z0K=^?`tDwk|;(#haSsd`FwFt5f0@8*7#a22Dh>ivVM*?Q4M*_8i zO2GmP9uDO82Qr5P3#~#BHvot_3Rq+rM*$6j8o^T*IRYpg2;__aO08OucrXxqH1Mot z9}P4M>IG#MGZH8n1Qd(}7F(SlFwj@S3#*N0thC5Ppzv@YClRQ&YC+-=KqGz;nl zH5PLsP!b0eoCvJ8Izh@XAmJonjpd&Nv}kli5jN{Iq*+ogX^OBR$w7|_tmU=KF3AsjGW@ZJ z!k*TO$L|`t?@<(lawBU`K!lFa|Yfb;iAKU+)`W^besowK$ zP!NAq>W&BY1O-K^g{$`O|Iqni#{`bq8x+({c#t+;cEkLz9>JkK_XRD>doU~^xc`9Q zVEymh@3{Qh8Ao3|d;cF5dIgKHn4++4+N9@)D}#dgdmwjo2?PiA;ro=Z@duvIqNw9m z{NC-5qOc!BF6h3j*CS!wf&=IFQ8VoM*7j~c@hAs5vW?y>%g7JAFsvO{?ZPJEZ*pmnA+E_FQn!-50PQR=++y zIH>0`_ILgMak}W=>~Pg}^i(^1D4@od{rO_pVIhJ3kI>?>q$k4O3+Z{otjrs4oRK-J z@yXy0E~w@{{)c4lQm!F#Bc&9r~pUD}WK=Byc)XVKK2Zwqkh<5Gow+XT>)?=s zBbOb$K5Se_pf)-rC~{fGs<7_CcE<*`%RM+`|M5Pn?d-BE!wNOFx$Wa*N1YXRql$;M z_tH9?yx{A?t`F{6oEj2zFh^cNc2k$`Y9I7&$ybK7pR1)=%YJMOTN(%qm>0rX;dsAj zADW(TE(~cOvX99__xER6$q!-22ZuC2v+UztVYl~+Dc`)mjTNi^`x?)fedDa_M_fC* z>(?BHvA_0D2-P>Pa8shNwkz4k2kMNy$FFU4h_`b>d`g?-DCWY$j)>~BX?!bS4 zy(Gl&_w^-SH3qhqr~g-Z=P>DM!z0%3|7&wuk#=NAw^Q=|`g{MxFagEVW}?56(_v}UHfps&3_qWyoIFa5?% zf9QdHDjUdKd2{=>Mic{ ziu_OfgU)gL0n-t4ii6JJ&Zy-d+cyph>cjFQJ`63stvXWT_KRCz>>0P+Zu*-UujD!Y z3aVl59YGatd%U9lFNm+X{pNNc_PSe}Z+j57#_e~n$4ek6nmuW_|G<>}nR{UrgYts? zkCyU62#Qjdm_pn%d{^llFolv@p7;kSBPQ796y3SZbPuknKeba4P`mq>-FWkx^Df(^kbCJFyH3&j<$R?G199KW7VC$>KL~pu@9Lw#k&n>xxQV3f{wL1HF3PJ8Ue5I zRS9lKQ(onE0;WBTWPZ~vk$*Zz6Jxx3Jp8J!I>qf+${)LpbvusoVa&R=Pql2C$Q#Eh zT_6d}AL{C1O2_otJb^jcuk4GwiBZ_?xsZW;S6 zFX$xjLdVNN-2hHzzQ`@hHy(ps>~^)=DcB`$*J3)&W0@~?(}kuTpUOPlEgRE?n8ZA@ zJFjU?vp@~XIOglT;_Y5>JeKX2hpB_7G0$?l+v_D`H@X#I8o|?<=eW)DdK0kQ-0o9@ z>R}4=T*n8z;zTUZZNAr=gymzp={)51CbN8}*L&FQ4D2qqBDX2n-ENOy>R{fPe7V>0 zF|T+QHqXs44eQy=h5nj<98;%LnWwou;q}hJuEcZ)d_)3DRr-t%oQz>?kG4`=`C z&4tXTJJxu`i?9i9A9#ZoV<~R6UhfiYqT3p`OR-6AAG%$JO?F%BmZ9T6!|@}>>DUyv zb#9kqXS#jtb_I5p+j_T5>}~#{M2m*cAnd3ZdYSz zZuM^0VCTDi?shFU)$I$nnOM48Lpb}_@L$I~&2ghwydJy2?Mt^CunXNbxn*M)xqam} z3%l5Dv)gR!61T72Zq)H#>bS)*hl-cEedBf$mf_aub~85JZL3=@cDdWPZga3J+`e^nDufSNS@{O{>`#p=CV}mK)wDJQ_$T> zs6WN72FsasXOqpqG=$GH>)gt&_IfX{{5SP9UF-E;WLf7{(@eLQSk{e5({*l3SpFf; z@p{LX!3W)LaC-&Q`@g1aH+|aEwu8u7m^xj-JlE^p=(ZI5o>M%Syb04a^BVJQ3{ec3 zH{Tn4ox&tP?+?0FVrRHLORxI zKrOz-e81aczVX}G-#QOW=C*?6F0GhyT0*ynZJ(T!*o!eFfUarOz*qZvHZGQ4W?t-z?|dTuJ(GLV%J5szyAdV z)q2Ix!0UBiW%|%7*0X#QHkw@Prt_PH=^KiV+`eEr(`}u%*MLpOP9oQPJzWPGZl6T( z`qzombq1U4WfTZgBgG_j+5fv$0di2Cw%G z`wu$Haidpk#LmFRlAAD{&#lZ;+`jgWzr~KhG;MMFj^%-F-?%klqud(ZzQ=y;#raQS zVXNadmiK_NZ!zt-nYnxK{q{Y^y(DNmb1zKO4&QbM%X`^Y(@wXYD)_cPxcvb2@ojfS zaQ-#?yO=|~;*VbOM=Z?kC%2!l2)Ccze#Y8-$1RvHxEAK``|yQnx7YiH-_KYjelqPJ3o@Y-2TA6#3qn`yZy;>o!8TkyflLQnBT%ClEIix-CxY_c)c!ee`ET? zo0G{fZ2!-cXyGOB46vIw$WQTu%6;SRZXww7Zav&Wu@~KXVme~|zu$_mDJ=KK)ER!} zAM~hOU$56SnB$)ho=JrRyumP4WVp`4qTIr9q1N;eeE}ugWS4d|K+jYBTi9-l{{T?E?g>8O6%Tgng)MSB#5eAZEpQv`#xE;^M$*Al+Bwv>jl|-; z(?h&oU+h@7p;)NSe?Kq^JdfqWz2X7b$yge8gj*DLs#~0!-dx7H4RbpP8}D|co8GLN z51=uo;cor0yp?_=M>!4v^|w+qjleWA12O%)M$<^IcQ7{H?HI2&2)n}VSg&^omWfSe z+vD5@V_{gjuK(j54+Y2T?TjhGEe1<=JHbtF#f#iVxedjhbW3zQ413CLv|B9pwA+d8 z#`qr&mO7r~6_3E4aXZ;94tvgRjGNx?|Lt~)+mV>LjddH2Ep$88?I`T-JjW!*5nzGa zIJcv*Lbvg5Be5ghPIEg3>*JQ}7LNtoPIo&N>*|&_!SOgS#4*L~c;bpQZlkcnv4`3A3{2NiA~wYBOpHq)FK9G4-ajy$?;D?pJxrOmDBU>29ZCdZW^Gg>RdT=}k^kW}f5eV6$(0C8k^E1WfPYr7X|z22-$` zedB9<+lkl_Zr8d^!iHeavF%LkKyos6h}XNz>*bvR4)uz6JMtUTphMjX+|IC~`NeRMzKhlO zX^**Gh`sH1ICHxQdkd?eUWwbq*e#SbEx>dgU4o5J511Buy-W4;muPS~_=MwS7{5Dg z|ITQUZ=8X(s1>HCyxw$---EVKPrF@?J?>WOb_I4Crtg-X!SpK6#9n1?zy6;Gwat|P zzsGK$Ui6KxqO5be3Vq2fi?U9OrX_AODC;7AAA8yDYRY=q)?lx=T|+sGoqd44s`F1d z=vuxU53Xjpf{NgwQ-|a20myO-! z_O{!sV2=M@a19%+aGXuW``q5abjohT9`KE;-Ey!;+}_93>6@@(w+}Ggb8f~SbNdjZ z7?jHwlWF|d`o?p>60f+4>4puzl)_`dz`Pj3VcCyLq-HAQt_7$d4xC<+D<2BxHcVqu{`^K$6 zpZ}hU-v1r!R!}>+hl;KK0i+3|7<4aRZr3f0NjDtTE5r)1wJhs~Bb$c>d%Yig+xxIk zOyB+P!qmb0v99g)82_KV;saoWZ~U`YoR9VJjeo)PCifuL+pP`LjvvA{(P@1*{fD>r zF!qhxpKe9iS8n@cI{*B0lAt~QN%k+V_$c-pwx0EWW9s$4ur{w3%*~2oP%&Tjy6FZc z`@d*=6L_1d|NsBE2=@}oJQR{t$Sjm8RE9KAQHCTMsHBqdm}MSwWS&Bqqcl?)N@c1f z5oKzg=Rv>c^W3%Te0-|k_y7C-f9LUd-nI5?z1P}nuW9dd_I~d>jX%EzEi0ON6KJmn zEqkz=juwBC`LYXxQ-b&~Vwqr=BWN?wF3FwwEjee}G+)u8c%|a`ipD!_J=|P)~ z_8OP?$I&u^<{I;QrWTLo4&q$Ij69rVFw7IQd1yuXisk3jpv^}+H)wf-wg9a@+E>`+ z3)(`ohQTgBnys)1tx>Q$9W8lJ{}IHhe7EycC>SnATS?qc5kfX&OZc-kXhjK~+e^{b z1+65ZW8qP>r-N3C(7ccFXKBz%6PkA!+T+pvy|aVia>S>CVY#5KKwB2HbAq-K?a`o> zC-mr6p)C*Ed4%r7HGWmlDiOLmu0dNEw0JclY{wqw&*~sn4~A>e77+iD^xDC09a?|- z&QG17J%Kg=&2PGO(QJh$(JrGq{Zd;m*sVu7KW@67L-{cMJu-g4QQ!okHGM(aNCZA?zITZXydxC&I`P_Q`3buR!#9XmM>~!1&S1Blc#WXl6|@~_P0oFKE<)&Ca}RhI@w^3D|BDgvwmCs;H-AcVm?a4B3)-8+&q6zc@cy8^6|^%6dk5`p z;#b*3d>#ne9yA|3@zW=0@1W%gT3_$~vmM*Zp8_FszhL+-T6q@yT7=%O*KQww{29iN zx9ip3<4-o0Xg>pkwja&Q^G1Yrv33Xe(<5ku&}@bGJ^zjj1r7;@2hp0MH7E2QK0)jd ze;T5-AoL!-+6VmcxBZrc!_hdq#y%wOiRvoCS;6iwaZgHD6V49W5#qm~dH#vb3F1*i zo5#;wG;4T_ZP)VFg!6;lapL~a?8o&%yN}TPLE6uvVD~YaKet~;_(;$`A?|slE#cw} z_D>l5ls_IxJHjO-dL*9_&*4hK=Y^2@bJN`$pABdxe}Q%-S{K5Xg58(IU6gKtmxJ~d z@p;e{HU;f#&%fQtd_HE7?VT^Y1j(5%<@XjcVo8=7mt z4`^4T-9@-P0S2ck#v6Y(~|aCa#1XS8dB_Eyk-LAw;q&z?}=uV@W}_D;}# zL#vI}i*RqyekWcxXz!vWfB!pySSN`4gW(@&xzO$nj!$UlkLF4B`G>Mi~ zNXVOpwi)ey@*WLZRzbIrr9tzBkq2FBmd>jlZW>+Brchhvqqd7TUSV%%q|1;M!m|+Ic}Mk5-(E zOc$H;gLW=jv2Zb3A!z5JHH{;BrCKqF=ObQ%wg|0K&?=zSMXMOJx<3t~OQV&PiPLfDMe=g%Es z$1Q_h1GMYVyyU(jXbsWY1+5jDJ8p#LiOSE_!R`_?PgJYPdrdru{yy`1Fl>!xe>Oq$ z#G>K#!LBJk+gYgBEXw=%x004BH2> zIhvQ+Y8`^s0?m=`rFqAowM2Uf&CBpkLAwHN3)*vNHwCQ~+SZ_T4w|Rzd%gbib8`@J z2Z-Irob^(=OVF-Hdp=x3-x9QI&{lFm=@oKUG?&}fXsd$O1C7n(t^CzNyDQ|qmV|Xd zyE`}gx2dl~9EIrT-jMlvw9!GkAI&phTeLAj>xX9Ec4%XRW_Q}}H=vCV+K`~#h&BPu zOZeev1hMvU#Qun0!;c6Bc0fB1&1?A4XkM&#M5_?A$suzmw7h73rl7gwo6x+R_Y!_u zugt@{`6BIGmx$#^um%Lww^zp0k0t}kLDThDdL_1)$CUbe46;HXrBA41nn8(+k#d# zXwRZ;Mr%V@EojdXA6kI^_ky50B0=nV{tUxVttOiN^aAlEXkHK0Mq^6HHV~hK)|RkQ zC~zb3E6_a8UlOzzi4R3|4?n2XUFMp1*5>6rP8Fun6@nb>j6Lzu>?W3Ue4cdEX z9|x@;n$vi{r__~*QwawJ@c{8vLG$a9W8r<*$m9<+&QHuWJim*r`MlY;gE z@v_*twEL|}yAO#wW#g{dQ-XMyc%!h4x`MG8JHnq!gElSL9YwnwZ60AFXvc`R2-Ns74Hds4UX4}CHQNfPeN8+YahKv1gckS> zaZe&@Yl7Xk#Bbw3T%I3CBZz&+pI$**7wo=AyB#fg{r5x=e?YubkXvyop-!w#Y(b$CO=>MH~ zt)OiU1)f0jcS7x63ECgTZ%1=2cs1m;0C((^d>zdlXF9m%H$ z?QG&_g@IWB4f9wzG)KP!v=Ex3{~Y4i()@OHiC|Zr_@FqVt`lbjQP+xrX!dofpq)qj z4mA7Ki%7faeB#}Mb`~0&u?qZgC-!x@VCMrz&LaEzoS;=A?iIFO7%v~h3)t|Q-Osr} ztBmFsO#AS>pj9D$6wU5BKWJ5n9}8NApjAV&kL|*WL8~4#yRcHG7LV0nV=9JzE(nG- z(fm=uPvxN13YqP$DnYxDc=^!$RfAR=t$5H}#_f_iXts<^UL$CAlN$YRlh+F3Ma2CE zY!lTE1zt?tZ!We_ouJht?$Oyob%R!)xW5DVxhQB2&{hQP;-ED|TNSi=UjN&ljS%M` z+8XtPb_sER4e`?;XpPbQ$;B3G7_=tD&kIM~C}>U5&PTI_E(zMD#Qkl+Ph&J&CVm;> z21IMxG#Fk^++QlJ>7~I?-yna6u~L@@yXM6G8OBeuV5h&(%V_SbMX+m0+#ev+S_bV3 z;{3>QP0XEL5yV!+7h!0@t%7zX@kfGoWzeodvzy%6RY9AcKl8i$p=OEkP14IHRyRrS zU+GmYg}jg70%U=n;!@+kpT*l3S%b^)GKRwZ|X?mqBvl644rq{~9oU&KKDp(C` z61$qF-*txXJ;)B-IN$VuJ3%*d-OBIHxxT}t=|5zN>qy^(;(h+$Qm63#_rfL@=w?J3u z2DgH@{BH;E@_Sdm2iysFfp_Zlarf?gFSr-H0q+fWZ?Jnq-5cnA!TaOh5BL7}K!}6) zvxk7UtB3ic`fws6;XxP$qv0xArL`Rbd$~TGKr;@5u`mXP!+3ZAhJfzoBVYjB198yZ zybFwi4$u+C!7b1Ru7Ybd91H_Nzw>S|2=F(L^?}jQ7rH|)=mht}ZE!pE16|HB*0Y(24c zyw=fL$7&s^b)42wTEA%hp!Iv!&so1_{g`!I?gY9e>xQh`v2Mn=6~~iq#JUaZCahbq zZosgB6fuU@=*?dqkgSFTRDI^F7It5dB`v^ve|B&$!XKClg;4*W{j{RY3o3HSp% z$z_2w$a)I>{{iCra0vFnyD$Z&!Za8L!(jxBgi)ZgY+tw=dcr->3%=z7w;SQD&>osW zYq%a-LJPPC+Cf{mAr=WLWFT4xu;0bsV*27cqG&~E>!87nCtc5i& z8|J`VmN$?#=``d0ux~bJP3N@4ug@9i_xnmZcctu z$O_pY>BUW`Z?lfJdW7d7)M;LC?p(xmPuF1^5B``A`@ev0=laH)Aw z;RK-$uzG6i7_aZSey$V2_g(1UItF}mgKuhh35LReoa^hfN*|pT*XdCw$2UO7MjaV< z!fv>P#iapU1iNVp{S@DYEueqmYS1TfEi8u>um&Cl{SxnoJ9uvKZdeMB!U|XhkHLKX z6o(TT0i$6IEP!b+8wSC6NI)-`0fV7GjD+RzAk2eV&=ZEh0Js+x!$Rl-6JR3rg(c7% z9?8#?noMLm41_r_1s;I0un49?KbQogU?$uHad-%Z!Z?@4c|4JSPPnd;lN9VbIM_x4w_yGx!|7fUjUX?0{Xc z8{UGqVK2N3TcH_+w}3046DU@A-m z9pkQtw$Ki4fE%F$bc9ZD6Lf}~p$pssU7;K3M0XHAgu`$E9)bC=0v>~?8*><;b72o*>U5=(l}=TQxlGUPDfKW%dIXNcSQrQ6VG!I8z2SBk z&FNT&s>`4*l!48hSYCy*p#Us{#V{Er!6EWv@vCdbz3hQun1azL# zSt_p6(*w{K?uT>XJkaq;r>637CX|IEOdDMXbScnhNtXd#1U>+L5A;bm4s&VRc`zUH zkuNX!T&g$9--Nf|ZP?>;O2wFJuVSEIx_;>To$F`59d^J@c$Y%;OPU7yBI##z7x)Cf zzZ3b?zMk5?Kxrn-g4r+^=7Fw7w`1A|bRTL@YjuD&S=VpBKD}I)xQ;G5w&=(*97ezx z&^Ki~OagsUrodFt7e(I_eNA*N(UnBk5#2)OfnFbadFXJVgT)ZgS4<}g9VGOJ$OB)J z{+Ul}G~x*KRnQMXzk^>uUxSa}IBW&|47NdMj`Swz2seXn1&3J1uO!}-cw@f7H3T08 zY67j<_nVZz8=7GEB;De#eL3MQmgAy%nFVJOIUlNmZU7aa9Mq(MA29R>w6EcN@RvAU z0M2BcF9oHc44egJAuBt{4iB;8AJ{Ge@52W2Y$H4uDnLc31Q+;gO=YM8x(rlQv zrPeE9Ev$!iFc+SNrSLdB1&5foEX}OoQo=fYC4#d{+Gq=ng)k{wx${#e0&exgMT^pWtWk zd37E;k0+lqKZ^~YBY%^Gw_q>qhguZmk01@8DDls+@ri7o!1jr2AF$5Dbo!VD=@WPW zs<2*6g9P-0JD@w<3~eC`oS?k#;0J##y_Kn?7yWOble|x3XF*GYtdI?|gKz5a!Riq( z9EL$9s0|lDRj39vp%z>U#lVN6_3F`8$a@stGWM|)A5nfM(W8BOj&eEaiT#+af+gT% z&yT{X=-J_Ej&(uK#Ekao1LMv45z&W>vOwRAv>f)1{7lV z{-ELGwnaei_`;9}j*{;f9EXqKWAG7N{RbDpeDKLwo`j7jAAR*vSD$QMfuT>I{!Him z1e2KAK4dx#X2BR}2RFhE-~*#qLL0aWd@j`IK(7Ix{cHs-pe2+8pYuEod_2>~F~2KF zhxxqa#|*7c;WPLgcEB!pg2{In?xB(Q(sJ*BPc(bSq6CxBMx1va2Nq2;XxP$qhSn810T2C zO!zwZnB_TeE}Rb)z^5mDTGE@?-We|o@pGxM50L)BQF%Yk`+44On+#*&TGD(lunjba zmf#c4AHg^99TaAg`{S|?CUzmu9dHA@O448F@l34;;Xd&Bt0qtYUS;R{ zW|}$i zuz+bX7RDt84@@r{zlCU5=mT}25nKcfpguH(%iw%C4}3D`8z#<|@Dvm0X?O;nh3DXT zc$bFR4>cL5kJBJW2#>;27zY#Jdd4zO;KXA$5%I~H3m8vTp$_;kj1Rh84q3q;y&p!O z3f`yi_JH>xe1_D=K0CwB&;hEW&tr(qhc_4+pMt+xU(WXT4h=?uuY+1b#g_W^#atx5 zK<_+5xB49EBzmJGEvOS~Pa5nV=mp;H&j9bp=YiJH67Hl$Zi8;n7%D&|c!8GK024Xd zNiZ3_x7`H1pWPCw#;I{VYV0rWy*RpA;4R-JFbBNHya>Es>^keAP zJEs?cH%q-a>dnx`&;+iAiX3q_j_6jn4ZQv5PyF5@Xae3A@HRkm@Rxdj>A%cxwf>av zPy9Z(;H|)y!28kOfA-$tCvZA^MWsH2@4#Dp-qO1t27q_%`h!pA`M95V;zq&u96$pq zS074&H_FOEF}NI>7N-AwI^u2c@hx1-vWbjf{nG4O7QgH(v=W7@U_9 zUIK-n2>3SS)4_MpcF&pk<(Bj_;twz#2a|6M`0`WVVcHw|@%^n744@l*?VoS?^R0fq z#qSVn;D@k>eVmK!nNR}CKv_5gZe+dYG(O~lv1 z-3Q0AtzX>LFAKYvb8mvL_j(5|q;`8LZ7F;Ajas*XZ_&C1d`p&Z#p(n%Ku2f?ZQ(lb zWmdkt%6C;=0luHg_fcI#?R}4wuZ{9GQMtiaKKRCox+iFYB!bHr2N z4_2NSEl>d}!Ugc1=O8$R);K|!o$zPE9E5)meh)F?zYyjmOouFx3)0{R^j{$>@gE7Z z5&lN_6L`O|V4R)Qg^QpbG=N6nt9c%zhQ1Z2E98KjkOh9{5_u0?4$WXG%z}qtJPZY2 z8Pgy7z#VWO)P;MXJ)8;kA$}cyszD_<$|&3i6^Ne;r$cVY3E3b9zmxte`~R#Bw#kY2yxgBli@x13_gWtV3~IzmJ)dcM#6X)3Im}m_-+{A1@kk_b}>yhj5-X3 zi`l*iqV50lZo2S)-%rs_eAmnf=l}<^CQiL0y>rug%)g7F0n~?vuz}h08kIZh+yh_t z@)7u!mOkKHm8XDjUO5X&7u*h4gHwAxEPyC}2`h6H zPt{M3AEY%ughQ|kO0(4XN`gADm($E^l=%j{4!PJ)_X$9sZOIK~S#K_aI#3E~u+uxa zHo2U%`fU5^fZti8eg*Y!Luh;+J6iz#D0l$)aOP$3KJm98b;mEVt=swrSQzI|>d~%c z`x+*~3c{5dq@+Jgd?wf$Jqcf-d5_RyYZ#j+;6BzlJ;qCe-rptRJ@lH`T?n`kP-r7w-BOjF2Q~NnG*5OzYl0j`9`a2l*YKScT( z=uZ3?VM)SCFoJj?!Wo1aIq3g%Hiok?7$@&M-vHEAw$vU0>--zvF5ba10fL@S;G|SkSGf}B$df#|U_N!O0 zUcfs2>g3y>8Fv|BJza>!od&+b<^|Btb_3*sxiANY!x+$W)tB~W z0X7}MunqFvno#|z!SD6lD&TAdQ zZh&^+0_VCDt!tN~H3eI;1ffqhmV!sHDMnZX@`Juz`f{C(U3u`uRJdZrlNpz?u>>vx zGp;3^0d=4mOoGWU6{dkUsf(Zv1v(JC2rt3QunD$6WcN7nwJF;kL_5DFwnyv;ouD(^ z0^hKx`~bR1{Q_xdx!B@N40WLiTmZU4rLHx_*w(}8EGP8skE)|c#a?pk55m*e5!XlUr zy3x#qc`zLwh8Zv!rohw!x3W?aIk{k;vAqZ`hI&vR8p0*e1gb(oCgM<+ew<(LtM{RsPlE;NH+Fz7k6o^h9Y0{pju-Whv6X7rG0 z4;?_y81FK>oUpI>pVKq5Qke-CQh}=QD?9rQeupUCnbv`{c5oeB1FgUU4`cT}7k3_!_{Y0uWj_>p*+sb6tN#sJf80vwuZZ-z`f-HlXZ~;5;x!-Ewpgs*P z8)StT=$?@UZX>@g7}{7)H1M4uk!EE#Lwo?Eejxl$#@Fk#R1v5Go#AG1+*O0>&>Gsn zb#OhjgB##R=l~tTd@Vvq{`kKZ5M^#cf4&U*a(J1jtA>|~Ucn6`jQU;IjBXH(6$i8V zyt?a77ytJ`(*GyVqQ5(`d}KZy&Zg%7G^o5RIKi0s3XuS|o7p$UCIF=#fQr4nkK31oGaxD>3Kx?u+C2vwU^Q6z`Ji5fe3c8wE=fK&n~SmIbFr1Us2;}bs7QD|l!7y%I5Z-?{Q91Q(sP^| z*Ud+}p)dk`EM^nhE3gGN!^`jzya?;yQJ4YKVH!*U|H)x5xE*vA>_*rXy1)(44vN5a za4ocf*1CfEWAfGDfln=o&8dpb6y+1F5hhaL* zfpxGJd}bhOJf9sH8MX}{ht;qKR)BXVeY|TC=tamjKbi(nUr1fVP0%Y`eF>N$(v4f- zO3LN7=>r#aq1|U6J8K;yjt#q2EjOCJmZ@FrondWqhR{6PN1|QcvPs{r-s6#f=^>RKSX1wJ_lTo?E(;uqt<8@$y*i8_b9qOSUnN>xrt zsY{jr&vi-kn3G;SZjsl6)imA~>>3ZnQ;V8(f{xH0ZVaIhR(6J);AU{3-$EE2(yhdA z4To_XajO`m-ATNMr>yQo?f~1*V|QmH#O{Hfa2MPSrkiO1OoIM!AKVL$pWe_9`a&PL zAJiTI-}7TUvN4PsXw{ zPs~f%<~U=E31^11*@Uy8N@P?HLo>}qoCE6e2=Rrm2<912Olq2bdK05A#=iJ)330Qo zC43xK!Wvi&t6(`SgU2B1e(mQc22bQ)@UA#nCdnc+)hr6t{=SI#6C`;l@-(3;`&PJ{fA4|HG33)w*zrVRLv@=hVty(t@Hg^$pVf{%asVCPT7 ze{>LkN90@h2EK-`;7j-bK8GW42;PI;@HQNTZSW!Nf@AO*d;;&oK6n@2fgSKVyb7MQ zUn4ZH@p=xfXyc6_ZjTa4+e6%)YU7Ty*$EbyEC3s|XxqZA;F}PYYxovK_K~h#JTkO! z4fYa728L1GqmSYTi0@C?j`S$BsgHwsw2fNJ^6dg!))u7#@noSkk%>_O8rkd?5bemO zwn?=+Oc>do9GcG~Q@2~p6Lo=kC92pq``>~i(M%tQOp$Tw5quhKBYSsbi$zBm^||R^ zphp#P+p?o>`m@sUlf=}%{DHLZAu^7-D5{vcnme%@e}>5Rmz4OgA?~;_@9%`p5aaPE zgTjd*{t?0$(L`KohqcL&vK(fH- zs3V)`V4{|YcAC2VXWah(b0gF)+P2>cQmLqd9*~cKQsCNj@Qw1 zeu-;|d>Vwg#Rml8IGCQu(Pf%nn%9siK90ipk*v=L!r&_+!g zLwD-FEO!>#Cb%*ilg*c?w?f>2a31k%h+A_V)~&fm=27{pgbirAdeoRvygvC0()a~H z`-c3K*ot^sgXA|}#ycafDVM4p{1$Z9TLXDA#9)bPy5Y%UT z7-1X+!o6S%^nwo19{wT0{9T30&|1$RRg((WO&Gi(cY?CRK?_iHLwa+z%p0@7V;Qa z&{B9b#4W=-hATtdZR4xMw()1-Nq7dHw*Q|ZvL2p*b>KkJz)&s@p_=igVcWFl&|C@z z(i$6y+cLJ2vpF|>NBmpZ3}1i;vjskbS756%bQ9P_FT+bs^C^4+ z+I;gp%ZR)6xY;r4SQ}2YR>5me3>b*~R z0PL2%uphM92im^}@4`C}^}S`e&pnBQQ-H^QuRA%&%sis1+TYzkzn00RF?*A%;&Rdvk0}Z1$Ax6sxO~{i-QF&qr9DxgY(I?Mdk@G?#5(Pv8rB{8tJt#b*%rr9Jw| z6on#C2nzeiUIu5Z!i2@3xFVR*CAk#w(r_j=YUdCiiEf^9#LtGZU>;GwfUpu&gmdA1 z$VT4t2)zjNe}h#B@x-uo=>_7o*s2LNzzdJ5SXC!p4XQ#FSdM-np{02xRF6=fh9}VL zv+Y|M>OceHx&v6I<A9DE>M|CL!V5qt>Uw{7U6;NPp z5aO2Q_~=aBX;K>9SAW?;_n;LfUPz~!!EAJd0tlx=g7_aW9P}@{7n~~Hp%1hN3pJ1F z?)U-lKzbA24$)4%?s8|h!A;N;?gq>11h={fm?1J)LWUjLwDqn zM@P|*cwaExspoVa2m|2cDcv8mkHVbO&lf!KPKSFNYCEw*IFe z?LAVzXF78tJG(OK!iR`Yg^}R6ngkP_|Kp92=|RFG6yksyM|>1Gz{U`chOuBPxC5sp znPU@RGK|O0?d*h;z@<)Y3feeAmsS@f|BKu-;)e4Hm-_z-<`8L5VssSNekORNGYB7s z=|H`bkA$dKXWM?CMK~Mg!aO(uzrxS(6MP1iwE($a zgvVehEQCj35iEhl(3MKaqr_LhGFT4U$n&s?^k)g52JN1L$6*buhbJNa1b^1ST6hMY zgJ>t)h`$Uk!HZzQ8{h@l2=3I1y$bHg^i3hYnedem-$J+*_JU>YfVTkqc+!39O*VGI zYw&tzLegkE@i(9XP3KO`XeD=nM`hfj-VL^vJJRNDurlw!9&qQT?Sps0G{eW7|NDtF zvo8p3cAGnD`h&#nC%Yu-9=j{DQ8T~!Y@rXqirHB2~G1&hffdzV0 z7IqwtLevGvh4l&3EzIM^M?kgCrTvo#RB)c>1qjg{+aknKWHcrXK*kll=@Z`1jRMKt+Pdpbv ze)PPM50dMDK_V_Z9>r~N6L^Fkothav8f$%W3-m-U2HM_DsJ$)W*{&<`s5MHl-H~li za<+)A(E;wY&@&K=fbs5N(^#m56(uYV(N5H~F)V>z63zr$#vMNp(kw6PDt}HHf_@X4 z%XI1z9k+%a^$jFiJC8nDGs5fH_O+e*wVnm3m2d}E&R2Uj#MakI zw17tND&wdjVFRdlN~~$D7LkjfHdKcTp(gm>U272P8K;A-XTqw4RX|TU3$6^EvAZB~ z`G)l3B`dM{B#mJ5HON#)WK!J?b(hBx3G?AjvKF#Z)E%A0o{qT)EO1cvQD8~*OI8B&Wz6J z_fghJ;sgAd>@I|x!I66>VGrmIcfjr7D`9ViZqOBOfi9rE*B1XbVf>#8@Zxe5^nt$Y z>;Xt#4RbWTiTjVeeDADR)AvFzxCdNoPJ=$gy+YQ`%Q{21owlwsw%Ab5kS;OzqF3`{wvJl&j+*1k7kotqbb7-}&sR;w% zpDx2UVCT}~T44E}Ui-w$uXZt$wt1t%}; zf-kYT9^2xC+u42tw!z(OZzkLXcH7H@FTsnj5w^gq@QQD0+)Bhj%|+zU~&+N8Fkqx~)7?|>`o+k|_-uDX_ed7xilvolV_LFUg} z?$G9P2S*7HgGYJ%1_)EUgm`l*ggP1V0S9pzK#Na@Yp^yUBYuE@^9f4 zNxq>X2Q;Dx-;wFNGJhkBZ>{)@unBrr;_s5}C$@cu<{yN=!>{lQ{0!g2cknHI17E|( zP(M`dE8^Zy`-JdI_yRunbmC4v1rr-!EYVFiGZ}A)_95YZutJR?I_8tp{?1;_wlJ@8 z+s}46!2V;05e|Vzmzo&GZD@_7LTnx5QAKS~D}N#-zdMW3QkHEz3-LpQQJLB&_m?w> zO%f}%(i>LH1C91&*-;+rVLA3x9zq+i8Z*sBjdP-Zr@`S$W#iF$FjSQur z8aQ)oBhn;@`;d$WO92}jL8&3{h3o^5BhB*f;{2)7V+nuVpQ!Cev zPw=L0)SmRpOkCe(oHIT+rRiFgDSSS7?Q#G0!|m2+oN zA%<2s3bk|F`KT6ctDVkvv<8`$x(1!&?}^cor7l9YKyncxv;v3Nxsy9O>i_AgbP;*~ zZB>f@+p^@Ee)14<$fas0Z$}5C-UwWc^K*WZJiEj^k2R zT4s%Df8Q^T$vh{&R7@f(>_Y zC1G@fuvLhs?$p8?P>`X8c81jS)T8&LXPKR`?F9bb?C;EKfBt-I{~tqm0X(n!OPQDD zUaY=s=1_?7j@Y(`8$uyX(lWQbPPj2>+Ii})Pd+QK7(DV0q?_ic+Uv%f*j9^s0TC5w z4ZDCf>`LfW((Qy^j$5FoSu11(pQjM7wEfk6AZW9N3U$X`n;wMQDCcX+xDfreV58mb zRKo8crM+63fYC%Sliz&rC!?>Fx)-7}FIc0vN2l$0^7O%mLXsD^QMwnlR?2NJP?O&! zh+FwB*bgFnh0w}xb^dQ=!!IqH2w#Sm;6?DLHW0o5bK!Y-4xWLh;VD=TPr?(h4%Wis zum)DcDp(0CU^y&<$KX*|3QO$&`)JC=gpa@?7zGPq0nCSaFb8JCESL#1;9-~!377^C z!DN^O6JY|3hjB0##=vNJ5C%Yhh$oweBaOm=CbDgFS-JjH&h3%JN5F6x27_S`422=! zlQ!DetRBDvA)nh(+;QV}v@gPVaxkTeQ3X=9D1(*hlTxsHROl3T8f{M{9#uU0+NWJq zP81Hb|D%n63;o`hTA|cRI!+uPC+APCr~@*pU}`zZZ_BAdRB&`uKIQTwBRVQPwa|ak zEF-nd$nNjL|M<2X?L5jHRU(?-k^Z;gN!_ANRNk{G6>^O*Ej+#xPu=*l)*C}}x?_!9 zd|Ysx_o+uQnzX2r14y^eQ!5({Jj;mUt^rZ`ce?(&ASgKEqrx3Dp8edm$t}S6YuLFM z>9p30g{T;prjCjJItbOZBy;@`oy@C|$oUqKJb*hBbs1OB`PZ^CZa1v_B} zYzJ4c)Q>kmE&Mam7SkG^CfaUKuOHvX=DV;L-U%32GwnUt4+r3V_yp>a-8Y_oPW(B- zF9^R3`lzrQnkV_RR#EEv18G0OFJOoKO89eTod2Snl5m3f@9-N$b-#>;X$pR^&P$`6 z3fa82hp4f#5>JD>*_mHAeIen!bb>#`tYh2Lk-G2l&JMn~@K!n}m+x`)4Th%#(HDOE z)-c}|W*EhD6E6gnsYpS>)4{ie<%9g7ULb@;2z?t+QD}xfl^vHLzKP0tKl~af$u>dk zjOs+9qwpcN==o5eJGv4)mSwXwS+0Sr;ViZ*5&HW}1vnqh z10VP+lgRRRdbPM&E@ty0s0+2>LZ}Ysl2#thfpTy*xVH*~)}RL*gQ2ho?JbCEdqJ>? zj>KADLG52dFHhO}ufFYbAd3)ckWdHlMdFSIp9`8qya8Ovc0JNJ689B?4%Fuf7lQv{ zpcrYsUeKrLd|COE;16a`5YC_+pXgjlTu-`nge_>c=!ft%cJ^w-Rp2yTNw@-*fFq_l zwf5N$uPeK-{Q~jDgf-z2m=FF~IgfA-`2P?5KM3|=HK+oW!RcxF1Ih37cL`6PQ@mEF zia~U=&4~N2g!;j)&<%XIraQkL+;JPY94>~7pbpf68c-XwF}x7eqqt$+upQaNFGaWv z8bL#_$$fd1#`QyJT+Jb`z1!w#0zPzRp2lzqnC7;2KB(4|P@C5w%Dad773j@#(*GWD zRGT>@Sa2u$EkS$+SXfJF5$ue+6GPw9*9t5nvWenXrRdt5{~EX&EK{wv{ok5MRI}@d zUmFr_K6Pme7981SFo`|7o6-FLDeWLS$~4j*Crw+M`zG+9ZiH{pZy@x5la=s2w;iDa zv=4M5G;`MwT8KNa0%mgiHqcJZZI8wWnA}lc=mFi~4!9jGTYJ0Ixcf9c?uHo+j}kil zqJny%-2)om1wFw`R@OrA29N4ah<0EFw2ii-P|XThmSNZj|Ac{!2f!WmhWjDf;eEvK zg=lA~JJKd9JgVeBZCj~S`@iD!zs)BjAP%=ee~6lPKuX+Z_Tkilgf_Dkw2AFc``mII zH^X5V422;u7zTkY=+RrDWTo9x1$!Y%j^J)rx8g6Of*wu z)RuT^L4F^ci#DCmtC8}|7SC#n(409p5?@HX1K|R~<**Ev!lU4w6@R&ZjQBR28+?<|n}nX) z-zMxu7+niQ*9h;}|Hm=(d>_NeBYlK0Cog-kMNT2~)!=FHJG$ra-w1z!FX0RL96o`M z;Q+h~d%;%mV|+in2m8S7_rbI!>_7R-#zzRp;6um?g#iDOqZYGCot_-NG&t9 z1#Hn1Aw90~AK+1B3C(R&XD4p$vk_)Z$)LTNEyQ%UBl{d^?o`dLY(Srn82ncpW9|QT?6^FM^C+kgVo^{lL0BA$!HpE!5Z=blBk>5R zeasi?`ua|H=!N$>@IV@&c`)v%EO=0s>4BXAXHlu-0owl`kysk>L3Us*OA$X4!uO%% z*PpZ4E(3lci0r*Gj`BoblT1G!y9Q7n&IY&r4`b!v94HU|x3L;jB3{o3)CK>2P#y5! z3RQv1;J+EF02RT1HB<}CXrAg&4Q6o={tF`WUkJVd{35XIhERy~oEwqM9;Tll88m@v?&=Q(MGq@aDfR6=UL8#u1xZzmV5&v=5<+2*@SgGH8t<9W8B(6$L+F4W-2ja40QnoTHwwK;csuEx zz;9aKP`!?eYa+eYIf{t)AY3&J3>rA{JVQu)CLbNrmeU}tFZG05p zH1kEa+TDs>H@L_3|KuH*F{%It|CJt9AhHPs{g<5=COz1REqMnFVA~2^N>~@H$Zekg zPfoDL(N&Cvn4X=H>ves7;?a@)XF-{EQ`ylZm61s~fO zOcOr9hQ@;k9TPea^dWQs^2Pd5dN1Pl!M)HM?g#S?BaCbY6OYR2OWgeZp&tx{0pPPq zJE=_EAEw;!Cjx)Oi3*9rp%@PVcj7=b^r424Xd}P{XB6RsFdBS>uoee2p7>Z87sA?T z6Nq0(colgpXR_;m)KujWPGbjCFj9L6{LSAP;qU&Q38N;zi6)&zdRxLaa5D^qcF-3d zCT%+0K-^hkz8P#A&Lq5!&^#B~|B4Dx;v5WS2O~9ELM0ZWEr3~6az0@LLUk*)i|r!d zy5O3y1EOj62JzRy-w`|~yhi+0*Z^(f2+?BUEf(kg4h)|p)W0W2bL#P;U(ffTUymn} z=ShEv_)5a1pu^b`!o~0iWFemm&uY*)Z91$B+r~v-qWB7o9|awXcEd8_kHI|Rss236 z(ahktpT%I@O0EL)K0&w+*23ek23Es<(k#oePcD<~_}?a^8t)~e&SZ!Fp^*2{-v#}= zq8;F1l+mfRT#rgqyB%|mCjsHr>)ZMmV*8}Y=_&EwNUX(mhliC7m z`ux2R(#@-GUcb2LtYovlNcu)_J^46};I|mR(Yy}!)hi@M8MYF?gdN$JX4(S!hrL7? z6}XAGWtjJ6;@U@ju8n1H4mR#XEz;vBe}!_iUkuyGP=nCzCJ+_ckhqz3x3Usj2tS9K zVBAr^9X(nlqw_*%w4Gq9$&1*2?EH5JHp?d@9)lxr0HTq-o4Czr3q)Ta_Mkbh-wbJQ z6TSu77`Hsbz3>j0KeCD9`_SL@{I6i<{qP=`Sz5CLXM;z3n9#xx5xyTZ=kY;ss@Vm$ zkhbRiknIn^xML*J4UeL0?>Xhg_6RgXvcHZKMo0J&@rOxs^*a?qzcQI-0gFhx4qjo0 zsTUls3(0Y^BAr}(DkYA6l78O$0-vUjZeO@~EHAkDM zpDD2?6D2RFgl&mhmuFPVvL|te!O_HAgC7!a64c1Lk!wIQ9~iUck<#6s&Xe4Im0Ik- zC@H5~v1R+K_88L59U@oaq*5VKw^>Hf;&m~|z@T2iN*`YL@iRxtXQ@HOJ?S(}+|?|j zTJd%m@S@{ED{o1h`un)ur759mr5cs^`TEwx^On#n?4oD(KFx3Xde5BX&MQ}{MSCW` zZkEw9%Y;Pz<{ZG{MBC<6`RT+swu)~jS3!#1_Wt~1Z!D^Fs7#g)H7ixG#INIr6EAB1 zQ{p}C^1jHg{n(utP=4%tn;uz*od?FDl}hAofnBA zS8v3;dZnt>D%Fg2NlenbXJVP=eG>->DlWp@hU>d=@I%WR*BMeK`zRE9axWX4K8HH_@*pJNkfhd$Pd=ZF(HaGvzCGM6*?)F33(PKE@+KKmn$+(%l;)=zQhL)WfUyi=4HOMk({=PFJXkG z+HUJrp!*GV)3S7^kv!s9{!NMBMrKq^E59XC`N51LH80x2DILqo&0eYXW348Au&kLm z?5-e%5j?2zo|hj!vZ2T-QmQ-77}#4910T$&TB1|1=r!}j!l&K;`ZriqVJ~#RZCetr zW5Hggjmj95w*J+`kWm>eipREP7J2pI#dl2Yyy{vqRJLiW@}4w~r&^ZG!%7>xEwOVH zm79RQE%-+K$7ko2Z?qTtY7V{1u?3_QAmxu`zZBfqrb~m6!d;Okw-i#$*&p%o&|gtY-e#GDl*?4NsKpcK)DhX<4e2s#vNTLv<4c+8JXPq|fR(c}c^x zELB6wnXe_jNG+(&n2cg+`Cm(1J0^24qYcAeO8j>*7Vc-lwnT%m8AZ}Ae`^i(@m2rVZYan71aQ&>1yj6Lw^_LG^|| z)Nb)w;uhMVW+gg+%b*>JeB)@pbyyVRpejCa!;CL~th_O4;lPh=C#4)IBQALI>1n%m z4oS-r#(3DZtnNRUwfmhO5-Vmvc8%`c+;-LorV*3BuWvM=tWL@^UGd;WQ}d@ zdi7s9NA60jCg;CcL}jv%QgbNtvt5bp6H@kt-okD4D?N@ryAy-ht~qLV=2+Zu{OK3p zzqD@&_UYiIZJKk04*bozSKU`;&a>~5Qav*zDm#S#UMpLz#0lCtA7yQu^h@FOov$94 zJhG}Tt5JPY>Teq*W=&*x{jC_6}q8)uQ~AjH*n6o7%DN-8&_tdd;Wa$;{pOx)SB$ z)AL@I+;i2MtUudGanHS1?>IVf?S%ED)W}@A4!o0ie+r}Et9KGVO<{EB*qdlNm7`d~ zeUDs-YulMSoh98XHEN>w?MYHRi;R!+@0FH4)m znnXs?^l0sE@^0d{zvMrc((((~z8JQ%+Ut#80T@_9gOl%_x}Y^H4^~ zOY36hfT{I-j`h!$Xtgz25f(j$B`Ka}FCNkAl{M2_T%Sy#l6-AC>5`zp$yJ)VZ`!ns zss;YrZo$69`w!9ZZ4w=)Wt2YszYQ{vEu^Q-elM|eT1JtIi{HzfA+4)SS+i%~D-S1+ zCAkLtQwe`I!$MA0uCrW+w5EiBkY&E{BmEz%=Pu012C-aPLwi%z6?*>S=BhbHFQQ+mZ;Dfb^rj5qICEF5sX z&svc0;Mo4%|FT#}N)b|)ZJK$<&ogV^`BzHjp;b-WcsP-72F>{P;lz0}GP;&{`AFvU zsK5B*->RN*=l2{XR{}2jZyZT1$MT;nINV!~CJt$F|Iy3_ZM*c-t&Qiu-aA=F#yS{oh-7be0tzRT?#{H%=!&SZ-u=U`}w!vAs-eeToD=DaX> ze9qR=y(Wdse>Gin(zLFp&CjS>yzgh3v*gDeFXevxhi5C0!^>52)LqZetCp70@{7z9 zQ>QOtiP;M?3TN$3Wc|X7=2=&NfmhX{j8C)vy-mTT84qXO`$H_TW@$#@3(oj4bNwy1 z_Or*bHu$tzvT8LvTiv=bv(n9edbNA@FaKA2-vJd>^7K1%F(Aw!CihNWZU#rt{eSO!>72(o zdgtD*uCA)CuCA_5Yg*dt)wjC1e>U3Y(pwFGtE0QyY`t)}n5~=Dc)T^=j21KlKe}wU z^{Gg2d5iEK@ay8a&SNSttUwC-*NK#NTZ%k0P8xa;DNMgn-Y#TLW>}8lN1-jYyR;uy zx7hl)#lGjNy>41m5zm0tHIPZTQD@)lsMuE9u~rS!ba5ND+Ez%Xt;yG9xqXu?+OZu{ z6jXTSfVp9WeB5rk#j4h49c|fRThQt=ew^O{Ft9<7ci8rjg=p;{e?0YyMi22pr`P+C=jV7tayk1UTGqv*Th3u^$Q z@MN?!h!3JsPNfHFw3OEd*xAXj%huNlwMDge+4`toBUzP$BiWvVX6*vmN5y-b%ZXcw ziJu+_qI@c0uNfWP1zENhgbY~pYwqx={$#JOoRf>GwKatq4UQfVEf(GAwK2%KT?HH0 z?9*t1#=fr~sG4F;LAxRG9oFPs!04hJv8H*u;V)i54tucCGZ)40vvthDLIi_zQ4(NH z5xMkQhiI5rucgDpYv^u0b^I?tX|WgJN5L5?v$8I0j=;&FeL!lKgRc-^h$SX!z2EjnA^mR& z$wKbv(j5-KyiU$b^$(z=OO7=1fUQ5`EISWk#QdWZ-D97-I8oqs@Y2_bybs!X79Hxu zwdpXP%u%AL%X}6ldz^%PyuB(h>vqM7!VhB9p&_bgBQyMzFY*^?OGG|${RP@y5YyVM zah2&@@}_;|^UTl*cg5405*cJwXIh4*+6<8S0a>B&^OgIm&*P&EtvL%w(@{XMk;~Yj z?xs!p70e%Cqf$6pMO=6-);(I>&$;@}86pLKjYTO1vMyx}^*vj`gD#w=+YtEriyfOyWFK}hnWe;a^TPpBM?A{9O=%u zdig$g+jk`|c3HOZ^%+f1`54taB5|UE@wVC3?+!jpnGHVR(<69SF^PBFGwXdG`18EK zliBcqr!>LP0s|LQW`hq7F%)^(uq4tnIOc?Ua+f*pj3l~+yah5FeDJ(wDEATD56a#m zWH^eU+~*?Xbrgb%EUMQ=D@S7%&0Sw|#XUs}FEdrxUXa94xqn!;G*QuG++B$oPg61a1V~dmKokMQR-b^er>;Fl zmI9Y6c#9ZS#?Qbwd|!Xne(nLM*hcu{RkjR0OC#0QuZV3k11)+`=l5}076lU zll>DwmMX5-!g1x?OH>Yx_nypgAuy}^p*US&kR6JX#|uD?0AxYn^toPrw{Fno{AQes zij#UAko$|%oIlVGic=t7)w{^xfef==-LJE|PPQ%P44;eBRurzNC1?f9=v{&iq6noy z2})w$Ta=&|48xETdR-}C_^nZgmBzBupF_Kt^I8$pNF~VQ1RxKTpj1ZOWk513R^ZTq z=5=q?j?^H1*vKiR1oa1``WX;xfZ4Oi&GBGMm{4EB9XNs4Cg$4XLs663QZFZ)HdxORV8IdaTeT)=DMdZ$4*Ooglir>}PczGt%ACeK z2uM6@>q~*>;4z99Wl(84eHuVFN>kctTYu952+I}4x9pzpuh(V#5Q>$4au&>1z%nBZ zvE)b{RGQ2C@4px9Y&329B*6jN$fPplevMPO;v)L0tRcZe0BB98oy*fjomy6}jYD7M z7&w29b(aeQcO^-LuVBnYc~_R)&mra_8U42yBpdYpvaPFHtDIg}6ymr&BG2;^TU}Uu zndxCB<;ilO8}=8>(pC<6Q{Y=@0qE~cq4q7e8q;N=?TlpW&@i4W~*^sk@-n!J@!!!=iH;Cfd3wt;>^tVg`}OlEm{HC0Wuc8;d|+ z5JGkE^e1$sjRaayq%x{&zG92`3WO4i)q|6#`fp zzUlnLqNBSC0YHy4a>tuf2HaoOh6}a6WE+r2U}mtM%JI! z{I#a@rIandyL`X#sRghEhXsA!¬NALVQApkLEHdQ9?D;a8(+cK@mQ1lfzM358zc ziX6qB{9R)_g}uYn6~2xqOkL~i87zZkxhP-DFS_M6Yhq z1E%+9f^pUlNVF0i-Zc?%bFPuA6(hSsSsYg_7g66@my%eM4#JgCEV~xbBVaQ4<1ILO z+@{N%Qm|5R>5Y^r6}OgVC9xoq0`A!QeZymr;2GGJG)lHJ2#T?(&aBPNON9Xi!hJ6L zb2mtHax4Xq2~rEjzuQ#5=o~epASsqo7PawxOjP_2RJ+VBxs&f1XthlG-g_olg~qGv za0VF*%{N=Wu~3&AzK6|Dr-fA0t6Z}6B~ne_gpx2fL9-K<&FA~9e53BNF4x}DoKos# z+oDRz`V{>Js@$+XMLmS?+q*vR_&)w*jGq>i8$nX(9Zy3F>xyj>Pn&YZ_rRRE^oqCD zrxfH>&jW%vjhg~4fA+6+00UYHA$d}KsoEoyCfgM6!P1*_#@4L0MF}VC4!(RX=F?~8 z>x=66hL11&bmhsH-uS=pwZX%G=3`s>*1}^}gkP*k@Av<0uUD$EWtIH@s`%eN0FhOJ zRuarQWDCopp2pajMGapKej2%>$I}JyCsi>@ZM79J=T4nGei!n94 zMafNu4&1`&k>h=qnuw{{z z(0qNp*HiWPSQ56LetvJ8U!4UE+7g^ePIZ$b_Kq#AEhJmZmaI-c?RkSG`|6p6!rUoFGBNW(_@}$}B zHd&U%RyAnE>hcC~$i`bgZ+coX*ofaQ|odQ{#`eA&SzBVm^Wj{@q2fYZmzl z#1zJPuPm)S%?PSCqo~iAdGr5-QQhZew2Xn<;%HcHf7dAs~Rr>flv_(C1gP8YKq74vn=NB6&5=%xmCz*fFU5s z5M2@}(c4B8y}kDh0(LUxQF96fMd~L&Faz82YS4%gzf@Zb2q8dTL`de#9@rvJU5OSH zq!?TlRx!9LgIg?YZSXbeTk;t^`&Sd}or@39reJya--r}e&_6lP3=Q71m9PHM!gGaN zQdq3PDLZBYyjxPlDf~oOVn$0!*<%P%R<|U3#o$B(^aeMjTq~NTH@K(?t$4`k!0>0y zuhsupQ=?j&hu|3UW%JYVj4pIG-r&p-iuZ3wD{EPBPW_d$ZE34wh)|$RURIcikySYZ z$MV{PxvH^~%HB^6LsSoIP_-EtQI$&JW)x`!c4SWRoxHOd{FDqYu5pX98LlbnGaUHK zre*C)ByPMnb^wcrv8h!^{Z)IKkrQR7wWswt4cc56n~}`n1HH)6f&OOS_|%;vRkJp@ z%Xupbvo>T?k6;FpDc$-3p2M-R5DHS5Mwumjxzw8^Uj zZ@M#U9!zMs{OD8QV*`GuXmycdm}Hzk&bRV%q_8=6XeB1p%H%>xQZ}UmDVV+ccc78E zKz&dL+KzYAAYfpz_@~Lwp1+!1hGAfHNsz%*q_E!lAOG2Z`aCGo3n^IB#@6#hb)Yol z{YG2d+kw1ofc-b%V6mEelaf|n>@b$CHW3SlQ;@=f*W0dp{C0HS$S95-X2RRpk-}{Z zA?h|5ELPwBwzggNJnyO5FgwDEEccJJMe%E~nUhtY(Lq0Pu=6;+sE`H9b=x|UpRJ*; z64#MN+8R8RN}Xt#tzij!Rx*Hji>X0cVK9tT<^++e(NINwCA8w`@T3Fh{6GGrNknsp zFyjd=a53!*(rYVGb5i);a?d`G(jc_@Jugz4HCSnS(zeW9q#!4g<{v?H2zgaqXFd@y zy~e$Xi-^Th&=IasjLyKCIM+%UaL-tH7>51<*{=`4Fr?LeRG z0W6E>Q@<|CZ-(SE(dpCS>9f0XdRdlTpeF_9L79I*q)buz{uAq0X@_4TGN;bd{3cPQz%%Oe_uoy+aB>!{v8b$f;ozG!^NWhf(5OJRc4tdmvZe4&zNc zp-}!>ZYTRS1Ycs6mSH$8D~4hvIa7yIN=CBw4W~qwUV8-jSIR(MhLZa)MoIErKZ?rC z#=E3QKIQjCqbS-9cr3r498I6_-E?U*U;R^Q!VmTjes6vel=Aghy4y%$1~lQ=y;Tp+ zZM}&Uwl@QHlRTRI-NB_{43Fv@ntW#D!nh{PJc~$jnK2Z>AZi1Gbq~wKPi%a?#xB7O z(Pj+oc85eSjix8=27kG>%aNKCG`P8CN|mM;Z0Qx&fWZ=B8wS=Btt@D0qTCouFA74< z-b7Hq4@MU<Mi+I!IL>Be*ML439ZE9GDk@~eI6CM70ZkZ3S3IC_ zvjNF^-&N}djXbd4%^r|Kxn(6U8%NOtj4q~afOG(4_>{N5u6yPBi9vFo?hsO#x3@25 zZ>@Ph=k9|Pq1G42(TqY6%mY9$S1X_M`3ZY3HD>Go1%%LJHMp-{+l8||zK&N#k3k4~ zNr-pj$WS3el?r-T%dS%xjZVI|nn-sFXMhWy7|C>W=tL@01SDi#z}$%x%plfH>0#UntndhXQnk!kIzb5G2~rXhum8*)Vr?f-e% z_*A5@1<2^qY$uWXJXBW5T%)U0Pc>!|mt6Lo1Lqv5zPXFGo}WSMEV+^mAm%{#SvgIX3`-?l0y+vO@j zD5GY)Wy_RGDs`LdFhXoxrzxc@OqfWd;|q;`)Y=PQEV8T1=kZZ-&#v}e6CRJ$HXgv& zg{e-PNAX^$1dAN${gr5gY7U(0?}*AsbNo=I#N-cbVTLeAuJfs5IWUzxm3w6U`i^`# zbXS{mT6M7^bdm|#(xjP`-#Ih+>BDSeer4tYD#Mz^(gjrC8-r21gNI}tUdgN;80rvf-P!TdEoZ~NnuTPnj!ixB=<>ZRI(8Y zO&~8HgR9yGoUjnUzz4OH;+Mw4k=6Vha3U)-c_D@SfXECLuDJ>@ya_%qF~Z{*5J^e> z(dq=_>ZnNGA1vS5enqKe%|4qEXF#NBjzA!*T_7N}JSrEoYA_PJfR)NDQCTSUH>~*? zqFU%KxcTVsha$2-X~{nCXM7cbK(_hxc9w~l80GYL1w$U2e-`n|5vpv;x-V(9m}_t0 zyxHddF=^sBh)w98>}5o=pgE?mm0wC&+7l1gx*h+eTk#Qe@9Tr)6dtJXuN?0BQOQ5R5OkpSsLEGT@(I%n)an@gBBp zy}FfLuD52!TF6i2r5pW>t`txi!b@Hr*QYXb`twH7!75OEZOfh-Gu;eP4=Kz+d{m_3oizu4U4s-hV1Q%RDvD}U#Xw=`DvrJ7 z`jOk+N0(%gE8!p>UPbW?B6T&#p8aYQ{gBla*aCJT%zA66PBp^?#Vv~RREJk%wT>3B zXVZ0Y`Dz$cy?SXqHyu|3>Th^H`wu^46@1@XPXRUI4nA5>%W8tjzW~YBtPgGD>o#+A zz*#{Cy4FwYDG?Bg?FM>Q6C?aun`m+^gTLB%6VI`>)!NOA&$aKS;nrdUtv69hE!cpf zo2hVZkoUtD`l~kF#!XxF+R~oS<4;U`-*Vvq?zs4(j5AxPRvl1r9T02@aP+O5`%c{p z^T57fHnuNs(xq;p(RD$E%~qNPNTtYDQggv+HErcuab-#1z3EO1`*NHWFP%ZHl6`lNrn7ZXb!Wg2tNzz^DYx>yt8~&^U!ywX2rCV@kbgZuT#Du`lC)Bq9WVk?#9phy&KhN+nWOvYTVJkL{2SwgOC}no822JVB z-#%JiZ8`Up7^=|_O=e3B#Ww_wBY{P)260m=J{m1lE! z2v4IW>QZ9Jt`YJoyEw!@(F+<_br|{r5G)jjfUt{5N&C_J?Kp=Xvw2=7A+KH35qXu` zyJ%=51XkPcqC1VCLH&18p2m2N+(q^AR3`yL9+ZC8+vEDtGOrm1m=R`3umN}hAWQ@Z z7ED}zaQy9D*{`!zYb*{Ah#g2_b-QZXyk?6N1~biJb&Hf^yC|(OO1-s{hD9QdE0`FSQK7$9l08766U{aepk+iM@p#tA=liXJI<% z1UrtRLo6Kvgc1@<(anK#P%L@RfChvk2eVO$Zhv>f5kn(n4sYG`SgO?wkObVb@mw2A zsiW}R8B4R+_d~IiI1?BWfPoq6gt^&rU9FrnMq=>M-HfH6xqx^kAnHbj?A=;V2MfeC z)uekDOZI`lWgSO`Ie6xeqxjKydd5)@zN^*ZcuSr#HAnBg6YsGa68vzE&D1@MrIUfM zq(Txbl%;KZ;r#k5Rrb;+#&@H=6tE#fNp1I1tvL{5_>UOh2&8nYHAXx+s@vwJ<*f`k zmGb*2umyCn=02{+WAaqI^*MDuXev_5 z#ST%&*5Dm78QL0FAOpL8->4*6DO^-86x0Uu5;E`BHU?Ky)?H$^c&_|OuZteeKPsUo zt3YnX&{?Ln`F>}K=8VoVye-H^XSt{?xEDn$QbBtkiEM}D*89k{9T4({;gSv}$fve* zP^lN%rPJ<9ruK$j0$l47QrZKJkZHPle^+@;&yVtsz*y{XwYnF}^#G5;m)L9I2Il#b zB}-bAJLa!d37b&Sr5&Y19Z(vY{E8`1^ussm| z)@3}c*mSM#DQl=~#Db0p5!YIPQ2stf?K?sMU5?Ynj?j*}C&;rCIs1wq8m*$v* z?Lre+*->4kT)=6$e6`rodoWI^h{nVz9wat%yr3ZNPKP`U9;71m;WxxafR# zo+XbiK-}dVwPeqM=V)pd5P|})bTK?p_MfBpuHfj{ISTBDf)mbhOyg_Ji8$m{nH4N| zIh`ZBZh-s)&oDfb&rwnzK8yI_9QE&yPq`9k1&}B~2{fl03VWD90U>z*kU)33q0pD- z$-4&%8GeC#!o}>yk1K6ea|H_FUAAuW1q$wt9LjMT*&Tuh#;BfnM`7-D;n{NxzDoW? z>fQrh-nvBIcibMgqI{BR6!RQdzXP?{mq-aHOF5oMk9wg0nT#@7Q1E7Lr&`e?H_g!? znTw$dO5iECXF1fHc3{gHbIO8YrE}SxnOZGkYtCma94Xd@_5-kI#>PkQ`Po_`H z+n2j`DqcW?V2*?ioFs;zUx^ktE|0%^{9vbK=B~4CV4wpYp?gnAP0D~vQQO<>cbV+_ zfEg|hU$y#WPV!p)<#qN$odN{Oyci}h(+ohc?rUbq{!3m?$-x2w#au=TGj0W9U%seT zX%$aAB#q^JwqtE(N(I&AX)-~kv*+gOxm<}o8T`?%>b?; zy&*pjK(IN#lzvX(XUnxPiB;l*6NN=JJ`%cQUb6>1hW4`G3>ASPC!UEhF&K5hl1 zn)5n0F1qcF2i+{Qk@--}KmiwT4!(-y9n^UBMLQL8r0sptv7ETUiC@)pzgjvpqNSO= z3peONU$A!p5X^e*89b`ZYpYshhRD#~X5A$JP;e@nA}UU6cNsurlgxdKlzym!E28y^ zcCI9xqdx3=CRsU%wmg6rWN!0-h7!A|A8v6SnmqA=%eJr2@0MR^pN z!#0l%fXlNQ6AG6u|G?YaFo*0MylR(Chz-yR)wD!2eSjgrl(nsT2}DedYV2Ke!}s%+ zN17Bh9Ty_Ysv_ZZN)FO)Q%Bf2)#eW8wb9#MLtg%6Vz!kj9B*rL!XU%Wcj!2KikxIW z5bbBsT`DsWb;O^TO#FJRE2bK{#nbkID5zo*SB^pht=lI@*&We{)>;}m_G=_tXcJ!upnv54iC-Zeu&Sz&f#$eVKH7UJL;XqV=NM6H%fc1&P@Vt$l zcPJ3}0|6TZbPEd)>@sy3Gqoa`(ETCR8j9w!>mh9%3R&*Z)2*RkSzw?@XG30EITS7= z>w_82jQuWq=a3<4hbO!R4gYz_FL__QpJ`@~Q{}5>>Pu)#g5da!9*$B6Jf*Y4(_LT} z3Ljwzu=Iu^M?&U8rqb)CfRTprRy&^SsnZyPv&^BsiQqN6ckbxBb)tr`zDKYvT%>P| zHiXA)S({dSQOGZ&P>AKALRR9x9x}L{c+O3H-phr(*6v(-h)IkMb-Z<#QOL~EC`8t; zbYOWsn>iJZq*dt`dMY^1;7ql~7+lTCSvZo?{jo|xw!4s+TlHk#a2vkZy{6-{4Yk;T zW7;|w-I-)P{kajCJ;PBKvOGy3Z4HMv%9lX6NV!{0P0^F{Sc4DKnJ+w2K9upbng@XM zW5J&ok|7aU$Y3%yDNoH0$N|o<-ED@BaASl=uQJ9*ksW|*kE|BSiKP|4=w6HY_5U$b$krMh(r|iAQjmU-+ zEGA;Z=2^&mm|=x6=RcK*se(vE!?jpU;|;kjb#OdKx^<(8OvSejJ$w6sPcG?sSO2Fx}wlcJVE5 zi1BuhH#OMR{iUK0XU-Q4*bTt_Fda-h0Ej*K9KP>$#q3oYZ2<@~_ao$L!g{aN+Ph997AAWp3a)yCL=mf-WP?Z`7&0OrT<`S6Ps78}De^31=sH|unn!@~GZ4_J5Ge$>AERM4P*jQX~LE{pK z8s1!-8+n+g0~IpE;y44ZdGNq1;x>8)n-bV&))R-&78-t><%$zFk;3AJZQD<1y;r}7 z#Y!sTND8D3*VAa^RhI*z7%QjWPZyjQ4;*QRII5>;hW!a3*v|F475+|r=TP)dGlZR@ zXgk&ud;A?W@7b#~b4mq;KC!&PfIwwLcr~wh=EM&HtUDLw&p`@2q=;?PmfnnSp`Ak_ zQq25eu$^=l9XJ1?tsJ{B|9|e?5+B~#f;XS?|3Mj+I5N_t_RPhdi+p(>`Ins9kojm8 zxi352KnE9s`p8^#Wg$kcHLa;_BpjJ0)-;1X+h7q_Bx)qYn(NVn+s#k)PIe0d2Ie|L zSi`L2{*E+E)Tb+^3|fBQNf2R8*^MbOOeMN)>be*~f^CSNvdPwoHGePAIPr7?ws4w9 zPZt;{W-**Edn36n0j&>=6nGE3{9}ykwFDD2O4r;pd8uKm@;o>BEi?3IF6P>00Q_iA z*Onp7>fk``%dv8@SO9Mdk@gX_%Xiw2}AZ=$U$Aib2lTza?fcf8lrSf`_w0}IQ` z>pthDBnFB3AIFt=7Tp}zaHV0dUYVSqlvSt@J~33UhzKaX&#!1hgwnH@>b4bLc#Or8 zxu=1$UaVqzsLd0(ko#&wK$bp%k1jlxrmjYT!WE?7S0nB-q5#!cgW+5zUO($i&}jZk zLA#P`4W8Lss*0{C)y{6~6c@VI@J25?J4YI^9;>$xsI+K3d{{m|=c1fYBN3%FT|_Q6 zu)MqYFW>cJ*Tb_yr-{{IIHFsm+=<_?kThQ;cU!W=f=f_8?%Q-&k}R#g1i!erPCQn^0(D(~}C`^}KorNXpvGgPik5whQ6 zh|o~Y-(v7lGhN_-TEzHO;~H~7#mQ?cC}+clt&oOq2}(R-aH?DhR|}L-v=I*#safVm z|LXZQcD3^Y+9HKTA(Lx&Xj`F~V`VKx^CAY6ApdPZGo=JYY%{oMlq}t5@NwLXEG&lA z^5)2rrPWFyihc=>=h$ZOP~(uoA}jxF?CL-9dcg<{8C$EaJ5hpEcAU}G5)^+GPky|S zr}6*?5p2iI$V(jf!P0F?(%$U`Pn$v|6>Wv@%98W~-_>Zmv!V3Qr^9Wpp1<>fW3Grr z#P3Uz#|}W`DWz!hYpD_E0zHerlS_@DS$ubauUZxmOn=U9oRa%m_6D~#99o@MFBN$K zh5uNJ4(>o5^eh#51g}F&(V=5_PAx?>qVc3s)HWId*ag+bZ(q1e7Wb=RQbT+uk4Lr#^9yvRC(sl;fACSyf8MUTa z<1X71dI=sOg)yE~>mnfMc~TmK+zd!&hh2(4E_7$kk|F{Ub#)v#cLCxGAed@6)~-Gj+DrUDXvgg16{{DzsXv%BCS_QfG0 z33&O07t>JWVV=Cxtl@<|T|dwKF@_y^ZX<=o)}D3Qp1t~z^_R`%J}ONCyV0)y0R*c_ zt5(CNKZ;b}2nYmzRM5=wI{rT6hePYnC5seDDrXs5wi_}PTSMg2a?1!KveF(HYEc*8 z*nYzGN*%B7D6>#X z$83l>L6{V7l3h$YD=XS$bDv%f-VRHux?htGCdzT$1r(SWSBs_&)rRSGKgv;B)QM9S zioS$xQ%jFRgi@8b?xd6ALX0zEY0Pv9D2h4;5paX&&kUR4IGTWvfNEV;(WcdFdnvs_ zd;X(p)UtUnh$pcs ztvJo~OskPwCk%ngt*Yd85+AEnBk%K2D1!ZF_9!SIsm0UgC2I>ZFec{B!KomON8M`N zH5>KMUuBPUUXRX6i<6?8gkDAio!SZz42{>KLZzP7F3gOn2!R?~(u0$rikn}Yka!AQ z4J}Rnr;sfa*_h3_w0>2~!15$L25#f9k7q4`uN^)wc+_*Ca*7BaqE{VsN?c$BZ9mokQ~wwL-TTgs1@4lKZB=%uYaS6)8*@ zB1gtgyhrer$TBAJj4ra7|DWmKSu>#GJHer}2LIiiymz+px_{fvYuhIO@9yc-`x@3| zXiZtOEZjo5(9jcnf9BWyinL*+EnR%&L{VZeT>-yD1;HO0y+3A?QenwNQ?!eGzFhVk{-_HF*{hPU~ zC$m-N75NGLSUk84cIg<_*h$q5)we6w@@)Z2hgHhpet)gJ|b5xs+4jIN-GMbD!0+u z$d}aHhB8WGGjhL!uu9gWX;G-n&mfESkyw?u@eZ_L{EzhJ4(j4=3$Ese|2q1(=#475 zzz7R-z=04EF?JZSGY!5A|3$2|RI}b}EF*R}0Qlg22=)`=vn>ATH+trxzedNfkp$wi zY$Xk_dnExP(`zxX-4a)zwWO{|pfFb}?l#?{&C`W}YQcwcc3 zwf>?toxO*u>YAJ5ZZ)}!U7y%p6OfZNAo!Qb%gN(Dsz&Ajh9&obK?pNF=!Vm*Qz2Z* zHhDZSIA(tiw7F^Qc9`fz?Wo2lL%vEry39{(W)qo*+wmdZ)SnI(QyS*%r|8$?3u`~9 zLhUT--`i3A1918h-`Q1A@yiQ-?%QPS51<#+viT0V_1CUF**%0)Q>MM5?PjacW%i`5 zSC+W|QtX>;j1;y(H!X3v=kYwtcAHarx2KNCtB3=qm5>;k!*ESQ4z@Go$bI*y?M+6p zfu_KueC#OHsvPr=Iy{!DxGZbW5dno zx|mZ;9jMGBaN8abto1fJ-@JLpR}Sn3A(1z{0|f)Zv|2!1HRg1Bw0PrNGsH=xu)tNN zoU``LuTYrvMk4R?4z!)+weQFw7H)Kn+UHTYv>Bp;NI5k3(umG2qvo1Z+IOThM%h?E zu>Pn`^4zIbEjBLZ5UeiObtLb{zEcMcqo5Y_S`L_%GI#aAaF;?t z*}KXqYpxd_ZcbSfM9Yv@O%M==MuhC%wfTo@W{B58l*q6b?5yapHZ&YX(ZW*|07EDoq7&}HlBvmXuy>VPOKC^{cvC6tF zNGS*GkKd)$aSf^7-i-YtQea0S_IWOJ`*ZJt7)5^rUszM{>cUghe5JbHNlKVz&eItw zFt!o@1a?~ftmTB0A|*Qtn%jk{Jp-}F0D}G?qI*5p4kvD?EVwH);7u0_1BA)5tD?g& zIHJ269=b864YLsfA_yt)eS@C{i3oA-DdEz6LXO?jhur3j*>1!oYzcwDkqZ9S8_^!gGTfXHF<*Vrm0Bo7q9PGQ1}x0YX{RlimZDB5@02 ztY)q2;-CTb>z)r)psntg2K~z;3DS?^m*+9a?gX649A;kS;RIi&$S)S+{0d9@xepm< z^R%jwl9gvQWL|Y&(X0M8fE&c$ofi~S*KKw+tB1rOs8&P5c>H-waNJKbPhSo9A-vJ@!+%l9uOk~RO9`LcNb21Wmlf{e;9x?45t&NK@u(zQj@Ru+24v|duh zFN1LT7xg7`e6MWF^e-jN__WklaiR!ac#W}~W%lnWo+Rr#a4J@#YaPPWU#f@Q>bhr~$utiDS;cUw^WCm7?e4W{)(?g4X|IFfgoA)6q>ks7Dr2q&)&)F%z5 zKI^=a3Q-z8OM}8$2>lzvlJ+R8YO%E8vN+4{dNl0V;&wH1D~D^r^;6>uX{FiVK4x4PUC9`Ud7q_IgbmT%>gRGqiMc% z;R53lrR_BG*5iPSE&yaf2xWch*^pj);hnQxW{6?y`XYr*jo07&d6T-cPHqKD0kj~y zZrC&mM_$LTZ#$YWjW+9z9?G0)lmG~IEpV`i`--+zt|-U4xo6X3Rf0CDwtrfrg5oa% zfH5*Bbz?&Pp$SFI08d5A^$-7?v`M}{$(*8}P65cPx=!ceh=!AOjmvCkJKqf9H=V{S zMqf1m5N!N^Xx*+84Y%!XsGZQ~#}*U?O{YZQP{O9uGsWnc{bxWH*RBCpex6R=R>mrd zF^NL0P|Wa|e8ik|#Oc$-YrP(5w{nzclbzFMQWPLe%K_ntV#fWdlxQ(Q8DoanDN>pY z(>HGZ>XyAZ<-|-%VR>%=f=xSyt*^0n{HW(E%@BVgg~@Kzi>|4L37b}%Q?k#ZYS}

<2}x1i0(*X8_G_t{*>6^(ZjV6 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 From 46cf310ad68b84452fa434fa6deae4694aefe032 Mon Sep 17 00:00:00 2001 From: dswbx Date: Wed, 5 Feb 2025 17:54:48 +0100 Subject: [PATCH 20/32] finalize new media settings --- app/__test__/ui/json-form.spec.ts | 4 +- app/package.json | 2 +- app/src/ui/client/BkndProvider.tsx | 3 +- .../ui/client/schema/media/use-bknd-media.ts | 21 ++------ app/src/ui/components/buttons/Button.tsx | 4 +- .../form/json-schema-form/Field.tsx | 5 +- .../form/json-schema-form/FieldWrapper.tsx | 48 +++++++++++-------- .../components/form/json-schema-form/Form.tsx | 17 ++++++- app/src/ui/routes/media/_media.root.tsx | 31 ++++-------- app/src/ui/routes/media/media.index.tsx | 20 ++++++++ app/src/ui/routes/media/media.settings.tsx | 29 +++++------ .../tests/json-schema-form-react-test.tsx | 4 +- 12 files changed, 102 insertions(+), 86 deletions(-) diff --git a/app/__test__/ui/json-form.spec.ts b/app/__test__/ui/json-form.spec.ts index 16998ca..3a2df82 100644 --- a/app/__test__/ui/json-form.spec.ts +++ b/app/__test__/ui/json-form.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from "bun:test"; import { Draft2019 } from "json-schema-library"; import type { JSONSchema } from "json-schema-to-ts"; -import * as utils from "../../src/ui/components/form/json-schema-form2/utils"; +import * as utils from "../../src/ui/components/form/json-schema-form/utils"; describe("json form", () => { test("normalize path", () => { @@ -122,7 +122,7 @@ describe("json form", () => { } }); - test.only("...", () => { + test("...", () => { const schema = { type: "object", properties: { diff --git a/app/package.json b/app/package.json index 1e9f061..4860cea 100644 --- a/app/package.json +++ b/app/package.json @@ -47,7 +47,7 @@ "dayjs": "^1.11.13", "fast-xml-parser": "^4.4.0", "hono": "^4.6.12", - "json-schema-form-react": "link:json-schema-form-react", + "json-schema-form-react": "^0.0.2", "json-schema-library": "^10.0.0-rc7", "kysely": "^0.27.4", "liquidjs": "^10.15.0", diff --git a/app/src/ui/client/BkndProvider.tsx b/app/src/ui/client/BkndProvider.tsx index 1209c0e..ba5b8a8 100644 --- a/app/src/ui/client/BkndProvider.tsx +++ b/app/src/ui/client/BkndProvider.tsx @@ -14,6 +14,7 @@ type BkndContext = { config: ModuleConfigs; permissions: string[]; hasSecrets: boolean; + fetched: boolean; requireSecrets: () => Promise; actions: ReturnType; app: AppReduced; @@ -103,7 +104,7 @@ export function BkndProvider({ return ( {/*{error && ( diff --git a/app/src/ui/client/schema/media/use-bknd-media.ts b/app/src/ui/client/schema/media/use-bknd-media.ts index 4d8dbd1..426bfb8 100644 --- a/app/src/ui/client/schema/media/use-bknd-media.ts +++ b/app/src/ui/client/schema/media/use-bknd-media.ts @@ -1,26 +1,15 @@ +import type { TAppMediaConfig } from "media/media-schema"; import { useBknd } from "ui/client/BkndProvider"; export function useBkndMedia() { const { config, schema, actions: bkndActions } = useBknd(); const actions = { - /*roles: { - add: async (name: string, data: any = {}) => { - console.log("add role", name, data); - return await bkndActions.add("auth", `roles.${name}`, data); - }, - patch: async (name: string, data: any) => { - console.log("patch role", name, data); - return await bkndActions.patch("auth", `roles.${name}`, data); - }, - delete: async (name: string) => { - console.log("delete role", name); - if (window.confirm(`Are you sure you want to delete the role "${name}"?`)) { - return await bkndActions.remove("auth", `roles.${name}`); - } - return false; + config: { + patch: async (data: Partial) => { + return await bkndActions.set("media", data, true); } - }*/ + } }; const $media = {}; diff --git a/app/src/ui/components/buttons/Button.tsx b/app/src/ui/components/buttons/Button.tsx index eb5ad35..89ee795 100644 --- a/app/src/ui/components/buttons/Button.tsx +++ b/app/src/ui/components/buttons/Button.tsx @@ -20,7 +20,7 @@ const styles = { default: "bg-primary/5 hover:bg-primary/10 link text-primary/70", primary: "bg-primary hover:bg-primary/80 link text-background", ghost: "bg-transparent hover:bg-primary/5 link text-primary/70", - outline: "border border-primary/50 bg-transparent hover:bg-primary/5 link text-primary/80", + outline: "border border-primary/20 bg-transparent hover:bg-primary/5 link text-primary/80", red: "dark:bg-red-950 dark:hover:bg-red-900 bg-red-100 hover:bg-red-200 link text-primary/70", subtlered: "dark:text-red-950 text-red-700 dark:hover:bg-red-900 bg-transparent hover:bg-red-50 link" @@ -51,7 +51,7 @@ const Base = ({ }: BaseProps) => ({ ...props, className: twMerge( - "flex flex-row flex-nowrap items-center font-semibold disabled:opacity-50 cursor-pointer disabled:cursor-not-allowed", + "flex flex-row flex-nowrap items-center font-semibold disabled:opacity-50 cursor-pointer disabled:cursor-not-allowed transition-[opacity,background-color,color,border-color]", sizes[size ?? "default"], styles[variant ?? "default"], props.className diff --git a/app/src/ui/components/form/json-schema-form/Field.tsx b/app/src/ui/components/form/json-schema-form/Field.tsx index 904a1a5..8d4acd3 100644 --- a/app/src/ui/components/form/json-schema-form/Field.tsx +++ b/app/src/ui/components/form/json-schema-form/Field.tsx @@ -38,10 +38,11 @@ export const Field = ({ name, schema: _schema, onChange, label: _label, hidden } setValue(pointer, value as any);*/ const value = coerce(e.target.value, schema as any, { required }); - //console.log("handleChange", pointer, e.target.value, { value }); - if (typeof value === "undefined" && !required) { + //console.log("handleChange", pointer, e.target.value, { value }, ctx.options); + if (typeof value === "undefined" && !required && ctx.options?.keepEmpty !== true) { ctx.deleteValue(pointer); } else { + //console.log("setValue", pointer, value); setValue(pointer, value); } } diff --git a/app/src/ui/components/form/json-schema-form/FieldWrapper.tsx b/app/src/ui/components/form/json-schema-form/FieldWrapper.tsx index a6ba1c7..4e555ff 100644 --- a/app/src/ui/components/form/json-schema-form/FieldWrapper.tsx +++ b/app/src/ui/components/form/json-schema-form/FieldWrapper.tsx @@ -2,7 +2,7 @@ import { Popover } from "@mantine/core"; import { IconBug } from "@tabler/icons-react"; import type { JsonError } from "json-schema-library"; import type { JSONSchema } from "json-schema-to-ts"; -import { Children, type ReactElement, type ReactNode, cloneElement } from "react"; +import { Children, type ReactElement, type ReactNode, cloneElement, isValidElement } from "react"; import { IconButton } from "ui/components/buttons/IconButton"; import { JsonViewer } from "ui/components/code/JsonViewer"; import * as Formy from "ui/components/form/Formy"; @@ -14,7 +14,7 @@ export type FieldwrapperProps = { required?: boolean; errors?: JsonError[]; schema?: Exclude; - debug?: object; + debug?: object | boolean; wrapper?: "group" | "fieldset"; hidden?: boolean; children: ReactElement | ReactNode; @@ -26,7 +26,7 @@ export function FieldWrapper({ required, errors = [], schema, - debug = {}, + debug, wrapper, hidden, children @@ -43,20 +43,28 @@ export function FieldWrapper({ as={wrapper === "fieldset" ? "fieldset" : "div"} className={hidden ? "hidden" : "relative"} > - {/*

- - - - - - - - -
*/} + {debug && ( +
+ + + + + + + + +
+ )} {label && ( @@ -65,9 +73,9 @@ export function FieldWrapper({ )}
- {children} - {/*{Children.count(children) === 1 + {Children.count(children) === 1 && isValidElement(children) ? cloneElement(children, { + // @ts-ignore list: examples.length > 0 ? examplesId : undefined }) : children} @@ -77,7 +85,7 @@ export function FieldWrapper({
{description && {description}} diff --git a/app/src/ui/components/form/json-schema-form/Form.tsx b/app/src/ui/components/form/json-schema-form/Form.tsx index ff4a7cc..8e8ae35 100644 --- a/app/src/ui/components/form/json-schema-form/Form.tsx +++ b/app/src/ui/components/form/json-schema-form/Form.tsx @@ -14,6 +14,7 @@ import { useRef, useState } from "react"; +import { JsonViewer } from "ui/components/code/JsonViewer"; import { Field } from "./Field"; import { isRequired, normalizePath, omitSchema, prefixPointer } from "./utils"; @@ -32,6 +33,10 @@ export type FormProps< onSubmit?: (data: Partial) => void | Promise; onInvalidSubmit?: (errors: JsonError[], data: Partial) => void; hiddenSubmit?: boolean; + options?: { + debug?: boolean; + keepEmpty?: boolean; + }; }; export type FormContext = { @@ -44,6 +49,7 @@ export type FormContext = { submitting: boolean; schema: JSONSchema; lib: Draft2019; + options: FormProps["options"]; }; const FormContext = createContext>(undefined!); @@ -62,6 +68,7 @@ export function Form< validateOn = "submit", hiddenSubmit = true, ignoreKeys = [], + options = {}, ...props }: FormProps) { const [schema, initial] = omitSchema(_schema, ignoreKeys, _initialValues); @@ -146,7 +153,8 @@ export function Form< deleteValue, errors, schema, - lib + lib, + options } as any; //console.log("context", context); @@ -229,3 +237,10 @@ export function Subscribe({ children }: { children: (ctx: FormContext) => R const ctx = useFormContext(); return children(ctx); } + +export function FormDebug() { + const { options, data, dirty, errors, submitting } = useFormContext(); + if (options?.debug !== true) return null; + + return ; +} diff --git a/app/src/ui/routes/media/_media.root.tsx b/app/src/ui/routes/media/_media.root.tsx index 891f6b5..a14e6e0 100644 --- a/app/src/ui/routes/media/_media.root.tsx +++ b/app/src/ui/routes/media/_media.root.tsx @@ -1,33 +1,17 @@ -import { IconPhoto } from "@tabler/icons-react"; +import { IconAlertHexagon } from "@tabler/icons-react"; import { TbSettings } from "react-icons/tb"; import { useBknd } from "ui/client/BkndProvider"; import { IconButton } from "ui/components/buttons/IconButton"; -import { Empty } from "ui/components/display/Empty"; import { Link } from "ui/components/wouter/Link"; import { Media } from "ui/elements"; import { useBrowserTitle } from "ui/hooks/use-browser-title"; import * as AppShell from "ui/layouts/AppShell/AppShell"; -import { useLocation } from "wouter"; export function MediaRoot({ children }) { const { app, config } = useBknd(); - const [, navigate] = useLocation(); + const mediaDisabled = !config.media.enabled; useBrowserTitle(["Media"]); - if (!config.media.enabled) { - return ( - navigate(app.getSettingsPath(["media"])) - }} - /> - ); - } - return ( <> @@ -42,12 +26,13 @@ export function MediaRoot({ children }) {
- {/*
- -
*/}