typion 0.0.0-stage → 0.1.1

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -2
  3. package/bin/typion.js +7 -0
  4. package/dist/auth/better-auth.d.ts +13 -0
  5. package/dist/auth/better-auth.js +11 -0
  6. package/dist/auth/better-auth.js.map +1 -0
  7. package/dist/cli/index.d.ts +14 -0
  8. package/dist/cli/index.js +883 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/column-kinds-Bkm4NJI2.js +47 -0
  11. package/dist/column-kinds-Bkm4NJI2.js.map +1 -0
  12. package/dist/context-B4e2eREP.d.ts +2100 -0
  13. package/dist/contract/index.d.ts +137 -0
  14. package/dist/contract/index.js +42 -0
  15. package/dist/contract/index.js.map +1 -0
  16. package/dist/db/pglite.d.ts +12 -0
  17. package/dist/db/pglite.js +27 -0
  18. package/dist/db/pglite.js.map +1 -0
  19. package/dist/descriptor-Cc3mGp73.js +12 -0
  20. package/dist/descriptor-Cc3mGp73.js.map +1 -0
  21. package/dist/errors-ChDBxeS-.js +17 -0
  22. package/dist/errors-ChDBxeS-.js.map +1 -0
  23. package/dist/errors-D-CKO-px.js +114 -0
  24. package/dist/errors-D-CKO-px.js.map +1 -0
  25. package/dist/handler-BWVU8TCR.d.ts +23 -0
  26. package/dist/handler-_87bFkbP.js +565 -0
  27. package/dist/handler-_87bFkbP.js.map +1 -0
  28. package/dist/hono/index.d.ts +17 -0
  29. package/dist/hono/index.js +26 -0
  30. package/dist/hono/index.js.map +1 -0
  31. package/dist/http/index.d.ts +13 -0
  32. package/dist/http/index.js +2 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +1324 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/issues-DLqCBQT1.js +42 -0
  37. package/dist/issues-DLqCBQT1.js.map +1 -0
  38. package/dist/next/index.d.ts +8 -0
  39. package/dist/next/index.js +18 -0
  40. package/dist/next/index.js.map +1 -0
  41. package/dist/operations-D3rOacLX.js +1811 -0
  42. package/dist/operations-D3rOacLX.js.map +1 -0
  43. package/dist/schema/index.d.ts +18 -0
  44. package/dist/schema/index.js +3 -0
  45. package/dist/schema-Rzzq97cK.js +68 -0
  46. package/dist/schema-Rzzq97cK.js.map +1 -0
  47. package/dist/seed/index.d.ts +19 -0
  48. package/dist/seed/index.js +85 -0
  49. package/dist/seed/index.js.map +1 -0
  50. package/dist/structural-BZnjFmCs.js +247 -0
  51. package/dist/structural-BZnjFmCs.js.map +1 -0
  52. package/dist/testing/index.d.ts +26 -0
  53. package/dist/testing/index.js +92 -0
  54. package/dist/testing/index.js.map +1 -0
  55. package/dist/typion-Dh2BCSRz.js +1187 -0
  56. package/dist/typion-Dh2BCSRz.js.map +1 -0
  57. package/dist/validation/zod.d.ts +21 -0
  58. package/dist/validation/zod.js +84 -0
  59. package/dist/validation/zod.js.map +1 -0
  60. package/docs/README.md +145 -0
  61. package/docs/access.md +114 -0
  62. package/docs/auth.md +195 -0
  63. package/docs/collections.md +172 -0
  64. package/docs/database.md +76 -0
  65. package/docs/features/localization.md +112 -0
  66. package/docs/features/multi-tenant.md +166 -0
  67. package/docs/features/soft-delete.md +85 -0
  68. package/docs/features/versions.md +106 -0
  69. package/docs/hooks.md +106 -0
  70. package/docs/http.md +188 -0
  71. package/docs/queries.md +200 -0
  72. package/docs/testing.md +85 -0
  73. package/package.json +125 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations-D3rOacLX.js","names":[],"sources":["../src/define/plugin.ts","../src/define/entity.ts","../src/runtime/context.ts","../src/runtime/errors.ts","../src/runtime/filters.ts","../src/runtime/read/kinds.ts","../src/runtime/access.ts","../src/runtime/equal.ts","../src/runtime/write/pipeline.ts","../src/runtime/write/validate.ts","../src/runtime/write/references.ts","../src/runtime/write/mutations.ts","../src/runtime/write/operations.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport {\n getTableColumns,\n is,\n type RelationsBuilder,\n type RelationsBuilderConfig,\n} from 'drizzle-orm'\nimport { PgTable } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport type { EntityDef } from '../types/entity.js'\nimport type { ColumnKindRuntime, ColumnKindsTypes } from '../types/kinds.js'\nimport type {\n AnyPlugin,\n AnyPluginSpec,\n AnyFeatureTables,\n CollectionKinds,\n FeatureId,\n FeatureTables,\n Plugin,\n PluginEntityDefiner,\n PluginErrorDef,\n PluginRuntime,\n PluginSpec,\n} from '../types/plugin.js'\nimport type { EntityTraits, RuleKind, TraitOperation } from '../types/traits.js'\n\nconst PLUGIN_ID = /^[a-z][a-zA-Z0-9_]*$/\nconst SETUP_FEATURES: ReadonlySet<string> = new Set<FeatureId>(['localization', 'multiTenant'])\n\n// The literal-carrying parts of a spec are separate type parameters because a bare `spec: P` gives\n// `tables`/`requires` no inference site of their own: the `relations`/`entities` callbacks would be\n// checked against `RelationsBuilder<{}>`. The parts recompose into the `PluginSpec` that `Plugin<P>` reads.\nexport type PluginSpecInput<\n TId extends string,\n TTables extends Record<string, PgTable>,\n TRequires extends Record<string, PgTable>,\n TCtx extends object,\n TApi,\n TEntityOptions extends object,\n TErrors extends Record<string, PluginErrorDef>,\n TEntities extends Record<string, EntityDef<string, unknown>>,\n TRelations extends RelationsBuilderConfig<TTables & TRequires>,\n TKinds extends CollectionKinds = CollectionKinds,\n TCollectionOptions extends object = {},\n TSystemOptions extends object = {},\n TNeedsCtx extends object = {},\n TColumnKinds extends ColumnKindsTypes = never,\n TContextOptions extends object = {},\n TTraits extends EntityTraits = never,\n TDependsOn extends string = never,\n TFeatureTables extends AnyFeatureTables = {},\n> = Omit<\n PluginSpec<\n TId,\n TTables,\n TRequires,\n TCtx,\n TApi,\n TEntityOptions,\n TErrors,\n TKinds,\n TCollectionOptions,\n TSystemOptions,\n TNeedsCtx,\n TColumnKinds,\n TContextOptions,\n TTraits,\n TDependsOn,\n TFeatureTables\n >,\n 'entities' | 'relations'\n> & {\n relations?: (r: RelationsBuilder<TTables & TRequires>) => TRelations\n entities?: (define: PluginEntityDefiner<TTables>) => TEntities\n}\n\n// What `definePlugin` returns: an interface, so that TypeScript takes a plugin as a reference to it and looks\n// no further than its type arguments. The types of the collections carry the plugins registered with them, and a\n// plugin typed as the alias `Plugin<…>` was walked member by member wherever a collection's type was\n// instantiated: 339,000 times on the stress fixture (ADR-074).\nexport interface DefinedPlugin<\n TId extends string,\n TTables extends Record<string, PgTable>,\n TRequires extends Record<string, PgTable>,\n TCtx extends object,\n TApi,\n TEntityOptions extends object,\n TErrors extends Record<string, PluginErrorDef>,\n TEntities extends Record<string, EntityDef<string, unknown>>,\n TRelations extends RelationsBuilderConfig<TTables & TRequires>,\n TKinds extends CollectionKinds,\n TCollectionOptions extends object,\n TSystemOptions extends object,\n TNeedsCtx extends object,\n TColumnKinds extends ColumnKindsTypes,\n TContextOptions extends object,\n TTraits extends EntityTraits,\n TDependsOn extends string,\n TFeatureTables extends AnyFeatureTables = {},\n> extends Plugin<\n PluginSpecInput<\n TId,\n TTables,\n TRequires,\n TCtx,\n TApi,\n TEntityOptions,\n TErrors,\n TEntities,\n TRelations,\n TKinds,\n TCollectionOptions,\n TSystemOptions,\n TNeedsCtx,\n TColumnKinds,\n TContextOptions,\n TTraits,\n TDependsOn,\n TFeatureTables\n >\n> {}\n\n// Written inline in `.plugins([…])`, a call would take the `AnyPlugin` constraint as a contextual return type\n// and infer what the spec leaves out (`tables`, `entities`) from it, as `Record<string, …>`, turning every table\n// name of the engine into `string`. A conditional per argument blocks that inference and resolves to the argument\n// itself; `NoInfer` did too, but stayed in the plugin's type as a wrapper TypeScript always treats as generic,\n// which is what made every plugin walked (ADR-074).\ntype Guard<T> = [T] extends [infer X extends T] ? X : never\n\n// The core's own plugins: the features, and the second shapes of the engine's suite. Entity traits are the core's\n// (ADR-077), so only this definer takes them; `definePlugin` is the same function without them.\nexport function defineFeaturePlugin<\n const TId extends string,\n TTables extends Record<string, PgTable> = {},\n TRequires extends Record<string, PgTable> = {},\n TCtx extends object = {},\n TApi = {},\n TEntityOptions extends object = {},\n const TErrors extends Record<string, PluginErrorDef> = {},\n TEntities extends Record<string, EntityDef<string, unknown>> = {},\n TRelations extends RelationsBuilderConfig<TTables & TRequires> = {},\n TKinds extends CollectionKinds = CollectionKinds,\n TCollectionOptions extends object = {},\n TSystemOptions extends object = {},\n TNeedsCtx extends object = {},\n TColumnKinds extends ColumnKindsTypes = never,\n TContextOptions extends object = {},\n TTraits extends EntityTraits = never,\n TDependsOn extends string = never,\n>(\n spec: PluginSpecInput<\n TId,\n TTables,\n TRequires,\n TCtx,\n TApi,\n TEntityOptions,\n TErrors,\n TEntities,\n TRelations,\n TKinds,\n TCollectionOptions,\n TSystemOptions,\n TNeedsCtx,\n TColumnKinds,\n TContextOptions,\n TTraits,\n TDependsOn\n >,\n): DefinedPlugin<\n Guard<TId>,\n Guard<TTables>,\n Guard<TRequires>,\n Guard<TCtx>,\n Guard<TApi>,\n Guard<TEntityOptions>,\n Guard<TErrors>,\n Guard<TEntities>,\n Guard<TRelations>,\n Guard<TKinds>,\n Guard<TCollectionOptions>,\n Guard<TSystemOptions>,\n Guard<TNeedsCtx>,\n Guard<TColumnKinds>,\n Guard<TContextOptions>,\n Guard<TTraits>,\n Guard<TDependsOn>\n> {\n if (typeof spec.id !== 'string' || !PLUGIN_ID.test(spec.id)) {\n throw new ConfigError(\n `definePlugin: '${String(spec.id)}' is not a valid plugin id (letters, digits, underscore; lowercase first letter)`,\n )\n }\n for (const [key, table] of Object.entries(spec.tables ?? {})) {\n if (!is(table, PgTable)) {\n throw new ConfigError(`Plugin '${spec.id}': tables.${key} is not a pg table`)\n }\n }\n for (const [feature, tables] of Object.entries((spec as AnyPluginSpec).featureTables ?? {})) {\n if (!SETUP_FEATURES.has(feature)) {\n throw new ConfigError(\n `Plugin '${spec.id}': featureTables.${feature} is not a feature a setup configures (${[...SETUP_FEATURES].join(', ')})`,\n )\n }\n for (const [key, table] of Object.entries(tables)) {\n if (!(key in (spec.tables ?? {})) || !is(table, PgTable)) {\n throw new ConfigError(\n `Plugin '${spec.id}': featureTables.${feature}.${key} is not a pg table standing for one of its tables`,\n )\n }\n }\n }\n // `$api` / `$context` / `$entityOptions` / `$entities` are type-level accumulators only.\n return spec as never\n}\n\n// A plugin adds and reacts: collections, tables, entities, hooks, context, an API, routes, errors, collection options\n// and column kinds. What changes the meaning of reads and writes is a feature of the core (ADR-077), so entity traits\n// are not part of a plugin's spec.\nexport function definePlugin<\n const TId extends string,\n TTables extends Record<string, PgTable> = {},\n TRequires extends Record<string, PgTable> = {},\n TCtx extends object = {},\n TApi = {},\n TEntityOptions extends object = {},\n const TErrors extends Record<string, PluginErrorDef> = {},\n TEntities extends Record<string, EntityDef<string, unknown>> = {},\n TRelations extends RelationsBuilderConfig<TTables & TRequires> = {},\n TKinds extends CollectionKinds = CollectionKinds,\n TCollectionOptions extends object = {},\n TSystemOptions extends object = {},\n TNeedsCtx extends object = {},\n TColumnKinds extends ColumnKindsTypes = never,\n TContextOptions extends object = {},\n TDependsOn extends string = never,\n TFeatureTables extends FeatureTables<TTables> = {},\n>(\n spec: PluginSpecInput<\n TId,\n TTables,\n TRequires,\n TCtx,\n TApi,\n TEntityOptions,\n TErrors,\n TEntities,\n TRelations,\n TKinds,\n TCollectionOptions,\n TSystemOptions,\n TNeedsCtx,\n TColumnKinds,\n TContextOptions,\n never,\n TDependsOn,\n TFeatureTables\n > & { traits?: never },\n): DefinedPlugin<\n Guard<TId>,\n Guard<TTables>,\n Guard<TRequires>,\n Guard<TCtx>,\n Guard<TApi>,\n Guard<TEntityOptions>,\n Guard<TErrors>,\n Guard<TEntities>,\n Guard<TRelations>,\n Guard<TKinds>,\n Guard<TCollectionOptions>,\n Guard<TSystemOptions>,\n Guard<TNeedsCtx>,\n Guard<TColumnKinds>,\n Guard<TContextOptions>,\n never,\n Guard<TDependsOn>,\n Guard<TFeatureTables>\n> {\n if ((spec as { traits?: unknown }).traits !== undefined) {\n throw new ConfigError(\n `Plugin '${String(spec.id)}': entity traits are the core's; a plugin adds and reacts (ADR-077)`,\n )\n }\n return defineFeaturePlugin(spec as never) as never\n}\n\nfunction assertRequirements(spec: AnyPluginSpec, hostTables: Readonly<Record<string, unknown>>) {\n for (const [key, shape] of Object.entries(spec.requires ?? {})) {\n const host = hostTables[key]\n if (!is(host, PgTable)) {\n throw new ConfigError(\n `Plugin '${spec.id}' requires a table '${key}' that the engine's tables do not provide`,\n )\n }\n // A `requires` value is often a type-only cast (`{} as { users: TableShape<…> }`); only a real\n // table carries columns to compare.\n if (!is(shape, PgTable)) continue\n const hostColumns = getTableColumns(host)\n for (const column of Object.keys(getTableColumns(shape))) {\n if (!(column in hostColumns)) {\n throw new ConfigError(\n `Plugin '${spec.id}' requires column '${column}' on table '${key}', which the engine's table lacks`,\n )\n }\n }\n }\n}\n\n// Before it, because the order is what the engine runs plugins in: their contexts, hooks, plans and operations.\nfunction assertDependencies(\n spec: AnyPluginSpec,\n before: ReadonlySet<string>,\n installed: ReadonlySet<string>,\n): void {\n for (const needed of spec.dependsOn ?? []) {\n if (needed === spec.id) {\n throw new ConfigError(`Plugin '${spec.id}' cannot depend on itself`)\n }\n if (before.has(needed)) continue\n throw new ConfigError(\n installed.has(needed)\n ? `Plugin '${spec.id}' needs plugin '${needed}' installed before it`\n : `Plugin '${spec.id}' needs plugin '${needed}', which is not installed`,\n )\n }\n}\n\n// Where a list of plugins is written (`defineSetup`), before any engine resolves it.\nexport function checkDependencies(plugins: readonly AnyPluginSpec[]): void {\n const installed = new Set(plugins.map((plugin) => plugin.id))\n const before = new Set<string>()\n for (const plugin of plugins) {\n assertDependencies(plugin, before, installed)\n before.add(plugin.id)\n }\n}\n\nfunction collectEntities(spec: AnyPluginSpec): Record<string, EntityDef<string, unknown>> {\n if (spec.entities === undefined) return {}\n const tables = spec.tables ?? {}\n const define = (name: string, options: unknown): EntityDef<string, unknown> => {\n if (!(name in tables)) {\n throw new ConfigError(\n `Plugin '${spec.id}' defines entity '${name}' but owns no table with that key`,\n )\n }\n return { name, options: options ?? {} }\n }\n const entities = spec.entities(define as never)\n for (const [key, def] of Object.entries(entities)) {\n if (def.name !== key) {\n throw new ConfigError(\n `Plugin '${spec.id}': entity registered as '${key}' is defined as '${def.name}'`,\n )\n }\n }\n return entities\n}\n\nexport function resolvePlugins(\n plugins: readonly AnyPlugin[],\n hostTables: Readonly<Record<string, unknown>>,\n): PluginRuntime[] {\n const seen = new Set<string>()\n const installed = new Set(plugins.map((plugin) => plugin.id))\n const claimedTables = new Map<string, string>()\n const runtimes: PluginRuntime[] = []\n for (const plugin of plugins) {\n const spec: AnyPluginSpec = plugin\n if (seen.has(spec.id)) throw new ConfigError(`Duplicate plugin id '${spec.id}'`)\n assertDependencies(spec, seen, installed)\n seen.add(spec.id)\n assertRequirements(spec, hostTables)\n const tables = { ...spec.tables }\n for (const [feature, variants] of Object.entries(spec.featureTables ?? {})) {\n if (installed.has(feature)) Object.assign(tables, variants)\n }\n for (const key of Object.keys(tables)) {\n if (key in hostTables) {\n throw new ConfigError(\n `Plugin '${spec.id}' table '${key}' collides with a table of the engine`,\n )\n }\n const owner = claimedTables.get(key)\n if (owner !== undefined) {\n throw new ConfigError(\n `Plugin '${spec.id}' table '${key}' collides with a table of plugin '${owner}'`,\n )\n }\n claimedTables.set(key, spec.id)\n }\n runtimes.push({\n id: spec.id,\n spec,\n columnKinds: spec.columnKinds ?? null,\n traits: spec.traits ?? null,\n tables,\n entities: collectEntities(spec),\n hooks: spec.hooks ?? null,\n routes: spec.routes ?? [],\n errors: spec.errors ?? {},\n })\n }\n columnKindsOf(runtimes)\n traitOperations(runtimes)\n traitRules(runtimes)\n return runtimes\n}\n\nexport type ResolvedOperation = {\n readonly name: string\n readonly plugin: PluginRuntime\n readonly spec: TraitOperation\n}\n\nconst CORE_OPS = new Set([\n 'find',\n 'findOne',\n 'findById',\n 'count',\n 'page',\n 'create',\n 'update',\n 'updateMany',\n 'delete',\n 'deleteMany',\n 'query',\n 'queryOne',\n 'run',\n 'schemas',\n])\n\nconst byPlugins = new WeakMap<readonly PluginRuntime[], ReadonlyMap<string, ResolvedOperation>>()\n\n// Operation names are one namespace: the entity API, descriptors and routes all address them by name, and a\n// dotted one (`versions.list`) is a method of an object named after its first part, which is then no method.\nexport function traitOperations(\n plugins: readonly PluginRuntime[],\n): ReadonlyMap<string, ResolvedOperation> {\n let operations = byPlugins.get(plugins)\n if (operations !== undefined) return operations\n const out = new Map<string, ResolvedOperation>()\n for (const plugin of plugins) {\n for (const [name, spec] of Object.entries(plugin.traits?.operations ?? {})) {\n const path = name.split('.')\n if (path.some((part) => part === '') || CORE_OPS.has(path[0] as string)) {\n throw new ConfigError(`Plugin '${plugin.id}': '${name}' cannot name an operation`)\n }\n const owner = out.get(name)\n if (owner !== undefined) {\n throw new ConfigError(\n `Operation '${name}' is added by both plugin '${owner.plugin.id}' and plugin '${plugin.id}'`,\n )\n }\n for (const other of out.keys()) {\n if (other.startsWith(`${name}.`) || name.startsWith(`${other}.`)) {\n throw new ConfigError(\n `Operation '${name}' and operation '${other}' cannot both exist: one would hide the other`,\n )\n }\n }\n out.set(name, { name, plugin, spec })\n }\n }\n operations = out\n byPlugins.set(plugins, operations)\n return operations\n}\n\nexport type ResolvedRule = {\n readonly name: string\n readonly plugin: string\n readonly kind: RuleKind\n}\n\nexport const CORE_RULES: ReadonlyMap<string, RuleKind> = new Map([\n ['read', 'filter'],\n ['create', 'boolean'],\n ['update', 'filter'],\n ['delete', 'filter'],\n])\n\nconst rulesByPlugins = new WeakMap<readonly PluginRuntime[], ReadonlyMap<string, ResolvedRule>>()\n\n// Rule names are one namespace too: `access` is one object, whoever declared its keys.\nexport function traitRules(plugins: readonly PluginRuntime[]): ReadonlyMap<string, ResolvedRule> {\n let rules = rulesByPlugins.get(plugins)\n if (rules !== undefined) return rules\n const out = new Map<string, ResolvedRule>()\n for (const plugin of plugins) {\n for (const [name, kind] of Object.entries(plugin.traits?.rules ?? {})) {\n if (CORE_RULES.has(name)) {\n throw new ConfigError(`Plugin '${plugin.id}': rule '${name}' is one of the engine's`)\n }\n if (kind !== 'filter' && kind !== 'boolean') {\n throw new ConfigError(`Plugin '${plugin.id}': rule '${name}' must be 'filter' or 'boolean'`)\n }\n const owner = out.get(name)\n if (owner !== undefined) {\n throw new ConfigError(\n `Rule '${name}' is added by both plugin '${owner.plugin}' and plugin '${plugin.id}'`,\n )\n }\n out.set(name, { name, plugin: plugin.id, kind })\n }\n }\n rules = out\n rulesByPlugins.set(plugins, rules)\n return rules\n}\n\nconst kindsByPlugins = new WeakMap<readonly PluginRuntime[], Map<string, ColumnKindRuntime>>()\n\n// A column is marked with a kind id (`localized`); the plugin that gives the kind behaviour is the one that\n// lists it. A kind nobody lists is inert: the column reads and writes as what it stores.\nexport function columnKindsOf(runtimes: readonly PluginRuntime[]): Map<string, ColumnKindRuntime> {\n let kinds = kindsByPlugins.get(runtimes)\n if (kinds !== undefined) return kinds\n kinds = new Map()\n for (const runtime of runtimes) {\n for (const [id, spec] of Object.entries(runtime.columnKinds?.kinds ?? {})) {\n const owner = kinds.get(id)\n if (owner !== undefined) {\n throw new ConfigError(\n `Column kind '${id}' is handled by both plugin '${owner.plugin}' and plugin '${runtime.id}'`,\n )\n }\n kinds.set(id, { ...spec, id, plugin: runtime.id })\n }\n }\n kindsByPlugins.set(runtimes, kinds)\n return kinds\n}\n\nfunction isPromise(value: unknown): value is Promise<unknown> {\n return typeof (value as { then?: unknown } | null)?.then === 'function'\n}\n\n// Plugin entity options are the non-core keys of the entity options; every plugin's schema sees the\n// same record, so schemas must tolerate keys owned by other plugins.\nexport function validatePluginEntityOptions(\n runtimes: readonly PluginRuntime[],\n entity: string,\n pluginOptions: Readonly<Record<string, unknown>>,\n): void {\n for (const runtime of runtimes) {\n const schema: StandardSchemaV1 | undefined = runtime.spec.entityOptions?.schema\n if (schema === undefined) continue\n const result = schema['~standard'].validate(pluginOptions)\n if (isPromise(result)) {\n throw new ConfigError(\n `Plugin '${runtime.id}': entityOptions.schema must validate synchronously (entity '${entity}')`,\n )\n }\n if (result.issues !== undefined && result.issues.length > 0) {\n throw new ConfigError(\n `Entity '${entity}': invalid options for plugin '${runtime.id}': ${result.issues\n .map((issue) => issue.message)\n .join('; ')}`,\n 'config',\n { entity, details: { plugin: runtime.id, issues: result.issues } },\n )\n }\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { type AnyRelations, getTableColumns, getTableName } from 'drizzle-orm'\nimport { type AnyPgColumn, getTableConfig, type PgTable } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\nimport { readColumnKind } from '../schema/column-kinds.js'\nimport type { AllowAll, AnyAccessRules } from '../types/access.js'\nimport type { EntityDef, FieldRuleArgs } from '../types/entity.js'\nimport type { EntityHooks } from '../types/hooks.js'\nimport type { ColumnMeta, EntityMeta, RelationMeta } from '../types/meta.js'\nimport type { PluginRuntime } from '../types/plugin.js'\nimport type { EntityTrait, OptionGroup } from '../types/traits.js'\nimport { CORE_RULES, columnKindsOf, traitRules, validatePluginEntityOptions } from './plugin.js'\n\n// The mark `allowAll()` leaves on an access object: the plugins' rules cannot be listed there, so it allows\n// whichever of them the entity has, and a rule given next to it still decides for itself. Global, so that two\n// copies of the package agree on it.\nexport const ALLOW_ALL: unique symbol = Symbol.for('typion.allowAll')\n\nexport function allowAll(): AllowAll {\n return { read: true, create: true, update: true, delete: true, [ALLOW_ALL]: true } as AllowAll\n}\n\nexport function defineEntity<N extends string, const O>(name: N, options?: O): EntityDef<N, O> {\n return { name, options: (options ?? {}) as O }\n}\n\ntype FieldRule = (a: FieldRuleArgs<any>) => boolean\n\ntype RawFieldOptions = {\n read?: false | FieldRule\n write?: false | 'system' | FieldRule\n kind?: string\n}\n\n// What `EntityOptions` looks like once the literal types are erased; every check below re-validates\n// what the type level promised, because plugin entities and JS callers bypass it.\nexport type RawEntityOptions = {\n idColumn?: string\n fields?: Record<string, RawFieldOptions | undefined>\n access?: AnyAccessRules\n hooks?: EntityHooks<AnyRelations, string, any>\n validate?: {\n insert?: StandardSchemaV1\n update?: StandardSchemaV1\n fields?: Record<string, unknown>\n }\n defaultOrder?: Record<string, 'asc' | 'desc' | undefined>\n maxLimit?: number\n links?: readonly string[]\n}\n\nconst CORE_OPTION_KEYS = new Set<string>([\n 'idColumn',\n 'fields',\n 'access',\n 'hooks',\n 'validate',\n 'defaultOrder',\n 'maxLimit',\n 'links',\n])\n\nexport type EntityMetaInput = {\n readonly name: string\n readonly options: unknown\n readonly table: PgTable\n readonly relations: AnyRelations\n readonly plugins: readonly PluginRuntime[]\n // Per plugin id, the tables its `derive` returned for this entity.\n readonly derived: ReadonlyMap<string, Readonly<Record<string, PgTable>>>\n readonly maxLimit: number\n readonly owner: 'user' | { readonly plugin: string }\n}\n\nfunction fail(entity: string, message: string): never {\n throw new ConfigError(`Entity '${entity}': ${message}`, 'config', { entity })\n}\n\n// rc.4 types every built column `isPrimaryKey: false`, so the id key is an option (default `id`) and the\n// runtime verifies it is the one and only primary key (ADR-048).\nfunction resolvePrimaryKey(\n entity: string,\n table: PgTable,\n columns: Record<string, AnyPgColumn>,\n idColumn: string,\n): string {\n const config = getTableConfig(table)\n const tableLevel = config.primaryKeys.flatMap((pk) => pk.columns)\n const columnLevel = Object.entries(columns).filter(([, c]) => c.primary)\n if (tableLevel.length + columnLevel.length > 1 || tableLevel.length > 1) {\n fail(entity, 'composite primary keys are not supported (v1 requires a single-column pk)')\n }\n const pkColumn = columnLevel[0]?.[1] ?? tableLevel[0]\n if (pkColumn === undefined) fail(entity, `table '${getTableName(table)}' has no primary key`)\n const pkKey = Object.entries(columns).find(([, c]) => c === pkColumn)?.[0]\n if (pkKey !== idColumn) {\n fail(\n entity,\n `the primary key is '${pkKey}', not '${idColumn}'; set idColumn: '${pkKey}' on the entity`,\n )\n }\n return idColumn\n}\n\nconst ALL_GROUPS: readonly OptionGroup[] = ['read', 'create', 'update', 'delete']\nconst NO_TABLES: Readonly<Record<string, PgTable>> = {}\n\n// A plugin with traits acts on every entity unless its `resolve` says otherwise.\nfunction resolveTraits(\n name: string,\n table: PgTable,\n options: Readonly<Record<string, unknown>>,\n columns: Record<string, AnyPgColumn>,\n plugins: readonly PluginRuntime[],\n derived: EntityMetaInput['derived'],\n): { traits: Record<string, EntityTrait>; managed: string[] } {\n const traits: Record<string, EntityTrait> = {}\n const managed: string[] = []\n for (const plugin of plugins) {\n const spec = plugin.traits\n if (spec === null) continue\n const tables = derived.get(plugin.id) ?? NO_TABLES\n const resolved =\n spec.resolve === undefined\n ? {}\n : spec.resolve({ entity: name, table, columns, options, derived: tables })\n if (resolved === null) {\n if (tables !== NO_TABLES) {\n fail(name, `plugin '${plugin.id}' derived tables for it but does not act on it`)\n }\n continue\n }\n for (const key of resolved.managed ?? []) {\n if (!(key in columns))\n fail(name, `plugin '${plugin.id}' manages '${key}', which is not a column`)\n if (!managed.includes(key)) managed.push(key)\n }\n const own = Object.keys(spec.rules ?? {})\n for (const rule of resolved.rules ?? []) {\n if (!own.includes(rule)) fail(name, `plugin '${plugin.id}' has no rule '${rule}'`)\n }\n traits[plugin.id] = {\n plugin: plugin.id,\n state: resolved.state,\n options: resolved.options ?? ALL_GROUPS,\n rules: resolved.rules ?? own,\n }\n }\n return { traits, managed }\n}\n\n// A rule the entity cannot have is a mistake a missing rule would hide: it would be denied in user mode.\nfunction checkAccess(\n name: string,\n access: Readonly<Record<string, unknown>>,\n traits: Readonly<Record<string, EntityTrait>>,\n plugins: readonly PluginRuntime[],\n): void {\n const rules = traitRules(plugins)\n for (const key of Object.keys(access)) {\n if (CORE_RULES.has(key)) continue\n const rule = rules.get(key)\n if (rule === undefined) fail(name, `access.${key} is not a rule`)\n if (!traits[rule.plugin]?.rules.includes(key)) {\n fail(\n name,\n `access.${key} is a rule of plugin '${rule.plugin}', which does not give it to this entity`,\n )\n }\n }\n}\n\nfunction relationMeta(relations: AnyRelations, entity: string): Record<string, RelationMeta> {\n const out: Record<string, RelationMeta> = {}\n for (const [key, rel] of Object.entries(relations[entity]?.relations ?? {})) {\n out[key] = {\n key,\n target: rel.targetTableName,\n type: rel.relationType,\n optional:\n rel.relationType === 'one' ? ((rel as { optional?: boolean }).optional ?? true) : false,\n through: rel.through !== undefined,\n }\n }\n return out\n}\n\nexport function buildEntityMeta(input: EntityMetaInput): EntityMeta {\n const { name, table } = input\n if (typeof input.options !== 'object' || input.options === null) {\n fail(name, 'options must be an object')\n }\n const options = input.options as RawEntityOptions & Record<string, unknown>\n const columns = getTableColumns(table) as Record<string, AnyPgColumn>\n const pkKey = resolvePrimaryKey(name, table, columns, options.idColumn ?? 'id')\n const { traits, managed: managedKeys } = resolveTraits(\n name,\n table,\n options,\n columns,\n input.plugins,\n input.derived,\n )\n const managed = new Set(managedKeys)\n const access = options.access ?? {}\n checkAccess(name, access, traits, input.plugins)\n\n const fields = options.fields ?? {}\n for (const key of Object.keys(fields)) {\n if (!(key in columns)) fail(name, `fields.${key} does not name a column`)\n }\n\n const kinds = columnKindsOf(input.plugins)\n const columnMeta: Record<string, ColumnMeta> = {}\n for (const [key, column] of Object.entries(columns)) {\n const field = fields[key] ?? {}\n const read = field.read === undefined ? true : field.read\n // TypionEngine-managed columns are written by the engine only; an explicit `write: false` still wins.\n const write =\n field.write !== undefined\n ? field.write\n : managed.has(key)\n ? ('system' as const)\n : ('user' as const)\n columnMeta[key] = {\n key,\n name: column.name,\n column,\n dataType: column.dataType,\n columnType: column.columnType,\n notNull: column.notNull,\n hasDefault: column.hasDefault,\n generated: column.generated !== undefined || column.generatedIdentity !== undefined,\n enumValues: column.enumValues,\n kind: field.kind ?? readColumnKind(column),\n columnKind: kinds.get(readColumnKind(column) ?? '') ?? null,\n read,\n write,\n }\n }\n const pk = columnMeta[pkKey] as ColumnMeta\n if (pk.read === false) fail(name, `the primary key '${pkKey}' cannot be hidden`)\n\n const defaultOrder = options.defaultOrder ?? null\n if (defaultOrder !== null) {\n for (const key of Object.keys(defaultOrder)) {\n if (!(key in columns)) fail(name, `defaultOrder.${key} does not name a column`)\n }\n }\n if (\n options.maxLimit !== undefined &&\n (!Number.isInteger(options.maxLimit) || options.maxLimit < 1)\n ) {\n fail(name, 'maxLimit must be a positive integer')\n }\n\n const relations = relationMeta(input.relations, name)\n for (const key of options.links ?? []) {\n if (relations[key]?.through !== true) {\n fail(name, `links: '${key}' is not a many-to-many relation through a table`)\n }\n }\n\n const pluginOptions: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(options)) {\n if (!CORE_OPTION_KEYS.has(key)) pluginOptions[key] = value\n }\n validatePluginEntityOptions(input.plugins, name, pluginOptions)\n\n const config = getTableConfig(table)\n return {\n name,\n table,\n tableName: config.name,\n pgSchema: config.schema,\n pk,\n columns: columnMeta,\n visibleKeys: Object.keys(columnMeta).filter((k) => columnMeta[k]?.read !== false),\n kindKeys: Object.keys(columnMeta).filter((k) => columnMeta[k]?.columnKind !== null),\n dynamicReadKeys: Object.keys(columnMeta).filter(\n (k) => typeof columnMeta[k]?.read === 'function',\n ),\n managedKeys,\n relations,\n links: new Set(options.links ?? []),\n traits,\n access,\n hooks: options.hooks ?? {},\n validate: options.validate ?? null,\n defaultOrder: defaultOrder as Readonly<Record<string, 'asc' | 'desc'>> | null,\n maxLimit: options.maxLimit ?? input.maxLimit,\n pluginOptions,\n owner: input.owner,\n }\n}\n","import type { Operation, OperationMeta } from '../types/access.js'\nimport type { BaseContext, TypionMode, MaybePromise } from '../types/context.js'\nimport type { AfterCommitQueue } from '../types/runtime.js'\n\nexport type AfterCommitErrorHandler = (error: unknown) => void\n\n// Callbacks of a failed savepoint must not survive it, so every nested operation records a mark and\n// truncates back to it on failure; only the root transaction flushes.\nexport class CommitQueue implements AfterCommitQueue {\n private items: (() => MaybePromise<void>)[] = []\n\n constructor(private readonly onError: AfterCommitErrorHandler) {}\n\n get size(): number {\n return this.items.length\n }\n\n push(fn: () => MaybePromise<void>): void {\n this.items.push(fn)\n }\n\n mark(): number {\n return this.items.length\n }\n\n truncate(mark: number): void {\n this.items.length = Math.min(this.items.length, mark)\n }\n\n async flush(): Promise<void> {\n const items = this.items\n this.items = []\n for (const fn of items) {\n try {\n await fn()\n } catch (error) {\n this.onError(error)\n }\n }\n }\n\n discard(): void {\n this.items = []\n }\n}\n\nexport type FullContext = BaseContext & Record<string, unknown>\n\nexport type ContextParts = {\n readonly user: object\n readonly mode: TypionMode\n readonly request: Request | null\n readonly systemReason: string | null\n readonly meta: Record<string, unknown> | undefined\n readonly now: Date\n}\n\n// Base keys win over same-named user keys: a context factory must not be able to forge the mode or\n// the system reason. `actorId` and `meta` are the two keys the user context is expected to provide.\nexport function buildContext(parts: ContextParts): FullContext {\n const user = parts.user as Record<string, unknown>\n const actorId = typeof user.actorId === 'string' ? user.actorId : null\n const userMeta = user.meta\n const meta =\n parts.meta ??\n (typeof userMeta === 'object' && userMeta !== null ? (userMeta as Record<string, unknown>) : {})\n return {\n ...user,\n mode: parts.mode,\n now: parts.now,\n // Web Crypto, not node:crypto: the runtime must stay importable on edge runtimes and workers.\n requestId: crypto.randomUUID(),\n request: parts.request,\n actorId,\n systemReason: parts.systemReason,\n meta,\n }\n}\n\nexport function operationMeta(\n ctx: FullContext,\n entity: string,\n operation: Operation,\n now: Date,\n): OperationMeta {\n return {\n entity,\n operation,\n mode: ctx.mode,\n requestId: ctx.requestId,\n now,\n systemReason: ctx.systemReason,\n }\n}\n","import { DrizzleError, getTableColumns, TransactionRollbackError } from 'drizzle-orm'\nimport { getTableConfig } from 'drizzle-orm/pg-core'\nimport { BadRequestError, ConflictError, isTypionError } from '../errors.js'\nimport type { EntityMeta } from '../types/meta.js'\nimport type { Runtime } from './internals.js'\n\n// Every error leaving the engine is either an TypionError or something the caller threw on purpose\n// (`tx.rollback()`); driver errors are mapped once, at the boundary.\nexport function normalizeError(runtime: Runtime, error: unknown): unknown {\n if (isTypionError(error) || error instanceof TransactionRollbackError) return error\n if (error instanceof DrizzleError && !(error as { query?: unknown }).query) {\n if (/relational filter field|not enough data provided|relation/i.test(error.message)) {\n return new BadRequestError(error.message, { cause: error })\n }\n }\n const mapped = runtime.dialect.mapError(error)\n return mapped instanceof ConflictError ? described(runtime, mapped) : (mapped ?? error)\n}\n\n// The columns a constraint of the entity's table covers, by its name: a unique index, a unique constraint, a column's\n// own `unique()`, a foreign key. An index over an expression (a localized value) names no column.\nfunction constraintKeys(entity: EntityMeta, constraint: string): string[] {\n const columns = Object.entries(getTableColumns(entity.table))\n const keyOf = (name: string | undefined) =>\n columns.find(([, column]) => column.name === name)?.[0]\n const keys = (names: (string | undefined)[]) =>\n names.map(keyOf).filter((key): key is string => key !== undefined)\n const config = getTableConfig(entity.table)\n const index = config.indexes.find((i) => i.config.name === constraint)\n if (index !== undefined) {\n return keys(index.config.columns.map((c) => (c as { name?: string } | undefined)?.name))\n }\n const unique = config.uniqueConstraints.find((u) => u.getName() === constraint)\n if (unique !== undefined) return keys(unique.columns.map((c) => c.name))\n const foreign = config.foreignKeys.find((f) => f.getName() === constraint)\n if (foreign !== undefined) return keys(foreign.reference().columns.map((c) => c.name))\n // A column's `unique()` without a name is named by drizzle-kit (`_unique`) or, pushed, by Postgres (`_key`).\n const own = columns.find(\n ([, column]) =>\n column.isUnique &&\n (column.uniqueName === constraint ||\n (column.uniqueName === undefined &&\n (constraint === `${config.name}_${column.name}_unique` ||\n constraint === `${config.name}_${column.name}_key`))),\n )\n return own === undefined ? [] : [own[0]]\n}\n\n// A unique or foreign key violation in the engine's words: the entity and its columns, read from the table's own\n// constraints, where Postgres's message names the table and comes in the server's language (ADR-087).\nfunction described(runtime: Runtime, error: ConflictError): ConflictError {\n if ((error.kind !== 'unique' && error.kind !== 'foreign_key') || error.constraint === undefined) {\n return error\n }\n const table = error.details?.table\n const entity = Object.values(runtime.def.entities).find((e) => e.tableName === table)\n if (entity === undefined) return error\n // A unique index within a tenant covers its column too, which the caller never writes: the others say what clashed.\n const covered = constraintKeys(entity, error.constraint)\n const written = covered.filter((key) => !entity.managedKeys.includes(key))\n const keys = written.length > 0 ? written : covered\n const what = keys.length === 0 ? `'${error.constraint}'` : keys.join(', ')\n const unique = error.kind === 'unique'\n return new ConflictError(\n unique\n ? `Entity '${entity.name}': a row with this ${what} exists already`\n : `Entity '${entity.name}': a reference does not hold (${what})`,\n error.kind,\n {\n entity: entity.name,\n constraint: error.constraint,\n details: { sqlstate: error.details?.sqlstate, constraint: error.constraint },\n cause: error.cause,\n ...(keys.length === 0\n ? {}\n : {\n issues: [\n { path: [keys[0] as string], message: unique ? 'already exists' : 'does not hold' },\n ],\n }),\n },\n )\n}\n\nexport async function guard<T>(runtime: Runtime, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn()\n } catch (error) {\n throw normalizeError(runtime, error)\n }\n}\n","import { type AnyRelationsFilter, sql } from 'drizzle-orm'\n\nexport type Filter = Record<string, unknown>\n\n// A denied nested include must still produce a valid query: `null` / `[]` for the relation, never a throw.\nexport const FALSE_FILTER: Filter = { RAW: sql`false` }\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\nexport function isEmptyFilter(filter: Filter | undefined): boolean {\n return filter === undefined || Object.values(filter).every((v) => v === undefined)\n}\n\nexport function andFilters(parts: readonly (Filter | undefined)[]): Filter | undefined {\n const present = parts.filter((p): p is Filter => !isEmptyFilter(p))\n if (present.length === 0) return undefined\n if (present.length === 1) return present[0]\n return { AND: present }\n}\n\n// `AnyRelationsFilter` is an intersection of erased index signatures that rejects ordinary objects, so\n// filters are composed as plain records and cast once, here.\nexport function asRelationsFilter(filter: Filter): AnyRelationsFilter {\n return filter as unknown as AnyRelationsFilter\n}\n","import {\n and,\n eq,\n gt,\n gte,\n ilike,\n inArray,\n isNotNull,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n notIlike,\n notInArray,\n notLike,\n or,\n type SQL,\n sql,\n} from 'drizzle-orm'\nimport type { AnyPgColumn } from 'drizzle-orm/pg-core'\nimport { BadRequestError, UnsupportedError } from '../../errors.js'\nimport type { Dialect } from '../../types/dialect.js'\nimport type { ColumnKindRuntime, OptionType } from '../../types/kinds.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { PluginRuntime } from '../../types/plugin.js'\nimport type { AnyRow } from '../../types/runtime.js'\nimport type { OptionGroup } from '../../types/traits.js'\nimport type { TraitOptionValues } from '../access.js'\nimport type { FullContext } from '../context.js'\nimport { isPlainObject } from '../filters.js'\n\n// Plugin id → the state its `read()` built for the current read (the locale chain, say).\nexport type KindStates = ReadonlyMap<string, unknown>\n\n// The options the installed plugins own: those of column kinds and those of entity traits together, since\n// a call takes them side by side. `write` are the kinds' (every write), `create` and `update` the traits'.\nexport type PluginOptions = {\n readonly read: ReadonlyMap<string, OptionType>\n readonly write: ReadonlyMap<string, OptionType>\n readonly create: ReadonlyMap<string, OptionType>\n readonly update: ReadonlyMap<string, OptionType>\n readonly delete: ReadonlyMap<string, OptionType>\n}\n\nconst optionsByPlugins = new WeakMap<readonly PluginRuntime[], PluginOptions>()\n\n// The read and write options the installed plugins own; without a plugin its options are unknown keys.\nexport function pluginOptions(plugins: readonly PluginRuntime[]): PluginOptions {\n let options = optionsByPlugins.get(plugins)\n if (options === undefined) {\n const read = new Map<string, OptionType>()\n const write = new Map<string, OptionType>()\n const create = new Map<string, OptionType>()\n const update = new Map<string, OptionType>()\n const del = new Map<string, OptionType>()\n for (const plugin of plugins) {\n for (const [key, type] of Object.entries(plugin.columnKinds?.readOptions ?? {})) {\n read.set(key, type)\n }\n for (const [key, type] of Object.entries(plugin.columnKinds?.writeOptions ?? {})) {\n write.set(key, type)\n }\n const traits = plugin.traits?.options\n for (const [group, target] of [\n ['read', read],\n ['create', create],\n ['update', update],\n ['delete', del],\n ] as const) {\n for (const [key, type] of Object.entries(traits?.[group] ?? {})) target.set(key, type)\n }\n }\n options = { read, write, create, update, delete: del }\n optionsByPlugins.set(plugins, options)\n }\n return options\n}\n\nexport function checkOptionType(key: string, type: OptionType, value: unknown): void {\n if (value !== undefined && typeof value !== type) {\n throw new BadRequestError(`${key} must be a ${type}`)\n }\n}\n\n// Each trait plugin's options of a group, picked out of a call's options. A plugin's option given on an\n// entity it does not act on is refused, as its type refuses it.\nexport function traitOptions(\n entity: EntityMeta,\n plugins: readonly PluginRuntime[],\n group: OptionGroup,\n given: AnyRow,\n): TraitOptionValues {\n const out = new Map<string, AnyRow>()\n for (const plugin of plugins) {\n const keys = plugin.traits?.options?.[group]\n if (keys === undefined) continue\n const values: AnyRow = {}\n for (const [key, type] of Object.entries(keys)) {\n checkOptionType(key, type, given[key])\n if (given[key] !== undefined) values[key] = given[key]\n }\n const names = Object.keys(values)\n if (names.length === 0) continue\n const trait = entity.traits[plugin.id]\n if (trait === undefined || !trait.options.includes(group)) {\n throw new UnsupportedError(\n `Entity '${entity.name}' does not take ${names.map((k) => `'${k}'`).join(', ')}: plugin '${plugin.id}' does not act on it`,\n { entity: entity.name },\n )\n }\n out.set(plugin.id, values)\n }\n return out\n}\n\n// The plugins whose kinds an entity has columns of.\nfunction kindPlugins(entity: EntityMeta): ReadonlySet<string> {\n const out = new Set<string>()\n for (const key of entity.kindKeys) {\n const kind = entity.columns[key]?.columnKind\n if (kind !== null && kind !== undefined) out.add(kind.plugin)\n }\n return out\n}\n\n// Plugin id → the state its `write()` built for one write. Write options belong to the entity written: a\n// plugin's option given where the entity has no column of its kinds is refused, as its type refuses it.\n// `null` is a write of stored data (a version restored), which the kinds leave as it is.\nexport type KindWriteStates = ReadonlyMap<string, unknown> | null\n\nexport function writeStates(\n entity: EntityMeta,\n plugins: readonly PluginRuntime[],\n ctx: FullContext,\n given: AnyRow,\n): KindWriteStates {\n const present = kindPlugins(entity)\n const states = new Map<string, unknown>()\n for (const plugin of plugins) {\n const spec = plugin.columnKinds\n if (spec === undefined || spec === null) continue\n const options: AnyRow = {}\n for (const [key, type] of Object.entries(spec.writeOptions ?? {})) {\n checkOptionType(key, type, given[key])\n if (given[key] !== undefined) options[key] = given[key]\n }\n if (!present.has(plugin.id)) {\n const names = Object.keys(options)\n if (names.length > 0) {\n throw new UnsupportedError(\n `Entity '${entity.name}' does not take ${names.map((k) => `'${k}'`).join(', ')}: it has no columns of plugin '${plugin.id}'`,\n { entity: entity.name },\n )\n }\n continue\n }\n if (spec.write !== undefined) states.set(plugin.id, spec.write({ options, ctx }))\n }\n return states\n}\n\nexport function readStates(\n plugins: readonly PluginRuntime[],\n ctx: FullContext,\n config: AnyRow,\n): KindStates {\n const states = new Map<string, unknown>()\n for (const plugin of plugins) {\n const spec = plugin.columnKinds\n if (spec?.read === undefined) continue\n const options: AnyRow = {}\n for (const [key, type] of Object.entries(spec.readOptions ?? {})) {\n checkOptionType(key, type, config[key])\n if (config[key] !== undefined) options[key] = config[key]\n }\n states.set(plugin.id, spec.read({ options, ctx }))\n }\n return states\n}\n\n// What filters, ordering and callbacks see in place of a kind column; `undefined` when the kind keeps the\n// column as it is.\nexport function kindExpression(\n kind: ColumnKindRuntime | null | undefined,\n column: AnyPgColumn | SQL,\n states: KindStates,\n dialect: Dialect,\n sample: unknown,\n): SQL | undefined {\n if (kind?.expression === undefined) return undefined\n return kind.expression({ column, state: states.get(kind.plugin), sample, dialect })\n}\n\n// Resolves the stored values of every kind column in `cells` with one call per kind, so a kind that loads\n// what it resolves to (a media plugin's assets) runs one query per read, not one per row.\nexport async function projectCells(\n cells: readonly {\n readonly row: AnyRow\n readonly key: string\n readonly kind: ColumnKindRuntime\n }[],\n states: KindStates,\n): Promise<void> {\n const byKind = new Map<ColumnKindRuntime, { row: AnyRow; key: string }[]>()\n for (const cell of cells) {\n let list = byKind.get(cell.kind)\n if (list === undefined) {\n list = []\n byKind.set(cell.kind, list)\n }\n list.push(cell)\n }\n for (const [kind, list] of byKind) {\n const project = kind.project\n if (project === undefined) continue\n const values = await project(\n list.map(({ row, key }) => row[key]),\n states.get(kind.plugin),\n )\n list.forEach(({ row, key }, i) => {\n row[key] = values[i]\n })\n }\n}\n\nfunction assertScalar(key: string, value: unknown) {\n if (isPlainObject(value) || Array.isArray(value)) {\n throw new BadRequestError(\n `Filter on column '${key}': only primitive values can be compared through its kind`,\n )\n }\n}\n\nfunction asArray(key: string, op: string, value: unknown): unknown[] {\n if (!Array.isArray(value)) throw new BadRequestError(`Filter '${key}.${op}' expects an array`)\n for (const item of value) assertScalar(key, item)\n return value\n}\n\nfunction asPattern(key: string, op: string, value: unknown): string {\n if (typeof value !== 'string') throw new BadRequestError(`Filter '${key}.${op}' expects a string`)\n return value\n}\n\n// The object filter language over an expression instead of a column: what a kind column compiles to when\n// its kind has an expression. `expr` gets the value compared with, for kinds that need a cast.\nexport function kindFilterSQL(expr: (sample: unknown) => SQL, key: string, filter: unknown): SQL {\n const build = (f: unknown): SQL | undefined => {\n if (!isPlainObject(f)) {\n if (f === null)\n throw new BadRequestError(`Filter '${key}': use { isNull: true } instead of null`)\n assertScalar(key, f)\n return eq(expr(f), f)\n }\n const parts: (SQL | undefined)[] = []\n for (const [op, value] of Object.entries(f)) {\n if (value === undefined) continue\n switch (op) {\n case 'eq':\n case 'ne':\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n assertScalar(key, value)\n const fn = { eq, ne, gt, gte, lt, lte }[op]\n parts.push(fn(expr(value), value))\n break\n }\n case 'in': {\n const items = asArray(key, op, value)\n parts.push(items.length === 0 ? sql`false` : inArray(expr(items[0]), items))\n break\n }\n case 'notIn': {\n const items = asArray(key, op, value)\n if (items.length > 0) parts.push(notInArray(expr(items[0]), items))\n break\n }\n case 'like':\n parts.push(like(expr(null), asPattern(key, op, value)))\n break\n case 'ilike':\n parts.push(ilike(expr(null), asPattern(key, op, value)))\n break\n case 'notLike':\n parts.push(notLike(expr(null), asPattern(key, op, value)))\n break\n case 'notIlike':\n parts.push(notIlike(expr(null), asPattern(key, op, value)))\n break\n case 'isNull':\n if (value === true) parts.push(isNull(expr(null)))\n break\n case 'isNotNull':\n if (value === true) parts.push(isNotNull(expr(null)))\n break\n case 'NOT': {\n const inner = build(value)\n if (inner !== undefined) parts.push(not(inner))\n break\n }\n case 'OR':\n case 'AND': {\n if (!Array.isArray(value))\n throw new BadRequestError(`Filter '${key}.${op}' expects an array`)\n const inner = value.map(build)\n parts.push(op === 'OR' ? or(...inner) : and(...inner))\n break\n }\n default:\n throw new BadRequestError(`Unknown filter operator '${op}' on '${key}'`)\n }\n }\n return and(...parts)\n }\n return build(filter) ?? sql`true`\n}\n","import { type AnyRelations, relationsFilterToSQL, type SQL } from 'drizzle-orm'\nimport type { PgTable } from 'drizzle-orm/pg-core'\nimport { ALLOW_ALL } from '../define/entity.js'\nimport { CORE_RULES, traitRules } from '../define/plugin.js'\nimport { ForbiddenError, InternalError } from '../errors.js'\nimport type { Operation, OperationMeta } from '../types/access.js'\nimport type { ColumnMeta, EntityMeta } from '../types/meta.js'\nimport type { RuleKind } from '../types/traits.js'\nimport { andFilters, asRelationsFilter, type Filter, isPlainObject } from './filters.js'\nimport type { InternalBound } from './internals.js'\nimport { type KindStates, kindExpression, kindFilterSQL, readStates } from './read/kinds.js'\n\n// The engine's rules (`read`, `update`) and those of the plugins acting on the entity (`publish`).\nexport type RuleName = string\n\nexport type RuleOutcome =\n | { readonly kind: 'allow' }\n | { readonly kind: 'deny' }\n | { readonly kind: 'filter'; readonly filter: Filter }\n\nconst ALLOW: RuleOutcome = { kind: 'allow' }\nconst DENY: RuleOutcome = { kind: 'deny' }\n\nexport function forbidden(entity: string, rule: RuleName, meta: OperationMeta, why: string) {\n return new ForbiddenError(`Entity '${entity}': ${why}`, {\n entity,\n operation: meta.operation,\n rule,\n })\n}\n\nfunction ruleKind(entity: EntityMeta, rule: RuleName, bound: InternalBound): RuleKind {\n const core = CORE_RULES.get(rule)\n if (core !== undefined) return core\n const declared = traitRules(bound.runtime.plugins).get(rule)\n if (declared === undefined || !entity.traits[declared.plugin]?.rules.includes(rule)) {\n throw new InternalError(`Entity '${entity.name}' has no rule '${rule}'`, {\n entity: entity.name,\n })\n }\n return declared.kind\n}\n\nexport async function evaluateRule(\n entity: EntityMeta,\n rule: RuleName,\n bound: InternalBound,\n meta: OperationMeta,\n extra: Record<string, unknown> = {},\n): Promise<RuleOutcome> {\n const kind = ruleKind(entity, rule, bound)\n if (bound.$mode === 'system') return ALLOW\n const access = entity.access as Record<string | symbol, unknown>\n const value = access[rule]\n if (value === undefined) {\n if (access[ALLOW_ALL] === true) return ALLOW\n throw forbidden(\n entity.name,\n rule,\n meta,\n `no access.${rule} rule, so '${meta.operation}' is denied in user mode (declare the rule or spread allowAll())`,\n )\n }\n const result =\n typeof value === 'function'\n ? await value({\n ctx: bound.ctx,\n meta,\n typion: bound.systemTwin(`access.${rule} of '${entity.name}'`),\n ...extra,\n })\n : value\n if (result === true) return ALLOW\n if (result === false) return DENY\n if (isPlainObject(result) && kind === 'filter') {\n const states = readStates(bound.runtime.plugins, bound.ctx, {})\n return {\n kind: 'filter',\n filter: ruleFilter(bound, meta.operation, entity.name, result, states),\n }\n }\n throw new InternalError(\n `Entity '${entity.name}': access.${rule} must return a boolean${kind === 'filter' ? ' or a filter object' : ''}`,\n { entity: entity.name },\n )\n}\n\n// A kind column in a rule's filter compares as it does in a caller's `where`, in the read state of the context\n// rather than of the query: what a rule means does not change with the options a caller picks. Unlike a\n// caller's filter it may name hidden columns, and it crosses relations without their rules — but not without what\n// the features keep the call to: a related row that is deleted, a draft or another tenant's grants nothing, whatever\n// options the call gave (ADR-080).\nexport function ruleFilter(\n bound: InternalBound,\n operation: Operation,\n tableKey: string,\n filter: Filter,\n states: KindStates,\n): Filter {\n const runtime = bound.runtime\n const entity = runtime.entityOrNull(tableKey)\n const relations = runtime.relations[tableKey]?.relations ?? {}\n const plain: Filter = {}\n const extra: Filter[] = []\n for (const [key, value] of Object.entries(filter)) {\n if (value === undefined) continue\n if ((key === 'AND' || key === 'OR') && Array.isArray(value)) {\n plain[key] = value.map((part) =>\n isPlainObject(part) ? ruleFilter(bound, operation, tableKey, part, states) : part,\n )\n continue\n }\n if (key === 'NOT' && isPlainObject(value)) {\n plain.NOT = ruleFilter(bound, operation, tableKey, value, states)\n continue\n }\n const relation = relations[key] as { targetTableName: string } | undefined\n if (relation !== undefined) {\n const target = runtime.entityOrNull(relation.targetTableName)\n const kept =\n target === null\n ? undefined\n : pluginFilter(target, bound, operation, NO_TRAIT_OPTIONS, READING)\n if (isPlainObject(value)) {\n const inner = ruleFilter(bound, operation, relation.targetTableName, value, states)\n plain[key] = andFilters([kept, inner]) ?? {}\n continue\n }\n if (value === true) {\n plain[key] = kept ?? true\n continue\n }\n if (value === false) {\n if (kept === undefined) plain[key] = false\n else extra.push({ NOT: { [key]: kept } })\n continue\n }\n }\n const kind = entity?.columns[key]?.columnKind\n if (kind?.expression === undefined) {\n plain[key] = value\n continue\n }\n extra.push({\n RAW: (t: Record<string, unknown>) =>\n kindFilterSQL(\n (sample) => kindExpression(kind, t[key] as SQL, states, runtime.dialect, sample) as SQL,\n key,\n value,\n ),\n })\n }\n return extra.length === 0 ? plain : { AND: [plain, ...extra] }\n}\n\n// Column → the value the call's rows belong to, and the plugin that says so.\nexport type Partition = ReadonlyMap<string, { readonly value: unknown; readonly plugin: string }>\n\nconst UNPARTITIONED: Partition = new Map()\n\nexport function partitionOf(\n entity: EntityMeta,\n bound: InternalBound,\n operation: Operation,\n): Partition {\n let out: Map<string, { value: unknown; plugin: string }> | undefined\n for (const plugin of bound.runtime.plugins) {\n const partition = plugin.traits?.partition\n const trait = entity.traits[plugin.id]\n if (partition === undefined || trait === undefined) continue\n const values = partition({ entity, state: trait.state, operation, ctx: bound.ctx })\n if (values === undefined) continue\n for (const [column, value] of Object.entries(values)) {\n if (!(column in entity.columns)) {\n throw new InternalError(\n `Plugin '${plugin.id}' partitions '${entity.name}' by '${column}', which is not a column`,\n { entity: entity.name },\n )\n }\n if (value === null || value === undefined) {\n throw new ForbiddenError(\n `Entity '${entity.name}' is partitioned by '${column}', and the call has no value for it`,\n { entity: entity.name, operation, rule: `partition:${plugin.id}` },\n )\n }\n out ??= new Map()\n out.set(column, { value, plugin: plugin.id })\n }\n }\n return out ?? UNPARTITIONED\n}\n\nexport function partitionFilter(partition: Partition): Filter | undefined {\n if (partition.size === 0) return undefined\n const filter: Filter = {}\n for (const [column, { value }] of partition) filter[column] = { eq: value }\n return filter\n}\n\n// Whether a filter selects the rows an operation writes (the lock of a write, the matches of a bulk write) or\n// rows it reads (every level of a read, every relation a filter crosses).\nexport type FilterUse = { readonly writing: boolean; readonly skip?: string }\n\nexport const READING: FilterUse = { writing: false }\nexport const WRITING: FilterUse = { writing: true }\n\n// What the plugins keep an operation to: the partition of the call and the rows they hide from it.\nexport function pluginFilter(\n entity: EntityMeta,\n bound: InternalBound,\n operation: Operation,\n options: TraitOptionValues,\n use: FilterUse,\n): Filter | undefined {\n return andFilters([\n partitionFilter(partitionOf(entity, bound, operation)),\n traitFilter(entity, bound, operation, options, use),\n ])\n}\n\n// Plugin id → the options of that plugin the current call gave (`{ withDeleted: true }`).\nexport type TraitOptionValues = ReadonlyMap<string, Readonly<Record<string, unknown>>>\n\nexport const NO_TRAIT_OPTIONS: TraitOptionValues = new Map()\nconst NO_OPTIONS: Readonly<Record<string, unknown>> = {}\n\n// The rows the plugins acting on an entity hide from an operation; `use.skip` names a plugin whose own filter a\n// read source it swapped in replaces.\nexport function traitFilter(\n entity: EntityMeta,\n bound: InternalBound,\n operation: Operation,\n options: TraitOptionValues,\n use: FilterUse,\n): Filter | undefined {\n const parts: (Filter | undefined)[] = []\n for (const plugin of bound.runtime.plugins) {\n const filter = plugin.traits?.filter\n const trait = entity.traits[plugin.id]\n if (filter === undefined || trait === undefined || plugin.id === use.skip) continue\n parts.push(\n filter({\n entity,\n state: trait.state,\n operation,\n writing: use.writing,\n options: options.get(plugin.id) ?? NO_OPTIONS,\n ctx: bound.ctx,\n }) as Filter | undefined,\n )\n }\n return andFilters(parts)\n}\n\nexport function filterToSQL(\n relations: AnyRelations,\n tableKey: string,\n table: PgTable,\n filter: Filter | undefined,\n): SQL | undefined {\n if (filter === undefined) return undefined\n const tableRelations = relations[tableKey]?.relations ?? {}\n return relationsFilterToSQL(table, asRelationsFilter(filter), tableRelations, relations)\n}\n\nexport function fieldReadDenied(\n entity: EntityMeta,\n bound: InternalBound,\n meta: OperationMeta,\n): string[] {\n if (bound.$mode === 'system') return []\n const denied: string[] = []\n for (const key of entity.dynamicReadKeys) {\n const rule = (entity.columns[key] as ColumnMeta).read\n if (typeof rule === 'function' && !rule({ ctx: bound.ctx, meta })) denied.push(key)\n }\n return denied\n}\n\n// Writes are never silently dropped: a key the caller may not write is a FORBIDDEN, not a no-op.\nexport function fieldWriteCheck(\n entity: EntityMeta,\n bound: InternalBound,\n meta: OperationMeta,\n data: Record<string, unknown>,\n allowed: ReadonlySet<string> = new Set(),\n): void {\n for (const key of Object.keys(data)) {\n if (data[key] === undefined || allowed.has(key)) continue\n const column = entity.columns[key]\n if (column === undefined) continue\n const write = column.write\n const denied =\n write === false ||\n (write === 'system' && bound.$mode === 'user') ||\n (typeof write === 'function' && bound.$mode === 'user' && !write({ ctx: bound.ctx, meta }))\n if (denied) {\n throw new ForbiddenError(`Entity '${entity.name}': column '${key}' is not writable here`, {\n entity: entity.name,\n operation: meta.operation,\n rule: `fields.${key}.write`,\n })\n }\n }\n}\n","export function deepEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (a instanceof Date || b instanceof Date) {\n return a instanceof Date && b instanceof Date && a.getTime() === b.getTime()\n }\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => deepEqual(item, b[i]))\n }\n const left = a as Record<string, unknown>\n const right = b as Record<string, unknown>\n const keys = new Set([...Object.keys(left), ...Object.keys(right)])\n for (const key of keys) {\n if (!deepEqual(left[key], right[key])) return false\n }\n return true\n}\n","import type { Operation, OperationMeta } from '../../types/access.js'\nimport type { ChangeOp, GlobalHooks } from '../../types/hooks.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { PluginRuntime } from '../../types/plugin.js'\nimport type { AnyRow, AnyTx } from '../../types/runtime.js'\nimport { CommitQueue, operationMeta } from '../context.js'\nimport { normalizeError } from '../errors.js'\nimport type { InternalBound } from '../internals.js'\n\nexport interface OpScope {\n readonly bound: InternalBound\n readonly tx: AnyTx\n readonly meta: OperationMeta\n readonly bag: Map<string, unknown>\n readonly queue: CommitQueue\n readonly entity: EntityMeta\n}\n\n// One operation = one transaction. Inside an existing transaction (a hook, `$transaction`, `$withTx`) the\n// operation gets a savepoint, so a caller that catches a nested failure keeps a usable transaction, and its\n// afterCommit callbacks are dropped with the savepoint instead of firing on the outer commit.\nexport async function runOperation<T>(\n bound: InternalBound,\n entity: EntityMeta,\n operation: Operation,\n fn: (scope: OpScope) => Promise<T>,\n): Promise<T> {\n const { runtime } = bound\n await runtime.ready()\n const meta = operationMeta(bound.ctx, entity.name, operation, runtime.now())\n const bag = new Map<string, unknown>()\n try {\n if (bound.$tx !== null && bound.queue !== null) {\n const queue = bound.queue\n const mark = queue.mark()\n try {\n return await bound.$tx.transaction((tx) =>\n fn({ bound: bound.joined(tx, queue), tx, meta, bag, queue, entity }),\n )\n } catch (error) {\n queue.truncate(mark)\n throw error\n }\n }\n const queue = new CommitQueue((error) =>\n runtime.afterCommitError(error, {\n entity: entity.name,\n operation,\n requestId: bound.ctx.requestId,\n }),\n )\n let result: T\n try {\n result = await bound.$executor.transaction((tx) =>\n fn({ bound: bound.joined(tx, queue), tx, meta, bag, queue, entity }),\n )\n } catch (error) {\n queue.discard()\n throw error\n }\n await queue.flush()\n return result\n } catch (error) {\n throw normalizeError(runtime, error)\n }\n}\n\nexport function hookBase(scope: OpScope) {\n return {\n ctx: scope.bound.ctx,\n meta: scope.meta,\n typion: scope.bound,\n tx: scope.tx,\n bag: scope.bag,\n }\n}\n\nfunction globalBase(scope: OpScope) {\n return { ...hookBase(scope), entityMeta: scope.entity }\n}\n\nexport function globalHooks(scope: OpScope): GlobalHooks[] {\n const out: GlobalHooks[] = []\n for (const plugin of scope.bound.runtime.plugins) {\n const hooks = plugin.hooks\n if (hooks === null) continue\n if (hooks.entities !== undefined && !hooks.entities.includes(scope.entity.name)) continue\n out.push(hooks)\n }\n return out\n}\n\nexport async function beforeOperation(scope: OpScope, args: unknown): Promise<void> {\n for (const hooks of globalHooks(scope)) {\n await hooks.beforeOperation?.({\n entity: scope.entity.name,\n op: scope.meta.operation,\n args,\n ...globalBase(scope),\n } as never)\n }\n}\n\nexport async function afterOperation(scope: OpScope, result: unknown): Promise<void> {\n for (const hooks of globalHooks(scope)) {\n await hooks.afterOperation?.({\n entity: scope.entity.name,\n op: scope.meta.operation,\n result,\n ...globalBase(scope),\n } as never)\n }\n}\n\nexport async function afterLink(\n scope: OpScope,\n outcome: { op: 'link' | 'unlink'; doc: AnyRow; relation: string; ids: readonly unknown[] },\n): Promise<void> {\n for (const hooks of globalHooks(scope)) {\n await hooks.afterLink?.({\n entity: scope.entity.name,\n ...outcome,\n ...globalBase(scope),\n } as never)\n }\n}\n\n// The arguments the plugins add to the hooks (`version`), per group: their defaults, then what a write's plans\n// and records give.\nexport type HookArgs = {\n readonly change: AnyRow\n readonly afterChange: AnyRow\n readonly afterDelete: AnyRow\n}\n\nconst argsByPlugins = new WeakMap<readonly PluginRuntime[], HookArgs>()\n\nexport function defaultHookArgs(plugins: readonly PluginRuntime[]): HookArgs {\n let args = argsByPlugins.get(plugins)\n if (args === undefined) {\n const out = { change: {}, afterChange: {}, afterDelete: {} }\n for (const plugin of plugins) {\n const defaults = plugin.traits?.hookArgs\n Object.assign(out.change, defaults?.change)\n Object.assign(out.afterChange, defaults?.afterChange)\n Object.assign(out.afterDelete, defaults?.afterDelete)\n }\n args = out\n argsByPlugins.set(plugins, args)\n }\n return args\n}\n\n// `op` is a plugin's operation name when the plugin runs the update (`restore`).\ntype ChangeInput = {\n op: ChangeOp | (string & {})\n data: AnyRow\n original: AnyRow | null\n args: AnyRow\n}\n\nasync function entityChangeHook(\n scope: OpScope,\n name: 'beforeValidate' | 'beforeChange',\n input: ChangeInput,\n): Promise<AnyRow> {\n const hook = scope.entity.hooks[name] as ((a: unknown) => unknown) | undefined\n if (hook === undefined) return input.data\n const { args, ...rest } = input\n const replaced = await hook({ ...args, ...rest, ...hookBase(scope) })\n return (replaced as AnyRow | undefined) ?? input.data\n}\n\nexport function beforeValidate(scope: OpScope, input: ChangeInput): Promise<AnyRow> {\n return entityChangeHook(scope, 'beforeValidate', input)\n}\n\nexport async function beforeChange(scope: OpScope, input: ChangeInput): Promise<AnyRow> {\n let data = await entityChangeHook(scope, 'beforeChange', input)\n const { args, ...rest } = input\n for (const hooks of globalHooks(scope)) {\n if (hooks.beforeChange === undefined) continue\n const replaced = await hooks.beforeChange({\n ...args,\n entity: scope.entity.name,\n ...rest,\n data,\n ...globalBase(scope),\n } as never)\n data = (replaced as AnyRow | undefined) ?? data\n }\n return data\n}\n\nexport type ChangeOutcome = {\n readonly op: ChangeOp | (string & {})\n readonly doc: AnyRow\n readonly previous: AnyRow | null\n readonly changes: readonly string[]\n readonly args: AnyRow\n}\n\nexport async function afterChange(scope: OpScope, outcome: ChangeOutcome): Promise<void> {\n const { args, ...rest } = outcome\n const hook = scope.entity.hooks.afterChange as ((a: unknown) => unknown) | undefined\n await hook?.({ ...args, ...rest, ...hookBase(scope) })\n for (const hooks of globalHooks(scope)) {\n await hooks.afterChange?.({\n ...args,\n entity: scope.entity.name,\n ...rest,\n ...globalBase(scope),\n } as never)\n }\n}\n\nexport async function beforeDelete(scope: OpScope, doc: AnyRow, options: AnyRow): Promise<void> {\n const hook = scope.entity.hooks.beforeDelete as ((a: unknown) => unknown) | undefined\n await hook?.({ doc, options, ...hookBase(scope) })\n}\n\nexport type DeleteOutcome = {\n readonly doc: AnyRow\n readonly previous: AnyRow\n readonly removed: boolean\n readonly options: AnyRow\n readonly args: AnyRow\n}\n\nexport async function afterDelete(scope: OpScope, outcome: DeleteOutcome): Promise<void> {\n const { doc, previous, removed, options, args } = outcome\n const hook = scope.entity.hooks.afterDelete as ((a: unknown) => unknown) | undefined\n await hook?.({ ...args, doc, options, ...hookBase(scope) })\n for (const hooks of globalHooks(scope)) {\n await hooks.afterDelete?.({\n ...args,\n entity: scope.entity.name,\n doc,\n previous,\n removed,\n options,\n ...globalBase(scope),\n } as never)\n }\n}\n\nexport function queueAfterCommit(scope: OpScope, doc: AnyRow | null, previous: AnyRow | null) {\n const { entity, meta, queue } = scope\n const ctx = scope.bound.ctx\n const hook = entity.hooks.afterCommit as ((a: unknown) => unknown) | undefined\n if (hook !== undefined) {\n queue.push(() => hook({ op: meta.operation, doc, previous, ctx, meta }) as void)\n }\n for (const hooks of globalHooks(scope)) {\n const global = hooks.afterCommit\n if (global === undefined) continue\n queue.push(() => global({ entity: entity.name, op: meta.operation, doc, previous, ctx, meta }))\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { is, SQL } from 'drizzle-orm'\nimport { BadRequestError, ValidationError } from '../../errors.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { AnyRow } from '../../types/runtime.js'\nimport { normalizeIssues } from '../../validation/issues.js'\nimport { isPlainObject } from '../filters.js'\nimport type { Runtime } from '../internals.js'\nimport type { KindWriteStates } from '../read/kinds.js'\n\ntype ColumnRuntime = {\n default?: unknown\n defaultFn?: () => unknown\n onUpdateFn?: () => unknown\n generated?: { type?: string }\n generatedIdentity?: { type?: string }\n}\n\nfunction runtimeColumn(entity: EntityMeta, key: string): ColumnRuntime {\n return entity.columns[key]?.column as unknown as ColumnRuntime\n}\n\nexport function isGeneratedAlways(entity: EntityMeta, key: string): boolean {\n const column = runtimeColumn(entity, key)\n return column.generated?.type === 'always' || column.generatedIdentity?.type === 'always'\n}\n\nexport function hasOnUpdate(entity: EntityMeta, key: string): boolean {\n return typeof runtimeColumn(entity, key).onUpdateFn === 'function'\n}\n\nexport function assertData(data: unknown, what = 'data'): AnyRow {\n if (!isPlainObject(data)) throw new BadRequestError(`${what} must be an object`)\n return data\n}\n\n// Rules see the caller's data typed by column (ADR-087), and run before validation: a rule that filters by\n// `data.projectId` must not be handed an operator object (`{ ne: … }`) for a column that holds a string. Objects and\n// arrays are refused here for every column that holds a scalar; a kind column and a json or array one take them.\nexport function assertScalars(entity: EntityMeta, data: AnyRow): void {\n const issues: { path: string[]; message: string }[] = []\n for (const [key, value] of Object.entries(data)) {\n if (!isPlainObject(value) && !Array.isArray(value)) continue\n const column = entity.columns[key]\n if (column === undefined || column.columnKind !== null) continue\n const type = column.dataType.split(' ')[0]\n if (type === 'string' || type === 'number' || type === 'boolean' || type === 'bigint') {\n issues.push({\n path: [key],\n message: `Expected a ${type}, not ${Array.isArray(value) ? 'an array' : 'an object'}`,\n })\n }\n }\n if (issues.length > 0) {\n throw new ValidationError(`Entity '${entity.name}': invalid data`, issues, {\n entity: entity.name,\n })\n }\n}\n\n// Only static values and `$defaultFn` are applied here, so hooks and validation see them; SQL defaults\n// (`defaultNow()`, `defaultRandom()`) stay with the database.\nexport function applyDefaults(entity: EntityMeta, data: AnyRow): AnyRow {\n const out = { ...data }\n for (const key of Object.keys(entity.columns)) {\n if (out[key] !== undefined) continue\n const column = runtimeColumn(entity, key)\n if (typeof column.defaultFn === 'function') out[key] = column.defaultFn()\n else if (column.default !== undefined && !is(column.default, SQL)) {\n out[key] =\n typeof column.default === 'object' ? structuredClone(column.default) : column.default\n }\n }\n return out\n}\n\n// A write that gives a plugin's write options hands the kind columns it sets to that plugin's kind, which\n// merges them with the stored value (a locale-scoped write into the per-locale object). Without options,\n// every column is written as given.\nexport function applyKindWrites(\n entity: EntityMeta,\n base: AnyRow | null,\n data: AnyRow,\n states: KindWriteStates,\n): AnyRow {\n const out = { ...data }\n if (states === null) return out\n for (const key of entity.kindKeys) {\n const kind = entity.columns[key]?.columnKind\n if (kind?.write === undefined || data[key] === undefined) continue\n out[key] = kind.write({ value: data[key], stored: base?.[key], state: states.get(kind.plugin) })\n }\n return out\n}\n\nasync function runSchema(schema: StandardSchemaV1, value: unknown, entity: EntityMeta) {\n const result = await schema['~standard'].validate(value)\n if (result.issues !== undefined) {\n const issues = normalizeIssues(result.issues)\n const summary = issues\n .slice(0, 3)\n .map((i) => `${i.path.map(String).join('.') || '(root)'}: ${i.message}`)\n .join('; ')\n throw new ValidationError(`Invalid ${entity.name}: ${summary}`, issues, { entity: entity.name })\n }\n return result.value as AnyRow\n}\n\nfunction insertable(entity: EntityMeta, row: AnyRow): AnyRow {\n const out: AnyRow = {}\n for (const key of Object.keys(entity.columns)) {\n if (row[key] !== undefined && !isGeneratedAlways(entity, key)) out[key] = row[key]\n }\n return out\n}\n\nexport async function validateCreate(runtime: Runtime, entity: EntityMeta, data: AnyRow) {\n const unknown = Object.keys(data).filter((k) => data[k] !== undefined && !(k in entity.columns))\n if (unknown.length > 0) {\n throw new ValidationError(\n `Invalid ${entity.name}: unknown key${unknown.length > 1 ? 's' : ''} ${unknown.join(', ')}`,\n unknown.map((k) => ({ path: [k], message: `Unknown key '${k}'` })),\n { entity: entity.name },\n )\n }\n const base = await runSchema(runtime.schema(entity, 'insert'), insertable(entity, data), entity)\n const user = entity.validate?.insert\n return user === undefined ? base : runSchema(user, base, entity)\n}\n\n// The merged row is validated with the insert schema because that is where the row invariants live (a\n// notNull localized column keeps its default locale, required columns stay set); user update rules see\n// the patch alone.\nexport async function validateUpdate(\n runtime: Runtime,\n entity: EntityMeta,\n base: AnyRow,\n patch: AnyRow,\n): Promise<AnyRow> {\n const unknown = Object.keys(patch).filter((k) => patch[k] !== undefined && !(k in entity.columns))\n if (unknown.length > 0) {\n throw new ValidationError(\n `Invalid ${entity.name}: unknown key${unknown.length > 1 ? 's' : ''} ${unknown.join(', ')}`,\n unknown.map((k) => ({ path: [k], message: `Unknown key '${k}'` })),\n { entity: entity.name },\n )\n }\n const merged = await runSchema(\n runtime.schema(entity, 'insert'),\n insertable(entity, { ...base, ...patch }),\n entity,\n )\n const validated: AnyRow = {}\n for (const key of Object.keys(patch)) {\n if (patch[key] === undefined) continue\n validated[key] = key in merged ? merged[key] : patch[key]\n }\n const user = entity.validate?.update\n return user === undefined ? validated : runSchema(user, validated, entity)\n}\n\nexport function stripHidden(entity: EntityMeta, row: AnyRow): AnyRow {\n const out: AnyRow = {}\n for (const [key, value] of Object.entries(row)) {\n if (entity.columns[key]?.read !== false) out[key] = value\n }\n return out\n}\n","import { getTableColumns } from 'drizzle-orm'\nimport type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core'\nimport { ValidationError, type ValidationIssue } from '../../errors.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { AnyRow } from '../../types/runtime.js'\nimport {\n filterToSQL,\n type Partition,\n partitionFilter,\n partitionOf,\n traitFilter,\n WRITING,\n} from '../access.js'\nimport { andFilters } from '../filters.js'\nimport type { InternalBound } from '../internals.js'\nimport { traitOptions } from '../read/kinds.js'\nimport type { OpScope } from './pipeline.js'\n\ntype OneRelation = {\n readonly sourceColumns: readonly AnyPgColumn[]\n readonly targetColumns: readonly AnyPgColumn[]\n}\n\nfunction keysOf(table: PgTable, columns: readonly AnyPgColumn[]): (string | undefined)[] {\n const entries = Object.entries(getTableColumns(table))\n return columns.map((column) => entries.find(([, c]) => c === column)?.[0])\n}\n\nfunction* oneTargets(entity: EntityMeta, bound: InternalBound) {\n for (const relation of Object.values(entity.relations)) {\n if (relation.type !== 'one' || relation.through) continue\n const target = bound.runtime.entityOrNull(relation.target)\n if (target !== null) yield { relation, target }\n }\n}\n\n// Whether a write to the entity may set a reference to a row soft delete keeps: then it takes `withDeleted`.\nexport function referencesDeletable(entity: EntityMeta, bound: InternalBound): boolean {\n for (const { target } of oneTargets(entity, bound)) {\n if (target.traits.softDelete !== undefined) return true\n }\n return false\n}\n\nconst NO_PARTITION: Partition = new Map()\n\n// A reference points at a row the write could reach: inside the call's partition — another tenant's row is refused,\n// and only an unscoped call is not checked (ADR-086) — and not one the features keep as gone, a soft-deleted row,\n// unless the call says `withDeleted` (ADR-088). Either is worded as a row that does not exist, so it tells the caller\n// nothing. Drafts count: a write reaches them. Only the references the write sets are checked.\nexport async function checkReferences(\n scope: OpScope,\n row: AnyRow,\n written: ReadonlySet<string>,\n options: AnyRow,\n): Promise<void> {\n const { entity, bound, tx, meta } = scope\n const partitioned = partitionOf(entity, bound, meta.operation).size > 0\n const issues: ValidationIssue[] = []\n for (const { relation, target } of oneTargets(entity, bound)) {\n const partition = partitioned ? partitionOf(target, bound, 'findById') : NO_PARTITION\n const kept = traitFilter(\n target,\n bound,\n 'findById',\n traitOptions(\n target,\n bound.runtime.plugins,\n 'read',\n options.withDeleted === true && target.traits.softDelete !== undefined\n ? { withDeleted: true }\n : {},\n ),\n WRITING,\n )\n if (partition.size === 0 && kept === undefined) continue\n const rel = bound.runtime.relations[entity.name]?.relations[\n relation.key\n ] as unknown as OneRelation\n const sources = keysOf(entity.table, rel.sourceColumns)\n const targets = keysOf(target.table, rel.targetColumns)\n // A relation whose columns are this row's key points the other way: the reference is the target's.\n if (sources.some((key) => key === undefined || key === entity.pk.key)) continue\n if (!sources.some((key) => written.has(key as string))) continue\n const values = sources.map((key) => row[key as string])\n if (values.some((value) => value === null || value === undefined)) continue\n const filter = andFilters([\n ...targets.map((key, i) => ({ [key as string]: { eq: values[i] } })),\n partitionFilter(partition),\n kept,\n ])\n const where = filterToSQL(bound.runtime.relations, target.name, target.table, filter)\n if (Number(await tx.$count(target.table, where)) === 0) {\n issues.push({\n path: [sources[0] as string],\n message: `No ${target.name} row ${values.map(String).join(', ')}`,\n })\n }\n }\n if (issues.length > 0) {\n throw new ValidationError(`Entity '${entity.name}': a reference points at no row`, issues, {\n entity: entity.name,\n })\n }\n}\n","import { eq } from 'drizzle-orm'\nimport type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core'\nimport { BadRequestError, ForbiddenError, InternalError, NotFoundError } from '../../errors.js'\nimport type { ChangeOp } from '../../types/hooks.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { AnyRow } from '../../types/runtime.js'\nimport type { HookArgGroup, HookArgValues } from '../../types/traits.js'\nimport {\n evaluateRule,\n fieldReadDenied,\n fieldWriteCheck,\n filterToSQL,\n forbidden,\n type RuleName,\n type RuleOutcome,\n partitionFilter,\n partitionOf,\n pluginFilter,\n type TraitOptionValues,\n type Partition,\n traitFilter,\n WRITING,\n} from '../access.js'\nimport { deepEqual } from '../equal.js'\nimport { andFilters, type Filter, isPlainObject } from '../filters.js'\nimport type { InternalBound } from '../internals.js'\nimport {\n type KindWriteStates,\n pluginOptions,\n projectCells,\n readStates,\n traitOptions,\n writeStates,\n} from '../read/kinds.js'\nimport {\n afterChange,\n afterDelete,\n afterOperation,\n beforeChange,\n beforeDelete,\n beforeOperation,\n beforeValidate,\n type DeleteOutcome,\n defaultHookArgs,\n type OpScope,\n queueAfterCommit,\n runOperation,\n} from './pipeline.js'\nimport {\n applyDefaults,\n applyKindWrites,\n assertData,\n assertScalars,\n stripHidden,\n validateCreate,\n validateUpdate,\n} from './validate.js'\nimport { checkReferences, referencesDeletable } from './references.js'\n\n// `withDeleted` on a write that may point at a soft-deleted row (ADR-088).\nexport function referenceOptionKeys(entity: EntityMeta, bound: InternalBound): string[] {\n return referencesDeletable(entity, bound) ? ['withDeleted'] : []\n}\n\nconst NO_KEYS: ReadonlySet<string> = new Set()\nconst NO_VALUES: Readonly<Record<string, unknown>> = {}\n\nfunction column(table: PgTable, key: string): AnyPgColumn {\n return (table as unknown as Record<string, AnyPgColumn>)[key] as AnyPgColumn\n}\n\nexport function assertId(entity: EntityMeta, id: unknown): void {\n if (id === undefined || id === null || typeof id === 'object') {\n throw new BadRequestError(`${entity.name}: a scalar id is required`, { entity: entity.name })\n }\n}\n\nexport function writeOptionKeys(bound: InternalBound): string[] {\n return [...pluginOptions(bound.runtime.plugins).write.keys()]\n}\n\n// What a write returns: the row as the caller would read it straight after, read with the write's options\n// (`locale`): hidden columns absent, those a field rule denies null, kind columns resolved. Hooks and what the\n// plugins record keep the stored row.\nexport async function resultOf(scope: OpScope, doc: AnyRow, options: AnyRow): Promise<AnyRow> {\n const { entity, bound } = scope\n const out = stripHidden(entity, doc)\n for (const key of fieldReadDenied(entity, bound, scope.meta)) {\n if (key in out) out[key] = null\n }\n const cells = entity.kindKeys.flatMap((key) => {\n const kind = entity.columns[key]?.columnKind\n return kind === null || kind === undefined || !(key in out) ? [] : [{ row: out, key, kind }]\n })\n if (cells.length > 0)\n await projectCells(cells, readStates(bound.runtime.plugins, bound.ctx, options))\n return out\n}\n\nexport function assertOptions(options: unknown, keys: readonly string[]): AnyRow {\n if (options === undefined) return {}\n if (!isPlainObject(options)) throw new BadRequestError('options must be an object')\n for (const key of Object.keys(options)) {\n if (!keys.includes(key)) throw new BadRequestError(`Unknown option '${key}'`)\n }\n return options\n}\n\nexport async function writeRule(\n scope: OpScope,\n rule: RuleName,\n extra: Record<string, unknown>,\n): Promise<Filter | undefined> {\n const outcome: RuleOutcome = await evaluateRule(\n scope.entity,\n rule,\n scope.bound,\n scope.meta,\n extra,\n )\n if (outcome.kind === 'deny') {\n throw forbidden(\n scope.entity.name,\n rule,\n scope.meta,\n `access.${rule} denies '${scope.meta.operation}'`,\n )\n }\n return outcome.kind === 'filter' ? outcome.filter : undefined\n}\n\n// A partition's columns are managed, but repeating the call's value is harmless; a different value would\n// move the row out of the caller's partition.\nexport function partitionAllowance(\n scope: OpScope,\n data: AnyRow,\n): { allowed: ReadonlySet<string>; partition: Partition } {\n const { entity, bound, meta } = scope\n const partition = partitionOf(entity, bound, meta.operation)\n let allowed: Set<string> | undefined\n for (const [key, { value, plugin }] of partition) {\n const given = data[key]\n if (given === undefined) continue\n if (!deepEqual(given, value)) {\n throw new ForbiddenError(\n `Entity '${entity.name}': '${key}' cannot be set outside the call's partition`,\n { entity: entity.name, operation: meta.operation, rule: `partition:${plugin}` },\n )\n }\n ;(allowed ??= new Set()).add(key)\n }\n return { allowed: allowed ?? NO_KEYS, partition }\n}\n\n// Lock first, then run hooks: a row the caller may not touch is never read, and concurrent writes to\n// one document serialize (what the plugins record of it, their checks of it).\nexport async function lockRow(\n scope: OpScope,\n id: unknown,\n parts: readonly (Filter | undefined)[],\n): Promise<AnyRow> {\n const { entity, bound } = scope\n const filter = andFilters([{ [entity.pk.key]: { eq: id } }, ...parts])\n const where = filterToSQL(bound.runtime.relations, entity.name, entity.table, filter)\n const rows = await bound.runtime.dialect.lockSelect(scope.tx, entity.table, where)\n const row = rows[0]\n if (row === undefined) {\n throw new NotFoundError(`${entity.name} '${String(id)}' not found`, { entity: entity.name })\n }\n return row\n}\n\nexport function changedKeys(entity: EntityMeta, before: AnyRow | null, after: AnyRow): string[] {\n return Object.keys(entity.columns).filter((key) =>\n before === null\n ? after[key] !== undefined && after[key] !== null\n : !deepEqual(before[key], after[key]),\n )\n}\n\ntype Args = Record<HookArgGroup, AnyRow>\n\nfunction hookArgs(scope: OpScope): Args {\n const defaults = defaultHookArgs(scope.bound.runtime.plugins)\n return {\n change: { ...defaults.change },\n afterChange: { ...defaults.afterChange },\n afterDelete: { ...defaults.afterDelete },\n }\n}\n\nfunction addArgs(args: Args, given: HookArgValues | undefined): void {\n if (given === undefined) return\n Object.assign(args.change, given.change)\n Object.assign(args.afterChange, given.afterChange)\n Object.assign(args.afterDelete, given.afterDelete)\n}\n\n// The plugins acting on the entity, with their resolved state, in the order they are installed.\nfunction* actingPlugins(scope: OpScope) {\n for (const plugin of scope.bound.runtime.plugins) {\n const trait = scope.entity.traits[plugin.id]\n if (plugin.traits !== null && trait !== undefined) {\n yield { plugin, trait, traits: plugin.traits }\n }\n }\n}\n\ntype RecordStep = {\n readonly operation: string\n readonly step: 'create' | 'update' | 'delete'\n readonly row: AnyRow\n readonly previous: AnyRow | null\n readonly written: boolean\n readonly options: TraitOptionValues\n}\n\n// What the plugins record of a write, merged into the arguments of the after hooks of its step.\nasync function record(scope: OpScope, input: RecordStep, into: AnyRow): Promise<void> {\n for (const { plugin, trait, traits } of actingPlugins(scope)) {\n if (traits.record === undefined) continue\n const recorded = await traits.record({\n entity: scope.entity,\n state: trait.state,\n operation: input.operation,\n step: input.step,\n row: input.row,\n previous: input.previous,\n written: input.written,\n options: input.options.get(plugin.id) ?? NO_VALUES,\n now: scope.meta.now,\n tx: scope.tx,\n ctx: scope.bound.ctx,\n })\n if (recorded !== undefined && recorded !== null) Object.assign(into, recorded)\n }\n}\n\nexport type UpdatePlan = {\n readonly base: AnyRow\n readonly keep: boolean\n readonly args: Args\n}\n\n// Under the row lock and before any hook: what the plugins do to this update. The first plugin that gives a\n// base or keeps the row decides; every plugin's arguments reach the hooks.\nexport async function planUpdate(\n scope: OpScope,\n row: AnyRow,\n op: string,\n options: TraitOptionValues,\n): Promise<UpdatePlan> {\n const args = hookArgs(scope)\n let base: AnyRow | undefined\n let keep = false\n for (const { plugin, trait, traits } of actingPlugins(scope)) {\n if (traits.update === undefined) continue\n const plan = await traits.update({\n entity: scope.entity,\n state: trait.state,\n operation: op,\n options: options.get(plugin.id) ?? NO_VALUES,\n row,\n tx: scope.tx,\n ctx: scope.bound.ctx,\n })\n if (plan === undefined) continue\n if (base === undefined && !keep) {\n base = plan.base\n keep = plan.keep === true\n }\n addArgs(args, plan.args)\n }\n return { base: base ?? row, keep, args }\n}\n\nexport type UpdateCoreArgs = {\n readonly original: AnyRow\n readonly patch: AnyRow\n readonly op: ChangeOp | (string & {})\n readonly plan: UpdatePlan\n readonly options: TraitOptionValues\n // The caller's `withDeleted`: the references it sets may point at soft-deleted rows.\n readonly withDeleted?: boolean\n}\n\nexport type WriteResult = { readonly doc: AnyRow }\n\nexport async function updateCore(scope: OpScope, args: UpdateCoreArgs): Promise<WriteResult> {\n const { entity, tx, bound } = scope\n const { original, op, plan } = args\n const { base, keep } = plan\n const change = plan.args.change\n let patch = await beforeValidate(scope, { op, data: args.patch, original, args: change })\n patch = await validateUpdate(bound.runtime, entity, base, patch)\n patch = await beforeChange(scope, { op, data: patch, original, args: change })\n await checkReferences(\n scope,\n { ...base, ...patch },\n new Set(Object.keys(patch).filter((key) => patch[key] !== undefined)),\n { withDeleted: args.withDeleted },\n )\n\n let doc: AnyRow\n if (keep) {\n doc = { ...base, ...patch }\n } else {\n const keys = Object.keys(patch).filter((k) => patch[k] !== undefined)\n if (keys.length === 0) return { doc: original }\n const pk = column(entity.table, entity.pk.key)\n const rows = (await tx\n .update(entity.table)\n .set(patch as never)\n .where(eq(pk, original[entity.pk.key]))\n .returning()) as AnyRow[]\n const updated = rows[0]\n if (updated === undefined) throw new InternalError(`${entity.name}: locked row vanished`)\n doc = updated\n }\n const after = { ...change, ...plan.args.afterChange }\n await record(\n scope,\n {\n operation: op,\n step: 'update',\n row: doc,\n previous: base,\n written: !keep,\n options: args.options,\n },\n after,\n )\n await afterChange(scope, {\n op,\n doc,\n previous: base,\n changes: changedKeys(entity, base, doc),\n args: after,\n })\n return { doc }\n}\n\n// Shared by update and bulk update: the plugins' plan decides what the write builds on, and the kinds merge\n// the caller's values into that.\nexport async function updateDocument(\n scope: OpScope,\n original: AnyRow,\n data: AnyRow,\n opts: {\n states: KindWriteStates\n op: ChangeOp\n options: TraitOptionValues\n withDeleted?: boolean\n },\n): Promise<WriteResult> {\n const plan = await planUpdate(scope, original, opts.op, opts.options)\n return updateCore(scope, {\n original,\n patch: applyKindWrites(scope.entity, plan.base, data, opts.states),\n op: opts.op,\n plan,\n options: opts.options,\n withDeleted: opts.withDeleted,\n })\n}\n\ntype CreatePlan = {\n readonly set: AnyRow\n readonly rules: readonly string[]\n readonly args: Args\n}\n\nfunction planCreate(scope: OpScope, row: AnyRow, options: TraitOptionValues): CreatePlan {\n const args = hookArgs(scope)\n const set: AnyRow = {}\n const rules: string[] = []\n for (const { plugin, trait, traits } of actingPlugins(scope)) {\n if (traits.create === undefined) continue\n const plan = traits.create({\n entity: scope.entity,\n state: trait.state,\n options: options.get(plugin.id) ?? NO_VALUES,\n row,\n now: scope.meta.now,\n ctx: scope.bound.ctx,\n })\n if (plan === undefined) continue\n for (const [key, value] of Object.entries(plan.set ?? {})) {\n if (!(key in scope.entity.columns)) {\n throw new InternalError(\n `Plugin '${plugin.id}' sets '${key}' on '${scope.entity.name}', which is not a column`,\n { entity: scope.entity.name },\n )\n }\n set[key] = value\n }\n for (const rule of plan.rules ?? []) if (!rules.includes(rule)) rules.push(rule)\n addArgs(args, plan.args)\n }\n return { set, rules, args }\n}\n\nexport function createOptionKeys(bound: InternalBound): string[] {\n return [...pluginOptions(bound.runtime.plugins).create.keys()]\n}\n\nexport function updateOptionKeys(bound: InternalBound): string[] {\n return [...pluginOptions(bound.runtime.plugins).update.keys()]\n}\n\nexport async function create(\n entity: EntityMeta,\n bound: InternalBound,\n input: unknown,\n rawOptions: unknown,\n): Promise<AnyRow> {\n const data = assertData(input)\n assertScalars(entity, data)\n const options = assertOptions(rawOptions, [\n ...createOptionKeys(bound),\n ...writeOptionKeys(bound),\n ...referenceOptionKeys(entity, bound),\n ])\n const values = traitOptions(entity, bound.runtime.plugins, 'create', options)\n return runOperation(bound, entity, 'create', async (scope) => {\n await beforeOperation(scope, { data, options })\n await writeRule(scope, 'create', { data })\n const { allowed, partition } = partitionAllowance(scope, data)\n fieldWriteCheck(entity, scope.bound, scope.meta, data, allowed)\n\n let row = applyKindWrites(\n entity,\n null,\n data,\n writeStates(entity, bound.runtime.plugins, bound.ctx, options),\n )\n for (const [key, { value }] of partition) row[key] = value\n const plan = planCreate(scope, row, values)\n // A plan's rules are asked before anything is written, and the row is checked against them once it is.\n const checks: { rule: string; filter: Filter }[] = []\n for (const rule of plan.rules) {\n const filter = await writeRule(scope, rule, {})\n if (filter !== undefined) checks.push({ rule, filter })\n }\n Object.assign(row, plan.set)\n const change = plan.args.change\n row = await beforeValidate(scope, { op: 'create', data: row, original: null, args: change })\n row = applyDefaults(entity, row)\n row = await validateCreate(bound.runtime, entity, row)\n row = await beforeChange(scope, { op: 'create', data: row, original: null, args: change })\n await checkReferences(scope, row, new Set(Object.keys(row)), options)\n\n const inserted = (await scope.tx\n .insert(entity.table)\n .values(row as never)\n .returning()) as AnyRow[]\n const doc = inserted[0]\n if (doc === undefined) throw new InternalError(`${entity.name}: insert returned no row`)\n for (const { rule, filter } of checks) {\n const where = filterToSQL(\n bound.runtime.relations,\n entity.name,\n entity.table,\n andFilters([{ [entity.pk.key]: { eq: doc[entity.pk.key] } }, filter]),\n )\n if (Number(await scope.tx.$count(entity.table, where)) === 0) {\n throw forbidden(entity.name, rule, scope.meta, `access.${rule} denies this row`)\n }\n }\n const after = { ...change, ...plan.args.afterChange }\n await record(\n scope,\n {\n operation: 'create',\n step: 'create',\n row: doc,\n previous: null,\n written: true,\n options: values,\n },\n after,\n )\n await afterChange(scope, {\n op: 'create',\n doc,\n previous: null,\n changes: changedKeys(entity, null, doc),\n args: after,\n })\n await afterOperation(scope, doc)\n queueAfterCommit(scope, doc, null)\n return resultOf(scope, doc, options)\n })\n}\n\nexport async function update(\n entity: EntityMeta,\n bound: InternalBound,\n id: unknown,\n input: unknown,\n rawOptions: unknown,\n): Promise<AnyRow> {\n assertId(entity, id)\n const data = assertData(input)\n assertScalars(entity, data)\n const options = assertOptions(rawOptions, [\n ...updateOptionKeys(bound),\n ...writeOptionKeys(bound),\n ...referenceOptionKeys(entity, bound),\n ])\n const values = traitOptions(entity, bound.runtime.plugins, 'update', options)\n return runOperation(bound, entity, 'update', async (scope) => {\n await beforeOperation(scope, { id, data, options })\n const rule = await writeRule(scope, 'update', { data })\n const { allowed, partition } = partitionAllowance(scope, data)\n fieldWriteCheck(entity, scope.bound, scope.meta, data, allowed)\n const original = await lockRow(scope, id, [\n partitionFilter(partition),\n traitFilter(entity, scope.bound, scope.meta.operation, values, WRITING),\n rule,\n ])\n const result = await updateDocument(scope, original, data, {\n states: writeStates(entity, bound.runtime.plugins, bound.ctx, options),\n op: 'update',\n options: values,\n withDeleted: options.withDeleted === true,\n })\n await afterOperation(scope, result.doc)\n queueAfterCommit(scope, result.doc, original)\n return resultOf(scope, result.doc, options)\n })\n}\n\n// The delete options of every plugin in one object: what rules and hooks see as `options`.\nexport function mergedOptions(values: TraitOptionValues): AnyRow {\n return Object.assign({}, ...values.values())\n}\n\n// A plugin that keeps the row (soft delete) replaces the removal; the first one that returns a row wins.\nasync function keepRow(\n scope: OpScope,\n original: AnyRow,\n values: TraitOptionValues,\n): Promise<AnyRow | undefined> {\n const { entity, tx } = scope\n const pk = column(entity.table, entity.pk.key)\n for (const { plugin, trait, traits } of actingPlugins(scope)) {\n const keep = traits.remove\n if (keep === undefined) continue\n const kept = keep({\n entity,\n state: trait.state,\n options: values.get(plugin.id) ?? NO_VALUES,\n row: original,\n now: scope.meta.now,\n update: async (patch) => {\n const rows = (await tx\n .update(entity.table)\n .set(patch as never)\n .where(eq(pk, original[entity.pk.key]))\n .returning()) as AnyRow[]\n const row = rows[0]\n if (row === undefined) throw new InternalError(`${entity.name}: locked row vanished`)\n return row\n },\n })\n if (kept !== undefined) return kept\n }\n return undefined\n}\n\nexport async function deleteDocument(\n scope: OpScope,\n original: AnyRow,\n values: TraitOptionValues,\n): Promise<AnyRow> {\n const { entity, tx } = scope\n const options = mergedOptions(values)\n await beforeDelete(scope, original, options)\n const kept = await keepRow(scope, original, values)\n let doc: AnyRow\n if (kept !== undefined) {\n doc = kept\n } else {\n const pk = column(entity.table, entity.pk.key)\n const rows = (await tx\n .delete(entity.table)\n .where(eq(pk, original[entity.pk.key]))\n .returning()) as AnyRow[]\n const gone = rows[0]\n if (gone === undefined) throw new InternalError(`${entity.name}: locked row vanished`)\n doc = gone\n }\n const args = hookArgs(scope).afterDelete\n const removed = kept === undefined\n await record(\n scope,\n {\n operation: 'delete',\n step: 'delete',\n row: doc,\n previous: original,\n written: removed,\n options: values,\n },\n args,\n )\n const outcome: DeleteOutcome = { doc, previous: original, removed, options, args }\n await afterDelete(scope, outcome)\n return outcome.doc\n}\n\nexport function deleteOptionKeys(bound: InternalBound): string[] {\n return [...pluginOptions(bound.runtime.plugins).delete.keys()]\n}\n\nexport async function remove(\n entity: EntityMeta,\n bound: InternalBound,\n id: unknown,\n rawOptions: unknown,\n): Promise<AnyRow> {\n assertId(entity, id)\n const options = assertOptions(rawOptions, deleteOptionKeys(bound))\n const values = traitOptions(entity, bound.runtime.plugins, 'delete', options)\n return runOperation(bound, entity, 'delete', async (scope) => {\n await beforeOperation(scope, { id, options })\n const rule = await writeRule(scope, 'delete', { options: mergedOptions(values) })\n const original = await lockRow(scope, id, [\n pluginFilter(entity, scope.bound, scope.meta.operation, values, WRITING),\n rule,\n ])\n const doc = await deleteDocument(scope, original, values)\n await afterOperation(scope, doc)\n queueAfterCommit(scope, doc, original)\n return resultOf(scope, doc, {})\n })\n}\n","import { traitOperations, type ResolvedOperation } from '../../define/plugin.js'\nimport { BadRequestError, ForbiddenError, UnsupportedError } from '../../errors.js'\nimport type { EntityMeta } from '../../types/meta.js'\nimport type { PluginRuntime } from '../../types/plugin.js'\nimport type { AnyRow } from '../../types/runtime.js'\nimport type { OperationKit } from '../../types/traits.js'\nimport {\n evaluateRule,\n forbidden,\n NO_TRAIT_OPTIONS,\n partitionOf,\n pluginFilter,\n WRITING,\n} from '../access.js'\nimport { operationMeta } from '../context.js'\nimport { guard } from '../errors.js'\nimport { isPlainObject } from '../filters.js'\nimport type { InternalBound } from '../internals.js'\nimport { checkOptionType } from '../read/kinds.js'\nimport { assertId, lockRow, planUpdate, resultOf, updateCore, writeRule } from './mutations.js'\nimport { afterOperation, beforeOperation, queueAfterCommit, runOperation } from './pipeline.js'\n\n// The operations of the plugins that act on this entity.\nexport function entityOperations(\n entity: EntityMeta,\n plugins: readonly PluginRuntime[],\n): ResolvedOperation[] {\n return [...traitOperations(plugins).values()].filter(\n (op) => entity.traits[op.plugin.id] !== undefined,\n )\n}\n\nexport function entityOperation(\n entity: EntityMeta,\n plugins: readonly PluginRuntime[],\n name: string,\n): ResolvedOperation | null {\n const op = traitOperations(plugins).get(name)\n return op !== undefined && entity.traits[op.plugin.id] !== undefined ? op : null\n}\n\n// `list(id, { limit })` is `{ id, limit }`: the positional arguments by name, and the keys of a trailing\n// options argument.\nexport function operationInput(op: ResolvedOperation, args: readonly unknown[]): AnyRow {\n const input: AnyRow = {}\n op.spec.args.forEach((key, i) => {\n if (args[i] !== undefined) input[key] = args[i]\n })\n const trailing = args[op.spec.args.length]\n if (op.spec.options !== undefined && trailing !== undefined) {\n if (!isPlainObject(trailing)) throw new BadRequestError(`${op.name}: options must be an object`)\n for (const [key, value] of Object.entries(trailing)) {\n if (value !== undefined) input[key] = value\n }\n }\n return input\n}\n\n// The operations as methods of the entity API: a dotted name is a method of a nested object.\nexport function operationMethods(\n entity: EntityMeta,\n plugins: readonly PluginRuntime[],\n run: (op: ResolvedOperation, args: readonly unknown[]) => Promise<unknown>,\n): AnyRow {\n const out: AnyRow = {}\n for (const op of entityOperations(entity, plugins)) {\n const path = op.name.split('.')\n let node = out\n for (const part of path.slice(0, -1)) node = (node[part] ??= {}) as AnyRow\n node[path[path.length - 1] as string] = (...args: unknown[]) => run(op, args)\n }\n return out\n}\n\nfunction kit(\n entity: EntityMeta,\n bound: InternalBound,\n op: ResolvedOperation,\n input: AnyRow,\n): OperationKit {\n const name = op.name\n return {\n update: (id, patch, options) => {\n assertId(entity, id)\n return runOperation(bound, entity, name, async (scope) => {\n await beforeOperation(scope, input)\n const rule = options?.rule ?? 'update'\n // The rule sees what the caller wrote, which is nothing: the patch is the plugin's.\n const filter = await writeRule(scope, rule, rule === 'update' ? { data: {} } : {})\n const original = await lockRow(scope, id, [\n pluginFilter(entity, scope.bound, name, NO_TRAIT_OPTIONS, WRITING),\n filter,\n ])\n const given =\n typeof patch === 'function'\n ? await patch({\n row: original,\n tx: scope.tx,\n now: scope.meta.now,\n ctx: scope.bound.ctx,\n })\n : patch\n if (given === undefined) return resultOf(scope, original, {})\n const values =\n options?.options === undefined\n ? NO_TRAIT_OPTIONS\n : new Map([[op.plugin.id, options.options]])\n const plan = await planUpdate(scope, original, name, values)\n const result = await updateCore(scope, {\n original,\n patch: { ...given },\n op: name,\n plan,\n options: values,\n })\n await afterOperation(scope, result.doc)\n queueAfterCommit(scope, result.doc, original)\n return resultOf(scope, result.doc, {})\n })\n },\n read: async (fn, options) => {\n await bound.runtime.ready()\n return guard(bound.runtime, async () => {\n const meta = operationMeta(bound.ctx, entity.name, name, bound.runtime.now())\n const rule = options?.rule ?? 'read'\n const outcome = await evaluateRule(entity, rule, bound, meta)\n if (outcome.kind === 'deny') {\n throw forbidden(entity.name, rule, meta, `access.${rule} denies '${name}'`)\n }\n if (outcome.kind === 'filter') {\n throw new ForbiddenError(\n `Entity '${entity.name}': access.${rule} must allow '${name}' as a whole, not return a filter`,\n { entity: entity.name, operation: name, rule },\n )\n }\n const partition: AnyRow = {}\n for (const [key, { value }] of partitionOf(entity, bound, name)) partition[key] = value\n return fn({ executor: bound.$executor, partition, now: meta.now, ctx: bound.ctx })\n })\n },\n }\n}\n\nexport async function runEntityOperation(\n entity: EntityMeta,\n bound: InternalBound,\n name: string,\n input: unknown,\n): Promise<unknown> {\n const op = entityOperation(entity, bound.runtime.plugins, name)\n if (op === null) {\n throw new UnsupportedError(`Entity '${entity.name}' has no operation '${name}'`, {\n entity: entity.name,\n })\n }\n const given = input ?? {}\n if (!isPlainObject(given)) throw new BadRequestError(`${name}: the input must be an object`)\n const options = op.spec.options ?? {}\n for (const [key, value] of Object.entries(given)) {\n const type = options[key]\n if (type !== undefined) checkOptionType(key, type, value)\n else if (!op.spec.args.includes(key)) {\n throw new BadRequestError(`${name}: unknown input '${key}'`)\n }\n }\n const trait = entity.traits[op.plugin.id]\n return op.spec.run({\n entity,\n state: trait?.state,\n input: given,\n kit: kit(entity, bound, op, given),\n })\n}\n"],"mappings":";;;;;;AA0BA,MAAM,YAAY;AAClB,MAAM,iCAAsC,IAAI,IAAe,CAAC,gBAAgB,aAAa,CAAC;AAwG9F,SAAgB,oBAmBd,MAqCA;CACA,IAAI,OAAO,KAAK,OAAO,YAAY,CAAC,UAAU,KAAK,KAAK,EAAE,GACxD,MAAM,IAAI,YACR,kBAAkB,OAAO,KAAK,EAAE,EAAE,iFACpC;CAEF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,GACzD,IAAI,CAAC,GAAG,OAAO,OAAO,GACpB,MAAM,IAAI,YAAY,WAAW,KAAK,GAAG,YAAY,IAAI,mBAAmB;CAGhF,KAAK,MAAM,CAAC,SAAS,WAAW,OAAO,QAAS,KAAuB,iBAAiB,CAAC,CAAC,GAAG;EAC3F,IAAI,CAAC,eAAe,IAAI,OAAO,GAC7B,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,mBAAmB,QAAQ,wCAAwC,CAAC,GAAG,cAAc,CAAC,CAAC,KAAK,IAAI,EAAE,EACvH;EAEF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAC9C,IAAI,EAAE,QAAQ,KAAK,UAAU,CAAC,OAAO,CAAC,GAAG,OAAO,OAAO,GACrD,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,mBAAmB,QAAQ,GAAG,IAAI,kDACvD;CAGN;CAEA,OAAO;AACT;AAKA,SAAgB,aAmBd,MAuCA;CACA,IAAK,KAA8B,WAAW,KAAA,GAC5C,MAAM,IAAI,YACR,WAAW,OAAO,KAAK,EAAE,EAAE,oEAC7B;CAEF,OAAO,oBAAoB,IAAa;AAC1C;AAEA,SAAS,mBAAmB,MAAqB,YAA+C;CAC9F,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,YAAY,CAAC,CAAC,GAAG;EAC9D,MAAM,OAAO,WAAW;EACxB,IAAI,CAAC,GAAG,MAAM,OAAO,GACnB,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,sBAAsB,IAAI,0CAC/C;EAIF,IAAI,CAAC,GAAG,OAAO,OAAO,GAAG;EACzB,MAAM,cAAc,gBAAgB,IAAI;EACxC,KAAK,MAAM,UAAU,OAAO,KAAK,gBAAgB,KAAK,CAAC,GACrD,IAAI,EAAE,UAAU,cACd,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,qBAAqB,OAAO,cAAc,IAAI,kCACnE;CAGN;AACF;AAGA,SAAS,mBACP,MACA,QACA,WACM;CACN,KAAK,MAAM,UAAU,KAAK,aAAa,CAAC,GAAG;EACzC,IAAI,WAAW,KAAK,IAClB,MAAM,IAAI,YAAY,WAAW,KAAK,GAAG,0BAA0B;EAErE,IAAI,OAAO,IAAI,MAAM,GAAG;EACxB,MAAM,IAAI,YACR,UAAU,IAAI,MAAM,IAChB,WAAW,KAAK,GAAG,kBAAkB,OAAO,yBAC5C,WAAW,KAAK,GAAG,kBAAkB,OAAO,0BAClD;CACF;AACF;AAGA,SAAgB,kBAAkB,SAAyC;CACzE,MAAM,YAAY,IAAI,IAAI,QAAQ,KAAK,WAAW,OAAO,EAAE,CAAC;CAC5D,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,UAAU,SAAS;EAC5B,mBAAmB,QAAQ,QAAQ,SAAS;EAC5C,OAAO,IAAI,OAAO,EAAE;CACtB;AACF;AAEA,SAAS,gBAAgB,MAAiE;CACxF,IAAI,KAAK,aAAa,KAAA,GAAW,OAAO,CAAC;CACzC,MAAM,SAAS,KAAK,UAAU,CAAC;CAC/B,MAAM,UAAU,MAAc,YAAiD;EAC7E,IAAI,EAAE,QAAQ,SACZ,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,oBAAoB,KAAK,kCAC9C;EAEF,OAAO;GAAE;GAAM,SAAS,WAAW,CAAC;EAAE;CACxC;CACA,MAAM,WAAW,KAAK,SAAS,MAAe;CAC9C,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,QAAQ,GAC9C,IAAI,IAAI,SAAS,KACf,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,2BAA2B,IAAI,mBAAmB,IAAI,KAAK,EAChF;CAGJ,OAAO;AACT;AAEA,SAAgB,eACd,SACA,YACiB;CACjB,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,YAAY,IAAI,IAAI,QAAQ,KAAK,WAAW,OAAO,EAAE,CAAC;CAC5D,MAAM,gCAAgB,IAAI,IAAoB;CAC9C,MAAM,WAA4B,CAAC;CACnC,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,OAAsB;EAC5B,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG,MAAM,IAAI,YAAY,wBAAwB,KAAK,GAAG,EAAE;EAC/E,mBAAmB,MAAM,MAAM,SAAS;EACxC,KAAK,IAAI,KAAK,EAAE;EAChB,mBAAmB,MAAM,UAAU;EACnC,MAAM,SAAS,EAAE,GAAG,KAAK,OAAO;EAChC,KAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,KAAK,iBAAiB,CAAC,CAAC,GACvE,IAAI,UAAU,IAAI,OAAO,GAAG,OAAO,OAAO,QAAQ,QAAQ;EAE5D,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;GACrC,IAAI,OAAO,YACT,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,WAAW,IAAI,sCACpC;GAEF,MAAM,QAAQ,cAAc,IAAI,GAAG;GACnC,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,YACR,WAAW,KAAK,GAAG,WAAW,IAAI,qCAAqC,MAAM,EAC/E;GAEF,cAAc,IAAI,KAAK,KAAK,EAAE;EAChC;EACA,SAAS,KAAK;GACZ,IAAI,KAAK;GACT;GACA,aAAa,KAAK,eAAe;GACjC,QAAQ,KAAK,UAAU;GACvB;GACA,UAAU,gBAAgB,IAAI;GAC9B,OAAO,KAAK,SAAS;GACrB,QAAQ,KAAK,UAAU,CAAC;GACxB,QAAQ,KAAK,UAAU,CAAC;EAC1B,CAAC;CACH;CACA,cAAc,QAAQ;CACtB,gBAAgB,QAAQ;CACxB,WAAW,QAAQ;CACnB,OAAO;AACT;AAQA,MAAM,2BAAW,IAAI,IAAI;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,4BAAY,IAAI,QAA0E;AAIhG,SAAgB,gBACd,SACwC;CACxC,IAAI,aAAa,UAAU,IAAI,OAAO;CACtC,IAAI,eAAe,KAAA,GAAW,OAAO;CACrC,MAAM,sBAAM,IAAI,IAA+B;CAC/C,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,OAAO,QAAQ,cAAc,CAAC,CAAC,GAAG;EAC1E,MAAM,OAAO,KAAK,MAAM,GAAG;EAC3B,IAAI,KAAK,MAAM,SAAS,SAAS,EAAE,KAAK,SAAS,IAAI,KAAK,EAAY,GACpE,MAAM,IAAI,YAAY,WAAW,OAAO,GAAG,MAAM,KAAK,2BAA2B;EAEnF,MAAM,QAAQ,IAAI,IAAI,IAAI;EAC1B,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,YACR,cAAc,KAAK,6BAA6B,MAAM,OAAO,GAAG,gBAAgB,OAAO,GAAG,EAC5F;EAEF,KAAK,MAAM,SAAS,IAAI,KAAK,GAC3B,IAAI,MAAM,WAAW,GAAG,KAAK,EAAE,KAAK,KAAK,WAAW,GAAG,MAAM,EAAE,GAC7D,MAAM,IAAI,YACR,cAAc,KAAK,mBAAmB,MAAM,8CAC9C;EAGJ,IAAI,IAAI,MAAM;GAAE;GAAM;GAAQ;EAAK,CAAC;CACtC;CAEF,aAAa;CACb,UAAU,IAAI,SAAS,UAAU;CACjC,OAAO;AACT;AAQA,MAAa,6BAA4C,IAAI,IAAI;CAC/D,CAAC,QAAQ,QAAQ;CACjB,CAAC,UAAU,SAAS;CACpB,CAAC,UAAU,QAAQ;CACnB,CAAC,UAAU,QAAQ;AACrB,CAAC;AAED,MAAM,iCAAiB,IAAI,QAAqE;AAGhG,SAAgB,WAAW,SAAsE;CAC/F,IAAI,QAAQ,eAAe,IAAI,OAAO;CACtC,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,MAAM,sBAAM,IAAI,IAA0B;CAC1C,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,OAAO,QAAQ,SAAS,CAAC,CAAC,GAAG;EACrE,IAAI,WAAW,IAAI,IAAI,GACrB,MAAM,IAAI,YAAY,WAAW,OAAO,GAAG,WAAW,KAAK,yBAAyB;EAEtF,IAAI,SAAS,YAAY,SAAS,WAChC,MAAM,IAAI,YAAY,WAAW,OAAO,GAAG,WAAW,KAAK,gCAAgC;EAE7F,MAAM,QAAQ,IAAI,IAAI,IAAI;EAC1B,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,YACR,SAAS,KAAK,6BAA6B,MAAM,OAAO,gBAAgB,OAAO,GAAG,EACpF;EAEF,IAAI,IAAI,MAAM;GAAE;GAAM,QAAQ,OAAO;GAAI;EAAK,CAAC;CACjD;CAEF,QAAQ;CACR,eAAe,IAAI,SAAS,KAAK;CACjC,OAAO;AACT;AAEA,MAAM,iCAAiB,IAAI,QAAkE;AAI7F,SAAgB,cAAc,UAAoE;CAChG,IAAI,QAAQ,eAAe,IAAI,QAAQ;CACvC,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,wBAAQ,IAAI,IAAI;CAChB,KAAK,MAAM,WAAW,UACpB,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,QAAQ,aAAa,SAAS,CAAC,CAAC,GAAG;EACzE,MAAM,QAAQ,MAAM,IAAI,EAAE;EAC1B,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,YACR,gBAAgB,GAAG,+BAA+B,MAAM,OAAO,gBAAgB,QAAQ,GAAG,EAC5F;EAEF,MAAM,IAAI,IAAI;GAAE,GAAG;GAAM;GAAI,QAAQ,QAAQ;EAAG,CAAC;CACnD;CAEF,eAAe,IAAI,UAAU,KAAK;CAClC,OAAO;AACT;AAEA,SAAS,UAAU,OAA2C;CAC5D,OAAO,OAAQ,OAAqC,SAAS;AAC/D;AAIA,SAAgB,4BACd,UACA,QACA,eACM;CACN,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,SAAuC,QAAQ,KAAK,eAAe;EACzE,IAAI,WAAW,KAAA,GAAW;EAC1B,MAAM,SAAS,OAAO,YAAY,CAAC,SAAS,aAAa;EACzD,IAAI,UAAU,MAAM,GAClB,MAAM,IAAI,YACR,WAAW,QAAQ,GAAG,+DAA+D,OAAO,GAC9F;EAEF,IAAI,OAAO,WAAW,KAAA,KAAa,OAAO,OAAO,SAAS,GACxD,MAAM,IAAI,YACR,WAAW,OAAO,iCAAiC,QAAQ,GAAG,KAAK,OAAO,OACvE,KAAK,UAAU,MAAM,OAAO,CAAC,CAC7B,KAAK,IAAI,KACZ,UACA;GAAE;GAAQ,SAAS;IAAE,QAAQ,QAAQ;IAAI,QAAQ,OAAO;GAAO;EAAE,CACnE;CAEJ;AACF;;;ACpiBA,MAAa,YAA2B,OAAO,IAAI,iBAAiB;AAEpE,SAAgB,WAAqB;CACnC,OAAO;EAAE,MAAM;EAAM,QAAQ;EAAM,QAAQ;EAAM,QAAQ;GAAO,YAAY;CAAK;AACnF;AAEA,SAAgB,aAAwC,MAAS,SAA8B;CAC7F,OAAO;EAAE;EAAM,SAAU,WAAW,CAAC;CAAQ;AAC/C;AA2BA,MAAM,mCAAmB,IAAI,IAAY;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAcD,SAAS,KAAK,QAAgB,SAAwB;CACpD,MAAM,IAAI,YAAY,WAAW,OAAO,KAAK,WAAW,UAAU,EAAE,OAAO,CAAC;AAC9E;AAIA,SAAS,kBACP,QACA,OACA,SACA,UACQ;CAER,MAAM,aADS,eAAe,KACN,CAAC,CAAC,YAAY,SAAS,OAAO,GAAG,OAAO;CAChE,MAAM,cAAc,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO;CACvE,IAAI,WAAW,SAAS,YAAY,SAAS,KAAK,WAAW,SAAS,GACpE,KAAK,QAAQ,2EAA2E;CAE1F,MAAM,WAAW,YAAY,EAAE,GAAG,MAAM,WAAW;CACnD,IAAI,aAAa,KAAA,GAAW,KAAK,QAAQ,UAAU,aAAa,KAAK,EAAE,qBAAqB;CAC5F,MAAM,QAAQ,OAAO,QAAQ,OAAO,CAAC,CAAC,MAAM,GAAG,OAAO,MAAM,QAAQ,CAAC,GAAG;CACxE,IAAI,UAAU,UACZ,KACE,QACA,uBAAuB,MAAM,UAAU,SAAS,oBAAoB,MAAM,gBAC5E;CAEF,OAAO;AACT;AAEA,MAAM,aAAqC;CAAC;CAAQ;CAAU;CAAU;AAAQ;AAChF,MAAM,YAA+C,CAAC;AAGtD,SAAS,cACP,MACA,OACA,SACA,SACA,SACA,SAC4D;CAC5D,MAAM,SAAsC,CAAC;CAC7C,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,MAAM;EACnB,MAAM,SAAS,QAAQ,IAAI,OAAO,EAAE,KAAK;EACzC,MAAM,WACJ,KAAK,YAAY,KAAA,IACb,CAAC,IACD,KAAK,QAAQ;GAAE,QAAQ;GAAM;GAAO;GAAS;GAAS,SAAS;EAAO,CAAC;EAC7E,IAAI,aAAa,MAAM;GACrB,IAAI,WAAW,WACb,KAAK,MAAM,WAAW,OAAO,GAAG,+CAA+C;GAEjF;EACF;EACA,KAAK,MAAM,OAAO,SAAS,WAAW,CAAC,GAAG;GACxC,IAAI,EAAE,OAAO,UACX,KAAK,MAAM,WAAW,OAAO,GAAG,aAAa,IAAI,yBAAyB;GAC5E,IAAI,CAAC,QAAQ,SAAS,GAAG,GAAG,QAAQ,KAAK,GAAG;EAC9C;EACA,MAAM,MAAM,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC;EACxC,KAAK,MAAM,QAAQ,SAAS,SAAS,CAAC,GACpC,IAAI,CAAC,IAAI,SAAS,IAAI,GAAG,KAAK,MAAM,WAAW,OAAO,GAAG,iBAAiB,KAAK,EAAE;EAEnF,OAAO,OAAO,MAAM;GAClB,QAAQ,OAAO;GACf,OAAO,SAAS;GAChB,SAAS,SAAS,WAAW;GAC7B,OAAO,SAAS,SAAS;EAC3B;CACF;CACA,OAAO;EAAE;EAAQ;CAAQ;AAC3B;AAGA,SAAS,YACP,MACA,QACA,QACA,SACM;CACN,MAAM,QAAQ,WAAW,OAAO;CAChC,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EACrC,IAAI,WAAW,IAAI,GAAG,GAAG;EACzB,MAAM,OAAO,MAAM,IAAI,GAAG;EAC1B,IAAI,SAAS,KAAA,GAAW,KAAK,MAAM,UAAU,IAAI,eAAe;EAChE,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,MAAM,SAAS,GAAG,GAC1C,KACE,MACA,UAAU,IAAI,wBAAwB,KAAK,OAAO,yCACpD;CAEJ;AACF;AAEA,SAAS,aAAa,WAAyB,QAA8C;CAC3F,MAAM,MAAoC,CAAC;CAC3C,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,UAAU,OAAO,EAAE,aAAa,CAAC,CAAC,GACxE,IAAI,OAAO;EACT;EACA,QAAQ,IAAI;EACZ,MAAM,IAAI;EACV,UACE,IAAI,iBAAiB,QAAU,IAA+B,YAAY,OAAQ;EACpF,SAAS,IAAI,YAAY,KAAA;CAC3B;CAEF,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAoC;CAClE,MAAM,EAAE,MAAM,UAAU;CACxB,IAAI,OAAO,MAAM,YAAY,YAAY,MAAM,YAAY,MACzD,KAAK,MAAM,2BAA2B;CAExC,MAAM,UAAU,MAAM;CACtB,MAAM,UAAU,gBAAgB,KAAK;CACrC,MAAM,QAAQ,kBAAkB,MAAM,OAAO,SAAS,QAAQ,YAAY,IAAI;CAC9E,MAAM,EAAE,QAAQ,SAAS,gBAAgB,cACvC,MACA,OACA,SACA,SACA,MAAM,SACN,MAAM,OACR;CACA,MAAM,UAAU,IAAI,IAAI,WAAW;CACnC,MAAM,SAAS,QAAQ,UAAU,CAAC;CAClC,YAAY,MAAM,QAAQ,QAAQ,MAAM,OAAO;CAE/C,MAAM,SAAS,QAAQ,UAAU,CAAC;CAClC,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,IAAI,EAAE,OAAO,UAAU,KAAK,MAAM,UAAU,IAAI,wBAAwB;CAG1E,MAAM,QAAQ,cAAc,MAAM,OAAO;CACzC,MAAM,aAAyC,CAAC;CAChD,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,OAAO,GAAG;EACnD,MAAM,QAAQ,OAAO,QAAQ,CAAC;EAC9B,MAAM,OAAO,MAAM,SAAS,KAAA,IAAY,OAAO,MAAM;EAErD,MAAM,QACJ,MAAM,UAAU,KAAA,IACZ,MAAM,QACN,QAAQ,IAAI,GAAG,IACZ,WACA;EACT,WAAW,OAAO;GAChB;GACA,MAAM,OAAO;GACb;GACA,UAAU,OAAO;GACjB,YAAY,OAAO;GACnB,SAAS,OAAO;GAChB,YAAY,OAAO;GACnB,WAAW,OAAO,cAAc,KAAA,KAAa,OAAO,sBAAsB,KAAA;GAC1E,YAAY,OAAO;GACnB,MAAM,MAAM,QAAQ,eAAe,MAAM;GACzC,YAAY,MAAM,IAAI,eAAe,MAAM,KAAK,EAAE,KAAK;GACvD;GACA;EACF;CACF;CACA,MAAM,KAAK,WAAW;CACtB,IAAI,GAAG,SAAS,OAAO,KAAK,MAAM,oBAAoB,MAAM,mBAAmB;CAE/E,MAAM,eAAe,QAAQ,gBAAgB;CAC7C,IAAI,iBAAiB,MACd;OAAA,MAAM,OAAO,OAAO,KAAK,YAAY,GACxC,IAAI,EAAE,OAAO,UAAU,KAAK,MAAM,gBAAgB,IAAI,wBAAwB;CAAA;CAGlF,IACE,QAAQ,aAAa,KAAA,MACpB,CAAC,OAAO,UAAU,QAAQ,QAAQ,KAAK,QAAQ,WAAW,IAE3D,KAAK,MAAM,qCAAqC;CAGlD,MAAM,YAAY,aAAa,MAAM,WAAW,IAAI;CACpD,KAAK,MAAM,OAAO,QAAQ,SAAS,CAAC,GAClC,IAAI,UAAU,IAAI,EAAE,YAAY,MAC9B,KAAK,MAAM,WAAW,IAAI,iDAAiD;CAI/E,MAAM,gBAAyC,CAAC;CAChD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAC/C,IAAI,CAAC,iBAAiB,IAAI,GAAG,GAAG,cAAc,OAAO;CAEvD,4BAA4B,MAAM,SAAS,MAAM,aAAa;CAE9D,MAAM,SAAS,eAAe,KAAK;CACnC,OAAO;EACL;EACA;EACA,WAAW,OAAO;EAClB,UAAU,OAAO;EACjB;EACA,SAAS;EACT,aAAa,OAAO,KAAK,UAAU,CAAC,CAAC,QAAQ,MAAM,WAAW,EAAE,EAAE,SAAS,KAAK;EAChF,UAAU,OAAO,KAAK,UAAU,CAAC,CAAC,QAAQ,MAAM,WAAW,EAAE,EAAE,eAAe,IAAI;EAClF,iBAAiB,OAAO,KAAK,UAAU,CAAC,CAAC,QACtC,MAAM,OAAO,WAAW,EAAE,EAAE,SAAS,UACxC;EACA;EACA;EACA,OAAO,IAAI,IAAI,QAAQ,SAAS,CAAC,CAAC;EAClC;EACA;EACA,OAAO,QAAQ,SAAS,CAAC;EACzB,UAAU,QAAQ,YAAY;EAChB;EACd,UAAU,QAAQ,YAAY,MAAM;EACpC;EACA,OAAO,MAAM;CACf;AACF;;;AC9RA,IAAa,cAAb,MAAqD;CAGtB;CAF7B,QAA8C,CAAC;CAE/C,YAAY,SAAmD;EAAlC,KAAA,UAAA;CAAmC;CAEhE,IAAI,OAAe;EACjB,OAAO,KAAK,MAAM;CACpB;CAEA,KAAK,IAAoC;EACvC,KAAK,MAAM,KAAK,EAAE;CACpB;CAEA,OAAe;EACb,OAAO,KAAK,MAAM;CACpB;CAEA,SAAS,MAAoB;EAC3B,KAAK,MAAM,SAAS,KAAK,IAAI,KAAK,MAAM,QAAQ,IAAI;CACtD;CAEA,MAAM,QAAuB;EAC3B,MAAM,QAAQ,KAAK;EACnB,KAAK,QAAQ,CAAC;EACd,KAAK,MAAM,MAAM,OACf,IAAI;GACF,MAAM,GAAG;EACX,SAAS,OAAO;GACd,KAAK,QAAQ,KAAK;EACpB;CAEJ;CAEA,UAAgB;EACd,KAAK,QAAQ,CAAC;CAChB;AACF;AAeA,SAAgB,aAAa,OAAkC;CAC7D,MAAM,OAAO,MAAM;CACnB,MAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;CAClE,MAAM,WAAW,KAAK;CACtB,MAAM,OACJ,MAAM,SACL,OAAO,aAAa,YAAY,aAAa,OAAQ,WAAuC,CAAC;CAChG,OAAO;EACL,GAAG;EACH,MAAM,MAAM;EACZ,KAAK,MAAM;EAEX,WAAW,OAAO,WAAW;EAC7B,SAAS,MAAM;EACf;EACA,cAAc,MAAM;EACpB;CACF;AACF;AAEA,SAAgB,cACd,KACA,QACA,WACA,KACe;CACf,OAAO;EACL;EACA;EACA,MAAM,IAAI;EACV,WAAW,IAAI;EACf;EACA,cAAc,IAAI;CACpB;AACF;;;ACrFA,SAAgB,eAAe,SAAkB,OAAyB;CACxE,IAAI,cAAc,KAAK,KAAK,iBAAiB,0BAA0B,OAAO;CAC9E,IAAI,iBAAiB,gBAAgB,CAAE,MAA8B,OAC/D;MAAA,6DAA6D,KAAK,MAAM,OAAO,GACjF,OAAO,IAAI,gBAAgB,MAAM,SAAS,EAAE,OAAO,MAAM,CAAC;CAAA;CAG9D,MAAM,SAAS,QAAQ,QAAQ,SAAS,KAAK;CAC7C,OAAO,kBAAkB,gBAAgB,UAAU,SAAS,MAAM,IAAK,UAAU;AACnF;AAIA,SAAS,eAAe,QAAoB,YAA8B;CACxE,MAAM,UAAU,OAAO,QAAQ,gBAAgB,OAAO,KAAK,CAAC;CAC5D,MAAM,SAAS,SACb,QAAQ,MAAM,GAAG,YAAY,OAAO,SAAS,IAAI,CAAC,GAAG;CACvD,MAAM,QAAQ,UACZ,MAAM,IAAI,KAAK,CAAC,CAAC,QAAQ,QAAuB,QAAQ,KAAA,CAAS;CACnE,MAAM,SAAS,eAAe,OAAO,KAAK;CAC1C,MAAM,QAAQ,OAAO,QAAQ,MAAM,MAAM,EAAE,OAAO,SAAS,UAAU;CACrE,IAAI,UAAU,KAAA,GACZ,OAAO,KAAK,MAAM,OAAO,QAAQ,KAAK,MAAO,GAAqC,IAAI,CAAC;CAEzF,MAAM,SAAS,OAAO,kBAAkB,MAAM,MAAM,EAAE,QAAQ,MAAM,UAAU;CAC9E,IAAI,WAAW,KAAA,GAAW,OAAO,KAAK,OAAO,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC;CACvE,MAAM,UAAU,OAAO,YAAY,MAAM,MAAM,EAAE,QAAQ,MAAM,UAAU;CACzE,IAAI,YAAY,KAAA,GAAW,OAAO,KAAK,QAAQ,UAAU,CAAC,CAAC,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC;CAErF,MAAM,MAAM,QAAQ,MACjB,GAAG,YACF,OAAO,aACN,OAAO,eAAe,cACpB,OAAO,eAAe,KAAA,MACpB,eAAe,GAAG,OAAO,KAAK,GAAG,OAAO,KAAK,YAC5C,eAAe,GAAG,OAAO,KAAK,GAAG,OAAO,KAAK,OACvD;CACA,OAAO,QAAQ,KAAA,IAAY,CAAC,IAAI,CAAC,IAAI,EAAE;AACzC;AAIA,SAAS,UAAU,SAAkB,OAAqC;CACxE,IAAK,MAAM,SAAS,YAAY,MAAM,SAAS,iBAAkB,MAAM,eAAe,KAAA,GACpF,OAAO;CAET,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,SAAS,OAAO,OAAO,QAAQ,IAAI,QAAQ,CAAC,CAAC,MAAM,MAAM,EAAE,cAAc,KAAK;CACpF,IAAI,WAAW,KAAA,GAAW,OAAO;CAEjC,MAAM,UAAU,eAAe,QAAQ,MAAM,UAAU;CACvD,MAAM,UAAU,QAAQ,QAAQ,QAAQ,CAAC,OAAO,YAAY,SAAS,GAAG,CAAC;CACzE,MAAM,OAAO,QAAQ,SAAS,IAAI,UAAU;CAC5C,MAAM,OAAO,KAAK,WAAW,IAAI,IAAI,MAAM,WAAW,KAAK,KAAK,KAAK,IAAI;CACzE,MAAM,SAAS,MAAM,SAAS;CAC9B,OAAO,IAAI,cACT,SACI,WAAW,OAAO,KAAK,qBAAqB,KAAK,mBACjD,WAAW,OAAO,KAAK,gCAAgC,KAAK,IAChE,MAAM,MACN;EACE,QAAQ,OAAO;EACf,YAAY,MAAM;EAClB,SAAS;GAAE,UAAU,MAAM,SAAS;GAAU,YAAY,MAAM;EAAW;EAC3E,OAAO,MAAM;EACb,GAAI,KAAK,WAAW,IAChB,CAAC,IACD,EACE,QAAQ,CACN;GAAE,MAAM,CAAC,KAAK,EAAY;GAAG,SAAS,SAAS,mBAAmB;EAAgB,CACpF,EACF;CACN,CACF;AACF;AAEA,eAAsB,MAAS,SAAkB,IAAkC;CACjF,IAAI;EACF,OAAO,MAAM,GAAG;CAClB,SAAS,OAAO;EACd,MAAM,eAAe,SAAS,KAAK;CACrC;AACF;;;ACrFA,MAAa,eAAuB,EAAE,KAAK,GAAG,QAAQ;AAEtD,SAAgB,cAAc,OAAkD;CAC9E,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG,OAAO;CAChF,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AAEA,SAAgB,cAAc,QAAqC;CACjE,OAAO,WAAW,KAAA,KAAa,OAAO,OAAO,MAAM,CAAC,CAAC,OAAO,MAAM,MAAM,KAAA,CAAS;AACnF;AAEA,SAAgB,WAAW,OAA4D;CACrF,MAAM,UAAU,MAAM,QAAQ,MAAmB,CAAC,cAAc,CAAC,CAAC;CAClE,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;CACjC,IAAI,QAAQ,WAAW,GAAG,OAAO,QAAQ;CACzC,OAAO,EAAE,KAAK,QAAQ;AACxB;AAIA,SAAgB,kBAAkB,QAAoC;CACpE,OAAO;AACT;;;ACkBA,MAAM,mCAAmB,IAAI,QAAiD;AAG9E,SAAgB,cAAc,SAAkD;CAC9E,IAAI,UAAU,iBAAiB,IAAI,OAAO;CAC1C,IAAI,YAAY,KAAA,GAAW;EACzB,MAAM,uBAAO,IAAI,IAAwB;EACzC,MAAM,wBAAQ,IAAI,IAAwB;EAC1C,MAAM,yBAAS,IAAI,IAAwB;EAC3C,MAAM,yBAAS,IAAI,IAAwB;EAC3C,MAAM,sBAAM,IAAI,IAAwB;EACxC,KAAK,MAAM,UAAU,SAAS;GAC5B,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,OAAO,aAAa,eAAe,CAAC,CAAC,GAC5E,KAAK,IAAI,KAAK,IAAI;GAEpB,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,OAAO,aAAa,gBAAgB,CAAC,CAAC,GAC7E,MAAM,IAAI,KAAK,IAAI;GAErB,MAAM,SAAS,OAAO,QAAQ;GAC9B,KAAK,MAAM,CAAC,OAAO,WAAW;IAC5B,CAAC,QAAQ,IAAI;IACb,CAAC,UAAU,MAAM;IACjB,CAAC,UAAU,MAAM;IACjB,CAAC,UAAU,GAAG;GAChB,GACE,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,SAAS,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,IAAI;EAEzF;EACA,UAAU;GAAE;GAAM;GAAO;GAAQ;GAAQ,QAAQ;EAAI;EACrD,iBAAiB,IAAI,SAAS,OAAO;CACvC;CACA,OAAO;AACT;AAEA,SAAgB,gBAAgB,KAAa,MAAkB,OAAsB;CACnF,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,MAC1C,MAAM,IAAI,gBAAgB,GAAG,IAAI,aAAa,MAAM;AAExD;AAIA,SAAgB,aACd,QACA,SACA,OACA,OACmB;CACnB,MAAM,sBAAM,IAAI,IAAoB;CACpC,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,OAAO,OAAO,QAAQ,UAAU;EACtC,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,SAAiB,CAAC;EACxB,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,IAAI,GAAG;GAC9C,gBAAgB,KAAK,MAAM,MAAM,IAAI;GACrC,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,MAAM;EACpD;EACA,MAAM,QAAQ,OAAO,KAAK,MAAM;EAChC,IAAI,MAAM,WAAW,GAAG;EACxB,MAAM,QAAQ,OAAO,OAAO,OAAO;EACnC,IAAI,UAAU,KAAA,KAAa,CAAC,MAAM,QAAQ,SAAS,KAAK,GACtD,MAAM,IAAI,iBACR,WAAW,OAAO,KAAK,kBAAkB,MAAM,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,YAAY,OAAO,GAAG,uBACrG,EAAE,QAAQ,OAAO,KAAK,CACxB;EAEF,IAAI,IAAI,OAAO,IAAI,MAAM;CAC3B;CACA,OAAO;AACT;AAGA,SAAS,YAAY,QAAyC;CAC5D,MAAM,sBAAM,IAAI,IAAY;CAC5B,KAAK,MAAM,OAAO,OAAO,UAAU;EACjC,MAAM,OAAO,OAAO,QAAQ,IAAI,EAAE;EAClC,IAAI,SAAS,QAAQ,SAAS,KAAA,GAAW,IAAI,IAAI,KAAK,MAAM;CAC9D;CACA,OAAO;AACT;AAOA,SAAgB,YACd,QACA,SACA,KACA,OACiB;CACjB,MAAM,UAAU,YAAY,MAAM;CAClC,MAAM,yBAAS,IAAI,IAAqB;CACxC,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,KAAA,KAAa,SAAS,MAAM;EACzC,MAAM,UAAkB,CAAC;EACzB,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,gBAAgB,CAAC,CAAC,GAAG;GACjE,gBAAgB,KAAK,MAAM,MAAM,IAAI;GACrC,IAAI,MAAM,SAAS,KAAA,GAAW,QAAQ,OAAO,MAAM;EACrD;EACA,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE,GAAG;GAC3B,MAAM,QAAQ,OAAO,KAAK,OAAO;GACjC,IAAI,MAAM,SAAS,GACjB,MAAM,IAAI,iBACR,WAAW,OAAO,KAAK,kBAAkB,MAAM,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,iCAAiC,OAAO,GAAG,IAC1H,EAAE,QAAQ,OAAO,KAAK,CACxB;GAEF;EACF;EACA,IAAI,KAAK,UAAU,KAAA,GAAW,OAAO,IAAI,OAAO,IAAI,KAAK,MAAM;GAAE;GAAS;EAAI,CAAC,CAAC;CAClF;CACA,OAAO;AACT;AAEA,SAAgB,WACd,SACA,KACA,QACY;CACZ,MAAM,yBAAS,IAAI,IAAqB;CACxC,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,OAAO,OAAO;EACpB,IAAI,MAAM,SAAS,KAAA,GAAW;EAC9B,MAAM,UAAkB,CAAC;EACzB,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,eAAe,CAAC,CAAC,GAAG;GAChE,gBAAgB,KAAK,MAAM,OAAO,IAAI;GACtC,IAAI,OAAO,SAAS,KAAA,GAAW,QAAQ,OAAO,OAAO;EACvD;EACA,OAAO,IAAI,OAAO,IAAI,KAAK,KAAK;GAAE;GAAS;EAAI,CAAC,CAAC;CACnD;CACA,OAAO;AACT;AAIA,SAAgB,eACd,MACA,QACA,QACA,SACA,QACiB;CACjB,IAAI,MAAM,eAAe,KAAA,GAAW,OAAO,KAAA;CAC3C,OAAO,KAAK,WAAW;EAAE;EAAQ,OAAO,OAAO,IAAI,KAAK,MAAM;EAAG;EAAQ;CAAQ,CAAC;AACpF;AAIA,eAAsB,aACpB,OAKA,QACe;CACf,MAAM,yBAAS,IAAI,IAAuD;CAC1E,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,OAAO,OAAO,IAAI,KAAK,IAAI;EAC/B,IAAI,SAAS,KAAA,GAAW;GACtB,OAAO,CAAC;GACR,OAAO,IAAI,KAAK,MAAM,IAAI;EAC5B;EACA,KAAK,KAAK,IAAI;CAChB;CACA,KAAK,MAAM,CAAC,MAAM,SAAS,QAAQ;EACjC,MAAM,UAAU,KAAK;EACrB,IAAI,YAAY,KAAA,GAAW;EAC3B,MAAM,SAAS,MAAM,QACnB,KAAK,KAAK,EAAE,KAAK,UAAU,IAAI,IAAI,GACnC,OAAO,IAAI,KAAK,MAAM,CACxB;EACA,KAAK,SAAS,EAAE,KAAK,OAAO,MAAM;GAChC,IAAI,OAAO,OAAO;EACpB,CAAC;CACH;AACF;AAEA,SAAS,aAAa,KAAa,OAAgB;CACjD,IAAI,cAAc,KAAK,KAAK,MAAM,QAAQ,KAAK,GAC7C,MAAM,IAAI,gBACR,qBAAqB,IAAI,0DAC3B;AAEJ;AAEA,SAAS,QAAQ,KAAa,IAAY,OAA2B;CACnE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,gBAAgB,WAAW,IAAI,GAAG,GAAG,mBAAmB;CAC7F,KAAK,MAAM,QAAQ,OAAO,aAAa,KAAK,IAAI;CAChD,OAAO;AACT;AAEA,SAAS,UAAU,KAAa,IAAY,OAAwB;CAClE,IAAI,OAAO,UAAU,UAAU,MAAM,IAAI,gBAAgB,WAAW,IAAI,GAAG,GAAG,mBAAmB;CACjG,OAAO;AACT;AAIA,SAAgB,cAAc,MAAgC,KAAa,QAAsB;CAC/F,MAAM,SAAS,MAAgC;EAC7C,IAAI,CAAC,cAAc,CAAC,GAAG;GACrB,IAAI,MAAM,MACR,MAAM,IAAI,gBAAgB,WAAW,IAAI,wCAAwC;GACnF,aAAa,KAAK,CAAC;GACnB,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC;EACtB;EACA,MAAM,QAA6B,CAAC;EACpC,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,CAAC,GAAG;GAC3C,IAAI,UAAU,KAAA,GAAW;GACzB,QAAQ,IAAR;IACE,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,OAAO;KACV,aAAa,KAAK,KAAK;KACvB,MAAM,KAAK;MAAE;MAAI;MAAI;MAAI;MAAK;MAAI;KAAI,EAAE;KACxC,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,CAAC;KACjC;IACF;IACA,KAAK,MAAM;KACT,MAAM,QAAQ,QAAQ,KAAK,IAAI,KAAK;KACpC,MAAM,KAAK,MAAM,WAAW,IAAI,GAAG,UAAU,QAAQ,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;KAC3E;IACF;IACA,KAAK,SAAS;KACZ,MAAM,QAAQ,QAAQ,KAAK,IAAI,KAAK;KACpC,IAAI,MAAM,SAAS,GAAG,MAAM,KAAK,WAAW,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;KAClE;IACF;IACA,KAAK;KACH,MAAM,KAAK,KAAK,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;KACtD;IACF,KAAK;KACH,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;KACvD;IACF,KAAK;KACH,MAAM,KAAK,QAAQ,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;KACzD;IACF,KAAK;KACH,MAAM,KAAK,SAAS,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;KAC1D;IACF,KAAK;KACH,IAAI,UAAU,MAAM,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC;KACjD;IACF,KAAK;KACH,IAAI,UAAU,MAAM,MAAM,KAAK,UAAU,KAAK,IAAI,CAAC,CAAC;KACpD;IACF,KAAK,OAAO;KACV,MAAM,QAAQ,MAAM,KAAK;KACzB,IAAI,UAAU,KAAA,GAAW,MAAM,KAAK,IAAI,KAAK,CAAC;KAC9C;IACF;IACA,KAAK;IACL,KAAK,OAAO;KACV,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,gBAAgB,WAAW,IAAI,GAAG,GAAG,mBAAmB;KACpE,MAAM,QAAQ,MAAM,IAAI,KAAK;KAC7B,MAAM,KAAK,OAAO,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,CAAC;KACrD;IACF;IACA,SACE,MAAM,IAAI,gBAAgB,4BAA4B,GAAG,QAAQ,IAAI,EAAE;GAC3E;EACF;EACA,OAAO,IAAI,GAAG,KAAK;CACrB;CACA,OAAO,MAAM,MAAM,KAAK,GAAG;AAC7B;;;AC3SA,MAAM,QAAqB,EAAE,MAAM,QAAQ;AAC3C,MAAM,OAAoB,EAAE,MAAM,OAAO;AAEzC,SAAgB,UAAU,QAAgB,MAAgB,MAAqB,KAAa;CAC1F,OAAO,IAAI,eAAe,WAAW,OAAO,KAAK,OAAO;EACtD;EACA,WAAW,KAAK;EAChB;CACF,CAAC;AACH;AAEA,SAAS,SAAS,QAAoB,MAAgB,OAAgC;CACpF,MAAM,OAAO,WAAW,IAAI,IAAI;CAChC,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,MAAM,WAAW,WAAW,MAAM,QAAQ,OAAO,CAAC,CAAC,IAAI,IAAI;CAC3D,IAAI,aAAa,KAAA,KAAa,CAAC,OAAO,OAAO,SAAS,OAAO,EAAE,MAAM,SAAS,IAAI,GAChF,MAAM,IAAI,cAAc,WAAW,OAAO,KAAK,iBAAiB,KAAK,IAAI,EACvE,QAAQ,OAAO,KACjB,CAAC;CAEH,OAAO,SAAS;AAClB;AAEA,eAAsB,aACpB,QACA,MACA,OACA,MACA,QAAiC,CAAC,GACZ;CACtB,MAAM,OAAO,SAAS,QAAQ,MAAM,KAAK;CACzC,IAAI,MAAM,UAAU,UAAU,OAAO;CACrC,MAAM,SAAS,OAAO;CACtB,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,KAAA,GAAW;EACvB,IAAI,OAAO,eAAe,MAAM,OAAO;EACvC,MAAM,UACJ,OAAO,MACP,MACA,MACA,aAAa,KAAK,aAAa,KAAK,UAAU,iEAChD;CACF;CACA,MAAM,SACJ,OAAO,UAAU,aACb,MAAM,MAAM;EACV,KAAK,MAAM;EACX;EACA,QAAQ,MAAM,WAAW,UAAU,KAAK,OAAO,OAAO,KAAK,EAAE;EAC7D,GAAG;CACL,CAAC,IACD;CACN,IAAI,WAAW,MAAM,OAAO;CAC5B,IAAI,WAAW,OAAO,OAAO;CAC7B,IAAI,cAAc,MAAM,KAAK,SAAS,UAAU;EAC9C,MAAM,SAAS,WAAW,MAAM,QAAQ,SAAS,MAAM,KAAK,CAAC,CAAC;EAC9D,OAAO;GACL,MAAM;GACN,QAAQ,WAAW,OAAO,KAAK,WAAW,OAAO,MAAM,QAAQ,MAAM;EACvE;CACF;CACA,MAAM,IAAI,cACR,WAAW,OAAO,KAAK,YAAY,KAAK,wBAAwB,SAAS,WAAW,wBAAwB,MAC5G,EAAE,QAAQ,OAAO,KAAK,CACxB;AACF;AAOA,SAAgB,WACd,OACA,WACA,UACA,QACA,QACQ;CACR,MAAM,UAAU,MAAM;CACtB,MAAM,SAAS,QAAQ,aAAa,QAAQ;CAC5C,MAAM,YAAY,QAAQ,UAAU,SAAS,EAAE,aAAa,CAAC;CAC7D,MAAM,QAAgB,CAAC;CACvB,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;EACjD,IAAI,UAAU,KAAA,GAAW;EACzB,KAAK,QAAQ,SAAS,QAAQ,SAAS,MAAM,QAAQ,KAAK,GAAG;GAC3D,MAAM,OAAO,MAAM,KAAK,SACtB,cAAc,IAAI,IAAI,WAAW,OAAO,WAAW,UAAU,MAAM,MAAM,IAAI,IAC/E;GACA;EACF;EACA,IAAI,QAAQ,SAAS,cAAc,KAAK,GAAG;GACzC,MAAM,MAAM,WAAW,OAAO,WAAW,UAAU,OAAO,MAAM;GAChE;EACF;EACA,MAAM,WAAW,UAAU;EAC3B,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,SAAS,QAAQ,aAAa,SAAS,eAAe;GAC5D,MAAM,OACJ,WAAW,OACP,KAAA,IACA,aAAa,QAAQ,OAAO,WAAW,kBAAkB,OAAO;GACtE,IAAI,cAAc,KAAK,GAAG;IAExB,MAAM,OAAO,WAAW,CAAC,MADX,WAAW,OAAO,WAAW,SAAS,iBAAiB,OAAO,MAC7C,CAAK,CAAC,KAAK,CAAC;IAC3C;GACF;GACA,IAAI,UAAU,MAAM;IAClB,MAAM,OAAO,QAAQ;IACrB;GACF;GACA,IAAI,UAAU,OAAO;IACnB,IAAI,SAAS,KAAA,GAAW,MAAM,OAAO;SAChC,MAAM,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;IACxC;GACF;EACF;EACA,MAAM,OAAO,QAAQ,QAAQ,IAAI,EAAE;EACnC,IAAI,MAAM,eAAe,KAAA,GAAW;GAClC,MAAM,OAAO;GACb;EACF;EACA,MAAM,KAAK,EACT,MAAM,MACJ,eACG,WAAW,eAAe,MAAM,EAAE,MAAa,QAAQ,QAAQ,SAAS,MAAM,GAC/E,KACA,KACF,EACJ,CAAC;CACH;CACA,OAAO,MAAM,WAAW,IAAI,QAAQ,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,EAAE;AAC/D;AAKA,MAAM,gCAA2B,IAAI,IAAI;AAEzC,SAAgB,YACd,QACA,OACA,WACW;CACX,IAAI;CACJ,KAAK,MAAM,UAAU,MAAM,QAAQ,SAAS;EAC1C,MAAM,YAAY,OAAO,QAAQ;EACjC,MAAM,QAAQ,OAAO,OAAO,OAAO;EACnC,IAAI,cAAc,KAAA,KAAa,UAAU,KAAA,GAAW;EACpD,MAAM,SAAS,UAAU;GAAE;GAAQ,OAAO,MAAM;GAAO;GAAW,KAAK,MAAM;EAAI,CAAC;EAClF,IAAI,WAAW,KAAA,GAAW;EAC1B,KAAK,MAAM,CAAC,QAAQ,UAAU,OAAO,QAAQ,MAAM,GAAG;GACpD,IAAI,EAAE,UAAU,OAAO,UACrB,MAAM,IAAI,cACR,WAAW,OAAO,GAAG,gBAAgB,OAAO,KAAK,QAAQ,OAAO,2BAChE,EAAE,QAAQ,OAAO,KAAK,CACxB;GAEF,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC9B,MAAM,IAAI,eACR,WAAW,OAAO,KAAK,uBAAuB,OAAO,sCACrD;IAAE,QAAQ,OAAO;IAAM;IAAW,MAAM,aAAa,OAAO;GAAK,CACnE;GAEF,wBAAQ,IAAI,IAAI;GAChB,IAAI,IAAI,QAAQ;IAAE;IAAO,QAAQ,OAAO;GAAG,CAAC;EAC9C;CACF;CACA,OAAO,OAAO;AAChB;AAEA,SAAgB,gBAAgB,WAA0C;CACxE,IAAI,UAAU,SAAS,GAAG,OAAO,KAAA;CACjC,MAAM,SAAiB,CAAC;CACxB,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,WAAW,OAAO,UAAU,EAAE,IAAI,MAAM;CAC1E,OAAO;AACT;AAMA,MAAa,UAAqB,EAAE,SAAS,MAAM;AACnD,MAAa,UAAqB,EAAE,SAAS,KAAK;AAGlD,SAAgB,aACd,QACA,OACA,WACA,SACA,KACoB;CACpB,OAAO,WAAW,CAChB,gBAAgB,YAAY,QAAQ,OAAO,SAAS,CAAC,GACrD,YAAY,QAAQ,OAAO,WAAW,SAAS,GAAG,CACpD,CAAC;AACH;AAKA,MAAa,mCAAsC,IAAI,IAAI;AAC3D,MAAM,aAAgD,CAAC;AAIvD,SAAgB,YACd,QACA,OACA,WACA,SACA,KACoB;CACpB,MAAM,QAAgC,CAAC;CACvC,KAAK,MAAM,UAAU,MAAM,QAAQ,SAAS;EAC1C,MAAM,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,OAAO,OAAO,OAAO;EACnC,IAAI,WAAW,KAAA,KAAa,UAAU,KAAA,KAAa,OAAO,OAAO,IAAI,MAAM;EAC3E,MAAM,KACJ,OAAO;GACL;GACA,OAAO,MAAM;GACb;GACA,SAAS,IAAI;GACb,SAAS,QAAQ,IAAI,OAAO,EAAE,KAAK;GACnC,KAAK,MAAM;EACb,CAAC,CACH;CACF;CACA,OAAO,WAAW,KAAK;AACzB;AAEA,SAAgB,YACd,WACA,UACA,OACA,QACiB;CACjB,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;CACjC,MAAM,iBAAiB,UAAU,SAAS,EAAE,aAAa,CAAC;CAC1D,OAAO,qBAAqB,OAAO,kBAAkB,MAAM,GAAG,gBAAgB,SAAS;AACzF;AAEA,SAAgB,gBACd,QACA,OACA,MACU;CACV,IAAI,MAAM,UAAU,UAAU,OAAO,CAAC;CACtC,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,OAAO,OAAO,iBAAiB;EACxC,MAAM,OAAQ,OAAO,QAAQ,IAAI,CAAgB;EACjD,IAAI,OAAO,SAAS,cAAc,CAAC,KAAK;GAAE,KAAK,MAAM;GAAK;EAAK,CAAC,GAAG,OAAO,KAAK,GAAG;CACpF;CACA,OAAO;AACT;AAGA,SAAgB,gBACd,QACA,OACA,MACA,MACA,0BAA+B,IAAI,IAAI,GACjC;CACN,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAAG;EACnC,IAAI,KAAK,SAAS,KAAA,KAAa,QAAQ,IAAI,GAAG,GAAG;EACjD,MAAM,SAAS,OAAO,QAAQ;EAC9B,IAAI,WAAW,KAAA,GAAW;EAC1B,MAAM,QAAQ,OAAO;EAKrB,IAHE,UAAU,SACT,UAAU,YAAY,MAAM,UAAU,UACtC,OAAO,UAAU,cAAc,MAAM,UAAU,UAAU,CAAC,MAAM;GAAE,KAAK,MAAM;GAAK;EAAK,CAAC,GAEzF,MAAM,IAAI,eAAe,WAAW,OAAO,KAAK,aAAa,IAAI,yBAAyB;GACxF,QAAQ,OAAO;GACf,WAAW,KAAK;GAChB,MAAM,UAAU,IAAI;EACtB,CAAC;CAEL;AACF;;;AChTA,SAAgB,UAAU,GAAY,GAAqB;CACzD,IAAI,OAAO,GAAG,GAAG,CAAC,GAAG,OAAO;CAC5B,IAAI,aAAa,QAAQ,aAAa,MACpC,OAAO,aAAa,QAAQ,aAAa,QAAQ,EAAE,QAAQ,MAAM,EAAE,QAAQ;CAE7E,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM,OAAO;CACvF,IAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,GAAG,OAAO;CAClD,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GACrC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,MAAM,MAAM,UAAU,MAAM,EAAE,EAAE,CAAC;CAE5E,MAAM,OAAO;CACb,MAAM,QAAQ;CACd,MAAM,uBAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,IAAI,GAAG,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC;CAClE,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,UAAU,KAAK,MAAM,MAAM,IAAI,GAAG,OAAO;CAEhD,OAAO;AACT;;;ACIA,eAAsB,aACpB,OACA,QACA,WACA,IACY;CACZ,MAAM,EAAE,YAAY;CACpB,MAAM,QAAQ,MAAM;CACpB,MAAM,OAAO,cAAc,MAAM,KAAK,OAAO,MAAM,WAAW,QAAQ,IAAI,CAAC;CAC3E,MAAM,sBAAM,IAAI,IAAqB;CACrC,IAAI;EACF,IAAI,MAAM,QAAQ,QAAQ,MAAM,UAAU,MAAM;GAC9C,MAAM,QAAQ,MAAM;GACpB,MAAM,OAAO,MAAM,KAAK;GACxB,IAAI;IACF,OAAO,MAAM,MAAM,IAAI,aAAa,OAClC,GAAG;KAAE,OAAO,MAAM,OAAO,IAAI,KAAK;KAAG;KAAI;KAAM;KAAK;KAAO;IAAO,CAAC,CACrE;GACF,SAAS,OAAO;IACd,MAAM,SAAS,IAAI;IACnB,MAAM;GACR;EACF;EACA,MAAM,QAAQ,IAAI,aAAa,UAC7B,QAAQ,iBAAiB,OAAO;GAC9B,QAAQ,OAAO;GACf;GACA,WAAW,MAAM,IAAI;EACvB,CAAC,CACH;EACA,IAAI;EACJ,IAAI;GACF,SAAS,MAAM,MAAM,UAAU,aAAa,OAC1C,GAAG;IAAE,OAAO,MAAM,OAAO,IAAI,KAAK;IAAG;IAAI;IAAM;IAAK;IAAO;GAAO,CAAC,CACrE;EACF,SAAS,OAAO;GACd,MAAM,QAAQ;GACd,MAAM;EACR;EACA,MAAM,MAAM,MAAM;EAClB,OAAO;CACT,SAAS,OAAO;EACd,MAAM,eAAe,SAAS,KAAK;CACrC;AACF;AAEA,SAAgB,SAAS,OAAgB;CACvC,OAAO;EACL,KAAK,MAAM,MAAM;EACjB,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,IAAI,MAAM;EACV,KAAK,MAAM;CACb;AACF;AAEA,SAAS,WAAW,OAAgB;CAClC,OAAO;EAAE,GAAG,SAAS,KAAK;EAAG,YAAY,MAAM;CAAO;AACxD;AAEA,SAAgB,YAAY,OAA+B;CACzD,MAAM,MAAqB,CAAC;CAC5B,KAAK,MAAM,UAAU,MAAM,MAAM,QAAQ,SAAS;EAChD,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,MAAM;EACpB,IAAI,MAAM,aAAa,KAAA,KAAa,CAAC,MAAM,SAAS,SAAS,MAAM,OAAO,IAAI,GAAG;EACjF,IAAI,KAAK,KAAK;CAChB;CACA,OAAO;AACT;AAEA,eAAsB,gBAAgB,OAAgB,MAA8B;CAClF,KAAK,MAAM,SAAS,YAAY,KAAK,GACnC,MAAM,MAAM,kBAAkB;EAC5B,QAAQ,MAAM,OAAO;EACrB,IAAI,MAAM,KAAK;EACf;EACA,GAAG,WAAW,KAAK;CACrB,CAAU;AAEd;AAEA,eAAsB,eAAe,OAAgB,QAAgC;CACnF,KAAK,MAAM,SAAS,YAAY,KAAK,GACnC,MAAM,MAAM,iBAAiB;EAC3B,QAAQ,MAAM,OAAO;EACrB,IAAI,MAAM,KAAK;EACf;EACA,GAAG,WAAW,KAAK;CACrB,CAAU;AAEd;AAEA,eAAsB,UACpB,OACA,SACe;CACf,KAAK,MAAM,SAAS,YAAY,KAAK,GACnC,MAAM,MAAM,YAAY;EACtB,QAAQ,MAAM,OAAO;EACrB,GAAG;EACH,GAAG,WAAW,KAAK;CACrB,CAAU;AAEd;AAUA,MAAM,gCAAgB,IAAI,QAA4C;AAEtE,SAAgB,gBAAgB,SAA6C;CAC3E,IAAI,OAAO,cAAc,IAAI,OAAO;CACpC,IAAI,SAAS,KAAA,GAAW;EACtB,MAAM,MAAM;GAAE,QAAQ,CAAC;GAAG,aAAa,CAAC;GAAG,aAAa,CAAC;EAAE;EAC3D,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,WAAW,OAAO,QAAQ;GAChC,OAAO,OAAO,IAAI,QAAQ,UAAU,MAAM;GAC1C,OAAO,OAAO,IAAI,aAAa,UAAU,WAAW;GACpD,OAAO,OAAO,IAAI,aAAa,UAAU,WAAW;EACtD;EACA,OAAO;EACP,cAAc,IAAI,SAAS,IAAI;CACjC;CACA,OAAO;AACT;AAUA,eAAe,iBACb,OACA,MACA,OACiB;CACjB,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,IAAI,SAAS,KAAA,GAAW,OAAO,MAAM;CACrC,MAAM,EAAE,MAAM,GAAG,SAAS;CAE1B,OAAQ,MADe,KAAK;EAAE,GAAG;EAAM,GAAG;EAAM,GAAG,SAAS,KAAK;CAAE,CAAC,KACzB,MAAM;AACnD;AAEA,SAAgB,eAAe,OAAgB,OAAqC;CAClF,OAAO,iBAAiB,OAAO,kBAAkB,KAAK;AACxD;AAEA,eAAsB,aAAa,OAAgB,OAAqC;CACtF,IAAI,OAAO,MAAM,iBAAiB,OAAO,gBAAgB,KAAK;CAC9D,MAAM,EAAE,MAAM,GAAG,SAAS;CAC1B,KAAK,MAAM,SAAS,YAAY,KAAK,GAAG;EACtC,IAAI,MAAM,iBAAiB,KAAA,GAAW;EAQtC,OAAQ,MAPe,MAAM,aAAa;GACxC,GAAG;GACH,QAAQ,MAAM,OAAO;GACrB,GAAG;GACH;GACA,GAAG,WAAW,KAAK;EACrB,CAAU,KACiC;CAC7C;CACA,OAAO;AACT;AAUA,eAAsB,YAAY,OAAgB,SAAuC;CACvF,MAAM,EAAE,MAAM,GAAG,SAAS;CAC1B,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,MAAM,OAAO;EAAE,GAAG;EAAM,GAAG;EAAM,GAAG,SAAS,KAAK;CAAE,CAAC;CACrD,KAAK,MAAM,SAAS,YAAY,KAAK,GACnC,MAAM,MAAM,cAAc;EACxB,GAAG;EACH,QAAQ,MAAM,OAAO;EACrB,GAAG;EACH,GAAG,WAAW,KAAK;CACrB,CAAU;AAEd;AAEA,eAAsB,aAAa,OAAgB,KAAa,SAAgC;CAC9F,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,MAAM,OAAO;EAAE;EAAK;EAAS,GAAG,SAAS,KAAK;CAAE,CAAC;AACnD;AAUA,eAAsB,YAAY,OAAgB,SAAuC;CACvF,MAAM,EAAE,KAAK,UAAU,SAAS,SAAS,SAAS;CAClD,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,MAAM,OAAO;EAAE,GAAG;EAAM;EAAK;EAAS,GAAG,SAAS,KAAK;CAAE,CAAC;CAC1D,KAAK,MAAM,SAAS,YAAY,KAAK,GACnC,MAAM,MAAM,cAAc;EACxB,GAAG;EACH,QAAQ,MAAM,OAAO;EACrB;EACA;EACA;EACA;EACA,GAAG,WAAW,KAAK;CACrB,CAAU;AAEd;AAEA,SAAgB,iBAAiB,OAAgB,KAAoB,UAAyB;CAC5F,MAAM,EAAE,QAAQ,MAAM,UAAU;CAChC,MAAM,MAAM,MAAM,MAAM;CACxB,MAAM,OAAO,OAAO,MAAM;CAC1B,IAAI,SAAS,KAAA,GACX,MAAM,WAAW,KAAK;EAAE,IAAI,KAAK;EAAW;EAAK;EAAU;EAAK;CAAK,CAAC,CAAS;CAEjF,KAAK,MAAM,SAAS,YAAY,KAAK,GAAG;EACtC,MAAM,SAAS,MAAM;EACrB,IAAI,WAAW,KAAA,GAAW;EAC1B,MAAM,WAAW,OAAO;GAAE,QAAQ,OAAO;GAAM,IAAI,KAAK;GAAW;GAAK;GAAU;GAAK;EAAK,CAAC,CAAC;CAChG;AACF;;;AChPA,SAAS,cAAc,QAAoB,KAA4B;CACrE,OAAO,OAAO,QAAQ,IAAI,EAAE;AAC9B;AAEA,SAAgB,kBAAkB,QAAoB,KAAsB;CAC1E,MAAM,SAAS,cAAc,QAAQ,GAAG;CACxC,OAAO,OAAO,WAAW,SAAS,YAAY,OAAO,mBAAmB,SAAS;AACnF;AAMA,SAAgB,WAAW,MAAe,OAAO,QAAgB;CAC/D,IAAI,CAAC,cAAc,IAAI,GAAG,MAAM,IAAI,gBAAgB,GAAG,KAAK,mBAAmB;CAC/E,OAAO;AACT;AAKA,SAAgB,cAAc,QAAoB,MAAoB;CACpE,MAAM,SAAgD,CAAC;CACvD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;EAC/C,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK,GAAG;EACpD,MAAM,SAAS,OAAO,QAAQ;EAC9B,IAAI,WAAW,KAAA,KAAa,OAAO,eAAe,MAAM;EACxD,MAAM,OAAO,OAAO,SAAS,MAAM,GAAG,CAAC,CAAC;EACxC,IAAI,SAAS,YAAY,SAAS,YAAY,SAAS,aAAa,SAAS,UAC3E,OAAO,KAAK;GACV,MAAM,CAAC,GAAG;GACV,SAAS,cAAc,KAAK,QAAQ,MAAM,QAAQ,KAAK,IAAI,aAAa;EAC1E,CAAC;CAEL;CACA,IAAI,OAAO,SAAS,GAClB,MAAM,IAAI,gBAAgB,WAAW,OAAO,KAAK,kBAAkB,QAAQ,EACzE,QAAQ,OAAO,KACjB,CAAC;AAEL;AAIA,SAAgB,cAAc,QAAoB,MAAsB;CACtE,MAAM,MAAM,EAAE,GAAG,KAAK;CACtB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,OAAO,GAAG;EAC7C,IAAI,IAAI,SAAS,KAAA,GAAW;EAC5B,MAAM,SAAS,cAAc,QAAQ,GAAG;EACxC,IAAI,OAAO,OAAO,cAAc,YAAY,IAAI,OAAO,OAAO,UAAU;OACnE,IAAI,OAAO,YAAY,KAAA,KAAa,CAAC,GAAG,OAAO,SAAS,GAAG,GAC9D,IAAI,OACF,OAAO,OAAO,YAAY,WAAW,gBAAgB,OAAO,OAAO,IAAI,OAAO;CAEpF;CACA,OAAO;AACT;AAKA,SAAgB,gBACd,QACA,MACA,MACA,QACQ;CACR,MAAM,MAAM,EAAE,GAAG,KAAK;CACtB,IAAI,WAAW,MAAM,OAAO;CAC5B,KAAK,MAAM,OAAO,OAAO,UAAU;EACjC,MAAM,OAAO,OAAO,QAAQ,IAAI,EAAE;EAClC,IAAI,MAAM,UAAU,KAAA,KAAa,KAAK,SAAS,KAAA,GAAW;EAC1D,IAAI,OAAO,KAAK,MAAM;GAAE,OAAO,KAAK;GAAM,QAAQ,OAAO;GAAM,OAAO,OAAO,IAAI,KAAK,MAAM;EAAE,CAAC;CACjG;CACA,OAAO;AACT;AAEA,eAAe,UAAU,QAA0B,OAAgB,QAAoB;CACrF,MAAM,SAAS,MAAM,OAAO,YAAY,CAAC,SAAS,KAAK;CACvD,IAAI,OAAO,WAAW,KAAA,GAAW;EAC/B,MAAM,SAAS,gBAAgB,OAAO,MAAM;EAC5C,MAAM,UAAU,OACb,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC,KAAK,GAAG,KAAK,SAAS,IAAI,EAAE,SAAS,CAAC,CACvE,KAAK,IAAI;EACZ,MAAM,IAAI,gBAAgB,WAAW,OAAO,KAAK,IAAI,WAAW,QAAQ,EAAE,QAAQ,OAAO,KAAK,CAAC;CACjG;CACA,OAAO,OAAO;AAChB;AAEA,SAAS,WAAW,QAAoB,KAAqB;CAC3D,MAAM,MAAc,CAAC;CACrB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,OAAO,GAC1C,IAAI,IAAI,SAAS,KAAA,KAAa,CAAC,kBAAkB,QAAQ,GAAG,GAAG,IAAI,OAAO,IAAI;CAEhF,OAAO;AACT;AAEA,eAAsB,eAAe,SAAkB,QAAoB,MAAc;CACvF,MAAM,UAAU,OAAO,KAAK,IAAI,CAAC,CAAC,QAAQ,MAAM,KAAK,OAAO,KAAA,KAAa,EAAE,KAAK,OAAO,QAAQ;CAC/F,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,gBACR,WAAW,OAAO,KAAK,eAAe,QAAQ,SAAS,IAAI,MAAM,GAAG,GAAG,QAAQ,KAAK,IAAI,KACxF,QAAQ,KAAK,OAAO;EAAE,MAAM,CAAC,CAAC;EAAG,SAAS,gBAAgB,EAAE;CAAG,EAAE,GACjE,EAAE,QAAQ,OAAO,KAAK,CACxB;CAEF,MAAM,OAAO,MAAM,UAAU,QAAQ,OAAO,QAAQ,QAAQ,GAAG,WAAW,QAAQ,IAAI,GAAG,MAAM;CAC/F,MAAM,OAAO,OAAO,UAAU;CAC9B,OAAO,SAAS,KAAA,IAAY,OAAO,UAAU,MAAM,MAAM,MAAM;AACjE;AAKA,eAAsB,eACpB,SACA,QACA,MACA,OACiB;CACjB,MAAM,UAAU,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,MAAM,OAAO,KAAA,KAAa,EAAE,KAAK,OAAO,QAAQ;CACjG,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,gBACR,WAAW,OAAO,KAAK,eAAe,QAAQ,SAAS,IAAI,MAAM,GAAG,GAAG,QAAQ,KAAK,IAAI,KACxF,QAAQ,KAAK,OAAO;EAAE,MAAM,CAAC,CAAC;EAAG,SAAS,gBAAgB,EAAE;CAAG,EAAE,GACjE,EAAE,QAAQ,OAAO,KAAK,CACxB;CAEF,MAAM,SAAS,MAAM,UACnB,QAAQ,OAAO,QAAQ,QAAQ,GAC/B,WAAW,QAAQ;EAAE,GAAG;EAAM,GAAG;CAAM,CAAC,GACxC,MACF;CACA,MAAM,YAAoB,CAAC;CAC3B,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EACpC,IAAI,MAAM,SAAS,KAAA,GAAW;EAC9B,UAAU,OAAO,OAAO,SAAS,OAAO,OAAO,MAAM;CACvD;CACA,MAAM,OAAO,OAAO,UAAU;CAC9B,OAAO,SAAS,KAAA,IAAY,YAAY,UAAU,MAAM,WAAW,MAAM;AAC3E;AAEA,SAAgB,YAAY,QAAoB,KAAqB;CACnE,MAAM,MAAc,CAAC;CACrB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAC3C,IAAI,OAAO,QAAQ,IAAI,EAAE,SAAS,OAAO,IAAI,OAAO;CAEtD,OAAO;AACT;;;AChJA,SAAS,OAAO,OAAgB,SAAyD;CACvF,MAAM,UAAU,OAAO,QAAQ,gBAAgB,KAAK,CAAC;CACrD,OAAO,QAAQ,KAAK,WAAW,QAAQ,MAAM,GAAG,OAAO,MAAM,MAAM,CAAC,GAAG,EAAE;AAC3E;AAEA,UAAU,WAAW,QAAoB,OAAsB;CAC7D,KAAK,MAAM,YAAY,OAAO,OAAO,OAAO,SAAS,GAAG;EACtD,IAAI,SAAS,SAAS,SAAS,SAAS,SAAS;EACjD,MAAM,SAAS,MAAM,QAAQ,aAAa,SAAS,MAAM;EACzD,IAAI,WAAW,MAAM,MAAM;GAAE;GAAU;EAAO;CAChD;AACF;AAGA,SAAgB,oBAAoB,QAAoB,OAA+B;CACrF,KAAK,MAAM,EAAE,YAAY,WAAW,QAAQ,KAAK,GAC/C,IAAI,OAAO,OAAO,eAAe,KAAA,GAAW,OAAO;CAErD,OAAO;AACT;AAEA,MAAM,+BAA0B,IAAI,IAAI;AAMxC,eAAsB,gBACpB,OACA,KACA,SACA,SACe;CACf,MAAM,EAAE,QAAQ,OAAO,IAAI,SAAS;CACpC,MAAM,cAAc,YAAY,QAAQ,OAAO,KAAK,SAAS,CAAC,CAAC,OAAO;CACtE,MAAM,SAA4B,CAAC;CACnC,KAAK,MAAM,EAAE,UAAU,YAAY,WAAW,QAAQ,KAAK,GAAG;EAC5D,MAAM,YAAY,cAAc,YAAY,QAAQ,OAAO,UAAU,IAAI;EACzE,MAAM,OAAO,YACX,QACA,OACA,YACA,aACE,QACA,MAAM,QAAQ,SACd,QACA,QAAQ,gBAAgB,QAAQ,OAAO,OAAO,eAAe,KAAA,IACzD,EAAE,aAAa,KAAK,IACpB,CAAC,CACP,GACA,OACF;EACA,IAAI,UAAU,SAAS,KAAK,SAAS,KAAA,GAAW;EAChD,MAAM,MAAM,MAAM,QAAQ,UAAU,OAAO,KAAK,EAAE,UAChD,SAAS;EAEX,MAAM,UAAU,OAAO,OAAO,OAAO,IAAI,aAAa;EACtD,MAAM,UAAU,OAAO,OAAO,OAAO,IAAI,aAAa;EAEtD,IAAI,QAAQ,MAAM,QAAQ,QAAQ,KAAA,KAAa,QAAQ,OAAO,GAAG,GAAG,GAAG;EACvE,IAAI,CAAC,QAAQ,MAAM,QAAQ,QAAQ,IAAI,GAAa,CAAC,GAAG;EACxD,MAAM,SAAS,QAAQ,KAAK,QAAQ,IAAI,IAAc;EACtD,IAAI,OAAO,MAAM,UAAU,UAAU,QAAQ,UAAU,KAAA,CAAS,GAAG;EACnE,MAAM,SAAS,WAAW;GACxB,GAAG,QAAQ,KAAK,KAAK,OAAO,GAAG,MAAgB,EAAE,IAAI,OAAO,GAAG,EAAE,EAAE;GACnE,gBAAgB,SAAS;GACzB;EACF,CAAC;EACD,MAAM,QAAQ,YAAY,MAAM,QAAQ,WAAW,OAAO,MAAM,OAAO,OAAO,MAAM;EACpF,IAAI,OAAO,MAAM,GAAG,OAAO,OAAO,OAAO,KAAK,CAAC,MAAM,GACnD,OAAO,KAAK;GACV,MAAM,CAAC,QAAQ,EAAY;GAC3B,SAAS,MAAM,OAAO,KAAK,OAAO,OAAO,IAAI,MAAM,CAAC,CAAC,KAAK,IAAI;EAChE,CAAC;CAEL;CACA,IAAI,OAAO,SAAS,GAClB,MAAM,IAAI,gBAAgB,WAAW,OAAO,KAAK,kCAAkC,QAAQ,EACzF,QAAQ,OAAO,KACjB,CAAC;AAEL;;;AC5CA,SAAgB,oBAAoB,QAAoB,OAAgC;CACtF,OAAO,oBAAoB,QAAQ,KAAK,IAAI,CAAC,aAAa,IAAI,CAAC;AACjE;AAEA,MAAM,0BAA+B,IAAI,IAAI;AAC7C,MAAM,YAA+C,CAAC;AAEtD,SAAS,OAAO,OAAgB,KAA0B;CACxD,OAAQ,MAAiD;AAC3D;AAEA,SAAgB,SAAS,QAAoB,IAAmB;CAC9D,IAAI,OAAO,KAAA,KAAa,OAAO,QAAQ,OAAO,OAAO,UACnD,MAAM,IAAI,gBAAgB,GAAG,OAAO,KAAK,4BAA4B,EAAE,QAAQ,OAAO,KAAK,CAAC;AAEhG;AAEA,SAAgB,gBAAgB,OAAgC;CAC9D,OAAO,CAAC,GAAG,cAAc,MAAM,QAAQ,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;AAC9D;AAKA,eAAsB,SAAS,OAAgB,KAAa,SAAkC;CAC5F,MAAM,EAAE,QAAQ,UAAU;CAC1B,MAAM,MAAM,YAAY,QAAQ,GAAG;CACnC,KAAK,MAAM,OAAO,gBAAgB,QAAQ,OAAO,MAAM,IAAI,GACzD,IAAI,OAAO,KAAK,IAAI,OAAO;CAE7B,MAAM,QAAQ,OAAO,SAAS,SAAS,QAAQ;EAC7C,MAAM,OAAO,OAAO,QAAQ,IAAI,EAAE;EAClC,OAAO,SAAS,QAAQ,SAAS,KAAA,KAAa,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC;GAAE,KAAK;GAAK;GAAK;EAAK,CAAC;CAC7F,CAAC;CACD,IAAI,MAAM,SAAS,GACjB,MAAM,aAAa,OAAO,WAAW,MAAM,QAAQ,SAAS,MAAM,KAAK,OAAO,CAAC;CACjF,OAAO;AACT;AAEA,SAAgB,cAAc,SAAkB,MAAiC;CAC/E,IAAI,YAAY,KAAA,GAAW,OAAO,CAAC;CACnC,IAAI,CAAC,cAAc,OAAO,GAAG,MAAM,IAAI,gBAAgB,2BAA2B;CAClF,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GACnC,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,MAAM,IAAI,gBAAgB,mBAAmB,IAAI,EAAE;CAE9E,OAAO;AACT;AAEA,eAAsB,UACpB,OACA,MACA,OAC6B;CAC7B,MAAM,UAAuB,MAAM,aACjC,MAAM,QACN,MACA,MAAM,OACN,MAAM,MACN,KACF;CACA,IAAI,QAAQ,SAAS,QACnB,MAAM,UACJ,MAAM,OAAO,MACb,MACA,MAAM,MACN,UAAU,KAAK,WAAW,MAAM,KAAK,UAAU,EACjD;CAEF,OAAO,QAAQ,SAAS,WAAW,QAAQ,SAAS,KAAA;AACtD;AAIA,SAAgB,mBACd,OACA,MACwD;CACxD,MAAM,EAAE,QAAQ,OAAO,SAAS;CAChC,MAAM,YAAY,YAAY,QAAQ,OAAO,KAAK,SAAS;CAC3D,IAAI;CACJ,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,aAAa,WAAW;EAChD,MAAM,QAAQ,KAAK;EACnB,IAAI,UAAU,KAAA,GAAW;EACzB,IAAI,CAAC,UAAU,OAAO,KAAK,GACzB,MAAM,IAAI,eACR,WAAW,OAAO,KAAK,MAAM,IAAI,+CACjC;GAAE,QAAQ,OAAO;GAAM,WAAW,KAAK;GAAW,MAAM,aAAa;EAAS,CAChF;EAED,CAAC,4BAAY,IAAI,IAAI,EAAA,CAAG,IAAI,GAAG;CAClC;CACA,OAAO;EAAE,SAAS,WAAW;EAAS;CAAU;AAClD;AAIA,eAAsB,QACpB,OACA,IACA,OACiB;CACjB,MAAM,EAAE,QAAQ,UAAU;CAC1B,MAAM,SAAS,WAAW,CAAC,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC;CACrE,MAAM,QAAQ,YAAY,MAAM,QAAQ,WAAW,OAAO,MAAM,OAAO,OAAO,MAAM;CAEpF,MAAM,OAAM,MADO,MAAM,QAAQ,QAAQ,WAAW,MAAM,IAAI,OAAO,OAAO,KAAK,EAAA,CAChE;CACjB,IAAI,QAAQ,KAAA,GACV,MAAM,IAAI,cAAc,GAAG,OAAO,KAAK,IAAI,OAAO,EAAE,EAAE,cAAc,EAAE,QAAQ,OAAO,KAAK,CAAC;CAE7F,OAAO;AACT;AAEA,SAAgB,YAAY,QAAoB,QAAuB,OAAyB;CAC9F,OAAO,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,QAAQ,QACzC,WAAW,OACP,MAAM,SAAS,KAAA,KAAa,MAAM,SAAS,OAC3C,CAAC,UAAU,OAAO,MAAM,MAAM,IAAI,CACxC;AACF;AAIA,SAAS,SAAS,OAAsB;CACtC,MAAM,WAAW,gBAAgB,MAAM,MAAM,QAAQ,OAAO;CAC5D,OAAO;EACL,QAAQ,EAAE,GAAG,SAAS,OAAO;EAC7B,aAAa,EAAE,GAAG,SAAS,YAAY;EACvC,aAAa,EAAE,GAAG,SAAS,YAAY;CACzC;AACF;AAEA,SAAS,QAAQ,MAAY,OAAwC;CACnE,IAAI,UAAU,KAAA,GAAW;CACzB,OAAO,OAAO,KAAK,QAAQ,MAAM,MAAM;CACvC,OAAO,OAAO,KAAK,aAAa,MAAM,WAAW;CACjD,OAAO,OAAO,KAAK,aAAa,MAAM,WAAW;AACnD;AAGA,UAAU,cAAc,OAAgB;CACtC,KAAK,MAAM,UAAU,MAAM,MAAM,QAAQ,SAAS;EAChD,MAAM,QAAQ,MAAM,OAAO,OAAO,OAAO;EACzC,IAAI,OAAO,WAAW,QAAQ,UAAU,KAAA,GACtC,MAAM;GAAE;GAAQ;GAAO,QAAQ,OAAO;EAAO;CAEjD;AACF;AAYA,eAAe,OAAO,OAAgB,OAAmB,MAA6B;CACpF,KAAK,MAAM,EAAE,QAAQ,OAAO,YAAY,cAAc,KAAK,GAAG;EAC5D,IAAI,OAAO,WAAW,KAAA,GAAW;EACjC,MAAM,WAAW,MAAM,OAAO,OAAO;GACnC,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,WAAW,MAAM;GACjB,MAAM,MAAM;GACZ,KAAK,MAAM;GACX,UAAU,MAAM;GAChB,SAAS,MAAM;GACf,SAAS,MAAM,QAAQ,IAAI,OAAO,EAAE,KAAK;GACzC,KAAK,MAAM,KAAK;GAChB,IAAI,MAAM;GACV,KAAK,MAAM,MAAM;EACnB,CAAC;EACD,IAAI,aAAa,KAAA,KAAa,aAAa,MAAM,OAAO,OAAO,MAAM,QAAQ;CAC/E;AACF;AAUA,eAAsB,WACpB,OACA,KACA,IACA,SACqB;CACrB,MAAM,OAAO,SAAS,KAAK;CAC3B,IAAI;CACJ,IAAI,OAAO;CACX,KAAK,MAAM,EAAE,QAAQ,OAAO,YAAY,cAAc,KAAK,GAAG;EAC5D,IAAI,OAAO,WAAW,KAAA,GAAW;EACjC,MAAM,OAAO,MAAM,OAAO,OAAO;GAC/B,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,WAAW;GACX,SAAS,QAAQ,IAAI,OAAO,EAAE,KAAK;GACnC;GACA,IAAI,MAAM;GACV,KAAK,MAAM,MAAM;EACnB,CAAC;EACD,IAAI,SAAS,KAAA,GAAW;EACxB,IAAI,SAAS,KAAA,KAAa,CAAC,MAAM;GAC/B,OAAO,KAAK;GACZ,OAAO,KAAK,SAAS;EACvB;EACA,QAAQ,MAAM,KAAK,IAAI;CACzB;CACA,OAAO;EAAE,MAAM,QAAQ;EAAK;EAAM;CAAK;AACzC;AAcA,eAAsB,WAAW,OAAgB,MAA4C;CAC3F,MAAM,EAAE,QAAQ,IAAI,UAAU;CAC9B,MAAM,EAAE,UAAU,IAAI,SAAS;CAC/B,MAAM,EAAE,MAAM,SAAS;CACvB,MAAM,SAAS,KAAK,KAAK;CACzB,IAAI,QAAQ,MAAM,eAAe,OAAO;EAAE;EAAI,MAAM,KAAK;EAAO;EAAU,MAAM;CAAO,CAAC;CACxF,QAAQ,MAAM,eAAe,MAAM,SAAS,QAAQ,MAAM,KAAK;CAC/D,QAAQ,MAAM,aAAa,OAAO;EAAE;EAAI,MAAM;EAAO;EAAU,MAAM;CAAO,CAAC;CAC7E,MAAM,gBACJ,OACA;EAAE,GAAG;EAAM,GAAG;CAAM,GACpB,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,QAAQ,MAAM,SAAS,KAAA,CAAS,CAAC,GACpE,EAAE,aAAa,KAAK,YAAY,CAClC;CAEA,IAAI;CACJ,IAAI,MACF,MAAM;EAAE,GAAG;EAAM,GAAG;CAAM;MACrB;EAEL,IADa,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,MAAM,OAAO,KAAA,CACpD,CAAC,CAAC,WAAW,GAAG,OAAO,EAAE,KAAK,SAAS;EAC9C,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,GAAG,GAAG;EAM7C,MAAM,WAAU,MALI,GACjB,OAAO,OAAO,KAAK,CAAC,CACpB,IAAI,KAAc,CAAC,CACnB,MAAM,GAAG,IAAI,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,CACtC,UAAU,EAAA,CACQ;EACrB,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,cAAc,GAAG,OAAO,KAAK,sBAAsB;EACxF,MAAM;CACR;CACA,MAAM,QAAQ;EAAE,GAAG;EAAQ,GAAG,KAAK,KAAK;CAAY;CACpD,MAAM,OACJ,OACA;EACE,WAAW;EACX,MAAM;EACN,KAAK;EACL,UAAU;EACV,SAAS,CAAC;EACV,SAAS,KAAK;CAChB,GACA,KACF;CACA,MAAM,YAAY,OAAO;EACvB;EACA;EACA,UAAU;EACV,SAAS,YAAY,QAAQ,MAAM,GAAG;EACtC,MAAM;CACR,CAAC;CACD,OAAO,EAAE,IAAI;AACf;AAIA,eAAsB,eACpB,OACA,UACA,MACA,MAMsB;CACtB,MAAM,OAAO,MAAM,WAAW,OAAO,UAAU,KAAK,IAAI,KAAK,OAAO;CACpE,OAAO,WAAW,OAAO;EACvB;EACA,OAAO,gBAAgB,MAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,MAAM;EACjE,IAAI,KAAK;EACT;EACA,SAAS,KAAK;EACd,aAAa,KAAK;CACpB,CAAC;AACH;AAQA,SAAS,WAAW,OAAgB,KAAa,SAAwC;CACvF,MAAM,OAAO,SAAS,KAAK;CAC3B,MAAM,MAAc,CAAC;CACrB,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,EAAE,QAAQ,OAAO,YAAY,cAAc,KAAK,GAAG;EAC5D,IAAI,OAAO,WAAW,KAAA,GAAW;EACjC,MAAM,OAAO,OAAO,OAAO;GACzB,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,SAAS,QAAQ,IAAI,OAAO,EAAE,KAAK;GACnC;GACA,KAAK,MAAM,KAAK;GAChB,KAAK,MAAM,MAAM;EACnB,CAAC;EACD,IAAI,SAAS,KAAA,GAAW;EACxB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,GAAG;GACzD,IAAI,EAAE,OAAO,MAAM,OAAO,UACxB,MAAM,IAAI,cACR,WAAW,OAAO,GAAG,UAAU,IAAI,QAAQ,MAAM,OAAO,KAAK,2BAC7D,EAAE,QAAQ,MAAM,OAAO,KAAK,CAC9B;GAEF,IAAI,OAAO;EACb;EACA,KAAK,MAAM,QAAQ,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI;EAC/E,QAAQ,MAAM,KAAK,IAAI;CACzB;CACA,OAAO;EAAE;EAAK;EAAO;CAAK;AAC5B;AAEA,SAAgB,iBAAiB,OAAgC;CAC/D,OAAO,CAAC,GAAG,cAAc,MAAM,QAAQ,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC;AAC/D;AAEA,SAAgB,iBAAiB,OAAgC;CAC/D,OAAO,CAAC,GAAG,cAAc,MAAM,QAAQ,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC;AAC/D;AAEA,eAAsB,OACpB,QACA,OACA,OACA,YACiB;CACjB,MAAM,OAAO,WAAW,KAAK;CAC7B,cAAc,QAAQ,IAAI;CAC1B,MAAM,UAAU,cAAc,YAAY;EACxC,GAAG,iBAAiB,KAAK;EACzB,GAAG,gBAAgB,KAAK;EACxB,GAAG,oBAAoB,QAAQ,KAAK;CACtC,CAAC;CACD,MAAM,SAAS,aAAa,QAAQ,MAAM,QAAQ,SAAS,UAAU,OAAO;CAC5E,OAAO,aAAa,OAAO,QAAQ,UAAU,OAAO,UAAU;EAC5D,MAAM,gBAAgB,OAAO;GAAE;GAAM;EAAQ,CAAC;EAC9C,MAAM,UAAU,OAAO,UAAU,EAAE,KAAK,CAAC;EACzC,MAAM,EAAE,SAAS,cAAc,mBAAmB,OAAO,IAAI;EAC7D,gBAAgB,QAAQ,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO;EAE9D,IAAI,MAAM,gBACR,QACA,MACA,MACA,YAAY,QAAQ,MAAM,QAAQ,SAAS,MAAM,KAAK,OAAO,CAC/D;EACA,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,WAAW,IAAI,OAAO;EACrD,MAAM,OAAO,WAAW,OAAO,KAAK,MAAM;EAE1C,MAAM,SAA6C,CAAC;EACpD,KAAK,MAAM,QAAQ,KAAK,OAAO;GAC7B,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM,CAAC,CAAC;GAC9C,IAAI,WAAW,KAAA,GAAW,OAAO,KAAK;IAAE;IAAM;GAAO,CAAC;EACxD;EACA,OAAO,OAAO,KAAK,KAAK,GAAG;EAC3B,MAAM,SAAS,KAAK,KAAK;EACzB,MAAM,MAAM,eAAe,OAAO;GAAE,IAAI;GAAU,MAAM;GAAK,UAAU;GAAM,MAAM;EAAO,CAAC;EAC3F,MAAM,cAAc,QAAQ,GAAG;EAC/B,MAAM,MAAM,eAAe,MAAM,SAAS,QAAQ,GAAG;EACrD,MAAM,MAAM,aAAa,OAAO;GAAE,IAAI;GAAU,MAAM;GAAK,UAAU;GAAM,MAAM;EAAO,CAAC;EACzF,MAAM,gBAAgB,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,GAAG,CAAC,GAAG,OAAO;EAMpE,MAAM,OAAM,MAJY,MAAM,GAC3B,OAAO,OAAO,KAAK,CAAC,CACpB,OAAO,GAAY,CAAC,CACpB,UAAU,EAAA,CACQ;EACrB,IAAI,QAAQ,KAAA,GAAW,MAAM,IAAI,cAAc,GAAG,OAAO,KAAK,yBAAyB;EACvF,KAAK,MAAM,EAAE,MAAM,YAAY,QAAQ;GACrC,MAAM,QAAQ,YACZ,MAAM,QAAQ,WACd,OAAO,MACP,OAAO,OACP,WAAW,CAAC,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,IAAI,OAAO,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC,CACtE;GACA,IAAI,OAAO,MAAM,MAAM,GAAG,OAAO,OAAO,OAAO,KAAK,CAAC,MAAM,GACzD,MAAM,UAAU,OAAO,MAAM,MAAM,MAAM,MAAM,UAAU,KAAK,iBAAiB;EAEnF;EACA,MAAM,QAAQ;GAAE,GAAG;GAAQ,GAAG,KAAK,KAAK;EAAY;EACpD,MAAM,OACJ,OACA;GACE,WAAW;GACX,MAAM;GACN,KAAK;GACL,UAAU;GACV,SAAS;GACT,SAAS;EACX,GACA,KACF;EACA,MAAM,YAAY,OAAO;GACvB,IAAI;GACJ;GACA,UAAU;GACV,SAAS,YAAY,QAAQ,MAAM,GAAG;GACtC,MAAM;EACR,CAAC;EACD,MAAM,eAAe,OAAO,GAAG;EAC/B,iBAAiB,OAAO,KAAK,IAAI;EACjC,OAAO,SAAS,OAAO,KAAK,OAAO;CACrC,CAAC;AACH;AAEA,eAAsB,OACpB,QACA,OACA,IACA,OACA,YACiB;CACjB,SAAS,QAAQ,EAAE;CACnB,MAAM,OAAO,WAAW,KAAK;CAC7B,cAAc,QAAQ,IAAI;CAC1B,MAAM,UAAU,cAAc,YAAY;EACxC,GAAG,iBAAiB,KAAK;EACzB,GAAG,gBAAgB,KAAK;EACxB,GAAG,oBAAoB,QAAQ,KAAK;CACtC,CAAC;CACD,MAAM,SAAS,aAAa,QAAQ,MAAM,QAAQ,SAAS,UAAU,OAAO;CAC5E,OAAO,aAAa,OAAO,QAAQ,UAAU,OAAO,UAAU;EAC5D,MAAM,gBAAgB,OAAO;GAAE;GAAI;GAAM;EAAQ,CAAC;EAClD,MAAM,OAAO,MAAM,UAAU,OAAO,UAAU,EAAE,KAAK,CAAC;EACtD,MAAM,EAAE,SAAS,cAAc,mBAAmB,OAAO,IAAI;EAC7D,gBAAgB,QAAQ,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO;EAC9D,MAAM,WAAW,MAAM,QAAQ,OAAO,IAAI;GACxC,gBAAgB,SAAS;GACzB,YAAY,QAAQ,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ,OAAO;GACtE;EACF,CAAC;EACD,MAAM,SAAS,MAAM,eAAe,OAAO,UAAU,MAAM;GACzD,QAAQ,YAAY,QAAQ,MAAM,QAAQ,SAAS,MAAM,KAAK,OAAO;GACrE,IAAI;GACJ,SAAS;GACT,aAAa,QAAQ,gBAAgB;EACvC,CAAC;EACD,MAAM,eAAe,OAAO,OAAO,GAAG;EACtC,iBAAiB,OAAO,OAAO,KAAK,QAAQ;EAC5C,OAAO,SAAS,OAAO,OAAO,KAAK,OAAO;CAC5C,CAAC;AACH;AAGA,SAAgB,cAAc,QAAmC;CAC/D,OAAO,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC;AAC7C;AAGA,eAAe,QACb,OACA,UACA,QAC6B;CAC7B,MAAM,EAAE,QAAQ,OAAO;CACvB,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,GAAG,GAAG;CAC7C,KAAK,MAAM,EAAE,QAAQ,OAAO,YAAY,cAAc,KAAK,GAAG;EAC5D,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,OAAO,KAAK;GAChB;GACA,OAAO,MAAM;GACb,SAAS,OAAO,IAAI,OAAO,EAAE,KAAK;GAClC,KAAK;GACL,KAAK,MAAM,KAAK;GAChB,QAAQ,OAAO,UAAU;IAMvB,MAAM,OAAM,MALQ,GACjB,OAAO,OAAO,KAAK,CAAC,CACpB,IAAI,KAAc,CAAC,CACnB,MAAM,GAAG,IAAI,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,CACtC,UAAU,EAAA,CACI;IACjB,IAAI,QAAQ,KAAA,GAAW,MAAM,IAAI,cAAc,GAAG,OAAO,KAAK,sBAAsB;IACpF,OAAO;GACT;EACF,CAAC;EACD,IAAI,SAAS,KAAA,GAAW,OAAO;CACjC;AAEF;AAEA,eAAsB,eACpB,OACA,UACA,QACiB;CACjB,MAAM,EAAE,QAAQ,OAAO;CACvB,MAAM,UAAU,cAAc,MAAM;CACpC,MAAM,aAAa,OAAO,UAAU,OAAO;CAC3C,MAAM,OAAO,MAAM,QAAQ,OAAO,UAAU,MAAM;CAClD,IAAI;CACJ,IAAI,SAAS,KAAA,GACX,MAAM;MACD;EACL,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,GAAG,GAAG;EAK7C,MAAM,QAAO,MAJO,GACjB,OAAO,OAAO,KAAK,CAAC,CACpB,MAAM,GAAG,IAAI,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,CACtC,UAAU,EAAA,CACK;EAClB,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,cAAc,GAAG,OAAO,KAAK,sBAAsB;EACrF,MAAM;CACR;CACA,MAAM,OAAO,SAAS,KAAK,CAAC,CAAC;CAC7B,MAAM,UAAU,SAAS,KAAA;CACzB,MAAM,OACJ,OACA;EACE,WAAW;EACX,MAAM;EACN,KAAK;EACL,UAAU;EACV,SAAS;EACT,SAAS;CACX,GACA,IACF;CACA,MAAM,UAAyB;EAAE;EAAK,UAAU;EAAU;EAAS;EAAS;CAAK;CACjF,MAAM,YAAY,OAAO,OAAO;CAChC,OAAO,QAAQ;AACjB;AAEA,SAAgB,iBAAiB,OAAgC;CAC/D,OAAO,CAAC,GAAG,cAAc,MAAM,QAAQ,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC;AAC/D;AAEA,eAAsB,OACpB,QACA,OACA,IACA,YACiB;CACjB,SAAS,QAAQ,EAAE;CACnB,MAAM,UAAU,cAAc,YAAY,iBAAiB,KAAK,CAAC;CACjE,MAAM,SAAS,aAAa,QAAQ,MAAM,QAAQ,SAAS,UAAU,OAAO;CAC5E,OAAO,aAAa,OAAO,QAAQ,UAAU,OAAO,UAAU;EAC5D,MAAM,gBAAgB,OAAO;GAAE;GAAI;EAAQ,CAAC;EAC5C,MAAM,OAAO,MAAM,UAAU,OAAO,UAAU,EAAE,SAAS,cAAc,MAAM,EAAE,CAAC;EAChF,MAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,CACxC,aAAa,QAAQ,MAAM,OAAO,MAAM,KAAK,WAAW,QAAQ,OAAO,GACvE,IACF,CAAC;EACD,MAAM,MAAM,MAAM,eAAe,OAAO,UAAU,MAAM;EACxD,MAAM,eAAe,OAAO,GAAG;EAC/B,iBAAiB,OAAO,KAAK,QAAQ;EACrC,OAAO,SAAS,OAAO,KAAK,CAAC,CAAC;CAChC,CAAC;AACH;;;ACtmBA,SAAgB,iBACd,QACA,SACqB;CACrB,OAAO,CAAC,GAAG,gBAAgB,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAC3C,OAAO,OAAO,OAAO,GAAG,OAAO,QAAQ,KAAA,CAC1C;AACF;AAEA,SAAgB,gBACd,QACA,SACA,MAC0B;CAC1B,MAAM,KAAK,gBAAgB,OAAO,CAAC,CAAC,IAAI,IAAI;CAC5C,OAAO,OAAO,KAAA,KAAa,OAAO,OAAO,GAAG,OAAO,QAAQ,KAAA,IAAY,KAAK;AAC9E;AAIA,SAAgB,eAAe,IAAuB,MAAkC;CACtF,MAAM,QAAgB,CAAC;CACvB,GAAG,KAAK,KAAK,SAAS,KAAK,MAAM;EAC/B,IAAI,KAAK,OAAO,KAAA,GAAW,MAAM,OAAO,KAAK;CAC/C,CAAC;CACD,MAAM,WAAW,KAAK,GAAG,KAAK,KAAK;CACnC,IAAI,GAAG,KAAK,YAAY,KAAA,KAAa,aAAa,KAAA,GAAW;EAC3D,IAAI,CAAC,cAAc,QAAQ,GAAG,MAAM,IAAI,gBAAgB,GAAG,GAAG,KAAK,4BAA4B;EAC/F,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,IAAI,UAAU,KAAA,GAAW,MAAM,OAAO;CAE1C;CACA,OAAO;AACT;AAGA,SAAgB,iBACd,QACA,SACA,KACQ;CACR,MAAM,MAAc,CAAC;CACrB,KAAK,MAAM,MAAM,iBAAiB,QAAQ,OAAO,GAAG;EAClD,MAAM,OAAO,GAAG,KAAK,MAAM,GAAG;EAC9B,IAAI,OAAO;EACX,KAAK,MAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,GAAG,OAAQ,KAAK,UAAU,CAAC;EAC9D,KAAK,KAAK,KAAK,SAAS,OAAiB,GAAG,SAAoB,IAAI,IAAI,IAAI;CAC9E;CACA,OAAO;AACT;AAEA,SAAS,IACP,QACA,OACA,IACA,OACc;CACd,MAAM,OAAO,GAAG;CAChB,OAAO;EACL,SAAS,IAAI,OAAO,YAAY;GAC9B,SAAS,QAAQ,EAAE;GACnB,OAAO,aAAa,OAAO,QAAQ,MAAM,OAAO,UAAU;IACxD,MAAM,gBAAgB,OAAO,KAAK;IAClC,MAAM,OAAO,SAAS,QAAQ;IAE9B,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM,SAAS,WAAW,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IACjF,MAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,CACxC,aAAa,QAAQ,MAAM,OAAO,MAAM,kBAAkB,OAAO,GACjE,MACF,CAAC;IACD,MAAM,QACJ,OAAO,UAAU,aACb,MAAM,MAAM;KACV,KAAK;KACL,IAAI,MAAM;KACV,KAAK,MAAM,KAAK;KAChB,KAAK,MAAM,MAAM;IACnB,CAAC,IACD;IACN,IAAI,UAAU,KAAA,GAAW,OAAO,SAAS,OAAO,UAAU,CAAC,CAAC;IAC5D,MAAM,SACJ,SAAS,YAAY,KAAA,IACjB,mCACA,IAAI,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,OAAO,CAAC,CAAC;IAC/C,MAAM,OAAO,MAAM,WAAW,OAAO,UAAU,MAAM,MAAM;IAC3D,MAAM,SAAS,MAAM,WAAW,OAAO;KACrC;KACA,OAAO,EAAE,GAAG,MAAM;KAClB,IAAI;KACJ;KACA,SAAS;IACX,CAAC;IACD,MAAM,eAAe,OAAO,OAAO,GAAG;IACtC,iBAAiB,OAAO,OAAO,KAAK,QAAQ;IAC5C,OAAO,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC;GACvC,CAAC;EACH;EACA,MAAM,OAAO,IAAI,YAAY;GAC3B,MAAM,MAAM,QAAQ,MAAM;GAC1B,OAAO,MAAM,MAAM,SAAS,YAAY;IACtC,MAAM,OAAO,cAAc,MAAM,KAAK,OAAO,MAAM,MAAM,MAAM,QAAQ,IAAI,CAAC;IAC5E,MAAM,OAAO,SAAS,QAAQ;IAC9B,MAAM,UAAU,MAAM,aAAa,QAAQ,MAAM,OAAO,IAAI;IAC5D,IAAI,QAAQ,SAAS,QACnB,MAAM,UAAU,OAAO,MAAM,MAAM,MAAM,UAAU,KAAK,WAAW,KAAK,EAAE;IAE5E,IAAI,QAAQ,SAAS,UACnB,MAAM,IAAI,eACR,WAAW,OAAO,KAAK,YAAY,KAAK,eAAe,KAAK,oCAC5D;KAAE,QAAQ,OAAO;KAAM,WAAW;KAAM;IAAK,CAC/C;IAEF,MAAM,YAAoB,CAAC;IAC3B,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,YAAY,QAAQ,OAAO,IAAI,GAAG,UAAU,OAAO;IAClF,OAAO,GAAG;KAAE,UAAU,MAAM;KAAW;KAAW,KAAK,KAAK;KAAK,KAAK,MAAM;IAAI,CAAC;GACnF,CAAC;EACH;CACF;AACF;AAEA,eAAsB,mBACpB,QACA,OACA,MACA,OACkB;CAClB,MAAM,KAAK,gBAAgB,QAAQ,MAAM,QAAQ,SAAS,IAAI;CAC9D,IAAI,OAAO,MACT,MAAM,IAAI,iBAAiB,WAAW,OAAO,KAAK,sBAAsB,KAAK,IAAI,EAC/E,QAAQ,OAAO,KACjB,CAAC;CAEH,MAAM,QAAQ,SAAS,CAAC;CACxB,IAAI,CAAC,cAAc,KAAK,GAAG,MAAM,IAAI,gBAAgB,GAAG,KAAK,8BAA8B;CAC3F,MAAM,UAAU,GAAG,KAAK,WAAW,CAAC;CACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,MAAM,OAAO,QAAQ;EACrB,IAAI,SAAS,KAAA,GAAW,gBAAgB,KAAK,MAAM,KAAK;OACnD,IAAI,CAAC,GAAG,KAAK,KAAK,SAAS,GAAG,GACjC,MAAM,IAAI,gBAAgB,GAAG,KAAK,mBAAmB,IAAI,EAAE;CAE/D;CACA,MAAM,QAAQ,OAAO,OAAO,GAAG,OAAO;CACtC,OAAO,GAAG,KAAK,IAAI;EACjB;EACA,OAAO,OAAO;EACd,OAAO;EACP,KAAK,IAAI,QAAQ,OAAO,IAAI,KAAK;CACnC,CAAC;AACH"}
