@polardbx/pxbaas 0.1.0-beta.1 → 0.1.0-beta.3

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 (58) hide show
  1. package/README.md +179 -0
  2. package/dist/app/preflight.d.ts +12 -1
  3. package/dist/app/preflight.d.ts.map +1 -1
  4. package/dist/app/preflight.js +28 -5
  5. package/dist/app/preflight.js.map +1 -1
  6. package/dist/app/spec-lint.d.ts.map +1 -1
  7. package/dist/app/spec-lint.js +16 -0
  8. package/dist/app/spec-lint.js.map +1 -1
  9. package/dist/commands/app/index.d.ts.map +1 -1
  10. package/dist/commands/app/index.js +253 -12
  11. package/dist/commands/app/index.js.map +1 -1
  12. package/dist/commands/db/index.d.ts +1 -0
  13. package/dist/commands/db/index.d.ts.map +1 -1
  14. package/dist/commands/db/index.js +74 -27
  15. package/dist/commands/db/index.js.map +1 -1
  16. package/dist/commands/gen/index.d.ts.map +1 -1
  17. package/dist/commands/gen/index.js +13 -10
  18. package/dist/commands/gen/index.js.map +1 -1
  19. package/dist/commands/login/index.d.ts.map +1 -1
  20. package/dist/commands/login/index.js +9 -34
  21. package/dist/commands/login/index.js.map +1 -1
  22. package/dist/commands/profile/index.d.ts.map +1 -1
  23. package/dist/commands/profile/index.js +3 -0
  24. package/dist/commands/profile/index.js.map +1 -1
  25. package/dist/credentials/index.d.ts +2 -0
  26. package/dist/credentials/index.d.ts.map +1 -1
  27. package/dist/credentials/index.js +2 -0
  28. package/dist/credentials/index.js.map +1 -1
  29. package/dist/db/apply-schema.d.ts +98 -11
  30. package/dist/db/apply-schema.d.ts.map +1 -1
  31. package/dist/db/apply-schema.js +247 -80
  32. package/dist/db/apply-schema.js.map +1 -1
  33. package/dist/db/introspect.d.ts +54 -0
  34. package/dist/db/introspect.d.ts.map +1 -0
  35. package/dist/db/introspect.js +140 -0
  36. package/dist/db/introspect.js.map +1 -0
  37. package/dist/db/sql-file.d.ts +55 -0
  38. package/dist/db/sql-file.d.ts.map +1 -1
  39. package/dist/db/sql-file.js +417 -0
  40. package/dist/db/sql-file.js.map +1 -1
  41. package/package.json +2 -2
  42. package/skills/pxbaas-app-spec/references/runtime-contract.md +1 -1
  43. package/skills/pxbaas-app-spec/references/templates-examples.md +5 -2
  44. package/skills/pxbaas-cli/SKILL.md +7 -4
  45. package/skills/pxbaas-cli/references/app-deploy.md +29 -2
  46. package/skills/pxbaas-cli/references/auth-and-credentials.md +14 -2
  47. package/skills/pxbaas-cli/references/data-postgrest.md +15 -0
  48. package/skills/pxbaas-cli/references/db-and-meta.md +12 -0
  49. package/skills/pxbaas-cli/references/multi-tenant-apps.md +35 -4
  50. package/templates/webapp/csr-bff/db/rls.json +13 -0
  51. package/templates/webapp/csr-bff/db/schema.sql +8 -28
  52. package/templates/webapp/manifest.json +6 -3
  53. package/templates/webapp/react-vite-hono/backend/index.ts +21 -4
  54. package/templates/webapp/ssr-blog/db/rls.json +13 -0
  55. package/templates/webapp/ssr-blog/db/schema.sql +8 -28
  56. package/templates/webapp/ssr-hono/backend/index.ts +50 -31
  57. package/templates/webapp/ssr-shop/db/rls.json +16 -0
  58. package/templates/webapp/ssr-shop/db/schema.sql +12 -42
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Schema introspection shared by `db tables`, `db schema`, and `gen types`.
3
+ *
4
+ * Why this exists (fixes defect C1): those three commands used the Meta API
5
+ * (`MetaDriver` -> `/pg/*`) unconditionally. In multi-tenant mode `/pg/*` only
6
+ * accepts the platform/global service_role key, so a per-tenant key is rejected
7
+ * with 401 (`Authentication failed`) — even though the same credentials work for
8
+ * `db query` (which already routes through tenant-ddl), `data *` (REST), and
9
+ * `storage`. See `db/apply-schema.ts` ("per-tenant keys are rejected 401 on
10
+ * /pg/query").
11
+ *
12
+ * The fix keeps single-tenant behavior EXACTLY as before (Meta API) and adds a
13
+ * multi-tenant path that runs the same portable `information_schema` queries
14
+ * through `TenantDdlDriver` (which the tenant key CAN call). The introspection
15
+ * SQL is backend-agnostic, so it is factored into pure functions that take an
16
+ * injectable `SqlRunner` — trivial to unit-test without a network.
17
+ */
18
+ import { type TableInfo, type TableColumn, type TableIndex } from '@polardbx/pxbaas-client';
19
+ /** Runs a SELECT and returns bare rows. Backed by MetaDriver (single-tenant
20
+ * `/pg/query`) or TenantDdlDriver (multi-tenant `/api/tenant-ddl/query`). */
21
+ export type SqlRunner = (sql: string) => Promise<Record<string, unknown>[]>;
22
+ /** List tables/views via information_schema (portable across both drivers). */
23
+ export declare function listTablesViaSql(run: SqlRunner, schema?: string): Promise<TableInfo[]>;
24
+ /** List a table's columns via information_schema (mirrors MetaDriver SQL). */
25
+ export declare function getTableColumnsViaSql(run: SqlRunner, table: string, schema?: string): Promise<TableColumn[]>;
26
+ /** List a table's indexes via information_schema (mirrors MetaDriver SQL). */
27
+ export declare function getTableIndexesViaSql(run: SqlRunner, table: string, schema?: string): Promise<TableIndex[]>;
28
+ /** A schema introspector bound to the correct backend for the profile's mode. */
29
+ export interface SchemaIntrospector {
30
+ /** Human label for the schema being introspected (tenant db in multi-tenant). */
31
+ currentSchema(): Promise<string>;
32
+ listTables(): Promise<TableInfo[]>;
33
+ getColumns(table: string): Promise<TableColumn[]>;
34
+ getIndexes(table: string): Promise<TableIndex[]>;
35
+ }
36
+ export interface MakeIntrospectorOptions {
37
+ /** Profile mode; 'multi-tenant' routes through tenant-ddl, else Meta API. */
38
+ mode?: string;
39
+ endpoint: string;
40
+ anonKey: string;
41
+ serviceRoleKey?: string;
42
+ tenantId?: string;
43
+ /** Single-tenant explicit schema (default 'public'). Ignored in multi-tenant. */
44
+ schema?: string;
45
+ /** Single-tenant: use the service_role key for Meta API reads (default true). */
46
+ useServiceRole?: boolean;
47
+ }
48
+ /**
49
+ * Build the mode-appropriate introspector.
50
+ * - multi-tenant: TenantDdlDriver + information_schema scoped to DATABASE().
51
+ * - single-tenant: the existing MetaDriver behavior, unchanged.
52
+ */
53
+ export declare function makeIntrospector(opts: MakeIntrospectorOptions): SchemaIntrospector;
54
+ //# sourceMappingURL=introspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../src/db/introspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAEjC;8EAC8E;AAC9E,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAuB5E,+EAA+E;AAC/E,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,EAAE,CAAC,CAetB;AAED,8EAA8E;AAC9E,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,CAAC,CAmBxB;AAED,8EAA8E;AAC9E,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,EAAE,CAAC,CAiBvB;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACnC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,kBAAkB,CA+ClF"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Schema introspection shared by `db tables`, `db schema`, and `gen types`.
3
+ *
4
+ * Why this exists (fixes defect C1): those three commands used the Meta API
5
+ * (`MetaDriver` -> `/pg/*`) unconditionally. In multi-tenant mode `/pg/*` only
6
+ * accepts the platform/global service_role key, so a per-tenant key is rejected
7
+ * with 401 (`Authentication failed`) — even though the same credentials work for
8
+ * `db query` (which already routes through tenant-ddl), `data *` (REST), and
9
+ * `storage`. See `db/apply-schema.ts` ("per-tenant keys are rejected 401 on
10
+ * /pg/query").
11
+ *
12
+ * The fix keeps single-tenant behavior EXACTLY as before (Meta API) and adds a
13
+ * multi-tenant path that runs the same portable `information_schema` queries
14
+ * through `TenantDdlDriver` (which the tenant key CAN call). The introspection
15
+ * SQL is backend-agnostic, so it is factored into pure functions that take an
16
+ * injectable `SqlRunner` — trivial to unit-test without a network.
17
+ */
18
+ import { MetaDriver, TenantDdlDriver, } from '@polardbx/pxbaas-client';
19
+ /** Escape a single-quoted SQL string literal. */
20
+ function esc(value) {
21
+ return value.replace(/'/g, "''");
22
+ }
23
+ /**
24
+ * Schema predicate for information_schema filters. An explicit schema filters by
25
+ * name; otherwise scope to the connection's current database via DATABASE() —
26
+ * correct for multi-tenant, where the tenant-ddl connection is bound to the
27
+ * tenant's own database (tenant_<id>), not a Postgres-style `public`.
28
+ */
29
+ function schemaPredicate(schema) {
30
+ return schema && schema !== ''
31
+ ? `table_schema = '${esc(schema)}'`
32
+ : 'table_schema = DATABASE()';
33
+ }
34
+ function toBool(v) {
35
+ return v === 1 || v === true || v === '1';
36
+ }
37
+ /** List tables/views via information_schema (portable across both drivers). */
38
+ export async function listTablesViaSql(run, schema) {
39
+ const sql = `SELECT table_schema AS \`schema\`, table_name AS \`name\`, table_type AS \`type\`, ` +
40
+ `table_rows AS \`rowCount\`, table_comment AS \`comment\` ` +
41
+ `FROM information_schema.tables ` +
42
+ `WHERE ${schemaPredicate(schema)} AND table_type IN ('BASE TABLE','VIEW') ` +
43
+ `ORDER BY table_name`;
44
+ const rows = await run(sql);
45
+ return rows.map((t) => ({
46
+ schema: String(t.schema ?? ''),
47
+ name: String(t.name ?? ''),
48
+ type: String(t.type ?? '').toUpperCase() === 'VIEW' ? 'view' : 'table',
49
+ rowCount: t.rowCount != null ? Number(t.rowCount) : undefined,
50
+ comment: t.comment != null && t.comment !== '' ? String(t.comment) : undefined,
51
+ }));
52
+ }
53
+ /** List a table's columns via information_schema (mirrors MetaDriver SQL). */
54
+ export async function getTableColumnsViaSql(run, table, schema) {
55
+ const sql = `SELECT column_name AS \`name\`, data_type AS \`dataType\`, ` +
56
+ `CASE WHEN is_nullable='YES' THEN 1 ELSE 0 END AS \`isNullable\`, ` +
57
+ `column_default AS \`defaultValue\`, ` +
58
+ `CASE WHEN column_key='PRI' THEN 1 ELSE 0 END AS \`isPrimaryKey\`, ` +
59
+ `column_comment AS \`comment\` ` +
60
+ `FROM information_schema.columns ` +
61
+ `WHERE ${schemaPredicate(schema)} AND table_name='${esc(table)}' ` +
62
+ `ORDER BY ordinal_position`;
63
+ const rows = await run(sql);
64
+ return rows.map((row) => ({
65
+ name: String(row.name),
66
+ dataType: String(row.dataType),
67
+ isNullable: toBool(row.isNullable),
68
+ defaultValue: row.defaultValue == null ? null : String(row.defaultValue),
69
+ isPrimaryKey: toBool(row.isPrimaryKey),
70
+ comment: row.comment != null && row.comment !== '' ? String(row.comment) : undefined,
71
+ }));
72
+ }
73
+ /** List a table's indexes via information_schema (mirrors MetaDriver SQL). */
74
+ export async function getTableIndexesViaSql(run, table, schema) {
75
+ const sql = `SELECT index_name AS \`name\`, ` +
76
+ `GROUP_CONCAT(column_name ORDER BY seq_in_index) AS \`cols\`, ` +
77
+ `CASE WHEN MIN(non_unique)=0 THEN 1 ELSE 0 END AS \`isUnique\`, ` +
78
+ `CASE WHEN index_name='PRIMARY' THEN 1 ELSE 0 END AS \`isPrimary\` ` +
79
+ `FROM information_schema.statistics ` +
80
+ `WHERE ${schemaPredicate(schema)} AND table_name='${esc(table)}' ` +
81
+ `GROUP BY index_name`;
82
+ const rows = await run(sql);
83
+ return rows.map((row) => ({
84
+ name: String(row.name),
85
+ columns: row.cols != null && row.cols !== '' ? String(row.cols).split(',') : [],
86
+ isUnique: toBool(row.isUnique),
87
+ isPrimary: toBool(row.isPrimary),
88
+ type: 'BTREE',
89
+ }));
90
+ }
91
+ /**
92
+ * Build the mode-appropriate introspector.
93
+ * - multi-tenant: TenantDdlDriver + information_schema scoped to DATABASE().
94
+ * - single-tenant: the existing MetaDriver behavior, unchanged.
95
+ */
96
+ export function makeIntrospector(opts) {
97
+ if (opts.mode === 'multi-tenant') {
98
+ if (!opts.tenantId) {
99
+ throw new Error('Multi-tenant profile is missing tenantId; re-run "pxbaas login --tenant-id <id>" with per-tenant keys.');
100
+ }
101
+ const tenantDriver = new TenantDdlDriver({
102
+ endpoint: opts.endpoint,
103
+ serviceRoleKey: opts.serviceRoleKey,
104
+ });
105
+ const run = async (sql) => (await tenantDriver.query(sql));
106
+ let cachedSchema = null;
107
+ return {
108
+ async currentSchema() {
109
+ if (cachedSchema == null) {
110
+ const rows = await run('SELECT DATABASE() AS db');
111
+ cachedSchema = rows.length > 0 ? String(rows[0].db ?? '') : '';
112
+ }
113
+ return cachedSchema;
114
+ },
115
+ listTables: () => listTablesViaSql(run),
116
+ getColumns: (table) => getTableColumnsViaSql(run, table),
117
+ getIndexes: (table) => getTableIndexesViaSql(run, table),
118
+ };
119
+ }
120
+ const metaDriver = new MetaDriver({
121
+ endpoint: opts.endpoint,
122
+ anonKey: opts.anonKey,
123
+ serviceRoleKey: opts.serviceRoleKey,
124
+ tenantId: opts.tenantId,
125
+ });
126
+ const schema = opts.schema ?? 'public';
127
+ const useServiceRole = opts.useServiceRole ?? true;
128
+ return {
129
+ async currentSchema() {
130
+ return schema;
131
+ },
132
+ async listTables() {
133
+ const all = await metaDriver.listTables(useServiceRole);
134
+ return all.filter((t) => t.schema === schema);
135
+ },
136
+ getColumns: (table) => metaDriver.getTableColumns(table, schema, useServiceRole),
137
+ getIndexes: (table) => metaDriver.getTableIndexes(table, schema, useServiceRole),
138
+ };
139
+ }
140
+ //# sourceMappingURL=introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../src/db/introspect.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@
9
9
  * `;`, correctly ignoring separators that appear inside strings, quoted
10
10
  * identifiers, or comments.
11
11
  */
12
+ import type { RlsTableInput, RlsPolicyInput } from "@polardbx/pxbaas-client";
12
13
  /** Placeholder that every webapp template's db/schema.sql uses for the target schema. */
13
14
  export declare const SCHEMA_PLACEHOLDER = "__SCHEMA__";
14
15
  /** True when the script still contains the `__SCHEMA__` placeholder. */
@@ -46,4 +47,58 @@ export declare function buildStatementPlan(rawSql: string, schema: string): {
46
47
  statements: string[];
47
48
  substituted: boolean;
48
49
  };
50
+ /**
51
+ * Multi-tenant variant of {@link substituteSchema}: DROP the `__SCHEMA__`.
52
+ * qualifier entirely instead of filling it in. The tenant-ddl connection is
53
+ * already bound to the tenant's own database, and cross-schema fully-qualified
54
+ * names are denied by GRANT / the server pre-check — so `__SCHEMA__`.`t` must
55
+ * become just `t`. The CLI never knows the tenant's real db_name (the resolver
56
+ * does not expose it), so de-qualifying is the only safe substitution.
57
+ */
58
+ export declare function substituteSchemaForTenant(sql: string): string;
59
+ export interface StatementPartition {
60
+ /** `INSERT ... supabase._mysqlrest_rls_tables` statements. */
61
+ rlsTableInserts: string[];
62
+ /** `INSERT ... supabase._mysqlrest_rls_policies` statements. */
63
+ rlsPolicyInserts: string[];
64
+ /** Everything else (DDL, seed DML) — runs verbatim through the query channel. */
65
+ plain: string[];
66
+ }
67
+ /**
68
+ * Split statements into central-registry RLS INSERTs vs. plain DDL/DML. In
69
+ * multi-tenant mode the RLS INSERTs MUST be diverted to the structured
70
+ * `/api/tenant-ddl/rls/*` endpoints (the tenant account has no GRANT on the
71
+ * shared `supabase` database, so a raw INSERT would be denied).
72
+ */
73
+ export declare function partitionStatements(statements: string[]): StatementPartition;
74
+ /** Thrown when an RLS INSERT does not match the constrained shape we can parse. */
75
+ export declare class SqlParseError extends Error {
76
+ constructor(message: string);
77
+ }
78
+ /** Parse one `_mysqlrest_rls_tables` INSERT into structured inputs (schema dropped). */
79
+ export declare function parseRlsTableInsert(stmt: string): RlsTableInput[];
80
+ /** Parse one `_mysqlrest_rls_policies` INSERT into structured inputs (schema dropped). */
81
+ export declare function parseRlsPolicyInsert(stmt: string): RlsPolicyInput[];
82
+ /** Render an idempotent central-registry INSERT for one RLS table toggle. */
83
+ export declare function renderRlsTableInsert(schema: string, input: RlsTableInput): string;
84
+ /** Render an idempotent central-registry INSERT for one RLS policy. */
85
+ export declare function renderRlsPolicyInsert(schema: string, input: RlsPolicyInput): string;
86
+ /**
87
+ * Extract the table names created by a schema.sql script (for `--purge-db`).
88
+ * Handles `CREATE TABLE [IF NOT EXISTS] [`__SCHEMA__`.]<name>` with optional
89
+ * backticks. Names are returned de-qualified and de-duplicated, in first-seen order.
90
+ */
91
+ export declare function extractCreateTableNames(sql: string): string[];
92
+ export interface RlsJson {
93
+ tables: RlsTableInput[];
94
+ policies: RlsPolicyInput[];
95
+ }
96
+ /**
97
+ * Parse + validate a declarative `db/rls.json`. Accepts the documented friendly
98
+ * keys (table/name/role/using/check/rlsEnabled/...) and their snake_case aliases,
99
+ * mapping them onto the driver's structured inputs. `table_schema` is NEVER read
100
+ * here — the execution layer decides it (single-tenant = --schema; multi-tenant =
101
+ * server-bound).
102
+ */
103
+ export declare function parseRlsJson(text: string): RlsJson;
49
104
  //# sourceMappingURL=sql-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-file.d.ts","sourceRoot":"","sources":["../../src/db/sql-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAmHxD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAIhD"}
1
+ {"version":3,"file":"sql-file.d.ts","sourceRoot":"","sources":["../../src/db/sql-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE7E,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAmHxD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAIhD;AAMD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7D;AAQD,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,iFAAiF;IACjF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAU5E;AAED,mFAAmF;AACnF,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AA2ID,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAiBjE;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CA2BnE;AAaD,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAOjF;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAYnF;AAGD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAU7D;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAgBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAoDlD"}