@jant/core 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +112 -85
- package/dist/auth.d.ts +1 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +2 -1
- package/dist/client.js +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/i18n/context.d.ts.map +1 -1
- package/dist/i18n/context.js +0 -3
- package/dist/i18n/detect.d.ts +0 -11
- package/dist/i18n/detect.d.ts.map +1 -1
- package/dist/i18n/detect.js +1 -52
- package/dist/i18n/i18n.d.ts +4 -14
- package/dist/i18n/i18n.d.ts.map +1 -1
- package/dist/i18n/i18n.js +19 -25
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/middleware.d.ts +2 -5
- package/dist/i18n/middleware.d.ts.map +1 -1
- package/dist/i18n/middleware.js +12 -23
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/sse.d.ts +45 -17
- package/dist/lib/sse.d.ts.map +1 -1
- package/dist/lib/sse.js +77 -37
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/routes/api/posts.js +0 -1
- package/dist/routes/api/upload.js +13 -3
- package/dist/routes/dash/collections.d.ts.map +1 -1
- package/dist/routes/dash/collections.js +134 -142
- package/dist/routes/dash/index.js +25 -25
- package/dist/routes/dash/media.d.ts.map +1 -1
- package/dist/routes/dash/media.js +60 -56
- package/dist/routes/dash/pages.d.ts.map +1 -1
- package/dist/routes/dash/pages.js +64 -66
- package/dist/routes/dash/posts.d.ts.map +1 -1
- package/dist/routes/dash/posts.js +50 -59
- package/dist/routes/dash/redirects.d.ts.map +1 -1
- package/dist/routes/dash/redirects.js +63 -60
- package/dist/routes/dash/settings.d.ts.map +1 -1
- package/dist/routes/dash/settings.js +249 -93
- package/dist/routes/feed/rss.js +6 -4
- package/dist/routes/pages/archive.js +60 -62
- package/dist/routes/pages/collection.js +8 -8
- package/dist/routes/pages/home.js +14 -14
- package/dist/routes/pages/page.js +7 -6
- package/dist/routes/pages/post.js +8 -8
- package/dist/routes/pages/search.js +25 -27
- package/dist/services/collection.d.ts.map +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/media.d.ts.map +1 -1
- package/dist/services/post.d.ts.map +1 -1
- package/dist/services/redirect.d.ts.map +1 -1
- package/dist/services/settings.d.ts.map +1 -1
- package/dist/theme/components/ActionButtons.d.ts +1 -1
- package/dist/theme/components/ActionButtons.d.ts.map +1 -1
- package/dist/theme/components/ActionButtons.js +17 -21
- package/dist/theme/components/CrudPageHeader.d.ts.map +1 -1
- package/dist/theme/components/DangerZone.d.ts.map +1 -1
- package/dist/theme/components/DangerZone.js +12 -15
- package/dist/theme/components/EmptyState.d.ts.map +1 -1
- package/dist/theme/components/PageForm.d.ts.map +1 -1
- package/dist/theme/components/PageForm.js +58 -56
- package/dist/theme/components/Pagination.d.ts.map +1 -1
- package/dist/theme/components/Pagination.js +22 -25
- package/dist/theme/components/PostForm.d.ts +0 -1
- package/dist/theme/components/PostForm.d.ts.map +1 -1
- package/dist/theme/components/PostForm.js +85 -77
- package/dist/theme/components/PostList.d.ts.map +1 -1
- package/dist/theme/components/PostList.js +17 -17
- package/dist/theme/components/ThreadView.d.ts.map +1 -1
- package/dist/theme/components/ThreadView.js +15 -18
- package/dist/theme/components/TypeBadge.d.ts.map +1 -1
- package/dist/theme/components/TypeBadge.js +20 -20
- package/dist/theme/components/VisibilityBadge.d.ts.map +1 -1
- package/dist/theme/components/VisibilityBadge.js +14 -14
- package/dist/theme/components/index.d.ts +2 -2
- package/dist/theme/components/index.d.ts.map +1 -1
- package/dist/theme/layouts/BaseLayout.d.ts.map +1 -1
- package/dist/theme/layouts/BaseLayout.js +4 -2
- package/dist/theme/layouts/DashLayout.d.ts.map +1 -1
- package/dist/theme/layouts/DashLayout.js +29 -29
- package/dist/types/lingui-react-macro.d.js +9 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vendor/datastar.js +1606 -0
- package/package.json +7 -15
- package/src/app.tsx +222 -59
- package/src/auth.ts +5 -1
- package/src/client.ts +1 -1
- package/src/db/migrations/meta/0000_snapshot.json +16 -47
- package/src/db/migrations/meta/_journal.json +1 -1
- package/src/db/schema.ts +22 -7
- package/src/i18n/EXAMPLES.md +45 -23
- package/src/i18n/README.md +39 -25
- package/src/i18n/context.tsx +1 -4
- package/src/i18n/detect.ts +1 -67
- package/src/i18n/i18n.ts +15 -19
- package/src/i18n/index.ts +0 -3
- package/src/i18n/middleware.ts +12 -24
- package/src/lib/constants.ts +2 -1
- package/src/lib/image-processor.ts +14 -6
- package/src/lib/image.ts +2 -2
- package/src/lib/schemas.ts +7 -3
- package/src/lib/sse.ts +133 -51
- package/src/middleware/auth.ts +6 -2
- package/src/routes/api/posts.ts +9 -9
- package/src/routes/api/upload.ts +39 -10
- package/src/routes/dash/collections.tsx +249 -81
- package/src/routes/dash/index.tsx +22 -7
- package/src/routes/dash/media.tsx +94 -24
- package/src/routes/dash/pages.tsx +132 -54
- package/src/routes/dash/posts.tsx +99 -57
- package/src/routes/dash/redirects.tsx +117 -36
- package/src/routes/dash/settings.tsx +268 -55
- package/src/routes/feed/rss.ts +6 -4
- package/src/routes/pages/archive.tsx +78 -24
- package/src/routes/pages/collection.tsx +32 -8
- package/src/routes/pages/home.tsx +38 -10
- package/src/routes/pages/page.tsx +15 -5
- package/src/routes/pages/post.tsx +17 -6
- package/src/routes/pages/search.tsx +50 -13
- package/src/services/collection.ts +29 -8
- package/src/services/index.ts +4 -1
- package/src/services/media.ts +15 -3
- package/src/services/post.ts +37 -10
- package/src/services/redirect.ts +4 -1
- package/src/services/settings.ts +14 -3
- package/src/theme/components/ActionButtons.tsx +31 -15
- package/src/theme/components/CrudPageHeader.tsx +3 -4
- package/src/theme/components/DangerZone.tsx +19 -13
- package/src/theme/components/EmptyState.tsx +1 -5
- package/src/theme/components/PageForm.tsx +80 -25
- package/src/theme/components/Pagination.tsx +34 -31
- package/src/theme/components/PostForm.tsx +91 -27
- package/src/theme/components/PostList.tsx +23 -6
- package/src/theme/components/ThreadView.tsx +25 -10
- package/src/theme/components/TypeBadge.tsx +13 -4
- package/src/theme/components/VisibilityBadge.tsx +17 -5
- package/src/theme/components/index.ts +12 -2
- package/src/theme/layouts/BaseLayout.tsx +6 -5
- package/src/theme/layouts/DashLayout.tsx +71 -18
- package/src/types/lingui-react-macro.d.ts +34 -0
- package/src/types.ts +16 -4
- package/src/vendor/datastar.js +9 -0
- package/src/vendor/datastar.js.map +7 -0
- package/dist/plugin.d.ts +0 -3
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -20
- package/dist/tailwind.d.ts +0 -12
- package/dist/tailwind.d.ts.map +0 -1
- package/dist/tailwind.js +0 -15
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAGlD,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoCvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,MAAM,GAAE,UAAe,GAAG,GAAG,CAodtD"}
|
package/dist/app.js
CHANGED
|
@@ -5,7 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
|
5
5
|
import { createDatabase } from "./db/index.js";
|
|
6
6
|
import { createServices } from "./services/index.js";
|
|
7
7
|
import { createAuth } from "./auth.js";
|
|
8
|
-
import { i18nMiddleware
|
|
8
|
+
import { i18nMiddleware } from "./i18n/index.js";
|
|
9
|
+
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
9
10
|
// Routes - Pages
|
|
10
11
|
import { homeRoutes } from "./routes/pages/home.js";
|
|
11
12
|
import { postRoutes } from "./routes/pages/post.js";
|
|
@@ -32,6 +33,7 @@ import { sitemapRoutes } from "./routes/feed/sitemap.js";
|
|
|
32
33
|
import { requireAuth } from "./middleware/auth.js";
|
|
33
34
|
// Layouts for auth pages
|
|
34
35
|
import { BaseLayout } from "./theme/layouts/index.js";
|
|
36
|
+
import { sse } from "./lib/sse.js";
|
|
35
37
|
/**
|
|
36
38
|
* Create a Jant application
|
|
37
39
|
*
|
|
@@ -106,8 +108,8 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
106
108
|
// API Routes
|
|
107
109
|
app.route("/api/posts", postsApiRoutes);
|
|
108
110
|
// Setup page component
|
|
109
|
-
const SetupContent = (
|
|
110
|
-
const {
|
|
111
|
+
const SetupContent = ()=>{
|
|
112
|
+
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
111
113
|
return /*#__PURE__*/ _jsx("div", {
|
|
112
114
|
class: "min-h-screen flex items-center justify-center",
|
|
113
115
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
@@ -116,28 +118,27 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
116
118
|
/*#__PURE__*/ _jsxs("header", {
|
|
117
119
|
children: [
|
|
118
120
|
/*#__PURE__*/ _jsx("h2", {
|
|
119
|
-
children:
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
children: $__i18n._({
|
|
122
|
+
id: "GorKul",
|
|
123
|
+
message: "Welcome to Jant"
|
|
122
124
|
})
|
|
123
125
|
}),
|
|
124
126
|
/*#__PURE__*/ _jsx("p", {
|
|
125
|
-
children:
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
children: $__i18n._({
|
|
128
|
+
id: "ig4hg2",
|
|
129
|
+
message: "Let's set up your site."
|
|
128
130
|
})
|
|
129
131
|
})
|
|
130
132
|
]
|
|
131
133
|
}),
|
|
132
134
|
/*#__PURE__*/ _jsxs("section", {
|
|
133
135
|
children: [
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
children: error
|
|
136
|
+
/*#__PURE__*/ _jsx("div", {
|
|
137
|
+
id: "setup-message"
|
|
137
138
|
}),
|
|
138
139
|
/*#__PURE__*/ _jsxs("form", {
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
"data-signals": "{siteName: '', name: '', email: '', password: ''}",
|
|
141
|
+
"data-on:submit__prevent": "@post('/setup')",
|
|
141
142
|
class: "flex flex-col gap-4",
|
|
142
143
|
children: [
|
|
143
144
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -145,19 +146,19 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
145
146
|
children: [
|
|
146
147
|
/*#__PURE__*/ _jsx("label", {
|
|
147
148
|
class: "label",
|
|
148
|
-
children:
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
children: $__i18n._({
|
|
150
|
+
id: "SJmfuf",
|
|
151
|
+
message: "Site Name"
|
|
151
152
|
})
|
|
152
153
|
}),
|
|
153
154
|
/*#__PURE__*/ _jsx("input", {
|
|
154
155
|
type: "text",
|
|
155
|
-
|
|
156
|
+
"data-bind": "siteName",
|
|
156
157
|
class: "input",
|
|
157
158
|
required: true,
|
|
158
|
-
placeholder:
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
placeholder: $__i18n._({
|
|
160
|
+
id: "HfyyXl",
|
|
161
|
+
message: "My Blog"
|
|
161
162
|
})
|
|
162
163
|
})
|
|
163
164
|
]
|
|
@@ -167,14 +168,14 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
167
168
|
children: [
|
|
168
169
|
/*#__PURE__*/ _jsx("label", {
|
|
169
170
|
class: "label",
|
|
170
|
-
children:
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
children: $__i18n._({
|
|
172
|
+
id: "/Rj5P4",
|
|
173
|
+
message: "Your Name"
|
|
173
174
|
})
|
|
174
175
|
}),
|
|
175
176
|
/*#__PURE__*/ _jsx("input", {
|
|
176
177
|
type: "text",
|
|
177
|
-
|
|
178
|
+
"data-bind": "name",
|
|
178
179
|
class: "input",
|
|
179
180
|
required: true,
|
|
180
181
|
placeholder: "John Doe"
|
|
@@ -186,14 +187,14 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
186
187
|
children: [
|
|
187
188
|
/*#__PURE__*/ _jsx("label", {
|
|
188
189
|
class: "label",
|
|
189
|
-
children:
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
children: $__i18n._({
|
|
191
|
+
id: "O3oNi5",
|
|
192
|
+
message: "Email"
|
|
192
193
|
})
|
|
193
194
|
}),
|
|
194
195
|
/*#__PURE__*/ _jsx("input", {
|
|
195
196
|
type: "email",
|
|
196
|
-
|
|
197
|
+
"data-bind": "email",
|
|
197
198
|
class: "input",
|
|
198
199
|
required: true,
|
|
199
200
|
placeholder: "you@example.com"
|
|
@@ -205,14 +206,14 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
205
206
|
children: [
|
|
206
207
|
/*#__PURE__*/ _jsx("label", {
|
|
207
208
|
class: "label",
|
|
208
|
-
children:
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
children: $__i18n._({
|
|
210
|
+
id: "8ZsakT",
|
|
211
|
+
message: "Password"
|
|
211
212
|
})
|
|
212
213
|
}),
|
|
213
214
|
/*#__PURE__*/ _jsx("input", {
|
|
214
215
|
type: "password",
|
|
215
|
-
|
|
216
|
+
"data-bind": "password",
|
|
216
217
|
class: "input",
|
|
217
218
|
required: true,
|
|
218
219
|
minLength: 8
|
|
@@ -222,9 +223,9 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
222
223
|
/*#__PURE__*/ _jsx("button", {
|
|
223
224
|
type: "submit",
|
|
224
225
|
class: "btn",
|
|
225
|
-
children:
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
children: $__i18n._({
|
|
227
|
+
id: "EGwzOK",
|
|
228
|
+
message: "Complete Setup"
|
|
228
229
|
})
|
|
229
230
|
})
|
|
230
231
|
]
|
|
@@ -239,31 +240,31 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
239
240
|
app.get("/setup", async (c)=>{
|
|
240
241
|
const isComplete = await c.var.services.settings.isOnboardingComplete();
|
|
241
242
|
if (isComplete) return c.redirect("/");
|
|
242
|
-
const error = c.req.query("error");
|
|
243
243
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
244
244
|
title: "Setup - Jant",
|
|
245
245
|
c: c,
|
|
246
|
-
children: /*#__PURE__*/ _jsx(SetupContent, {
|
|
247
|
-
error: error
|
|
248
|
-
})
|
|
246
|
+
children: /*#__PURE__*/ _jsx(SetupContent, {})
|
|
249
247
|
}));
|
|
250
248
|
});
|
|
251
249
|
app.post("/setup", async (c)=>{
|
|
252
250
|
const isComplete = await c.var.services.settings.isOnboardingComplete();
|
|
253
251
|
if (isComplete) return c.redirect("/");
|
|
254
|
-
const
|
|
255
|
-
const siteName =
|
|
256
|
-
const name = formData.get("name");
|
|
257
|
-
const email = formData.get("email");
|
|
258
|
-
const password = formData.get("password");
|
|
252
|
+
const body = await c.req.json();
|
|
253
|
+
const { siteName, name, email, password } = body;
|
|
259
254
|
if (!siteName || !name || !email || !password) {
|
|
260
|
-
return c
|
|
255
|
+
return sse(c, async (stream)=>{
|
|
256
|
+
await stream.patchElements('<div id="setup-message"><p class="text-destructive text-sm mb-4">All fields are required</p></div>');
|
|
257
|
+
});
|
|
261
258
|
}
|
|
262
259
|
if (password.length < 8) {
|
|
263
|
-
return c
|
|
260
|
+
return sse(c, async (stream)=>{
|
|
261
|
+
await stream.patchElements('<div id="setup-message"><p class="text-destructive text-sm mb-4">Password must be at least 8 characters</p></div>');
|
|
262
|
+
});
|
|
264
263
|
}
|
|
265
264
|
if (!c.var.auth) {
|
|
266
|
-
return c
|
|
265
|
+
return sse(c, async (stream)=>{
|
|
266
|
+
await stream.patchElements('<div id="setup-message"><p class="text-destructive text-sm mb-4">AUTH_SECRET not configured</p></div>');
|
|
267
|
+
});
|
|
267
268
|
}
|
|
268
269
|
try {
|
|
269
270
|
const signUpResponse = await c.var.auth.api.signUpEmail({
|
|
@@ -274,23 +275,33 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
274
275
|
}
|
|
275
276
|
});
|
|
276
277
|
if (!signUpResponse || "error" in signUpResponse) {
|
|
277
|
-
return c
|
|
278
|
+
return sse(c, async (stream)=>{
|
|
279
|
+
await stream.patchElements('<div id="setup-message"><p class="text-destructive text-sm mb-4">Failed to create account</p></div>');
|
|
280
|
+
});
|
|
278
281
|
}
|
|
279
282
|
await c.var.services.settings.setMany({
|
|
280
283
|
SITE_NAME: siteName,
|
|
281
284
|
SITE_LANGUAGE: "en"
|
|
282
285
|
});
|
|
283
286
|
await c.var.services.settings.completeOnboarding();
|
|
284
|
-
return c
|
|
287
|
+
return sse(c, async (stream)=>{
|
|
288
|
+
await stream.redirect("/signin");
|
|
289
|
+
});
|
|
285
290
|
} catch (err) {
|
|
286
291
|
// eslint-disable-next-line no-console -- Error logging is intentional
|
|
287
292
|
console.error("Setup error:", err);
|
|
288
|
-
return c
|
|
293
|
+
return sse(c, async (stream)=>{
|
|
294
|
+
await stream.patchElements('<div id="setup-message"><p class="text-destructive text-sm mb-4">Failed to create account</p></div>');
|
|
295
|
+
});
|
|
289
296
|
}
|
|
290
297
|
});
|
|
291
298
|
// Signin page component
|
|
292
|
-
const SigninContent = ({
|
|
293
|
-
const {
|
|
299
|
+
const SigninContent = ({ demoEmail, demoPassword })=>{
|
|
300
|
+
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
301
|
+
const signals = JSON.stringify({
|
|
302
|
+
email: demoEmail || "",
|
|
303
|
+
password: demoPassword || ""
|
|
304
|
+
}).replace(/</g, "\\u003c");
|
|
294
305
|
return /*#__PURE__*/ _jsx("div", {
|
|
295
306
|
class: "min-h-screen flex items-center justify-center",
|
|
296
307
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
@@ -298,21 +309,27 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
298
309
|
children: [
|
|
299
310
|
/*#__PURE__*/ _jsx("header", {
|
|
300
311
|
children: /*#__PURE__*/ _jsx("h2", {
|
|
301
|
-
children:
|
|
302
|
-
|
|
303
|
-
|
|
312
|
+
children: $__i18n._({
|
|
313
|
+
id: "n1ekoW",
|
|
314
|
+
message: "Sign In"
|
|
304
315
|
})
|
|
305
316
|
})
|
|
306
317
|
}),
|
|
307
318
|
/*#__PURE__*/ _jsxs("section", {
|
|
308
319
|
children: [
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
320
|
+
/*#__PURE__*/ _jsx("div", {
|
|
321
|
+
id: "signin-message"
|
|
322
|
+
}),
|
|
323
|
+
demoEmail && demoPassword && /*#__PURE__*/ _jsx("p", {
|
|
324
|
+
class: "text-muted-foreground text-sm mb-4",
|
|
325
|
+
children: $__i18n._({
|
|
326
|
+
id: "er8+x7",
|
|
327
|
+
message: "Demo account pre-filled. Just click Sign In."
|
|
328
|
+
})
|
|
312
329
|
}),
|
|
313
330
|
/*#__PURE__*/ _jsxs("form", {
|
|
314
|
-
|
|
315
|
-
|
|
331
|
+
"data-signals": signals,
|
|
332
|
+
"data-on:submit__prevent": "@post('/signin')",
|
|
316
333
|
class: "flex flex-col gap-4",
|
|
317
334
|
children: [
|
|
318
335
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -320,14 +337,14 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
320
337
|
children: [
|
|
321
338
|
/*#__PURE__*/ _jsx("label", {
|
|
322
339
|
class: "label",
|
|
323
|
-
children:
|
|
324
|
-
|
|
325
|
-
|
|
340
|
+
children: $__i18n._({
|
|
341
|
+
id: "O3oNi5",
|
|
342
|
+
message: "Email"
|
|
326
343
|
})
|
|
327
344
|
}),
|
|
328
345
|
/*#__PURE__*/ _jsx("input", {
|
|
329
346
|
type: "email",
|
|
330
|
-
|
|
347
|
+
"data-bind": "email",
|
|
331
348
|
class: "input",
|
|
332
349
|
required: true
|
|
333
350
|
})
|
|
@@ -338,14 +355,14 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
338
355
|
children: [
|
|
339
356
|
/*#__PURE__*/ _jsx("label", {
|
|
340
357
|
class: "label",
|
|
341
|
-
children:
|
|
342
|
-
|
|
343
|
-
|
|
358
|
+
children: $__i18n._({
|
|
359
|
+
id: "8ZsakT",
|
|
360
|
+
message: "Password"
|
|
344
361
|
})
|
|
345
362
|
}),
|
|
346
363
|
/*#__PURE__*/ _jsx("input", {
|
|
347
364
|
type: "password",
|
|
348
|
-
|
|
365
|
+
"data-bind": "password",
|
|
349
366
|
class: "input",
|
|
350
367
|
required: true
|
|
351
368
|
})
|
|
@@ -354,9 +371,9 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
354
371
|
/*#__PURE__*/ _jsx("button", {
|
|
355
372
|
type: "submit",
|
|
356
373
|
class: "btn",
|
|
357
|
-
children:
|
|
358
|
-
|
|
359
|
-
|
|
374
|
+
children: $__i18n._({
|
|
375
|
+
id: "n1ekoW",
|
|
376
|
+
message: "Sign In"
|
|
360
377
|
})
|
|
361
378
|
})
|
|
362
379
|
]
|
|
@@ -369,22 +386,23 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
369
386
|
};
|
|
370
387
|
// Signin page
|
|
371
388
|
app.get("/signin", async (c)=>{
|
|
372
|
-
const error = c.req.query("error");
|
|
373
389
|
return c.html(/*#__PURE__*/ _jsx(BaseLayout, {
|
|
374
390
|
title: "Sign In - Jant",
|
|
375
391
|
c: c,
|
|
376
392
|
children: /*#__PURE__*/ _jsx(SigninContent, {
|
|
377
|
-
|
|
393
|
+
demoEmail: c.env.DEMO_EMAIL,
|
|
394
|
+
demoPassword: c.env.DEMO_PASSWORD
|
|
378
395
|
})
|
|
379
396
|
}));
|
|
380
397
|
});
|
|
381
398
|
app.post("/signin", async (c)=>{
|
|
382
399
|
if (!c.var.auth) {
|
|
383
|
-
return c
|
|
400
|
+
return sse(c, async (stream)=>{
|
|
401
|
+
await stream.patchElements('<div id="signin-message"><p class="text-destructive text-sm mb-4">Auth not configured</p></div>');
|
|
402
|
+
});
|
|
384
403
|
}
|
|
385
|
-
const
|
|
386
|
-
const email =
|
|
387
|
-
const password = formData.get("password");
|
|
404
|
+
const body = await c.req.json();
|
|
405
|
+
const { email, password } = body;
|
|
388
406
|
try {
|
|
389
407
|
const signInRequest = new Request(`${c.env.SITE_URL}/api/auth/sign-in/email`, {
|
|
390
408
|
method: "POST",
|
|
@@ -398,18 +416,27 @@ import { BaseLayout } from "./theme/layouts/index.js";
|
|
|
398
416
|
});
|
|
399
417
|
const response = await c.var.auth.handler(signInRequest);
|
|
400
418
|
if (!response.ok) {
|
|
401
|
-
return c
|
|
419
|
+
return sse(c, async (stream)=>{
|
|
420
|
+
await stream.patchElements('<div id="signin-message"><p class="text-destructive text-sm mb-4">Invalid email or password</p></div>');
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
// Forward Set-Cookie headers from auth response
|
|
424
|
+
const cookieHeaders = {};
|
|
425
|
+
const setCookie = response.headers.get("set-cookie");
|
|
426
|
+
if (setCookie) {
|
|
427
|
+
cookieHeaders["Set-Cookie"] = setCookie;
|
|
402
428
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
headers
|
|
429
|
+
return sse(c, async (stream)=>{
|
|
430
|
+
await stream.redirect("/dash");
|
|
431
|
+
}, {
|
|
432
|
+
headers: cookieHeaders
|
|
408
433
|
});
|
|
409
434
|
} catch (err) {
|
|
410
435
|
// eslint-disable-next-line no-console -- Error logging is intentional
|
|
411
436
|
console.error("Signin error:", err);
|
|
412
|
-
return c
|
|
437
|
+
return sse(c, async (stream)=>{
|
|
438
|
+
await stream.patchElements('<div id="signin-message"><p class="text-destructive text-sm mb-4">Invalid email or password</p></div>');
|
|
439
|
+
});
|
|
413
440
|
}
|
|
414
441
|
});
|
|
415
442
|
app.get("/signout", async (c)=>{
|
package/dist/auth.d.ts
CHANGED
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,UAAU,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,UAAU,CACxB,EAAE,EAAE,UAAU,EACd,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;GA4B7C;AAED,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
package/dist/auth.js
CHANGED
package/dist/client.js
CHANGED
package/dist/db/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBhB,CAAC;AAMH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYhB,CAAC;AAMH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOtB,CAAC;AAMH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY3B,CAAC;AAMF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMpB,CAAC;AAMH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAInB,CAAC;AAOH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWf,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWlB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBlB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/i18n/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAG5D;;;GAGG;AACH,KAAK,qBAAqB,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAKF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,CAAC,EAAE,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAM9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS;;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/i18n/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAG5D;;;GAGG;AACH,KAAK,qBAAqB,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAKF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,CAAC,EAAE,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAM9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS;;oBAQQ,qBAAqB;oBAArB,qBAAqB;EAYrD"}
|
package/dist/i18n/context.js
CHANGED
|
@@ -44,10 +44,7 @@ export const I18nProvider = ({ c, children })=>{
|
|
|
44
44
|
if (!currentI18n) {
|
|
45
45
|
throw new Error("useLingui() called outside of I18nProvider. " + "Make sure your component is wrapped in <I18nProvider c={c}>...</I18nProvider>");
|
|
46
46
|
}
|
|
47
|
-
// Create translation function that accepts both pre-macro and post-macro formats
|
|
48
47
|
const translate = (descriptor)=>{
|
|
49
|
-
// The macro will add the id, or it's already present
|
|
50
|
-
// At runtime, we pass it to i18n._ which handles the descriptor with values
|
|
51
48
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- currentI18n is checked above
|
|
52
49
|
return currentI18n._(descriptor);
|
|
53
50
|
};
|
package/dist/i18n/detect.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Language Detection Utilities
|
|
3
3
|
*/
|
|
4
|
-
import type { Context } from "hono";
|
|
5
4
|
import { type Locale } from "./locales.js";
|
|
6
|
-
export declare const LANGUAGE_COOKIE_NAME = "lang";
|
|
7
5
|
/**
|
|
8
6
|
* Get display name for a language code
|
|
9
7
|
*/
|
|
@@ -19,13 +17,4 @@ export declare function getSupportedLanguages(): Array<{
|
|
|
19
17
|
* Check if a language code is valid
|
|
20
18
|
*/
|
|
21
19
|
export declare function isValidLanguage(lang: unknown): lang is Locale;
|
|
22
|
-
/**
|
|
23
|
-
* Parse Accept-Language header and return best matching locale
|
|
24
|
-
*/
|
|
25
|
-
export declare function parseAcceptLanguage(header: string | null): Locale;
|
|
26
|
-
/**
|
|
27
|
-
* Detect user's preferred language from Hono context
|
|
28
|
-
* Priority: Cookie > Accept-Language header > Default
|
|
29
|
-
*/
|
|
30
|
-
export declare function detectLanguage(c: Context): Locale;
|
|
31
20
|
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/i18n/detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/i18n/detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9D;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAK7E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAE7D"}
|
package/dist/i18n/detect.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Language Detection Utilities
|
|
3
|
-
*/ import { locales,
|
|
4
|
-
export const LANGUAGE_COOKIE_NAME = "lang";
|
|
3
|
+
*/ import { locales, isLocale } from "./locales.js";
|
|
5
4
|
/**
|
|
6
5
|
* Get display name for a language code
|
|
7
6
|
*/ export function getLanguageDisplayName(locale) {
|
|
@@ -25,53 +24,3 @@ export const LANGUAGE_COOKIE_NAME = "lang";
|
|
|
25
24
|
*/ export function isValidLanguage(lang) {
|
|
26
25
|
return isLocale(lang);
|
|
27
26
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Parse Accept-Language header and return best matching locale
|
|
30
|
-
*/ export function parseAcceptLanguage(header) {
|
|
31
|
-
if (!header) return baseLocale;
|
|
32
|
-
// Parse "en-US,en;q=0.9,zh-CN;q=0.8" format
|
|
33
|
-
const languages = header.split(",").map((part)=>{
|
|
34
|
-
const [lang, qPart] = part.trim().split(";");
|
|
35
|
-
const q = qPart ? parseFloat(qPart.replace("q=", "")) : 1;
|
|
36
|
-
return {
|
|
37
|
-
lang: lang?.trim() ?? "",
|
|
38
|
-
q
|
|
39
|
-
};
|
|
40
|
-
}).sort((a, b)=>b.q - a.q);
|
|
41
|
-
for (const { lang } of languages){
|
|
42
|
-
// Direct match
|
|
43
|
-
if (isLocale(lang)) {
|
|
44
|
-
return lang;
|
|
45
|
-
}
|
|
46
|
-
// Map common variants
|
|
47
|
-
const normalized = lang.toLowerCase();
|
|
48
|
-
if (normalized.startsWith("zh-cn") || normalized.startsWith("zh-hans")) {
|
|
49
|
-
return "zh-Hans";
|
|
50
|
-
}
|
|
51
|
-
if (normalized.startsWith("zh-tw") || normalized.startsWith("zh-hk") || normalized.startsWith("zh-hant")) {
|
|
52
|
-
return "zh-Hant";
|
|
53
|
-
}
|
|
54
|
-
if (normalized.startsWith("zh")) {
|
|
55
|
-
return "zh-Hans"; // Default Chinese to Simplified
|
|
56
|
-
}
|
|
57
|
-
if (normalized.startsWith("en")) {
|
|
58
|
-
return "en";
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return baseLocale;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Detect user's preferred language from Hono context
|
|
65
|
-
* Priority: Cookie > Accept-Language header > Default
|
|
66
|
-
*/ export function detectLanguage(c) {
|
|
67
|
-
// 1. Check cookie (using getCookie helper)
|
|
68
|
-
const cookies = c.req.raw.headers.get("Cookie") ?? "";
|
|
69
|
-
const cookieMatch = cookies.match(new RegExp(`${LANGUAGE_COOKIE_NAME}=([^;]+)`));
|
|
70
|
-
const cookieLang = cookieMatch?.[1];
|
|
71
|
-
if (cookieLang && isLocale(cookieLang)) {
|
|
72
|
-
return cookieLang;
|
|
73
|
-
}
|
|
74
|
-
// 2. Check Accept-Language header
|
|
75
|
-
const acceptLang = c.req.header("Accept-Language") ?? null;
|
|
76
|
-
return parseAcceptLanguage(acceptLang);
|
|
77
|
-
}
|
package/dist/i18n/i18n.d.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* i18n Runtime using @lingui/core
|
|
2
|
+
* i18n Runtime using @lingui/core
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* const { i18n } = bindI18n(c.get("i18n"));
|
|
9
|
-
*
|
|
10
|
-
* // Simple message
|
|
11
|
-
* i18n._(msg({ message: "Hello", comment: "@context: Greeting" }))
|
|
12
|
-
*
|
|
13
|
-
* // With interpolation
|
|
14
|
-
* i18n._(msg({ message: "Welcome, {name}!", comment: "@context: Welcome" }), { name })
|
|
15
|
-
*
|
|
16
|
-
* The msg macro generates hash-based IDs at compile time, which match the compiled catalogs.
|
|
4
|
+
* The SWC Lingui plugin adds hash-based IDs to t() calls when imports come
|
|
5
|
+
* from @lingui/react/macro. The runtimeConfigModule setting rewrites those
|
|
6
|
+
* imports to our custom Hono JSX implementation at build time.
|
|
17
7
|
*/
|
|
18
8
|
import { I18n } from "@lingui/core";
|
|
19
9
|
import { locales, baseLocale, isLocale, type Locale } from "./locales.js";
|
package/dist/i18n/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/i18n/i18n.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/i18n/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAK1E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;AAGtD,YAAY,EAAE,IAAI,EAAE,CAAC;AASrB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAU/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAE3D"}
|