@@ -0,0 +1,18 @@
1
+ import { Er as timestamps, Mi as ColumnKind, Tr as defaultIdColumn } from "../context-B4e2eREP.js";
2
+ import { AnyPgColumn, AnyPgColumnBuilder, PgSchema } from "drizzle-orm/pg-core";
3
+ //#region src/schema/clone.d.ts
4
+ type CloneColumnOptions = {
5
+ keepDefault?: boolean;
6
+ };
7
+ export declare function cloneColumn(column: AnyPgColumn, opts?: CloneColumnOptions): AnyPgColumnBuilder;
8
+ //#endregion
9
+ //#region src/schema/column-kinds.d.ts
10
+ export declare const COLUMN_KIND_MARKER: unique symbol;
11
+ export declare function defineColumnKind<const TId extends string, TMeta = undefined>(id: TId): ColumnKind<TId, TMeta>;
12
+ export declare function readColumnKind(column: AnyPgColumn): string | null;
13
+ //#endregion
14
+ //#region src/schema/pg-schema.d.ts
15
+ export declare const typion: PgSchema<'typion'>;
16
+ //#endregion
17
+ export { type CloneColumnOptions, type ColumnKind, defaultIdColumn, timestamps };
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ import { i as timestamps, n as cloneColumn, r as defaultIdColumn, t as typion } from "../schema-Rzzq97cK.js";
2
+ import { n as defineColumnKind, r as readColumnKind, t as COLUMN_KIND_MARKER } from "../column-kinds-Bkm4NJI2.js";
3
+ export { COLUMN_KIND_MARKER, cloneColumn, defaultIdColumn, defineColumnKind, readColumnKind, timestamps, typion };
@@ -0,0 +1,68 @@
1
+ import { PgBigInt53, PgBigInt64, PgColumnBuilder, PgInteger, PgSmallInt, pgSchema, timestamp, uuid } from "drizzle-orm/pg-core";
2
+ //#region src/schema/columns.ts
3
+ function defaultIdColumn() {
4
+ return uuid().primaryKey().defaultRandom();
5
+ }
6
+ function timestamps() {
7
+ return {
8
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
9
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
10
+ };
11
+ }
12
+ //#endregion
13
+ //#region src/schema/clone.ts
14
+ const SERIAL_TO_PLAIN = {
15
+ PgSerial: {
16
+ cls: PgInteger,
17
+ columnType: "PgInteger"
18
+ },
19
+ PgSmallSerial: {
20
+ cls: PgSmallInt,
21
+ columnType: "PgSmallInt"
22
+ },
23
+ PgBigSerial53: {
24
+ cls: PgBigInt53,
25
+ columnType: "PgBigInt53"
26
+ },
27
+ PgBigSerial64: {
28
+ cls: PgBigInt64,
29
+ columnType: "PgBigInt64"
30
+ }
31
+ };
32
+ function cloneColumn(column, opts = {}) {
33
+ const src = column;
34
+ const keepDefault = opts.keepDefault ?? true;
35
+ const config = {
36
+ ...src.config,
37
+ primaryKey: false,
38
+ isUnique: false,
39
+ uniqueName: void 0,
40
+ uniqueType: void 0,
41
+ generated: void 0,
42
+ generatedIdentity: void 0,
43
+ defaultFn: void 0,
44
+ onUpdateFn: void 0
45
+ };
46
+ let cls = src.constructor;
47
+ const plain = SERIAL_TO_PLAIN[config.columnType];
48
+ if (plain !== void 0) {
49
+ cls = plain.cls;
50
+ config.columnType = plain.columnType;
51
+ config.hasDefault = false;
52
+ } else if (!keepDefault || config.default === void 0) {
53
+ config.default = void 0;
54
+ config.hasDefault = false;
55
+ }
56
+ const shim = Object.create(PgColumnBuilder.prototype);
57
+ shim.config = config;
58
+ shim.foreignKeyConfigs = [];
59
+ shim.build = (table) => new cls(table, config, config.enumValues);
60
+ return shim;
61
+ }
62
+ //#endregion
63
+ //#region src/schema/pg-schema.ts
64
+ const typion = pgSchema("typion");
65
+ //#endregion
66
+ export { timestamps as i, cloneColumn as n, defaultIdColumn as r, typion as t };
67
+
68
+ //# sourceMappingURL=schema-Rzzq97cK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-Rzzq97cK.js","names":[],"sources":["../src/schema/columns.ts","../src/schema/clone.ts","../src/schema/pg-schema.ts"],"sourcesContent":["import { timestamp, uuid } from 'drizzle-orm/pg-core'\n\n// The primary key a collection gets when it declares none.\nexport function defaultIdColumn() {\n return uuid().primaryKey().defaultRandom()\n}\n\nexport function timestamps() {\n return {\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n }\n}\n","import {\n type AnyPgColumn,\n type AnyPgColumnBuilder,\n PgBigInt53,\n PgBigInt64,\n PgColumnBuilder,\n PgInteger,\n PgSmallInt,\n} from 'drizzle-orm/pg-core'\n\ntype ColumnClass = new (table: unknown, config: unknown, extra?: unknown) => unknown\n\ntype RuntimeColumn = {\n config: Record<string, unknown>\n constructor: ColumnClass\n}\n\n// serial/bigserial/smallserial are pseudo-types that would create a sequence on the clone, whose rows copy the\n// values of the source, so they degrade to the plain integer class.\nconst SERIAL_TO_PLAIN: Record<string, { cls: ColumnClass; columnType: string }> = {\n PgSerial: { cls: PgInteger as unknown as ColumnClass, columnType: 'PgInteger' },\n PgSmallSerial: { cls: PgSmallInt as unknown as ColumnClass, columnType: 'PgSmallInt' },\n PgBigSerial53: { cls: PgBigInt53 as unknown as ColumnClass, columnType: 'PgBigInt53' },\n PgBigSerial64: { cls: PgBigInt64 as unknown as ColumnClass, columnType: 'PgBigInt64' },\n}\n\nexport type CloneColumnOptions = { keepDefault?: boolean }\n\n// A builder that re-creates a built column on another table — the same name, type, nullability, enum values\n// and static default, and no primary key, uniqueness, identity, generation, runtime default or reference —\n// which is what a table a plugin derives from an entity's is made of (the history of versions).\n// The only place that touches @internal drizzle fields: a built column keeps its builder config and class, so a\n// builder shim over a copied config re-creates the same class. Object.create keeps the prototype methods\n// pgTable() calls (setName, buildExtraConfigColumn).\nexport function cloneColumn(\n column: AnyPgColumn,\n opts: CloneColumnOptions = {},\n): AnyPgColumnBuilder {\n const src = column as unknown as RuntimeColumn\n const keepDefault = opts.keepDefault ?? true\n const config: Record<string, unknown> = {\n ...src.config,\n primaryKey: false,\n isUnique: false,\n uniqueName: undefined,\n uniqueType: undefined,\n generated: undefined,\n generatedIdentity: undefined,\n defaultFn: undefined,\n onUpdateFn: undefined,\n }\n let cls = src.constructor\n const plain = SERIAL_TO_PLAIN[config.columnType as string]\n if (plain !== undefined) {\n cls = plain.cls\n config.columnType = plain.columnType\n config.hasDefault = false\n } else if (!keepDefault || config.default === undefined) {\n config.default = undefined\n config.hasDefault = false\n }\n const shim = Object.create(PgColumnBuilder.prototype) as Record<string, unknown>\n shim.config = config\n shim.foreignKeyConfigs = []\n shim.build = (table: unknown) => new cls(table, config, config.enumValues)\n return shim as unknown as AnyPgColumnBuilder\n}\n","import { type PgSchema, pgSchema } from 'drizzle-orm/pg-core'\nimport { ConfigError } from '../errors.js'\n\nexport const typion: PgSchema<'typion'> = pgSchema('typion')\n\n// Unquoted-identifier rules keep the name usable verbatim in the drift check's information_schema\n// queries and in error messages.\nconst IDENTIFIER = /^[a-z_][a-z0-9_]*$/\n\nexport function defineInternalSchema<N extends string>(name: N): PgSchema<N> {\n if (!IDENTIFIER.test(name)) {\n throw new ConfigError(\n `defineInternalSchema: '${name}' must be a lowercase identifier (letters, digits, underscore)`,\n )\n }\n return pgSchema(name)\n}\n"],"mappings":";;AAGA,SAAgB,kBAAkB;CAChC,OAAO,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,cAAc;AAC3C;AAEA,SAAgB,aAAa;CAC3B,OAAO;EACL,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;EAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CACvD,QAAQ,CAAC,CACT,WAAW,CAAC,CACZ,gCAAgB,IAAI,KAAK,CAAC;CAC/B;AACF;;;ACIA,MAAM,kBAA4E;CAChF,UAAU;EAAE,KAAK;EAAqC,YAAY;CAAY;CAC9E,eAAe;EAAE,KAAK;EAAsC,YAAY;CAAa;CACrF,eAAe;EAAE,KAAK;EAAsC,YAAY;CAAa;CACrF,eAAe;EAAE,KAAK;EAAsC,YAAY;CAAa;AACvF;AAUA,SAAgB,YACd,QACA,OAA2B,CAAC,GACR;CACpB,MAAM,MAAM;CACZ,MAAM,cAAc,KAAK,eAAe;CACxC,MAAM,SAAkC;EACtC,GAAG,IAAI;EACP,YAAY;EACZ,UAAU;EACV,YAAY,KAAA;EACZ,YAAY,KAAA;EACZ,WAAW,KAAA;EACX,mBAAmB,KAAA;EACnB,WAAW,KAAA;EACX,YAAY,KAAA;CACd;CACA,IAAI,MAAM,IAAI;CACd,MAAM,QAAQ,gBAAgB,OAAO;CACrC,IAAI,UAAU,KAAA,GAAW;EACvB,MAAM,MAAM;EACZ,OAAO,aAAa,MAAM;EAC1B,OAAO,aAAa;CACtB,OAAO,IAAI,CAAC,eAAe,OAAO,YAAY,KAAA,GAAW;EACvD,OAAO,UAAU,KAAA;EACjB,OAAO,aAAa;CACtB;CACA,MAAM,OAAO,OAAO,OAAO,gBAAgB,SAAS;CACpD,KAAK,SAAS;CACd,KAAK,oBAAoB,CAAC;CAC1B,KAAK,SAAS,UAAmB,IAAI,IAAI,OAAO,QAAQ,OAAO,UAAU;CACzE,OAAO;AACT;;;AC/DA,MAAa,SAA6B,SAAS,QAAQ"}
@@ -0,0 +1,19 @@
1
+ import { B as EntityMeta, na as SeedGenerators, pn as TypionConfig } from "../context-B4e2eREP.js";
2
+ import { PgAsyncDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
3
+ //#region src/seed/index.d.ts
4
+ type Db = PgAsyncDatabase<PgQueryResultHKT, any>;
5
+ export type CollectionSeed = (generators: SeedGenerators, entity: EntityMeta) => Record<string, unknown>;
6
+ export type SeedOptions = {
7
+ count?: number;
8
+ seed?: number;
9
+ collections?: readonly string[];
10
+ values?: Readonly<Record<string, unknown>>;
11
+ refine?: (generators: SeedGenerators) => Record<string, unknown>;
12
+ db?: Db;
13
+ };
14
+ export declare const DRIZZLE_SEED = "1.0.0-rc.5-ab785fc";
15
+ export declare function seedCollections(config: TypionConfig<any>, options?: SeedOptions): Promise<void>;
16
+ export declare function resetCollections(config: TypionConfig<any>, options?: Pick<SeedOptions, 'collections' | 'db'>): Promise<void>;
17
+ export declare function resetTables(config: TypionConfig<any>, options?: Pick<SeedOptions, 'db'>): Promise<void>;
18
+ //#endregion
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,85 @@
1
+ import { n as ConfigError } from "../errors-D-CKO-px.js";
2
+ import { PgTable, getTableConfig } from "drizzle-orm/pg-core";
3
+ import { is, sql } from "drizzle-orm";
4
+ //#region src/seed/index.ts
5
+ const DRIZZLE_SEED = "1.0.0-rc.5-ab785fc";
6
+ async function load() {
7
+ try {
8
+ return await import("drizzle-seed");
9
+ } catch (error) {
10
+ throw new ConfigError(`Seeding needs drizzle-seed@${DRIZZLE_SEED} (\`pnpm add -D drizzle-seed@${DRIZZLE_SEED}\`)`, "config", { cause: error });
11
+ }
12
+ }
13
+ function truncate(db, tables) {
14
+ if (tables.length === 0) return void 0;
15
+ const names = tables.map((table) => {
16
+ const info = getTableConfig(table);
17
+ return `"${info.schema ?? "public"}"."${info.name}"`;
18
+ });
19
+ return db.execute(sql.raw(`truncate table ${names.join(", ")} cascade`));
20
+ }
21
+ function connect(config, given) {
22
+ if (given !== void 0) return given;
23
+ if (config.db === void 0) throw new ConfigError("The config has no database adapter (`db` in defineConfig)");
24
+ return config.db.connect(config.definition.relations);
25
+ }
26
+ function collectionsOf(config, names) {
27
+ const own = Object.values(config.definition.entities).filter((entity) => entity.owner === "user");
28
+ if (names === void 0) return own;
29
+ return names.map((name) => {
30
+ const entity = own.find((candidate) => candidate.name === name);
31
+ if (entity === void 0) throw new ConfigError(`'${name}' is not a collection of this config`);
32
+ return entity;
33
+ });
34
+ }
35
+ function columnsFor(config, entity, input) {
36
+ const columns = {};
37
+ for (const plugin of config.definition.plugins) Object.assign(columns, plugin.spec.seed?.columns?.(entity, input));
38
+ const generators = input.generators;
39
+ const own = entity.pluginOptions.seed;
40
+ if (typeof own === "function") Object.assign(columns, own(generators, entity));
41
+ return columns;
42
+ }
43
+ async function seedCollections(config, options = {}) {
44
+ const { seed } = await load();
45
+ const defaults = config.seed ?? {};
46
+ const db = connect(config, options.db);
47
+ const entities = collectionsOf(config, options.collections ?? defaults.collections);
48
+ const schema = {};
49
+ for (const entity of entities) schema[entity.name] = entity.table;
50
+ const values = {
51
+ ...defaults.values,
52
+ ...options.values
53
+ };
54
+ const count = options.count ?? defaults.count ?? 10;
55
+ const refine = options.refine ?? defaults.refine;
56
+ await seed(db, schema, {
57
+ count,
58
+ seed: options.seed ?? defaults.seed
59
+ }).refine((generators) => {
60
+ const refinements = {};
61
+ for (const entity of entities) {
62
+ const columns = columnsFor(config, entity, {
63
+ generators,
64
+ values,
65
+ count
66
+ });
67
+ if (Object.keys(columns).length > 0) refinements[entity.name] = { columns };
68
+ }
69
+ return {
70
+ ...refinements,
71
+ ...refine?.(generators)
72
+ };
73
+ });
74
+ }
75
+ async function resetCollections(config, options = {}) {
76
+ await truncate(connect(config, options.db), collectionsOf(config, options.collections).map((entity) => entity.table));
77
+ }
78
+ async function resetTables(config, options = {}) {
79
+ const tables = Object.values(config.schema).filter((value) => is(value, PgTable));
80
+ await truncate(connect(config, options.db), tables);
81
+ }
82
+ //#endregion
83
+ export { DRIZZLE_SEED, resetCollections, resetTables, seedCollections };
84
+
85
+ //# sourceMappingURL=index.js.map