llmapi-v2 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/.env.example +40 -0
  2. package/Dockerfile +17 -0
  3. package/dist/config.d.ts +48 -0
  4. package/dist/config.js +98 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/converter/request.d.ts +6 -0
  7. package/dist/converter/request.js +184 -0
  8. package/dist/converter/request.js.map +1 -0
  9. package/dist/converter/response.d.ts +6 -0
  10. package/dist/converter/response.js +76 -0
  11. package/dist/converter/response.js.map +1 -0
  12. package/dist/converter/stream.d.ts +54 -0
  13. package/dist/converter/stream.js +318 -0
  14. package/dist/converter/stream.js.map +1 -0
  15. package/dist/converter/types.d.ts +239 -0
  16. package/dist/converter/types.js +6 -0
  17. package/dist/converter/types.js.map +1 -0
  18. package/dist/data/posts.d.ts +19 -0
  19. package/dist/data/posts.js +462 -0
  20. package/dist/data/posts.js.map +1 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +233 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/middleware/api-key-auth.d.ts +6 -0
  25. package/dist/middleware/api-key-auth.js +76 -0
  26. package/dist/middleware/api-key-auth.js.map +1 -0
  27. package/dist/middleware/quota-guard.d.ts +10 -0
  28. package/dist/middleware/quota-guard.js +27 -0
  29. package/dist/middleware/quota-guard.js.map +1 -0
  30. package/dist/middleware/rate-limiter.d.ts +5 -0
  31. package/dist/middleware/rate-limiter.js +50 -0
  32. package/dist/middleware/rate-limiter.js.map +1 -0
  33. package/dist/middleware/request-logger.d.ts +6 -0
  34. package/dist/middleware/request-logger.js +37 -0
  35. package/dist/middleware/request-logger.js.map +1 -0
  36. package/dist/middleware/session-auth.d.ts +19 -0
  37. package/dist/middleware/session-auth.js +99 -0
  38. package/dist/middleware/session-auth.js.map +1 -0
  39. package/dist/providers/aliyun.d.ts +13 -0
  40. package/dist/providers/aliyun.js +20 -0
  41. package/dist/providers/aliyun.js.map +1 -0
  42. package/dist/providers/base-provider.d.ts +36 -0
  43. package/dist/providers/base-provider.js +133 -0
  44. package/dist/providers/base-provider.js.map +1 -0
  45. package/dist/providers/deepseek.d.ts +11 -0
  46. package/dist/providers/deepseek.js +18 -0
  47. package/dist/providers/deepseek.js.map +1 -0
  48. package/dist/providers/registry.d.ts +18 -0
  49. package/dist/providers/registry.js +98 -0
  50. package/dist/providers/registry.js.map +1 -0
  51. package/dist/providers/types.d.ts +17 -0
  52. package/dist/providers/types.js +3 -0
  53. package/dist/providers/types.js.map +1 -0
  54. package/dist/routes/admin.d.ts +1 -0
  55. package/dist/routes/admin.js +153 -0
  56. package/dist/routes/admin.js.map +1 -0
  57. package/dist/routes/auth.d.ts +2 -0
  58. package/dist/routes/auth.js +318 -0
  59. package/dist/routes/auth.js.map +1 -0
  60. package/dist/routes/blog.d.ts +1 -0
  61. package/dist/routes/blog.js +29 -0
  62. package/dist/routes/blog.js.map +1 -0
  63. package/dist/routes/dashboard.d.ts +1 -0
  64. package/dist/routes/dashboard.js +184 -0
  65. package/dist/routes/dashboard.js.map +1 -0
  66. package/dist/routes/messages.d.ts +1 -0
  67. package/dist/routes/messages.js +309 -0
  68. package/dist/routes/messages.js.map +1 -0
  69. package/dist/routes/models.d.ts +1 -0
  70. package/dist/routes/models.js +39 -0
  71. package/dist/routes/models.js.map +1 -0
  72. package/dist/routes/payment.d.ts +1 -0
  73. package/dist/routes/payment.js +150 -0
  74. package/dist/routes/payment.js.map +1 -0
  75. package/dist/routes/sitemap.d.ts +1 -0
  76. package/dist/routes/sitemap.js +38 -0
  77. package/dist/routes/sitemap.js.map +1 -0
  78. package/dist/services/alipay.d.ts +27 -0
  79. package/dist/services/alipay.js +106 -0
  80. package/dist/services/alipay.js.map +1 -0
  81. package/dist/services/database.d.ts +4 -0
  82. package/dist/services/database.js +170 -0
  83. package/dist/services/database.js.map +1 -0
  84. package/dist/services/health-checker.d.ts +13 -0
  85. package/dist/services/health-checker.js +95 -0
  86. package/dist/services/health-checker.js.map +1 -0
  87. package/dist/services/mailer.d.ts +3 -0
  88. package/dist/services/mailer.js +91 -0
  89. package/dist/services/mailer.js.map +1 -0
  90. package/dist/services/metrics.d.ts +56 -0
  91. package/dist/services/metrics.js +94 -0
  92. package/dist/services/metrics.js.map +1 -0
  93. package/dist/services/remote-control.d.ts +20 -0
  94. package/dist/services/remote-control.js +209 -0
  95. package/dist/services/remote-control.js.map +1 -0
  96. package/dist/services/remote-ws.d.ts +5 -0
  97. package/dist/services/remote-ws.js +143 -0
  98. package/dist/services/remote-ws.js.map +1 -0
  99. package/dist/services/usage.d.ts +13 -0
  100. package/dist/services/usage.js +39 -0
  101. package/dist/services/usage.js.map +1 -0
  102. package/dist/utils/errors.d.ts +27 -0
  103. package/dist/utils/errors.js +48 -0
  104. package/dist/utils/errors.js.map +1 -0
  105. package/dist/utils/logger.d.ts +2 -0
  106. package/dist/utils/logger.js +14 -0
  107. package/dist/utils/logger.js.map +1 -0
  108. package/docker-compose.yml +19 -0
  109. package/package.json +39 -0
  110. package/public/robots.txt +8 -0
  111. package/src/config.ts +140 -0
  112. package/src/converter/request.ts +207 -0
  113. package/src/converter/response.ts +85 -0
  114. package/src/converter/stream.ts +373 -0
  115. package/src/converter/types.ts +257 -0
  116. package/src/data/posts.ts +474 -0
  117. package/src/index.ts +219 -0
  118. package/src/middleware/api-key-auth.ts +82 -0
  119. package/src/middleware/quota-guard.ts +28 -0
  120. package/src/middleware/rate-limiter.ts +61 -0
  121. package/src/middleware/request-logger.ts +36 -0
  122. package/src/middleware/session-auth.ts +91 -0
  123. package/src/providers/aliyun.ts +16 -0
  124. package/src/providers/base-provider.ts +148 -0
  125. package/src/providers/deepseek.ts +14 -0
  126. package/src/providers/registry.ts +111 -0
  127. package/src/providers/types.ts +26 -0
  128. package/src/routes/admin.ts +169 -0
  129. package/src/routes/auth.ts +369 -0
  130. package/src/routes/blog.ts +28 -0
  131. package/src/routes/dashboard.ts +208 -0
  132. package/src/routes/messages.ts +346 -0
  133. package/src/routes/models.ts +37 -0
  134. package/src/routes/payment.ts +189 -0
  135. package/src/routes/sitemap.ts +40 -0
  136. package/src/services/alipay.ts +116 -0
  137. package/src/services/database.ts +187 -0
  138. package/src/services/health-checker.ts +115 -0
  139. package/src/services/mailer.ts +90 -0
  140. package/src/services/metrics.ts +104 -0
  141. package/src/services/remote-control.ts +226 -0
  142. package/src/services/remote-ws.ts +145 -0
  143. package/src/services/usage.ts +57 -0
  144. package/src/types/express.d.ts +46 -0
  145. package/src/utils/errors.ts +44 -0
  146. package/src/utils/logger.ts +8 -0
  147. package/tsconfig.json +17 -0
  148. package/views/pages/404.ejs +14 -0
  149. package/views/pages/admin.ejs +307 -0
  150. package/views/pages/blog-post.ejs +378 -0
  151. package/views/pages/blog.ejs +148 -0
  152. package/views/pages/dashboard.ejs +441 -0
  153. package/views/pages/docs.ejs +807 -0
  154. package/views/pages/index.ejs +416 -0
  155. package/views/pages/login.ejs +170 -0
  156. package/views/pages/orders.ejs +111 -0
  157. package/views/pages/pricing.ejs +379 -0
  158. package/views/pages/register.ejs +397 -0
  159. package/views/pages/remote.ejs +334 -0
  160. package/views/pages/settings.ejs +373 -0
  161. package/views/partials/header.ejs +70 -0
  162. package/views/partials/nav.ejs +140 -0
