convex-ents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/functions.d.ts +303 -0
- package/dist/functions.js +1167 -0
- package/dist/functions.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1460 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +293 -0
- package/dist/schema.js +325 -0
- package/dist/schema.js.map +1 -0
- package/dist/writer.d.ts +30 -0
- package/dist/writer.js +970 -0
- package/dist/writer.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/writer.ts","../src/functions.ts"],"sourcesContent":["export { defineEnt, defineEntSchema, getEntDefinitions } from \"./schema\";\nexport type { EntDefinition } from \"./schema\";\nexport { entsTableFactory, addEntRules } from \"./functions\";\nexport type {\n GenericEnt,\n GenericEntWriter,\n PromiseOrderedQueryOrNull,\n PromiseQueryOrNull,\n PromiseTableBase,\n PromiseTable,\n PromiseOrderedQueryBase,\n PromiseOrderedQuery,\n PromiseQuery,\n PromiseEntsOrNull,\n PromiseEnts,\n PromiseEntsOrNulls,\n PromiseEntOrNull,\n PromiseEntWriterOrNull,\n PromiseEnt,\n PromiseTableWriter,\n PromiseEntWriter,\n PromiseEntId,\n PromiseEdgeEntsOrNull,\n PromiseEdgeEnts,\n PromiseOrderedQueryWriter,\n PromiseQueryWriter,\n PromiseEntsWriter,\n} from \"./functions\";\n","import {\n DataModelFromSchemaDefinition,\n DefineSchemaOptions,\n GenericDataModel,\n GenericDocument,\n GenericTableIndexes,\n GenericTableSearchIndexes,\n GenericTableVectorIndexes,\n SchemaDefinition,\n SearchIndexConfig,\n TableDefinition,\n VectorIndexConfig,\n defineSchema,\n} from \"convex/server\";\nimport {\n GenericId,\n ObjectType,\n PropertyValidators,\n Validator,\n v,\n} from \"convex/values\";\n\nexport function defineEntSchema<\n Schema extends Record<string, EntDefinition>,\n StrictTableNameTypes extends boolean = true\n>(\n schema: Schema,\n options?: DefineSchemaOptions<StrictTableNameTypes>\n): SchemaDefinition<Schema, StrictTableNameTypes> {\n // Set the properties of edges which requires knowing their inverses,\n // and add edge tables.\n const tableNames = Object.keys(schema);\n for (const tableName of tableNames) {\n const table = schema[tableName];\n for (const edge of edgeConfigsFromEntDefinition(table)) {\n if (\n // Skip inverse edges, we process their forward edges\n (edge.cardinality === \"multiple\" &&\n edge.type === \"ref\" &&\n edge.inverse !== undefined) ||\n // symmetric is only set by defineEntSchema,\n // so we already processed the pair\n (edge as any).symmetric !== undefined\n ) {\n continue;\n }\n\n const otherTableName = edge.to;\n const otherTable = schema[otherTableName];\n if (otherTable === undefined) {\n throw new Error(\n `Edge \"${edge.name}\" in table \"${tableName}\" ` +\n `points to an undefined table \"${otherTableName}\"`\n );\n }\n\n const isSelfDirected = edge.to === tableName;\n\n const inverseEdgeCandidates = edgeConfigsFromEntDefinition(\n otherTable\n ).filter(canBeInverseEdge(tableName, edge, isSelfDirected));\n if (inverseEdgeCandidates.length > 1) {\n throw new Error(\n `Edge \"${edge.name}\" in table \"${tableName}\" ` +\n `has too many potential inverse edges in table \"${otherTableName}\": ` +\n `${inverseEdgeCandidates\n .map((edge) => `\"${edge.name}\"`)\n .join(\", \")}`\n );\n }\n const inverseEdge: EdgeConfigFromEntDefinition | undefined =\n inverseEdgeCandidates[0];\n\n // Default `ref` on the multiple end of the edge,\n if (edge.cardinality === \"single\" && edge.type === \"ref\") {\n if (inverseEdge === undefined) {\n throw new Error(\n `Missing inverse edge in table \"${otherTableName}\" ${\n edge.ref !== null ? `with field \"${edge.ref}\" ` : \"\"\n }for edge \"${edge.name}\" in table \"${tableName}\"`\n );\n }\n if (\n inverseEdge.cardinality === \"single\" &&\n inverseEdge.type === \"ref\"\n ) {\n // TODO: If we want to support optional 1:1 edges in the future\n // throw new Error(\n // `Both edge \"${edge.name}\" on ent \"${inverseEdge.to}\" and ` +\n // `edge \"${inverseEdge.name}\" on ent \"${edge.to}\" are marked ` +\n // `as optional, specify which table should store the 1:1 edge by ` +\n // `providing a \\`field\\` name.`\n // );\n throw new Error(\n `Both edge \"${edge.name}\" in table \"${inverseEdge.to}\" and ` +\n `edge \"${inverseEdge.name}\" in table \"${edge.to}\" are marked ` +\n `as optional, choose one to be required.`\n );\n }\n if (\n inverseEdge.cardinality !== \"single\" ||\n inverseEdge.type !== \"field\"\n ) {\n throw new Error(\n `Unexpected inverse edge type ${edge.name}, ${inverseEdge?.name}`\n );\n }\n if (edge.ref === null) {\n (edge as any).ref = inverseEdge.field;\n }\n // For now the the non-optional end is always unique\n (inverseEdge as any).unique = true;\n }\n if (edge.cardinality === \"multiple\") {\n if (!isSelfDirected && inverseEdge === undefined) {\n throw new Error(\n `Missing inverse edge in table \"${otherTableName}\" ` +\n `for edge \"${edge.name}\" in table \"${tableName}\"`\n );\n }\n\n if (inverseEdge?.cardinality === \"single\") {\n if (inverseEdge.type === \"ref\") {\n throw new Error(\n `The edge \"${inverseEdge.name}\" in table \"${otherTableName}\" ` +\n `cannot be optional, as it must store the 1:many edge as a field. ` +\n `Check the its inverse edge \"${edge.name}\" in table \"${tableName}\".`\n );\n }\n if (edge.type === \"ref\") {\n throw new Error(\n `The edge \"${inverseEdge.name}\" in table \"${otherTableName}\" ` +\n `cannot be singular, as the edge \"${edge.name}\" in table \"${tableName}\" did not ` +\n `specify the \\`ref\\` option.`\n );\n }\n (edge as any).type = \"field\";\n (edge as any).ref = inverseEdge.field;\n }\n\n if (inverseEdge?.cardinality === \"multiple\" || isSelfDirected) {\n if (!isSelfDirected && edge?.type === \"field\") {\n throw new Error(\n `The edge \"${edge.name}\" in table \"${tableName}\" ` +\n `specified \\`ref\\`, but its inverse edge \"${inverseEdge.name}\" ` +\n `in table \"${otherTableName}\" is not the singular end of a 1:many edge.`\n );\n }\n if (inverseEdge?.type === \"field\") {\n throw new Error(\n `The edge \"${inverseEdge.name}\" in table \"${otherTableName}\" ` +\n `specified \\`ref\\`, but its inverse edge \"${edge.name}\" ` +\n `in table \"${tableName}\" is not the singular end of a 1:many edge.`\n );\n }\n\n const edgeTableName =\n edge.type === \"ref\" && edge.table !== undefined\n ? edge.table\n : inverseEdge === undefined\n ? `${tableName}_${edge.name}`\n : inverseEdge.name !== tableName\n ? `${tableName}_${inverseEdge.name}_to_${edge.name}`\n : `${inverseEdge.name}_to_${edge.name}`;\n\n const forwardId =\n edge.type === \"ref\" && edge.field !== undefined\n ? edge.field\n : inverseEdge === undefined\n ? \"aId\"\n : tableName === otherTableName\n ? inverseEdge.name + \"Id\"\n : tableName + \"Id\";\n const inverseId =\n isSelfDirected &&\n edge.type === \"ref\" &&\n edge.inverseField !== undefined\n ? edge.inverseField\n : inverseEdge === undefined\n ? \"bId\"\n : inverseEdge.type === \"ref\" && inverseEdge.field !== undefined\n ? inverseEdge.field\n : tableName === otherTableName\n ? edge.name + \"Id\"\n : otherTableName + \"Id\";\n // Add the table\n (schema as any)[edgeTableName] = defineEnt({\n [forwardId]: v.id(tableName),\n [inverseId]: v.id(otherTableName),\n })\n .index(forwardId, [forwardId, inverseId])\n .index(inverseId, [inverseId, forwardId]);\n\n (edge as any).type = \"ref\";\n (edge as any).table = edgeTableName;\n (edge as any).field = forwardId;\n (edge as any).ref = inverseId;\n (edge as any).symmetric = inverseEdge === undefined;\n if (inverseEdge !== undefined) {\n inverseEdge.type = \"ref\";\n (inverseEdge as any).table = edgeTableName;\n (inverseEdge as any).field = inverseId;\n (inverseEdge as any).ref = forwardId;\n (inverseEdge as any).symmetric = false;\n }\n }\n }\n }\n }\n return defineSchema(schema, options);\n}\n\nfunction canBeInverseEdge(\n tableName: string,\n edge: EdgeConfigFromEntDefinition,\n isSelfDirected: boolean\n) {\n return (candidate: EdgeConfigFromEntDefinition) => {\n if (candidate.to !== tableName) {\n return false;\n }\n // Simple: pick out explicit inverse edges\n if (isSelfDirected) {\n return (\n candidate.cardinality === \"multiple\" &&\n candidate.type === \"ref\" &&\n candidate.inverse === edge.name\n );\n }\n // If both ref and field are known, only consider matching edges (from the ref side)\n if (\n (edge.cardinality === \"single\" &&\n edge.type === \"ref\" &&\n edge.ref !== null) ||\n (edge.cardinality === \"multiple\" &&\n edge.type === \"field\" &&\n edge.ref !== true)\n ) {\n if (candidate.cardinality === \"single\" && candidate.type === \"field\") {\n return edge.ref === candidate.field;\n }\n }\n // If both ref and field are known, only consider matching edges (from the field side)\n if (\n edge.cardinality === \"single\" &&\n edge.type === \"field\" &&\n edge.field !== null\n ) {\n if (\n (candidate.cardinality === \"single\" &&\n candidate.type === \"ref\" &&\n candidate.ref !== null) ||\n (candidate.cardinality === \"multiple\" &&\n candidate.type === \"field\" &&\n candidate.ref !== true)\n ) {\n return edge.field === candidate.ref;\n }\n }\n\n // If table is known on both ends, only consider matching edges\n if (\n edge.cardinality === \"multiple\" &&\n edge.type === \"ref\" &&\n edge.table !== undefined\n ) {\n return (\n candidate.cardinality === \"multiple\" &&\n candidate.type === \"ref\" &&\n edge.table === candidate.table\n );\n }\n if (\n candidate.cardinality === \"multiple\" &&\n candidate.type === \"ref\" &&\n candidate.table !== undefined\n ) {\n return (\n edge.cardinality === \"multiple\" &&\n edge.type === \"ref\" &&\n edge.table === candidate.table\n );\n }\n return true;\n };\n}\n\nfunction edgeConfigsFromEntDefinition(table: EntDefinition) {\n return Object.values(\n (table as any).edgeConfigs as Record<string, EdgeConfigFromEntDefinition>\n );\n}\n\nexport function defineEnt<\n DocumentSchema extends Record<string, Validator<any, any, any>>\n>(\n documentSchema: DocumentSchema\n): EntDefinition<\n ExtractDocument<ObjectValidator<DocumentSchema>>,\n ExtractFieldPaths<ObjectValidator<DocumentSchema>>\n> {\n return new EntDefinitionImpl(documentSchema) as any;\n}\n\ntype GenericEdges = Record<string, GenericEdgeConfig>;\n\nexport type GenericEdgeConfig = {\n name: string;\n to: string;\n cardinality: \"single\" | \"multiple\";\n type: \"field\" | \"ref\";\n};\n\nexport interface EntDefinition<\n Document extends GenericDocument = GenericDocument,\n FieldPaths extends string = string,\n // eslint-disable-next-line @typescript-eslint/ban-types\n Indexes extends GenericTableIndexes = {},\n // eslint-disable-next-line @typescript-eslint/ban-types\n SearchIndexes extends GenericTableSearchIndexes = {},\n // eslint-disable-next-line @typescript-eslint/ban-types\n VectorIndexes extends GenericTableVectorIndexes = {},\n // eslint-disable-next-line @typescript-eslint/ban-types\n Edges extends GenericEdges = {}\n> extends TableDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes\n > {\n /**\n * Define an index on this table.\n *\n * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/using/indexes).\n *\n * @param name - The name of the index.\n * @param fields - The fields to index, in order. Must specify at least one\n * field.\n * @returns A {@link TableDefinition} with this index included.\n */\n index<\n IndexName extends string,\n FirstFieldPath extends FieldPaths,\n RestFieldPaths extends FieldPaths[]\n >(\n name: IndexName,\n fields: [FirstFieldPath, ...RestFieldPaths]\n ): EntDefinition<\n Document,\n FieldPaths,\n Expand<\n Indexes &\n Record<IndexName, [FirstFieldPath, ...RestFieldPaths, \"_creationTime\"]>\n >,\n SearchIndexes,\n VectorIndexes,\n Edges\n >;\n\n /**\n * Define a search index on this table.\n *\n * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The search index configuration object.\n * @returns A {@link TableDefinition} with this search index included.\n */\n searchIndex<\n IndexName extends string,\n SearchField extends FieldPaths,\n FilterFields extends FieldPaths = never\n >(\n name: IndexName,\n indexConfig: Expand<SearchIndexConfig<SearchField, FilterFields>>\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n Expand<\n SearchIndexes &\n Record<\n IndexName,\n {\n searchField: SearchField;\n filterFields: FilterFields;\n }\n >\n >,\n VectorIndexes,\n Edges\n >;\n\n // /**\n // * Define a vector index on this table.\n // *\n // * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).\n // *\n // * @param name - The name of the index.\n // * @param indexConfig - The vector index configuration object.\n // * @returns A {@link TableDefinition} with this vector index included.\n // */\n vectorIndex<\n IndexName extends string,\n VectorField extends FieldPaths,\n FilterFields extends FieldPaths = never\n >(\n name: IndexName,\n indexConfig: Expand<VectorIndexConfig<VectorField, FilterFields>>\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n Expand<\n VectorIndexes &\n Record<\n IndexName,\n {\n vectorField: VectorField;\n dimensions: number;\n filterFields: FilterFields;\n }\n >\n >,\n Edges\n >;\n\n field<FieldName extends string, T extends Validator<any, any, any>>(\n field: FieldName,\n validator: T\n ): EntDefinition<\n Document & ObjectFieldType<FieldName, T>,\n FieldPaths | FieldName,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges\n >;\n field<FieldName extends string, T extends Validator<any, any, any>>(\n field: FieldName,\n validator: T,\n options: { index: true }\n ): EntDefinition<\n Document & ObjectFieldType<FieldName, T>,\n FieldPaths | FieldName,\n Indexes & { [key in FieldName]: [FieldName] },\n SearchIndexes,\n VectorIndexes,\n Edges\n >;\n field<FieldName extends string, T extends Validator<any, any, any>>(\n field: FieldName,\n validator: T,\n options: { unique: true }\n ): EntDefinition<\n Document & ObjectFieldType<FieldName, T>,\n FieldPaths | FieldName,\n Indexes & { [key in FieldName]: [FieldName] },\n SearchIndexes,\n VectorIndexes,\n Edges\n >;\n field<FieldName extends string, T extends Validator<any, false, any>>(\n field: FieldName,\n validator: T,\n options: { default: T[\"type\"] }\n ): EntDefinition<\n Document & ObjectFieldType<FieldName, T>,\n FieldPaths | FieldName,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges\n >;\n\n edge<EdgeName extends string>(\n edge: EdgeName\n ): EntDefinition<\n Document & { [key in `${EdgeName}Id`]: GenericId<`${EdgeName}s`> },\n FieldPaths | `${EdgeName}Id`,\n Indexes & { [key in `${EdgeName}Id`]: [`${EdgeName}Id`] },\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgeName]: {\n name: EdgeName;\n to: `${EdgeName}s`;\n type: \"field\";\n cardinality: \"single\";\n };\n }\n >;\n edge<EdgeName extends string, const FieldName extends string>(\n edge: EdgeName,\n options: { field: FieldName }\n ): EntDefinition<\n Document & { [key in NoInfer<FieldName>]: GenericId<`${EdgeName}s`> },\n FieldPaths | NoInfer<FieldName>,\n Indexes & { [key in NoInfer<FieldName>]: [NoInfer<FieldName>] },\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgeName]: {\n name: EdgeName;\n to: `${EdgeName}s`;\n type: \"field\";\n cardinality: \"single\";\n };\n }\n >;\n edge<\n EdgeName extends string,\n const FieldName extends string,\n const ToTable extends string\n >(\n edge: EdgeName,\n options: { field: FieldName; to: ToTable }\n ): EntDefinition<\n Document & { [key in NoInfer<FieldName>]: GenericId<ToTable> },\n FieldPaths | NoInfer<FieldName>,\n Indexes & { [key in NoInfer<FieldName>]: [NoInfer<FieldName>] },\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgeName]: {\n name: EdgeName;\n to: ToTable;\n type: \"field\";\n cardinality: \"single\";\n };\n }\n >;\n edge<EdgeName extends string>(\n edge: EdgeName,\n options: { optional: true; ref?: string }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgeName]: {\n name: EdgeName;\n to: `${EdgeName}s`;\n type: \"ref\";\n cardinality: \"single\";\n };\n }\n >;\n edge<EdgeName extends string, const ToTable extends string>(\n edge: EdgeName,\n options: { optional: true; to: ToTable; ref?: string }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgeName]: {\n name: EdgeName;\n to: NoInfer<ToTable>;\n type: \"ref\";\n cardinality: \"single\";\n };\n }\n >;\n\n /**\n * Define many:1 edge to another table.\n * @param edge The name of the edge, also the name of the target table.\n * @param options.ref The name of the field that stores the many:1 edge\n * on the other table, or `true` to infer it.\n */\n edges<EdgesName extends string>(\n edge: EdgesName,\n options: {\n ref: true | string;\n }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgesName]: {\n name: EdgesName;\n to: EdgesName;\n type: \"field\";\n cardinality: \"multiple\";\n };\n }\n >;\n /**\n * Define many:1 edge to another table.\n * @param edge The name of the edge.\n * @param options.to Name of the table the edge points to.\n * If it's the same as the table this edge is defined on, this edge is\n * a symmetric, self-directed many:many edge.\n * @param options.ref The name of the field that stores the many:1 edge\n * on the other table, or `true` to infer it.\n */\n edges<EdgesName extends string, TableName extends string>(\n edge: EdgesName,\n options: {\n to: TableName;\n ref: true | string;\n }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgesName]: {\n name: EdgesName;\n to: NoInfer<TableName>;\n type: \"field\";\n cardinality: \"multiple\";\n };\n }\n >;\n\n /**\n * Define many:many edge to another table.\n * @param edge The name of the edge, also the name of the target table.\n * @param options.table Optional, name of the table to store the many:many edge in.\n * @param options.field Optional, name of the field to store the ID of the\n * this end of the many:many edge.\n */\n edges<EdgesName extends string>(\n edge: EdgesName,\n options?: {\n table?: string;\n field?: string;\n }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgesName]: {\n name: EdgesName;\n to: EdgesName;\n type: \"ref\";\n cardinality: \"multiple\";\n };\n }\n >;\n /**\n * Define many:many edge to another table.\n * @param edge The name of the edge.\n * @param options.to Name of the table the edge points to.\n * If it's the same as the table this edge is defined on, this edge is\n * a symmetric, self-directed many:many edge.\n * @param options.table Optional, name of the table to store the many:many edge in.\n * @param options.field Optional, name of the field to store the ID of the\n * of the source end of the forward many:many edge.\n * @param options.inverseField Optional, name of the field to store the ID\n * of the target end of the forward edge. Only allowed for symmetric,\n * self-directed many:many edges.\n */\n edges<EdgesName extends string, TableName extends string>(\n edge: EdgesName,\n options: {\n to: TableName;\n table?: string;\n field?: string;\n inverseField?: string;\n }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgesName]: {\n name: EdgesName;\n to: NoInfer<TableName>;\n type: \"ref\";\n cardinality: \"multiple\";\n };\n }\n >;\n /**\n * Define self-directed, assymetric, many:many edge.\n * @param edge The name of the edge.\n * @param options.to Name of the table the edge points to.\n * Must be the same as the table this edge is defined on.\n * @param options.inverse Name of the inverse edge.\n * @param options.table Optional, name of the table to store the many:many edge in.\n * @param options.field Optional, name of the field to store the ID of the\n * of the source end of the forward many:many edge.\n * @param options.inverseField Optional, name of the field to store the ID\n * of the target end of the forward many:many edge.\n */\n edges<\n EdgesName extends string,\n TableName extends string,\n InverseEdgesNames extends string\n >(\n edge: EdgesName,\n options: {\n to: TableName;\n inverse: InverseEdgesNames;\n table?: string;\n field?: string;\n inverseField?: string;\n }\n ): EntDefinition<\n Document,\n FieldPaths,\n Indexes,\n SearchIndexes,\n VectorIndexes,\n Edges & {\n [key in EdgesName]: {\n name: EdgesName;\n to: NoInfer<TableName>;\n type: \"ref\";\n cardinality: \"multiple\";\n };\n } & {\n [key in NoInfer<InverseEdgesNames>]: {\n name: NoInfer<InverseEdgesNames>;\n to: NoInfer<TableName>;\n type: \"ref\";\n cardinality: \"multiple\";\n };\n }\n >;\n}\n\ntype NoInfer<T> = [T][T extends any ? 0 : never];\n\ntype FieldOptions = {\n index?: true;\n unique?: true;\n default?: any;\n};\n\ntype EdgeOptions = {\n optional?: true;\n field?: string;\n ref?: string;\n to?: string;\n};\n\ntype EdgesOptions = {\n to?: string;\n inverse?: string;\n ref?: string;\n table?: string;\n field?: string;\n inverseField?: string;\n};\n\nclass EntDefinitionImpl {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n private indexes: Index[] = [];\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n private searchIndexes: SearchIndex[] = [];\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n private vectorIndexes: VectorIndex[] = [];\n\n private documentSchema: Record<string, Validator<any, any, any>>;\n\n private edgeConfigs: Record<string, EdgeConfigFromEntDefinition> = {};\n\n private fieldConfigs: Record<string, FieldConfig> = {};\n\n private defaults: Record<string, any> = {};\n\n constructor(documentSchema: Record<string, Validator<any, any, any>>) {\n this.documentSchema = documentSchema;\n }\n\n index(name: any, fields: any) {\n this.indexes.push({ indexDescriptor: name, fields });\n return this;\n }\n\n searchIndex(name: any, indexConfig: any) {\n this.searchIndexes.push({\n indexDescriptor: name,\n searchField: indexConfig.searchField,\n filterFields: indexConfig.filterFields || [],\n });\n return this;\n }\n\n vectorIndex(name: any, indexConfig: any) {\n this.vectorIndexes.push({\n indexDescriptor: name,\n vectorField: indexConfig.vectorField,\n dimensions: indexConfig.dimensions,\n filterFields: indexConfig.filterFields || [],\n });\n return this;\n }\n\n /**\n * Export the contents of this definition.\n *\n * This is called internally by the Convex framework.\n * @internal\n */\n export() {\n return {\n indexes: this.indexes,\n searchIndexes: this.searchIndexes,\n vectorIndexes: this.vectorIndexes,\n documentType: (v.object(this.documentSchema) as any).json,\n };\n }\n\n field(name: string, validator: any, options?: FieldOptions): this {\n if (this.documentSchema[name] !== undefined) {\n // TODO: Store the fieldConfigs in an array so that we can\n // do the uniqueness check in defineEntSchema where we\n // know the table name.\n throw new Error(`Duplicate field \"${name}\"`);\n }\n const finalValidator =\n options?.default !== undefined ? v.optional(validator) : validator;\n this.documentSchema = { ...this.documentSchema, [name]: finalValidator };\n if (options?.unique === true || options?.index === true) {\n this.indexes.push({ indexDescriptor: name, fields: [name] });\n }\n if (options?.default !== undefined) {\n this.defaults[name] = options.default;\n }\n if (options?.unique === true) {\n this.fieldConfigs[name] = { name, unique: true };\n }\n return this;\n }\n\n edge(edgeName: string, options?: EdgeOptions): this {\n if (this.edgeConfigs[edgeName] !== undefined) {\n // TODO: Store the edgeConfigs in an array so that we can\n // do the uniqueness check in defineEntSchema where we\n // know the source table name.\n throw new Error(`Duplicate edge \"${edgeName}\"`);\n }\n const to = options?.to ?? edgeName + \"s\";\n if (options?.optional !== true) {\n const fieldName = options?.field ?? edgeName + \"Id\";\n this.documentSchema = { ...this.documentSchema, [fieldName]: v.id(to) };\n this.edgeConfigs[edgeName] = {\n name: edgeName,\n to,\n cardinality: \"single\",\n type: \"field\",\n field: fieldName,\n };\n this.indexes.push({\n indexDescriptor: fieldName,\n fields: [fieldName],\n });\n return this;\n }\n if (options.optional === true) {\n this.edgeConfigs[edgeName] = {\n name: edgeName,\n to,\n cardinality: \"single\",\n type: \"ref\",\n ref: options.ref ?? null,\n };\n }\n return this;\n }\n\n edges(name: string, options?: EdgesOptions): this {\n const cardinality = \"multiple\";\n const to = options?.to ?? name;\n const ref = options?.ref;\n const table = options?.table;\n // TODO: Do this later when we have the table name,\n // or rework schema to use a builder pattern.\n if (ref !== undefined && table !== undefined) {\n throw new Error(\n `Cannot specify both \\`ref\\` and \\`table\\` for the same edge, ` +\n `as the former is for 1:many edges and the latter ` +\n `for many:many edges. Config: \\`${JSON.stringify(options)}\\``\n );\n }\n const field = options?.field;\n const inverseField = options?.inverseField;\n // TODO: Do this later when we have the table name,\n // or rework schema to use a builder pattern.\n if (\n (field !== undefined || inverseField !== undefined) &&\n table === undefined\n ) {\n throw new Error(\n `Specify \\`table\\` if you're customizing the \\`field\\` or ` +\n `\\`inverseField\\` for a many:many edge. ` +\n `Config: \\`${JSON.stringify(options)}\\``\n );\n }\n const inverseName = options?.inverse;\n this.edgeConfigs[name] =\n ref !== undefined\n ? { name, to, cardinality, type: \"field\", ref }\n : { name, to, cardinality, type: \"ref\", table, field, inverseField };\n if (inverseName !== undefined) {\n this.edgeConfigs[inverseName] = {\n name: inverseName,\n to,\n cardinality,\n type: \"ref\",\n inverse: name,\n table,\n };\n }\n return this;\n }\n}\n\ntype ObjectFieldType<\n FieldName extends string,\n T extends Validator<any, any, any>\n> = T[\"isOptional\"] extends true\n ? { [key in FieldName]?: T[\"type\"] }\n : { [key in FieldName]: T[\"type\"] };\n\nexport type EdgeConfig = {\n name: string;\n to: string;\n} & (\n | ({\n cardinality: \"single\";\n } & (\n | {\n type: \"field\";\n field: string;\n unique: boolean;\n }\n | { type: \"ref\"; ref: string }\n ))\n | ({\n cardinality: \"multiple\";\n } & (\n | { type: \"field\"; ref: string }\n | {\n type: \"ref\";\n table: string;\n field: string;\n ref: string;\n inverse: boolean;\n symmetric: boolean;\n }\n ))\n);\n\ntype EdgeConfigFromEntDefinition = {\n name: string;\n to: string;\n} & (\n | ({\n cardinality: \"single\";\n } & (\n | {\n type: \"field\";\n field: string;\n }\n | { type: \"ref\"; ref: null | string }\n ))\n | ({\n cardinality: \"multiple\";\n } & (\n | { type: \"field\"; ref: true | string }\n | {\n type: \"ref\";\n table?: string;\n field?: string;\n inverseField?: string;\n inverse?: string;\n }\n ))\n);\n\nexport type FieldConfig = {\n name: string;\n unique: boolean;\n};\n\ntype ExtractDocument<T extends Validator<any, any, any>> =\n // Add the system fields to `Value` (except `_id` because it depends on\n //the table name) and trick TypeScript into expanding them.\n Expand<SystemFields & T[\"type\"]>;\n\nexport type Expand<ObjectType extends Record<any, any>> =\n ObjectType extends Record<any, any>\n ? {\n [Key in keyof ObjectType]: ObjectType[Key];\n }\n : never;\ntype ExtractFieldPaths<T extends Validator<any, any, any>> =\n // Add in the system fields available in index definitions.\n // This should be everything except for `_id` because thats added to indexes\n // automatically.\n T[\"fieldPaths\"] | keyof SystemFields;\nexport type SystemFields = {\n _creationTime: number;\n};\n\ntype ObjectValidator<Validators extends PropertyValidators> = Validator<\n // Compute the TypeScript type this validator refers to.\n ObjectType<Validators>,\n false,\n // Compute the field paths for this validator. For every property in the object,\n // add on a field path for that property and extend all the field paths in the\n // validator.\n {\n [Property in keyof Validators]:\n | JoinFieldPaths<Property & string, Validators[Property][\"fieldPaths\"]>\n | Property;\n }[keyof Validators] &\n string\n>;\n\ntype JoinFieldPaths<\n Start extends string,\n End extends string\n> = `${Start}.${End}`;\n\nexport type GenericEntsDataModel = GenericDataModel &\n Record<string, GenericEntModel>;\n\nexport type GenericEntModel = {\n edges: Record<string, GenericEdgeConfig>;\n};\n\nexport type EntDataModelFromSchema<\n SchemaDef extends SchemaDefinition<any, boolean>\n> = DataModelFromSchemaDefinition<SchemaDef> & {\n [TableName in keyof SchemaDef[\"tables\"] &\n string]: SchemaDef[\"tables\"][TableName] extends EntDefinition<\n any,\n any,\n any,\n any,\n any,\n infer Edges\n >\n ? {\n edges: Edges;\n }\n : never;\n};\n\nexport function getEntDefinitions<\n SchemaDef extends SchemaDefinition<any, boolean>\n>(schema: SchemaDef): EntDataModelFromSchema<typeof schema> {\n const tables = schema.tables;\n return Object.keys(tables).reduce(\n (acc, tableName) => ({\n ...acc,\n [tableName]: {\n defaults: tables[tableName].defaults,\n edges: tables[tableName].edgeConfigs,\n fields: tables[tableName].fieldConfigs,\n },\n }),\n {}\n ) as any;\n}\n","import {\n DocumentByName,\n GenericDatabaseWriter,\n GenericDocument,\n TableNamesInDataModel,\n} from \"convex/server\";\nimport { GenericId } from \"convex/values\";\nimport { entWrapper, getReadRule, getWriteRule } from \"./functions\";\nimport {\n EdgeConfig,\n FieldConfig,\n GenericEdgeConfig,\n GenericEntsDataModel,\n} from \"./schema\";\n\nexport class WriterImplBase<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> {\n constructor(\n protected db: GenericDatabaseWriter<EntsDataModel>,\n protected entDefinitions: EntsDataModel,\n protected table: Table\n ) {}\n\n async writeEdges(docId: GenericId<any>, changes: EdgeChanges) {\n await Promise.all(\n Object.values(\n this.entDefinitions[this.table].edges as Record<string, EdgeConfig>\n ).map(async (edgeDefinition) => {\n const idOrIds = changes[edgeDefinition.name];\n if (idOrIds === undefined) {\n return;\n }\n if (edgeDefinition.cardinality === \"single\") {\n if (edgeDefinition.type === \"ref\") {\n if (idOrIds.remove !== undefined) {\n // Cascading delete because 1:1 edges are not optional\n // on the stored field end.\n await this.db.delete(idOrIds.remove as GenericId<any>);\n }\n if (idOrIds.add !== undefined) {\n await this.db.patch(\n idOrIds.add as GenericId<any>,\n { [edgeDefinition.ref]: docId } as any\n );\n }\n }\n } else {\n if (edgeDefinition.type === \"field\") {\n if (idOrIds.remove !== undefined) {\n // Cascading delete because 1:many edges are not optional\n // on the stored field end.\n await Promise.all(\n (idOrIds.remove as GenericId<any>[]).map((id) =>\n this.db.delete(id)\n )\n );\n // This would be behavior for optional edge:\n // await Promise.all(\n // (idOrIds.remove as GenericId<any>[]).map((id) =>\n // this.db.patch(id, {\n // [edgeDefinition.ref]: undefined,\n // } as any)\n // )\n // );\n }\n if (idOrIds.add !== undefined) {\n await Promise.all(\n (idOrIds.add as GenericId<any>[]).map(async (id) =>\n this.db.patch(id, {\n [edgeDefinition.ref]: docId,\n } as any)\n )\n );\n }\n } else {\n let removeEdges: GenericId<any>[] = [];\n if (idOrIds.remove !== undefined) {\n removeEdges = (\n await Promise.all(\n (idOrIds.remove as GenericId<any>[]).map(async (id) =>\n (\n await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.field, (q) =>\n (q.eq(edgeDefinition.field, docId as any) as any).eq(\n edgeDefinition.ref,\n id\n )\n )\n .collect()\n ).concat(\n edgeDefinition.symmetric\n ? await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.ref, (q) =>\n (\n q.eq(edgeDefinition.ref, docId as any) as any\n ).eq(edgeDefinition.field, id)\n )\n .collect()\n : []\n )\n )\n )\n ).map((doc) => (doc as any)._id);\n }\n if (idOrIds.removeEdges !== undefined) {\n removeEdges = idOrIds.removeEdges;\n }\n if (removeEdges.length > 0) {\n await Promise.all(\n removeEdges.map(async (id) => {\n try {\n await this.db.delete(id);\n } catch (e) {\n // TODO:\n // For now we're gonna ignore errors here,\n // because we assume that the only error\n // is \"document not found\", which\n // can be caused by concurrent deletions.\n // In the future we could track which\n // edges are being deleted by this mutation,\n // and skip the call to delete altogether\n }\n })\n );\n }\n\n if (idOrIds.add !== undefined) {\n await Promise.all(\n (idOrIds.add as GenericId<any>[]).map(async (id) => {\n await this.db.insert(edgeDefinition.table, {\n [edgeDefinition.field]: docId,\n [edgeDefinition.ref]: id,\n } as any);\n if (edgeDefinition.symmetric) {\n await this.db.insert(edgeDefinition.table, {\n [edgeDefinition.field]: id,\n [edgeDefinition.ref]: docId,\n } as any);\n }\n })\n );\n }\n }\n }\n })\n );\n }\n\n async checkUniqueness(value: Partial<GenericDocument>, id?: GenericId<any>) {\n await Promise.all(\n Object.values(\n (this.entDefinitions[this.table] as any).fields as Record<\n string,\n FieldConfig\n >\n ).map(async (fieldDefinition) => {\n if (fieldDefinition.unique) {\n const key = fieldDefinition.name;\n const fieldValue = value[key];\n const existing = await this.db\n .query(this.table)\n .withIndex(key, (q) => q.eq(key, value[key] as any))\n .unique();\n if (existing !== null && (id === undefined || existing._id !== id)) {\n throw new Error(\n `In table \"${\n this.table\n }\" cannot create a duplicate document with field \"${key}\" of value \\`${\n fieldValue as string\n }\\`, existing document with ID \"${\n existing._id as string\n }\" already has it.`\n );\n }\n }\n })\n );\n await Promise.all(\n Object.values(\n this.entDefinitions[this.table].edges as Record<string, EdgeConfig>\n ).map(async (edgeDefinition) => {\n if (\n edgeDefinition.cardinality === \"single\" &&\n edgeDefinition.type === \"field\" &&\n edgeDefinition.unique\n ) {\n const key = edgeDefinition.field;\n if (value[key] === undefined) {\n return;\n }\n // Enforce uniqueness\n const existing = await this.db\n .query(this.table)\n .withIndex(key, (q) => q.eq(key, value[key] as any))\n .unique();\n if (existing !== null && (id === undefined || existing._id !== id)) {\n throw new Error(\n `In table \"${this.table}\" cannot create a duplicate 1:1 edge \"${\n edgeDefinition.name\n }\" to ID \"${value[key] as string}\", existing document with ID \"${\n existing._id as string\n }\" already has it.`\n );\n }\n }\n })\n );\n }\n\n fieldsOnly(\n value: Partial<\n WithEdgePatches<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ) {\n const fields: GenericDocument = {};\n Object.keys(value).forEach((key) => {\n const edgeDefinition: EdgeConfig | undefined = (\n this.entDefinitions[this.table].edges as EntsDataModel[Table][\"edges\"]\n )[key] as any;\n if (\n edgeDefinition === undefined\n // This doesn't do anything because the edge name doesn't match the field name\n // ||\n // (edgeDefinition.cardinality === \"single\" &&\n // edgeDefinition.type === \"field\")\n ) {\n fields[key] = value[key]!;\n }\n });\n return fields;\n }\n\n async checkReadAndWriteRule(\n operation: \"create\" | \"update\" | \"delete\",\n id: GenericId<Table> | undefined,\n value: Partial<GenericDocument> | undefined\n ) {\n if (id !== undefined) {\n const readPolicy = getReadRule(this.entDefinitions, this.table);\n if (readPolicy !== undefined) {\n const doc = await this.db.get(id);\n if (doc === null) {\n throw new Error(\n `Cannot update document with ID \"${id}\" in table \"${this.table} because it does not exist\"`\n );\n }\n const decision = await readPolicy(doc);\n if (!decision) {\n throw new Error(\n `Cannot update document with ID \"${id}\" from table \"${this.table}\"`\n );\n }\n }\n }\n const writePolicy = getWriteRule(this.entDefinitions, this.table);\n if (writePolicy === undefined) {\n return;\n }\n const ent =\n id === undefined\n ? undefined\n : entWrapper(\n (await this.db.get(id))!,\n this.db,\n this.entDefinitions,\n this.table\n );\n // Replace allows _id and _creationTime, but rules should not\n // rely on them.\n const { _id, _creationTime, ...safeValue } = value ?? {};\n const decision = await writePolicy({\n operation,\n ent: ent as any,\n value: value !== undefined ? (safeValue as any) : undefined,\n });\n if (!decision) {\n if (id === undefined) {\n throw new Error(\n `Cannot insert into table \"${this.table}\": \\`${JSON.stringify(\n value\n )}\\``\n );\n } else if (value === undefined) {\n throw new Error(\n `Cannot delete from table \"${this.table}\" with ID \"${id}\"`\n );\n } else {\n throw new Error(\n `Cannot update document with ID \"${id}\" in table \"${\n this.table\n }\" with: \\`${JSON.stringify(value)}\\``\n );\n }\n }\n }\n}\n\nexport type WithEdges<\n Document extends GenericDocument,\n Edges extends Record<string, GenericEdgeConfig>\n> = Document & {\n [key in keyof Edges as Edges[key][\"cardinality\"] extends \"single\"\n ? never\n : key]?: GenericId<Edges[key][\"to\"]>[];\n};\n\nexport type WithEdgePatches<\n Document extends GenericDocument,\n Edges extends Record<string, GenericEdgeConfig>\n> = Document & {\n [key in keyof Edges as Edges[key][\"cardinality\"] extends \"single\"\n ? never\n : key]?: {\n add?: GenericId<Edges[key][\"to\"]>[];\n remove?: GenericId<Edges[key][\"to\"]>[];\n };\n};\n\nexport type EdgeChanges = Record<\n string,\n {\n add?: GenericId<any>[] | GenericId<any>;\n remove?: GenericId<any>[] | GenericId<any>;\n removeEdges?: GenericId<any>[];\n }\n>;\n","import {\n DocumentByName,\n ExpressionOrValue,\n FieldTypeFromFieldPath,\n FilterBuilder,\n GenericDataModel,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n GenericDocument,\n IndexNames,\n IndexRange,\n IndexRangeBuilder,\n NamedIndex,\n NamedSearchIndex,\n NamedTableInfo,\n PaginationOptions,\n PaginationResult,\n Query,\n QueryInitializer,\n SearchFilter,\n SearchFilterBuilder,\n SearchIndexNames,\n TableNamesInDataModel,\n WithOptionalSystemFields,\n WithoutSystemFields,\n} from \"convex/server\";\nimport { GenericId } from \"convex/values\";\nimport { EdgeConfig, GenericEntsDataModel } from \"./schema\";\nimport {\n EdgeChanges,\n WithEdgePatches,\n WithEdges,\n WriterImplBase,\n} from \"./writer\";\n\n// TODO: Figure out how to make get() variadic\n// type FieldTypes<\n//\n// Table extends TableNamesInDataModel<EntsDataModel>,\n// T extends string[]\n// > = {\n// [K in keyof T]: FieldTypeFromFieldPath<\n// DocumentByName<EntsDataModel, Table>,\n// T[K]\n// >;\n// };\n\nexport interface PromiseOrderedQueryOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[] | null\n > {\n filter(\n predicate: (\n q: FilterBuilder<NamedTableInfo<EntsDataModel, Table>>\n ) => ExpressionOrValue<boolean>\n ): this;\n\n map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ): Promise<TOutput[] | null>;\n\n // TODO: entWrapper for pagination\n paginate(\n paginationOpts: PaginationOptions\n ): Promise<PaginationResult<DocumentByName<EntsDataModel, Table>> | null>;\n\n take(n: number): PromiseEntsOrNull<EntsDataModel, Table>;\n\n first(): PromiseEntOrNull<EntsDataModel, Table>;\n\n unique(): PromiseEntOrNull<EntsDataModel, Table>;\n\n docs(): Promise<DocumentByName<EntsDataModel, Table>[] | null>;\n}\n\nexport interface PromiseQueryOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseOrderedQueryOrNull<EntsDataModel, Table> {\n // TODO: The index variant should not be allowed if\n // this query already used an index\n order(\n order: \"asc\" | \"desc\",\n indexName?: IndexNames<NamedTableInfo<EntsDataModel, Table>>\n ): PromiseOrderedQueryOrNull<EntsDataModel, Table>;\n}\n\nexport interface PromiseTableBase<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> {\n getMany<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n values: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >[]\n ): PromiseEntsOrNulls<EntsDataModel, Table>;\n getMany(ids: GenericId<Table>[]): PromiseEntsOrNulls<EntsDataModel, Table>;\n getManyX<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n values: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >[]\n ): PromiseEnts<EntsDataModel, Table>;\n getManyX(ids: GenericId<Table>[]): PromiseEnts<EntsDataModel, Table>;\n /**\n * Returns the string ID format for the ID in a given table, or null if the ID\n * is from a different table or is not a valid ID.\n *\n * This does not guarantee that the ID exists (i.e. `table(\"foo\").get(id)` may return `null`).\n *\n * @param tableName - The name of the table.\n * @param id - The ID string.\n */\n normalizeId(id: string): GenericId<Table> | null;\n}\n\nexport interface PromiseTable<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseQuery<EntsDataModel, Table>,\n PromiseTableBase<EntsDataModel, Table> {\n get<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n // TODO: Figure out how to make this variadic\n value0: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >\n ): PromiseEntOrNull<EntsDataModel, Table>;\n get(id: GenericId<Table>): PromiseEntOrNull<EntsDataModel, Table>;\n /**\n * Fetch a document from the DB using given index, throw if it doesn't exist.\n */\n getX<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n // TODO: Figure out how to make this variadic\n value0: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >\n ): PromiseEnt<EntsDataModel, Table>;\n /**\n * Fetch a document from the DB for a given ID, throw if it doesn't exist.\n */\n getX(id: GenericId<Table>): PromiseEnt<EntsDataModel, Table>;\n /**\n * Query by running a full text search against a search index.\n *\n * Search queries must always search for some text within the index's\n * `searchField`. This query can optionally add equality filters for any\n * `filterFields` specified in the index.\n *\n * Documents will be returned in relevance order based on how well they\n * match the search text.\n *\n * To learn about full text search, see [Indexes](https://docs.convex.dev/text-search).\n *\n * @param indexName - The name of the search index to query.\n * @param searchFilter - A search filter expression constructed with the\n * supplied {@link SearchFilterBuilder}. This defines the full text search to run\n * along with equality filtering to run within the search index.\n * @returns - A query that searches for matching documents, returning them\n * in relevancy order.\n */\n search<\n IndexName extends SearchIndexNames<NamedTableInfo<EntsDataModel, Table>>\n >(\n indexName: IndexName,\n searchFilter: (\n q: SearchFilterBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedSearchIndex<NamedTableInfo<EntsDataModel, Table>, IndexName>\n >\n ) => SearchFilter\n ): PromiseOrderedQuery<EntsDataModel, Table>;\n}\n\nexport interface PromiseOrderedQueryBase<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> {\n filter(\n predicate: (\n q: FilterBuilder<NamedTableInfo<EntsDataModel, Table>>\n ) => ExpressionOrValue<boolean>\n ): this;\n\n // TODO: entWrapper for pagination\n paginate(\n paginationOpts: PaginationOptions\n ): Promise<PaginationResult<DocumentByName<EntsDataModel, Table>>>;\n\n first(): PromiseEntOrNull<EntsDataModel, Table>;\n\n unique(): PromiseEntOrNull<EntsDataModel, Table>;\n\n docs(): Promise<DocumentByName<EntsDataModel, Table>[]>;\n}\n\nexport interface PromiseOrderedQuery<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n >,\n PromiseOrderedQueryBase<EntsDataModel, Table> {\n map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ): Promise<TOutput[]>;\n\n take(n: number): PromiseEnts<EntsDataModel, Table>;\n\n firstX(): PromiseEnt<EntsDataModel, Table>;\n\n uniqueX(): PromiseEnt<EntsDataModel, Table>;\n}\n\nexport interface PromiseQuery<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseOrderedQuery<EntsDataModel, Table> {\n order(\n order: \"asc\" | \"desc\",\n indexName?: IndexNames<NamedTableInfo<EntsDataModel, Table>>\n ): PromiseOrderedQuery<EntsDataModel, Table>;\n}\n\nclass PromiseQueryOrNullImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n >\n extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[] | null\n >\n implements PromiseQueryOrNull<EntsDataModel, Table>\n{\n constructor(\n protected db: GenericDatabaseReader<EntsDataModel>,\n protected entDefinitions: EntsDataModel,\n protected table: Table,\n protected retrieve: () => Promise<Query<\n NamedTableInfo<EntsDataModel, Table>\n > | null>\n ) {\n super(() => {});\n }\n\n filter(\n predicate: (\n q: FilterBuilder<NamedTableInfo<EntsDataModel, Table>>\n ) => ExpressionOrValue<boolean>\n ): any {\n return new PromiseQueryOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const query = await this.retrieve();\n if (query === null) {\n return null;\n }\n return query.filter(predicate);\n }\n );\n }\n\n async map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ) {\n const array = await this;\n if (array === null) {\n return [];\n }\n return await Promise.all(array.map(callbackFn));\n }\n\n order(\n order: \"asc\" | \"desc\",\n indexName?: IndexNames<NamedTableInfo<EntsDataModel, Table>>\n ): any {\n return new PromiseQueryOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const query = await this.retrieve();\n if (query === null) {\n return null;\n }\n if (indexName !== undefined) {\n return (\n query as QueryInitializer<NamedTableInfo<EntsDataModel, Table>>\n )\n .withIndex(indexName)\n .order(order);\n }\n return query.order(order) as any;\n }\n );\n }\n\n // TODO: RLS for pagination\n async paginate(\n paginationOpts: PaginationOptions\n ): Promise<PaginationResult<DocumentByName<EntsDataModel, Table>> | null> {\n const query = await this.retrieve();\n if (query === null) {\n return null;\n }\n return await query.paginate(paginationOpts);\n }\n\n take(n: number) {\n return new PromiseEntsOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n return await this._take(n);\n },\n false\n );\n }\n\n first() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this._take(1);\n if (docs === null) {\n return nullRetriever;\n }\n const [doc] = docs;\n return loadedRetriever(doc);\n },\n false\n );\n }\n\n firstX() {\n return new PromiseEntWriterImpl(\n this.db as any,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this._take(1);\n if (docs === null) {\n return nullRetriever;\n }\n const [doc] = docs;\n if (doc === undefined) {\n throw new Error(\"Query returned no documents\");\n }\n return loadedRetriever(doc);\n },\n false\n );\n }\n\n unique() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this._take(2);\n if (docs === null) {\n return nullRetriever;\n }\n if (docs.length === 0) {\n return nullRetriever;\n }\n if (docs.length === 2) {\n throw new Error(\"unique() query returned more than one result\");\n }\n const [doc] = docs;\n return loadedRetriever(doc);\n },\n false\n );\n }\n\n uniqueX() {\n return new PromiseEntWriterImpl(\n this.db as any,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this._take(2);\n if (docs === null) {\n return nullRetriever;\n }\n if (docs.length === 0) {\n throw new Error(\"Query returned no documents\");\n }\n if (docs.length === 2) {\n throw new Error(\"unique() query returned more than one result\");\n }\n const [doc] = docs;\n return loadedRetriever(doc);\n },\n true\n );\n }\n\n async docs() {\n const query = await this.retrieve();\n if (query === null) {\n return null;\n }\n const docs = await query.collect();\n return filterByReadRule(\n this.db,\n this.entDefinitions,\n this.table,\n docs,\n false\n );\n }\n\n then<\n TResult1 =\n | Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n | null,\n TResult2 = never\n >(\n onfulfilled?:\n | ((\n value:\n | Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n | null\n ) => TResult1 | PromiseLike<TResult1>)\n | undefined\n | null,\n onrejected?:\n | ((reason: any) => TResult2 | PromiseLike<TResult2>)\n | undefined\n | null\n ): Promise<TResult1 | TResult2> {\n return this.docs()\n .then((documents) =>\n documents === null\n ? null\n : documents.map((doc) =>\n entWrapper(doc, this.db, this.entDefinitions, this.table)\n )\n )\n .then(onfulfilled, onrejected);\n }\n\n async _take(n: number) {\n const query = await this.retrieve();\n if (query === null) {\n return null;\n }\n const readPolicy = getReadRule(this.entDefinitions, this.table);\n if (readPolicy === undefined) {\n return await query.take(n);\n }\n let numItems = n;\n const docs = [];\n let hasMore = true;\n const iterator = query[Symbol.asyncIterator]();\n while (hasMore && docs.length < n) {\n const page = [];\n for (let i = 0; i < numItems; i++) {\n const { done, value } = await iterator.next();\n if (done) {\n hasMore = false;\n break;\n }\n page.push(value);\n }\n docs.push(\n ...(await filterByReadRule(\n this.db,\n this.entDefinitions,\n this.table,\n page,\n false\n ))!.slice(0, n - docs.length)\n );\n numItems = Math.min(64, numItems * 2);\n }\n return docs;\n }\n}\n\nclass PromiseTableImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseQueryOrNullImpl<EntsDataModel, Table> {\n constructor(\n db: GenericDatabaseReader<EntsDataModel>,\n entDefinitions: EntsDataModel,\n table: Table\n ) {\n super(db, entDefinitions, table, async () => db.query(table));\n }\n\n get(...args: any[]) {\n return this.getImpl(args);\n }\n\n getX(...args: any[]) {\n return this.getImpl(args, true);\n }\n\n getMany(...args: any[]) {\n return this.getManyImpl(args);\n }\n\n getManyX(...args: any[]) {\n return this.getManyImpl(args, true);\n }\n\n getImpl(args: any[], throwIfNull = false) {\n return new PromiseEntWriterImpl(\n this.db as any,\n this.entDefinitions,\n this.table,\n args.length === 1\n ? async () => {\n const id = args[0] as GenericId<Table>;\n if (this.db.normalizeId(this.table, id) === null) {\n throw new Error(`Invalid id \\`${id}\\` for table \"${this.table}\"`);\n }\n return {\n id,\n doc: async () => {\n const doc = await this.db.get(id);\n if (throwIfNull && doc === null) {\n throw new Error(\n `Document not found with id \\`${id}\\` in table \"${this.table}\"`\n );\n }\n return doc;\n },\n } as any; // any because PromiseEntWriterImpl expects non-nullable\n }\n : async () => {\n const [indexName, value] = args;\n const doc = await this.db\n .query(this.table)\n .withIndex(indexName, (q) => q.eq(indexName, value))\n .unique();\n if (throwIfNull && doc === null) {\n throw new Error(\n `Table \"${this.table}\" does not contain document with field \"${indexName}\" = \\`${value}\\``\n );\n }\n return loadedRetriever(doc);\n },\n throwIfNull\n );\n }\n\n getManyImpl(args: any[], throwIfNull = false) {\n return new PromiseEntsOrNullImpl(\n this.db as any,\n this.entDefinitions as any,\n this.table,\n args.length === 1\n ? async () => {\n const ids = args[0] as GenericId<Table>[];\n ids.forEach((id) => {\n if (this.db.normalizeId(this.table, id) === null) {\n throw new Error(\n `Invalid id \\`${id}\\` for table \"${this.table}\"`\n );\n }\n });\n return await Promise.all(\n ids.map(async (id) => {\n const doc = await this.db.get(id);\n if (doc === null) {\n throw new Error(\n `Document not found with id \\`${id}\\` in table \"${this.table}\"`\n );\n }\n return doc;\n })\n );\n }\n : async () => {\n const [indexName, values] = args;\n return (await Promise.all(\n (values as any[]).map(async (value) => {\n const doc = await this.db\n .query(this.table)\n .withIndex(indexName, (q) => q.eq(indexName, value))\n .unique();\n if (throwIfNull && doc === null) {\n throw new Error(\n `Table \"${this.table}\" does not contain document with field \"${indexName}\" = \\`${value}\\``\n );\n }\n return doc;\n })\n )) as any;\n },\n throwIfNull\n );\n }\n\n normalizeId(id: string): GenericId<Table> | null {\n return this.db.normalizeId(this.table, id);\n }\n\n // normalizeId or throw\n normalizeIdX(id: string): GenericId<Table> {\n const normalized = this.normalizeId(id);\n if (normalized === null) {\n throw new Error(`Invalid id \\`${id}\\` for table \"${this.table}\"`);\n }\n return normalized;\n }\n\n withIndex(\n indexName: IndexNames<NamedTableInfo<EntsDataModel, Table>>,\n indexRange?: (\n q: IndexRangeBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedIndex<NamedTableInfo<EntsDataModel, Table>, typeof indexName>\n >\n ) => IndexRange\n ) {\n return new PromiseQueryOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const query = await this.retrieve();\n return (\n query as QueryInitializer<NamedTableInfo<EntsDataModel, Table>>\n ).withIndex(indexName, indexRange);\n }\n );\n }\n\n search<\n IndexName extends SearchIndexNames<NamedTableInfo<EntsDataModel, Table>>\n >(\n indexName: IndexName,\n searchFilter: (\n q: SearchFilterBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedSearchIndex<NamedTableInfo<EntsDataModel, Table>, IndexName>\n >\n ) => SearchFilter\n ) {\n return new PromiseQueryOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const query = await this.retrieve();\n return (\n query as QueryInitializer<NamedTableInfo<EntsDataModel, Table>>\n ).withSearchIndex(indexName, searchFilter) as any;\n }\n );\n }\n}\n\n// This lazy promise materializes objects, so chaining to this type of\n// lazy promise performs one operation for each\n// retrieved document in JavaScript, basically as if using `Promise.all()`.\nexport interface PromiseEntsOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[] | null\n > {\n // TODO: At this point there is nothing query specific here, and we can either:\n // 1. Return a generic lazy promise of the list.\n // 2. Not give any methods, because they might lead devs down the wrong path.\n // // This just returns the first retrieved document, it does not optimize\n // // the previous steps in the query.\n // first(): PromiseEntOrNull<EntsDataModel, Table>;\n // // This just returns the unique retrieved document, it does not optimize\n // // the previous steps in the query. Otherwise it behaves like db.query().unique().\n // unique(): PromiseEntOrNull<EntsDataModel, Table>;\n\n map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ): Promise<TOutput[] | null>;\n\n docs(): Promise<DocumentByName<EntsDataModel, Table>[] | null>;\n}\n\n// This lazy promise materializes objects, so chaining to this type of\n// lazy promise performs one operation for each\n// retrieved document in JavaScript, basically as if using\n// `Promise.all()`.\nexport interface PromiseEnts<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n > {\n // TODO: At this point there is nothing query specific here, and we can either:\n // 1. Return a generic lazy promise of the list.\n // 2. Not give any methods, because they might lead devs down the wrong path.\n // // This just returns the first retrieved document, it does not optimize\n // // the previous steps in the query.\n // first(): PromiseEntOrNull<EntsDataModel, Table>;\n // // This just returns the first retrieved document, or throws if there\n // // are no documents. It does not optimize the previous steps in the query.\n // firstX(): PromiseEnt<EntsDataModel, Table>;\n // // This just returns the unique retrieved document, it does not optimize\n // // the previous steps in the query. Otherwise it behaves like db.query().unique().\n // unique(): PromiseEntOrNull<EntsDataModel, Table>;\n // // This just returns the unique retrieved document, or throws if there\n // // are no documents. It does not optimize the previous steps in the query.\n // // Otherwise it behaves like db.query().unique().\n // uniqueX(): PromiseEnt<EntsDataModel, Table>;\n\n map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ): Promise<TOutput[]>;\n\n docs(): Promise<DocumentByName<EntsDataModel, Table>[]>;\n}\n\nclass PromiseEntsOrNullImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n >\n extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[] | null\n >\n implements PromiseEntsOrNull<EntsDataModel, Table>\n{\n constructor(\n private db: GenericDatabaseReader<EntsDataModel>,\n private entDefinitions: EntsDataModel,\n private table: Table,\n private retrieve: () => Promise<\n DocumentByName<EntsDataModel, Table>[] | null\n >,\n private throwIfNull: boolean\n ) {\n super(() => {});\n }\n\n async map<TOutput>(\n callbackFn: (\n value: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>,\n index: number,\n array: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n ) => Promise<TOutput> | TOutput\n ) {\n const array = await this;\n if (array === null) {\n return [];\n }\n return await Promise.all(array.map(callbackFn));\n }\n\n first() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this.retrieve();\n if (docs === null) {\n return nullRetriever;\n }\n return loadedRetriever(docs[0] ?? null);\n },\n false\n );\n }\n\n firstX() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this.retrieve();\n if (docs === null) {\n return nullRetriever;\n }\n const doc = docs[0] ?? undefined;\n if (doc === undefined) {\n throw new Error(\"Query returned no documents\");\n }\n return loadedRetriever(doc);\n },\n true\n );\n }\n\n unique() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this.retrieve();\n if (docs === null) {\n return nullRetriever;\n }\n if (docs.length > 1) {\n throw new Error(\"unique() query returned more than one result\");\n }\n return loadedRetriever(docs[0] ?? null);\n },\n false\n );\n }\n\n uniqueX() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const docs = await this.retrieve();\n if (docs === null) {\n return nullRetriever;\n }\n if (docs.length > 1) {\n throw new Error(\"unique() query returned more than one result\");\n }\n if (docs.length < 1) {\n throw new Error(\"unique() query returned no documents\");\n }\n return loadedRetriever(docs[0]);\n },\n true\n );\n }\n\n async docs() {\n const docs = await this.retrieve();\n return filterByReadRule(\n this.db,\n this.entDefinitions,\n this.table,\n docs,\n this.throwIfNull\n );\n }\n\n then<\n TResult1 =\n | Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n | null,\n TResult2 = never\n >(\n onfulfilled?:\n | ((\n value:\n | Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n | null\n ) => TResult1 | PromiseLike<TResult1>)\n | undefined\n | null,\n onrejected?:\n | ((reason: any) => TResult2 | PromiseLike<TResult2>)\n | undefined\n | null\n ): Promise<TResult1 | TResult2> {\n return this.docs()\n .then((docs) =>\n docs === null\n ? null\n : docs.map((doc) =>\n entWrapper(doc, this.db, this.entDefinitions, this.table)\n )\n )\n .then(onfulfilled, onrejected);\n }\n}\n\n// This lazy promise materializes objects, so chaining to this type of\n// lazy promise performs one operation for each\n// retrieved document in JavaScript, basically as if using\n// `Promise.all()`.\nexport interface PromiseEntsOrNulls<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n (Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel> | null)[]\n > {}\n\nexport interface PromiseEdgeEntsOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseEntsOrNull<EntsDataModel, Table> {\n /**\n * Returns whether there is an ent with given ID on the other side\n * the edge. Returns null if chained to a null result.\n * @param id The ID of the ent on the other end of the edge\n */\n has(id: GenericId<Table>): Promise<boolean | null>;\n}\n\nexport interface PromiseEdgeEnts<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseEnts<EntsDataModel, Table> {\n /**\n * Returns whether there is an ent with given ID on the other side\n * the edge.\n * @param id The ID of the ent on the other end of the edge\n */\n has(id: GenericId<Table>): Promise<boolean>;\n}\n\nclass PromiseEdgeOrNullImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n >\n extends PromiseEntsOrNullImpl<EntsDataModel, Table>\n implements PromiseEdgeEntsOrNull<EntsDataModel, Table>\n{\n constructor(\n db: GenericDatabaseReader<EntsDataModel>,\n entDefinitions: EntsDataModel,\n table: Table,\n private field: string,\n private retrieveRange: (\n indexRange: (\n q: IndexRangeBuilder<DocumentByName<EntsDataModel, Table>, any>\n ) => any\n ) => Promise<DocumentByName<EntsDataModel, Table>[] | null>\n ) {\n super(db, entDefinitions, table, () => retrieveRange((q) => q), false);\n }\n\n async has(id: GenericId<Table>) {\n const docs = await this.retrieveRange((q) => q.eq(this.field, id as any));\n return (docs?.length ?? 0) > 0;\n }\n}\n\nexport interface PromiseEntOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n > | null> {\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdgeOrNull<EntsDataModel, Table, Edge>;\n\n doc(): Promise<DocumentByName<EntsDataModel, Table> | null>;\n}\n\nexport interface PromiseEnt<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>\n > {\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdge<EntsDataModel, Table, Edge>;\n\n edgeX<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdgeOrThrow<EntsDataModel, Table, Edge>;\n\n doc(): Promise<DocumentByName<EntsDataModel, Table>>;\n}\n\nclass PromiseEntOrNullImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n >\n extends Promise<Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n > | null>\n implements PromiseEntOrNull<EntsDataModel, Table>\n{\n constructor(\n protected db: GenericDatabaseReader<EntsDataModel>,\n protected entDefinitions: EntsDataModel,\n protected table: Table,\n protected retrieve: DocRetriever<\n GenericId<Table> | null,\n DocumentByName<EntsDataModel, Table> | null\n >,\n protected throwIfNull: boolean\n ) {\n super(() => {});\n }\n\n async doc() {\n const { id, doc: getDoc } = await this.retrieve();\n if (id === null) {\n return null;\n }\n const doc = await getDoc();\n if (doc === null) {\n return null;\n }\n const readPolicy = getReadRule(this.entDefinitions, this.table);\n if (readPolicy !== undefined) {\n const decision = await readPolicy(\n entWrapper(doc, this.db, this.entDefinitions, this.table)\n );\n if (this.throwIfNull && !decision) {\n throw new Error(\n `Document cannot be read with id \\`${doc._id as string}\\` in table \"${\n this.table\n }\"`\n );\n }\n return decision ? doc : null;\n }\n return doc;\n }\n\n then<\n TResult1 = Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n > | null,\n TResult2 = never\n >(\n onfulfilled?:\n | ((\n value: Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n > | null\n ) => TResult1 | PromiseLike<TResult1>)\n | undefined\n | null,\n onrejected?:\n | ((reason: any) => TResult2 | PromiseLike<TResult2>)\n | undefined\n | null\n ): Promise<TResult1 | TResult2> {\n return this.doc()\n .then((doc) =>\n doc === null\n ? null\n : entWrapper(doc, this.db, this.entDefinitions, this.table)\n )\n .then(onfulfilled, onrejected);\n }\n\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(edge: Edge) {\n return this.edgeImpl(edge);\n }\n\n edgeX<Edge extends keyof EntsDataModel[Table][\"edges\"]>(edge: Edge) {\n return this.edgeImpl(edge, true);\n }\n\n edgeImpl<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge,\n throwIfNull = false\n ) {\n const edgeDefinition: EdgeConfig = (\n this.entDefinitions[this.table].edges as EntsDataModel[Table][\"edges\"]\n )[edge] as any;\n\n if (edgeDefinition.cardinality === \"multiple\") {\n if (edgeDefinition.type === \"ref\") {\n return new PromiseEdgeOrNullImpl(\n this.db,\n this.entDefinitions,\n edgeDefinition.to,\n edgeDefinition.ref,\n async (indexRange) => {\n const { id } = await this.retrieve();\n if (id === null) {\n return null;\n }\n const edgeDocs = await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.field, (q) =>\n indexRange(q.eq(edgeDefinition.field, id as any) as any)\n )\n .collect();\n return (\n await Promise.all(\n edgeDocs.map((edgeDoc) =>\n this.db.get(edgeDoc[edgeDefinition.ref] as any)\n )\n )\n ).filter(<TValue>(doc: TValue | null, i: number): doc is TValue => {\n if (doc === null) {\n throw new Error(\n `Dangling reference for edge \"${edgeDefinition.name}\" in ` +\n `table \"${this.table}\" for document with ID \"${id}\": ` +\n `Could not find a document with ID \"${\n edgeDocs[i][edgeDefinition.field] as string\n }\"` +\n ` in table \"${edgeDefinition.to}\" (edge document ID is \"${\n edgeDocs[i]._id as string\n }\").`\n );\n }\n return true;\n });\n }\n ) as any;\n }\n return new PromiseQueryOrNullImpl(\n this.db,\n this.entDefinitions,\n edgeDefinition.to,\n async () => {\n const { id } = await this.retrieve();\n if (id === null) {\n return null;\n }\n return this.db\n .query(edgeDefinition.to)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, id as any)\n );\n }\n ) as any;\n }\n\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n edgeDefinition.to,\n async () => {\n const { id, doc: getDoc } = await this.retrieve();\n if (id === null) {\n return nullRetriever;\n }\n\n if (edgeDefinition.type === \"ref\") {\n const otherDoc = await this.db\n .query(edgeDefinition.to)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, id as any)\n )\n .unique();\n if (throwIfNull && otherDoc === null) {\n throw new Error(\n `Edge \"${\n edgeDefinition.name\n }\" does not exist for document with ID \"${id as string}\"`\n );\n }\n return loadedRetriever(otherDoc);\n }\n const doc = (await getDoc())!;\n const otherId = doc[edgeDefinition.field] as any;\n return {\n id: otherId,\n doc: async () => {\n const otherDoc = await this.db.get(otherId);\n if (otherDoc === null) {\n throw new Error(\n `Dangling reference for edge \"${edgeDefinition.name}\" in ` +\n `table \"${this.table}\" for document with ID \"${id}\": ` +\n `Could not find a document with ID \"${otherId}\"` +\n ` in table \"${edgeDefinition.to}\".`\n );\n }\n return otherDoc;\n },\n };\n },\n throwIfNull\n ) as any;\n }\n}\n\nexport function entWrapper<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n>(\n fields: DocumentByName<EntsDataModel, Table>,\n db: GenericDatabaseReader<EntsDataModel>,\n entDefinitions: EntsDataModel,\n table: Table\n): Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel> {\n const doc = { ...fields };\n const queryInterface = new PromiseEntWriterImpl(\n db as any,\n entDefinitions as any,\n table,\n async () => ({ id: doc._id as any, doc: async () => doc }),\n // this `true` doesn't matter, the queryInterface cannot be awaited\n true\n );\n Object.defineProperty(doc, \"edge\", {\n value: (edge: any) => {\n return queryInterface.edge(edge);\n },\n enumerable: false,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(doc, \"edgeX\", {\n value: (edge: any) => {\n return queryInterface.edgeX(edge);\n },\n enumerable: false,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(doc, \"patch\", {\n value: (value: any) => {\n return queryInterface.patch(value);\n },\n enumerable: false,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(doc, \"replace\", {\n value: (value: any) => {\n return queryInterface.replace(value);\n },\n enumerable: false,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(doc, \"delete\", {\n value: () => {\n return queryInterface.delete();\n },\n enumerable: false,\n writable: false,\n configurable: false,\n });\n Object.entries((entDefinitions as any)[table].defaults).map(\n ([field, value]) => {\n if (doc[field] === undefined) {\n (doc as any)[field] = value;\n }\n }\n );\n return doc as any;\n}\n\nexport function entsTableFactory<\n Database extends GenericDatabaseReader<any>,\n EntsDataModel extends GenericEntsDataModel\n>(\n db: Database,\n entDefinitions: EntsDataModel\n): Database extends GenericDatabaseWriter<any>\n ? EntsTableWriter<EntsDataModel>\n : EntsTable<EntsDataModel> {\n return (\n table: TableNamesInDataModel<EntsDataModel>,\n indexName?: string,\n indexRange?: any\n ) => {\n // Consider being strict here if people struggle with setup:\n // if (typeof db?.query !== \"function\") {\n // throw new Error(\n // `Expected context with \\`db\\`, got \\`${JSON.stringify(db)}\\``\n // );\n // }\n if (typeof table !== \"string\") {\n throw new Error(`Expected table name, got \\`${table as any}\\``);\n }\n if (indexName !== undefined) {\n return new PromiseTableImpl(db, entDefinitions, table).withIndex(\n indexName,\n indexRange\n );\n }\n if ((db as any).insert !== undefined) {\n return new PromiseTableWriterImpl(\n db as unknown as GenericDatabaseWriter<any>,\n entDefinitions,\n table\n ) as any;\n }\n return new PromiseTableImpl(db, entDefinitions, table);\n };\n}\n\ntype EntsTable<EntsDataModel extends GenericEntsDataModel> = {\n <\n Table extends TableNamesInDataModel<EntsDataModel>,\n IndexName extends IndexNames<NamedTableInfo<EntsDataModel, Table>>\n >(\n table: Table,\n indexName: IndexName,\n indexRange?: (\n q: IndexRangeBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedIndex<NamedTableInfo<EntsDataModel, Table>, IndexName>\n >\n ) => IndexRange\n ): PromiseQuery<EntsDataModel, Table>;\n <Table extends TableNamesInDataModel<EntsDataModel>>(\n table: Table\n ): PromiseTable<EntsDataModel, Table>;\n};\n\ntype EntsTableWriter<EntsDataModel extends GenericEntsDataModel> = {\n <\n Table extends TableNamesInDataModel<EntsDataModel>,\n IndexName extends IndexNames<NamedTableInfo<EntsDataModel, Table>>\n >(\n table: Table,\n indexName: IndexName,\n indexRange?: (\n q: IndexRangeBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedIndex<NamedTableInfo<EntsDataModel, Table>, IndexName>\n >\n ) => IndexRange\n ): PromiseTable<EntsDataModel, Table>;\n <Table extends TableNamesInDataModel<EntsDataModel>>(\n table: Table\n ): PromiseTableWriter<Table, EntsDataModel>;\n};\n\ndeclare class EntInstance<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> {\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdge<EntsDataModel, Table, Edge>;\n edgeX<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdgeOrThrow<EntsDataModel, Table, Edge>;\n}\n\nexport type Ent<\n Table extends TableNamesInDataModel<EntsDataModel>,\n Doc extends DocumentByName<EntsDataModel, Table>,\n EntsDataModel extends GenericEntsDataModel\n> = Doc & EntInstance<EntsDataModel, Table>;\n\nexport type GenericEnt<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> = Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>;\n\nexport type PromiseEdge<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>,\n Edge extends keyof EntsDataModel[Table][\"edges\"]\n> = EntsDataModel[Table][\"edges\"][Edge][\"cardinality\"] extends \"multiple\"\n ? EntsDataModel[Table][\"edges\"][Edge][\"type\"] extends \"ref\"\n ? PromiseEdgeEnts<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : PromiseQuery<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : EntsDataModel[Table][\"edges\"][Edge][\"type\"] extends \"ref\"\n ? PromiseEntOrNull<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : PromiseEnt<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>;\n\nexport type PromiseEdgeOrThrow<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>,\n Edge extends keyof EntsDataModel[Table][\"edges\"]\n> = EntsDataModel[Table][\"edges\"][Edge][\"cardinality\"] extends \"multiple\"\n ? EntsDataModel[Table][\"edges\"][Edge][\"type\"] extends \"ref\"\n ? PromiseEdgeEnts<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : PromiseQuery<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : EntsDataModel[Table][\"edges\"][Edge][\"type\"] extends \"ref\"\n ? PromiseEnt<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>\n : PromiseEnt<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>;\n\ntype PromiseEdgeOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>,\n Edge extends keyof EntsDataModel[Table][\"edges\"]\n> = EntsDataModel[Table][\"edges\"][Edge][\"cardinality\"] extends \"multiple\"\n ? EntsDataModel[Table][\"edges\"][Edge][\"type\"] extends \"ref\"\n ? PromiseEdgeEntsOrNull<\n EntsDataModel,\n EntsDataModel[Table][\"edges\"][Edge][\"to\"]\n >\n : PromiseQueryOrNull<\n EntsDataModel,\n EntsDataModel[Table][\"edges\"][Edge][\"to\"]\n >\n : PromiseEntOrNull<EntsDataModel, EntsDataModel[Table][\"edges\"][Edge][\"to\"]>;\n\nexport interface PromiseOrderedQueryWriter<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n EntWriter<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>[]\n >,\n PromiseOrderedQueryBase<EntsDataModel, Table> {\n map<TOutput>(\n callbackFn: (\n value: EntWriter<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n >,\n index: number,\n array: EntWriter<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n >[]\n ) => Promise<TOutput> | TOutput\n ): Promise<TOutput[]>;\n\n take(n: number): PromiseEntsWriter<EntsDataModel, Table>;\n\n firstX(): PromiseEntWriter<EntsDataModel, Table>;\n\n uniqueX(): PromiseEntWriter<EntsDataModel, Table>;\n}\n\nexport interface PromiseQueryWriter<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseOrderedQueryWriter<EntsDataModel, Table> {\n order(\n order: \"asc\" | \"desc\",\n indexName?: IndexNames<NamedTableInfo<EntsDataModel, Table>>\n ): PromiseOrderedQueryWriter<EntsDataModel, Table>;\n}\n\n// This lazy promise materializes objects, so chaining to this type of\n// lazy promise performs one operation for each\n// retrieved document in JavaScript, basically as if using\n// `Promise.all()`.\nexport interface PromiseEntsWriter<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseEnts<EntsDataModel, Table> {\n // This just returns the first retrieved document, or throws if there\n // are no documents. It does not optimize the previous steps in the query.\n firstX(): PromiseEntWriter<EntsDataModel, Table>;\n\n // This just returns the unique retrieved document, or throws if there\n // are no documents. It does not optimize the previous steps in the query.\n // Otherwise it behaves like db.query().unique().\n uniqueX(): PromiseEntWriter<EntsDataModel, Table>;\n}\n\nexport interface PromiseTableWriter<\n Table extends TableNamesInDataModel<EntsDataModel>,\n EntsDataModel extends GenericEntsDataModel\n> extends PromiseQueryWriter<EntsDataModel, Table>,\n PromiseTableBase<EntsDataModel, Table> {\n get<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n // TODO: Figure out how to make this variadic\n value0: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >\n ): PromiseEntWriterOrNull<EntsDataModel, Table>;\n get(id: GenericId<Table>): PromiseEntWriterOrNull<EntsDataModel, Table>;\n /**\n * Fetch a document from the DB using given index, throw if it doesn't exist.\n */\n getX<\n Indexes extends EntsDataModel[Table][\"indexes\"],\n Index extends keyof Indexes\n >(\n indexName: Index,\n // TODO: Figure out how to make this variadic\n value0: FieldTypeFromFieldPath<\n DocumentByName<EntsDataModel, Table>,\n Indexes[Index][0]\n >\n ): PromiseEnt<EntsDataModel, Table>;\n /**\n * Fetch a document from the DB for a given ID, throw if it doesn't exist.\n */\n getX(id: GenericId<Table>): PromiseEntWriter<EntsDataModel, Table>;\n /**\n * Query by running a full text search against a search index.\n *\n * Search queries must always search for some text within the index's\n * `searchField`. This query can optionally add equality filters for any\n * `filterFields` specified in the index.\n *\n * Documents will be returned in relevance order based on how well they\n * match the search text.\n *\n * To learn about full text search, see [Indexes](https://docs.convex.dev/text-search).\n *\n * @param indexName - The name of the search index to query.\n * @param searchFilter - A search filter expression constructed with the\n * supplied {@link SearchFilterBuilder}. This defines the full text search to run\n * along with equality filtering to run within the search index.\n * @returns - A query that searches for matching documents, returning them\n * in relevancy order.\n */\n search<\n IndexName extends SearchIndexNames<NamedTableInfo<EntsDataModel, Table>>\n >(\n indexName: IndexName,\n searchFilter: (\n q: SearchFilterBuilder<\n DocumentByName<EntsDataModel, Table>,\n NamedSearchIndex<NamedTableInfo<EntsDataModel, Table>, IndexName>\n >\n ) => SearchFilter\n ): PromiseOrderedQueryWriter<EntsDataModel, Table>;\n /**\n * Insert a new document into a table.\n *\n * @param table - The name of the table to insert a new document into.\n * @param value - The {@link Value} to insert into the given table.\n * @returns - {@link GenericId} of the new document.\n */\n // TODO: Chain methods to get the written document?\n insert(\n value: WithoutSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ): PromiseEntId<EntsDataModel, Table>;\n /**\n * Insert new documents into a table.\n *\n * @param table - The name of the table to insert a new document into.\n * @param value - The {@link Value} to insert into the given table.\n * @returns - {@link GenericId} of the new document.\n */\n // TODO: Chain methods to get the written documents?\n insertMany(\n values: WithoutSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >[]\n ): Promise<GenericId<Table>[]>;\n}\n\nclass PromiseTableWriterImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseTableImpl<EntsDataModel, Table> {\n private base: WriterImplBase<EntsDataModel, Table>;\n\n constructor(\n protected db: GenericDatabaseWriter<EntsDataModel>,\n entDefinitions: EntsDataModel,\n table: Table\n ) {\n super(db, entDefinitions, table);\n this.base = new WriterImplBase(db, entDefinitions, table);\n }\n\n insert(\n value: WithoutSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ) {\n return new PromiseEntIdImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n await this.base.checkReadAndWriteRule(\"create\", undefined, value);\n await this.base.checkUniqueness(value);\n const fields = this.base.fieldsOnly(value as any);\n const docId = await this.db.insert(this.table, fields as any);\n const edges: EdgeChanges = {};\n Object.keys(value).forEach((key) => {\n const edgeDefinition: EdgeConfig = (\n this.entDefinitions[this.table]\n .edges as EntsDataModel[Table][\"edges\"]\n )[key] as any;\n if (\n edgeDefinition === undefined ||\n (edgeDefinition.cardinality === \"single\" &&\n edgeDefinition.type === \"field\")\n ) {\n return;\n }\n if (edgeDefinition.cardinality === \"single\") {\n throw new Error(\"Cannot set 1:1 edge from optional end.\");\n }\n edges[key] = { add: value[key] };\n });\n await this.base.writeEdges(docId, edges);\n return docId;\n }\n );\n }\n\n // TODO: fluent API\n async insertMany(\n values: WithoutSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >[]\n ) {\n return await Promise.all(values.map((value) => this.insert(value)));\n }\n}\n\nexport interface PromiseEntWriterOrNull<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<EntWriter<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n > | null> {\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdgeOrNull<EntsDataModel, Table, Edge>;\n\n doc(): Promise<DocumentByName<EntsDataModel, Table> | null>;\n}\n\nexport interface PromiseEntWriter<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<\n EntWriter<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>\n > {\n edge<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdge<EntsDataModel, Table, Edge>;\n\n edgeX<Edge extends keyof EntsDataModel[Table][\"edges\"]>(\n edge: Edge\n ): PromiseEdgeOrThrow<EntsDataModel, Table, Edge>;\n\n doc(): Promise<DocumentByName<EntsDataModel, Table>>;\n\n /**\n * Patch this existing document, shallow merging it with the given partial\n * document.\n *\n * New fields are added. Existing fields are overwritten. Fields set to\n * `undefined` are removed.\n *\n * @param value - The partial {@link GenericDocument} to merge into this document. If this new value\n * specifies system fields like `_id`, they must match the document's existing field values.\n */\n patch(\n value: Partial<\n WithEdgePatches<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ): Promise<PromiseEntId<EntsDataModel, Table>>;\n\n /**\n * Replace the value of an existing document, overwriting its old value.\n *\n * @param value - The new {@link GenericDocument} for the document. This value can omit the system fields,\n * and the database will preserve them in.\n */\n replace(\n value: WithOptionalSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ): Promise<PromiseEntId<EntsDataModel, Table>>;\n\n /**\n * Delete this existing document.\n *\n * @param id - The {@link GenericId} of the document to remove.\n */\n delete(): Promise<GenericId<Table>>;\n}\n\nclass PromiseEntWriterImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends PromiseEntOrNullImpl<EntsDataModel, Table> {\n private base: WriterImplBase<EntsDataModel, Table>;\n\n constructor(\n protected db: GenericDatabaseWriter<EntsDataModel>,\n protected entDefinitions: EntsDataModel,\n protected table: Table,\n protected retrieve: DocRetriever<\n GenericId<Table> | null,\n DocumentByName<EntsDataModel, Table> | null\n >,\n protected throwIfNull: boolean\n ) {\n super(db, entDefinitions, table, retrieve, throwIfNull);\n this.base = new WriterImplBase(db, entDefinitions, table);\n }\n\n patch(\n value: Partial<\n WithEdgePatches<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ) {\n return new PromiseEntIdImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const { id: docId } = await this.retrieve();\n const id = docId!;\n await this.base.checkReadAndWriteRule(\"update\", id, value);\n await this.base.checkUniqueness(value, id);\n const fields = this.base.fieldsOnly(value);\n await this.db.patch(id, fields);\n\n const edges: EdgeChanges = {};\n await Promise.all(\n Object.keys(value).map(async (key) => {\n const edgeDefinition: EdgeConfig = (\n this.entDefinitions[this.table]\n .edges as EntsDataModel[Table][\"edges\"]\n )[key] as any;\n if (\n edgeDefinition === undefined ||\n (edgeDefinition.cardinality === \"single\" &&\n edgeDefinition.type === \"field\")\n ) {\n return;\n }\n if (edgeDefinition.cardinality === \"single\") {\n throw new Error(\"Cannot set 1:1 edge from optional end.\");\n // const existing = await this.db\n // .query(edgeDefinition.to)\n // .withIndex(edgeDefinition.ref, (q) =>\n // q.eq(edgeDefinition.ref, docId as any)\n // )\n // .unique();\n\n // edges[key] = {\n // add: value[key] as GenericId<any>,\n // remove: existing?._id as GenericId<any> | undefined,\n // };\n } else {\n edges[key] = value[key] as any;\n }\n })\n );\n await this.base.writeEdges(id, edges);\n return id;\n }\n );\n }\n\n replace(\n value: WithOptionalSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ) {\n return new PromiseEntIdImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const { id } = await this.retrieve();\n const docId = id!;\n await this.base.checkReadAndWriteRule(\"update\", docId, value);\n await this.base.checkUniqueness(value, docId);\n const fields = this.base.fieldsOnly(value as any);\n await this.db.replace(docId, fields as any);\n\n const edges: EdgeChanges = {};\n\n await Promise.all(\n Object.values(\n this.entDefinitions[this.table].edges as Record<string, EdgeConfig>\n ).map(async (edgeDefinition) => {\n const key = edgeDefinition.name;\n const idOrIds = value[key];\n if (edgeDefinition.cardinality === \"single\") {\n if (edgeDefinition.type === \"ref\") {\n const oldDoc = (await this.db.get(docId))!;\n if (oldDoc[key] !== undefined && oldDoc[key] !== idOrIds) {\n // This should be only allowed if the edge is optional\n // on the field side.\n // TODO: Write this info into the ref side of the edge in defineEntSchema.\n // TODO: Even better encode this in types so that replace\n // doesn't have this single edge in the signature.\n throw new Error(\"Cannot set 1:1 edge from optional end.\");\n // edges[key] = {\n // add: idOrIds as GenericId<any>,\n // remove: oldDoc[key] as GenericId<any> | undefined,\n // };\n }\n }\n } else {\n if (edgeDefinition.type === \"field\") {\n // TODO: Same issue around optionality as above\n const existing = (\n await this.db\n .query(edgeDefinition.to)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, docId as any)\n )\n .collect()\n ).map((doc) => doc._id);\n edges[key] = {\n add: idOrIds as GenericId<any>[],\n remove: existing as GenericId<any>[],\n };\n } else {\n const requested = new Set(idOrIds ?? []);\n const remove = (\n await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.field, (q) =>\n q.eq(edgeDefinition.field, docId as any)\n )\n .collect()\n )\n .map((doc) => [doc._id, doc[edgeDefinition.ref]] as const)\n .concat(\n edgeDefinition.symmetric\n ? (\n await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, docId as any)\n )\n .collect()\n ).map(\n (doc) => [doc._id, doc[edgeDefinition.field]] as const\n )\n : []\n )\n .filter(([_edgeId, otherId]) => {\n if (requested.has(otherId as any)) {\n requested.delete(otherId as any);\n return false;\n }\n return true;\n })\n .map(([edgeId]) => edgeId);\n edges[key] = {\n add: Array.from(requested) as GenericId<any>[],\n removeEdges: remove as GenericId<any>[],\n };\n }\n }\n })\n );\n await this.base.writeEdges(docId, edges);\n return docId;\n }\n );\n }\n\n async delete() {\n const { id: docId } = await this.retrieve();\n const id = docId!;\n await this.base.checkReadAndWriteRule(\"delete\", id, undefined);\n let memoized: GenericDocument | undefined = undefined;\n const oldDoc = async () => {\n if (memoized !== undefined) {\n return memoized;\n }\n return (memoized = (await this.db.get(id))!);\n };\n const edges: EdgeChanges = {};\n await Promise.all(\n Object.values(\n this.entDefinitions[this.table].edges as Record<string, EdgeConfig>\n ).map(async (edgeDefinition) => {\n const key = edgeDefinition.name;\n if (edgeDefinition.cardinality === \"single\") {\n if (edgeDefinition.type === \"ref\") {\n edges[key] = {\n remove: (await oldDoc())[key] as GenericId<any> | undefined,\n };\n }\n } else {\n if (edgeDefinition.type === \"field\") {\n const existing = (\n await this.db\n .query(edgeDefinition.to)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, id as any)\n )\n .collect()\n ).map((doc) => doc._id);\n edges[key] = { remove: existing as GenericId<any>[] };\n } else {\n const existing = (\n await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.field, (q) =>\n q.eq(edgeDefinition.field, id as any)\n )\n .collect()\n )\n .concat(\n edgeDefinition.symmetric\n ? await this.db\n .query(edgeDefinition.table)\n .withIndex(edgeDefinition.ref, (q) =>\n q.eq(edgeDefinition.ref, id as any)\n )\n .collect()\n : []\n )\n .map((doc) => doc._id);\n edges[key] = { removeEdges: existing as GenericId<any>[] };\n }\n }\n })\n );\n await this.db.delete(id);\n await this.base.writeEdges(id, edges);\n return id;\n }\n}\n\ndeclare class EntWriterInstance<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends EntInstance<EntsDataModel, Table> {\n /**\n * Patch this existing document, shallow merging it with the given partial\n * document.\n *\n * New fields are added. Existing fields are overwritten. Fields set to\n * `undefined` are removed.\n *\n * @param value - The partial {@link GenericDocument} to merge into this document. If this new value\n * specifies system fields like `_id`, they must match the document's existing field values.\n */\n patch(\n value: Partial<\n WithEdgePatches<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ): PromiseEntId<EntsDataModel, Table>;\n\n /**\n * Replace the value of this existing document, overwriting its old value.\n *\n * @param value - The new {@link GenericDocument} for the document. This value can omit the system fields,\n * and the database will preserve them in.\n */\n replace(\n value: WithOptionalSystemFields<\n WithEdges<\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel[Table][\"edges\"]\n >\n >\n ): PromiseEntId<EntsDataModel, Table>;\n\n /**\n * Delete this existing document.\n *\n * @param id - The {@link GenericId} of the document to remove.\n */\n delete(): Promise<GenericId<Table>>;\n}\n\n// This type is strange: The ordering is strange,\n// and the `Doc` would not have to be generic:\n// This is all just so that the type shows useful\n// informatin when hovering values.\ntype EntWriter<\n Table extends TableNamesInDataModel<EntsDataModel>,\n Doc extends DocumentByName<EntsDataModel, Table>,\n EntsDataModel extends GenericEntsDataModel\n> = Doc & EntWriterInstance<EntsDataModel, Table>;\n\nexport type GenericEntWriter<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> = EntWriter<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>;\n\nexport interface PromiseEntId<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n> extends Promise<GenericId<Table>> {\n get(): PromiseEntWriter<EntsDataModel, Table>;\n}\n\nclass PromiseEntIdImpl<\n EntsDataModel extends GenericEntsDataModel,\n Table extends TableNamesInDataModel<EntsDataModel>\n >\n extends Promise<GenericId<Table>>\n implements PromiseEntId<EntsDataModel, Table>\n{\n constructor(\n private db: GenericDatabaseWriter<EntsDataModel>,\n private entDefinitions: EntsDataModel,\n private table: Table,\n private retrieve: () => Promise<GenericId<Table>>\n ) {\n super(() => {});\n }\n\n get() {\n return new PromiseEntOrNullImpl(\n this.db,\n this.entDefinitions,\n this.table,\n async () => {\n const id = await this.retrieve();\n return { id, doc: async () => this.db.get(id) };\n },\n true\n ) as any;\n }\n\n then<TResult1 = GenericId<Table>, TResult2 = never>(\n onfulfilled?:\n | ((value: GenericId<Table>) => TResult1 | PromiseLike<TResult1>)\n | undefined\n | null,\n onrejected?:\n | ((reason: any) => TResult2 | PromiseLike<TResult2>)\n | undefined\n | null\n ): Promise<TResult1 | TResult2> {\n return this.retrieve().then(onfulfilled, onrejected);\n }\n}\n\nexport type DocRetriever<ID, Doc> = () => Promise<{\n id: ID;\n doc: () => Promise<Doc>;\n}>;\n\nconst nullRetriever = {\n id: null,\n doc: async () => null,\n};\n\n// function idRetriever<\n// DataModel extends GenericDataModel,\n// Table extends TableNamesInDataModel<DataModel>\n// >(db: GenericDatabaseReader<DataModel>, id: GenericId<Table>) {\n// return {\n// id,\n// doc: async () => db.get(id),\n// };\n// }\n\nfunction loadedRetriever<\n DataModel extends GenericDataModel,\n Table extends TableNamesInDataModel<DataModel>\n>(doc: DocumentByName<DataModel, Table> | null) {\n return {\n id: (doc?._id ?? null) as GenericId<Table> | null,\n doc: async () => doc,\n };\n}\n\ntype Rules = Record<string, RuleConfig>;\n\ntype RuleConfig = {\n read?: (doc: GenericDocument) => Promise<boolean>;\n write?: (\n args:\n | {\n operation: \"create\";\n ent: undefined;\n value: WithoutSystemFields<GenericDocument>;\n }\n | {\n operation: \"update\";\n ent: Ent<any, GenericDocument, any>;\n value: Partial<WithoutSystemFields<GenericDocument>>;\n }\n | {\n operation: \"delete\";\n ent: Ent<any, GenericDocument, any>;\n value: undefined;\n }\n ) => Promise<boolean>;\n};\n\nexport function addEntRules<EntsDataModel extends GenericEntsDataModel>(\n entDefinitions: EntsDataModel,\n rules: {\n [Table in keyof EntsDataModel]?: Table extends TableNamesInDataModel<EntsDataModel>\n ? {\n read?: (\n ent: Ent<Table, DocumentByName<EntsDataModel, Table>, EntsDataModel>\n ) => Promise<boolean>;\n write?: (\n args:\n | {\n operation: \"create\";\n ent: undefined;\n value: WithoutSystemFields<\n DocumentByName<EntsDataModel, Table>\n >;\n }\n | {\n operation: \"update\";\n ent: Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n >;\n value: Partial<\n WithoutSystemFields<DocumentByName<EntsDataModel, Table>>\n >;\n }\n | {\n operation: \"delete\";\n ent: Ent<\n Table,\n DocumentByName<EntsDataModel, Table>,\n EntsDataModel\n >;\n value: undefined;\n }\n ) => Promise<boolean>;\n }\n : never;\n }\n): EntsDataModel {\n return { ...entDefinitions, rules };\n}\n\nasync function filterByReadRule(\n db: GenericDatabaseReader<any>,\n entDefinitions: GenericEntsDataModel,\n table: string,\n docs: GenericDocument[] | null,\n throwIfNull: boolean\n) {\n if (docs === null) {\n return null;\n }\n const readPolicy = getReadRule(entDefinitions, table);\n if (readPolicy !== undefined) {\n const decisions = await Promise.all(\n docs.map(async (doc) => {\n const decision = await readPolicy(\n entWrapper(doc, db, entDefinitions, table)\n );\n if (throwIfNull && !decision) {\n throw new Error(\n `Document cannot be read with id \\`${\n doc._id as string\n }\\` in table \"${table}\"`\n );\n }\n return decision;\n })\n );\n return docs.filter((_, i) => decisions[i]);\n }\n return docs;\n}\n\nexport function getReadRule(\n entDefinitions: GenericEntsDataModel,\n table: string\n) {\n return (entDefinitions.rules as Rules)?.[table]?.read;\n}\n\nexport function getWriteRule(\n entDefinitions: GenericEntsDataModel,\n table: string\n) {\n return (entDefinitions.rules as Rules)?.[table]?.write;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAaO;AACP,oBAMO;AAEA,SAAS,gBAId,QACA,SACgD;AAGhD,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,aAAW,aAAa,YAAY;AAClC,UAAM,QAAQ,OAAO,SAAS;AAC9B,eAAW,QAAQ,6BAA6B,KAAK,GAAG;AACtD;AAAA;AAAA,QAEG,KAAK,gBAAgB,cACpB,KAAK,SAAS,SACd,KAAK,YAAY;AAAA;AAAA,QAGlB,KAAa,cAAc;AAAA,QAC5B;AACA;AAAA,MACF;AAEA,YAAM,iBAAiB,KAAK;AAC5B,YAAM,aAAa,OAAO,cAAc;AACxC,UAAI,eAAe,QAAW;AAC5B,cAAM,IAAI;AAAA,UACR,SAAS,KAAK,IAAI,eAAe,SAAS,mCACP,cAAc;AAAA,QACnD;AAAA,MACF;AAEA,YAAM,iBAAiB,KAAK,OAAO;AAEnC,YAAM,wBAAwB;AAAA,QAC5B;AAAA,MACF,EAAE,OAAO,iBAAiB,WAAW,MAAM,cAAc,CAAC;AAC1D,UAAI,sBAAsB,SAAS,GAAG;AACpC,cAAM,IAAI;AAAA,UACR,SAAS,KAAK,IAAI,eAAe,SAAS,oDACU,cAAc,MAC7D,sBACA,IAAI,CAACA,UAAS,IAAIA,MAAK,IAAI,GAAG,EAC9B,KAAK,IAAI,CAAC;AAAA,QACjB;AAAA,MACF;AACA,YAAM,cACJ,sBAAsB,CAAC;AAGzB,UAAI,KAAK,gBAAgB,YAAY,KAAK,SAAS,OAAO;AACxD,YAAI,gBAAgB,QAAW;AAC7B,gBAAM,IAAI;AAAA,YACR,kCAAkC,cAAc,KAC9C,KAAK,QAAQ,OAAO,eAAe,KAAK,GAAG,OAAO,EACpD,aAAa,KAAK,IAAI,eAAe,SAAS;AAAA,UAChD;AAAA,QACF;AACA,YACE,YAAY,gBAAgB,YAC5B,YAAY,SAAS,OACrB;AAQA,gBAAM,IAAI;AAAA,YACR,cAAc,KAAK,IAAI,eAAe,YAAY,EAAE,eACzC,YAAY,IAAI,eAAe,KAAK,EAAE;AAAA,UAEnD;AAAA,QACF;AACA,YACE,YAAY,gBAAgB,YAC5B,YAAY,SAAS,SACrB;AACA,gBAAM,IAAI;AAAA,YACR,gCAAgC,KAAK,IAAI,KAAK,aAAa,IAAI;AAAA,UACjE;AAAA,QACF;AACA,YAAI,KAAK,QAAQ,MAAM;AACrB,UAAC,KAAa,MAAM,YAAY;AAAA,QAClC;AAEA,QAAC,YAAoB,SAAS;AAAA,MAChC;AACA,UAAI,KAAK,gBAAgB,YAAY;AACnC,YAAI,CAAC,kBAAkB,gBAAgB,QAAW;AAChD,gBAAM,IAAI;AAAA,YACR,kCAAkC,cAAc,eACjC,KAAK,IAAI,eAAe,SAAS;AAAA,UAClD;AAAA,QACF;AAEA,YAAI,aAAa,gBAAgB,UAAU;AACzC,cAAI,YAAY,SAAS,OAAO;AAC9B,kBAAM,IAAI;AAAA,cACR,aAAa,YAAY,IAAI,eAAe,cAAc,kGAEzB,KAAK,IAAI,eAAe,SAAS;AAAA,YACpE;AAAA,UACF;AACA,cAAI,KAAK,SAAS,OAAO;AACvB,kBAAM,IAAI;AAAA,cACR,aAAa,YAAY,IAAI,eAAe,cAAc,sCACpB,KAAK,IAAI,eAAe,SAAS;AAAA,YAEzE;AAAA,UACF;AACA,UAAC,KAAa,OAAO;AACrB,UAAC,KAAa,MAAM,YAAY;AAAA,QAClC;AAEA,YAAI,aAAa,gBAAgB,cAAc,gBAAgB;AAC7D,cAAI,CAAC,kBAAkB,MAAM,SAAS,SAAS;AAC7C,kBAAM,IAAI;AAAA,cACR,aAAa,KAAK,IAAI,eAAe,SAAS,8CACA,YAAY,IAAI,eAC/C,cAAc;AAAA,YAC/B;AAAA,UACF;AACA,cAAI,aAAa,SAAS,SAAS;AACjC,kBAAM,IAAI;AAAA,cACR,aAAa,YAAY,IAAI,eAAe,cAAc,8CACZ,KAAK,IAAI,eACxC,SAAS;AAAA,YAC1B;AAAA,UACF;AAEA,gBAAM,gBACJ,KAAK,SAAS,SAAS,KAAK,UAAU,SAClC,KAAK,QACL,gBAAgB,SAChB,GAAG,SAAS,IAAI,KAAK,IAAI,KACzB,YAAY,SAAS,YACrB,GAAG,SAAS,IAAI,YAAY,IAAI,OAAO,KAAK,IAAI,KAChD,GAAG,YAAY,IAAI,OAAO,KAAK,IAAI;AAEzC,gBAAM,YACJ,KAAK,SAAS,SAAS,KAAK,UAAU,SAClC,KAAK,QACL,gBAAgB,SAChB,QACA,cAAc,iBACd,YAAY,OAAO,OACnB,YAAY;AAClB,gBAAM,YACJ,kBACA,KAAK,SAAS,SACd,KAAK,iBAAiB,SAClB,KAAK,eACL,gBAAgB,SAChB,QACA,YAAY,SAAS,SAAS,YAAY,UAAU,SACpD,YAAY,QACZ,cAAc,iBACd,KAAK,OAAO,OACZ,iBAAiB;AAEvB,UAAC,OAAe,aAAa,IAAI,UAAU;AAAA,YACzC,CAAC,SAAS,GAAG,gBAAE,GAAG,SAAS;AAAA,YAC3B,CAAC,SAAS,GAAG,gBAAE,GAAG,cAAc;AAAA,UAClC,CAAC,EACE,MAAM,WAAW,CAAC,WAAW,SAAS,CAAC,EACvC,MAAM,WAAW,CAAC,WAAW,SAAS,CAAC;AAE1C,UAAC,KAAa,OAAO;AACrB,UAAC,KAAa,QAAQ;AACtB,UAAC,KAAa,QAAQ;AACtB,UAAC,KAAa,MAAM;AACpB,UAAC,KAAa,YAAY,gBAAgB;AAC1C,cAAI,gBAAgB,QAAW;AAC7B,wBAAY,OAAO;AACnB,YAAC,YAAoB,QAAQ;AAC7B,YAAC,YAAoB,QAAQ;AAC7B,YAAC,YAAoB,MAAM;AAC3B,YAAC,YAAoB,YAAY;AAAA,UACnC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,aAAO,4BAAa,QAAQ,OAAO;AACrC;AAEA,SAAS,iBACP,WACA,MACA,gBACA;AACA,SAAO,CAAC,cAA2C;AACjD,QAAI,UAAU,OAAO,WAAW;AAC9B,aAAO;AAAA,IACT;AAEA,QAAI,gBAAgB;AAClB,aACE,UAAU,gBAAgB,cAC1B,UAAU,SAAS,SACnB,UAAU,YAAY,KAAK;AAAA,IAE/B;AAEA,QACG,KAAK,gBAAgB,YACpB,KAAK,SAAS,SACd,KAAK,QAAQ,QACd,KAAK,gBAAgB,cACpB,KAAK,SAAS,WACd,KAAK,QAAQ,MACf;AACA,UAAI,UAAU,gBAAgB,YAAY,UAAU,SAAS,SAAS;AACpE,eAAO,KAAK,QAAQ,UAAU;AAAA,MAChC;AAAA,IACF;AAEA,QACE,KAAK,gBAAgB,YACrB,KAAK,SAAS,WACd,KAAK,UAAU,MACf;AACA,UACG,UAAU,gBAAgB,YACzB,UAAU,SAAS,SACnB,UAAU,QAAQ,QACnB,UAAU,gBAAgB,cACzB,UAAU,SAAS,WACnB,UAAU,QAAQ,MACpB;AACA,eAAO,KAAK,UAAU,UAAU;AAAA,MAClC;AAAA,IACF;AAGA,QACE,KAAK,gBAAgB,cACrB,KAAK,SAAS,SACd,KAAK,UAAU,QACf;AACA,aACE,UAAU,gBAAgB,cAC1B,UAAU,SAAS,SACnB,KAAK,UAAU,UAAU;AAAA,IAE7B;AACA,QACE,UAAU,gBAAgB,cAC1B,UAAU,SAAS,SACnB,UAAU,UAAU,QACpB;AACA,aACE,KAAK,gBAAgB,cACrB,KAAK,SAAS,SACd,KAAK,UAAU,UAAU;AAAA,IAE7B;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,6BAA6B,OAAsB;AAC1D,SAAO,OAAO;AAAA,IACX,MAAc;AAAA,EACjB;AACF;AAEO,SAAS,UAGd,gBAIA;AACA,SAAO,IAAI,kBAAkB,cAAc;AAC7C;AA+cA,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA,EAGd,UAAmB,CAAC;AAAA;AAAA;AAAA,EAGpB,gBAA+B,CAAC;AAAA;AAAA;AAAA,EAGhC,gBAA+B,CAAC;AAAA,EAEhC;AAAA,EAEA,cAA2D,CAAC;AAAA,EAE5D,eAA4C,CAAC;AAAA,EAE7C,WAAgC,CAAC;AAAA,EAEzC,YAAY,gBAA0D;AACpE,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,MAAM,MAAW,QAAa;AAC5B,SAAK,QAAQ,KAAK,EAAE,iBAAiB,MAAM,OAAO,CAAC;AACnD,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,MAAW,aAAkB;AACvC,SAAK,cAAc,KAAK;AAAA,MACtB,iBAAiB;AAAA,MACjB,aAAa,YAAY;AAAA,MACzB,cAAc,YAAY,gBAAgB,CAAC;AAAA,IAC7C,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,MAAW,aAAkB;AACvC,SAAK,cAAc,KAAK;AAAA,MACtB,iBAAiB;AAAA,MACjB,aAAa,YAAY;AAAA,MACzB,YAAY,YAAY;AAAA,MACxB,cAAc,YAAY,gBAAgB,CAAC;AAAA,IAC7C,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS;AACP,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,eAAe,KAAK;AAAA,MACpB,eAAe,KAAK;AAAA,MACpB,cAAe,gBAAE,OAAO,KAAK,cAAc,EAAU;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAM,MAAc,WAAgB,SAA8B;AAChE,QAAI,KAAK,eAAe,IAAI,MAAM,QAAW;AAI3C,YAAM,IAAI,MAAM,oBAAoB,IAAI,GAAG;AAAA,IAC7C;AACA,UAAM,iBACJ,SAAS,YAAY,SAAY,gBAAE,SAAS,SAAS,IAAI;AAC3D,SAAK,iBAAiB,EAAE,GAAG,KAAK,gBAAgB,CAAC,IAAI,GAAG,eAAe;AACvE,QAAI,SAAS,WAAW,QAAQ,SAAS,UAAU,MAAM;AACvD,WAAK,QAAQ,KAAK,EAAE,iBAAiB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AAAA,IAC7D;AACA,QAAI,SAAS,YAAY,QAAW;AAClC,WAAK,SAAS,IAAI,IAAI,QAAQ;AAAA,IAChC;AACA,QAAI,SAAS,WAAW,MAAM;AAC5B,WAAK,aAAa,IAAI,IAAI,EAAE,MAAM,QAAQ,KAAK;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,UAAkB,SAA6B;AAClD,QAAI,KAAK,YAAY,QAAQ,MAAM,QAAW;AAI5C,YAAM,IAAI,MAAM,mBAAmB,QAAQ,GAAG;AAAA,IAChD;AACA,UAAM,KAAK,SAAS,MAAM,WAAW;AACrC,QAAI,SAAS,aAAa,MAAM;AAC9B,YAAM,YAAY,SAAS,SAAS,WAAW;AAC/C,WAAK,iBAAiB,EAAE,GAAG,KAAK,gBAAgB,CAAC,SAAS,GAAG,gBAAE,GAAG,EAAE,EAAE;AACtE,WAAK,YAAY,QAAQ,IAAI;AAAA,QAC3B,MAAM;AAAA,QACN;AAAA,QACA,aAAa;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AACA,WAAK,QAAQ,KAAK;AAAA,QAChB,iBAAiB;AAAA,QACjB,QAAQ,CAAC,SAAS;AAAA,MACpB,CAAC;AACD,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,aAAa,MAAM;AAC7B,WAAK,YAAY,QAAQ,IAAI;AAAA,QAC3B,MAAM;AAAA,QACN;AAAA,QACA,aAAa;AAAA,QACb,MAAM;AAAA,QACN,KAAK,QAAQ,OAAO;AAAA,MACtB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAc,SAA8B;AAChD,UAAM,cAAc;AACpB,UAAM,KAAK,SAAS,MAAM;AAC1B,UAAM,MAAM,SAAS;AACrB,UAAM,QAAQ,SAAS;AAGvB,QAAI,QAAQ,UAAa,UAAU,QAAW;AAC5C,YAAM,IAAI;AAAA,QACR,gJAEoC,KAAK,UAAU,OAAO,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,UAAM,QAAQ,SAAS;AACvB,UAAM,eAAe,SAAS;AAG9B,SACG,UAAU,UAAa,iBAAiB,WACzC,UAAU,QACV;AACA,YAAM,IAAI;AAAA,QACR,6GAEe,KAAK,UAAU,OAAO,CAAC;AAAA,MACxC;AAAA,IACF;AACA,UAAM,cAAc,SAAS;AAC7B,SAAK,YAAY,IAAI,IACnB,QAAQ,SACJ,EAAE,MAAM,IAAI,aAAa,MAAM,SAAS,IAAI,IAC5C,EAAE,MAAM,IAAI,aAAa,MAAM,OAAO,OAAO,OAAO,aAAa;AACvE,QAAI,gBAAgB,QAAW;AAC7B,WAAK,YAAY,WAAW,IAAI;AAAA,QAC9B,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAuIO,SAAS,kBAEd,QAA0D;AAC1D,QAAM,SAAS,OAAO;AACtB,SAAO,OAAO,KAAK,MAAM,EAAE;AAAA,IACzB,CAAC,KAAK,eAAe;AAAA,MACnB,GAAG;AAAA,MACH,CAAC,SAAS,GAAG;AAAA,QACX,UAAU,OAAO,SAAS,EAAE;AAAA,QAC5B,OAAO,OAAO,SAAS,EAAE;AAAA,QACzB,QAAQ,OAAO,SAAS,EAAE;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AACF;;;ACziCO,IAAM,iBAAN,MAGL;AAAA,EACA,YACY,IACA,gBACA,OACV;AAHU;AACA;AACA;AAAA,EACT;AAAA,EAEH,MAAM,WAAW,OAAuB,SAAsB;AAC5D,UAAM,QAAQ;AAAA,MACZ,OAAO;AAAA,QACL,KAAK,eAAe,KAAK,KAAK,EAAE;AAAA,MAClC,EAAE,IAAI,OAAO,mBAAmB;AAC9B,cAAM,UAAU,QAAQ,eAAe,IAAI;AAC3C,YAAI,YAAY,QAAW;AACzB;AAAA,QACF;AACA,YAAI,eAAe,gBAAgB,UAAU;AAC3C,cAAI,eAAe,SAAS,OAAO;AACjC,gBAAI,QAAQ,WAAW,QAAW;AAGhC,oBAAM,KAAK,GAAG,OAAO,QAAQ,MAAwB;AAAA,YACvD;AACA,gBAAI,QAAQ,QAAQ,QAAW;AAC7B,oBAAM,KAAK,GAAG;AAAA,gBACZ,QAAQ;AAAA,gBACR,EAAE,CAAC,eAAe,GAAG,GAAG,MAAM;AAAA,cAChC;AAAA,YACF;AAAA,UACF;AAAA,QACF,OAAO;AACL,cAAI,eAAe,SAAS,SAAS;AACnC,gBAAI,QAAQ,WAAW,QAAW;AAGhC,oBAAM,QAAQ;AAAA,gBACX,QAAQ,OAA4B;AAAA,kBAAI,CAAC,OACxC,KAAK,GAAG,OAAO,EAAE;AAAA,gBACnB;AAAA,cACF;AAAA,YASF;AACA,gBAAI,QAAQ,QAAQ,QAAW;AAC7B,oBAAM,QAAQ;AAAA,gBACX,QAAQ,IAAyB;AAAA,kBAAI,OAAO,OAC3C,KAAK,GAAG,MAAM,IAAI;AAAA,oBAChB,CAAC,eAAe,GAAG,GAAG;AAAA,kBACxB,CAAQ;AAAA,gBACV;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AACL,gBAAI,cAAgC,CAAC;AACrC,gBAAI,QAAQ,WAAW,QAAW;AAChC,6BACE,MAAM,QAAQ;AAAA,gBACX,QAAQ,OAA4B;AAAA,kBAAI,OAAO,QAE5C,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,oBAAU,eAAe;AAAA,oBAAO,CAAC,MAC/B,EAAE,GAAG,eAAe,OAAO,KAAY,EAAU;AAAA,sBAChD,eAAe;AAAA,sBACf;AAAA,oBACF;AAAA,kBACF,EACC,QAAQ,GACX;AAAA,oBACA,eAAe,YACX,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,sBAAU,eAAe;AAAA,sBAAK,CAAC,MAE5B,EAAE,GAAG,eAAe,KAAK,KAAY,EACrC,GAAG,eAAe,OAAO,EAAE;AAAA,oBAC/B,EACC,QAAQ,IACX,CAAC;AAAA,kBACP;AAAA,gBACF;AAAA,cACF,GACA,IAAI,CAAC,QAAS,IAAY,GAAG;AAAA,YACjC;AACA,gBAAI,QAAQ,gBAAgB,QAAW;AACrC,4BAAc,QAAQ;AAAA,YACxB;AACA,gBAAI,YAAY,SAAS,GAAG;AAC1B,oBAAM,QAAQ;AAAA,gBACZ,YAAY,IAAI,OAAO,OAAO;AAC5B,sBAAI;AACF,0BAAM,KAAK,GAAG,OAAO,EAAE;AAAA,kBACzB,SAAS,GAAG;AAAA,kBASZ;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAEA,gBAAI,QAAQ,QAAQ,QAAW;AAC7B,oBAAM,QAAQ;AAAA,gBACX,QAAQ,IAAyB,IAAI,OAAO,OAAO;AAClD,wBAAM,KAAK,GAAG,OAAO,eAAe,OAAO;AAAA,oBACzC,CAAC,eAAe,KAAK,GAAG;AAAA,oBACxB,CAAC,eAAe,GAAG,GAAG;AAAA,kBACxB,CAAQ;AACR,sBAAI,eAAe,WAAW;AAC5B,0BAAM,KAAK,GAAG,OAAO,eAAe,OAAO;AAAA,sBACzC,CAAC,eAAe,KAAK,GAAG;AAAA,sBACxB,CAAC,eAAe,GAAG,GAAG;AAAA,oBACxB,CAAQ;AAAA,kBACV;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,OAAiC,IAAqB;AAC1E,UAAM,QAAQ;AAAA,MACZ,OAAO;AAAA,QACJ,KAAK,eAAe,KAAK,KAAK,EAAU;AAAA,MAI3C,EAAE,IAAI,OAAO,oBAAoB;AAC/B,YAAI,gBAAgB,QAAQ;AAC1B,gBAAM,MAAM,gBAAgB;AAC5B,gBAAM,aAAa,MAAM,GAAG;AAC5B,gBAAM,WAAW,MAAM,KAAK,GACzB,MAAM,KAAK,KAAK,EAChB,UAAU,KAAK,CAAC,MAAM,EAAE,GAAG,KAAK,MAAM,GAAG,CAAQ,CAAC,EAClD,OAAO;AACV,cAAI,aAAa,SAAS,OAAO,UAAa,SAAS,QAAQ,KAAK;AAClE,kBAAM,IAAI;AAAA,cACR,aACE,KAAK,KACP,oDAAoD,GAAG,gBACrD,UACF,kCACE,SAAS,GACX;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,QAAQ;AAAA,MACZ,OAAO;AAAA,QACL,KAAK,eAAe,KAAK,KAAK,EAAE;AAAA,MAClC,EAAE,IAAI,OAAO,mBAAmB;AAC9B,YACE,eAAe,gBAAgB,YAC/B,eAAe,SAAS,WACxB,eAAe,QACf;AACA,gBAAM,MAAM,eAAe;AAC3B,cAAI,MAAM,GAAG,MAAM,QAAW;AAC5B;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,KAAK,GACzB,MAAM,KAAK,KAAK,EAChB,UAAU,KAAK,CAAC,MAAM,EAAE,GAAG,KAAK,MAAM,GAAG,CAAQ,CAAC,EAClD,OAAO;AACV,cAAI,aAAa,SAAS,OAAO,UAAa,SAAS,QAAQ,KAAK;AAClE,kBAAM,IAAI;AAAA,cACR,aAAa,KAAK,KAAK,yCACrB,eAAe,IACjB,YAAY,MAAM,GAAG,CAAW,iCAC9B,SAAS,GACX;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,WACE,OAMA;AACA,UAAM,SAA0B,CAAC;AACjC,WAAO,KAAK,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAClC,YAAM,iBACJ,KAAK,eAAe,KAAK,KAAK,EAAE,MAChC,GAAG;AACL,UACE,mBAAmB,QAKnB;AACA,eAAO,GAAG,IAAI,MAAM,GAAG;AAAA,MACzB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,sBACJ,WACA,IACA,OACA;AACA,QAAI,OAAO,QAAW;AACpB,YAAM,aAAa,YAAY,KAAK,gBAAgB,KAAK,KAAK;AAC9D,UAAI,eAAe,QAAW;AAC5B,cAAM,MAAM,MAAM,KAAK,GAAG,IAAI,EAAE;AAChC,YAAI,QAAQ,MAAM;AAChB,gBAAM,IAAI;AAAA,YACR,mCAAmC,EAAE,eAAe,KAAK,KAAK;AAAA,UAChE;AAAA,QACF;AACA,cAAMC,YAAW,MAAM,WAAW,GAAG;AACrC,YAAI,CAACA,WAAU;AACb,gBAAM,IAAI;AAAA,YACR,mCAAmC,EAAE,iBAAiB,KAAK,KAAK;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,aAAa,KAAK,gBAAgB,KAAK,KAAK;AAChE,QAAI,gBAAgB,QAAW;AAC7B;AAAA,IACF;AACA,UAAM,MACJ,OAAO,SACH,SACA;AAAA,MACG,MAAM,KAAK,GAAG,IAAI,EAAE;AAAA,MACrB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAGN,UAAM,EAAE,KAAK,eAAe,GAAG,UAAU,IAAI,SAAS,CAAC;AACvD,UAAM,WAAW,MAAM,YAAY;AAAA,MACjC;AAAA,MACA;AAAA,MACA,OAAO,UAAU,SAAa,YAAoB;AAAA,IACpD,CAAC;AACD,QAAI,CAAC,UAAU;AACb,UAAI,OAAO,QAAW;AACpB,cAAM,IAAI;AAAA,UACR,6BAA6B,KAAK,KAAK,QAAQ,KAAK;AAAA,YAClD;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,WAAW,UAAU,QAAW;AAC9B,cAAM,IAAI;AAAA,UACR,6BAA6B,KAAK,KAAK,cAAc,EAAE;AAAA,QACzD;AAAA,MACF,OAAO;AACL,cAAM,IAAI;AAAA,UACR,mCAAmC,EAAE,eACnC,KAAK,KACP,aAAa,KAAK,UAAU,KAAK,CAAC;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AClDA,IAAM,yBAAN,MAAM,gCAII,QAIV;AAAA,EACE,YACY,IACA,gBACA,OACA,UAGV;AACA,UAAM,MAAM;AAAA,IAAC,CAAC;AAPJ;AACA;AACA;AACA;AAAA,EAKZ;AAAA,EAEA,OACE,WAGK;AACL,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,YAAI,UAAU,MAAM;AAClB,iBAAO;AAAA,QACT;AACA,eAAO,MAAM,OAAO,SAAS;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,YAKA;AACA,UAAM,QAAQ,MAAM;AACpB,QAAI,UAAU,MAAM;AAClB,aAAO,CAAC;AAAA,IACV;AACA,WAAO,MAAM,QAAQ,IAAI,MAAM,IAAI,UAAU,CAAC;AAAA,EAChD;AAAA,EAEA,MACE,OACA,WACK;AACL,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,YAAI,UAAU,MAAM;AAClB,iBAAO;AAAA,QACT;AACA,YAAI,cAAc,QAAW;AAC3B,iBACE,MAEC,UAAU,SAAS,EACnB,MAAM,KAAK;AAAA,QAChB;AACA,eAAO,MAAM,MAAM,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SACJ,gBACwE;AACxE,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAI,UAAU,MAAM;AAClB,aAAO;AAAA,IACT;AACA,WAAO,MAAM,MAAM,SAAS,cAAc;AAAA,EAC5C;AAAA,EAEA,KAAK,GAAW;AACd,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,eAAO,MAAM,KAAK,MAAM,CAAC;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,MAAM,CAAC;AAC/B,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,cAAM,CAAC,GAAG,IAAI;AACd,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,MAAM,CAAC;AAC/B,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,cAAM,CAAC,GAAG,IAAI;AACd,YAAI,QAAQ,QAAW;AACrB,gBAAM,IAAI,MAAM,6BAA6B;AAAA,QAC/C;AACA,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,MAAM,CAAC;AAC/B,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,WAAW,GAAG;AACrB,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,WAAW,GAAG;AACrB,gBAAM,IAAI,MAAM,8CAA8C;AAAA,QAChE;AACA,cAAM,CAAC,GAAG,IAAI;AACd,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AACR,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,MAAM,CAAC;AAC/B,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,WAAW,GAAG;AACrB,gBAAM,IAAI,MAAM,6BAA6B;AAAA,QAC/C;AACA,YAAI,KAAK,WAAW,GAAG;AACrB,gBAAM,IAAI,MAAM,8CAA8C;AAAA,QAChE;AACA,cAAM,CAAC,GAAG,IAAI;AACd,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO;AACX,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAI,UAAU,MAAM;AAClB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,MAAM,MAAM,QAAQ;AACjC,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAME,aAQA,YAI8B;AAC9B,WAAO,KAAK,KAAK,EACd;AAAA,MAAK,CAAC,cACL,cAAc,OACV,OACA,UAAU;AAAA,QAAI,CAAC,QACb,WAAW,KAAK,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK;AAAA,MAC1D;AAAA,IACN,EACC,KAAK,aAAa,UAAU;AAAA,EACjC;AAAA,EAEA,MAAM,MAAM,GAAW;AACrB,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAI,UAAU,MAAM;AAClB,aAAO;AAAA,IACT;AACA,UAAM,aAAa,YAAY,KAAK,gBAAgB,KAAK,KAAK;AAC9D,QAAI,eAAe,QAAW;AAC5B,aAAO,MAAM,MAAM,KAAK,CAAC;AAAA,IAC3B;AACA,QAAI,WAAW;AACf,UAAM,OAAO,CAAC;AACd,QAAI,UAAU;AACd,UAAM,WAAW,MAAM,OAAO,aAAa,EAAE;AAC7C,WAAO,WAAW,KAAK,SAAS,GAAG;AACjC,YAAM,OAAO,CAAC;AACd,eAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,SAAS,KAAK;AAC5C,YAAI,MAAM;AACR,oBAAU;AACV;AAAA,QACF;AACA,aAAK,KAAK,KAAK;AAAA,MACjB;AACA,WAAK;AAAA,QACH,IAAI,MAAM;AAAA,UACR,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACF,GAAI,MAAM,GAAG,IAAI,KAAK,MAAM;AAAA,MAC9B;AACA,iBAAW,KAAK,IAAI,IAAI,WAAW,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,mBAAN,cAGU,uBAA6C;AAAA,EACrD,YACE,IACA,gBACA,OACA;AACA,UAAM,IAAI,gBAAgB,OAAO,YAAY,GAAG,MAAM,KAAK,CAAC;AAAA,EAC9D;AAAA,EAEA,OAAO,MAAa;AAClB,WAAO,KAAK,QAAQ,IAAI;AAAA,EAC1B;AAAA,EAEA,QAAQ,MAAa;AACnB,WAAO,KAAK,QAAQ,MAAM,IAAI;AAAA,EAChC;AAAA,EAEA,WAAW,MAAa;AACtB,WAAO,KAAK,YAAY,IAAI;AAAA,EAC9B;AAAA,EAEA,YAAY,MAAa;AACvB,WAAO,KAAK,YAAY,MAAM,IAAI;AAAA,EACpC;AAAA,EAEA,QAAQ,MAAa,cAAc,OAAO;AACxC,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,WAAW,IACZ,YAAY;AACV,cAAM,KAAK,KAAK,CAAC;AACjB,YAAI,KAAK,GAAG,YAAY,KAAK,OAAO,EAAE,MAAM,MAAM;AAChD,gBAAM,IAAI,MAAM,gBAAgB,EAAE,iBAAiB,KAAK,KAAK,GAAG;AAAA,QAClE;AACA,eAAO;AAAA,UACL;AAAA,UACA,KAAK,YAAY;AACf,kBAAM,MAAM,MAAM,KAAK,GAAG,IAAI,EAAE;AAChC,gBAAI,eAAe,QAAQ,MAAM;AAC/B,oBAAM,IAAI;AAAA,gBACR,gCAAgC,EAAE,gBAAgB,KAAK,KAAK;AAAA,cAC9D;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,IACA,YAAY;AACV,cAAM,CAAC,WAAW,KAAK,IAAI;AAC3B,cAAM,MAAM,MAAM,KAAK,GACpB,MAAM,KAAK,KAAK,EAChB,UAAU,WAAW,CAAC,MAAM,EAAE,GAAG,WAAW,KAAK,CAAC,EAClD,OAAO;AACV,YAAI,eAAe,QAAQ,MAAM;AAC/B,gBAAM,IAAI;AAAA,YACR,UAAU,KAAK,KAAK,2CAA2C,SAAS,SAAS,KAAK;AAAA,UACxF;AAAA,QACF;AACA,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,MAAa,cAAc,OAAO;AAC5C,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,WAAW,IACZ,YAAY;AACV,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,QAAQ,CAAC,OAAO;AAClB,cAAI,KAAK,GAAG,YAAY,KAAK,OAAO,EAAE,MAAM,MAAM;AAChD,kBAAM,IAAI;AAAA,cACR,gBAAgB,EAAE,iBAAiB,KAAK,KAAK;AAAA,YAC/C;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO,MAAM,QAAQ;AAAA,UACnB,IAAI,IAAI,OAAO,OAAO;AACpB,kBAAM,MAAM,MAAM,KAAK,GAAG,IAAI,EAAE;AAChC,gBAAI,QAAQ,MAAM;AAChB,oBAAM,IAAI;AAAA,gBACR,gCAAgC,EAAE,gBAAgB,KAAK,KAAK;AAAA,cAC9D;AAAA,YACF;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF,IACA,YAAY;AACV,cAAM,CAAC,WAAW,MAAM,IAAI;AAC5B,eAAQ,MAAM,QAAQ;AAAA,UACnB,OAAiB,IAAI,OAAO,UAAU;AACrC,kBAAM,MAAM,MAAM,KAAK,GACpB,MAAM,KAAK,KAAK,EAChB,UAAU,WAAW,CAAC,MAAM,EAAE,GAAG,WAAW,KAAK,CAAC,EAClD,OAAO;AACV,gBAAI,eAAe,QAAQ,MAAM;AAC/B,oBAAM,IAAI;AAAA,gBACR,UAAU,KAAK,KAAK,2CAA2C,SAAS,SAAS,KAAK;AAAA,cACxF;AAAA,YACF;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,IAAqC;AAC/C,WAAO,KAAK,GAAG,YAAY,KAAK,OAAO,EAAE;AAAA,EAC3C;AAAA;AAAA,EAGA,aAAa,IAA8B;AACzC,UAAM,aAAa,KAAK,YAAY,EAAE;AACtC,QAAI,eAAe,MAAM;AACvB,YAAM,IAAI,MAAM,gBAAgB,EAAE,iBAAiB,KAAK,KAAK,GAAG;AAAA,IAClE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UACE,WACA,YAMA;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,eACE,MACA,UAAU,WAAW,UAAU;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAGE,WACA,cAMA;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,eACE,MACA,gBAAgB,WAAW,YAAY;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;AAsEA,IAAM,wBAAN,cAIU,QAIV;AAAA,EACE,YACU,IACA,gBACA,OACA,UAGA,aACR;AACA,UAAM,MAAM;AAAA,IAAC,CAAC;AARN;AACA;AACA;AACA;AAGA;AAAA,EAGV;AAAA,EAEA,MAAM,IACJ,YAKA;AACA,UAAM,QAAQ,MAAM;AACpB,QAAI,UAAU,MAAM;AAClB,aAAO,CAAC;AAAA,IACV;AACA,WAAO,MAAM,QAAQ,IAAI,MAAM,IAAI,UAAU,CAAC;AAAA,EAChD;AAAA,EAEA,QAAQ;AACN,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,SAAS;AACjC,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,eAAO,gBAAgB,KAAK,CAAC,KAAK,IAAI;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,SAAS;AACjC,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,cAAM,MAAM,KAAK,CAAC,KAAK;AACvB,YAAI,QAAQ,QAAW;AACrB,gBAAM,IAAI,MAAM,6BAA6B;AAAA,QAC/C;AACA,eAAO,gBAAgB,GAAG;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,SAAS;AACjC,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,SAAS,GAAG;AACnB,gBAAM,IAAI,MAAM,8CAA8C;AAAA,QAChE;AACA,eAAO,gBAAgB,KAAK,CAAC,KAAK,IAAI;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AACR,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,OAAO,MAAM,KAAK,SAAS;AACjC,YAAI,SAAS,MAAM;AACjB,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,SAAS,GAAG;AACnB,gBAAM,IAAI,MAAM,8CAA8C;AAAA,QAChE;AACA,YAAI,KAAK,SAAS,GAAG;AACnB,gBAAM,IAAI,MAAM,sCAAsC;AAAA,QACxD;AACA,eAAO,gBAAgB,KAAK,CAAC,CAAC;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO;AACX,UAAM,OAAO,MAAM,KAAK,SAAS;AACjC,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,KAME,aAQA,YAI8B;AAC9B,WAAO,KAAK,KAAK,EACd;AAAA,MAAK,CAAC,SACL,SAAS,OACL,OACA,KAAK;AAAA,QAAI,CAAC,QACR,WAAW,KAAK,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK;AAAA,MAC1D;AAAA,IACN,EACC,KAAK,aAAa,UAAU;AAAA,EACjC;AACF;AAqCA,IAAM,wBAAN,cAIU,sBAEV;AAAA,EACE,YACE,IACA,gBACA,OACQ,OACA,eAKR;AACA,UAAM,IAAI,gBAAgB,OAAO,MAAM,cAAc,CAAC,MAAM,CAAC,GAAG,KAAK;AAP7D;AACA;AAAA,EAOV;AAAA,EAEA,MAAM,IAAI,IAAsB;AAC9B,UAAM,OAAO,MAAM,KAAK,cAAc,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,EAAS,CAAC;AACxE,YAAQ,MAAM,UAAU,KAAK;AAAA,EAC/B;AACF;AAkCA,IAAM,uBAAN,MAAM,8BAII,QAMV;AAAA,EACE,YACY,IACA,gBACA,OACA,UAIA,aACV;AACA,UAAM,MAAM;AAAA,IAAC,CAAC;AATJ;AACA;AACA;AACA;AAIA;AAAA,EAGZ;AAAA,EAEA,MAAM,MAAM;AACV,UAAM,EAAE,IAAI,KAAK,OAAO,IAAI,MAAM,KAAK,SAAS;AAChD,QAAI,OAAO,MAAM;AACf,aAAO;AAAA,IACT;AACA,UAAM,MAAM,MAAM,OAAO;AACzB,QAAI,QAAQ,MAAM;AAChB,aAAO;AAAA,IACT;AACA,UAAM,aAAa,YAAY,KAAK,gBAAgB,KAAK,KAAK;AAC9D,QAAI,eAAe,QAAW;AAC5B,YAAM,WAAW,MAAM;AAAA,QACrB,WAAW,KAAK,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK;AAAA,MAC1D;AACA,UAAI,KAAK,eAAe,CAAC,UAAU;AACjC,cAAM,IAAI;AAAA,UACR,qCAAqC,IAAI,GAAa,gBACpD,KAAK,KACP;AAAA,QACF;AAAA,MACF;AACA,aAAO,WAAW,MAAM;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAQE,aAUA,YAI8B;AAC9B,WAAO,KAAK,IAAI,EACb;AAAA,MAAK,CAAC,QACL,QAAQ,OACJ,OACA,WAAW,KAAK,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK;AAAA,IAC9D,EACC,KAAK,aAAa,UAAU;AAAA,EACjC;AAAA,EAEA,KAAuD,MAAY;AACjE,WAAO,KAAK,SAAS,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAwD,MAAY;AAClE,WAAO,KAAK,SAAS,MAAM,IAAI;AAAA,EACjC;AAAA,EAEA,SACE,MACA,cAAc,OACd;AACA,UAAM,iBACJ,KAAK,eAAe,KAAK,KAAK,EAAE,MAChC,IAAI;AAEN,QAAI,eAAe,gBAAgB,YAAY;AAC7C,UAAI,eAAe,SAAS,OAAO;AACjC,eAAO,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL,eAAe;AAAA,UACf,eAAe;AAAA,UACf,OAAO,eAAe;AACpB,kBAAM,EAAE,GAAG,IAAI,MAAM,KAAK,SAAS;AACnC,gBAAI,OAAO,MAAM;AACf,qBAAO;AAAA,YACT;AACA,kBAAM,WAAW,MAAM,KAAK,GACzB,MAAM,eAAe,KAAK,EAC1B;AAAA,cAAU,eAAe;AAAA,cAAO,CAAC,MAChC,WAAW,EAAE,GAAG,eAAe,OAAO,EAAS,CAAQ;AAAA,YACzD,EACC,QAAQ;AACX,oBACE,MAAM,QAAQ;AAAA,cACZ,SAAS;AAAA,gBAAI,CAAC,YACZ,KAAK,GAAG,IAAI,QAAQ,eAAe,GAAG,CAAQ;AAAA,cAChD;AAAA,YACF,GACA,OAAO,CAAS,KAAoB,MAA6B;AACjE,kBAAI,QAAQ,MAAM;AAChB,sBAAM,IAAI;AAAA,kBACR,gCAAgC,eAAe,IAAI,eACvC,KAAK,KAAK,2BAA2B,EAAE,yCAE/C,SAAS,CAAC,EAAE,eAAe,KAAK,CAClC,eACc,eAAe,EAAE,2BAC7B,SAAS,CAAC,EAAE,GACd;AAAA,gBACJ;AAAA,cACF;AACA,qBAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,QACL,eAAe;AAAA,QACf,YAAY;AACV,gBAAM,EAAE,GAAG,IAAI,MAAM,KAAK,SAAS;AACnC,cAAI,OAAO,MAAM;AACf,mBAAO;AAAA,UACT;AACA,iBAAO,KAAK,GACT,MAAM,eAAe,EAAE,EACvB;AAAA,YAAU,eAAe;AAAA,YAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,EAAS;AAAA,UACpC;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAEA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,eAAe;AAAA,MACf,YAAY;AACV,cAAM,EAAE,IAAI,KAAK,OAAO,IAAI,MAAM,KAAK,SAAS;AAChD,YAAI,OAAO,MAAM;AACf,iBAAO;AAAA,QACT;AAEA,YAAI,eAAe,SAAS,OAAO;AACjC,gBAAM,WAAW,MAAM,KAAK,GACzB,MAAM,eAAe,EAAE,EACvB;AAAA,YAAU,eAAe;AAAA,YAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,EAAS;AAAA,UACpC,EACC,OAAO;AACV,cAAI,eAAe,aAAa,MAAM;AACpC,kBAAM,IAAI;AAAA,cACR,SACE,eAAe,IACjB,0CAA0C,EAAY;AAAA,YACxD;AAAA,UACF;AACA,iBAAO,gBAAgB,QAAQ;AAAA,QACjC;AACA,cAAM,MAAO,MAAM,OAAO;AAC1B,cAAM,UAAU,IAAI,eAAe,KAAK;AACxC,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,KAAK,YAAY;AACf,kBAAM,WAAW,MAAM,KAAK,GAAG,IAAI,OAAO;AAC1C,gBAAI,aAAa,MAAM;AACrB,oBAAM,IAAI;AAAA,gBACR,gCAAgC,eAAe,IAAI,eACvC,KAAK,KAAK,2BAA2B,EAAE,yCACX,OAAO,eAC/B,eAAe,EAAE;AAAA,cACnC;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,WAId,QACA,IACA,gBACA,OACiE;AACjE,QAAM,MAAM,EAAE,GAAG,OAAO;AACxB,QAAM,iBAAiB,IAAI;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,EAAE,IAAI,IAAI,KAAY,KAAK,YAAY,IAAI;AAAA;AAAA,IAExD;AAAA,EACF;AACA,SAAO,eAAe,KAAK,QAAQ;AAAA,IACjC,OAAO,CAAC,SAAc;AACpB,aAAO,eAAe,KAAK,IAAI;AAAA,IACjC;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,SAAO,eAAe,KAAK,SAAS;AAAA,IAClC,OAAO,CAAC,SAAc;AACpB,aAAO,eAAe,MAAM,IAAI;AAAA,IAClC;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,SAAO,eAAe,KAAK,SAAS;AAAA,IAClC,OAAO,CAAC,UAAe;AACrB,aAAO,eAAe,MAAM,KAAK;AAAA,IACnC;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,SAAO,eAAe,KAAK,WAAW;AAAA,IACpC,OAAO,CAAC,UAAe;AACrB,aAAO,eAAe,QAAQ,KAAK;AAAA,IACrC;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,SAAO,eAAe,KAAK,UAAU;AAAA,IACnC,OAAO,MAAM;AACX,aAAO,eAAe,OAAO;AAAA,IAC/B;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AACD,SAAO,QAAS,eAAuB,KAAK,EAAE,QAAQ,EAAE;AAAA,IACtD,CAAC,CAAC,OAAO,KAAK,MAAM;AAClB,UAAI,IAAI,KAAK,MAAM,QAAW;AAC5B,QAAC,IAAY,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iBAId,IACA,gBAG2B;AAC3B,SAAO,CACL,OACA,WACA,eACG;AAOH,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,MAAM,8BAA8B,KAAY,IAAI;AAAA,IAChE;AACA,QAAI,cAAc,QAAW;AAC3B,aAAO,IAAI,iBAAiB,IAAI,gBAAgB,KAAK,EAAE;AAAA,QACrD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAK,GAAW,WAAW,QAAW;AACpC,aAAO,IAAI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,iBAAiB,IAAI,gBAAgB,KAAK;AAAA,EACvD;AACF;AAoQA,IAAM,yBAAN,cAGU,iBAAuC;AAAA,EAG/C,YACY,IACV,gBACA,OACA;AACA,UAAM,IAAI,gBAAgB,KAAK;AAJrB;AAKV,SAAK,OAAO,IAAI,eAAe,IAAI,gBAAgB,KAAK;AAAA,EAC1D;AAAA,EATQ;AAAA,EAWR,OACE,OAMA;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,KAAK,KAAK,sBAAsB,UAAU,QAAW,KAAK;AAChE,cAAM,KAAK,KAAK,gBAAgB,KAAK;AACrC,cAAM,SAAS,KAAK,KAAK,WAAW,KAAY;AAChD,cAAM,QAAQ,MAAM,KAAK,GAAG,OAAO,KAAK,OAAO,MAAa;AAC5D,cAAM,QAAqB,CAAC;AAC5B,eAAO,KAAK,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAClC,gBAAM,iBACJ,KAAK,eAAe,KAAK,KAAK,EAC3B,MACH,GAAG;AACL,cACE,mBAAmB,UAClB,eAAe,gBAAgB,YAC9B,eAAe,SAAS,SAC1B;AACA;AAAA,UACF;AACA,cAAI,eAAe,gBAAgB,UAAU;AAC3C,kBAAM,IAAI,MAAM,wCAAwC;AAAA,UAC1D;AACA,gBAAM,GAAG,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE;AAAA,QACjC,CAAC;AACD,cAAM,KAAK,KAAK,WAAW,OAAO,KAAK;AACvC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WACJ,QAMA;AACA,WAAO,MAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,OAAO,KAAK,CAAC,CAAC;AAAA,EACpE;AACF;AA2EA,IAAM,uBAAN,cAGU,qBAA2C;AAAA,EAGnD,YACY,IACA,gBACA,OACA,UAIA,aACV;AACA,UAAM,IAAI,gBAAgB,OAAO,UAAU,WAAW;AAT5C;AACA;AACA;AACA;AAIA;AAGV,SAAK,OAAO,IAAI,eAAe,IAAI,gBAAgB,KAAK;AAAA,EAC1D;AAAA,EAdQ;AAAA,EAgBR,MACE,OAMA;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,EAAE,IAAI,MAAM,IAAI,MAAM,KAAK,SAAS;AAC1C,cAAM,KAAK;AACX,cAAM,KAAK,KAAK,sBAAsB,UAAU,IAAI,KAAK;AACzD,cAAM,KAAK,KAAK,gBAAgB,OAAO,EAAE;AACzC,cAAM,SAAS,KAAK,KAAK,WAAW,KAAK;AACzC,cAAM,KAAK,GAAG,MAAM,IAAI,MAAM;AAE9B,cAAM,QAAqB,CAAC;AAC5B,cAAM,QAAQ;AAAA,UACZ,OAAO,KAAK,KAAK,EAAE,IAAI,OAAO,QAAQ;AACpC,kBAAM,iBACJ,KAAK,eAAe,KAAK,KAAK,EAC3B,MACH,GAAG;AACL,gBACE,mBAAmB,UAClB,eAAe,gBAAgB,YAC9B,eAAe,SAAS,SAC1B;AACA;AAAA,YACF;AACA,gBAAI,eAAe,gBAAgB,UAAU;AAC3C,oBAAM,IAAI,MAAM,wCAAwC;AAAA,YAY1D,OAAO;AACL,oBAAM,GAAG,IAAI,MAAM,GAAG;AAAA,YACxB;AAAA,UACF,CAAC;AAAA,QACH;AACA,cAAM,KAAK,KAAK,WAAW,IAAI,KAAK;AACpC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QACE,OAMA;AACA,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,EAAE,GAAG,IAAI,MAAM,KAAK,SAAS;AACnC,cAAM,QAAQ;AACd,cAAM,KAAK,KAAK,sBAAsB,UAAU,OAAO,KAAK;AAC5D,cAAM,KAAK,KAAK,gBAAgB,OAAO,KAAK;AAC5C,cAAM,SAAS,KAAK,KAAK,WAAW,KAAY;AAChD,cAAM,KAAK,GAAG,QAAQ,OAAO,MAAa;AAE1C,cAAM,QAAqB,CAAC;AAE5B,cAAM,QAAQ;AAAA,UACZ,OAAO;AAAA,YACL,KAAK,eAAe,KAAK,KAAK,EAAE;AAAA,UAClC,EAAE,IAAI,OAAO,mBAAmB;AAC9B,kBAAM,MAAM,eAAe;AAC3B,kBAAM,UAAU,MAAM,GAAG;AACzB,gBAAI,eAAe,gBAAgB,UAAU;AAC3C,kBAAI,eAAe,SAAS,OAAO;AACjC,sBAAM,SAAU,MAAM,KAAK,GAAG,IAAI,KAAK;AACvC,oBAAI,OAAO,GAAG,MAAM,UAAa,OAAO,GAAG,MAAM,SAAS;AAMxD,wBAAM,IAAI,MAAM,wCAAwC;AAAA,gBAK1D;AAAA,cACF;AAAA,YACF,OAAO;AACL,kBAAI,eAAe,SAAS,SAAS;AAEnC,sBAAM,YACJ,MAAM,KAAK,GACR,MAAM,eAAe,EAAE,EACvB;AAAA,kBAAU,eAAe;AAAA,kBAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,KAAY;AAAA,gBACvC,EACC,QAAQ,GACX,IAAI,CAAC,QAAQ,IAAI,GAAG;AACtB,sBAAM,GAAG,IAAI;AAAA,kBACX,KAAK;AAAA,kBACL,QAAQ;AAAA,gBACV;AAAA,cACF,OAAO;AACL,sBAAM,YAAY,IAAI,IAAI,WAAW,CAAC,CAAC;AACvC,sBAAM,UACJ,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,kBAAU,eAAe;AAAA,kBAAO,CAAC,MAChC,EAAE,GAAG,eAAe,OAAO,KAAY;AAAA,gBACzC,EACC,QAAQ,GAEV,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,eAAe,GAAG,CAAC,CAAU,EACxD;AAAA,kBACC,eAAe,aAET,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,oBAAU,eAAe;AAAA,oBAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,KAAY;AAAA,kBACvC,EACC,QAAQ,GACX;AAAA,oBACA,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,eAAe,KAAK,CAAC;AAAA,kBAC9C,IACA,CAAC;AAAA,gBACP,EACC,OAAO,CAAC,CAAC,SAAS,OAAO,MAAM;AAC9B,sBAAI,UAAU,IAAI,OAAc,GAAG;AACjC,8BAAU,OAAO,OAAc;AAC/B,2BAAO;AAAA,kBACT;AACA,yBAAO;AAAA,gBACT,CAAC,EACA,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM;AAC3B,sBAAM,GAAG,IAAI;AAAA,kBACX,KAAK,MAAM,KAAK,SAAS;AAAA,kBACzB,aAAa;AAAA,gBACf;AAAA,cACF;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AACA,cAAM,KAAK,KAAK,WAAW,OAAO,KAAK;AACvC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS;AACb,UAAM,EAAE,IAAI,MAAM,IAAI,MAAM,KAAK,SAAS;AAC1C,UAAM,KAAK;AACX,UAAM,KAAK,KAAK,sBAAsB,UAAU,IAAI,MAAS;AAC7D,QAAI,WAAwC;AAC5C,UAAM,SAAS,YAAY;AACzB,UAAI,aAAa,QAAW;AAC1B,eAAO;AAAA,MACT;AACA,aAAQ,WAAY,MAAM,KAAK,GAAG,IAAI,EAAE;AAAA,IAC1C;AACA,UAAM,QAAqB,CAAC;AAC5B,UAAM,QAAQ;AAAA,MACZ,OAAO;AAAA,QACL,KAAK,eAAe,KAAK,KAAK,EAAE;AAAA,MAClC,EAAE,IAAI,OAAO,mBAAmB;AAC9B,cAAM,MAAM,eAAe;AAC3B,YAAI,eAAe,gBAAgB,UAAU;AAC3C,cAAI,eAAe,SAAS,OAAO;AACjC,kBAAM,GAAG,IAAI;AAAA,cACX,SAAS,MAAM,OAAO,GAAG,GAAG;AAAA,YAC9B;AAAA,UACF;AAAA,QACF,OAAO;AACL,cAAI,eAAe,SAAS,SAAS;AACnC,kBAAM,YACJ,MAAM,KAAK,GACR,MAAM,eAAe,EAAE,EACvB;AAAA,cAAU,eAAe;AAAA,cAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,EAAS;AAAA,YACpC,EACC,QAAQ,GACX,IAAI,CAAC,QAAQ,IAAI,GAAG;AACtB,kBAAM,GAAG,IAAI,EAAE,QAAQ,SAA6B;AAAA,UACtD,OAAO;AACL,kBAAM,YACJ,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,cAAU,eAAe;AAAA,cAAO,CAAC,MAChC,EAAE,GAAG,eAAe,OAAO,EAAS;AAAA,YACtC,EACC,QAAQ,GAEV;AAAA,cACC,eAAe,YACX,MAAM,KAAK,GACR,MAAM,eAAe,KAAK,EAC1B;AAAA,gBAAU,eAAe;AAAA,gBAAK,CAAC,MAC9B,EAAE,GAAG,eAAe,KAAK,EAAS;AAAA,cACpC,EACC,QAAQ,IACX,CAAC;AAAA,YACP,EACC,IAAI,CAAC,QAAQ,IAAI,GAAG;AACvB,kBAAM,GAAG,IAAI,EAAE,aAAa,SAA6B;AAAA,UAC3D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,KAAK,GAAG,OAAO,EAAE;AACvB,UAAM,KAAK,KAAK,WAAW,IAAI,KAAK;AACpC,WAAO;AAAA,EACT;AACF;AAsEA,IAAM,mBAAN,cAIU,QAEV;AAAA,EACE,YACU,IACA,gBACA,OACA,UACR;AACA,UAAM,MAAM;AAAA,IAAC,CAAC;AALN;AACA;AACA;AACA;AAAA,EAGV;AAAA,EAEA,MAAM;AACJ,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AACV,cAAM,KAAK,MAAM,KAAK,SAAS;AAC/B,eAAO,EAAE,IAAI,KAAK,YAAY,KAAK,GAAG,IAAI,EAAE,EAAE;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KACE,aAIA,YAI8B;AAC9B,WAAO,KAAK,SAAS,EAAE,KAAK,aAAa,UAAU;AAAA,EACrD;AACF;AAOA,IAAM,gBAAgB;AAAA,EACpB,IAAI;AAAA,EACJ,KAAK,YAAY;AACnB;AAYA,SAAS,gBAGP,KAA8C;AAC9C,SAAO;AAAA,IACL,IAAK,KAAK,OAAO;AAAA,IACjB,KAAK,YAAY;AAAA,EACnB;AACF;AA0BO,SAAS,YACd,gBACA,OAuCe;AACf,SAAO,EAAE,GAAG,gBAAgB,MAAM;AACpC;AAEA,eAAe,iBACb,IACA,gBACA,OACA,MACA,aACA;AACA,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,QAAM,aAAa,YAAY,gBAAgB,KAAK;AACpD,MAAI,eAAe,QAAW;AAC5B,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,KAAK,IAAI,OAAO,QAAQ;AACtB,cAAM,WAAW,MAAM;AAAA,UACrB,WAAW,KAAK,IAAI,gBAAgB,KAAK;AAAA,QAC3C;AACA,YAAI,eAAe,CAAC,UAAU;AAC5B,gBAAM,IAAI;AAAA,YACR,qCACE,IAAI,GACN,gBAAgB,KAAK;AAAA,UACvB;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,WAAO,KAAK,OAAO,CAAC,GAAG,MAAM,UAAU,CAAC,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAEO,SAAS,YACd,gBACA,OACA;AACA,SAAQ,eAAe,QAAkB,KAAK,GAAG;AACnD;AAEO,SAAS,aACd,gBACA,OACA;AACA,SAAQ,eAAe,QAAkB,KAAK,GAAG;AACnD;","names":["edge","decision"]}
|