@zhang_libo/resource-hub 1.0.2 → 1.0.9

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 (45) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +13 -3
  3. package/README.ja.md +12 -2
  4. package/README.md +12 -2
  5. package/README.zh-TW.md +12 -2
  6. package/dist/app.js +4 -1
  7. package/dist/app.js.map +1 -1
  8. package/dist/db/migrate.js +135 -111
  9. package/dist/db/migrate.js.map +1 -1
  10. package/package.json +70 -73
  11. package/public/app.jsx +174 -174
  12. package/public/features/ChangePasswordModal.jsx +187 -187
  13. package/public/features/ResourceFormModal.jsx +915 -915
  14. package/public/layout/AppLayout.jsx +119 -119
  15. package/public/layout/Sidebar.jsx +1 -1
  16. package/dist/app.d.ts +0 -2
  17. package/dist/app.d.ts.map +0 -1
  18. package/dist/db/migrate.d.ts +0 -3
  19. package/dist/db/migrate.d.ts.map +0 -1
  20. package/dist/db/schema.d.ts +0 -743
  21. package/dist/db/schema.d.ts.map +0 -1
  22. package/dist/plugins/admin.d.ts +0 -4
  23. package/dist/plugins/admin.d.ts.map +0 -1
  24. package/dist/plugins/auth.d.ts +0 -4
  25. package/dist/plugins/auth.d.ts.map +0 -1
  26. package/dist/routes/auth.d.ts +0 -4
  27. package/dist/routes/auth.d.ts.map +0 -1
  28. package/dist/routes/categories.d.ts +0 -4
  29. package/dist/routes/categories.d.ts.map +0 -1
  30. package/dist/routes/config.d.ts +0 -4
  31. package/dist/routes/config.d.ts.map +0 -1
  32. package/dist/routes/resources.d.ts +0 -4
  33. package/dist/routes/resources.d.ts.map +0 -1
  34. package/dist/routes/tags.d.ts +0 -4
  35. package/dist/routes/tags.d.ts.map +0 -1
  36. package/dist/routes/users.d.ts +0 -4
  37. package/dist/routes/users.d.ts.map +0 -1
  38. package/dist/services/crypto.js +0 -49
  39. package/dist/services/crypto.js.map +0 -1
  40. package/dist/services/mail.d.ts +0 -16
  41. package/dist/services/mail.d.ts.map +0 -1
  42. package/dist/services/token.d.ts +0 -9
  43. package/dist/services/token.d.ts.map +0 -1
  44. package/dist/types.d.ts +0 -80
  45. package/dist/types.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAShB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKrB,CAAA;AAEF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAapB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG0C,CAAA;AAEnE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIgD,CAAA;AAEtE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKvB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUvB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAStB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKtB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGtB,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const _default: FastifyPluginAsync;