@@ -0,0 +1,318 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createAuthRouter = createAuthRouter;
7
+ const express_1 = require("express");
8
+ const bcryptjs_1 = __importDefault(require("bcryptjs"));
9
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
+ const crypto_1 = __importDefault(require("crypto"));
11
+ const database_1 = require("../services/database");
12
+ const session_auth_1 = require("../middleware/session-auth");
13
+ const mailer_1 = require("../services/mailer");
14
+ const logger_1 = require("../utils/logger");
15
+ const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID || '128504392054-4rfrtk05umm9fvfpd83l9qn9r4qnaa98.apps.googleusercontent.com';
16
+ function createAuthRouter(jwtSecret) {
17
+ const router = (0, express_1.Router)();
18
+ // In-memory pending registrations (code -> {email, hash, name, expiresAt})
19
+ const pending = new Map();
20
+ // Cleanup expired entries every 5 min
21
+ setInterval(() => {
22
+ const now = Date.now();
23
+ for (const [key, val] of pending) {
24
+ if (val.expiresAt < now)
25
+ pending.delete(key);
26
+ }
27
+ }, 5 * 60_000);
28
+ /**
29
+ * POST /api/auth/send-code
30
+ * Step 1 of registration: validate inputs, send verification code.
31
+ */
32
+ router.post('/send-code', async (req, res) => {
33
+ try {
34
+ const { email, password, name } = req.body;
35
+ if (!email || !password || !name) {
36
+ res.status(400).json({ success: false, error: 'Missing required fields' });
37
+ return;
38
+ }
39
+ if (password.length < 8) {
40
+ res.status(400).json({ success: false, error: 'Password must be at least 8 characters' });
41
+ return;
42
+ }
43
+ const pool = (0, database_1.getPool)();
44
+ const [existing] = await pool.execute('SELECT id FROM users WHERE email = ?', [email]);
45
+ if (existing.length > 0) {
46
+ res.status(409).json({ success: false, error: 'Email already registered' });
47
+ return;
48
+ }
49
+ const code = String(Math.floor(100000 + Math.random() * 900000));
50
+ const passwordHash = await bcryptjs_1.default.hash(password, 10);
51
+ pending.set(email, {
52
+ email,
53
+ passwordHash,
54
+ name,
55
+ code,
56
+ expiresAt: Date.now() + 30 * 60_000, // 30 min
57
+ });
58
+ await (0, mailer_1.sendVerificationEmail)(email, code, name);
59
+ res.json({ success: true, message: 'Verification code sent' });
60
+ }
61
+ catch (err) {
62
+ logger_1.logger.error({ err }, 'send-code error');
63
+ res.status(500).json({ success: false, error: 'Internal error' });
64
+ }
65
+ });
66
+ /**
67
+ * POST /api/auth/register
68
+ * Step 2: verify code, create user, issue JWT.
69
+ */
70
+ router.post('/register', async (req, res) => {
71
+ try {
72
+ const { email, code } = req.body;
73
+ const entry = pending.get(email);
74
+ if (!entry || entry.code !== code || entry.expiresAt < Date.now()) {
75
+ res.status(400).json({ success: false, error: 'Invalid or expired verification code' });
76
+ return;
77
+ }
78
+ const pool = (0, database_1.getPool)();
79
+ // Create user
80
+ const [result] = await pool.execute('INSERT INTO users (email, password_hash, name, verified, status) VALUES (?, ?, ?, 1, ?)', [entry.email, entry.passwordHash, entry.name, 'active']);
81
+ const userId = result.insertId;
82
+ // Assign free plan
83
+ const [plans] = await pool.execute('SELECT id FROM plans WHERE name = ?', ['free']);
84
+ const planId = plans[0]?.id;
85
+ if (planId) {
86
+ await pool.execute("INSERT INTO subscriptions (user_id, plan_id, period_end) VALUES (?, ?, NOW() + INTERVAL '100 years')", [userId, planId]);
87
+ }
88
+ pending.delete(email);
89
+ // Issue JWT
90
+ const token = jsonwebtoken_1.default.sign({ id: userId }, jwtSecret, { expiresIn: '7d' });
91
+ res.cookie('token', token, { httpOnly: true, maxAge: 7 * 24 * 3600_000, sameSite: 'lax' });
92
+ // Send welcome email (async, don't block)
93
+ (0, mailer_1.sendWelcomeEmail)(entry.email, entry.name).catch(() => { });
94
+ res.json({ success: true, user: { id: userId, email: entry.email, name: entry.name } });
95
+ }
96
+ catch (err) {
97
+ logger_1.logger.error({ err }, 'register error');
98
+ res.status(500).json({ success: false, error: 'Internal error' });
99
+ }
100
+ });
101
+ /**
102
+ * POST /api/auth/login
103
+ */
104
+ router.post('/login', async (req, res) => {
105
+ try {
106
+ const { email, password } = req.body;
107
+ if (!email || !password) {
108
+ res.status(400).json({ success: false, error: 'Email and password required' });
109
+ return;
110
+ }
111
+ const pool = (0, database_1.getPool)();
112
+ const [rows] = await pool.execute('SELECT * FROM users WHERE email = ?', [email]);
113
+ const user = rows[0];
114
+ if (!user || !(await bcryptjs_1.default.compare(password, user.password_hash))) {
115
+ res.status(401).json({ success: false, error: 'Invalid email or password' });
116
+ return;
117
+ }
118
+ if (user.status !== 'active') {
119
+ res.status(403).json({ success: false, error: 'Account suspended' });
120
+ return;
121
+ }
122
+ const token = jsonwebtoken_1.default.sign({ id: user.id }, jwtSecret, { expiresIn: '7d' });
123
+ res.cookie('token', token, { httpOnly: true, maxAge: 7 * 24 * 3600_000, sameSite: 'lax' });
124
+ res.json({ success: true, user: { id: user.id, email: user.email, name: user.name } });
125
+ }
126
+ catch (err) {
127
+ logger_1.logger.error({ err }, 'login error');
128
+ res.status(500).json({ success: false, error: 'Internal error' });
129
+ }
130
+ });
131
+ /**
132
+ * POST /api/auth/logout
133
+ */
134
+ router.post('/logout', (_req, res) => {
135
+ res.clearCookie('token');
136
+ res.json({ success: true });
137
+ });
138
+ /**
139
+ * GET /api/auth/me
140
+ */
141
+ router.get('/me', session_auth_1.sessionAuth, async (req, res) => {
142
+ try {
143
+ const pool = (0, database_1.getPool)();
144
+ const [subs] = await pool.execute(`
145
+ SELECT s.*, p.name as plan_name, p.display_name, p.token_limit_monthly, p.rate_limit_rpm, p.max_api_keys, p.price_monthly
146
+ FROM subscriptions s JOIN plans p ON s.plan_id = p.id
147
+ WHERE s.user_id = ? ORDER BY s.period_start DESC LIMIT 1
148
+ `, [req.userId]);
149
+ res.json({
150
+ success: true,
151
+ user: req.user,
152
+ subscription: subs[0] || null,
153
+ });
154
+ }
155
+ catch (err) {
156
+ logger_1.logger.error({ err }, 'me error');
157
+ res.status(500).json({ success: false, error: 'Internal error' });
158
+ }
159
+ });
160
+ /**
161
+ * POST /api/auth/update-profile
162
+ */
163
+ router.post('/update-profile', session_auth_1.sessionAuth, async (req, res) => {
164
+ try {
165
+ const { name } = req.body;
166
+ if (!name || name.length < 2) {
167
+ res.status(400).json({ success: false, error: 'Name must be at least 2 characters' });
168
+ return;
169
+ }
170
+ const pool = (0, database_1.getPool)();
171
+ await pool.execute('UPDATE users SET name = ? WHERE id = ?', [name, req.userId]);
172
+ res.json({ success: true });
173
+ }
174
+ catch (err) {
175
+ logger_1.logger.error({ err }, 'update-profile error');
176
+ res.status(500).json({ success: false, error: 'Internal error' });
177
+ }
178
+ });
179
+ /**
180
+ * POST /api/auth/change-password
181
+ */
182
+ router.post('/change-password', session_auth_1.sessionAuth, async (req, res) => {
183
+ try {
184
+ const { currentPassword, newPassword } = req.body;
185
+ if (!currentPassword || !newPassword || newPassword.length < 8) {
186
+ res.status(400).json({ success: false, error: 'Invalid password' });
187
+ return;
188
+ }
189
+ const pool = (0, database_1.getPool)();
190
+ const [rows] = await pool.execute('SELECT password_hash FROM users WHERE id = ?', [req.userId]);
191
+ const user = rows[0];
192
+ if (!user || !(await bcryptjs_1.default.compare(currentPassword, user.password_hash))) {
193
+ res.status(401).json({ success: false, error: 'Current password is incorrect' });
194
+ return;
195
+ }
196
+ const hash = await bcryptjs_1.default.hash(newPassword, 10);
197
+ await pool.execute('UPDATE users SET password_hash = ? WHERE id = ?', [hash, req.userId]);
198
+ res.json({ success: true });
199
+ }
200
+ catch (err) {
201
+ logger_1.logger.error({ err }, 'change-password error');
202
+ res.status(500).json({ success: false, error: 'Internal error' });
203
+ }
204
+ });
205
+ /**
206
+ * POST /api/auth/delete-account
207
+ */
208
+ router.post('/delete-account', session_auth_1.sessionAuth, async (req, res) => {
209
+ try {
210
+ const { email } = req.body;
211
+ if (email !== req.user?.email) {
212
+ res.status(400).json({ success: false, error: 'Email confirmation does not match' });
213
+ return;
214
+ }
215
+ const pool = (0, database_1.getPool)();
216
+ await pool.execute('DELETE FROM users WHERE id = ?', [req.userId]);
217
+ res.clearCookie('token');
218
+ res.json({ success: true });
219
+ }
220
+ catch (err) {
221
+ logger_1.logger.error({ err }, 'delete-account error');
222
+ res.status(500).json({ success: false, error: 'Internal error' });
223
+ }
224
+ });
225
+ // ============================================================
226
+ // Google Sign-In (frontend-based, no server-to-Google network calls)
227
+ // ============================================================
228
+ /**
229
+ * Decode a Google ID token (JWT) without network access.
230
+ * We trust the token because it comes from Google's Sign-In SDK
231
+ * running in the user's browser with our client_id configured.
232
+ */
233
+ function decodeGoogleIdToken(idToken) {
234
+ const parts = idToken.split('.');
235
+ if (parts.length !== 3)
236
+ throw new Error('Invalid token');
237
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());
238
+ if (!['accounts.google.com', 'https://accounts.google.com'].includes(payload.iss)) {
239
+ throw new Error('Invalid issuer');
240
+ }
241
+ if (payload.aud !== GOOGLE_CLIENT_ID) {
242
+ throw new Error('Invalid audience');
243
+ }
244
+ if (payload.exp * 1000 < Date.now()) {
245
+ throw new Error('Token expired');
246
+ }
247
+ return payload;
248
+ }
249
+ /**
250
+ * POST /api/auth/google/token
251
+ * Receive a Google ID token from the frontend, verify it, create/login user.
252
+ */
253
+ router.post('/google/token', async (req, res) => {
254
+ try {
255
+ const { idToken } = req.body;
256
+ if (!idToken || typeof idToken !== 'string') {
257
+ res.status(400).json({ success: false, error: 'Missing idToken' });
258
+ return;
259
+ }
260
+ if (!GOOGLE_CLIENT_ID) {
261
+ res.status(500).json({ success: false, error: 'Google OAuth not configured' });
262
+ return;
263
+ }
264
+ let googleUser;
265
+ try {
266
+ googleUser = decodeGoogleIdToken(idToken);
267
+ }
268
+ catch (err) {
269
+ logger_1.logger.warn({ err: err.message }, 'Invalid Google ID token');
270
+ res.status(401).json({ success: false, error: 'Invalid Google token' });
271
+ return;
272
+ }
273
+ if (!googleUser.email) {
274
+ res.status(400).json({ success: false, error: 'No email in Google token' });
275
+ return;
276
+ }
277
+ const pool = (0, database_1.getPool)();
278
+ // Check if user exists
279
+ const [existing] = await pool.execute('SELECT * FROM users WHERE email = ?', [googleUser.email]);
280
+ let userId;
281
+ if (existing.length > 0) {
282
+ // Existing user — login
283
+ const user = existing[0];
284
+ if (user.status !== 'active') {
285
+ res.status(403).json({ success: false, error: 'Account suspended' });
286
+ return;
287
+ }
288
+ userId = user.id;
289
+ }
290
+ else {
291
+ // New user — register
292
+ const randomPassword = crypto_1.default.randomBytes(32).toString('hex');
293
+ const hash = await bcryptjs_1.default.hash(randomPassword, 10);
294
+ const name = googleUser.name || googleUser.email.split('@')[0];
295
+ const [result] = await pool.execute('INSERT INTO users (email, password_hash, name, verified, status) VALUES (?, ?, ?, 1, ?) RETURNING id', [googleUser.email, hash, name, 'active']);
296
+ userId = result[0].id;
297
+ // Assign free plan
298
+ const [plans] = await pool.execute('SELECT id FROM plans WHERE name = ?', ['free']);
299
+ const planId = plans[0]?.id;
300
+ if (planId) {
301
+ await pool.execute("INSERT INTO subscriptions (user_id, plan_id, period_end) VALUES (?, ?, NOW() + INTERVAL '100 years')", [userId, planId]);
302
+ }
303
+ // Welcome email (async)
304
+ (0, mailer_1.sendWelcomeEmail)(googleUser.email, name).catch(() => { });
305
+ }
306
+ // Issue JWT
307
+ const token = jsonwebtoken_1.default.sign({ id: userId }, jwtSecret, { expiresIn: '7d' });
308
+ res.cookie('token', token, { httpOnly: true, maxAge: 7 * 24 * 3600_000, sameSite: 'lax' });
309
+ res.json({ success: true, user: { id: userId, email: googleUser.email, name: googleUser.name } });
310
+ }
311
+ catch (err) {
312
+ logger_1.logger.error({ err }, 'Google token login error');
313
+ res.status(500).json({ success: false, error: 'Internal error' });
314
+ }
315
+ });
316
+ return router;
317
+ }
318
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":";;;;;AAYA,4CAoWC;AAhXD,qCAAiC;AAEjC,wDAA8B;AAC9B,gEAA+B;AAC/B,oDAA4B;AAC5B,mDAA+C;AAC/C,6DAAyD;AACzD,+CAA6E;AAC7E,4CAAyC;AAEzC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,0EAA0E,CAAC;AAEpI,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;IAExB,2EAA2E;IAC3E,MAAM,OAAO,GAAG,IAAI,GAAG,EAMnB,CAAC;IAEL,sCAAsC;IACtC,WAAW,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,SAAS,GAAG,GAAG;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;IAEf;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9D,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAE3C,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;gBAC3E,OAAO;YACT,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC,CAAC;gBAC1F,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,sCAAsC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACvF,IAAK,QAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBAC5E,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;YACjE,MAAM,YAAY,GAAG,MAAM,kBAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAErD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;gBACjB,KAAK;gBACL,YAAY;gBACZ,IAAI;gBACJ,IAAI;gBACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,SAAS;aAC/C,CAAC,CAAC;YAEH,MAAM,IAAA,8BAAqB,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE/C,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;YACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC7D,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAEjC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAClE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YAEvB,cAAc;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,yFAAyF,EACzF,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CACxD,CAAC;YACF,MAAM,MAAM,GAAI,MAAc,CAAC,QAAQ,CAAC;YAExC,mBAAmB;YACnB,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YACpF,MAAM,MAAM,GAAI,KAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,CAAC,OAAO,CAChB,sGAAsG,EACtG,CAAC,MAAM,EAAE,MAAM,CAAC,CACjB,CAAC;YACJ,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEtB,YAAY;YACZ,MAAM,KAAK,GAAG,sBAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAE3F,0CAA0C;YAC1C,IAAA,yBAAgB,EAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAE1D,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACxC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC1D,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YACrC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;gBAC/E,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAClF,MAAM,IAAI,GAAI,IAAc,CAAC,CAAC,CAAC,CAAC;YAEhC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,kBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBACnE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;gBAC7E,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBACrE,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,sBAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAE3F,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;YACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QACtD,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,0BAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACnE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;;OAIjC,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;YAElB,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,YAAY,EAAG,IAAc,CAAC,CAAC,CAAC,IAAI,IAAI;aACzC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,0BAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChF,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC,CAAC;gBACtF,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,IAAI,CAAC,OAAO,CAAC,wCAAwC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;YAClF,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,0BAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACjF,IAAI,CAAC;YACH,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAClD,IAAI,CAAC,eAAe,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBACpE,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,8CAA8C,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;YACjG,MAAM,IAAI,GAAI,IAAc,CAAC,CAAC,CAAC,CAAC;YAEhC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,kBAAM,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBAC1E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;gBACjF,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,kBAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChD,MAAM,IAAI,CAAC,OAAO,CAAC,iDAAiD,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;YAE3F,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,uBAAuB,CAAC,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,0BAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChF,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAC3B,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;gBAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;gBACrF,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YACvB,MAAM,IAAI,CAAC,OAAO,CAAC,gCAAgC,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;YACpE,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+DAA+D;IAC/D,qEAAqE;IACrE,+DAA+D;IAE/D;;;;OAIG;IACH,SAAS,mBAAmB,CAAC,OAAe;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,CAAC,qBAAqB,EAAE,6BAA6B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,KAAK,gBAAgB,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,OAA0E,CAAC;IACpF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACjE,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC5C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;gBACnE,OAAO;YACT,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;gBAC/E,OAAO;YACT,CAAC;YAED,IAAI,UAA2E,CAAC;YAChF,IAAI,CAAC;gBACH,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,eAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,yBAAyB,CAAC,CAAC;gBAC7D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;gBACxE,OAAO;YACT,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBAC5E,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;YAEvB,uBAAuB;YACvB,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YACjG,IAAI,MAAc,CAAC;YAEnB,IAAK,QAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,wBAAwB;gBACxB,MAAM,IAAI,GAAI,QAAkB,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;oBACrE,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,sBAAsB;gBACtB,MAAM,cAAc,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC9D,MAAM,IAAI,GAAG,MAAM,kBAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAE/D,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,sGAAsG,EACtG,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CACzC,CAAC;gBACF,MAAM,GAAI,MAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEjC,mBAAmB;gBACnB,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpF,MAAM,MAAM,GAAI,KAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACvC,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,IAAI,CAAC,OAAO,CAChB,sGAAsG,EACtG,CAAC,MAAM,EAAE,MAAM,CAAC,CACjB,CAAC;gBACJ,CAAC;gBAED,wBAAwB;gBACxB,IAAA,yBAAgB,EAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC3D,CAAC;YAED,YAAY;YACZ,MAAM,KAAK,GAAG,sBAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3F,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEpG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,0BAA0B,CAAC,CAAC;YAClD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const blogRouter: import("express-serve-static-core").Router;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.blogRouter = void 0;
4
+ const express_1 = require("express");
5
+ const posts_1 = require("../data/posts");
6
+ exports.blogRouter = (0, express_1.Router)();
7
+ exports.blogRouter.get('/blog', (req, res) => {
8
+ const posts = (0, posts_1.getRecentPosts)(20);
9
+ const categories = (0, posts_1.getAllCategories)();
10
+ res.render('pages/blog', {
11
+ viewUser: req.user || null,
12
+ posts,
13
+ categories,
14
+ });
15
+ });
16
+ exports.blogRouter.get('/blog/:slug', (req, res) => {
17
+ const post = (0, posts_1.getPostBySlug)(req.params.slug);
18
+ if (!post) {
19
+ res.status(404).render('pages/404', { viewUser: req.user || null });
20
+ return;
21
+ }
22
+ const recentPosts = (0, posts_1.getRecentPosts)(5).filter(p => p.slug !== post.slug).slice(0, 3);
23
+ res.render('pages/blog-post', {
24
+ viewUser: req.user || null,
25
+ post,
26
+ recentPosts,
27
+ });
28
+ });
29
+ //# sourceMappingURL=blog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.js","sourceRoot":"","sources":["../../src/routes/blog.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AACjC,yCAAgF;AAEnE,QAAA,UAAU,GAAG,IAAA,gBAAM,GAAE,CAAC;AAEnC,kBAAU,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACnC,MAAM,KAAK,GAAG,IAAA,sBAAc,EAAC,EAAE,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,IAAA,wBAAgB,GAAE,CAAC;IACtC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE;QACvB,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QAC1B,KAAK;QACL,UAAU;KACX,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,kBAAU,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACzC,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QACpE,OAAO;IACT,CAAC;IACD,MAAM,WAAW,GAAG,IAAA,sBAAc,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpF,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE;QAC5B,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QAC1B,IAAI;QACJ,WAAW;KACZ,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const dashboardRouter: import("express-serve-static-core").Router;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.dashboardRouter = void 0;
7
+ const express_1 = require("express");
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ const database_1 = require("../services/database");
10
+ const session_auth_1 = require("../middleware/session-auth");
11
+ const logger_1 = require("../utils/logger");
12
+ exports.dashboardRouter = (0, express_1.Router)();
13
+ // All routes require session auth
14
+ exports.dashboardRouter.use(session_auth_1.sessionAuth);
15
+ /**
16
+ * GET /api/dashboard/stats
17
+ * User's usage statistics.
18
+ */
19
+ exports.dashboardRouter.get('/stats', async (req, res) => {
20
+ try {
21
+ const pool = (0, database_1.getPool)();
22
+ const userId = req.userId;
23
+ // Subscription info
24
+ const [subs] = await pool.execute(`
25
+ SELECT s.*, p.name as plan_name, p.display_name, p.token_limit_monthly, p.rate_limit_rpm, p.max_api_keys, p.price_monthly
26
+ FROM subscriptions s JOIN plans p ON s.plan_id = p.id
27
+ WHERE s.user_id = ? ORDER BY s.period_start DESC LIMIT 1
28
+ `, [userId]);
29
+ const sub = subs[0];
30
+ // Token breakdown
31
+ const [tokens] = await pool.execute(`
32
+ SELECT
33
+ COALESCE(SUM(input_tokens), 0) as total_input,
34
+ COALESCE(SUM(output_tokens), 0) as total_output,
35
+ COALESCE(SUM(thinking_tokens), 0) as total_thinking,
36
+ COALESCE(SUM(provider_cost), 0) as total_cost,
37
+ COUNT(*) as total_requests,
38
+ COALESCE(AVG(ttft_ms), 0) as avg_ttft,
39
+ COALESCE(AVG(tokens_per_sec), 0) as avg_tps,
40
+ COALESCE(AVG(duration_ms), 0) as avg_duration
41
+ FROM usage_logs WHERE user_id = ?
42
+ `, [userId]);
43
+ // Today's requests
44
+ const [today] = await pool.execute(`
45
+ SELECT COUNT(*) as cnt, COALESCE(SUM(input_tokens + output_tokens), 0) as tokens
46
+ FROM usage_logs WHERE user_id = ? AND DATE(created_at) = CURRENT_DATE
47
+ `, [userId]);
48
+ // API key count
49
+ const [keys] = await pool.execute('SELECT COUNT(*) as cnt FROM api_keys WHERE user_id = ? AND status = ?', [userId, 'active']);
50
+ const tokenData = tokens[0];
51
+ const totalUsed = tokenData.total_input + tokenData.total_output;
52
+ const limit = sub?.token_limit_monthly || 0;
53
+ res.json({
54
+ success: true,
55
+ subscription: sub,
56
+ usage: {
57
+ totalInput: tokenData.total_input,
58
+ totalOutput: tokenData.total_output,
59
+ totalThinking: tokenData.total_thinking,
60
+ totalCost: parseFloat(tokenData.total_cost),
61
+ totalRequests: tokenData.total_requests,
62
+ avgTtft: Math.round(tokenData.avg_ttft),
63
+ avgTps: Math.round(tokenData.avg_tps * 100) / 100,
64
+ avgDuration: Math.round(tokenData.avg_duration),
65
+ totalUsed,
66
+ percentUsed: limit > 0 ? Math.round((totalUsed / limit) * 10000) / 100 : 0,
67
+ },
68
+ today: today[0],
69
+ apiKeyCount: keys[0].cnt,
70
+ });
71
+ }
72
+ catch (err) {
73
+ logger_1.logger.error({ err }, 'dashboard stats error');
74
+ res.status(500).json({ success: false, error: 'Internal error' });
75
+ }
76
+ });
77
+ /**
78
+ * GET /api/dashboard/usage
79
+ * Last 30 days daily usage.
80
+ */
81
+ exports.dashboardRouter.get('/usage', async (req, res) => {
82
+ try {
83
+ const pool = (0, database_1.getPool)();
84
+ const [rows] = await pool.execute(`
85
+ SELECT
86
+ DATE(created_at) as date,
87
+ COALESCE(SUM(input_tokens), 0) as input_tokens,
88
+ COALESCE(SUM(output_tokens), 0) as output_tokens,
89
+ COUNT(*) as requests
90
+ FROM usage_logs
91
+ WHERE user_id = ? AND created_at >= CURRENT_DATE - INTERVAL '30 days'
92
+ GROUP BY DATE(created_at)
93
+ ORDER BY date
94
+ `, [req.userId]);
95
+ res.json({ success: true, daily: rows });
96
+ }
97
+ catch (err) {
98
+ logger_1.logger.error({ err }, 'dashboard usage error');
99
+ res.status(500).json({ success: false, error: 'Internal error' });
100
+ }
101
+ });
102
+ /**
103
+ * GET /api/dashboard/api-keys
104
+ * List user's active API keys.
105
+ */
106
+ exports.dashboardRouter.get('/api-keys', async (req, res) => {
107
+ try {
108
+ const pool = (0, database_1.getPool)();
109
+ const [rows] = await pool.execute('SELECT id, key_prefix, name, status, last_used_at, created_at FROM api_keys WHERE user_id = ? AND status = ? ORDER BY created_at DESC', [req.userId, 'active']);
110
+ res.json({ success: true, keys: rows });
111
+ }
112
+ catch (err) {
113
+ logger_1.logger.error({ err }, 'list keys error');
114
+ res.status(500).json({ success: false, error: 'Internal error' });
115
+ }
116
+ });
117
+ /**
118
+ * POST /api/dashboard/api-keys
119
+ * Create a new API key.
120
+ */
121
+ exports.dashboardRouter.post('/api-keys', async (req, res) => {
122
+ try {
123
+ const pool = (0, database_1.getPool)();
124
+ const { name = 'Default' } = req.body;
125
+ // Check plan limit
126
+ const [subs] = await pool.execute(`
127
+ SELECT p.max_api_keys FROM subscriptions s JOIN plans p ON s.plan_id = p.id
128
+ WHERE s.user_id = ? ORDER BY s.period_start DESC LIMIT 1
129
+ `, [req.userId]);
130
+ const maxKeys = subs[0]?.max_api_keys || 1;
131
+ const [existing] = await pool.execute('SELECT COUNT(*) as cnt FROM api_keys WHERE user_id = ? AND status = ?', [req.userId, 'active']);
132
+ if (existing[0].cnt >= maxKeys) {
133
+ res.status(400).json({ success: false, error: `Maximum ${maxKeys} API keys allowed on your plan` });
134
+ return;
135
+ }
136
+ // Generate key: sk-relay-<48 hex chars>
137
+ const rawKey = `sk-relay-${crypto_1.default.randomBytes(24).toString('hex')}`;
138
+ const keyPrefix = rawKey.substring(0, 12);
139
+ const keyHash = crypto_1.default.createHash('sha256').update(rawKey).digest('hex');
140
+ await pool.execute('INSERT INTO api_keys (user_id, key_prefix, key_hash, name) VALUES (?, ?, ?, ?)', [req.userId, keyPrefix, keyHash, name]);
141
+ // Return full key ONCE (never stored in plain text)
142
+ res.json({ success: true, key: rawKey, prefix: keyPrefix });
143
+ }
144
+ catch (err) {
145
+ logger_1.logger.error({ err }, 'create key error');
146
+ res.status(500).json({ success: false, error: 'Internal error' });
147
+ }
148
+ });
149
+ /**
150
+ * DELETE /api/dashboard/api-keys/:id
151
+ * Revoke an API key.
152
+ */
153
+ exports.dashboardRouter.delete('/api-keys/:id', async (req, res) => {
154
+ try {
155
+ const pool = (0, database_1.getPool)();
156
+ await pool.execute('UPDATE api_keys SET status = ? WHERE id = ? AND user_id = ?', ['revoked', req.params.id, req.userId]);
157
+ res.json({ success: true });
158
+ }
159
+ catch (err) {
160
+ logger_1.logger.error({ err }, 'revoke key error');
161
+ res.status(500).json({ success: false, error: 'Internal error' });
162
+ }
163
+ });
164
+ /**
165
+ * GET /api/dashboard/recent
166
+ * Recent API requests (last 10).
167
+ */
168
+ exports.dashboardRouter.get('/recent', async (req, res) => {
169
+ try {
170
+ const pool = (0, database_1.getPool)();
171
+ const [rows] = await pool.execute(`
172
+ SELECT model, provider_name, input_tokens, output_tokens, thinking_tokens,
173
+ ttft_ms, tokens_per_sec, duration_ms, status, created_at
174
+ FROM usage_logs WHERE user_id = ?
175
+ ORDER BY created_at DESC LIMIT 10
176
+ `, [req.userId]);
177
+ res.json({ success: true, recent: rows });
178
+ }
179
+ catch (err) {
180
+ logger_1.logger.error({ err }, 'recent error');
181
+ res.status(500).json({ success: false, error: 'Internal error' });
182
+ }
183
+ });
184
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/routes/dashboard.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAiC;AAEjC,oDAA4B;AAE5B,mDAA+C;AAC/C,6DAAyD;AACzD,4CAAyC;AAE5B,QAAA,eAAe,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExC,kCAAkC;AAClC,uBAAe,CAAC,GAAG,CAAC,0BAAW,CAAC,CAAC;AAEjC;;;GAGG;AACH,uBAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAClE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAO,CAAC;QAE3B,oBAAoB;QACpB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;;KAIjC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACb,MAAM,GAAG,GAAI,IAAc,CAAC,CAAC,CAAC,CAAC;QAE/B,kBAAkB;QAClB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;;;;;;;;;KAWnC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAEb,mBAAmB;QACnB,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;KAGlC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAEb,gBAAgB;QAChB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,uEAAuE,EACvE,CAAC,MAAM,EAAE,QAAQ,CAAC,CACnB,CAAC;QAEF,MAAM,SAAS,GAAI,MAAgB,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC;QACjE,MAAM,KAAK,GAAG,GAAG,EAAE,mBAAmB,IAAI,CAAC,CAAC;QAE5C,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,GAAG;YACjB,KAAK,EAAE;gBACL,UAAU,EAAE,SAAS,CAAC,WAAW;gBACjC,WAAW,EAAE,SAAS,CAAC,YAAY;gBACnC,aAAa,EAAE,SAAS,CAAC,cAAc;gBACvC,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC;gBAC3C,aAAa,EAAE,SAAS,CAAC,cAAc;gBACvC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC;gBACvC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG;gBACjD,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC;gBAC/C,SAAS;gBACT,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;aAC3E;YACD,KAAK,EAAG,KAAe,CAAC,CAAC,CAAC;YAC1B,WAAW,EAAG,IAAc,CAAC,CAAC,CAAC,CAAC,GAAG;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,uBAAuB,CAAC,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,uBAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAClE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;;;;;;;;KAUjC,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;QAElB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,uBAAuB,CAAC,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,uBAAe,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACrE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,uIAAuI,EACvI,CAAC,GAAG,CAAC,MAAO,EAAE,QAAQ,CAAC,CACxB,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,uBAAe,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACtE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,EAAE,IAAI,GAAG,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAEtC,mBAAmB;QACnB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;KAGjC,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;QAClB,MAAM,OAAO,GAAI,IAAc,CAAC,CAAC,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC;QAEtD,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CACnC,uEAAuE,EACvE,CAAC,GAAG,CAAC,MAAO,EAAE,QAAQ,CAAC,CACxB,CAAC;QACF,IAAK,QAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,OAAO,gCAAgC,EAAE,CAAC,CAAC;YACpG,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,MAAM,MAAM,GAAG,YAAY,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEzE,MAAM,IAAI,CAAC,OAAO,CAChB,gFAAgF,EAChF,CAAC,GAAG,CAAC,MAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CACxC,CAAC;QAEF,oDAAoD;QACpD,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,uBAAe,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC5E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,IAAI,CAAC,OAAO,CAChB,6DAA6D,EAC7D,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,MAAO,CAAC,CACxC,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,uBAAe,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACnE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,kBAAO,GAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;;;;;KAKjC,EAAE,CAAC,GAAG,CAAC,MAAO,CAAC,CAAC,CAAC;QAClB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;QACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const messagesRouter: import("express-serve-static-core").Router;