3
- export default _default;
4
- //# sourceMappingURL=admin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/plugins/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAA;;AAa/E,wBAA8B"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const _default: FastifyPluginAsync;
3
- export default _default;
4
- //# sourceMappingURL=auth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/plugins/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAA;;AAiC/E,wBAA6B"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const authRoutes: FastifyPluginAsync;
3
- export default authRoutes;
4
- //# sourceMappingURL=auth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,SAAS,CAAA;AAwE/D,QAAA,MAAM,UAAU,EAAE,kBAiRjB,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const categoriesRoutes: FastifyPluginAsync;
3
- export default categoriesRoutes;
4
- //# sourceMappingURL=categories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/routes/categories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAA;AA6C/E,QAAA,MAAM,gBAAgB,EAAE,kBA4EvB,CAAA;AAED,eAAe,gBAAgB,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const configRoutes: FastifyPluginAsync;
3
- export default configRoutes;
4
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,SAAS,CAAA;AAkB/D,QAAA,MAAM,YAAY,EAAE,kBA8FnB,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const resourcesRoutes: FastifyPluginAsync;
3
- export default resourcesRoutes;
4
- //# sourceMappingURL=resources.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/routes/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAA;AAqH/E,QAAA,MAAM,eAAe,EAAE,kBAuXtB,CAAA;AAED,eAAe,eAAe,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const tagsRoutes: FastifyPluginAsync;
3
- export default tagsRoutes;
4
- //# sourceMappingURL=tags.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/routes/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,SAAS,CAAA;AAS/D,QAAA,MAAM,UAAU,EAAE,kBA2BjB,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -1,4 +0,0 @@
1
- import type { FastifyPluginAsync } from 'fastify';
2
- declare const usersRoutes: FastifyPluginAsync;
3
- export default usersRoutes;
4
- //# sourceMappingURL=users.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,SAAS,CAAA;AAuD/D,QAAA,MAAM,WAAW,EAAE,kBAoJlB,CAAA;AAED,eAAe,WAAW,CAAA"}
@@ -1,49 +0,0 @@
1
- import { constants, createPrivateKey, createPublicKey, generateKeyPairSync, privateDecrypt } from 'crypto';
2
- let privateKey;
3
- let publicKeyPem;
4
- function initRsaKeyPair() {
5
- const pem = process.env.RSA_PRIVATE_KEY_PEM;
6
- if (pem && typeof pem === 'string' && pem.trim().length > 0) {
7
- privateKey = createPrivateKey({ key: pem.trim(), format: 'pem' });
8
- const pubKey = createPublicKey(privateKey);
9
- publicKeyPem = pubKey.export({ type: 'spki', format: 'pem' });
10
- return;
11
- }
12
- const { privateKey: priv, publicKey: pub } = generateKeyPairSync('rsa', {
13
- modulusLength: 2048,
14
- publicKeyEncoding: { type: 'spki', format: 'pem' },
15
- privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
16
- });
17
- privateKey = createPrivateKey(priv);
18
- publicKeyPem = pub;
19
- }
20
- initRsaKeyPair();
21
- export function getPublicKeyPem() {
22
- return publicKeyPem;
23
- }
24
- /**
25
- * Decrypt RSA-OAEP ciphertext (Base64) to UTF-8 plaintext.
26
- * Returns null if decryption fails (invalid base64 or bad ciphertext).
27
- */
28
- export function decryptPassword(ciphertextBase64) {
29
- if (typeof ciphertextBase64 !== 'string' || !ciphertextBase64.trim()) {
30
- return null;
31
- }
32
- let buf;
33
- try {
34
- buf = Buffer.from(ciphertextBase64.trim(), 'base64');
35
- }
36
- catch {
37
- return null;
38
- }
39
- if (buf.length === 0)
40
- return null;
41
- try {
42
- const decrypted = privateDecrypt({ key: privateKey, padding: constants.RSA_PKCS1_OAEP_PADDING }, buf);
43
- return decrypted.toString('utf8');
44
- }
45
- catch {
46
- return null;
47
- }
48
- }
49
- //# sourceMappingURL=crypto.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/services/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE1G,IAAI,UAA+C,CAAA;AACnD,IAAI,YAAoB,CAAA;AAExB,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAA;IAC3C,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,UAAU,GAAG,gBAAgB,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACjE,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;QAC1C,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAW,CAAA;QACvE,OAAM;IACR,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,mBAAmB,CAAC,KAAK,EAAE;QACtE,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,kBAAkB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;KACrD,CAAC,CAAA;IACF,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACnC,YAAY,GAAG,GAAG,CAAA;AACpB,CAAC;AAED,cAAc,EAAE,CAAA;AAEhB,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB;IACtD,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;QACrE,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,cAAc,CAC9B,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,sBAAsB,EAAE,EAC9D,GAAG,CACJ,CAAA;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -1,16 +0,0 @@
1
- import type { EmailPreview } from '../types.js';
2
- interface MailConfig {
3
- smtpHost: string | null;
4
- smtpPort: number | null;
5
- encryption: string | null;
6
- fromEmail: string | null;
7
- fromName: string | null;
8
- smtpUser: string | null;
9
- smtpPassword: string | null;
10
- }
11
- /**
12
- * Deliver an email. Returns EmailPreview if in mock mode (smtpHost empty), null otherwise.
13
- */
14
- export declare function deliverMail(to: string, subject: string, body: string, config: MailConfig): Promise<EmailPreview | null>;
15
- export {};
16
- //# sourceMappingURL=mail.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mail.d.ts","sourceRoot":"","sources":["../../src/services/mail.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA8B9B"}
@@ -1,9 +0,0 @@
1
- export declare function generateResetToken(): string;
2
- export declare function createResetToken(email: string): string;
3
- export declare function validateResetToken(token: string): {
4
- valid: boolean;
5
- error?: string;
6
- email?: string;
7
- };
8
- export declare function markTokenUsed(token: string): void;
9
- //# sourceMappingURL=token.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/services/token.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAMpG;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEjD"}
package/dist/types.d.ts DELETED
@@ -1,80 +0,0 @@
1
- export interface JwtPayload {
2
- userId: string;
3
- role: 'admin' | 'user';
4
- }
5
- export interface User {
6
- id: string;
7
- username: string;
8
- displayName: string;
9
- email: string;
10
- role: 'admin' | 'user';
11
- isActive: boolean;
12
- createdAt: string;
13
- updatedAt: string;
14
- }
15
- export interface Resource {
16
- id: string;
17
- title: string;
18
- url: string;
19
- description: string | null;
20
- icon: string | null;
21
- categoryId: string | null;
22
- authorId: string;
23
- isPublic: boolean;
24
- isEnabled: boolean;
25
- sortOrder: number;
26
- createdAt: string;
27
- updatedAt: string;
28
- }
29
- export interface Category {
30
- id: string;
31
- name: string;
32
- icon: string | null;
33
- sortOrder: number;
34
- createdAt: string;
35
- }
36
- export interface Tag {
37
- id: string;
38
- name: string;
39
- createdAt: string;
40
- }
41
- export interface SystemConfig {
42
- id: number;
43
- siteName: string;
44
- siteDesc: string | null;
45
- enableRegister: boolean;
46
- tokenExpiry: number;
47
- updatedAt: string;
48
- }
49
- export interface EmailConfig {
50
- id: number;
51
- smtpHost: string;
52
- smtpPort: number;
53
- smtpUser: string;
54
- smtpPass: string;
55
- smtpFrom: string;
56
- updatedAt: string;
57
- }
58
- export interface EmailPreview {
59
- to: string;
60
- subject: string;
61
- body: string;
62
- }
63
- export interface ResetToken {
64
- id: string;
65
- userId: string;
66
- token: string;
67
- expiresAt: string;
68
- used: boolean;
69
- createdAt: string;
70
- }
71
- declare module 'fastify' {
72
- interface FastifyRequest {
73
- user: JwtPayload;
74
- }
75
- interface FastifyInstance {
76
- authenticate: (request: import('fastify').FastifyRequest, reply: import('fastify').FastifyReply) => Promise<void>;
77
- requireAdmin: (request: import('fastify').FastifyRequest, reply: import('fastify').FastifyReply) => Promise<void>;
78
- }
79
- }
80
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;IACtB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,cAAc,EAAE,OAAO,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB;AAGD,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,IAAI,EAAE,UAAU,CAAA;KACjB;IACD,UAAU,eAAe;QACvB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,SAAS,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QACjH,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,SAAS,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAClH;CACF"}