forge-sql-orm 2.1.12 → 2.1.14
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 +922 -549
- package/dist/core/ForgeSQLAnalyseOperations.d.ts.map +1 -1
- package/dist/core/ForgeSQLAnalyseOperations.js +257 -0
- package/dist/core/ForgeSQLAnalyseOperations.js.map +1 -0
- package/dist/core/ForgeSQLCacheOperations.js +172 -0
- package/dist/core/ForgeSQLCacheOperations.js.map +1 -0
- package/dist/core/ForgeSQLCrudOperations.js +349 -0
- package/dist/core/ForgeSQLCrudOperations.js.map +1 -0
- package/dist/core/ForgeSQLORM.d.ts +29 -1
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLORM.js +1252 -0
- package/dist/core/ForgeSQLORM.js.map +1 -0
- package/dist/core/ForgeSQLQueryBuilder.d.ts +179 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.js +77 -0
- package/dist/core/ForgeSQLQueryBuilder.js.map +1 -0
- package/dist/core/ForgeSQLSelectOperations.js +81 -0
- package/dist/core/ForgeSQLSelectOperations.js.map +1 -0
- package/dist/core/Rovo.d.ts +116 -0
- package/dist/core/Rovo.d.ts.map +1 -0
- package/dist/core/Rovo.js +647 -0
- package/dist/core/Rovo.js.map +1 -0
- package/dist/core/SystemTables.js +258 -0
- package/dist/core/SystemTables.js.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.js +527 -0
- package/dist/lib/drizzle/extensions/additionalActions.js.map +1 -0
- package/dist/utils/cacheContextUtils.d.ts.map +1 -1
- package/dist/utils/cacheContextUtils.js +198 -0
- package/dist/utils/cacheContextUtils.js.map +1 -0
- package/dist/utils/cacheUtils.d.ts.map +1 -1
- package/dist/utils/cacheUtils.js +383 -0
- package/dist/utils/cacheUtils.js.map +1 -0
- package/dist/utils/forgeDriver.d.ts.map +1 -1
- package/dist/utils/forgeDriver.js +139 -0
- package/dist/utils/forgeDriver.js.map +1 -0
- package/dist/utils/forgeDriverProxy.js +68 -0
- package/dist/utils/forgeDriverProxy.js.map +1 -0
- package/dist/utils/metadataContextUtils.d.ts.map +1 -1
- package/dist/utils/metadataContextUtils.js +26 -0
- package/dist/utils/metadataContextUtils.js.map +1 -0
- package/dist/utils/requestTypeContextUtils.js +10 -0
- package/dist/utils/requestTypeContextUtils.js.map +1 -0
- package/dist/utils/sqlHints.js +52 -0
- package/dist/utils/sqlHints.js.map +1 -0
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/dist/utils/sqlUtils.js +590 -0
- package/dist/utils/sqlUtils.js.map +1 -0
- package/dist/webtriggers/applyMigrationsWebTrigger.js +77 -0
- package/dist/webtriggers/applyMigrationsWebTrigger.js.map +1 -0
- package/dist/webtriggers/clearCacheSchedulerTrigger.js +83 -0
- package/dist/webtriggers/clearCacheSchedulerTrigger.js.map +1 -0
- package/dist/webtriggers/dropMigrationWebTrigger.js +54 -0
- package/dist/webtriggers/dropMigrationWebTrigger.js.map +1 -0
- package/dist/webtriggers/dropTablesMigrationWebTrigger.js +54 -0
- package/dist/webtriggers/dropTablesMigrationWebTrigger.js.map +1 -0
- package/dist/webtriggers/fetchSchemaWebTrigger.js +82 -0
- package/dist/webtriggers/fetchSchemaWebTrigger.js.map +1 -0
- package/dist/webtriggers/index.js +40 -0
- package/dist/webtriggers/index.js.map +1 -0
- package/dist/webtriggers/slowQuerySchedulerTrigger.js +80 -0
- package/dist/webtriggers/slowQuerySchedulerTrigger.js.map +1 -0
- package/package.json +31 -25
- package/src/core/ForgeSQLAnalyseOperations.ts +3 -2
- package/src/core/ForgeSQLORM.ts +64 -0
- package/src/core/ForgeSQLQueryBuilder.ts +200 -1
- package/src/core/Rovo.ts +765 -0
- package/src/lib/drizzle/extensions/additionalActions.ts +11 -0
- package/src/utils/cacheContextUtils.ts +9 -6
- package/src/utils/cacheUtils.ts +6 -4
- package/src/utils/forgeDriver.ts +3 -7
- package/src/utils/metadataContextUtils.ts +1 -3
- package/src/utils/sqlUtils.ts +33 -34
- package/dist/ForgeSQLORM.js +0 -3922
- package/dist/ForgeSQLORM.js.map +0 -1
- package/dist/ForgeSQLORM.mjs +0 -3905
- package/dist/ForgeSQLORM.mjs.map +0 -1
package/dist/ForgeSQLORM.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ForgeSQLORM.js","sources":["../src/core/SystemTables.ts","../src/utils/sqlUtils.ts","../src/utils/cacheUtils.ts","../src/utils/cacheContextUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/utils/metadataContextUtils.ts","../src/utils/requestTypeContextUtils.ts","../src/utils/forgeDriver.ts","../src/utils/sqlHints.ts","../src/utils/forgeDriverProxy.ts","../src/lib/drizzle/extensions/additionalActions.ts","../src/core/ForgeSQLAnalyseOperations.ts","../src/core/ForgeSQLCacheOperations.ts","../src/core/ForgeSQLORM.ts","../src/core/ForgeSQLQueryBuilder.ts","../src/webtriggers/dropMigrationWebTrigger.ts","../src/webtriggers/applyMigrationsWebTrigger.ts","../src/webtriggers/fetchSchemaWebTrigger.ts","../src/webtriggers/dropTablesMigrationWebTrigger.ts","../src/webtriggers/clearCacheSchedulerTrigger.ts","../src/webtriggers/slowQuerySchedulerTrigger.ts","../src/webtriggers/index.ts"],"sourcesContent":["import {\n bigint,\n mysqlTable,\n timestamp,\n varchar,\n double,\n mysqlSchema,\n longtext,\n int,\n text,\n boolean,\n} from \"drizzle-orm/mysql-core\";\nimport { Table } from \"drizzle-orm\";\nimport { sql } from \"@forge/sql\";\n\nexport const migrations = mysqlTable(\"__migrations\", {\n id: bigint(\"id\", { mode: \"number\" }).primaryKey().autoincrement(),\n name: varchar(\"name\", { length: 255 }).notNull(),\n migratedAt: timestamp(\"migratedAt\").defaultNow().notNull(),\n});\n\nconst informationSchema = mysqlSchema(\"information_schema\");\n\nexport const slowQuery = informationSchema.table(\"CLUSTER_SLOW_QUERY\", {\n time: timestamp(\"Time\", { fsp: 6, mode: \"string\" }).notNull(), // Timestamp when the slow query was recorded\n\n txnStartTs: bigint(\"Txn_start_ts\", { mode: \"bigint\", unsigned: true }), // Transaction start timestamp (TSO)\n user: varchar(\"User\", { length: 64 }), // User executing the query\n host: varchar(\"Host\", { length: 64 }), // Host from which the query originated\n connId: bigint(\"Conn_ID\", { mode: \"bigint\", unsigned: true }), // Connection ID\n sessionAlias: varchar(\"Session_alias\", { length: 64 }), // Session alias\n\n execRetryCount: bigint(\"Exec_retry_count\", { mode: \"bigint\", unsigned: true }), // Number of retries during execution\n execRetryTime: double(\"Exec_retry_time\"), // Time spent in retries\n queryTime: double(\"Query_time\"), // Total execution time\n parseTime: double(\"Parse_time\"), // Time spent parsing SQL\n compileTime: double(\"Compile_time\"), // Time spent compiling query plan\n rewriteTime: double(\"Rewrite_time\"), // Time spent rewriting query\n preprocSubqueries: bigint(\"Preproc_subqueries\", { mode: \"bigint\", unsigned: true }), // Number of subqueries preprocessed\n preprocSubqueriesTime: double(\"Preproc_subqueries_time\"), // Time spent preprocessing subqueries\n optimizeTime: double(\"Optimize_time\"), // Time spent in optimizer\n waitTs: double(\"Wait_TS\"), // Wait time for getting TSO\n prewriteTime: double(\"Prewrite_time\"), // Time spent in prewrite phase\n waitPrewriteBinlogTime: double(\"Wait_prewrite_binlog_time\"), // Time waiting for binlog prewrite\n commitTime: double(\"Commit_time\"), // Commit duration\n getCommitTsTime: double(\"Get_commit_ts_time\"), // Time waiting for commit TSO\n commitBackoffTime: double(\"Commit_backoff_time\"), // Backoff time during commit\n backoffTypes: varchar(\"Backoff_types\", { length: 64 }), // Types of backoff occurred\n resolveLockTime: double(\"Resolve_lock_time\"), // Time resolving locks\n localLatchWaitTime: double(\"Local_latch_wait_time\"), // Time waiting on local latch\n\n writeKeys: bigint(\"Write_keys\", { mode: \"bigint\" }), // Number of keys written\n writeSize: bigint(\"Write_size\", { mode: \"bigint\" }), // Amount of data written\n prewriteRegion: bigint(\"Prewrite_region\", { mode: \"bigint\" }), // Regions involved in prewrite\n txnRetry: bigint(\"Txn_retry\", { mode: \"bigint\" }), // Transaction retry count\n\n copTime: double(\"Cop_time\"), // Time spent in coprocessor\n processTime: double(\"Process_time\"), // Processing time\n waitTime: double(\"Wait_time\"), // Wait time in TiKV\n backoffTime: double(\"Backoff_time\"), // Backoff wait time\n lockKeysTime: double(\"LockKeys_time\"), // Time spent waiting for locks\n\n requestCount: bigint(\"Request_count\", { mode: \"bigint\", unsigned: true }), // Total number of requests\n totalKeys: bigint(\"Total_keys\", { mode: \"bigint\", unsigned: true }), // Total keys scanned\n processKeys: bigint(\"Process_keys\", { mode: \"bigint\", unsigned: true }), // Keys processed\n\n rocksdbDeleteSkippedCount: bigint(\"Rocksdb_delete_skipped_count\", {\n mode: \"bigint\",\n unsigned: true,\n }), // RocksDB delete skips\n rocksdbKeySkippedCount: bigint(\"Rocksdb_key_skipped_count\", { mode: \"bigint\", unsigned: true }), // RocksDB key skips\n rocksdbBlockCacheHitCount: bigint(\"Rocksdb_block_cache_hit_count\", {\n mode: \"bigint\",\n unsigned: true,\n }), // RocksDB block cache hits\n rocksdbBlockReadCount: bigint(\"Rocksdb_block_read_count\", { mode: \"bigint\", unsigned: true }), // RocksDB block reads\n rocksdbBlockReadByte: bigint(\"Rocksdb_block_read_byte\", { mode: \"bigint\", unsigned: true }), // RocksDB block read bytes\n\n db: varchar(\"DB\", { length: 64 }), // Database name\n indexNames: varchar(\"Index_names\", { length: 100 }), // Indexes used\n\n isInternal: boolean(\"Is_internal\"), // Whether the query is internal\n digest: varchar(\"Digest\", { length: 64 }), // SQL digest hash\n stats: varchar(\"Stats\", { length: 512 }), // Stats used during planning\n\n copProcAvg: double(\"Cop_proc_avg\"), // Coprocessor average processing time\n copProcP90: double(\"Cop_proc_p90\"), // Coprocessor 90th percentile processing time\n copProcMax: double(\"Cop_proc_max\"), // Coprocessor max processing time\n copProcAddr: varchar(\"Cop_proc_addr\", { length: 64 }), // Coprocessor address for processing\n\n copWaitAvg: double(\"Cop_wait_avg\"), // Coprocessor average wait time\n copWaitP90: double(\"Cop_wait_p90\"), // Coprocessor 90th percentile wait time\n copWaitMax: double(\"Cop_wait_max\"), // Coprocessor max wait time\n copWaitAddr: varchar(\"Cop_wait_addr\", { length: 64 }), // Coprocessor address for wait\n\n memMax: bigint(\"Mem_max\", { mode: \"bigint\" }), // Max memory usage\n diskMax: bigint(\"Disk_max\", { mode: \"bigint\" }), // Max disk usage\n\n kvTotal: double(\"KV_total\"), // Total KV request time\n pdTotal: double(\"PD_total\"), // Total PD request time\n backoffTotal: double(\"Backoff_total\"), // Total backoff time\n writeSqlResponseTotal: double(\"Write_sql_response_total\"), // SQL response write time\n\n resultRows: bigint(\"Result_rows\", { mode: \"bigint\" }), // Rows returned\n warnings: longtext(\"Warnings\"), // Warnings during execution\n backoffDetail: varchar(\"Backoff_Detail\", { length: 4096 }), // Detailed backoff info\n\n prepared: boolean(\"Prepared\"), // Whether query was prepared\n succ: boolean(\"Succ\"), // Success flag\n isExplicitTxn: boolean(\"IsExplicitTxn\"), // Whether explicit transaction\n isWriteCacheTable: boolean(\"IsWriteCacheTable\"), // Whether wrote to cache table\n planFromCache: boolean(\"Plan_from_cache\"), // Plan was from cache\n planFromBinding: boolean(\"Plan_from_binding\"), // Plan was from binding\n hasMoreResults: boolean(\"Has_more_results\"), // Query returned multiple results\n\n resourceGroup: varchar(\"Resource_group\", { length: 64 }), // Resource group name\n requestUnitRead: double(\"Request_unit_read\"), // RU consumed for read\n requestUnitWrite: double(\"Request_unit_write\"), // RU consumed for write\n timeQueuedByRc: double(\"Time_queued_by_rc\"), // Time queued by resource control\n\n tidbCpuTime: double(\"Tidb_cpu_time\"), // TiDB CPU time\n tikvCpuTime: double(\"Tikv_cpu_time\"), // TiKV CPU time\n\n plan: longtext(\"Plan\"), // Query execution plan\n planDigest: varchar(\"Plan_digest\", { length: 128 }), // Plan digest hash\n binaryPlan: longtext(\"Binary_plan\"), // Binary execution plan\n prevStmt: longtext(\"Prev_stmt\"), // Previous statement in session\n query: longtext(\"Query\"), // Original SQL query\n});\n\nexport type SlowQuery = typeof slowQuery.$inferSelect;\n\n// Common schema for cluster statements summary tables\nconst createClusterStatementsSummarySchema = () => ({\n instance: varchar(\"INSTANCE\", { length: 64 }), // TiDB/TiKV instance address\n\n summaryBeginTime: timestamp(\"SUMMARY_BEGIN_TIME\", { mode: \"string\" }).notNull(), // Begin time of this summary window\n summaryEndTime: timestamp(\"SUMMARY_END_TIME\", { mode: \"string\" }).notNull(), // End time of this summary window\n\n stmtType: varchar(\"STMT_TYPE\", { length: 64 }).notNull(), // Statement type (e.g., Select/Insert/Update)\n schemaName: varchar(\"SCHEMA_NAME\", { length: 64 }), // Current schema name\n digest: varchar(\"DIGEST\", { length: 64 }), // SQL digest (normalized hash)\n digestText: text(\"DIGEST_TEXT\").notNull(), // Normalized SQL text\n\n tableNames: text(\"TABLE_NAMES\"), // Involved table names\n indexNames: text(\"INDEX_NAMES\"), // Used index names\n\n sampleUser: varchar(\"SAMPLE_USER\", { length: 64 }), // Sampled user who executed the statements\n\n execCount: bigint(\"EXEC_COUNT\", { mode: \"bigint\", unsigned: true }).notNull(), // Total executions\n sumErrors: int(\"SUM_ERRORS\", { unsigned: true }).notNull(), // Sum of errors\n sumWarnings: int(\"SUM_WARNINGS\", { unsigned: true }).notNull(), // Sum of warnings\n\n sumLatency: bigint(\"SUM_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Sum of latency (ns)\n maxLatency: bigint(\"MAX_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Max latency (ns)\n minLatency: bigint(\"MIN_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Min latency (ns)\n avgLatency: bigint(\"AVG_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg latency (ns)\n\n avgParseLatency: bigint(\"AVG_PARSE_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg parse time (ns)\n maxParseLatency: bigint(\"MAX_PARSE_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Max parse time (ns)\n avgCompileLatency: bigint(\"AVG_COMPILE_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg compile time (ns)\n maxCompileLatency: bigint(\"MAX_COMPILE_LATENCY\", { mode: \"bigint\", unsigned: true }).notNull(), // Max compile time (ns)\n\n sumCopTaskNum: bigint(\"SUM_COP_TASK_NUM\", { mode: \"bigint\", unsigned: true }).notNull(), // Total number of cop tasks\n maxCopProcessTime: bigint(\"MAX_COP_PROCESS_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max TiKV coprocessor processing time (ns)\n maxCopProcessAddress: varchar(\"MAX_COP_PROCESS_ADDRESS\", { length: 256 }), // Address of cop task with max processing time\n maxCopWaitTime: bigint(\"MAX_COP_WAIT_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max TiKV coprocessor wait time (ns)\n maxCopWaitAddress: varchar(\"MAX_COP_WAIT_ADDRESS\", { length: 256 }), // Address of cop task with max wait time\n\n avgProcessTime: bigint(\"AVG_PROCESS_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg TiKV processing time (ns)\n maxProcessTime: bigint(\"MAX_PROCESS_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max TiKV processing time (ns)\n avgWaitTime: bigint(\"AVG_WAIT_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg TiKV wait time (ns)\n maxWaitTime: bigint(\"MAX_WAIT_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max TiKV wait time (ns)\n\n avgBackoffTime: bigint(\"AVG_BACKOFF_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg backoff time before retry (ns)\n maxBackoffTime: bigint(\"MAX_BACKOFF_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max backoff time before retry (ns)\n\n avgTotalKeys: bigint(\"AVG_TOTAL_KEYS\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg scanned keys\n maxTotalKeys: bigint(\"MAX_TOTAL_KEYS\", { mode: \"bigint\", unsigned: true }).notNull(), // Max scanned keys\n avgProcessedKeys: bigint(\"AVG_PROCESSED_KEYS\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg processed keys\n maxProcessedKeys: bigint(\"MAX_PROCESSED_KEYS\", { mode: \"bigint\", unsigned: true }).notNull(), // Max processed keys\n\n avgRocksdbDeleteSkippedCount: double(\"AVG_ROCKSDB_DELETE_SKIPPED_COUNT\").notNull(), // Avg RocksDB deletes skipped\n maxRocksdbDeleteSkippedCount: int(\"MAX_ROCKSDB_DELETE_SKIPPED_COUNT\", {\n unsigned: true,\n }).notNull(), // Max RocksDB deletes skipped\n avgRocksdbKeySkippedCount: double(\"AVG_ROCKSDB_KEY_SKIPPED_COUNT\").notNull(), // Avg RocksDB keys skipped\n maxRocksdbKeySkippedCount: int(\"MAX_ROCKSDB_KEY_SKIPPED_COUNT\", { unsigned: true }).notNull(), // Max RocksDB keys skipped\n avgRocksdbBlockCacheHitCount: double(\"AVG_ROCKSDB_BLOCK_CACHE_HIT_COUNT\").notNull(), // Avg RocksDB block cache hits\n maxRocksdbBlockCacheHitCount: int(\"MAX_ROCKSDB_BLOCK_CACHE_HIT_COUNT\", {\n unsigned: true,\n }).notNull(), // Max RocksDB block cache hits\n avgRocksdbBlockReadCount: double(\"AVG_ROCKSDB_BLOCK_READ_COUNT\").notNull(), // Avg RocksDB block reads\n maxRocksdbBlockReadCount: int(\"MAX_ROCKSDB_BLOCK_READ_COUNT\", { unsigned: true }).notNull(), // Max RocksDB block reads\n avgRocksdbBlockReadByte: double(\"AVG_ROCKSDB_BLOCK_READ_BYTE\").notNull(), // Avg RocksDB block read bytes\n maxRocksdbBlockReadByte: int(\"MAX_ROCKSDB_BLOCK_READ_BYTE\", { unsigned: true }).notNull(), // Max RocksDB block read bytes\n\n avgPrewriteTime: bigint(\"AVG_PREWRITE_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg prewrite phase time (ns)\n maxPrewriteTime: bigint(\"MAX_PREWRITE_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max prewrite phase time (ns)\n avgCommitTime: bigint(\"AVG_COMMIT_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg commit phase time (ns)\n maxCommitTime: bigint(\"MAX_COMMIT_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max commit phase time (ns)\n avgGetCommitTsTime: bigint(\"AVG_GET_COMMIT_TS_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg get commit_ts time (ns)\n maxGetCommitTsTime: bigint(\"MAX_GET_COMMIT_TS_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Max get commit_ts time (ns)\n avgCommitBackoffTime: bigint(\"AVG_COMMIT_BACKOFF_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg backoff during commit (ns)\n maxCommitBackoffTime: bigint(\"MAX_COMMIT_BACKOFF_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Max backoff during commit (ns)\n avgResolveLockTime: bigint(\"AVG_RESOLVE_LOCK_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg resolve lock time (ns)\n maxResolveLockTime: bigint(\"MAX_RESOLVE_LOCK_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Max resolve lock time (ns)\n avgLocalLatchWaitTime: bigint(\"AVG_LOCAL_LATCH_WAIT_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg local latch wait (ns)\n maxLocalLatchWaitTime: bigint(\"MAX_LOCAL_LATCH_WAIT_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Max local latch wait (ns)\n\n avgWriteKeys: double(\"AVG_WRITE_KEYS\").notNull(), // Avg number of written keys\n maxWriteKeys: bigint(\"MAX_WRITE_KEYS\", { mode: \"bigint\", unsigned: true }).notNull(), // Max written keys\n avgWriteSize: double(\"AVG_WRITE_SIZE\").notNull(), // Avg written bytes\n maxWriteSize: bigint(\"MAX_WRITE_SIZE\", { mode: \"bigint\", unsigned: true }).notNull(), // Max written bytes\n avgPrewriteRegions: double(\"AVG_PREWRITE_REGIONS\").notNull(), // Avg regions in prewrite\n maxPrewriteRegions: int(\"MAX_PREWRITE_REGIONS\", { unsigned: true }).notNull(), // Max regions in prewrite\n avgTxnRetry: double(\"AVG_TXN_RETRY\").notNull(), // Avg transaction retry count\n maxTxnRetry: int(\"MAX_TXN_RETRY\", { unsigned: true }).notNull(), // Max transaction retry count\n\n sumExecRetry: bigint(\"SUM_EXEC_RETRY\", { mode: \"bigint\", unsigned: true }).notNull(), // Sum of execution retries (pessimistic)\n sumExecRetryTime: bigint(\"SUM_EXEC_RETRY_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Sum time of execution retries (ns)\n sumBackoffTimes: bigint(\"SUM_BACKOFF_TIMES\", { mode: \"bigint\", unsigned: true }).notNull(), // Sum of backoff retries\n backoffTypes: varchar(\"BACKOFF_TYPES\", { length: 1024 }), // Backoff types with counts\n\n avgMem: bigint(\"AVG_MEM\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg memory used (bytes)\n maxMem: bigint(\"MAX_MEM\", { mode: \"bigint\", unsigned: true }).notNull(), // Max memory used (bytes)\n avgDisk: bigint(\"AVG_DISK\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg disk used (bytes)\n maxDisk: bigint(\"MAX_DISK\", { mode: \"bigint\", unsigned: true }).notNull(), // Max disk used (bytes)\n\n avgKvTime: bigint(\"AVG_KV_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg time spent in TiKV (ns)\n avgPdTime: bigint(\"AVG_PD_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg time spent in PD (ns)\n avgBackoffTotalTime: bigint(\"AVG_BACKOFF_TOTAL_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg total backoff time (ns)\n avgWriteSqlRespTime: bigint(\"AVG_WRITE_SQL_RESP_TIME\", {\n mode: \"bigint\",\n unsigned: true,\n }).notNull(), // Avg write SQL response time (ns)\n\n avgTidbCpuTime: bigint(\"AVG_TIDB_CPU_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg TiDB CPU time (ns)\n avgTikvCpuTime: bigint(\"AVG_TIKV_CPU_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg TiKV CPU time (ns)\n\n maxResultRows: bigint(\"MAX_RESULT_ROWS\", { mode: \"bigint\" }).notNull(), // Max number of result rows\n minResultRows: bigint(\"MIN_RESULT_ROWS\", { mode: \"bigint\" }).notNull(), // Min number of result rows\n avgResultRows: bigint(\"AVG_RESULT_ROWS\", { mode: \"bigint\" }).notNull(), // Avg number of result rows\n\n prepared: boolean(\"PREPARED\").notNull(), // Whether statements are prepared\n avgAffectedRows: double(\"AVG_AFFECTED_ROWS\").notNull(), // Avg affected rows\n\n firstSeen: timestamp(\"FIRST_SEEN\", { mode: \"string\" }).notNull(), // First time statements observed\n lastSeen: timestamp(\"LAST_SEEN\", { mode: \"string\" }).notNull(), // Last time statements observed\n\n planInCache: boolean(\"PLAN_IN_CACHE\").notNull(), // Whether last stmt hit plan cache\n planCacheHits: bigint(\"PLAN_CACHE_HITS\", { mode: \"bigint\" }).notNull(), // Number of plan cache hits\n planInBinding: boolean(\"PLAN_IN_BINDING\").notNull(), // Whether matched bindings\n\n querySampleText: text(\"QUERY_SAMPLE_TEXT\"), // Sampled original SQL\n prevSampleText: text(\"PREV_SAMPLE_TEXT\"), // Sampled previous SQL before commit\n\n planDigest: varchar(\"PLAN_DIGEST\", { length: 64 }), // Plan digest hash\n plan: text(\"PLAN\"), // Sampled textual plan\n binaryPlan: text(\"BINARY_PLAN\"), // Sampled binary plan\n\n charset: varchar(\"CHARSET\", { length: 64 }), // Sampled charset\n collation: varchar(\"COLLATION\", { length: 64 }), // Sampled collation\n planHint: varchar(\"PLAN_HINT\", { length: 64 }), // Sampled plan hint\n\n maxRequestUnitRead: double(\"MAX_REQUEST_UNIT_READ\").notNull(), // Max RU cost (read)\n avgRequestUnitRead: double(\"AVG_REQUEST_UNIT_READ\").notNull(), // Avg RU cost (read)\n maxRequestUnitWrite: double(\"MAX_REQUEST_UNIT_WRITE\").notNull(), // Max RU cost (write)\n avgRequestUnitWrite: double(\"AVG_REQUEST_UNIT_WRITE\").notNull(), // Avg RU cost (write)\n\n maxQueuedRcTime: bigint(\"MAX_QUEUED_RC_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Max queued time waiting for RU (ns)\n avgQueuedRcTime: bigint(\"AVG_QUEUED_RC_TIME\", { mode: \"bigint\", unsigned: true }).notNull(), // Avg queued time waiting for RU (ns)\n\n resourceGroup: varchar(\"RESOURCE_GROUP\", { length: 64 }), // Bound resource group name\n\n planCacheUnqualified: bigint(\"PLAN_CACHE_UNQUALIFIED\", { mode: \"bigint\" }).notNull(), // Times not eligible for plan cache\n planCacheUnqualifiedLastReason: text(\"PLAN_CACHE_UNQUALIFIED_LAST_REASON\"), // Last reason of plan cache ineligibility\n});\n\nexport const clusterStatementsSummaryHistory = informationSchema.table(\n \"CLUSTER_STATEMENTS_SUMMARY_HISTORY\",\n createClusterStatementsSummarySchema(),\n);\n\n// Types\nexport type ClusterStatementsSummaryHistory = typeof clusterStatementsSummaryHistory.$inferSelect;\n\nexport const statementsSummaryHistory = informationSchema.table(\n \"STATEMENTS_SUMMARY_HISTORY\",\n createClusterStatementsSummarySchema(),\n);\n\n// Types\nexport type StatementsSummaryHistory = typeof statementsSummaryHistory.$inferSelect;\n\nexport const statementsSummary = informationSchema.table(\n \"STATEMENTS_SUMMARY\",\n createClusterStatementsSummarySchema(),\n);\n\n// Types\nexport type StatementsSummary = typeof statementsSummary.$inferSelect;\n\nexport const clusterStatementsSummary = informationSchema.table(\n \"CLUSTER_STATEMENTS_SUMMARY\",\n createClusterStatementsSummarySchema(),\n);\n\n// Types\nexport type ClusterStatementsSummary = typeof clusterStatementsSummary.$inferSelect;\n\nexport interface ExplainAnalyzeRow {\n id: string;\n estRows?: string;\n estCost?: string;\n actRows?: string;\n task?: string;\n accessObject?: string;\n executionInfo?: string;\n operatorInfo?: string;\n memory?: string;\n disk?: string;\n}\n\nexport interface SlowQueryNormalized {\n time: string;\n txnStartTs: number;\n user: string;\n host: string;\n connId: number;\n db: string;\n query: string;\n digest: string;\n queryTime: number;\n compileTime: number;\n optimizeTime: number;\n processTime: number;\n waitTime: number;\n parseTime: number;\n rewriteTime: number;\n copTime: number;\n copProcAvg: number;\n copProcMax: number;\n copProcP90: number;\n copProcAddr: string;\n copWaitAvg: number;\n copWaitMax: number;\n copWaitP90: number;\n copWaitAddr: string;\n memMax: number;\n diskMax: number;\n totalKeys: number;\n processKeys: number;\n requestCount: number;\n kvTotal: number;\n pdTotal: number;\n resultRows: number;\n rocksdbBlockCacheHitCount: number;\n rocksdbBlockReadCount: number;\n rocksdbBlockReadByte: number;\n plan: string;\n parsedPlan?: ExplainAnalyzeRow[];\n binaryPlan: string;\n planDigest: string;\n}\n\nexport interface ClusterStatementRowCamelCase {\n instance: string;\n summaryBeginTime: string;\n summaryEndTime: string;\n stmtType: string;\n schemaName: string;\n digest: string;\n digestText: string;\n tableNames: string;\n indexNames: string | null;\n sampleUser: string;\n execCount: number;\n sumErrors: number;\n sumWarnings: number;\n sumLatency: number;\n maxLatency: number;\n minLatency: number;\n avgLatency: number;\n avgParseLatency: number;\n maxParseLatency: number;\n avgCompileLatency: number;\n maxCompileLatency: number;\n sumCopTaskNum: number;\n maxCopProcessTime: number;\n maxCopProcessAddress: string;\n maxCopWaitTime: number;\n maxCopWaitAddress: string;\n avgProcessTime: number;\n maxProcessTime: number;\n avgWaitTime: number;\n maxWaitTime: number;\n avgBackoffTime: number;\n maxBackoffTime: number;\n avgTotalKeys: number;\n maxTotalKeys: number;\n avgProcessedKeys: number;\n maxProcessedKeys: number;\n avgRocksdbDeleteSkippedCount: number;\n maxRocksdbDeleteSkippedCount: number;\n avgRocksdbKeySkippedCount: number;\n maxRocksdbKeySkippedCount: number;\n avgRocksdbBlockCacheHitCount: number;\n maxRocksdbBlockCacheHitCount: number;\n avgRocksdbBlockReadCount: number;\n maxRocksdbBlockReadCount: number;\n avgRocksdbBlockReadByte: number;\n maxRocksdbBlockReadByte: number;\n avgPrewriteTime: number;\n maxPrewriteTime: number;\n avgCommitTime: number;\n maxCommitTime: number;\n avgGetCommitTsTime: number;\n maxGetCommitTsTime: number;\n avgCommitBackoffTime: number;\n maxCommitBackoffTime: number;\n avgResolveLockTime: number;\n maxResolveLockTime: number;\n avgLocalLatchWaitTime: number;\n maxLocalLatchWaitTime: number;\n avgWriteKeys: number;\n maxWriteKeys: number;\n avgWriteSize: number;\n maxWriteSize: number;\n avgPrewriteRegions: number;\n maxPrewriteRegions: number;\n avgTxnRetry: number;\n maxTxnRetry: number;\n sumExecRetry: number;\n sumExecRetryTime: number;\n sumBackoffTimes: number;\n backoffTypes: string | null;\n avgMem: number;\n maxMem: number;\n avgDisk: number;\n maxDisk: number;\n avgKvTime: number;\n avgPdTime: number;\n avgBackoffTotalTime: number;\n avgWriteSqlRespTime: number;\n avgTidbCpuTime: number;\n avgTikvCpuTime: number;\n maxResultRows: number;\n minResultRows: number;\n avgResultRows: number;\n prepared: number;\n avgAffectedRows: number;\n firstSeen: string;\n lastSeen: string;\n planInCache: number;\n planCacheHits: number;\n planInBinding: number;\n querySampleText: string;\n prevSampleText: string;\n planDigest: string;\n plan: string;\n binaryPlan: string;\n charset: string;\n collation: string;\n planHint: string;\n maxRequestUnitRead: number;\n avgRequestUnitRead: number;\n maxRequestUnitWrite: number;\n avgRequestUnitWrite: number;\n maxQueuedRcTime: number;\n avgQueuedRcTime: number;\n resourceGroup: string;\n planCacheUnqualified: number;\n planCacheUnqualifiedLastReason: string;\n parsedPlan?: ExplainAnalyzeRow[];\n}\n\n/**\n * Retrieves all tables from the database\n */\nexport async function getTables(): Promise<string[]> {\n const tables = await sql.executeDDL<string>(\"SHOW TABLES\");\n return tables.rows.flatMap((tableInfo) => Object.values(tableInfo));\n}\n\nexport const forgeSystemTables: Table[] = [migrations];\n","import {\n and,\n AnyColumn,\n Column,\n gte,\n ilike,\n isNotNull,\n isTable,\n ne,\n not,\n notInArray,\n SQL,\n sql,\n StringChunk,\n} from \"drizzle-orm\";\nimport { AnyMySqlTable, MySqlCustomColumn } from \"drizzle-orm/mysql-core/index\";\nimport { DateTime } from \"luxon\";\nimport { PrimaryKeyBuilder } from \"drizzle-orm/mysql-core/primary-keys\";\nimport { AnyIndexBuilder } from \"drizzle-orm/mysql-core/indexes\";\nimport { CheckBuilder } from \"drizzle-orm/mysql-core/checks\";\nimport { ForeignKeyBuilder } from \"drizzle-orm/mysql-core/foreign-keys\";\nimport { UniqueConstraintBuilder } from \"drizzle-orm/mysql-core/unique-constraint\";\nimport { SelectedFields } from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core\";\nimport { isSQLWrapper } from \"drizzle-orm/sql/sql\";\nimport { clusterStatementsSummary, slowQuery } from \"../core/SystemTables\";\nimport { ForgeSqlOperation } from \"../core/ForgeSQLQueryBuilder\";\nimport { ColumnDataType } from \"drizzle-orm/column-builder\";\nimport { AnyMySqlColumn } from \"drizzle-orm/mysql-core/columns/common\";\nimport type { ColumnBaseConfig } from \"drizzle-orm/column\";\n\n/**\n * Interface representing table metadata information\n */\nexport interface MetadataInfo {\n /** The name of the table */\n tableName: string;\n /** Record of column names and their corresponding column definitions */\n columns: Record<string, AnyColumn>;\n /** Array of index builders */\n indexes: AnyIndexBuilder[];\n /** Array of check constraint builders */\n checks: CheckBuilder[];\n /** Array of foreign key builders */\n foreignKeys: ForeignKeyBuilder[];\n /** Array of primary key builders */\n primaryKeys: PrimaryKeyBuilder[];\n /** Array of unique constraint builders */\n uniqueConstraints: UniqueConstraintBuilder[];\n /** Array of all extra builders */\n extras: any[];\n}\n\n/**\n * Interface for config builder data\n */\ninterface ConfigBuilderData {\n value?: any;\n [key: string]: any;\n}\n\n/**\n * Parses a date string into a Date object using the specified format\n * @param value - The date string to parse or Date\n * @param format - The format to use for parsing\n * @returns Date object\n */\n\nexport const parseDateTime = (value: string | Date, format: string): Date => {\n let result: Date;\n if (value instanceof Date) {\n result = value;\n } else {\n // 1. Try to parse using the provided format (strict mode)\n const dt = DateTime.fromFormat(value, format);\n if (dt.isValid) {\n result = dt.toJSDate();\n } else {\n // 2. Try to parse as SQL string\n const sqlDt = DateTime.fromSQL(value);\n if (sqlDt.isValid) {\n result = sqlDt.toJSDate();\n } else {\n // 3. Try to parse as RFC2822 string\n const isoDt = DateTime.fromRFC2822(value);\n if (isoDt.isValid) {\n result = isoDt.toJSDate();\n } else {\n // 4. Fallback: use native Date constructor\n result = new Date(value);\n }\n }\n }\n }\n // 4. Ensure the result is a valid Date object\n if (isNaN(result.getTime())) {\n result = new Date(value);\n }\n return result;\n};\n\n/**\n * Helper function to validate and format a date-like value using Luxon DateTime.\n * @param value - Date object, ISO/RFC2822/SQL/HTTP string, or timestamp (number|string).\n * @param format - DateTime format string (Luxon format tokens).\n * @returns Formatted date string.\n * @throws Error if value cannot be parsed as a valid date.\n */\nexport function formatDateTime(\n value: Date | string | number,\n format: string,\n isTimeStamp: boolean,\n): string {\n let dt: DateTime | null = null;\n\n if (value instanceof Date) {\n dt = DateTime.fromJSDate(value);\n } else if (typeof value === \"string\") {\n for (const parser of [\n DateTime.fromISO,\n DateTime.fromRFC2822,\n DateTime.fromSQL,\n DateTime.fromHTTP,\n ]) {\n dt = parser(value);\n if (dt.isValid) break;\n }\n if (!dt?.isValid) {\n const parsed = Number(value);\n if (!isNaN(parsed)) {\n dt = DateTime.fromMillis(parsed);\n }\n }\n } else if (typeof value === \"number\") {\n dt = DateTime.fromMillis(value);\n } else {\n throw new Error(\"Unsupported type\");\n }\n\n if (!dt?.isValid) {\n throw new Error(\"Invalid Date\");\n }\n const minDate = DateTime.fromSeconds(1);\n const maxDate = DateTime.fromMillis(2147483647 * 1000); // 2038-01-19 03:14:07.999 UTC\n\n if (isTimeStamp) {\n if (dt < minDate) {\n throw new Error(\n \"Atlassian Forge does not support zero or negative timestamps. Allowed range: from '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.999999'.\",\n );\n }\n if (dt > maxDate) {\n throw new Error(\n \"Atlassian Forge does not support timestamps beyond 2038-01-19 03:14:07.999999. Please use a smaller date within the supported range.\",\n );\n }\n }\n\n return dt.toFormat(format);\n}\n\n/**\n * Gets primary keys from the schema.\n * @template T - The type of the table schema\n * @param {T} table - The table schema\n * @returns {[string, AnyColumn][]} Array of primary key name and column pairs\n */\nexport function getPrimaryKeys<T extends AnyMySqlTable>(table: T): [string, AnyColumn][] {\n const { columns, primaryKeys } = getTableMetadata(table);\n\n // First try to find primary keys in columns\n const columnPrimaryKeys = Object.entries(columns).filter(([, column]) => column.primary) as [\n string,\n AnyColumn,\n ][];\n\n if (columnPrimaryKeys.length > 0) {\n return columnPrimaryKeys;\n }\n\n // If no primary keys found in columns, check primary key builders\n if (Array.isArray(primaryKeys) && primaryKeys.length > 0) {\n // Collect all primary key columns from all primary key builders\n const primaryKeyColumns = new Set<[string, AnyColumn]>();\n\n primaryKeys.forEach((primaryKeyBuilder) => {\n // Get primary key columns from each builder\n Object.entries(columns)\n .filter(([, column]) => {\n // @ts-ignore - PrimaryKeyBuilder has internal columns property\n return primaryKeyBuilder.columns.includes(column);\n })\n .forEach(([name, column]) => {\n primaryKeyColumns.add([name, column]);\n });\n });\n\n return Array.from(primaryKeyColumns);\n }\n\n return [];\n}\n\n/**\n * Processes foreign keys from both foreignKeysSymbol and extraSymbol\n * @param table - The table schema\n * @param foreignKeysSymbol - Symbol for foreign keys\n * @param extraSymbol - Symbol for extra configuration\n * @returns Array of foreign key builders\n */\nfunction processForeignKeys(\n table: AnyMySqlTable,\n foreignKeysSymbol: symbol | undefined,\n extraSymbol: symbol | undefined,\n): ForeignKeyBuilder[] {\n const foreignKeys: ForeignKeyBuilder[] = [];\n\n // Process foreign keys from foreignKeysSymbol\n if (foreignKeysSymbol) {\n // @ts-ignore\n const fkArray: any[] = table[foreignKeysSymbol];\n if (fkArray) {\n fkArray.forEach((fk) => {\n if (fk.reference) {\n const item = fk.reference(fk);\n foreignKeys.push(item);\n }\n });\n }\n }\n\n // Process foreign keys from extraSymbol\n if (extraSymbol) {\n // @ts-ignore\n const extraConfigBuilder = table[extraSymbol];\n if (extraConfigBuilder && typeof extraConfigBuilder === \"function\") {\n const configBuilderData = extraConfigBuilder(table);\n if (configBuilderData) {\n const configBuilders = Array.isArray(configBuilderData)\n ? configBuilderData\n : Object.values(configBuilderData).map(\n (item) => (item as ConfigBuilderData).value ?? item,\n );\n\n configBuilders.forEach((builder) => {\n if (!builder?.constructor) return;\n\n const builderName = builder.constructor.name.toLowerCase();\n if (builderName.includes(\"foreignkeybuilder\")) {\n foreignKeys.push(builder);\n }\n });\n }\n }\n }\n\n return foreignKeys;\n}\n\n/**\n * Extracts table metadata from the schema.\n * @param {AnyMySqlTable} table - The table schema\n * @returns {MetadataInfo} Object containing table metadata\n */\nexport function getTableMetadata(table: AnyMySqlTable): MetadataInfo {\n const symbols = Object.getOwnPropertySymbols(table);\n const nameSymbol = symbols.find((s) => s.toString().includes(\"Name\"));\n const columnsSymbol = symbols.find((s) => s.toString().includes(\"Columns\"));\n const foreignKeysSymbol = symbols.find((s) => s.toString().includes(\"ForeignKeys)\"));\n const extraSymbol = symbols.find((s) => s.toString().includes(\"ExtraConfigBuilder\"));\n\n // Initialize builders arrays\n const builders = {\n indexes: [] as AnyIndexBuilder[],\n checks: [] as CheckBuilder[],\n foreignKeys: [] as ForeignKeyBuilder[],\n primaryKeys: [] as PrimaryKeyBuilder[],\n uniqueConstraints: [] as UniqueConstraintBuilder[],\n extras: [] as any[],\n };\n\n // Process foreign keys\n builders.foreignKeys = processForeignKeys(table, foreignKeysSymbol, extraSymbol);\n\n // Process extra configuration if available\n if (extraSymbol) {\n // @ts-ignore\n const extraConfigBuilder = table[extraSymbol];\n if (extraConfigBuilder && typeof extraConfigBuilder === \"function\") {\n const configBuilderData = extraConfigBuilder(table);\n if (configBuilderData) {\n // Convert configBuilderData to array if it's an object\n const configBuilders = Array.isArray(configBuilderData)\n ? configBuilderData\n : Object.values(configBuilderData).map(\n (item) => (item as ConfigBuilderData).value ?? item,\n );\n\n // Process each builder\n configBuilders.forEach((builder) => {\n if (!builder?.constructor) return;\n\n const builderName = builder.constructor.name.toLowerCase();\n\n // Map builder types to their corresponding arrays\n const builderMap = {\n indexbuilder: builders.indexes,\n checkbuilder: builders.checks,\n primarykeybuilder: builders.primaryKeys,\n uniqueconstraintbuilder: builders.uniqueConstraints,\n };\n\n // Add builder to appropriate array if it matches any type\n for (const [type, array] of Object.entries(builderMap)) {\n if (builderName.includes(type)) {\n array.push(builder);\n break;\n }\n }\n\n // Always add to extras array\n builders.extras.push(builder);\n });\n }\n }\n }\n\n return {\n tableName: nameSymbol ? (table as any)[nameSymbol] : \"\",\n columns: columnsSymbol ? ((table as any)[columnsSymbol] as Record<string, AnyColumn>) : {},\n ...builders,\n };\n}\n\n/**\n * Generates SQL statements for dropping tables and/or their sequences.\n *\n * @param tables - List of table names to generate DROP statements for.\n * @param options - Configuration object:\n * - sequence: whether to drop associated sequences (default: true)\n * - table: whether to drop tables themselves (default: true)\n * @returns Array of SQL statements for dropping the specified objects\n */\nexport function generateDropTableStatements(\n tables: string[],\n options?: { sequence: boolean; table: boolean },\n): string[] {\n const dropStatements: string[] = [];\n const validOptions = options ?? { sequence: true, table: true };\n if (!validOptions.sequence && !validOptions.table) {\n // eslint-disable-next-line no-console\n console.warn('No drop operations requested: both \"table\" and \"sequence\" options are false');\n return [];\n }\n tables.forEach((tableName) => {\n if (validOptions.table) {\n dropStatements.push(`DROP TABLE IF EXISTS \\`${tableName}\\`;`);\n }\n if (validOptions.sequence) {\n dropStatements.push(`DROP SEQUENCE IF EXISTS \\`${tableName}\\`;`);\n }\n });\n\n return dropStatements;\n}\n\ntype AliasColumnMap = Record<string, AnyColumn>;\n\nfunction mapSelectTableToAlias(\n table: MySqlTable,\n uniqPrefix: string,\n aliasMap: AliasColumnMap,\n): any {\n const { columns, tableName } = getTableMetadata(table);\n const selectionsTableFields: Record<string, unknown> = {};\n Object.keys(columns).forEach((name) => {\n const column = columns[name] as AnyColumn;\n const uniqName = `a_${uniqPrefix}_${tableName}_${column.name}`.toLowerCase();\n const fieldAlias = sql.raw(uniqName);\n selectionsTableFields[name] = sql`${column} as \\`${fieldAlias}\\``;\n aliasMap[uniqName] = column;\n });\n return selectionsTableFields;\n}\n\nfunction isDrizzleColumn(column: any): boolean {\n return column && typeof column === \"object\" && \"table\" in column;\n}\n\nexport function mapSelectAllFieldsToAlias(\n selections: any,\n name: string,\n uniqName: string,\n fields: any,\n aliasMap: AliasColumnMap,\n): any {\n if (isTable(fields)) {\n selections[name] = mapSelectTableToAlias(fields as MySqlTable, uniqName, aliasMap);\n } else if (isDrizzleColumn(fields)) {\n const column = fields as Column;\n const uniqAliasName = `a_${uniqName}_${column.name}`.toLowerCase();\n let aliasName = sql.raw(uniqAliasName);\n selections[name] = sql`${column} as \\`${aliasName}\\``;\n aliasMap[uniqAliasName] = column;\n } else if (isSQLWrapper(fields)) {\n selections[name] = fields;\n } else {\n const innerSelections: any = {};\n Object.entries(fields).forEach(([iname, ifields]) => {\n mapSelectAllFieldsToAlias(innerSelections, iname, `${uniqName}_${iname}`, ifields, aliasMap);\n });\n selections[name] = innerSelections;\n }\n return selections;\n}\nexport function mapSelectFieldsWithAlias<TSelection extends SelectedFields>(\n fields: TSelection,\n): { selections: TSelection; aliasMap: AliasColumnMap } {\n if (!fields) {\n throw new Error(\"fields is empty\");\n }\n const aliasMap: AliasColumnMap = {};\n const selections: any = {};\n Object.entries(fields).forEach(([name, fields]) => {\n mapSelectAllFieldsToAlias(selections, name, name, fields, aliasMap);\n });\n return { selections, aliasMap };\n}\n\nfunction getAliasFromDrizzleAlias(value: unknown): string | undefined {\n const isSQL =\n value !== null && typeof value === \"object\" && isSQLWrapper(value) && \"queryChunks\" in value;\n if (isSQL) {\n const sql = value as SQL;\n const queryChunks = sql.queryChunks;\n if (queryChunks.length > 3) {\n const aliasNameChunk = queryChunks[queryChunks.length - 2];\n if (isSQLWrapper(aliasNameChunk) && \"queryChunks\" in aliasNameChunk) {\n const aliasNameChunkSql = aliasNameChunk as SQL;\n if (aliasNameChunkSql.queryChunks?.length === 1 && aliasNameChunkSql.queryChunks[0]) {\n const queryChunksStringChunc = aliasNameChunkSql.queryChunks[0];\n if (\"value\" in queryChunksStringChunc) {\n const values = (queryChunksStringChunc as StringChunk).value;\n if (values && values.length === 1) {\n return values[0];\n }\n }\n }\n }\n }\n }\n return undefined;\n}\n\nfunction transformValue(\n value: unknown,\n alias: string,\n aliasMap: Record<string, AnyColumn>,\n): unknown {\n const column = aliasMap[alias];\n if (!column) return value;\n\n let customColumn = column as MySqlCustomColumn<any>;\n // @ts-ignore\n const fromDriver = customColumn?.mapFrom;\n if (fromDriver && value !== null && value !== undefined) {\n return fromDriver(value);\n }\n return value;\n}\n\nfunction transformObject(\n obj: Record<string, unknown>,\n selections: Record<string, unknown>,\n aliasMap: Record<string, AnyColumn>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const selection = selections[key];\n const alias = getAliasFromDrizzleAlias(selection);\n if (alias && aliasMap[alias]) {\n result[key] = transformValue(value, alias, aliasMap);\n } else if (selection && typeof selection === \"object\" && !isSQLWrapper(selection)) {\n result[key] = transformObject(\n value as Record<string, unknown>,\n selection as Record<string, unknown>,\n aliasMap,\n );\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport function applyFromDriverTransform<T, TSelection>(\n rows: T[],\n selections: TSelection,\n aliasMap: Record<string, AnyColumn>,\n): T[] {\n return rows.map((row) => {\n const transformed = transformObject(\n row as Record<string, unknown>,\n selections as Record<string, unknown>,\n aliasMap,\n ) as Record<string, unknown>;\n\n return processNullBranches(transformed) as unknown as T;\n });\n}\n\nfunction processNullBranches(obj: Record<string, unknown>): Record<string, unknown> | null {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n // Skip built-in objects like Date, Array, etc.\n if (obj.constructor && obj.constructor.name !== \"Object\") {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n let allNull = true;\n\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) {\n result[key] = null;\n continue;\n }\n\n if (typeof value === \"object\") {\n const processed = processNullBranches(value as Record<string, unknown>);\n result[key] = processed;\n if (processed !== null) {\n allNull = false;\n }\n } else {\n result[key] = value;\n allNull = false;\n }\n }\n\n return allNull ? null : result;\n}\n\nexport function formatLimitOffset(limitOrOffset: number): number {\n if (typeof limitOrOffset !== \"number\" || isNaN(limitOrOffset)) {\n throw new Error(\"limitOrOffset must be a valid number\");\n }\n return sql.raw(`${limitOrOffset}`) as unknown as number;\n}\n\nexport function nextVal(sequenceName: string): number {\n return sql.raw(`NEXTVAL(${sequenceName})`) as unknown as number;\n}\n\n/**\n * Analyzes and prints query performance data from CLUSTER_STATEMENTS_SUMMARY table.\n *\n * This function queries the CLUSTER_STATEMENTS_SUMMARY table to find queries that were executed\n * within the specified time window and prints detailed performance information including:\n * - SQL query text\n * - Memory usage (average and max in MB)\n * - Execution time (average in ms)\n * - Number of executions\n * - Execution plan\n *\n * @param forgeSQLORM - The ForgeSQL operation instance for database access\n * @param timeDiffMs - Time window in milliseconds to look back for queries (e.g., 1500 for last 1.5 seconds)\n * @param timeout - Optional timeout in milliseconds for the query execution (defaults to 1500ms)\n *\n * @example\n * ```typescript\n * // Analyze queries from the last 2 seconds\n * await printQueriesWithPlan(forgeSQLORM, 2000);\n *\n * // Analyze queries with custom timeout\n * await printQueriesWithPlan(forgeSQLORM, 1000, 3000);\n * ```\n *\n * @throws Does not throw - errors are logged to console.debug instead\n */\nexport async function printQueriesWithPlan(\n forgeSQLORM: ForgeSqlOperation,\n timeDiffMs: number,\n timeout?: number,\n) {\n try {\n const statementsTable = clusterStatementsSummary;\n const timeoutMs = timeout ?? 3000;\n const results = await withTimeout(\n forgeSQLORM\n .getDrizzleQueryBuilder()\n .select({\n digestText: withTidbHint(statementsTable.digestText),\n avgLatency: statementsTable.avgLatency,\n avgMem: statementsTable.avgMem,\n execCount: statementsTable.execCount,\n plan: statementsTable.plan,\n stmtType: statementsTable.stmtType,\n })\n .from(statementsTable)\n .where(\n and(\n isNotNull(statementsTable.digest),\n not(ilike(statementsTable.digestText, \"%information_schema%\")),\n notInArray(statementsTable.stmtType, [\n \"Use\",\n \"Set\",\n \"Show\",\n \"Commit\",\n \"Rollback\",\n \"Begin\",\n ]),\n gte(\n statementsTable.lastSeen,\n sql`DATE_SUB\n (NOW(), INTERVAL\n ${timeDiffMs * 1000}\n MICROSECOND\n )`,\n ),\n ),\n ),\n `Timeout ${timeoutMs}ms in printQueriesWithPlan - transient timeouts are usually fine; repeated timeouts mean this diagnostic query is consistently slow and should be investigated`,\n timeoutMs + 200,\n );\n\n results.forEach((result) => {\n // Average execution time (convert from nanoseconds to milliseconds)\n const avgTimeMs = Number(result.avgLatency) / 1_000_000;\n const avgMemMB = Number(result.avgMem) / 1_000_000;\n\n // 1. Query info: SQL, memory, time, executions\n // eslint-disable-next-line no-console\n console.warn(\n `SQL: ${result.digestText} | Memory: ${avgMemMB.toFixed(2)} MB | Time: ${avgTimeMs.toFixed(2)} ms | stmtType: ${result.stmtType} | Executions: ${result.execCount}\\n Plan:${result.plan}`,\n );\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.debug(\n `Error occurred while retrieving query execution plan: ${error instanceof Error ? error.message : \"Unknown error\"}. Try again after some time`,\n error,\n );\n }\n}\n\nconst SESSION_ALIAS_NAME_ORM = \"orm\";\n\n/**\n * Analyzes and logs slow queries from the last specified number of hours.\n *\n * This function queries the slow query system table to find queries that were executed\n * within the specified time window and logs detailed performance information including:\n * - SQL query text\n * - Maximum memory usage (in MB)\n * - Query execution time (in ms)\n * - Execution count\n * - Execution plan\n *\n * @param forgeSQLORM - The ForgeSQL operation instance for database access\n * @param hours - Number of hours to look back for slow queries (e.g., 1 for last hour, 24 for last day)\n * @param timeout - Optional timeout in milliseconds for the query execution (defaults to 1500ms)\n *\n * @example\n * ```typescript\n * // Analyze slow queries from the last hour\n * await slowQueryPerHours(forgeSQLORM, 1);\n *\n * // Analyze slow queries from the last 24 hours with custom timeout\n * await slowQueryPerHours(forgeSQLORM, 24, 3000);\n *\n * // Analyze slow queries from the last 6 hours\n * await slowQueryPerHours(forgeSQLORM, 6);\n * ```\n *\n * @throws Does not throw - errors are logged to console.debug instead\n */\nexport async function slowQueryPerHours(\n forgeSQLORM: ForgeSqlOperation,\n hours: number,\n timeout?: number,\n) {\n try {\n const timeoutMs = timeout ?? 1500;\n const results = await withTimeout(\n forgeSQLORM\n .getDrizzleQueryBuilder()\n .select({\n query: withTidbHint(slowQuery.query),\n queryTime: slowQuery.queryTime,\n memMax: slowQuery.memMax,\n plan: slowQuery.plan,\n })\n .from(slowQuery)\n .where(\n and(\n isNotNull(slowQuery.digest),\n ne(slowQuery.sessionAlias, SESSION_ALIAS_NAME_ORM),\n gte(\n slowQuery.time,\n sql`DATE_SUB\n (NOW(), INTERVAL\n ${hours}\n HOUR\n )`,\n ),\n ),\n ),\n `Timeout ${timeoutMs}ms in slowQueryPerHours - transient timeouts are usually fine; repeated timeouts mean this diagnostic query is consistently slow and should be investigated`,\n timeoutMs,\n );\n const response: string[] = [];\n results.forEach((result) => {\n // Convert memory from bytes to MB and handle null values\n const memMaxMB = result.memMax ? Number(result.memMax) / 1_000_000 : 0;\n\n const message = `Found SlowQuery SQL: ${result.query} | Memory: ${memMaxMB.toFixed(2)} MB | Time: ${result.queryTime} ms\\n Plan:${result.plan}`;\n response.push(message);\n // 1. Query info: SQL, memory, time, executions\n // eslint-disable-next-line no-console\n console.warn(message);\n });\n return response;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.debug(\n `Error occurred while retrieving query execution plan: ${error instanceof Error ? error.message : \"Unknown error\"}. Try again after some time`,\n error,\n );\n return [\n `Error occurred while retrieving query execution plan: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ];\n }\n}\n\n/**\n * Executes a promise with a timeout.\n *\n * @param promise - The promise to execute\n * @param timeoutMs - Timeout in milliseconds\n * @returns Promise that resolves with the result or rejects on timeout\n * @throws {Error} When the operation times out\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n message: string,\n timeoutMs: number,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(message));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n}\n\nexport function withTidbHint<\n TDataType extends ColumnDataType,\n TPartial extends Partial<ColumnBaseConfig<TDataType, string>>,\n>(column: AnyMySqlColumn<TPartial>): AnyMySqlColumn<TPartial> {\n // We lie a bit to TypeScript here: at runtime this is a new SQL fragment,\n // but returning TExpr keeps the column type info in downstream inference.\n return sql`/*+ SET_VAR(tidb_session_alias=${sql.raw(`${SESSION_ALIAS_NAME_ORM}`)}) */ ${column}` as unknown as AnyMySqlColumn<TPartial>;\n}\n","import { DateTime } from \"luxon\";\nimport * as crypto from \"crypto\";\nimport { Query } from \"drizzle-orm\";\nimport { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { getTableName } from \"drizzle-orm/table\";\nimport { Filter, FilterConditions, kvs, WhereConditions } from \"@forge/kvs\";\nimport { ForgeSqlOrmOptions } from \"../core/ForgeSQLQueryBuilder\";\nimport { cacheApplicationContext, isTableContainsTableInCacheContext } from \"./cacheContextUtils\";\n\n// Constants for better maintainability\nconst CACHE_CONSTANTS = {\n BATCH_SIZE: 25,\n MAX_RETRY_ATTEMPTS: 3,\n INITIAL_RETRY_DELAY: 1000,\n RETRY_DELAY_MULTIPLIER: 2,\n DEFAULT_ENTITY_QUERY_NAME: \"sql\",\n DEFAULT_EXPIRATION_NAME: \"expiration\",\n DEFAULT_DATA_NAME: \"data\",\n HASH_LENGTH: 32,\n} as const;\n\n// Types for better type safety\ntype CacheEntity = {\n [key: string]: string | number;\n};\n\n/**\n * Gets the current Unix timestamp in seconds.\n *\n * @returns Current timestamp as integer\n */\nfunction getCurrentTime(): number {\n const dt = DateTime.now();\n return Math.floor(dt.toSeconds());\n}\n\n/**\n * Calculates a future timestamp by adding seconds to the current time.\n * Validates that the result is within 32-bit integer range.\n *\n * @param secondsToAdd - Number of seconds to add to current time\n * @returns Future timestamp in seconds\n * @throws Error if the result is out of 32-bit integer range\n */\nfunction nowPlusSeconds(secondsToAdd: number): number {\n const dt = DateTime.now().plus({ seconds: secondsToAdd });\n return Math.floor(dt.toSeconds());\n}\n\n/**\n * Extracts all table/column names between backticks from SQL query and returns them as comma-separated string.\n *\n * @param sql - SQL query string\n * @returns Comma-separated string of unique backticked values\n */\nfunction extractBacktickedValues(sql: string): string {\n const regex = /`([^`]+)`/g;\n const matches = new Set<string>();\n let match;\n\n while ((match = regex.exec(sql.toLowerCase())) !== null) {\n if (!match[1].startsWith(\"a_\")) {\n matches.add(`\\`${match[1]}\\``);\n }\n }\n\n // Sort to ensure consistent order for the same input\n return Array.from(matches).sort().join(\",\");\n}\n\n/**\n * Generates a hash key for a query based on its SQL and parameters.\n *\n * @param query - The Drizzle query object\n * @returns 32-character hexadecimal hash\n */\nexport function hashKey(query: Query): string {\n const h = crypto.createHash(\"sha256\");\n h.update(query.sql.toLowerCase());\n h.update(JSON.stringify(query.params));\n return \"CachedQuery_\" + h.digest(\"hex\").slice(0, CACHE_CONSTANTS.HASH_LENGTH);\n}\n\n/**\n * Deletes cache entries in batches to respect Forge limits and timeouts.\n *\n * @param results - Array of cache entries to delete\n * @param cacheEntityName - Name of the cache entity\n * @returns Promise that resolves when all deletions are complete\n */\nasync function deleteCacheEntriesInBatches(\n results: Array<{ key: string }>,\n cacheEntityName: string,\n): Promise<void> {\n for (let i = 0; i < results.length; i += CACHE_CONSTANTS.BATCH_SIZE) {\n const batch = results.slice(i, i + CACHE_CONSTANTS.BATCH_SIZE);\n let transactionBuilder = kvs.transact();\n batch.forEach((result) => {\n transactionBuilder = transactionBuilder.delete(result.key, { entityName: cacheEntityName });\n });\n await transactionBuilder.execute();\n }\n}\n\n/**\n * Clears cache entries for specific tables using cursor-based pagination.\n *\n * @param tables - Array of table names to clear cache for\n * @param cursor - Pagination cursor for large result sets\n * @param options - ForgeSQL ORM options\n * @returns Total number of deleted cache entries\n */\nasync function clearCursorCache(\n tables: string[],\n cursor: string,\n options: ForgeSqlOrmOptions,\n): Promise<number> {\n const cacheEntityName = options.cacheEntityName;\n if (!cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n const entityQueryName = options.cacheEntityQueryName ?? CACHE_CONSTANTS.DEFAULT_ENTITY_QUERY_NAME;\n let filters = new Filter<{\n [entityQueryName]: string;\n }>();\n\n for (const table of tables) {\n const wrapIfNeeded = options.cacheWrapTable ? `\\`${table}\\`` : table;\n filters.or(entityQueryName, FilterConditions.contains(wrapIfNeeded?.toLowerCase()));\n }\n\n let entityQueryBuilder = kvs\n .entity<{\n [entityQueryName]: string;\n }>(cacheEntityName)\n .query()\n .index(entityQueryName)\n .filters(filters);\n\n if (cursor) {\n entityQueryBuilder = entityQueryBuilder.cursor(cursor);\n }\n\n const listResult = await entityQueryBuilder.limit(100).getMany();\n\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`clear cache Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);\n }\n\n await deleteCacheEntriesInBatches(listResult.results, cacheEntityName);\n\n if (listResult.nextCursor) {\n return (\n listResult.results.length + (await clearCursorCache(tables, listResult.nextCursor, options))\n );\n } else {\n return listResult.results.length;\n }\n}\n\n/**\n * Clears expired cache entries using cursor-based pagination.\n *\n * @param cursor - Pagination cursor for large result sets\n * @param options - ForgeSQL ORM options\n * @returns Total number of deleted expired cache entries\n */\nasync function clearExpirationCursorCache(\n cursor: string,\n options: ForgeSqlOrmOptions,\n): Promise<number> {\n const cacheEntityName = options.cacheEntityName;\n if (!cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n const entityExpirationName =\n options.cacheEntityExpirationName ?? CACHE_CONSTANTS.DEFAULT_EXPIRATION_NAME;\n let entityQueryBuilder = kvs\n .entity<{\n [entityExpirationName]: number;\n }>(cacheEntityName)\n .query()\n .index(entityExpirationName)\n .where(WhereConditions.lessThan(Math.floor(DateTime.now().toSeconds())));\n\n if (cursor) {\n entityQueryBuilder = entityQueryBuilder.cursor(cursor);\n }\n\n const listResult = await entityQueryBuilder.limit(100).getMany();\n\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`clear expired Records: ${JSON.stringify(listResult.results.map((r) => r.key))}`);\n }\n\n await deleteCacheEntriesInBatches(listResult.results, cacheEntityName);\n\n if (listResult.nextCursor) {\n return (\n listResult.results.length + (await clearExpirationCursorCache(listResult.nextCursor, options))\n );\n } else {\n return listResult.results.length;\n }\n}\n\n/**\n * Executes a function with retry logic and exponential backoff.\n *\n * @param operation - Function to execute with retry\n * @param operationName - Name of the operation for logging\n * @param options - ForgeSQL ORM options for logging\n * @returns Promise that resolves to the operation result\n */\nasync function executeWithRetry<T>(operation: () => Promise<T>, operationName: string): Promise<T> {\n let attempt = 0;\n let delay = CACHE_CONSTANTS.INITIAL_RETRY_DELAY;\n\n while (attempt < CACHE_CONSTANTS.MAX_RETRY_ATTEMPTS) {\n try {\n return await operation();\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.warn(`Error during ${operationName}: ${err.message}, retry ${attempt}`, err);\n attempt++;\n\n if (attempt >= CACHE_CONSTANTS.MAX_RETRY_ATTEMPTS) {\n // eslint-disable-next-line no-console\n console.error(`Error during ${operationName}: ${err.message}`, err);\n throw err;\n }\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n delay *= CACHE_CONSTANTS.RETRY_DELAY_MULTIPLIER;\n }\n }\n\n throw new Error(`Maximum retry attempts exceeded for ${operationName}`);\n}\n\n/**\n * Clears cache for a specific table.\n * Uses cache context if available, otherwise clears immediately.\n *\n * @param schema - The table schema to clear cache for\n * @param options - ForgeSQL ORM options\n */\nexport async function clearCache<T extends AnyMySqlTable>(\n schema: T,\n options: ForgeSqlOrmOptions,\n): Promise<void> {\n const tableName = getTableName(schema);\n if (cacheApplicationContext.getStore()) {\n cacheApplicationContext.getStore()?.tables.add(tableName);\n } else {\n await clearTablesCache([tableName], options);\n }\n}\n\n/**\n * Clears cache for multiple tables with retry logic and performance logging.\n *\n * @param tables - Array of table names to clear cache for\n * @param options - ForgeSQL ORM options\n * @returns Promise that resolves when cache clearing is complete\n */\nexport async function clearTablesCache(\n tables: string[],\n options: ForgeSqlOrmOptions,\n): Promise<void> {\n if (!options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n const startTime = DateTime.now();\n let totalRecords = 0;\n\n try {\n totalRecords = await executeWithRetry(\n () => clearCursorCache(tables, \"\", options),\n \"clearing cache\",\n );\n } finally {\n if (options.logCache) {\n const duration = DateTime.now().toSeconds() - startTime.toSeconds();\n // eslint-disable-next-line no-console\n console.info(`Cleared ${totalRecords} cache records in ${duration} seconds`);\n }\n }\n}\n/**\n * Clears expired cache entries with retry logic and performance logging.\n *\n * @param options - ForgeSQL ORM options\n * @returns Promise that resolves when expired cache clearing is complete\n */\nexport async function clearExpiredCache(options: ForgeSqlOrmOptions): Promise<void> {\n if (!options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n const startTime = DateTime.now();\n let totalRecords = 0;\n\n try {\n totalRecords = await executeWithRetry(\n () => clearExpirationCursorCache(\"\", options),\n \"clearing expired cache\",\n );\n } finally {\n const duration = DateTime.now().toSeconds() - startTime.toSeconds();\n if (options?.logCache) {\n // eslint-disable-next-line no-console\n console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);\n }\n }\n}\n\n/**\n * Retrieves data from cache if it exists and is not expired.\n *\n * @param query - Query object with toSQL method\n * @param options - ForgeSQL ORM options\n * @returns Cached data if found and valid, undefined otherwise\n */\nexport async function getFromCache<T>(\n query: { toSQL: () => Query },\n options: ForgeSqlOrmOptions,\n): Promise<T | undefined> {\n if (!options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n const entityQueryName = options.cacheEntityQueryName ?? CACHE_CONSTANTS.DEFAULT_ENTITY_QUERY_NAME;\n const expirationName =\n options.cacheEntityExpirationName ?? CACHE_CONSTANTS.DEFAULT_EXPIRATION_NAME;\n const dataName = options.cacheEntityDataName ?? CACHE_CONSTANTS.DEFAULT_DATA_NAME;\n\n const sqlQuery = query.toSQL();\n const key = hashKey(sqlQuery);\n\n // Skip cache if table is in cache context (will be cleared)\n if (await isTableContainsTableInCacheContext(sqlQuery.sql, options)) {\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`Context contains value to clear. Skip getting from cache`);\n }\n return undefined;\n }\n\n try {\n const cacheResult = (await kvs.entity<CacheEntity>(options.cacheEntityName).get(key)) as\n | CacheEntity\n | undefined;\n\n if (\n cacheResult &&\n (cacheResult[expirationName] as number) >= getCurrentTime() &&\n extractBacktickedValues(sqlQuery.sql) === cacheResult[entityQueryName]\n ) {\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`Get value from cache, cacheKey: ${key}`);\n }\n const results = cacheResult[dataName];\n return JSON.parse(results as string);\n }\n } catch (error: any) {\n // eslint-disable-next-line no-console\n console.error(`Error getting from cache: ${error.message}`, error);\n }\n\n return undefined;\n}\n\n/**\n * Stores query results in cache with specified TTL.\n *\n * @param query - Query object with toSQL method\n * @param options - ForgeSQL ORM options\n * @param results - Data to cache\n * @param cacheTtl - Time to live in seconds\n * @returns Promise that resolves when data is stored in cache\n */\nexport async function setCacheResult(\n query: { toSQL: () => Query },\n options: ForgeSqlOrmOptions,\n results: unknown,\n cacheTtl: number,\n): Promise<void> {\n if (!options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n\n try {\n const entityQueryName =\n options.cacheEntityQueryName ?? CACHE_CONSTANTS.DEFAULT_ENTITY_QUERY_NAME;\n const expirationName =\n options.cacheEntityExpirationName ?? CACHE_CONSTANTS.DEFAULT_EXPIRATION_NAME;\n const dataName = options.cacheEntityDataName ?? CACHE_CONSTANTS.DEFAULT_DATA_NAME;\n\n const sqlQuery = query.toSQL();\n\n // Skip cache if table is in cache context (will be cleared)\n if (await isTableContainsTableInCacheContext(sqlQuery.sql, options)) {\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`Context contains value to clear. Skip setting from cache`);\n }\n return;\n }\n\n const key = hashKey(sqlQuery);\n\n await kvs\n .transact()\n .set(\n key,\n {\n [entityQueryName]: extractBacktickedValues(sqlQuery.sql),\n [expirationName]: nowPlusSeconds(cacheTtl),\n [dataName]: JSON.stringify(results),\n },\n { entityName: options.cacheEntityName },\n )\n .execute();\n\n if (options.logCache) {\n // eslint-disable-next-line no-console\n console.warn(`Store value to cache, cacheKey: ${key}`);\n }\n } catch (error: any) {\n // eslint-disable-next-line no-console\n console.error(`Error setting cache: ${error.message}`, error);\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { AnyMySqlSelectQueryBuilder, AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { getTableName } from \"drizzle-orm/table\";\nimport { ForgeSqlOrmOptions } from \"../core/ForgeSQLQueryBuilder\";\nimport { MySqlSelectDynamic } from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { hashKey } from \"./cacheUtils\";\nimport { Query } from \"drizzle-orm/sql/sql\";\n\n/**\n * Interface representing the cache application context.\n * Stores information about tables that are being processed within a cache context.\n */\nexport interface CacheApplicationContext {\n /** Set of table names (in lowercase) that are being processed within the cache context */\n tables: Set<string>;\n}\n\n/**\n * Interface representing the local cache application context.\n * Stores cached query results in memory for the duration of a local cache context.\n *\n * @interface LocalCacheApplicationContext\n */\nexport interface LocalCacheApplicationContext {\n /**\n * Cache object mapping query hash keys to cached results\n * @property {Record<string, {sql: string, data: unknown[]}>} cache - Map of query keys to cached data\n */\n cache: Record<\n string,\n {\n sql: string;\n data: unknown[];\n }\n >;\n}\n\nfunction isQuery(obj: any): obj is Query {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n typeof obj.sql === \"string\" &&\n Array.isArray(obj.params)\n );\n}\n\n/**\n * AsyncLocalStorage instance for managing cache context across async operations.\n * This allows tracking which tables are being processed within a cache context\n * without explicitly passing context through function parameters.\n */\nexport const cacheApplicationContext = new AsyncLocalStorage<CacheApplicationContext>();\n\n/**\n * AsyncLocalStorage instance for managing local cache context across async operations.\n * This allows storing and retrieving cached query results within a local cache context\n * without explicitly passing context through function parameters.\n */\nexport const localCacheApplicationContext = new AsyncLocalStorage<LocalCacheApplicationContext>();\n\n/**\n * Saves a table name to the current cache context if one exists.\n * This function is used to track which tables are being processed within\n * a cache context for proper cache invalidation.\n *\n * @param table - The Drizzle table schema to track\n * @returns Promise that resolves when the table is saved to context\n *\n * @example\n * ```typescript\n * await saveTableIfInsideCacheContext(usersTable);\n * ```\n */\nexport async function saveTableIfInsideCacheContext<T extends AnyMySqlTable>(\n table: T,\n): Promise<void> {\n const context = cacheApplicationContext.getStore();\n if (context) {\n const tableName = getTableName(table).toLowerCase();\n context.tables.add(tableName);\n }\n}\n\n/**\n * Saves a query result to the local cache context.\n * This function stores query results in memory for the duration of the local cache context.\n *\n * @param query - The Drizzle query to cache\n * @param rows - The query result data to cache\n * @param options - ForgeSqlOrm options\n * @returns Promise that resolves when the data is saved to local cache\n *\n * @example\n * ```typescript\n * const query = db.select({ id: users.id, name: users.name }).from(users);\n * const results = await query.execute();\n * await saveQueryLocalCacheQuery(query, results);\n * ```\n */\nexport async function saveQueryLocalCacheQuery<\n T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>,\n>(query: T, rows: unknown[], options: ForgeSqlOrmOptions): Promise<void> {\n const context = localCacheApplicationContext.getStore();\n if (context) {\n if (!context.cache) {\n context.cache = {};\n }\n let sql: { toSQL: () => Query };\n if (isQuery(query)) {\n sql = { toSQL: () => query };\n } else {\n sql = query as { toSQL: () => Query };\n }\n\n const key = hashKey(sql.toSQL());\n context.cache[key] = {\n sql: sql.toSQL().sql.toLowerCase(),\n data: rows,\n };\n if (options.logCache) {\n const q = sql.toSQL();\n // eslint-disable-next-line no-console\n console.debug(\n `[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql=\"${q.sql}\", params=${JSON.stringify(q.params)}`,\n );\n }\n }\n}\n\n/**\n * Retrieves a query result from the local cache context.\n * This function checks if a query result is already cached in memory.\n *\n * @param query - The Drizzle query to check for cached results\n * @param options - Option Property\n * @returns Promise that resolves to cached data if found, undefined otherwise\n *\n * @example\n * ```typescript\n * const query = db.select({ id: users.id, name: users.name }).from(users);\n * const cachedResult = await getQueryLocalCacheQuery(query);\n * if (cachedResult) {\n * return cachedResult; // Use cached data\n * }\n * // Execute query and cache result\n * ```\n */\nexport async function getQueryLocalCacheQuery<\n T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>,\n>(query: T, options: ForgeSqlOrmOptions): Promise<unknown[] | undefined> {\n const context = localCacheApplicationContext.getStore();\n if (context) {\n if (!context.cache) {\n context.cache = {};\n }\n let sql: { toSQL: () => Query };\n if (isQuery(query)) {\n sql = { toSQL: () => query };\n } else {\n sql = query as { toSQL: () => Query };\n }\n const key = hashKey(sql.toSQL());\n if (context.cache[key] && context.cache[key].sql === sql.toSQL().sql.toLowerCase()) {\n if (options.logCache) {\n const q = sql.toSQL();\n // eslint-disable-next-line no-console\n console.debug(\n `[forge-sql-orm][local-cache][HIT] Returned cached result. sql=\"${q.sql}\", params=${JSON.stringify(q.params)}`,\n );\n }\n return context.cache[key].data;\n }\n }\n return undefined;\n}\n\n/**\n * Evicts cached queries from the local cache context that involve the specified table.\n * This function removes cached query results that contain the given table name.\n *\n * @param table - The Drizzle table schema to evict cache for\n * @param options - ForgeSQL ORM options containing cache configuration\n * @returns Promise that resolves when cache eviction is complete\n *\n * @example\n * ```typescript\n * // After inserting/updating/deleting from users table\n * await evictLocalCacheQuery(usersTable, forgeSqlOptions);\n * // All cached queries involving users table are now removed\n * ```\n */\nexport async function evictLocalCacheQuery<T extends AnyMySqlTable>(\n table: T,\n options: ForgeSqlOrmOptions,\n): Promise<void> {\n const context = localCacheApplicationContext.getStore();\n if (context) {\n if (!context.cache) {\n context.cache = {};\n }\n const tableName = getTableName(table);\n const searchString = options.cacheWrapTable ? `\\`${tableName}\\`` : tableName;\n const keyToEvicts: string[] = [];\n Object.keys(context.cache).forEach((key) => {\n if (context.cache[key].sql.includes(searchString)) {\n keyToEvicts.push(key);\n }\n });\n keyToEvicts.forEach((key) => delete context.cache[key]);\n }\n}\n\n/**\n * Checks if the given SQL query contains any tables that are currently being processed\n * within a cache context. This is used to determine if cache should be bypassed\n * for queries that affect tables being modified within the context.\n *\n * @param sql - The SQL query string to check\n * @param options - ForgeSQL ORM options containing cache configuration\n * @returns Promise that resolves to true if the SQL contains tables in cache context\n *\n * @example\n * ```typescript\n * const shouldBypassCache = await isTableContainsTableInCacheContext(\n * \"SELECT * FROM users WHERE id = 1\",\n * forgeSqlOptions\n * );\n * ```\n */\nexport async function isTableContainsTableInCacheContext(\n sql: string,\n options: ForgeSqlOrmOptions,\n): Promise<boolean> {\n const context = cacheApplicationContext.getStore();\n if (!context) {\n return false;\n }\n\n const tables = Array.from(context.tables);\n const lowerSql = sql.toLowerCase();\n\n return tables.some((table) => {\n const tablePattern = options.cacheWrapTable ? `\\`${table}\\`` : table;\n return lowerSql.includes(tablePattern);\n });\n}\n","import { ForgeSqlOrmOptions } from \"..\";\nimport { VerioningModificationForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\nimport { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { and, AnyColumn, eq, InferInsertModel, SQL } from \"drizzle-orm\";\nimport { getPrimaryKeys, getTableMetadata } from \"../utils/sqlUtils\";\nimport { saveTableIfInsideCacheContext } from \"../utils/cacheContextUtils\";\n\n/**\n * Class implementing Modification operations for ForgeSQL ORM.\n * Provides methods for inserting, updating, and deleting records with support for optimistic locking.\n */\nexport class ForgeSQLCrudOperations implements VerioningModificationForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n private readonly options: ForgeSqlOrmOptions;\n\n /**\n * Creates a new instance of ForgeSQLCrudOperations.\n * @param forgeSqlOperations - The ForgeSQL operations instance\n * @param options - Configuration options for the ORM\n */\n constructor(forgeSqlOperations: ForgeSqlOperation, options: ForgeSqlOrmOptions) {\n this.forgeOperations = forgeSqlOperations;\n this.options = options;\n }\n\n /**\n * Inserts records into the database with optional versioning support.\n * If a version field exists in the schema, versioning is applied.\n *\n * This method automatically handles:\n * - Version field initialization for optimistic locking\n * - Batch insertion for multiple records\n * - Duplicate key handling with optional updates\n *\n * @template T - The type of the table schema\n * @param schema - The entity schema\n * @param models - Array of entities to insert\n * @param updateIfExists - Whether to update existing records (default: false)\n * @returns Promise that resolves to the number of inserted rows\n * @throws Error if the insert operation fails\n */\n async insert<T extends AnyMySqlTable>(\n schema: T,\n models: InferInsertModel<T>[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models?.length) return 0;\n\n const { tableName, columns } = getTableMetadata(schema);\n const versionMetadata = this.validateVersionField(tableName, columns);\n\n // Prepare models with version field if needed\n const preparedModels = models.map((model) =>\n this.prepareModelWithVersion(model, versionMetadata, columns),\n );\n\n // Build insert query\n const queryBuilder = this.forgeOperations.insert(schema).values(preparedModels);\n\n // Add onDuplicateKeyUpdate if needed\n const finalQuery = updateIfExists\n ? queryBuilder.onDuplicateKeyUpdate({\n set: Object.fromEntries(\n Object.keys(preparedModels[0]).map((key) => [key, (schema as any)[key]]),\n ) as any,\n })\n : queryBuilder;\n\n // Execute query\n const result = await finalQuery;\n await saveTableIfInsideCacheContext(schema);\n return result[0].insertId;\n }\n\n /**\n * Deletes a record by its primary key with optional version check.\n * If versioning is enabled, ensures the record hasn't been modified since last read.\n *\n * This method automatically handles:\n * - Single primary key validation\n * - Optimistic locking checks if versioning is enabled\n * - Version field validation before deletion\n *\n * @template T - The type of the table schema\n * @param id - The ID of the record to delete\n * @param schema - The entity schema\n * @returns Promise that resolves to the number of affected rows\n * @throws Error if the delete operation fails\n * @throws Error if multiple primary keys are found\n * @throws Error if optimistic locking check fails\n */\n async deleteById<T extends AnyMySqlTable>(id: unknown, schema: T): Promise<number> {\n const { tableName, columns } = getTableMetadata(schema);\n const primaryKeys = this.getPrimaryKeys(schema);\n\n if (primaryKeys.length !== 1) {\n throw new Error(\"Only single primary key is supported\");\n }\n\n const [primaryKeyName, primaryKeyColumn] = primaryKeys[0];\n const versionMetadata = this.validateVersionField(tableName, columns);\n\n // Build delete conditions\n const conditions: SQL<unknown>[] = [eq(primaryKeyColumn, id)];\n\n // Add version check if needed\n if (versionMetadata && columns) {\n const versionField = columns[versionMetadata.fieldName];\n if (versionField) {\n const oldModel = await this.getOldModel({ [primaryKeyName]: id }, schema, [\n versionMetadata.fieldName,\n versionField,\n ]);\n conditions.push(eq(versionField, (oldModel as any)[versionMetadata.fieldName]));\n }\n }\n\n // Execute delete query\n const queryBuilder = this.forgeOperations.delete(schema).where(and(...conditions));\n\n const result = await queryBuilder;\n if (versionMetadata && result[0].affectedRows === 0) {\n throw new Error(`Optimistic locking failed: record with primary key ${id} has been modified`);\n }\n await saveTableIfInsideCacheContext(schema);\n return result[0].affectedRows;\n }\n\n /**\n * Updates a record by its primary key with optimistic locking support.\n * If versioning is enabled:\n * - Retrieves the current version\n * - Checks for concurrent modifications\n * - Increments the version on successful update\n *\n * This method automatically handles:\n * - Primary key validation\n * - Version field retrieval and validation\n * - Optimistic locking conflict detection\n * - Version field incrementation\n *\n * @template T - The type of the table schema\n * @param entity - The entity with updated values (must include primary key)\n * @param schema - The entity schema\n * @returns Promise that resolves to the number of affected rows\n * @throws Error if the primary key is not provided\n * @throws Error if optimistic locking check fails\n * @throws Error if multiple primary keys are found\n */\n async updateById<T extends AnyMySqlTable>(\n entity: Partial<InferInsertModel<T>>,\n schema: T,\n ): Promise<number> {\n const { tableName, columns } = getTableMetadata(schema);\n const primaryKeys = this.getPrimaryKeys(schema);\n\n if (primaryKeys.length !== 1) {\n throw new Error(\"Only single primary key is supported\");\n }\n\n const [primaryKeyName, primaryKeyColumn] = primaryKeys[0];\n const versionMetadata = this.validateVersionField(tableName, columns);\n\n // Validate primary key\n if (!(primaryKeyName in entity)) {\n throw new Error(`Primary key ${primaryKeyName} must be provided in the entity`);\n }\n\n // Get current version if needed\n const currentVersion = await this.getCurrentVersion(\n entity,\n primaryKeyName,\n versionMetadata,\n columns,\n schema,\n );\n\n // Prepare update data with version\n const updateData = this.prepareUpdateData(entity, versionMetadata, columns, currentVersion);\n\n // Build update conditions\n const conditions: SQL<unknown>[] = [\n eq(primaryKeyColumn, entity[primaryKeyName as keyof typeof entity]),\n ];\n if (versionMetadata && columns) {\n const versionField = columns[versionMetadata.fieldName];\n if (versionField) {\n conditions.push(eq(versionField, currentVersion));\n }\n }\n\n // Execute update query\n const queryBuilder = this.forgeOperations\n .update(schema)\n .set(updateData)\n .where(and(...conditions));\n\n const result = await queryBuilder;\n // Check optimistic locking\n if (versionMetadata && result[0].affectedRows === 0) {\n throw new Error(\n `Optimistic locking failed: record with primary key ${entity[primaryKeyName as keyof typeof entity]} has been modified`,\n );\n }\n await saveTableIfInsideCacheContext(schema);\n return result[0].affectedRows;\n }\n\n /**\n * Updates specified fields of records based on provided conditions.\n * This method does not support versioning and should be used with caution.\n *\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} updateData - The data to update\n * @param {T} schema - The entity schema\n * @param {SQL<unknown>} where - The WHERE conditions\n * @returns {Promise<number>} Number of affected rows\n * @throws {Error} If WHERE conditions are not provided\n * @throws {Error} If the update operation fails\n */\n async updateFields<T extends AnyMySqlTable>(\n updateData: Partial<InferInsertModel<T>>,\n schema: T,\n where?: SQL<unknown>,\n ): Promise<number> {\n if (!where) {\n throw new Error(\"WHERE conditions must be provided\");\n }\n\n const queryBuilder = this.forgeOperations.update(schema).set(updateData).where(where);\n\n const result = await queryBuilder;\n await saveTableIfInsideCacheContext(schema);\n return result[0].affectedRows;\n }\n\n // Helper methods\n\n /**\n * Gets primary keys from the schema.\n * @template T - The type of the table schema\n * @param {T} schema - The table schema\n * @returns {[string, AnyColumn][]} Array of primary key name and column pairs\n * @throws {Error} If no primary keys are found\n */\n private getPrimaryKeys<T extends AnyMySqlTable>(schema: T): [string, AnyColumn][] {\n const primaryKeys = getPrimaryKeys(schema);\n if (!primaryKeys) {\n throw new Error(`No primary keys found for schema: ${schema}`);\n }\n\n return primaryKeys;\n }\n\n /**\n * Validates and retrieves version field metadata.\n * @param {string} tableName - The name of the table\n * @param {Record<string, AnyColumn>} columns - The table columns\n * @returns {Object | undefined} Version field metadata if valid, undefined otherwise\n */\n private validateVersionField(\n tableName: string,\n columns: Record<string, AnyColumn>,\n ): { fieldName: string; type: string } | undefined {\n if (this.options.disableOptimisticLocking) {\n return undefined;\n }\n const versionMetadata = this.options.additionalMetadata?.[tableName]?.versionField;\n if (!versionMetadata) return undefined;\n let fieldName = versionMetadata.fieldName;\n\n let versionField = columns[versionMetadata.fieldName];\n if (!versionField) {\n const find = Object.entries(columns).find(([, c]) => c.name === versionMetadata.fieldName);\n if (find) {\n fieldName = find[0];\n versionField = find[1];\n }\n }\n if (!versionField) {\n // eslint-disable-next-line no-console\n console.warn(\n `Version field \"${versionMetadata.fieldName}\" not found in table ${tableName}. Versioning will be skipped.`,\n );\n return undefined;\n }\n\n if (!versionField.notNull) {\n // eslint-disable-next-line no-console\n console.warn(\n `Version field \"${versionMetadata.fieldName}\" in table ${tableName} is nullable. Versioning may not work correctly.`,\n );\n return undefined;\n }\n\n const fieldType = versionField.getSQLType();\n const isSupportedType =\n fieldType === \"datetime\" ||\n fieldType === \"timestamp\" ||\n fieldType === \"int\" ||\n fieldType === \"number\" ||\n fieldType === \"decimal\";\n\n if (!isSupportedType) {\n // eslint-disable-next-line no-console\n console.warn(\n `Version field \"${versionMetadata.fieldName}\" in table ${tableName} has unsupported type \"${fieldType}\". ` +\n `Only datetime, timestamp, int, and decimal types are supported for versioning. Versioning will be skipped.`,\n );\n return undefined;\n }\n\n return { fieldName, type: fieldType };\n }\n\n /**\n * Gets the current version of an entity.\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} entity - The entity\n * @param {string} primaryKeyName - The name of the primary key\n * @param {Object | undefined} versionMetadata - Version field metadata\n * @param {Record<string, AnyColumn>} columns - The table columns\n * @param {T} schema - The table schema\n * @returns {Promise<unknown>} The current version value\n */\n private async getCurrentVersion<T extends AnyMySqlTable>(\n entity: Partial<InferInsertModel<T>>,\n primaryKeyName: string,\n versionMetadata: { fieldName: string; type: string } | undefined,\n columns: Record<string, AnyColumn>,\n schema: T,\n ): Promise<unknown> {\n if (!versionMetadata || !columns) return undefined;\n\n const versionField = columns[versionMetadata.fieldName];\n if (!versionField) return undefined;\n\n if (versionMetadata.fieldName in entity) {\n return entity[versionMetadata.fieldName as keyof typeof entity];\n }\n\n const oldModel = await this.getOldModel(\n { [primaryKeyName]: entity[primaryKeyName as keyof typeof entity] },\n schema,\n [versionMetadata.fieldName, versionField],\n );\n\n return (oldModel as any)[versionMetadata.fieldName];\n }\n\n /**\n * Prepares a model for insertion with version field.\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} model - The model to prepare\n * @param {Object | undefined} versionMetadata - Version field metadata\n * @param {Record<string, AnyColumn>} columns - The table columns\n * @returns {InferInsertModel<T>} The prepared model\n */\n private prepareModelWithVersion<T extends AnyMySqlTable>(\n model: Partial<InferInsertModel<T>>,\n versionMetadata: { fieldName: string; type: string } | undefined,\n columns: Record<string, AnyColumn>,\n ): InferInsertModel<T> {\n if (!versionMetadata || !columns) return model as InferInsertModel<T>;\n let fieldName = versionMetadata.fieldName;\n let versionField = columns[versionMetadata.fieldName];\n if (!versionField) {\n const find = Object.entries(columns).find(([, c]) => c.name === versionMetadata.fieldName);\n if (find) {\n fieldName = find[0];\n versionField = find[1];\n }\n }\n\n if (!versionField) return model as InferInsertModel<T>;\n\n const modelWithVersion = { ...model };\n const fieldType = versionField.getSQLType();\n const versionValue = fieldType === \"datetime\" || fieldType === \"timestamp\" ? new Date() : 1;\n modelWithVersion[fieldName as keyof typeof modelWithVersion] = versionValue as any;\n\n return modelWithVersion as InferInsertModel<T>;\n }\n\n /**\n * Prepares update data with version field.\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} entity - The entity to update\n * @param {Object | undefined} versionMetadata - Version field metadata\n * @param {Record<string, AnyColumn>} columns - The table columns\n * @param {unknown} currentVersion - The current version value\n * @returns {Partial<InferInsertModel<T>>} The prepared update data\n */\n private prepareUpdateData<T extends AnyMySqlTable>(\n entity: Partial<InferInsertModel<T>>,\n versionMetadata: { fieldName: string; type: string } | undefined,\n columns: Record<string, AnyColumn>,\n currentVersion: unknown,\n ): Partial<InferInsertModel<T>> {\n const updateData = { ...entity };\n\n if (versionMetadata && columns) {\n const versionField = columns[versionMetadata.fieldName];\n if (versionField) {\n const fieldType = versionField.getSQLType();\n updateData[versionMetadata.fieldName as keyof typeof updateData] =\n fieldType === \"datetime\" || fieldType === \"timestamp\"\n ? new Date()\n : (((currentVersion as number) + 1) as any);\n }\n }\n\n return updateData;\n }\n\n /**\n * Retrieves an existing model by primary key.\n * @template T - The type of the table schema\n * @param {Record<string, unknown>} primaryKeyValues - The primary key values\n * @param {T} schema - The table schema\n * @param {[string, AnyColumn]} versionField - The version field name and column\n * @returns {Promise<Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined>} The existing model\n * @throws {Error} If the record is not found\n */\n private async getOldModel<T extends AnyMySqlTable>(\n primaryKeyValues: Record<string, unknown>,\n schema: T,\n versionField: [string, AnyColumn],\n ): Promise<\n Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined\n > {\n const [versionFieldName, versionFieldColumn] = versionField;\n const primaryKeys = this.getPrimaryKeys(schema);\n const [primaryKeyName, primaryKeyColumn] = primaryKeys[0];\n\n const resultQuery = this.forgeOperations\n .select({\n [primaryKeyName]: primaryKeyColumn as any,\n [versionFieldName]: versionFieldColumn as any,\n })\n .from(schema)\n .where(eq(primaryKeyColumn, primaryKeyValues[primaryKeyName]));\n\n const model = await this.forgeOperations.fetch().executeQueryOnlyOne(resultQuery);\n\n if (!model) {\n throw new Error(`Record not found in table ${schema}`);\n }\n\n return model as Awaited<T> extends Array<any> ? Awaited<T>[number] : Awaited<T>;\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport { ForgeSqlOrmOptions, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\nimport {\n AnyMySqlSelectQueryBuilder,\n MySqlSelectDynamic,\n} from \"drizzle-orm/mysql-core/query-builders/select.types\";\n\n/**\n * Class implementing SQL select operations for ForgeSQL ORM.\n * Provides methods for executing queries and mapping results to entity types.\n */\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n private readonly options: ForgeSqlOrmOptions;\n\n /**\n * Creates a new instance of ForgeSQLSelectOperations.\n * @param {ForgeSqlOrmOptions} options - Configuration options for the ORM\n */\n constructor(options: ForgeSqlOrmOptions) {\n this.options = options;\n }\n\n /**\n * Executes a Drizzle query and returns a single result.\n * Throws an error if more than one record is returned.\n *\n * @template T - The type of the query builder\n * @param {T} query - The Drizzle query to execute\n * @returns {Promise<Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined>} A single result object or undefined\n * @throws {Error} If more than one record is returned\n */\n async executeQueryOnlyOne<T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>>(\n query: T,\n ): Promise<\n Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined\n > {\n const results: Awaited<T> = await query;\n const datas = results as unknown[];\n if (!datas.length) {\n return undefined;\n }\n if (datas.length > 1) {\n throw new Error(`Expected 1 record but returned ${datas.length}`);\n }\n\n return datas[0] as Awaited<T> extends Array<any> ? Awaited<T>[number] : Awaited<T>;\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * Logs the query if logging is enabled.\n *\n * @template T - The type of the result objects\n * @param {string} query - The raw SQL query to execute\n * @param {SqlParameters[]} [params] - Optional SQL parameters\n * @returns {Promise<T[]>} A list of results as objects\n */\n async executeRawSQL<T extends object | unknown>(query: string, params?: unknown[]): Promise<T[]> {\n if (this.options.logRawSqlQuery) {\n const paramsStr = params ? `, with params: ${JSON.stringify(params)}` : \"\";\n // eslint-disable-next-line no-console\n console.debug(`Executing with SQL ${query}${paramsStr}`);\n }\n const sqlStatement = sql.prepare<T>(query);\n if (params) {\n sqlStatement.bindParams(...params);\n }\n const result = await sqlStatement.execute();\n return result.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param {string} query - The raw SQL update query\n * @param {SqlParameters[]} [params] - Optional SQL parameters\n * @returns {Promise<UpdateQueryResponse>} The update response containing affected rows\n */\n async executeRawUpdateSQL(query: string, params?: unknown[]): Promise<UpdateQueryResponse> {\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n if (params) {\n sqlStatement.bindParams(...params);\n }\n if (this.options.logRawSqlQuery) {\n // eslint-disable-next-line no-console\n console.debug(\n `Executing Update with SQL ${query}` +\n (params ? `, with params: ${JSON.stringify(params)}` : \"\"),\n );\n }\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ForgeSQLMetadata } from \"./forgeDriver\";\nimport { ForgeSqlOperation } from \"../core/ForgeSQLQueryBuilder\";\nimport { printQueriesWithPlan } from \"./sqlUtils\";\n\nexport type MetadataQueryContext = {\n totalDbExecutionTime: number;\n totalResponseSize: number;\n beginTime: Date;\n printQueriesWithPlan: () => Promise<void>;\n forgeSQLORM: ForgeSqlOperation;\n};\nexport const metadataQueryContext = new AsyncLocalStorage<MetadataQueryContext>();\n\nexport async function saveMetaDataToContext(metadata?: ForgeSQLMetadata): Promise<void> {\n const context = metadataQueryContext.getStore();\n if (context) {\n context.printQueriesWithPlan = async () => {\n if (process.env.NODE_ENV !== \"test\") {\n await new Promise((r) => setTimeout(r, 200));\n }\n await printQueriesWithPlan(context.forgeSQLORM, Date.now() - context.beginTime.getTime());\n };\n if (metadata) {\n context.totalResponseSize += metadata.responseSize;\n context.totalDbExecutionTime += metadata.dbExecutionTime;\n }\n // Log the results to console\n }\n}\n\nexport async function getLastestMetadata(): Promise<MetadataQueryContext | undefined> {\n return metadataQueryContext.getStore();\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nexport type OperationType = \"DML\" | \"DDL\";\n\nexport type OperationTypeQueryContext = {\n operationType: OperationType;\n};\nexport const operationTypeQueryContext = new AsyncLocalStorage<OperationTypeQueryContext>();\n\nexport async function getOperationType(): Promise<OperationType> {\n return operationTypeQueryContext.getStore()?.operationType ?? \"DML\";\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport { saveMetaDataToContext } from \"./metadataContextUtils\";\nimport { getOperationType } from \"./requestTypeContextUtils\";\nimport { withTimeout } from \"./sqlUtils\";\n\nconst timeoutMs = 10000;\nconst timeoutMessage = `Atlassian @forge/sql did not return a response within ${timeoutMs}ms (${timeoutMs / 1000} seconds), so the request is blocked. Possible causes: slow query, network issues, or exceeding Forge SQL limits.`;\n\n/**\n * Metadata structure for Forge SQL query results.\n * Contains execution timing, response size, and field information.\n */\nexport type ForgeSQLMetadata = {\n dbExecutionTime: number;\n responseSize: number;\n fields: {\n catalog: string;\n name: string;\n schema: string;\n characterSet: number;\n decimals: number;\n table: string;\n orgTable: string;\n orgName: string;\n flags: number;\n columnType: number;\n columnLength: number;\n }[];\n};\n\n/**\n * Result structure for Forge SQL queries.\n * Contains rows data and execution metadata.\n */\nexport interface ForgeSQLResult {\n rows: Record<string, unknown>[] | Record<string, unknown>;\n metadata: ForgeSQLMetadata;\n}\n\n/**\n * Driver result structure for Drizzle ORM compatibility.\n */\nexport interface ForgeDriverResult {\n rows: unknown[];\n insertId?: number;\n affectedRows?: number;\n}\n\n/**\n * Query execution method types.\n */\nexport type QueryMethod = \"all\" | \"execute\";\n\n/**\n * Type guard to check if an object is an UpdateQueryResponse.\n *\n * @param obj - The object to check\n * @returns True if the object is an UpdateQueryResponse\n */\nexport function isUpdateQueryResponse(obj: unknown): obj is UpdateQueryResponse {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n typeof (obj as any).affectedRows === \"number\" &&\n typeof (obj as any).insertId === \"number\"\n );\n}\n\nfunction inlineParams(sql: string, params: unknown[]): string {\n let i = 0;\n return sql.replace(/\\?/g, () => {\n const val = params[i++];\n if (val === null) return \"NULL\";\n if (typeof val === \"number\") return val.toString();\n return `'${String(val).replace(/'/g, \"''\")}'`;\n });\n}\n\n/**\n * Processes DDL query results and saves metadata.\n *\n * @param result - The DDL query result\n * @returns Processed result for Drizzle ORM\n */\nasync function processDDLResult(method: QueryMethod, result: any): Promise<ForgeDriverResult> {\n if (result.metadata) {\n await saveMetaDataToContext(result.metadata as ForgeSQLMetadata);\n }\n\n if (!result?.rows) {\n return { rows: [] };\n }\n\n if (isUpdateQueryResponse(result.rows)) {\n const oneRow = result.rows as any;\n return { ...oneRow, rows: [oneRow] };\n }\n\n if (Array.isArray(result.rows)) {\n if (method === \"execute\") {\n return { rows: [result.rows] };\n } else {\n const rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));\n return { rows };\n }\n }\n\n return { rows: [] };\n}\n\n/**\n * Processes execute method results (UPDATE, INSERT, DELETE).\n *\n * @param query - The SQL query\n * @param params - Query parameters\n * @returns Processed result for Drizzle ORM\n */\nasync function processExecuteMethod(query: string, params: unknown[]): Promise<ForgeDriverResult> {\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n\n if (params) {\n sqlStatement.bindParams(...params);\n }\n\n const result = await withTimeout(sqlStatement.execute(), timeoutMessage, timeoutMs);\n await saveMetaDataToContext(result.metadata as ForgeSQLMetadata);\n if (!result.rows) {\n return { rows: [[]] };\n }\n\n return { rows: [result.rows] };\n}\n\n/**\n * Processes all method results (SELECT queries).\n *\n * @param query - The SQL query\n * @param params - Query parameters\n * @returns Processed result for Drizzle ORM\n */\nasync function processAllMethod(query: string, params: unknown[]): Promise<ForgeDriverResult> {\n const sqlStatement = await sql.prepare<unknown>(query);\n\n if (params) {\n await sqlStatement.bindParams(...params);\n }\n\n const result = (await withTimeout(\n sqlStatement.execute(),\n timeoutMessage,\n timeoutMs,\n )) as ForgeSQLResult;\n await saveMetaDataToContext(result.metadata);\n\n if (!result.rows) {\n return { rows: [] };\n }\n\n const rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));\n\n return { rows };\n}\n\n/**\n * Main Forge SQL driver function for Drizzle ORM integration.\n * Handles DDL operations, execute operations (UPDATE/INSERT/DELETE), and select operations.\n *\n * @param query - The SQL query to execute\n * @param params - Query parameters\n * @param method - Execution method (\"all\" for SELECT, \"execute\" for UPDATE/INSERT/DELETE)\n * @returns Promise with query results compatible with Drizzle ORM\n *\n * @throws {Error} When DDL operations are called with parameters\n *\n * @example\n * ```typescript\n * // DDL operation\n * await forgeDriver(\"CREATE TABLE users (id INT)\", [], \"all\");\n *\n * // SELECT operation\n * await forgeDriver(\"SELECT * FROM users WHERE id = ?\", [1], \"all\");\n *\n * // UPDATE operation\n * await forgeDriver(\"UPDATE users SET name = ? WHERE id = ?\", [\"John\", 1], \"execute\");\n * ```\n */\nexport const forgeDriver = async (\n query: string,\n params: unknown[],\n method: QueryMethod,\n): Promise<ForgeDriverResult> => {\n const operationType = await getOperationType();\n // Handle DDL operations\n if (operationType === \"DDL\") {\n const result = await withTimeout(\n sql.executeDDL(inlineParams(query, params)),\n timeoutMessage,\n timeoutMs,\n );\n return await processDDLResult(method, result);\n }\n\n // Handle execute method (UPDATE, INSERT, DELETE)\n if (method === \"execute\") {\n return await processExecuteMethod(query, params ?? []);\n }\n\n // Handle all method (SELECT)\n return await processAllMethod(query, params ?? []);\n};\n","/**\n * Interface for SQL hints configuration\n */\nexport interface SqlHints {\n /** SQL hints for SELECT queries */\n select?: string[];\n /** SQL hints for INSERT queries */\n insert?: string[];\n /** SQL hints for UPDATE queries */\n update?: string[];\n /** SQL hints for DELETE queries */\n delete?: string[];\n}\n\n/**\n * Detects the type of SQL query and injects appropriate hints\n * @param query - The SQL query to analyze\n * @param hints - The hints configuration\n * @returns The modified query with injected hints\n */\nexport function injectSqlHints(query: string, hints?: SqlHints): string {\n if (!hints) {\n return query;\n }\n\n // Normalize the query for easier matching\n const normalizedQuery = query.trim().toUpperCase();\n\n // Get the appropriate hints based on query type\n let queryHints: string[] | undefined;\n\n if (normalizedQuery.startsWith(\"SELECT\")) {\n queryHints = hints.select;\n } else if (normalizedQuery.startsWith(\"INSERT\")) {\n queryHints = hints.insert;\n } else if (normalizedQuery.startsWith(\"UPDATE\")) {\n queryHints = hints.update;\n } else if (normalizedQuery.startsWith(\"DELETE\")) {\n queryHints = hints.delete;\n }\n\n // If no hints for this query type, return original query\n if (!queryHints || queryHints.length === 0) {\n return query;\n }\n\n // Join all hints with spaces\n const hintsString = queryHints.join(\" \");\n\n // Inject hints into the query\n if (normalizedQuery.startsWith(\"SELECT\")) {\n return `SELECT /*+ ${hintsString} */ ${query.substring(6)}`;\n } else if (normalizedQuery.startsWith(\"INSERT\")) {\n return `INSERT /*+ ${hintsString} */ ${query.substring(6)}`;\n } else if (normalizedQuery.startsWith(\"UPDATE\")) {\n return `UPDATE /*+ ${hintsString} */ ${query.substring(6)}`;\n } else if (normalizedQuery.startsWith(\"DELETE\")) {\n return `DELETE /*+ ${hintsString} */ ${query.substring(6)}`;\n }\n\n // If no match found, return original query\n return query;\n}\n","import { forgeDriver } from \"./forgeDriver\";\nimport { injectSqlHints, SqlHints } from \"./sqlHints\";\nimport { ForgeSqlOperation } from \"../core/ForgeSQLQueryBuilder\";\nimport { printQueriesWithPlan } from \"./sqlUtils\";\n\n/**\n * Error codes and constants for query analysis\n */\nconst QUERY_ERROR_CODES = {\n TIMEOUT: \"SQL_QUERY_TIMEOUT\",\n OUT_OF_MEMORY_ERRNO: 8175,\n} as const;\n\n/**\n * Delay to wait for CLUSTER_STATEMENTS_SUMMARY to be populated\n */\nconst STATEMENTS_SUMMARY_DELAY_MS = 200;\n\n/**\n * Creates a proxy for the forgeDriver that injects SQL hints and handles query analysis\n * @param forgeSqlOperation - The ForgeSQL operation instance\n * @param options - SQL hints to inject\n * @param logRawSqlQuery - Whether to log raw SQL queries\n * @returns A proxied version of the forgeDriver\n */\nexport function createForgeDriverProxy(\n forgeSqlOperation: ForgeSqlOperation,\n options?: SqlHints,\n logRawSqlQuery?: boolean,\n) {\n return async (\n query: string,\n params: any[],\n method: \"all\" | \"execute\",\n ): Promise<{\n rows: any[];\n insertId?: number;\n affectedRows?: number;\n }> => {\n // Inject SQL hints into the query\n const modifiedQuery = injectSqlHints(query, options);\n\n if (options && logRawSqlQuery && modifiedQuery !== query) {\n // eslint-disable-next-line no-console\n console.debug(`SQL Hints injected: ${modifiedQuery}`);\n }\n\n const queryStartTime = Date.now();\n\n try {\n // Execute the query with injected hints\n return await forgeDriver(modifiedQuery, params, method);\n } catch (error: any) {\n // Check if this is a timeout or out-of-memory error that we want to analyze\n const isTimeoutError = error.code === QUERY_ERROR_CODES.TIMEOUT;\n const isOutOfMemoryError =\n error?.context?.debug?.errno === QUERY_ERROR_CODES.OUT_OF_MEMORY_ERRNO;\n\n if (isTimeoutError || isOutOfMemoryError) {\n if (isTimeoutError) {\n // eslint-disable-next-line no-console\n console.error(` TIMEOUT detected - Query exceeded time limit`);\n } else {\n // eslint-disable-next-line no-console\n console.error(`OUT OF MEMORY detected - Query exceeded memory limit`);\n }\n\n // Wait for CLUSTER_STATEMENTS_SUMMARY to be populated with our failed query data\n await new Promise((resolve) => setTimeout(resolve, STATEMENTS_SUMMARY_DELAY_MS));\n\n const queryEndTime = Date.now();\n const queryDuration = queryEndTime - queryStartTime;\n\n // Analyze the failed query using CLUSTER_STATEMENTS_SUMMARY\n await printQueriesWithPlan(forgeSqlOperation, queryDuration);\n }\n\n // Log SQL error details if requested\n if (logRawSqlQuery) {\n // eslint-disable-next-line no-console\n console.debug(`SQL Error Details:`, JSON.stringify(error, null, 2));\n }\n\n // Re-throw the original error\n throw error;\n }\n };\n}\n","import {\n MySqlRawQueryResult,\n MySqlRemoteDatabase,\n MySqlRemotePreparedQueryHKT,\n MySqlRemoteQueryResultHKT,\n} from \"drizzle-orm/mysql-proxy\";\n\nimport { SelectedFields } from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { applyFromDriverTransform, ForgeSqlOrmOptions, mapSelectFieldsWithAlias } from \"../../..\";\nimport { MySqlSelectBase, MySqlSelectBuilder } from \"drizzle-orm/mysql-core\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core/table\";\nimport {\n MySqlDeleteBase,\n MySqlInsertBuilder,\n MySqlUpdateBuilder,\n} from \"drizzle-orm/mysql-core/query-builders\";\nimport { clearCache, getFromCache, setCacheResult } from \"../../../utils/cacheUtils\";\nimport {\n cacheApplicationContext,\n evictLocalCacheQuery,\n getQueryLocalCacheQuery,\n saveQueryLocalCacheQuery,\n saveTableIfInsideCacheContext,\n} from \"../../../utils/cacheContextUtils\";\nimport { isSQLWrapper, SQLWrapper } from \"drizzle-orm/sql/sql\";\nimport type { MySqlQueryResultKind } from \"drizzle-orm/mysql-core/session\";\nimport { getTableColumns, Query, SQL } from \"drizzle-orm\";\nimport { MySqlDialect } from \"drizzle-orm/mysql-core/dialect\";\nimport {\n GetSelectTableName,\n GetSelectTableSelection,\n SelectResultField,\n} from \"drizzle-orm/query-builders/select.types\";\n\n// ============================================================================\n// TYPES AND INTERFACES\n// ============================================================================\n\n/**\n * Base interface for query builders that can be executed\n */\ninterface QueryBuilder {\n execute: (...args: any[]) => Promise<any>;\n then?: (onfulfilled?: any, onrejected?: any) => Promise<any>;\n toSQL?: () => any;\n}\n\n/**\n * Error codes that should not trigger cache clearing\n */\nconst NON_CACHE_CLEARING_ERROR_CODES = [\"VALIDATION_ERROR\", \"CONSTRAINT_ERROR\"] as const;\n\n/**\n * Error codes that should trigger cache clearing\n */\nconst CACHE_CLEARING_ERROR_CODES = [\"DEADLOCK\", \"LOCK_WAIT_TIMEOUT\", \"CONNECTION_ERROR\"] as const;\n\n/**\n * Error message patterns that should not trigger cache clearing\n */\nconst NON_CACHE_CLEARING_PATTERNS = [/validation/i, /constraint/i] as const;\n\n/**\n * Error message patterns that should trigger cache clearing\n */\nconst CACHE_CLEARING_PATTERNS = [/timeout/i, /connection/i] as const;\n\n// ============================================================================\n// CACHE MANAGEMENT UTILITIES\n// ============================================================================\n\n/**\n * Determines whether cache should be cleared based on the error type.\n * Only clears cache for errors that might indicate data consistency issues.\n *\n * @param error - The error that occurred during query execution\n * @returns true if cache should be cleared, false otherwise\n */\nfunction shouldClearCacheOnError(error: any): boolean {\n // Don't clear cache for client-side errors (validation, etc.)\n if (error?.code && NON_CACHE_CLEARING_ERROR_CODES.includes(error.code)) {\n return false;\n }\n\n if (\n error?.message &&\n NON_CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))\n ) {\n return false;\n }\n\n // Clear cache for database-level errors that might affect data consistency\n if (error?.code && CACHE_CLEARING_ERROR_CODES.includes(error.code)) {\n return true;\n }\n\n if (error?.message && CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {\n return true;\n }\n\n // For unknown errors, be conservative and clear cache\n return true;\n}\n\n// ============================================================================\n// EXPORTED TYPES\n// ============================================================================\n\n/**\n * Type for select queries with field aliasing\n */\nexport type SelectAliasedType = <TSelection extends SelectedFields>(\n fields: TSelection,\n) => MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for select distinct queries with field aliasing\n */\nexport type SelectAliasedDistinctType = <TSelection extends SelectedFields>(\n fields: TSelection,\n) => MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for select queries with field aliasing and caching\n */\nexport type SelectAliasedCacheableType = <TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTtl?: number,\n) => MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for select distinct queries with field aliasing and caching\n */\nexport type SelectAliasedDistinctCacheableType = <TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTtl?: number,\n) => MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for select queries from table with field aliasing\n */\nexport type SelectAllFromAliasedType = <T extends MySqlTable>(\n table: T,\n) => MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }[K];\n }[],\n any\n>;\n\n/**\n * Type for select distinct queries from table with field aliasing\n */\nexport type SelectAllDistinctFromAliasedType = <T extends MySqlTable>(\n table: T,\n) => MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }[K];\n }[],\n any\n>;\n\n/**\n * Type for select queries from table with field aliasing and caching\n */\nexport type SelectAllFromCacheableAliasedType = <T extends MySqlTable>(\n table: T,\n cacheTtl?: number,\n) => MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }[K];\n }[],\n any\n>;\n\n/**\n * Type for select distinct queries from table with field aliasing and caching\n */\nexport type SelectAllDistinctFromCacheableAliasedType = <T extends MySqlTable>(\n table: T,\n cacheTtl?: number,\n) => MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<GetSelectTableSelection<T>[Key]>;\n }[K];\n }[],\n any\n>;\n\n/**\n * Type for executing raw SQL queries with local cache\n */\nexport type ExecuteQuery = <T>(\n query: SQLWrapper | string,\n) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>>;\n\n/**\n * Type for executing raw SQL queries with local and global cache\n */\nexport type ExecuteQueryCacheable = <T>(\n query: SQLWrapper | string,\n cacheTtl?: number,\n) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>>;\n\n/**\n * Type for insert operations with cache eviction\n */\nexport type InsertAndEvictCacheType = <TTable extends MySqlTable>(\n table: TTable,\n) => MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for update operations with cache eviction\n */\nexport type UpdateAndEvictCacheType = <TTable extends MySqlTable>(\n table: TTable,\n) => MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Type for delete operations with cache eviction\n */\nexport type DeleteAndEvictCacheType = <TTable extends MySqlTable>(\n table: TTable,\n) => MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n/**\n * Handles successful query execution with cache management.\n *\n * @param rows - Query result rows\n * @param onfulfilled - Success callback\n * @param table - The table being modified\n * @param options - ForgeSQL ORM options\n * @param isCached - Whether to clear cache immediately\n * @returns Promise with result\n */\nasync function handleSuccessfulExecution(\n rows: unknown[],\n onfulfilled: any,\n table: MySqlTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): Promise<any> {\n try {\n await evictLocalCacheQuery(table, options);\n await saveTableIfInsideCacheContext(table);\n if (isCached && !cacheApplicationContext.getStore()) {\n await clearCache(table, options);\n }\n const result = onfulfilled ? onfulfilled(rows) : rows;\n return result;\n } catch (error) {\n // Only clear cache for certain types of errors\n if (shouldClearCacheOnError(error)) {\n await evictLocalCacheQuery(table, options);\n if (isCached) {\n await clearCache(table, options).catch((e) => {\n // eslint-disable-next-line no-console\n console.warn(\"Ignore cache clear errors\", e);\n });\n } else {\n await saveTableIfInsideCacheContext(table);\n }\n }\n throw error;\n }\n}\n\n/**\n * Handles function calls on the wrapped builder.\n *\n * @param value - The function to call\n * @param target - The target object\n * @param args - Function arguments\n * @param table - The table being modified\n * @param options - ForgeSQL ORM options\n * @param isCached - Whether to clear cache immediately\n * @returns Function result or wrapped builder\n */\nfunction handleFunctionCall(\n value: Function,\n target: any,\n args: any[],\n table: MySqlTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): any {\n const result = value.apply(target, args);\n if (typeof result === \"object\" && result !== null && \"execute\" in result) {\n return wrapCacheEvictBuilder(result as QueryBuilder, table, options, isCached);\n }\n return result;\n}\n\n/**\n * Wraps a query builder with cache eviction functionality.\n * Automatically clears cache after successful execution of insert/update/delete operations.\n *\n * @param rawBuilder - The original query builder to wrap\n * @param table - The table being modified (used for cache eviction)\n * @param options - ForgeSQL ORM options including cache configuration\n * @param isCached - Whether to clear cache immediately\n * @returns Wrapped query builder with cache eviction\n */\nconst wrapCacheEvictBuilder = <TTable extends MySqlTable>(\n rawBuilder: QueryBuilder,\n table: TTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): QueryBuilder => {\n return new Proxy(rawBuilder, {\n get(target, prop, receiver) {\n if (prop === \"then\") {\n return (onfulfilled?: any, onrejected?: any) =>\n target\n .execute()\n .then(\n (rows: unknown[]) =>\n handleSuccessfulExecution(rows, onfulfilled, table, options, isCached),\n onrejected,\n );\n }\n\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value === \"function\") {\n return (...args: any[]) =>\n handleFunctionCall(value, target, args, table, options, isCached);\n }\n\n return value;\n },\n });\n};\n\n/**\n * Creates an insert query builder that automatically evicts cache after execution.\n *\n * @param db - The database instance\n * @param table - The table to insert into\n * @param options - ForgeSQL ORM options\n * @returns Insert query builder with cache eviction\n */\nfunction insertAndEvictCacheBuilder<TTable extends MySqlTable>(\n db: MySqlRemoteDatabase<any>,\n table: TTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n const builder = db.insert(table);\n return wrapCacheEvictBuilder(\n builder as unknown as QueryBuilder,\n table,\n options,\n isCached,\n ) as unknown as MySqlInsertBuilder<\n TTable,\n MySqlRemoteQueryResultHKT,\n MySqlRemotePreparedQueryHKT\n >;\n}\n\n/**\n * Creates an update query builder that automatically evicts cache after execution.\n *\n * @param db - The database instance\n * @param table - The table to update\n * @param options - ForgeSQL ORM options\n * @returns Update query builder with cache eviction\n */\nfunction updateAndEvictCacheBuilder<TTable extends MySqlTable>(\n db: MySqlRemoteDatabase<any>,\n table: TTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n const builder = db.update(table);\n return wrapCacheEvictBuilder(\n builder as unknown as QueryBuilder,\n table,\n options,\n isCached,\n ) as unknown as MySqlUpdateBuilder<\n TTable,\n MySqlRemoteQueryResultHKT,\n MySqlRemotePreparedQueryHKT\n >;\n}\n\n/**\n * Creates a delete query builder that automatically evicts cache after execution.\n *\n * @param db - The database instance\n * @param table - The table to delete from\n * @param options - ForgeSQL ORM options\n * @returns Delete query builder with cache eviction\n */\nfunction deleteAndEvictCacheBuilder<TTable extends MySqlTable>(\n db: MySqlRemoteDatabase<any>,\n table: TTable,\n options: ForgeSqlOrmOptions,\n isCached: boolean,\n): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n const builder = db.delete(table);\n return wrapCacheEvictBuilder(\n builder as unknown as QueryBuilder,\n table,\n options,\n isCached,\n ) as unknown as MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n}\n\n/**\n * Handles cached query execution with proper error handling.\n *\n * @param target - The query target\n * @param options - ForgeSQL ORM options\n * @param cacheTtl - Cache TTL\n * @param selections - Field selections\n * @param aliasMap - Field alias mapping\n * @param onfulfilled - Success callback\n * @param onrejected - Error callback\n * @returns Promise with cached result\n */\nasync function handleCachedQuery(\n target: any,\n options: ForgeSqlOrmOptions,\n cacheTtl: number,\n selections: any,\n aliasMap: any,\n onfulfilled?: any,\n onrejected?: any,\n): Promise<any> {\n try {\n const localCached = await getQueryLocalCacheQuery(target, options);\n if (localCached) {\n return onfulfilled ? onfulfilled(localCached) : localCached;\n }\n const cacheResult = await getFromCache(target, options);\n if (cacheResult) {\n return onfulfilled ? onfulfilled(cacheResult) : cacheResult;\n }\n const rows = await target.execute();\n const transformed = applyFromDriverTransform(rows, selections, aliasMap);\n await saveQueryLocalCacheQuery(target, transformed, options);\n await setCacheResult(target, options, transformed, cacheTtl).catch((cacheError) => {\n // Log cache error but don't fail the query\n // eslint-disable-next-line no-console\n console.warn(\"Cache set error:\", cacheError);\n });\n\n return onfulfilled ? onfulfilled(transformed) : transformed;\n } catch (error) {\n if (onrejected) {\n return onrejected(error);\n }\n throw error;\n }\n}\n\n/**\n * Handles non-cached query execution.\n *\n * @param target - The query target\n * @param options - ForgeSQL ORM options\n * @param selections - Field selections\n * @param aliasMap - Field alias mapping\n * @param onfulfilled - Success callback\n * @param onrejected - Error callback\n * @returns Promise with transformed result\n */\nasync function handleNonCachedQuery(\n target: any,\n options: any,\n selections: any,\n aliasMap: any,\n onfulfilled?: any,\n onrejected?: any,\n): Promise<any> {\n try {\n const localCached = await getQueryLocalCacheQuery(target, options);\n if (localCached) {\n return onfulfilled ? onfulfilled(localCached) : localCached;\n }\n const rows = await target.execute();\n const transformed = applyFromDriverTransform(rows, selections, aliasMap);\n await saveQueryLocalCacheQuery(target, transformed, options);\n return onfulfilled ? onfulfilled(transformed) : transformed;\n } catch (error) {\n if (onrejected) {\n return onrejected(error);\n }\n throw error;\n }\n}\n\n/**\n * Creates a select query builder with field aliasing and optional caching support.\n *\n * @param db - The database instance\n * @param fields - The fields to select with aliases\n * @param selectFn - Function to create the base select query\n * @param useCache - Whether to enable caching for this query\n * @param options - ForgeSQL ORM options\n * @param cacheTtl - Optional cache TTL override\n * @returns Select query builder with aliasing and optional caching\n */\nfunction createAliasedSelectBuilder<TSelection extends SelectedFields>(\n db: MySqlRemoteDatabase<any>,\n fields: TSelection,\n selectFn: (selections: any) => MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>,\n useCache: boolean,\n options: ForgeSqlOrmOptions,\n cacheTtl?: number,\n): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n const { selections, aliasMap } = mapSelectFieldsWithAlias(fields);\n const builder = selectFn(selections);\n\n const wrapBuilder = (rawBuilder: any): any => {\n return new Proxy(rawBuilder, {\n get(target, prop, receiver) {\n if (prop === \"execute\") {\n return async (...args: any[]) => {\n const rows = await target.execute(...args);\n return applyFromDriverTransform(rows, selections, aliasMap);\n };\n }\n\n if (prop === \"then\") {\n return (onfulfilled?: any, onrejected?: any) => {\n if (useCache) {\n const ttl = cacheTtl ?? options.cacheTTL ?? 120;\n return handleCachedQuery(\n target,\n options,\n ttl,\n selections,\n aliasMap,\n onfulfilled,\n onrejected,\n );\n } else {\n return handleNonCachedQuery(\n target,\n options,\n selections,\n aliasMap,\n onfulfilled,\n onrejected,\n );\n }\n };\n }\n\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value === \"function\") {\n return (...args: any[]) => {\n const result = value.apply(target, args);\n\n if (typeof result === \"object\" && result !== null && \"execute\" in result) {\n return wrapBuilder(result);\n }\n\n return result;\n };\n }\n\n return value;\n },\n });\n };\n\n return wrapBuilder(builder);\n}\n\n// ============================================================================\n// CONFIGURATION AND CONSTANTS\n// ============================================================================\n\n/**\n * Default options for ForgeSQL ORM\n */\nconst DEFAULT_OPTIONS: ForgeSqlOrmOptions = {\n logRawSqlQuery: false,\n disableOptimisticLocking: false,\n cacheTTL: 120,\n cacheWrapTable: true,\n cacheEntityQueryName: \"sql\",\n cacheEntityExpirationName: \"expiration\",\n cacheEntityDataName: \"data\",\n} as const;\n\n// ============================================================================\n// QUERY BUILDER FACTORIES\n// ============================================================================\n\n/**\n * Creates a raw SQL query executor with caching support\n */\nfunction createRawQueryExecutor(\n db: MySqlRemoteDatabase<any>,\n options: ForgeSqlOrmOptions,\n useGlobalCache: boolean = false,\n) {\n return async function <T extends { [column: string]: any }>(\n query: SQLWrapper | string,\n cacheTtl?: number,\n ): Promise<MySqlRawQueryResult> {\n let sql: Query;\n\n if (isSQLWrapper(query)) {\n const dialect = (db as unknown as { dialect: MySqlDialect }).dialect;\n sql = dialect.sqlToQuery(query as SQL);\n } else {\n sql = {\n sql: query,\n params: [],\n };\n }\n\n // Check local cache first\n const localCacheResult = await getQueryLocalCacheQuery(sql, options);\n if (localCacheResult) {\n return localCacheResult as MySqlRawQueryResult;\n }\n\n // Check global cache if enabled\n if (useGlobalCache) {\n const cacheResult = await getFromCache({ toSQL: () => sql }, options);\n if (cacheResult) {\n return cacheResult as MySqlRawQueryResult;\n }\n }\n\n // Execute query\n const results = await db.execute<T>(query);\n\n // Save to local cache\n await saveQueryLocalCacheQuery(sql, results, options);\n\n // Save to global cache if enabled\n if (useGlobalCache) {\n await setCacheResult(\n { toSQL: () => sql },\n options,\n results,\n cacheTtl ?? options.cacheTTL ?? 120,\n );\n }\n\n return results;\n };\n}\n\n// ============================================================================\n// MAIN PATCH FUNCTION\n// ============================================================================\n\n/**\n * Patches a Drizzle database instance with additional methods for aliased selects and cache management.\n *\n * This function extends the database instance with:\n * - selectAliased: Select with field aliasing support\n * - selectAliasedDistinct: Select distinct with field aliasing support\n * - selectAliasedCacheable: Select with field aliasing and caching\n * - selectAliasedDistinctCacheable: Select distinct with field aliasing and caching\n * - insertAndEvictCache: Insert operations that automatically evict cache\n * - updateAndEvictCache: Update operations that automatically evict cache\n * - deleteAndEvictCache: Delete operations that automatically evict cache\n *\n * @param db - The Drizzle database instance to patch\n * @param options - Optional ForgeSQL ORM configuration\n * @returns The patched database instance with additional methods\n */\nexport function patchDbWithSelectAliased(\n db: MySqlRemoteDatabase<any>,\n options?: ForgeSqlOrmOptions,\n): MySqlRemoteDatabase<any> & {\n selectAliased: SelectAliasedType;\n selectAliasedDistinct: SelectAliasedDistinctType;\n selectAliasedCacheable: SelectAliasedCacheableType;\n selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;\n insertWithCacheContext: InsertAndEvictCacheType;\n insertAndEvictCache: InsertAndEvictCacheType;\n updateAndEvictCache: UpdateAndEvictCacheType;\n updateWithCacheContext: UpdateAndEvictCacheType;\n deleteAndEvictCache: DeleteAndEvictCacheType;\n deleteWithCacheContext: DeleteAndEvictCacheType;\n} {\n const newOptions = { ...DEFAULT_OPTIONS, ...options };\n\n // ============================================================================\n // SELECT METHODS WITH FIELD ALIASING\n // ============================================================================\n\n // Select aliased without cache\n db.selectAliased = function <TSelection extends SelectedFields>(fields: TSelection) {\n return createAliasedSelectBuilder(\n db,\n fields,\n (selections) => db.select(selections),\n false,\n newOptions,\n );\n };\n\n // Select aliased with cache\n db.selectAliasedCacheable = function <TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTtl?: number,\n ) {\n return createAliasedSelectBuilder(\n db,\n fields,\n (selections) => db.select(selections),\n true,\n newOptions,\n cacheTtl,\n );\n };\n\n // Select aliased distinct without cache\n db.selectAliasedDistinct = function <TSelection extends SelectedFields>(fields: TSelection) {\n return createAliasedSelectBuilder(\n db,\n fields,\n (selections) => db.selectDistinct(selections),\n false,\n newOptions,\n );\n };\n\n // Select aliased distinct with cache\n db.selectAliasedDistinctCacheable = function <TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTtl?: number,\n ) {\n return createAliasedSelectBuilder(\n db,\n fields,\n (selections) => db.selectDistinct(selections),\n true,\n newOptions,\n cacheTtl,\n );\n };\n\n // ============================================================================\n // TABLE-BASED SELECT METHODS\n // ============================================================================\n\n /**\n * Creates a select query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all columns from the specified table.\n *\n * @param table - The table to select from\n * @returns Select query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const users = await db.selectFrom(userTable).where(eq(userTable.id, 1));\n * ```\n */\n db.selectFrom = function <T extends MySqlTable>(\n table: T,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n > {\n return db.selectAliased(getTableColumns(table)).from(table) as unknown as MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string\n ? Record<string & GetSelectTableName<T>, \"not-null\">\n : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n };\n\n /**\n * Creates a select query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all columns from the specified table with caching enabled.\n *\n * @param table - The table to select from\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const users = await db.selectFromCacheable(userTable, 300).where(eq(userTable.id, 1));\n * ```\n */\n db.selectFromCacheable = function <T extends MySqlTable>(\n table: T,\n cacheTtl?: number,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n > {\n return db\n .selectAliasedCacheable(getTableColumns(table), cacheTtl)\n .from(table) as unknown as MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string\n ? Record<string & GetSelectTableName<T>, \"not-null\">\n : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n };\n\n /**\n * Creates a select distinct query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all distinct columns from the specified table.\n *\n * @param table - The table to select from\n * @returns Select distinct query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const uniqueUsers = await db.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));\n * ```\n */\n db.selectDistinctFrom = function <T extends MySqlTable>(\n table: T,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n > {\n return db\n .selectAliasedDistinct(getTableColumns(table))\n .from(table) as unknown as MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string\n ? Record<string & GetSelectTableName<T>, \"not-null\">\n : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n };\n\n /**\n * Creates a select distinct query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.\n *\n * @param table - The table to select from\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select distinct query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const uniqueUsers = await db.selectDistinctFromCacheable(userTable, 300).where(eq(userTable.status, 'active'));\n * ```\n */\n db.selectDistinctFromCacheable = function <T extends MySqlTable>(\n table: T,\n cacheTtl?: number,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n > {\n return db\n .selectAliasedDistinctCacheable(getTableColumns(table), cacheTtl)\n .from(table) as unknown as MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string\n ? Record<string & GetSelectTableName<T>, \"not-null\">\n : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n };\n\n // ============================================================================\n // CACHE-AWARE MODIFY OPERATIONS\n // ============================================================================\n\n // Insert with cache context support (participates in cache clearing when used within cache context)\n db.insertWithCacheContext = function <TTable extends MySqlTable>(table: TTable) {\n return insertAndEvictCacheBuilder(db, table, newOptions, false);\n };\n\n // Insert with cache eviction\n db.insertAndEvictCache = function <TTable extends MySqlTable>(table: TTable) {\n return insertAndEvictCacheBuilder(db, table, newOptions, true);\n };\n\n // Update with cache context support (participates in cache clearing when used within cache context)\n db.updateWithCacheContext = function <TTable extends MySqlTable>(table: TTable) {\n return updateAndEvictCacheBuilder(db, table, newOptions, false);\n };\n\n // Update with cache eviction\n db.updateAndEvictCache = function <TTable extends MySqlTable>(table: TTable) {\n return updateAndEvictCacheBuilder(db, table, newOptions, true);\n };\n\n // Delete with cache context support (participates in cache clearing when used within cache context)\n db.deleteWithCacheContext = function <TTable extends MySqlTable>(table: TTable) {\n return deleteAndEvictCacheBuilder(db, table, newOptions, false);\n };\n\n // Delete with cache eviction\n db.deleteAndEvictCache = function <TTable extends MySqlTable>(table: TTable) {\n return deleteAndEvictCacheBuilder(db, table, newOptions, true);\n };\n\n // ============================================================================\n // RAW SQL QUERY EXECUTORS\n // ============================================================================\n\n /**\n * Executes a raw SQL query with local cache support.\n * This method provides local caching for raw SQL queries within the current invocation context.\n * Results are cached locally and will be returned from cache on subsequent identical queries.\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper\n * const result = await db.executeQuery(sql`SELECT * FROM users WHERE id = ${userId}`);\n *\n * // Using string\n * const result = await db.executeQuery(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n db.executeQuery = createRawQueryExecutor(db, newOptions, false);\n\n /**\n * Executes a raw SQL query with both local and global cache support.\n * This method provides comprehensive caching for raw SQL queries:\n * - Local cache: Within the current invocation context\n * - Global cache: Cross-invocation caching using @forge/kvs\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper with custom TTL\n * const result = await db.executeQueryCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);\n *\n * // Using string with default TTL\n * const result = await db.executeQueryCacheable(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n db.executeQueryCacheable = createRawQueryExecutor(db, newOptions, true);\n\n return db;\n}\n","import { ForgeSqlOperation, SchemaAnalyzeForgeSql } from \"./ForgeSQLQueryBuilder\";\nimport { Query } from \"drizzle-orm\";\nimport {\n ClusterStatementRowCamelCase,\n ExplainAnalyzeRow,\n SlowQueryNormalized,\n} from \"./SystemTables\";\nimport { SqlParameters } from \"@forge/sql/out/sql-statement\";\nimport { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { getTableName } from \"drizzle-orm/table\";\nimport { DateTime } from \"luxon\";\n\n/**\n * Interface representing a row from the EXPLAIN ANALYZE output\n */\ninterface DecodedPlanRow {\n id: string;\n estRows?: string;\n estCost?: string;\n actRows?: string;\n task?: string;\n \"access object\"?: string;\n \"execution info\"?: string;\n \"operator info\"?: string;\n memory?: string;\n disk?: string;\n}\n\n/**\n * Interface representing a raw slow query row from the database\n */\ninterface SlowQueryRaw {\n Time: string;\n Txn_start_ts: number;\n User: string;\n Host: string;\n Conn_ID: number;\n DB: string;\n Query: string;\n Digest: string;\n Query_time: number;\n Compile_time: number;\n Optimize_time: number;\n Process_time: number;\n Wait_time: number;\n Parse_time: number;\n Rewrite_time: number;\n Cop_time: number;\n Cop_proc_avg: number;\n Cop_proc_max: number;\n Cop_proc_p90: number;\n Cop_proc_addr: string;\n Cop_wait_avg: number;\n Cop_wait_max: number;\n Cop_wait_p90: number;\n Cop_wait_addr: string;\n Mem_max: number;\n Disk_max: number;\n Total_keys: number;\n Process_keys: number;\n Request_count: number;\n KV_total: number;\n PD_total: number;\n Result_rows: number;\n Rocksdb_block_cache_hit_count: number;\n Rocksdb_block_read_count: number;\n Rocksdb_block_read_byte: number;\n Plan: string;\n Binary_plan: string;\n Plan_digest: string;\n}\n\n/**\n * Interface representing a row from the cluster statements table\n */\nexport interface ClusterStatementRow {\n INSTANCE: string;\n SUMMARY_BEGIN_TIME: string;\n SUMMARY_END_TIME: string;\n STMT_TYPE: string;\n SCHEMA_NAME: string;\n DIGEST: string;\n DIGEST_TEXT: string;\n TABLE_NAMES: string;\n INDEX_NAMES: string | null;\n SAMPLE_USER: string;\n EXEC_COUNT: number;\n SUM_ERRORS: number;\n SUM_WARNINGS: number;\n SUM_LATENCY: number;\n MAX_LATENCY: number;\n MIN_LATENCY: number;\n AVG_LATENCY: number;\n AVG_PARSE_LATENCY: number;\n MAX_PARSE_LATENCY: number;\n AVG_COMPILE_LATENCY: number;\n MAX_COMPILE_LATENCY: number;\n SUM_COP_TASK_NUM: number;\n MAX_COP_PROCESS_TIME: number;\n MAX_COP_PROCESS_ADDRESS: string;\n MAX_COP_WAIT_TIME: number;\n MAX_COP_WAIT_ADDRESS: string;\n AVG_PROCESS_TIME: number;\n MAX_PROCESS_TIME: number;\n AVG_WAIT_TIME: number;\n MAX_WAIT_TIME: number;\n AVG_BACKOFF_TIME: number;\n MAX_BACKOFF_TIME: number;\n AVG_TOTAL_KEYS: number;\n MAX_TOTAL_KEYS: number;\n AVG_PROCESSED_KEYS: number;\n MAX_PROCESSED_KEYS: number;\n AVG_ROCKSDB_DELETE_SKIPPED_COUNT: number;\n MAX_ROCKSDB_DELETE_SKIPPED_COUNT: number;\n AVG_ROCKSDB_KEY_SKIPPED_COUNT: number;\n MAX_ROCKSDB_KEY_SKIPPED_COUNT: number;\n AVG_ROCKSDB_BLOCK_CACHE_HIT_COUNT: number;\n MAX_ROCKSDB_BLOCK_CACHE_HIT_COUNT: number;\n AVG_ROCKSDB_BLOCK_READ_COUNT: number;\n MAX_ROCKSDB_BLOCK_READ_COUNT: number;\n AVG_ROCKSDB_BLOCK_READ_BYTE: number;\n MAX_ROCKSDB_BLOCK_READ_BYTE: number;\n AVG_PREWRITE_TIME: number;\n MAX_PREWRITE_TIME: number;\n AVG_COMMIT_TIME: number;\n MAX_COMMIT_TIME: number;\n AVG_GET_COMMIT_TS_TIME: number;\n MAX_GET_COMMIT_TS_TIME: number;\n AVG_COMMIT_BACKOFF_TIME: number;\n MAX_COMMIT_BACKOFF_TIME: number;\n AVG_RESOLVE_LOCK_TIME: number;\n MAX_RESOLVE_LOCK_TIME: number;\n AVG_LOCAL_LATCH_WAIT_TIME: number;\n MAX_LOCAL_LATCH_WAIT_TIME: number;\n AVG_WRITE_KEYS: number;\n MAX_WRITE_KEYS: number;\n AVG_WRITE_SIZE: number;\n MAX_WRITE_SIZE: number;\n AVG_PREWRITE_REGIONS: number;\n MAX_PREWRITE_REGIONS: number;\n AVG_TXN_RETRY: number;\n MAX_TXN_RETRY: number;\n SUM_EXEC_RETRY: number;\n SUM_EXEC_RETRY_TIME: number;\n SUM_BACKOFF_TIMES: number;\n BACKOFF_TYPES: string | null;\n AVG_MEM: number;\n MAX_MEM: number;\n AVG_DISK: number;\n MAX_DISK: number;\n AVG_KV_TIME: number;\n AVG_PD_TIME: number;\n AVG_BACKOFF_TOTAL_TIME: number;\n AVG_WRITE_SQL_RESP_TIME: number;\n AVG_TIDB_CPU_TIME: number;\n AVG_TIKV_CPU_TIME: number;\n MAX_RESULT_ROWS: number;\n MIN_RESULT_ROWS: number;\n AVG_RESULT_ROWS: number;\n PREPARED: number;\n AVG_AFFECTED_ROWS: number;\n FIRST_SEEN: string;\n LAST_SEEN: string;\n PLAN_IN_CACHE: number;\n PLAN_CACHE_HITS: number;\n PLAN_IN_BINDING: number;\n QUERY_SAMPLE_TEXT: string;\n PREV_SAMPLE_TEXT: string;\n PLAN_DIGEST: string;\n PLAN: string;\n BINARY_PLAN: string;\n CHARSET: string;\n COLLATION: string;\n PLAN_HINT: string;\n MAX_REQUEST_UNIT_READ: number;\n AVG_REQUEST_UNIT_READ: number;\n MAX_REQUEST_UNIT_WRITE: number;\n AVG_REQUEST_UNIT_WRITE: number;\n MAX_QUEUED_RC_TIME: number;\n AVG_QUEUED_RC_TIME: number;\n RESOURCE_GROUP: string;\n PLAN_CACHE_UNQUALIFIED: number;\n PLAN_CACHE_UNQUALIFIED_LAST_REASON: string;\n}\n\n/**\n * Class implementing SQL analysis operations for ForgeSQL ORM.\n * Provides methods for analyzing query performance, execution plans, and slow queries.\n */\nexport class ForgeSQLAnalyseOperation implements SchemaAnalyzeForgeSql {\n private readonly forgeOperations: ForgeSqlOperation;\n\n /**\n * Creates a new instance of ForgeSQLAnalizeOperation.\n * @param {ForgeSqlOperation} forgeOperations - The ForgeSQL operations instance\n */\n constructor(forgeOperations: ForgeSqlOperation) {\n this.forgeOperations = forgeOperations;\n this.mapToCamelCaseClusterStatement = this.mapToCamelCaseClusterStatement.bind(this);\n }\n\n /**\n * Executes EXPLAIN on a raw SQL query.\n * @param {string} query - The SQL query to analyze\n * @param {unknown[]} bindParams - The query parameters\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n async explainRaw(query: string, bindParams: unknown[]): Promise<ExplainAnalyzeRow[]> {\n const results = await this.forgeOperations\n .fetch()\n .executeRawSQL<DecodedPlanRow>(`EXPLAIN ${query}`, bindParams as SqlParameters);\n return results.map((row) => ({\n id: row.id,\n estRows: row.estRows,\n actRows: row.actRows,\n task: row.task,\n accessObject: row[\"access object\"],\n executionInfo: row[\"execution info\"],\n operatorInfo: row[\"operator info\"],\n memory: row.memory,\n disk: row.disk,\n }));\n }\n\n /**\n * Executes EXPLAIN on a Drizzle query.\n * @param {{ toSQL: () => Query }} query - The Drizzle query to analyze\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n async explain(query: { toSQL: () => Query }): Promise<ExplainAnalyzeRow[]> {\n const { sql, params } = query.toSQL();\n return this.explainRaw(sql, params);\n }\n\n /**\n * Executes EXPLAIN ANALYZE on a raw SQL query.\n * @param {string} query - The SQL query to analyze\n * @param {unknown[]} bindParams - The query parameters\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n async explainAnalyzeRaw(query: string, bindParams: unknown[]): Promise<ExplainAnalyzeRow[]> {\n const results = await this.forgeOperations\n .fetch()\n .executeRawSQL<DecodedPlanRow>(`EXPLAIN ANALYZE ${query}`, bindParams as SqlParameters);\n return results.map((row) => ({\n id: row.id,\n estRows: row.estRows,\n actRows: row.actRows,\n task: row.task,\n accessObject: row[\"access object\"],\n executionInfo: row[\"execution info\"],\n operatorInfo: row[\"operator info\"],\n memory: row.memory,\n disk: row.disk,\n }));\n }\n\n /**\n * Executes EXPLAIN ANALYZE on a Drizzle query.\n * @param {{ toSQL: () => Query }} query - The Drizzle query to analyze\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n async explainAnalyze(query: { toSQL: () => Query }): Promise<ExplainAnalyzeRow[]> {\n const { sql, params } = query.toSQL();\n return this.explainAnalyzeRaw(sql, params);\n }\n\n /**\n * Decodes a query execution plan from its string representation.\n * @param {string} input - The raw execution plan string\n * @returns {ExplainAnalyzeRow[]} The decoded execution plan rows\n */\n decodedPlan(input: string): ExplainAnalyzeRow[] {\n if (!input) {\n return [];\n }\n const lines = input.trim().split(\"\\n\");\n if (lines.length < 2) return [];\n\n const headersRaw = lines[0]\n .split(\"\\t\")\n .map((h) => h.trim())\n .filter(Boolean);\n const headers = headersRaw.map((h) => {\n return h\n .replace(/\\s+/g, \" \")\n .replace(/[-\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"))\n .replace(/^./, (s) => s.toLowerCase());\n });\n\n return lines.slice(1).map((line) => {\n const values = line\n .split(\"\\t\")\n .map((s) => s.trim())\n .filter(Boolean);\n const row: Record<string, string> = {};\n headers.forEach((key, i) => {\n row[key] = values[i] ?? \"\";\n });\n return row as unknown as ExplainAnalyzeRow;\n });\n }\n\n /**\n * Normalizes a raw slow query row into a more structured format.\n * @param {SlowQueryRaw} row - The raw slow query data\n * @returns {SlowQueryNormalized} The normalized slow query data\n */\n normalizeSlowQuery(row: SlowQueryRaw): SlowQueryNormalized {\n return {\n time: row.Time,\n txnStartTs: row.Txn_start_ts,\n user: row.User,\n host: row.Host,\n connId: row.Conn_ID,\n db: row.DB,\n query: row.Query,\n digest: row.Digest,\n queryTime: row.Query_time,\n compileTime: row.Compile_time,\n optimizeTime: row.Optimize_time,\n processTime: row.Process_time,\n waitTime: row.Wait_time,\n parseTime: row.Parse_time,\n rewriteTime: row.Rewrite_time,\n copTime: row.Cop_time,\n copProcAvg: row.Cop_proc_avg,\n copProcMax: row.Cop_proc_max,\n copProcP90: row.Cop_proc_p90,\n copProcAddr: row.Cop_proc_addr,\n copWaitAvg: row.Cop_wait_avg,\n copWaitMax: row.Cop_wait_max,\n copWaitP90: row.Cop_wait_p90,\n copWaitAddr: row.Cop_wait_addr,\n memMax: row.Mem_max,\n diskMax: row.Disk_max,\n totalKeys: row.Total_keys,\n processKeys: row.Process_keys,\n requestCount: row.Request_count,\n kvTotal: row.KV_total,\n pdTotal: row.PD_total,\n resultRows: row.Result_rows,\n rocksdbBlockCacheHitCount: row.Rocksdb_block_cache_hit_count,\n rocksdbBlockReadCount: row.Rocksdb_block_read_count,\n rocksdbBlockReadByte: row.Rocksdb_block_read_byte,\n plan: row.Plan,\n binaryPlan: row.Binary_plan,\n planDigest: row.Plan_digest,\n parsedPlan: this.decodedPlan(row.Plan),\n };\n }\n\n /**\n * Builds a SQL query for retrieving cluster statement history.\n * @param {string[]} tables - The tables to analyze\n * @param {Date} [from] - The start date for the analysis\n * @param {Date} [to] - The end date for the analysis\n * @returns {string} The SQL query for cluster statement history\n */\n buildClusterStatementQuery(tables: string[], from?: Date, to?: Date): string {\n const formatDateTime = (date: Date): string =>\n DateTime.fromJSDate(date).toFormat(\"yyyy-LL-dd'T'HH:mm:ss.SSS\");\n\n const tableConditions = tables\n .map((table) => `TABLE_NAMES LIKE CONCAT(SCHEMA_NAME, '.', '%', '${table}', '%')`)\n .join(\" OR \");\n\n const timeConditions: string[] = [];\n if (from) {\n timeConditions.push(`SUMMARY_BEGIN_TIME >= '${formatDateTime(from)}'`);\n }\n if (to) {\n timeConditions.push(`SUMMARY_END_TIME <= '${formatDateTime(to)}'`);\n }\n\n let whereClauses;\n if (tableConditions?.length) {\n whereClauses = [tableConditions ? `(${tableConditions})` : \"\", ...timeConditions];\n } else {\n whereClauses = timeConditions;\n }\n\n return `\n SELECT *\n FROM (\n SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY\n UNION ALL\n SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY\n ) AS combined\n ${whereClauses?.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\"}\n `;\n }\n\n /**\n * Retrieves and analyzes slow queries from the database.\n * @returns {Promise<SlowQueryNormalized[]>} The normalized slow query data\n */\n // CLUSTER_SLOW_QUERY STATISTICS\n async analyzeSlowQueries(): Promise<SlowQueryNormalized[]> {\n const results = await this.forgeOperations.fetch().executeRawSQL<SlowQueryRaw>(`\n SELECT *\n FROM information_schema.slow_query \n ORDER BY time DESC\n `);\n return results.map((row) => this.normalizeSlowQuery(row));\n }\n\n /**\n * Converts a cluster statement row to camelCase format.\n * @param {Record<string, any>} input - The input row data\n * @returns {ClusterStatementRowCamelCase} The converted row data\n */\n mapToCamelCaseClusterStatement(input: Record<string, any>): ClusterStatementRowCamelCase {\n if (!input) {\n return {} as ClusterStatementRowCamelCase;\n }\n\n const result: any = {};\n result.parsedPlan = this.decodedPlan(input[\"PLAN\"] ?? \"\");\n for (const key in input) {\n const camelKey = key.toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n result[camelKey] = input[key];\n }\n\n return result as ClusterStatementRowCamelCase;\n }\n\n /**\n * Analyzes query history for specific tables using raw table names.\n * @param {string[]} tables - The table names to analyze\n * @param {Date} [fromDate] - The start date for the analysis\n * @param {Date} [toDate] - The end date for the analysis\n * @returns {Promise<ClusterStatementRowCamelCase[]>} The analyzed query history\n */\n async analyzeQueriesHistoryRaw(\n tables: string[],\n fromDate?: Date,\n toDate?: Date,\n ): Promise<ClusterStatementRowCamelCase[]> {\n const results = await this.forgeOperations\n .fetch()\n .executeRawSQL<ClusterStatementRow>(\n this.buildClusterStatementQuery(tables ?? [], fromDate, toDate),\n );\n return results.map((r) => this.mapToCamelCaseClusterStatement(r));\n }\n\n /**\n * Analyzes query history for specific tables using Drizzle table objects.\n * @param {AnyMySqlTable[]} tables - The Drizzle table objects to analyze\n * @param {Date} [fromDate] - The start date for the analysis\n * @param {Date} [toDate] - The end date for the analysis\n * @returns {Promise<ClusterStatementRowCamelCase[]>} The analyzed query history\n */\n async analyzeQueriesHistory(\n tables: AnyMySqlTable[],\n fromDate?: Date,\n toDate?: Date,\n ): Promise<ClusterStatementRowCamelCase[]> {\n const tableNames = tables?.map((table) => getTableName(table)) ?? [];\n return this.analyzeQueriesHistoryRaw(tableNames, fromDate, toDate);\n }\n}\n","import { MySqlSelectDynamic } from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { AnyMySqlSelectQueryBuilder, AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { CacheForgeSQL, ForgeSqlOperation, ForgeSqlOrmOptions } from \"./ForgeSQLQueryBuilder\";\nimport { InferInsertModel, Query, SQL } from \"drizzle-orm\";\nimport { clearCache, getFromCache, setCacheResult, clearTablesCache } from \"../utils/cacheUtils\";\nimport { getTableName } from \"drizzle-orm/table\";\n\n/**\n * Implementation of cache operations for ForgeSQL ORM.\n * Provides methods for cacheable database operations with automatic cache management.\n *\n * ⚠️ **IMPORTANT**: All modification methods in this class use optimistic locking/versioning\n * through `modifyWithVersioning()` internally. This ensures data consistency and prevents\n * concurrent modification conflicts.\n */\nexport class ForgeSQLCacheOperations implements CacheForgeSQL {\n private readonly options: ForgeSqlOrmOptions;\n private readonly forgeOperations: ForgeSqlOperation;\n\n /**\n * Creates a new instance of ForgeSQLCacheOperations.\n *\n * @param options - Configuration options for the ORM\n * @param forgeOperations - The ForgeSQL operations instance\n */\n constructor(options: ForgeSqlOrmOptions, forgeOperations: ForgeSqlOperation) {\n this.options = options;\n this.forgeOperations = forgeOperations;\n }\n\n /**\n * Evicts cache for multiple tables using Drizzle table objects.\n *\n * @param tables - Array of Drizzle table objects to clear cache for\n * @returns Promise that resolves when cache eviction is complete\n * @throws Error if cacheEntityName is not configured\n */\n async evictCacheEntities(tables: AnyMySqlTable[]): Promise<void> {\n if (!this.options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n await this.evictCache(tables.map((t) => getTableName(t)));\n }\n\n /**\n * Evicts cache for multiple tables by their names.\n *\n * @param tables - Array of table names to clear cache for\n * @returns Promise that resolves when cache eviction is complete\n * @throws Error if cacheEntityName is not configured\n */\n async evictCache(tables: string[]): Promise<void> {\n if (!this.options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n await clearTablesCache(tables, this.options);\n }\n\n /**\n * Inserts records with optimistic locking/versioning and automatically evicts cache.\n *\n * This method uses `modifyWithVersioning().insert()` internally, providing:\n * - Automatic version field initialization\n * - Optimistic locking support\n * - Cache eviction after successful operation\n *\n * @param schema - The table schema\n * @param models - Array of entities to insert\n * @param updateIfExists - Whether to update existing records\n * @returns Promise that resolves to the number of inserted rows\n * @throws Error if cacheEntityName is not configured\n * @throws Error if optimistic locking check fails\n */\n async insert<T extends AnyMySqlTable>(\n schema: T,\n models: InferInsertModel<T>[],\n updateIfExists?: boolean,\n ): Promise<number> {\n this.validateCacheConfiguration();\n const number = await this.forgeOperations\n .modifyWithVersioning()\n .insert(schema, models, updateIfExists);\n await clearCache(schema, this.options);\n return number;\n }\n\n /**\n * Deletes a record by ID with optimistic locking/versioning and automatically evicts cache.\n *\n * This method uses `modifyWithVersioning().deleteById()` internally, providing:\n * - Optimistic locking checks before deletion\n * - Version field validation\n * - Cache eviction after successful operation\n *\n * @param id - The ID of the record to delete\n * @param schema - The table schema\n * @returns Promise that resolves to the number of affected rows\n * @throws Error if cacheEntityName is not configured\n * @throws Error if optimistic locking check fails\n */\n async deleteById<T extends AnyMySqlTable>(id: unknown, schema: T): Promise<number> {\n this.validateCacheConfiguration();\n const number = await this.forgeOperations.modifyWithVersioning().deleteById(id, schema);\n await clearCache(schema, this.options);\n return number;\n }\n\n /**\n * Updates a record by ID with optimistic locking/versioning and automatically evicts cache.\n *\n * This method uses `modifyWithVersioning().updateById()` internally, providing:\n * - Optimistic locking checks before update\n * - Version field incrementation\n * - Cache eviction after successful operation\n *\n * @param entity - The entity with updated values (must include primary key)\n * @param schema - The table schema\n * @returns Promise that resolves to the number of affected rows\n * @throws Error if cacheEntityName is not configured\n * @throws Error if optimistic locking check fails\n */\n async updateById<T extends AnyMySqlTable>(\n entity: Partial<InferInsertModel<T>>,\n schema: T,\n ): Promise<number> {\n this.validateCacheConfiguration();\n const number = await this.forgeOperations.modifyWithVersioning().updateById(entity, schema);\n await clearCache(schema, this.options);\n return number;\n }\n\n /**\n * Updates fields based on conditions with optimistic locking/versioning and automatically evicts cache.\n *\n * This method uses `modifyWithVersioning().updateFields()` internally, providing:\n * - Optimistic locking support (if version field is configured)\n * - Version field validation and incrementation\n * - Cache eviction after successful operation\n *\n * @param updateData - The data to update\n * @param schema - The table schema\n * @param where - Optional WHERE conditions\n * @returns Promise that resolves to the number of affected rows\n * @throws Error if cacheEntityName is not configured\n * @throws Error if optimistic locking check fails\n */\n async updateFields<T extends AnyMySqlTable>(\n updateData: Partial<InferInsertModel<T>>,\n schema: T,\n where?: SQL<unknown>,\n ): Promise<number> {\n this.validateCacheConfiguration();\n const number = await this.forgeOperations\n .modifyWithVersioning()\n .updateFields(updateData, schema, where);\n await clearCache(schema, this.options);\n return number;\n }\n\n /**\n * Executes a query with caching support.\n * First checks cache, if not found executes query and stores result in cache.\n *\n * @param query - The Drizzle query to execute\n * @param cacheTtl - Optional cache TTL override\n * @returns Promise that resolves to the query results\n * @throws Error if cacheEntityName is not configured\n */\n async executeQuery<T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>>(\n query: T,\n cacheTtl?: number,\n ): Promise<Awaited<T>> {\n this.validateCacheConfiguration();\n const sqlQuery = query as { toSQL: () => Query };\n const cacheResult = await getFromCache<Awaited<T>>(sqlQuery, this.options);\n if (cacheResult) {\n return cacheResult;\n }\n const results = await query;\n await setCacheResult(sqlQuery, this.options, results, cacheTtl ?? this.options.cacheTTL ?? 60);\n return results;\n }\n\n /**\n * Validates that cache configuration is properly set up.\n *\n * @throws Error if cacheEntityName is not configured\n * @private\n */\n private validateCacheConfiguration(): void {\n if (!this.options.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n }\n}\n","import { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport {\n VerioningModificationForgeSQL,\n ForgeSqlOperation,\n ForgeSqlOrmOptions,\n SchemaAnalyzeForgeSql,\n SchemaSqlForgeSql,\n} from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport {\n drizzle,\n MySqlRemoteDatabase,\n MySqlRemotePreparedQueryHKT,\n MySqlRemoteQueryResultHKT,\n} from \"drizzle-orm/mysql-proxy\";\nimport { createForgeDriverProxy } from \"../utils/forgeDriverProxy\";\nimport type { SelectedFields } from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { MySqlSelectBuilder } from \"drizzle-orm/mysql-core\";\nimport {\n DeleteAndEvictCacheType,\n InsertAndEvictCacheType,\n patchDbWithSelectAliased,\n SelectAliasedCacheableType,\n SelectAliasedDistinctCacheableType,\n SelectAliasedDistinctType,\n SelectAliasedType,\n UpdateAndEvictCacheType,\n} from \"../lib/drizzle/extensions/additionalActions\";\nimport { ForgeSQLAnalyseOperation } from \"./ForgeSQLAnalyseOperations\";\nimport { ForgeSQLCacheOperations } from \"./ForgeSQLCacheOperations\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core/table\";\nimport {\n MySqlDeleteBase,\n MySqlInsertBuilder,\n MySqlUpdateBuilder,\n} from \"drizzle-orm/mysql-core/query-builders\";\nimport { cacheApplicationContext, localCacheApplicationContext } from \"../utils/cacheContextUtils\";\nimport { clearTablesCache } from \"../utils/cacheUtils\";\nimport { SQLWrapper } from \"drizzle-orm/sql/sql\";\nimport { WithSubquery } from \"drizzle-orm/subquery\";\nimport { getLastestMetadata, metadataQueryContext } from \"../utils/metadataContextUtils\";\nimport { operationTypeQueryContext } from \"../utils/requestTypeContextUtils\";\nimport type { MySqlQueryResultKind } from \"drizzle-orm/mysql-core/session\";\n\n/**\n * Implementation of ForgeSQLORM that uses Drizzle ORM for query building.\n * This class provides a bridge between Forge SQL and Drizzle ORM, allowing\n * to use Drizzle's query builder while executing queries through Forge SQL.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly drizzle: MySqlRemoteDatabase<any> & {\n selectAliased: SelectAliasedType;\n selectAliasedDistinct: SelectAliasedDistinctType;\n selectAliasedCacheable: SelectAliasedCacheableType;\n selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;\n insertWithCacheContext: InsertAndEvictCacheType;\n insertAndEvictCache: InsertAndEvictCacheType;\n updateAndEvictCache: UpdateAndEvictCacheType;\n updateWithCacheContext: UpdateAndEvictCacheType;\n deleteAndEvictCache: DeleteAndEvictCacheType;\n deleteWithCacheContext: DeleteAndEvictCacheType;\n };\n private readonly crudOperations: VerioningModificationForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n private readonly analyzeOperations: SchemaAnalyzeForgeSql;\n private readonly cacheOperations: ForgeSQLCacheOperations;\n private readonly options: ForgeSqlOrmOptions;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n */\n private constructor(options?: ForgeSqlOrmOptions) {\n try {\n const newOptions: ForgeSqlOrmOptions = options ?? {\n logRawSqlQuery: false,\n logCache: false,\n disableOptimisticLocking: false,\n cacheWrapTable: true,\n cacheTTL: 120,\n cacheEntityQueryName: \"sql\",\n cacheEntityExpirationName: \"expiration\",\n cacheEntityDataName: \"data\",\n };\n this.options = newOptions;\n if (newOptions.logRawSqlQuery) {\n // eslint-disable-next-line no-console\n console.debug(\"Initializing ForgeSQLORM...\");\n }\n // Initialize Drizzle instance with our custom driver\n const proxiedDriver = createForgeDriverProxy(\n this,\n newOptions.hints,\n newOptions.logRawSqlQuery,\n );\n this.drizzle = patchDbWithSelectAliased(\n drizzle(proxiedDriver, { logger: newOptions.logRawSqlQuery }),\n newOptions,\n );\n this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);\n this.fetchOperations = new ForgeSQLSelectOperations(newOptions);\n this.analyzeOperations = new ForgeSQLAnalyseOperation(this);\n this.cacheOperations = new ForgeSQLCacheOperations(newOptions, this);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error;\n }\n }\n\n /**\n * Executes a query and provides access to execution metadata with performance monitoring.\n * This method allows you to capture detailed information about query execution\n * including database execution time, response size, and query analysis capabilities.\n *\n * The method aggregates metrics across all database operations within the query function,\n * making it ideal for monitoring resolver performance and detecting performance issues.\n *\n * @template T - The return type of the query\n * @param query - A function that returns a Promise with the query result. Can contain multiple database operations.\n * @param onMetadata - Callback function that receives aggregated execution metadata\n * @param onMetadata.totalDbExecutionTime - Total database execution time across all operations in the query function (in milliseconds)\n * @param onMetadata.totalResponseSize - Total response size across all operations (in bytes)\n * @param onMetadata.printQueries - Function to analyze and print query execution plans from CLUSTER_STATEMENTS_SUMMARY\n * @returns Promise with the query result\n *\n * @example\n * ```typescript\n * // Basic usage with performance monitoring\n * const result = await forgeSQL.executeWithMetadata(\n * async () => {\n * const users = await forgeSQL.selectFrom(usersTable);\n * const orders = await forgeSQL.selectFrom(ordersTable).where(eq(ordersTable.userId, usersTable.id));\n * return { users, orders };\n * },\n * (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Analyze and print query execution plans\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * ```\n *\n * @example\n * ```typescript\n * // Resolver with performance monitoring\n * resolver.define(\"fetch\", async (req: Request) => {\n * try {\n * return await forgeSQL.executeWithMetadata(\n * async () => {\n * // Resolver logic with multiple queries\n * const users = await forgeSQL.selectFrom(demoUsers);\n * const orders = await forgeSQL.selectFrom(demoOrders)\n * .where(eq(demoOrders.userId, demoUsers.id));\n * return { users, orders };\n * },\n * async (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Optionally log or capture diagnostics for further analysis\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * } catch (e) {\n * const error = e?.cause?.debug?.sqlMessage ?? e?.cause;\n * console.error(error, e);\n * throw error;\n * }\n * });\n * ```\n *\n * @note **Important**: When multiple resolvers are running concurrently, their query data may also appear in `printQueries()` analysis, as it queries the global `CLUSTER_STATEMENTS_SUMMARY` table.\n */\n async executeWithMetadata<T>(\n query: () => Promise<T>,\n onMetadata: (\n totalDbExecutionTime: number,\n totalResponseSize: number,\n printQueriesWithPlan: () => Promise<void>,\n ) => Promise<void> | void,\n ): Promise<T> {\n return metadataQueryContext.run(\n {\n totalDbExecutionTime: 0,\n totalResponseSize: 0,\n beginTime: new Date(),\n forgeSQLORM: this,\n printQueriesWithPlan: async () => {\n return;\n },\n },\n async () => {\n const result = await query();\n const metadata = await getLastestMetadata();\n try {\n if (metadata) {\n await onMetadata(\n metadata.totalDbExecutionTime,\n metadata.totalResponseSize,\n metadata.printQueriesWithPlan,\n );\n }\n } catch (e: any) {\n // eslint-disable-next-line no-console\n console.error(\n \"[ForgeSQLORM][executeWithMetadata] Failed to run onMetadata callback\",\n {\n errorMessage: e?.message,\n errorStack: e?.stack,\n totalDbExecutionTime: metadata?.totalDbExecutionTime,\n totalResponseSize: metadata?.totalResponseSize,\n beginTime: metadata?.beginTime,\n },\n e,\n );\n }\n return result;\n },\n );\n }\n\n /**\n * Executes operations within a cache context that collects cache eviction events.\n * All clearCache calls within the context are collected and executed in batch at the end.\n * Queries executed within this context will bypass cache for tables that were marked for clearing.\n *\n * This is useful for:\n * - Batch operations that affect multiple tables\n * - Transaction-like operations where you want to clear cache only at the end\n * - Performance optimization by reducing cache clear operations\n *\n * @param cacheContext - Function containing operations that may trigger cache evictions\n * @returns Promise that resolves when all operations and cache clearing are complete\n *\n * @example\n * ```typescript\n * await forgeSQL.executeWithCacheContext(async () => {\n * await forgeSQL.modifyWithVersioning().insert(users, userData);\n * await forgeSQL.modifyWithVersioning().insert(orders, orderData);\n * // Cache for both users and orders tables will be cleared at the end\n * });\n * ```\n */\n executeWithCacheContext(cacheContext: () => Promise<void>): Promise<void> {\n return this.executeWithCacheContextAndReturnValue<void>(cacheContext);\n }\n\n /**\n * Executes operations within a cache context and returns a value.\n * All clearCache calls within the context are collected and executed in batch at the end.\n * Queries executed within this context will bypass cache for tables that were marked for clearing.\n *\n * @param cacheContext - Function containing operations that may trigger cache evictions\n * @returns Promise that resolves to the return value of the cacheContext function\n *\n * @example\n * ```typescript\n * const result = await forgeSQL.executeWithCacheContextAndReturnValue(async () => {\n * await forgeSQL.modifyWithVersioning().insert(users, userData);\n * return await forgeSQL.fetch().executeQueryOnlyOne(selectUserQuery);\n * });\n * ```\n */\n async executeWithCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {\n return await this.executeWithLocalCacheContextAndReturnValue(\n async () =>\n await cacheApplicationContext.run(\n cacheApplicationContext.getStore() ?? { tables: new Set<string>() },\n async () => {\n try {\n return await cacheContext();\n } finally {\n await clearTablesCache(\n Array.from(cacheApplicationContext.getStore()?.tables ?? []),\n this.options,\n );\n }\n },\n ),\n );\n }\n /**\n * Executes operations within a local cache context and returns a value.\n * This provides in-memory caching for select queries within a single request scope.\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves to the return value of the cacheContext function\n */\n async executeWithLocalCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {\n return await localCacheApplicationContext.run(\n localCacheApplicationContext.getStore() ?? { cache: {} },\n async () => {\n return await cacheContext();\n },\n );\n }\n\n /**\n * Executes operations within a local cache context.\n * This provides in-memory caching for select queries within a single request scope.\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves when all operations are complete\n */\n executeWithLocalContext(cacheContext: () => Promise<void>): Promise<void> {\n return this.executeWithLocalCacheContextAndReturnValue<void>(cacheContext);\n }\n /**\n * Creates an insert query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder (no versioning, no cache management)\n */\n insert<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.insertWithCacheContext(table);\n }\n /**\n * Creates an insert query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder with automatic cache eviction (no versioning)\n */\n insertAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.insertAndEvictCache(table);\n }\n\n /**\n * Creates an update query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder with automatic cache eviction (no versioning)\n */\n updateAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.updateAndEvictCache(table);\n }\n\n /**\n * Creates an update query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder (no versioning, no cache management)\n */\n update<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.updateWithCacheContext(table);\n }\n\n /**\n * Creates a delete query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder (no versioning, no cache management)\n */\n delete<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.deleteWithCacheContext(table);\n }\n /**\n * Creates a delete query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder with automatic cache eviction (no versioning)\n */\n deleteAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.drizzle.deleteAndEvictCache(table);\n }\n\n /**\n * Create the modify operations instance.\n * @returns modify operations.\n */\n modifyWithVersioning(): VerioningModificationForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(options?: ForgeSqlOrmOptions): ForgeSqlOperation {\n ForgeSQLORMImpl.instance ??= new ForgeSQLORMImpl(options);\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Provides query analysis capabilities including EXPLAIN ANALYZE and slow query analysis.\n * @returns {SchemaAnalyzeForgeSql} Interface for analyzing query performance\n */\n analyze(): SchemaAnalyzeForgeSql {\n return this.analyzeOperations;\n }\n\n /**\n * Provides schema-level SQL operations with optimistic locking/versioning and automatic cache eviction.\n *\n * This method returns operations that use `modifyWithVersioning()` internally, providing:\n * - Optimistic locking support\n * - Automatic version field management\n * - Cache eviction after successful operations\n *\n * @returns {ForgeSQLCacheOperations} Interface for executing versioned SQL operations with cache management\n */\n modifyWithVersioningAndEvictCache(): ForgeSQLCacheOperations {\n return this.cacheOperations;\n }\n\n /**\n * Returns a Drizzle query builder instance.\n *\n * ⚠️ IMPORTANT: This method should be used ONLY for query building purposes.\n * The returned instance should NOT be used for direct database connections or query execution.\n * All database operations should be performed through Forge SQL's executeRawSQL or executeRawUpdateSQL methods.\n *\n * @returns A Drizzle query builder instance for query construction only.\n */\n getDrizzleQueryBuilder(): MySqlRemoteDatabase<Record<string, unknown>> & {\n selectAliased: SelectAliasedType;\n selectAliasedDistinct: SelectAliasedDistinctType;\n selectAliasedCacheable: SelectAliasedCacheableType;\n selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;\n insertWithCacheContext: InsertAndEvictCacheType;\n insertAndEvictCache: InsertAndEvictCacheType;\n updateAndEvictCache: UpdateAndEvictCacheType;\n updateWithCacheContext: UpdateAndEvictCacheType;\n deleteAndEvictCache: DeleteAndEvictCacheType;\n deleteWithCacheContext: DeleteAndEvictCacheType;\n } {\n return this.drizzle;\n }\n\n /**\n * Creates a select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .select({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n select<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n if (!fields) {\n throw new Error(\"fields is empty\");\n }\n return this.drizzle.selectAliased(fields);\n }\n\n /**\n * Creates a distinct select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A distinct select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectDistinct({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectDistinct<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n if (!fields) {\n throw new Error(\"fields is empty\");\n }\n return this.drizzle.selectAliasedDistinct(fields);\n }\n\n /**\n * Creates a cacheable select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @param {number} cacheTTL - cache ttl optional default is 60 sec.\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectCacheable({user: users, order: orders},60)\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n if (!fields) {\n throw new Error(\"fields is empty\");\n }\n return this.drizzle.selectAliasedCacheable(fields, cacheTTL);\n }\n\n /**\n * Creates a cacheable distinct select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @param {number} cacheTTL - cache ttl optional default is 60 sec.\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A distinct select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectDistinctCacheable({user: users, order: orders}, 60)\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectDistinctCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n if (!fields) {\n throw new Error(\"fields is empty\");\n }\n return this.drizzle.selectAliasedDistinctCacheable(fields, cacheTTL);\n }\n\n /**\n * Creates a select query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));\n * ```\n */\n selectFrom<T extends MySqlTable>(table: T) {\n return this.drizzle.selectFrom(table);\n }\n\n /**\n * Creates a select distinct query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all distinct columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select distinct query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctFrom<T extends MySqlTable>(table: T) {\n return this.drizzle.selectDistinctFrom(table);\n }\n\n /**\n * Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));\n * ```\n */\n selectCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {\n return this.drizzle.selectFromCacheable(table, cacheTTL);\n }\n\n /**\n * Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select distinct query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {\n return this.drizzle.selectDistinctFromCacheable(table, cacheTTL);\n }\n\n /**\n * Executes a raw SQL query with local cache support.\n * This method provides local caching for raw SQL queries within the current invocation context.\n * Results are cached locally and will be returned from cache on subsequent identical queries.\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper\n * const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);\n *\n * // Using string\n * const result = await forgeSQL.execute(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n execute<T>(query: SQLWrapper | string) {\n return this.drizzle.executeQuery<T>(query);\n }\n\n /**\n * Executes a Data Definition Language (DDL) SQL query.\n * DDL operations include CREATE, ALTER, DROP, TRUNCATE, and other schema modification statements.\n *\n * This method is specifically designed for DDL operations and provides:\n * - Proper operation type context for DDL queries\n * - No caching (DDL operations should not be cached)\n * - Direct execution without query optimization\n *\n * @template T - The expected return type of the query result\n * @param query - The DDL SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @throws {Error} If the DDL operation fails\n *\n * @example\n * ```typescript\n * // Create a new table\n * await forgeSQL.executeDDL(`\n * CREATE TABLE users (\n * id INT PRIMARY KEY AUTO_INCREMENT,\n * name VARCHAR(255) NOT NULL,\n * email VARCHAR(255) UNIQUE\n * )\n * `);\n *\n * // Alter table structure\n * await forgeSQL.executeDDL(sql`\n * ALTER TABLE users\n * ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n * `);\n *\n * // Drop a table\n * await forgeSQL.executeDDL(\"DROP TABLE IF EXISTS old_users\");\n * ```\n */\n async executeDDL<T>(query: SQLWrapper | string) {\n return this.executeDDLActions(async () => this.drizzle.executeQuery<T>(query));\n }\n\n /**\n * Executes a series of actions within a DDL operation context.\n * This method provides a way to execute regular SQL queries that should be treated\n * as DDL operations, ensuring proper operation type context for performance monitoring.\n *\n * This method is useful for:\n * - Executing regular SQL queries in DDL context for monitoring purposes\n * - Wrapping non-DDL operations that should be treated as DDL for analysis\n * - Ensuring proper operation type context for complex workflows\n * - Maintaining DDL operation context across multiple function calls\n *\n * @template T - The return type of the actions function\n * @param actions - Function containing SQL operations to execute in DDL context\n * @returns Promise that resolves to the return value of the actions function\n *\n * @example\n * ```typescript\n * // Execute regular SQL queries in DDL context for monitoring\n * await forgeSQL.executeDDLActions(async () => {\n * const slowQueries = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * WHERE AVG_LATENCY > 1000000\n * `);\n * return slowQueries;\n * });\n *\n * // Execute complex analysis queries in DDL context\n * const result = await forgeSQL.executeDDLActions(async () => {\n * const tableInfo = await forgeSQL.execute(\"SHOW TABLES\");\n * const performanceData = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY\n * WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)\n * `);\n * return { tableInfo, performanceData };\n * });\n *\n * // Execute monitoring queries with error handling\n * try {\n * await forgeSQL.executeDDLActions(async () => {\n * const metrics = await forgeSQL.execute(`\n * SELECT COUNT(*) as query_count\n * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * `);\n * console.log(`Total queries: ${metrics[0].query_count}`);\n * });\n * } catch (error) {\n * console.error(\"Monitoring query failed:\", error);\n * }\n * ```\n */\n async executeDDLActions<T>(actions: () => Promise<T>): Promise<T> {\n return operationTypeQueryContext.run({ operationType: \"DDL\" }, async () => actions());\n }\n\n /**\n * Executes a raw SQL query with both local and global cache support.\n * This method provides comprehensive caching for raw SQL queries:\n * - Local cache: Within the current invocation context\n * - Global cache: Cross-invocation caching using @forge/kvs\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper with custom TTL\n * const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);\n *\n * // Using string with default TTL\n * const result = await forgeSQL.executeCacheable(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n executeCacheable<T>(\n query: SQLWrapper | string,\n cacheTtl?: number,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>> {\n return this.drizzle.executeQueryCacheable<T>(query, cacheTtl);\n }\n\n /**\n * Creates a Common Table Expression (CTE) builder for complex queries.\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @returns WithBuilder for creating CTEs\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n * ```\n */\n get $with() {\n return this.drizzle.$with;\n }\n\n /**\n * Creates a query builder that uses Common Table Expressions (CTEs).\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @param queries - Array of CTE queries created with $with()\n * @returns Query builder with CTE support\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n *\n * const result = await forgeSQL.with(withQuery)\n * .select({ userId: withQuery.userId, count: withQuery.count })\n * .from(withQuery);\n * ```\n */\n with(...queries: WithSubquery[]) {\n return this.drizzle.with(...queries);\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n * Provides a clean interface for working with Forge SQL and Drizzle ORM.\n */\nclass ForgeSQLORM implements ForgeSqlOperation {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(options?: ForgeSqlOrmOptions) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(options);\n }\n\n /**\n * Executes a query and provides access to execution metadata with performance monitoring.\n * This method allows you to capture detailed information about query execution\n * including database execution time, response size, and query analysis capabilities.\n *\n * The method aggregates metrics across all database operations within the query function,\n * making it ideal for monitoring resolver performance and detecting performance issues.\n *\n * @template T - The return type of the query\n * @param query - A function that returns a Promise with the query result. Can contain multiple database operations.\n * @param onMetadata - Callback function that receives aggregated execution metadata\n * @param onMetadata.totalDbExecutionTime - Total database execution time across all operations in the query function (in milliseconds)\n * @param onMetadata.totalResponseSize - Total response size across all operations (in bytes)\n * @param onMetadata.printQueries - Function to analyze and print query execution plans from CLUSTER_STATEMENTS_SUMMARY\n * @returns Promise with the query result\n *\n * @example\n * ```typescript\n * // Basic usage with performance monitoring\n * const result = await forgeSQL.executeWithMetadata(\n * async () => {\n * const users = await forgeSQL.selectFrom(usersTable);\n * const orders = await forgeSQL.selectFrom(ordersTable).where(eq(ordersTable.userId, usersTable.id));\n * return { users, orders };\n * },\n * (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Analyze and print query execution plans\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * ```\n *\n * @example\n * ```typescript\n * // Resolver with performance monitoring\n * resolver.define(\"fetch\", async (req: Request) => {\n * try {\n * return await forgeSQL.executeWithMetadata(\n * async () => {\n * // Resolver logic with multiple queries\n * const users = await forgeSQL.selectFrom(demoUsers);\n * const orders = await forgeSQL.selectFrom(demoOrders)\n * .where(eq(demoOrders.userId, demoUsers.id));\n * return { users, orders };\n * },\n * async (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Optionally log or capture diagnostics for further analysis\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * } catch (e) {\n * const error = e?.cause?.debug?.sqlMessage ?? e?.cause;\n * console.error(error, e);\n * throw error;\n * }\n * });\n * ```\n *\n * @note **Important**: When multiple resolvers are running concurrently, their query data may also appear in `printQueries()` analysis, as it queries the global `CLUSTER_STATEMENTS_SUMMARY` table.\n */\n async executeWithMetadata<T>(\n query: () => Promise<T>,\n onMetadata: (\n totalDbExecutionTime: number,\n totalResponseSize: number,\n printQueriesWithPlan: () => Promise<void>,\n ) => Promise<void> | void,\n ): Promise<T> {\n return this.ormInstance.executeWithMetadata(query, onMetadata);\n }\n\n selectCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.selectCacheable(fields, cacheTTL);\n }\n\n selectDistinctCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.selectDistinctCacheable(fields, cacheTTL);\n }\n\n /**\n * Creates a select query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));\n * ```\n */\n selectFrom<T extends MySqlTable>(table: T) {\n return this.ormInstance.getDrizzleQueryBuilder().selectFrom(table);\n }\n\n /**\n * Creates a select distinct query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all distinct columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select distinct query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctFrom<T extends MySqlTable>(table: T) {\n return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFrom(table);\n }\n\n /**\n * Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));\n * ```\n */\n selectCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {\n return this.ormInstance.getDrizzleQueryBuilder().selectFromCacheable(table, cacheTTL);\n }\n\n /**\n * Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select distinct query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {\n return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFromCacheable(table, cacheTTL);\n }\n\n executeWithCacheContext(cacheContext: () => Promise<void>): Promise<void> {\n return this.ormInstance.executeWithCacheContext(cacheContext);\n }\n executeWithCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {\n return this.ormInstance.executeWithCacheContextAndReturnValue(cacheContext);\n }\n /**\n * Executes operations within a local cache context.\n * This provides in-memory caching for select queries within a single request scope.\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves when all operations are complete\n */\n executeWithLocalContext(cacheContext: () => Promise<void>): Promise<void> {\n return this.ormInstance.executeWithLocalContext(cacheContext);\n }\n\n /**\n * Executes operations within a local cache context and returns a value.\n * This provides in-memory caching for select queries within a single request scope.\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves to the return value of the cacheContext function\n */\n executeWithLocalCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {\n return this.ormInstance.executeWithLocalCacheContextAndReturnValue(cacheContext);\n }\n\n /**\n * Creates an insert query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder (no versioning, no cache management)\n */\n insert<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.insert(table);\n }\n\n /**\n * Creates an insert query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder with automatic cache eviction (no versioning)\n */\n insertAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.insertAndEvictCache(table);\n }\n\n /**\n * Creates an update query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder (no versioning, no cache management)\n */\n update<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.update(table);\n }\n\n /**\n * Creates an update query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder with automatic cache eviction (no versioning)\n */\n updateAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.updateAndEvictCache(table);\n }\n\n /**\n * Creates a delete query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder (no versioning, no cache management)\n */\n delete<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.delete(table);\n }\n\n /**\n * Creates a delete query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder with automatic cache eviction (no versioning)\n */\n deleteAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.deleteAndEvictCache(table);\n }\n\n /**\n * Creates a select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .select({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n select<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.select(fields);\n }\n\n /**\n * Creates a distinct select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>} A distinct select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectDistinct({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectDistinct<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT> {\n return this.ormInstance.selectDistinct(fields);\n }\n\n /**\n * Proxies the `modify` method from `ForgeSQLORMImpl`.\n * @returns Modify operations.\n */\n modifyWithVersioning(): VerioningModificationForgeSQL {\n return this.ormInstance.modifyWithVersioning();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n /**\n * Provides query analysis capabilities including EXPLAIN ANALYZE and slow query analysis.\n * @returns {SchemaAnalyzeForgeSql} Interface for analyzing query performance\n */\n analyze(): SchemaAnalyzeForgeSql {\n return this.ormInstance.analyze();\n }\n\n /**\n * Provides schema-level SQL cacheable operations with type safety.\n * @returns {ForgeSQLCacheOperations} Interface for executing schema-bound SQL queries\n */\n modifyWithVersioningAndEvictCache(): ForgeSQLCacheOperations {\n return this.ormInstance.modifyWithVersioningAndEvictCache();\n }\n\n /**\n * Returns a Drizzle query builder instance.\n *\n * @returns A Drizzle query builder instance for query construction only.\n */\n getDrizzleQueryBuilder() {\n return this.ormInstance.getDrizzleQueryBuilder();\n }\n\n /**\n * Executes a raw SQL query with local cache support.\n * This method provides local caching for raw SQL queries within the current invocation context.\n * Results are cached locally and will be returned from cache on subsequent identical queries.\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper\n * const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);\n *\n * // Using string\n * const result = await forgeSQL.execute(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n execute<T>(\n query: SQLWrapper | string,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>> {\n return this.ormInstance.execute(query);\n }\n\n /**\n * Executes a Data Definition Language (DDL) SQL query.\n * DDL operations include CREATE, ALTER, DROP, TRUNCATE, and other schema modification statements.\n *\n * This method is specifically designed for DDL operations and provides:\n * - Proper operation type context for DDL queries\n * - No caching (DDL operations should not be cached)\n * - Direct execution without query optimization\n *\n * @template T - The expected return type of the query result\n * @param query - The DDL SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @throws {Error} If the DDL operation fails\n *\n * @example\n * ```typescript\n * // Create a new table\n * await forgeSQL.executeDDL(`\n * CREATE TABLE users (\n * id INT PRIMARY KEY AUTO_INCREMENT,\n * name VARCHAR(255) NOT NULL,\n * email VARCHAR(255) UNIQUE\n * )\n * `);\n *\n * // Alter table structure\n * await forgeSQL.executeDDL(sql`\n * ALTER TABLE users\n * ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n * `);\n *\n * // Drop a table\n * await forgeSQL.executeDDL(\"DROP TABLE IF EXISTS old_users\");\n * ```\n */\n executeDDL(query: SQLWrapper | string) {\n return this.ormInstance.executeDDL(query);\n }\n\n /**\n * Executes a series of actions within a DDL operation context.\n * This method provides a way to execute regular SQL queries that should be treated\n * as DDL operations, ensuring proper operation type context for performance monitoring.\n *\n * This method is useful for:\n * - Executing regular SQL queries in DDL context for monitoring purposes\n * - Wrapping non-DDL operations that should be treated as DDL for analysis\n * - Ensuring proper operation type context for complex workflows\n * - Maintaining DDL operation context across multiple function calls\n *\n * @template T - The return type of the actions function\n * @param actions - Function containing SQL operations to execute in DDL context\n * @returns Promise that resolves to the return value of the actions function\n *\n * @example\n * ```typescript\n * // Execute regular SQL queries in DDL context for monitoring\n * await forgeSQL.executeDDLActions(async () => {\n * const slowQueries = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * WHERE AVG_LATENCY > 1000000\n * `);\n * return slowQueries;\n * });\n *\n * // Execute complex analysis queries in DDL context\n * const result = await forgeSQL.executeDDLActions(async () => {\n * const tableInfo = await forgeSQL.execute(\"SHOW TABLES\");\n * const performanceData = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY\n * WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)\n * `);\n * return { tableInfo, performanceData };\n * });\n *\n * // Execute monitoring queries with error handling\n * try {\n * await forgeSQL.executeDDLActions(async () => {\n * const metrics = await forgeSQL.execute(`\n * SELECT COUNT(*) as query_count\n * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * `);\n * console.log(`Total queries: ${metrics[0].query_count}`);\n * });\n * } catch (error) {\n * console.error(\"Monitoring query failed:\", error);\n * }\n * ```\n */\n executeDDLActions<T>(actions: () => Promise<T>): Promise<T> {\n return this.ormInstance.executeDDLActions(actions);\n }\n\n /**\n * Executes a raw SQL query with both local and global cache support.\n * This method provides comprehensive caching for raw SQL queries:\n * - Local cache: Within the current invocation context\n * - Global cache: Cross-invocation caching using @forge/kvs\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper with custom TTL\n * const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);\n *\n * // Using string with default TTL\n * const result = await forgeSQL.executeCacheable(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n executeCacheable<T>(\n query: SQLWrapper | string,\n cacheTtl?: number,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>> {\n return this.ormInstance.executeCacheable(query, cacheTtl);\n }\n\n /**\n * Creates a Common Table Expression (CTE) builder for complex queries.\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @returns WithBuilder for creating CTEs\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.getDrizzleQueryBuilder().select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n * ```\n */\n get $with() {\n return this.ormInstance.getDrizzleQueryBuilder().$with;\n }\n\n /**\n * Creates a query builder that uses Common Table Expressions (CTEs).\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @param queries - Array of CTE queries created with $with()\n * @returns Query builder with CTE support\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.getDrizzleQueryBuilder().select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n *\n * const result = await forgeSQL.with(withQuery)\n * .select({ userId: withQuery.userId, count: withQuery.count })\n * .from(withQuery);\n * ```\n */\n with(...queries: WithSubquery[]) {\n return this.ormInstance.getDrizzleQueryBuilder().with(...queries);\n }\n}\n\nexport default ForgeSQLORM;\n","import { UpdateQueryResponse } from \"@forge/sql\";\nimport { SqlParameters } from \"@forge/sql/out/sql-statement\";\nimport {\n AnyMySqlSelectQueryBuilder,\n AnyMySqlTable,\n customType,\n MySqlSelectBuilder,\n MySqlTable,\n} from \"drizzle-orm/mysql-core\";\nimport {\n MySqlSelectDynamic,\n type SelectedFields,\n} from \"drizzle-orm/mysql-core/query-builders/select.types\";\nimport { InferInsertModel, Query, SQL } from \"drizzle-orm\";\nimport { parseDateTime, formatDateTime } from \"../utils/sqlUtils\";\nimport {\n MySqlRemoteDatabase,\n MySqlRemotePreparedQueryHKT,\n MySqlRemoteQueryResultHKT,\n} from \"drizzle-orm/mysql-proxy\";\nimport { SqlHints } from \"../utils/sqlHints\";\nimport {\n ClusterStatementRowCamelCase,\n ExplainAnalyzeRow,\n SlowQueryNormalized,\n} from \"./SystemTables\";\nimport { ForgeSQLCacheOperations } from \"./ForgeSQLCacheOperations\";\nimport {\n DeleteAndEvictCacheType,\n ExecuteQuery,\n ExecuteQueryCacheable,\n InsertAndEvictCacheType,\n SelectAliasedCacheableType,\n SelectAliasedDistinctCacheableType,\n SelectAliasedDistinctType,\n SelectAliasedType,\n SelectAllDistinctFromAliasedType,\n SelectAllDistinctFromCacheableAliasedType,\n SelectAllFromAliasedType,\n SelectAllFromCacheableAliasedType,\n UpdateAndEvictCacheType,\n} from \"..\";\nimport {\n MySqlDeleteBase,\n MySqlInsertBuilder,\n MySqlSelectBase,\n MySqlUpdateBuilder,\n} from \"drizzle-orm/mysql-core/query-builders\";\n\nimport {\n GetSelectTableName,\n GetSelectTableSelection,\n SelectResultField,\n} from \"drizzle-orm/query-builders/select.types\";\nimport { SQLWrapper } from \"drizzle-orm/sql/sql\";\nimport type { MySqlQueryResultKind } from \"drizzle-orm/mysql-core/session\";\nimport type { WithBuilder } from \"drizzle-orm/mysql-core/subquery\";\nimport { WithSubquery } from \"drizzle-orm/subquery\";\n\n/**\n * Core interface for ForgeSQL operations.\n * Provides access to CRUD operations, schema-level SQL operations, and query analysis capabilities.\n *\n * This is the main interface that developers interact with when using ForgeSQL ORM.\n * It combines query building capabilities with database operations and caching.\n *\n * @interface ForgeSqlOperation\n * @extends {QueryBuilderForgeSql}\n */\nexport interface ForgeSqlOperation extends QueryBuilderForgeSql {\n /**\n * Creates a new query builder for the given entity.\n * @returns {MySqlRemoteDatabase<Record<string, unknown>>} The Drizzle database instance for building queries\n */\n getDrizzleQueryBuilder(): MySqlRemoteDatabase<Record<string, unknown>> & {\n selectAliased: SelectAliasedType;\n selectAliasedDistinct: SelectAliasedDistinctType;\n executeQuery: ExecuteQuery;\n selectAliasedCacheable: SelectAliasedCacheableType;\n selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;\n executeQueryCacheable: ExecuteQueryCacheable;\n insertWithCacheContext: InsertAndEvictCacheType;\n insertAndEvictCache: InsertAndEvictCacheType;\n updateAndEvictCache: UpdateAndEvictCacheType;\n updateWithCacheContext: UpdateAndEvictCacheType;\n deleteAndEvictCache: DeleteAndEvictCacheType;\n deleteWithCacheContext: DeleteAndEvictCacheType;\n selectFrom: SelectAllFromAliasedType;\n selectDistinctFrom: SelectAllDistinctFromAliasedType;\n selectFromCacheable: SelectAllFromCacheableAliasedType;\n selectDistinctFromCacheable: SelectAllDistinctFromCacheableAliasedType;\n };\n\n /**\n * Provides modify (Create, Update, Delete) operations with optimistic locking support.\n * @returns {VerioningModificationForgeSQL} Interface for performing CRUD operations\n */\n modifyWithVersioning(): VerioningModificationForgeSQL;\n\n /**\n * Provides schema-level SQL fetch operations with type safety.\n * @returns {SchemaSqlForgeSql} Interface for executing schema-bound SQL queries\n */\n fetch(): SchemaSqlForgeSql;\n\n /**\n * Provides query analysis capabilities including EXPLAIN ANALYZE and slow query analysis.\n * @returns {SchemaAnalyzeForgeSql} Interface for analyzing query performance\n */\n analyze(): SchemaAnalyzeForgeSql;\n\n /**\n * Provides schema-level SQL operations with optimistic locking/versioning and automatic cache eviction.\n *\n * This method returns operations that use `modifyWithVersioning()` internally, providing:\n * - Optimistic locking support\n * - Automatic version field management\n * - Cache eviction after successful operations\n *\n * @returns {ForgeSQLCacheOperations} Interface for executing versioned SQL operations with cache management\n */\n modifyWithVersioningAndEvictCache(): ForgeSQLCacheOperations;\n}\n\n/**\n * Interface for Query Builder operations.\n * Provides access to the underlying Drizzle ORM query builder with enhanced functionality.\n *\n * This interface extends Drizzle's query building capabilities with:\n * - Field aliasing to prevent name collisions in joins\n * - Caching support for select operations\n * - Automatic cache eviction for modify operations\n *\n * @interface QueryBuilderForgeSql\n */\nexport interface QueryBuilderForgeSql {\n /**\n * Creates a new query builder for the given entity.\n * @returns {MySqlRemoteDatabase<Record<string, unknown>>} The Drizzle database instance for building queries\n */\n getDrizzleQueryBuilder(): MySqlRemoteDatabase<Record<string, unknown>> & {\n selectAliased: SelectAliasedType;\n selectAliasedDistinct: SelectAliasedDistinctType;\n executeQuery: ExecuteQuery;\n selectAliasedCacheable: SelectAliasedCacheableType;\n selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;\n executeQueryCacheable: ExecuteQueryCacheable;\n insertWithCacheContext: InsertAndEvictCacheType;\n insertAndEvictCache: InsertAndEvictCacheType;\n updateAndEvictCache: UpdateAndEvictCacheType;\n updateWithCacheContext: UpdateAndEvictCacheType;\n deleteAndEvictCache: DeleteAndEvictCacheType;\n deleteWithCacheContext: DeleteAndEvictCacheType;\n };\n\n /**\n * Creates a select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>} A select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .select({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n select<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates a select query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));\n * ```\n */\n selectFrom<T extends MySqlTable>(\n table: T,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n\n /**\n * Creates a distinct select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @returns {MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>} A distinct select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectDistinct({user: users, order: orders})\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectDistinct<TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n /**\n * Creates a select distinct query builder for all columns from a table with field aliasing support.\n * This is a convenience method that automatically selects all distinct columns from the specified table.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @returns Select distinct query builder with all table columns and field aliasing support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctFrom<T extends MySqlTable>(\n table: T,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n\n /**\n * Creates a cacheable select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @param {number} cacheTTL - cache ttl optional default is 60 sec.\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectCacheable({user: users, order: orders},60)\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));\n * ```\n */\n selectCacheableFrom<T extends MySqlTable>(\n table: T,\n cacheTTL?: number,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n\n /**\n * Creates a cacheable distinct select query with unique field aliases to prevent field name collisions in joins.\n * This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.\n *\n * @template TSelection - The type of the selected fields\n * @param {TSelection} fields - Object containing the fields to select, with table schemas as values\n * @param {number} cacheTTL - cache ttl optional default is 60 sec.\n * @returns {MySqlSelectBuilder<TSelection, MySql2PreparedQueryHKT>} A distinct select query builder with unique field aliases\n * @throws {Error} If fields parameter is empty\n * @example\n * ```typescript\n * await forgeSQL\n * .selectDistinctCacheable({user: users, order: orders}, 60)\n * .from(orders)\n * .innerJoin(users, eq(orders.userId, users.id));\n * ```\n */\n selectDistinctCacheable<TSelection extends SelectedFields>(\n fields: TSelection,\n cacheTTL?: number,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.\n * This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.\n *\n * @template T - The type of the table\n * @param table - The table to select from\n * @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)\n * @returns Select distinct query builder with all table columns, field aliasing, and caching support\n * @example\n * ```typescript\n * const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));\n * ```\n */\n selectDistinctCacheableFrom<T extends MySqlTable>(\n table: T,\n cacheTTL?: number,\n ): MySqlSelectBase<\n GetSelectTableName<T>,\n GetSelectTableSelection<T>,\n \"single\",\n MySqlRemotePreparedQueryHKT,\n GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, \"not-null\"> : {},\n false,\n never,\n {\n [K in keyof {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }]: {\n [Key in keyof GetSelectTableSelection<T>]: SelectResultField<\n GetSelectTableSelection<T>[Key]\n >;\n }[K];\n }[],\n any\n >;\n\n /**\n * Creates an insert query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder (no versioning, no cache management)\n */\n insert<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates an insert query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned inserts, use `modifyWithVersioning().insert()` or `modifyWithVersioningAndEvictCache().insert()` instead.\n *\n * @param table - The table to insert into\n * @returns Insert query builder with automatic cache eviction (no versioning)\n */\n insertAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlInsertBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates an update query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder (no versioning, no cache management)\n */\n update<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates an update query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned updates, use `modifyWithVersioning().updateById()` or `modifyWithVersioningAndEvictCache().updateById()` instead.\n *\n * @param table - The table to update\n * @returns Update query builder with automatic cache eviction (no versioning)\n */\n updateAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlUpdateBuilder<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Creates a delete query builder.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder (no versioning, no cache management)\n */\n delete<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n /**\n * Creates a delete query builder that automatically evicts cache after execution.\n *\n * ⚠️ **IMPORTANT**: This method does NOT support optimistic locking/versioning.\n * For versioned deletes, use `modifyWithVersioning().deleteById()` or `modifyWithVersioningAndEvictCache().deleteById()` instead.\n *\n * @param table - The table to delete from\n * @returns Delete query builder with automatic cache eviction (no versioning)\n */\n deleteAndEvictCache<TTable extends MySqlTable>(\n table: TTable,\n ): MySqlDeleteBase<TTable, MySqlRemoteQueryResultHKT, MySqlRemotePreparedQueryHKT>;\n\n /**\n * Executes operations within a cache context that collects cache eviction events.\n * All clearCache calls within the context are collected and executed in batch at the end.\n * Queries executed within this context will bypass cache for tables that were marked for clearing.\n *\n * @param cacheContext - Function containing operations that may trigger cache evictions\n * @returns Promise that resolves when all operations and cache clearing are complete\n */\n executeWithCacheContext(cacheContext: () => Promise<void>): Promise<void>;\n\n /**\n * Executes operations within a cache context and returns a value.\n * All clearCache calls within the context are collected and executed in batch at the end.\n * Queries executed within this context will bypass cache for tables that were marked for clearing.\n *\n * @param cacheContext - Function containing operations that may trigger cache evictions\n * @returns Promise that resolves to the return value of the cacheContext function\n */\n executeWithCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T>;\n\n /**\n * Executes operations within a local cache context that provides in-memory caching for select queries.\n * This is useful for optimizing queries within a single resolver or request scope.\n *\n * Local cache features:\n * - Caches select query results in memory for the duration of the context\n * - Automatically evicts cache when insert/update/delete operations are performed\n * - Provides faster access to repeated queries within the same context\n * - Does not persist across different requests or contexts\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves when all operations are complete\n *\n * @example\n * ```typescript\n * await forgeSQL.executeWithLocalContext(async () => {\n * // First call - executes query and caches result\n * const users = await forgeSQL.select({ id: users.id, name: users.name })\n * .from(users).where(eq(users.active, true));\n *\n * // Second call - gets result from local cache (no database query)\n * const cachedUsers = await forgeSQL.select({ id: users.id, name: users.name })\n * .from(users).where(eq(users.active, true));\n *\n * // Insert operation - evicts local cache\n * await forgeSQL.insert(users).values({ name: 'New User', active: true });\n * });\n * ```\n */\n executeWithLocalContext(cacheContext: () => Promise<void>): Promise<void>;\n\n /**\n * Executes operations within a local cache context and returns a value.\n * This is useful for optimizing queries within a single resolver or request scope.\n *\n * Local cache features:\n * - Caches select query results in memory for the duration of the context\n * - Automatically evicts cache when insert/update/delete operations are performed\n * - Provides faster access to repeated queries within the same context\n * - Does not persist across different requests or contexts\n *\n * @param cacheContext - Function containing operations that will benefit from local caching\n * @returns Promise that resolves to the return value of the cacheContext function\n *\n * @example\n * ```typescript\n * const result = await forgeSQL.executeWithLocalCacheContextAndReturnValue(async () => {\n * // First call - executes query and caches result\n * const users = await forgeSQL.select({ id: users.id, name: users.name })\n * .from(users).where(eq(users.active, true));\n *\n * // Second call - gets result from local cache (no database query)\n * const cachedUsers = await forgeSQL.select({ id: users.id, name: users.name })\n * .from(users).where(eq(users.active, true));\n *\n * return { users, cachedUsers };\n * });\n * ```\n */\n executeWithLocalCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T>;\n\n /**\n * Executes a query and provides access to execution metadata with performance monitoring.\n * This method allows you to capture detailed information about query execution\n * including database execution time, response size, and query analysis capabilities.\n *\n * The method aggregates metrics across all database operations within the query function,\n * making it ideal for monitoring resolver performance and detecting performance issues.\n *\n * @template T - The return type of the query\n * @param query - A function that returns a Promise with the query result. Can contain multiple database operations.\n * @param onMetadata - Callback function that receives aggregated execution metadata\n * @param onMetadata.totalDbExecutionTime - Total database execution time across all operations in the query function (in milliseconds)\n * @param onMetadata.totalResponseSize - Total response size across all operations (in bytes)\n * @param onMetadata.printQueries - Function to analyze and print query execution plans from CLUSTER_STATEMENTS_SUMMARY\n * @returns Promise with the query result\n *\n * @example\n * ```typescript\n * // Basic usage with performance monitoring\n * const result = await forgeSQL.executeWithMetadata(\n * async () => {\n * const users = await forgeSQL.selectFrom(usersTable);\n * const orders = await forgeSQL.selectFrom(ordersTable).where(eq(ordersTable.userId, usersTable.id));\n * return { users, orders };\n * },\n * (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Analyze and print query execution plans\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * ```\n *\n * @example\n * ```typescript\n * // Resolver with performance monitoring\n * resolver.define(\"fetch\", async (req: Request) => {\n * try {\n * return await forgeSQL.executeWithMetadata(\n * async () => {\n * // Resolver logic with multiple queries\n * const users = await forgeSQL.selectFrom(demoUsers);\n * const orders = await forgeSQL.selectFrom(demoOrders)\n * .where(eq(demoOrders.userId, demoUsers.id));\n * return { users, orders };\n * },\n * async (totalDbExecutionTime, totalResponseSize, printQueries) => {\n * const threshold = 500; // ms baseline for this resolver\n *\n * if (totalDbExecutionTime > threshold * 1.5) {\n * console.warn(`[Performance Warning fetch] Resolver exceeded DB time: ${totalDbExecutionTime} ms`);\n * await printQueries(); // Optionally log or capture diagnostics for further analysis\n * } else if (totalDbExecutionTime > threshold) {\n * console.debug(`[Performance Debug] High DB time: ${totalDbExecutionTime} ms`);\n * }\n *\n * console.log(`DB response size: ${totalResponseSize} bytes`);\n * }\n * );\n * } catch (e) {\n * const error = e?.cause?.debug?.sqlMessage ?? e?.cause;\n * console.error(error, e);\n * throw error;\n * }\n * });\n * ```\n *\n * @note **Important**: When multiple resolvers are running concurrently, their query data may also appear in `printQueries()` analysis, as it queries the global `CLUSTER_STATEMENTS_SUMMARY` table.\n */\n executeWithMetadata<T>(\n query: () => Promise<T>,\n onMetadata: (\n totalDbExecutionTime: number,\n totalResponseSize: number,\n printQueriesWithPlan: () => Promise<void>,\n ) => Promise<void> | void,\n ): Promise<T>;\n /**\n * Executes a raw SQL query with local cache support.\n * This method provides local caching for raw SQL queries within the current invocation context.\n * Results are cached locally and will be returned from cache on subsequent identical queries.\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper\n * const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);\n *\n * // Using string\n * const result = await forgeSQL.execute(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n execute<T>(\n query: SQLWrapper | string,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>>;\n\n /**\n * Executes a Data Definition Language (DDL) SQL query.\n * DDL operations include CREATE, ALTER, DROP, TRUNCATE, and other schema modification statements.\n *\n * This method is specifically designed for DDL operations and provides:\n * - Proper operation type context for DDL queries\n * - No caching (DDL operations should not be cached)\n * - Direct execution without query optimization\n *\n * @template T - The expected return type of the query result\n * @param query - The DDL SQL query to execute (SQLWrapper or string)\n * @returns Promise with query results\n * @throws {Error} If the DDL operation fails\n *\n * @example\n * ```typescript\n * // Create a new table\n * await forgeSQL.executeDDL(`\n * CREATE TABLE users (\n * id INT PRIMARY KEY AUTO_INCREMENT,\n * name VARCHAR(255) NOT NULL,\n * email VARCHAR(255) UNIQUE\n * )\n * `);\n *\n * // Alter table structure\n * await forgeSQL.executeDDL(sql`\n * ALTER TABLE users\n * ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n * `);\n *\n * // Drop a table\n * await forgeSQL.executeDDL(\"DROP TABLE IF EXISTS old_users\");\n * ```\n */\n executeDDL<T>(\n query: SQLWrapper | string,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>>;\n\n /**\n * Executes a series of actions within a DDL operation context.\n * This method provides a way to execute regular SQL queries that should be treated\n * as DDL operations, ensuring proper operation type context for performance monitoring.\n *\n * This method is useful for:\n * - Executing regular SQL queries in DDL context for monitoring purposes\n * - Wrapping non-DDL operations that should be treated as DDL for analysis\n * - Ensuring proper operation type context for complex workflows\n * - Maintaining DDL operation context across multiple function calls\n *\n * @template T - The return type of the actions function\n * @param actions - Function containing SQL operations to execute in DDL context\n * @returns Promise that resolves to the return value of the actions function\n *\n * @example\n * ```typescript\n * // Execute regular SQL queries in DDL context for monitoring\n * await forgeSQL.executeDDLActions(async () => {\n * const slowQueries = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * WHERE AVG_LATENCY > 1000000\n * `);\n * return slowQueries;\n * });\n *\n * // Execute complex analysis queries in DDL context\n * const result = await forgeSQL.executeDDLActions(async () => {\n * const tableInfo = await forgeSQL.execute(\"SHOW TABLES\");\n * const performanceData = await forgeSQL.execute(`\n * SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY\n * WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)\n * `);\n * return { tableInfo, performanceData };\n * });\n *\n * // Execute monitoring queries with error handling\n * try {\n * await forgeSQL.executeDDLActions(async () => {\n * const metrics = await forgeSQL.execute(`\n * SELECT COUNT(*) as query_count\n * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY\n * `);\n * console.log(`Total queries: ${metrics[0].query_count}`);\n * });\n * } catch (error) {\n * console.error(\"Monitoring query failed:\", error);\n * }\n * ```\n */\n executeDDLActions<T>(actions: () => Promise<T>): Promise<T>;\n\n /**\n * Executes a raw SQL query with both local and global cache support.\n * This method provides comprehensive caching for raw SQL queries:\n * - Local cache: Within the current invocation context\n * - Global cache: Cross-invocation caching using @forge/kvs\n *\n * @param query - The SQL query to execute (SQLWrapper or string)\n * @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)\n * @returns Promise with query results\n * @example\n * ```typescript\n * // Using SQLWrapper with custom TTL\n * const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);\n *\n * // Using string with default TTL\n * const result = await forgeSQL.executeCacheable(\"SELECT * FROM users WHERE status = 'active'\");\n * ```\n */\n executeCacheable<T>(\n query: SQLWrapper | string,\n cacheTtl?: number,\n ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>>;\n /**\n * Creates a Common Table Expression (CTE) builder for complex queries.\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @returns WithBuilder for creating CTEs\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n * ```\n */\n $with: WithBuilder;\n\n /**\n * Creates a query builder that uses Common Table Expressions (CTEs).\n * CTEs allow you to define temporary named result sets that exist within the scope of a single query.\n *\n * @param queries - Array of CTE queries created with $with()\n * @returns Query builder with CTE support\n * @example\n * ```typescript\n * const withQuery = forgeSQL.$with('userStats').as(\n * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })\n * .from(users)\n * .groupBy(users.id)\n * );\n *\n * const result = await forgeSQL.with(withQuery)\n * .select({ userId: withQuery.userId, count: withQuery.count })\n * .from(withQuery);\n * ```\n */\n with(...queries: WithSubquery[]): {\n select: {\n (): MySqlSelectBuilder<undefined, MySqlRemotePreparedQueryHKT>;\n <TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n };\n selectDistinct: {\n (): MySqlSelectBuilder<undefined, MySqlRemotePreparedQueryHKT>;\n <TSelection extends SelectedFields>(\n fields: TSelection,\n ): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;\n };\n };\n}\n\n/**\n * Interface for Modify (Create, Update, Delete) operations.\n * Provides methods for basic database operations with support for optimistic locking.\n *\n * @interface VerioningModificationForgeSQL\n */\nexport interface VerioningModificationForgeSQL {\n /**\n * Inserts multiple records into the database.\n * @template T - The type of the table schema\n * @param {T} schema - The entity schema\n * @param {InferInsertModel<T>[]} models - The list of entities to insert\n * @param {boolean} [updateIfExists] - Whether to update the row if it already exists (default: false)\n * @returns {Promise<number>} The number of inserted rows\n * @throws {Error} If the insert operation fails\n */\n insert<T extends AnyMySqlTable>(\n schema: T,\n models: InferInsertModel<T>[],\n updateIfExists?: boolean,\n ): Promise<number>;\n\n /**\n * Deletes a record by its ID.\n * @template T - The type of the table schema\n * @param {unknown} id - The ID of the record to delete\n * @param {T} schema - The entity schema\n * @returns {Promise<number>} The number of rows affected\n * @throws {Error} If the delete operation fails\n */\n deleteById<T extends AnyMySqlTable>(id: unknown, schema: T): Promise<number>;\n\n /**\n * Updates a record by its ID with optimistic locking support.\n * If a version field is defined in the schema, versioning is applied:\n * - the current record version is retrieved\n * - checked for concurrent modifications\n * - and then incremented\n *\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} entity - The entity with updated values\n * @param {T} schema - The entity schema\n * @returns {Promise<number>} The number of rows affected\n * @throws {Error} If the primary key is not included in the update fields\n * @throws {Error} If optimistic locking check fails\n */\n updateById<T extends AnyMySqlTable>(\n entity: Partial<InferInsertModel<T>>,\n schema: T,\n ): Promise<number>;\n\n /**\n * Updates specified fields of records based on provided conditions.\n * If the \"where\" parameter is not provided, the WHERE clause is built from the entity fields\n * that are not included in the list of fields to update.\n *\n * @template T - The type of the table schema\n * @param {Partial<InferInsertModel<T>>} updateData - The object containing values to update\n * @param {T} schema - The entity schema\n * @param {SQL<unknown>} [where] - Optional filtering conditions for the WHERE clause\n * @returns {Promise<number>} The number of affected rows\n * @throws {Error} If no filtering criteria are provided\n * @throws {Error} If the update operation fails\n */\n updateFields<T extends AnyMySqlTable>(\n updateData: Partial<InferInsertModel<T>>,\n schema: T,\n where?: SQL<unknown>,\n ): Promise<number>;\n}\n\nexport interface CacheForgeSQL extends VerioningModificationForgeSQL {\n evictCache(tables: string[]): Promise<void>;\n evictCacheEntities(tables: AnyMySqlTable[]): Promise<void>;\n}\n\n/**\n * Interface for schema analysis operations.\n * Provides methods for analyzing query performance and execution plans.\n *\n * @interface SchemaAnalyzeForgeSql\n */\nexport interface SchemaAnalyzeForgeSql {\n /**\n * Executes EXPLAIN on a Drizzle query.\n * @param {{ toSQL: () => Query }} query - The Drizzle query to analyze\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n explain(query: { toSQL: () => Query }): Promise<ExplainAnalyzeRow[]>;\n\n /**\n * Executes EXPLAIN on a raw SQL query.\n * @param {string} query - The SQL query to analyze\n * @param {unknown[]} bindParams - The query parameters\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n explainRaw(query: string, bindParams: unknown[]): Promise<ExplainAnalyzeRow[]>;\n\n /**\n * Executes EXPLAIN ANALYZE on a Drizzle query.\n * @param {{ toSQL: () => Query }} query - The Drizzle query to analyze\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n explainAnalyze(query: { toSQL: () => Query }): Promise<ExplainAnalyzeRow[]>;\n\n /**\n * Executes EXPLAIN ANALYZE on a raw SQL query.\n * @param {string} query - The SQL query to analyze\n * @param {unknown[]} bindParams - The query parameters\n * @returns {Promise<ExplainAnalyzeRow[]>} The execution plan analysis results\n */\n explainAnalyzeRaw(query: string, bindParams: unknown[]): Promise<ExplainAnalyzeRow[]>;\n\n /**\n * Analyzes slow queries from the database.\n * @returns {Promise<SlowQueryNormalized[]>} The normalized slow query data\n */\n analyzeSlowQueries(): Promise<SlowQueryNormalized[]>;\n\n /**\n * Analyzes query history for specific tables using Drizzle table objects.\n * @param {AnyMySqlTable[]} tables - The Drizzle table objects to analyze\n * @param {Date} [fromDate] - The start date for the analysis\n * @param {Date} [toDate] - The end date for the analysis\n * @returns {Promise<ClusterStatementRowCamelCase[]>} The analyzed query history\n */\n analyzeQueriesHistory(\n tables: AnyMySqlTable[],\n fromDate?: Date,\n toDate?: Date,\n ): Promise<ClusterStatementRowCamelCase[]>;\n\n /**\n * Analyzes query history for specific tables using raw table names.\n * @param {string[]} tables - The table names to analyze\n * @param {Date} [fromDate] - The start date for the analysis\n * @param {Date} [toDate] - The end date for the analysis\n * @returns {Promise<ClusterStatementRowCamelCase[]>} The analyzed query history\n */\n analyzeQueriesHistoryRaw(\n tables: string[],\n fromDate?: Date,\n toDate?: Date,\n ): Promise<ClusterStatementRowCamelCase[]>;\n}\n\n/**\n * Interface for schema-level SQL operations.\n * Provides methods for executing SQL queries with schema binding and type safety.\n *\n * @interface SchemaSqlForgeSql\n */\nexport interface SchemaSqlForgeSql {\n /**\n * Executes a Drizzle query and returns a single result.\n * @template T - The type of the query builder\n * @param {T} query - The Drizzle query to execute\n * @returns {Promise<Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined>} A single result object or undefined\n * @throws {Error} If more than one record is returned\n * @throws {Error} If the query execution fails\n */\n executeQueryOnlyOne<T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>>(\n query: T,\n ): Promise<\n Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined\n >;\n\n /**\n * Executes a raw SQL query and returns the results.\n * @template T - The type of the result objects\n * @param {string} query - The raw SQL query\n * @param {SqlParameters[]} [params] - Optional SQL parameters\n * @returns {Promise<T[]>} A list of results as objects\n * @throws {Error} If the query execution fails\n */\n executeRawSQL<T extends object | unknown>(query: string, params?: SqlParameters[]): Promise<T[]>;\n\n /**\n * Executes a raw SQL update query.\n *\n * @param query - The raw SQL update query\n * @param params - Optional SQL parameters\n * @returns Promise that resolves to the update response containing affected rows\n * @throws Error if the update operation fails\n */\n executeRawUpdateSQL(query: string, params?: unknown[]): Promise<UpdateQueryResponse>;\n}\n\n/**\n * Interface for version field metadata.\n * Defines the configuration for optimistic locking version fields.\n *\n * @interface VersionFieldMetadata\n */\nexport interface VersionFieldMetadata {\n /** Name of the version field */\n fieldName: string;\n}\n\n/**\n * Interface for table metadata.\n * Defines the configuration for a specific table.\n *\n * @interface TableMetadata\n */\nexport interface TableMetadata {\n /** Name of the table */\n tableName: string;\n /** Version field configuration for optimistic locking */\n versionField: VersionFieldMetadata;\n}\n\n/**\n * Type for additional metadata configuration.\n * Maps table names to their metadata configuration.\n *\n * @type {AdditionalMetadata}\n */\nexport type AdditionalMetadata = Record<string, TableMetadata>;\n\n/**\n * Interface for ForgeSQL ORM options\n *\n * @interface ForgeSqlOrmOptions\n */\nexport interface ForgeSqlOrmOptions {\n /** Whether to log raw SQL queries to the console */\n logRawSqlQuery?: boolean;\n /** Whether to log cache operations (hits, misses, evictions) */\n logCache?: boolean;\n /** Whether to disable optimistic locking for update operations */\n disableOptimisticLocking?: boolean;\n /** SQL hints to be applied to queries for optimization */\n hints?: SqlHints;\n /** Default Cache TTL (Time To Live) in seconds */\n cacheTTL?: number;\n /** Name of the KVS entity used for cache storage */\n cacheEntityName?: string;\n /** Name of the field in cache entity that stores SQL query */\n cacheEntityQueryName?: string;\n /** Whether to wrap table names with backticks in cache keys */\n cacheWrapTable?: boolean;\n /** Name of the field in cache entity that stores expiration timestamp */\n cacheEntityExpirationName?: string;\n /** Name of the field in cache entity that stores cached data */\n cacheEntityDataName?: string;\n\n /**\n * Additional metadata for table configuration.\n * Allows specifying table-specific settings and behaviors such as version fields for optimistic locking.\n *\n * @example\n * ```typescript\n * {\n * users: {\n * tableName: \"users\",\n * versionField: {\n * fieldName: \"updatedAt\",\n * type: \"datetime\",\n * nullable: false\n * }\n * }\n * }\n * ```\n */\n additionalMetadata?: AdditionalMetadata;\n}\n\n/**\n * Custom type for MySQL datetime fields.\n * Handles conversion between JavaScript Date objects and MySQL datetime strings.\n *\n * @type {CustomType}\n */\nexport const forgeDateTimeString = customType<{\n data: Date;\n driver: string;\n config: { format?: string };\n}>({\n dataType() {\n return \"datetime\";\n },\n toDriver(value: Date) {\n return formatDateTime(value, \"yyyy-MM-dd' 'HH:mm:ss.SSS\", false);\n },\n fromDriver(value: unknown) {\n const format = \"yyyy-MM-dd' 'HH:mm:ss.SSS\";\n return parseDateTime(value as string, format);\n },\n});\n\n/**\n * Custom type for MySQL timestamp fields.\n * Handles conversion between JavaScript Date objects and MySQL timestamp strings.\n *\n * @type {CustomType}\n */\nexport const forgeTimestampString = customType<{\n data: Date;\n driver: string;\n config: { format?: string };\n}>({\n dataType() {\n return \"timestamp\";\n },\n toDriver(value: Date) {\n return formatDateTime(value, \"yyyy-MM-dd' 'HH:mm:ss.SSS\", true);\n },\n fromDriver(value: unknown) {\n const format = \"yyyy-MM-dd' 'HH:mm:ss.SSS\";\n return parseDateTime(value as string, format);\n },\n});\n\n/**\n * Custom type for MySQL date fields.\n * Handles conversion between JavaScript Date objects and MySQL date strings.\n *\n * @type {CustomType}\n */\nexport const forgeDateString = customType<{\n data: Date;\n driver: string;\n config: { format?: string };\n}>({\n dataType() {\n return \"date\";\n },\n toDriver(value: Date) {\n return formatDateTime(value, \"yyyy-MM-dd\", false);\n },\n fromDriver(value: unknown) {\n const format = \"yyyy-MM-dd\";\n return parseDateTime(value as string, format);\n },\n});\n\n/**\n * Custom type for MySQL time fields.\n * Handles conversion between JavaScript Date objects and MySQL time strings.\n *\n * @type {CustomType}\n */\nexport const forgeTimeString = customType<{\n data: Date;\n driver: string;\n config: { format?: string };\n}>({\n dataType() {\n return \"time\";\n },\n toDriver(value: Date) {\n return formatDateTime(value, \"HH:mm:ss.SSS\", false);\n },\n fromDriver(value: unknown) {\n return parseDateTime(value as string, \"HH:mm:ss.SSS\");\n },\n});\n","import { sql } from \"@forge/sql\";\nimport { generateDropTableStatements as generateStatements } from \"../utils/sqlUtils\";\nimport { getHttpResponse, TriggerResponse } from \"./index\";\nimport { getTables } from \"../core/SystemTables\";\n\n/**\n * ⚠️ DEVELOPMENT ONLY WEB TRIGGER ⚠️\n *\n * This web trigger is designed for development environments only and will permanently delete all data in the specified tables and sequences.\n * It generates and executes SQL statements to drop tables, their associated constraints, and sequences.\n *\n * @warning This trigger should NEVER be used in production environments because:\n * - It permanently deletes all data in the specified tables and sequences\n * - The operation cannot be undone\n * - It may affect application functionality\n * - It could lead to data loss and system instability\n *\n * @returns {Promise<TriggerResponse<string>>} A response containing:\n * - On success: 200 status with warning message about permanent deletion of tables and sequences\n * - On failure: 500 status with error message\n *\n * @example\n * ```typescript\n * // Example usage in development only\n * await dropSchemaMigrations();\n * // ⚠️ Warning: This will permanently delete all data in users and orders tables and their sequences\n * ```\n */\nexport async function dropSchemaMigrations(): Promise<TriggerResponse<string>> {\n try {\n const tables = await getTables();\n // Generate drop statements\n const dropStatements = generateStatements(tables, { sequence: true, table: true });\n\n // Execute each statement\n for (const statement of dropStatements) {\n // eslint-disable-next-line no-console\n console.debug(`execute DDL: ${statement}`);\n await sql.executeDDL(statement);\n }\n\n return getHttpResponse<string>(\n 200,\n \"⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.\",\n );\n } catch (error: any) {\n const errorMessage =\n error?.debug?.sqlMessage ??\n error?.debug?.message ??\n error.message ??\n \"Unknown error occurred\";\n // eslint-disable-next-line no-console\n console.error(errorMessage);\n return getHttpResponse<string>(500, errorMessage);\n }\n}\n","import { migrationRunner, sql } from \"@forge/sql\";\nimport { MigrationRunner } from \"@forge/sql/out/migration\";\n\n/**\n * Web trigger for applying database schema migrations in Atlassian Forge SQL.\n * This function handles the complete migration process including:\n * - Database provisioning\n * - Migration execution\n * - Migration history tracking\n *\n * @param migration - A function that takes a MigrationRunner instance and returns a Promise of MigrationRunner\n * This function should define the sequence of migrations to be applied\n * @returns {Promise<{\n * headers: { \"Content-Type\": [\"application/json\"] },\n * statusCode: number,\n * statusText: string,\n * body: string\n * }>} A response object containing:\n * - headers: Content-Type header set to application/json\n * - statusCode: 200 on success\n * - statusText: \"OK\" on success\n * - body: Success message or error details\n *\n * @throws {Error} If database provisioning fails\n * @throws {Error} If migration execution fails\n */\nexport const applySchemaMigrations = async (\n migration: (migrationRunner: MigrationRunner) => Promise<MigrationRunner>,\n) => {\n try {\n if (typeof migration !== \"function\") {\n throw new Error(\"migration is not a function\");\n }\n // eslint-disable-next-line no-console\n console.debug(\"Provisioning the database\");\n await sql._provision();\n // eslint-disable-next-line no-console\n console.debug(\"Running schema migrations\");\n const migrations = await migration(migrationRunner);\n const successfulMigrations = await migrations.run();\n // eslint-disable-next-line no-console\n console.debug(\"Migrations applied:\", successfulMigrations);\n\n const migrationList = await migrationRunner.list();\n let migrationHistory = \"No migrations found\";\n\n if (Array.isArray(migrationList) && migrationList.length > 0) {\n const sortedMigrations = migrationList.toSorted(\n (a, b) => a.migratedAt.getTime() - b.migratedAt.getTime(),\n );\n\n migrationHistory = sortedMigrations\n .map((y) => `${y.id}, ${y.name}, ${y.migratedAt.toUTCString()}`)\n .join(\"\\n\");\n }\n // eslint-disable-next-line no-console\n console.debug(\"Migrations history:\\nid, name, migrated_at\\n\", migrationHistory);\n\n return {\n headers: { \"Content-Type\": [\"application/json\"] },\n statusCode: 200,\n statusText: \"OK\",\n body: \"Migrations successfully executed\",\n };\n } catch (error: any) {\n const errorMessage =\n error?.cause?.context?.debug?.sqlMessage ??\n error?.cause?.context?.debug?.message ??\n error?.debug?.context?.sqlMessage ??\n error?.debug?.context?.message ??\n error.message ??\n \"Unknown error occurred\";\n // eslint-disable-next-line no-console\n console.error(\"Error during migration:\", errorMessage);\n return {\n headers: { \"Content-Type\": [\"application/json\"] },\n statusCode: 500,\n statusText: \"Internal Server Error\",\n body: error instanceof Error ? errorMessage : \"Unknown error during migration\",\n };\n }\n};\n","import { sql } from \"@forge/sql\";\nimport { getHttpResponse, TriggerResponse } from \"./index\";\nimport { forgeSystemTables, getTables } from \"../core/SystemTables\";\nimport { getTableName } from \"drizzle-orm/table\";\n\ninterface CreateTableRow {\n Table: string;\n \"Create Table\": string;\n}\n\n/**\n * ⚠️ DEVELOPMENT ONLY WEB TRIGGER ⚠️\n *\n * This web trigger retrieves the current database schema from Atlassian Forge SQL.\n * It generates SQL statements that can be used to recreate the database structure.\n *\n * @warning This trigger should ONLY be used in development environments. It:\n * - Exposes your database structure\n * - Disables foreign key checks temporarily\n * - Generates SQL that could potentially be used maliciously\n * - May expose sensitive table names and structures\n *\n * @returns {Promise<TriggerResponse<string>>} A response containing SQL statements to recreate the database schema\n * - On success: Returns 200 status with SQL statements\n * - On failure: Returns 500 status with error message\n *\n * @example\n * ```typescript\n * // The response will contain SQL statements like:\n * // SET foreign_key_checks = 0;\n * // CREATE TABLE IF NOT EXISTS users (...);\n * // CREATE TABLE IF NOT EXISTS orders (...);\n * // SET foreign_key_checks = 1;\n * ```\n */\nexport async function fetchSchemaWebTrigger(): Promise<TriggerResponse<string>> {\n try {\n const tables = await getTables();\n const createTableStatements = await generateCreateTableStatements(tables);\n const sqlStatements = wrapWithForeignKeyChecks(createTableStatements);\n\n return getHttpResponse<string>(200, sqlStatements.join(\";\\n\"));\n } catch (error: any) {\n const errorMessage =\n error?.debug?.sqlMessage ??\n error?.debug?.message ??\n error.message ??\n \"Unknown error occurred\";\n // eslint-disable-next-line no-console\n console.error(errorMessage);\n return getHttpResponse<string>(500, errorMessage);\n }\n}\n\n/**\n * Generates CREATE TABLE statements for each table\n */\nasync function generateCreateTableStatements(tables: string[]): Promise<string[]> {\n const statements: string[] = [];\n\n for (const table of tables) {\n const createTableResult = await sql.executeDDL<CreateTableRow>(`SHOW CREATE TABLE \"${table}\"`);\n\n const createTableStatements = createTableResult.rows\n .filter((row) => !isSystemTable(row.Table))\n .map((row) => formatCreateTableStatement(row[\"Create Table\"]));\n\n statements.push(...createTableStatements);\n }\n\n return statements;\n}\n\n/**\n * Checks if the table is a system table\n */\nfunction isSystemTable(tableName: string): boolean {\n return forgeSystemTables.some((st) => getTableName(st) === tableName);\n}\n\n/**\n * Formats the CREATE TABLE statement\n */\nfunction formatCreateTableStatement(statement: string): string {\n return statement.replace(/\"/g, \"\").replace(\"CREATE TABLE\", \"CREATE TABLE IF NOT EXISTS\");\n}\n\n/**\n * Wraps the SQL statements with foreign key check controls\n */\nfunction wrapWithForeignKeyChecks(statements: string[]): string[] {\n return [\"SET foreign_key_checks = 0\", ...statements, \"SET foreign_key_checks = 1\"];\n}\n","import { sql } from \"@forge/sql\";\nimport { generateDropTableStatements as generateStatements } from \"../utils/sqlUtils\";\nimport { getHttpResponse, TriggerResponse } from \"./index\";\nimport { getTables } from \"../core/SystemTables\";\n\n/**\n * ⚠️ DEVELOPMENT ONLY WEB TRIGGER ⚠️\n *\n * This web trigger is designed for development environments only and will permanently delete all data in the specified tables.\n * It generates and executes SQL statements to drop tables and their associated constraints.\n *\n * @warning This trigger should NEVER be used in production environments because:\n * - It permanently deletes all data in the specified tables\n * - The operation cannot be undone\n * - It may affect application functionality\n * - It could lead to data loss and system instability\n *\n * @returns {Promise<TriggerResponse<string>>} A response containing:\n * - On success: 200 status with warning message about permanent deletion\n * - On failure: 500 status with error message\n *\n * @example\n * ```typescript\n * // Example usage in development only\n * await dropTableSchemaMigrations();\n * // ⚠️ Warning: This will permanently delete all data in users and orders tables\n * ```\n */\nexport async function dropTableSchemaMigrations(): Promise<TriggerResponse<string>> {\n try {\n const tables = await getTables();\n // Generate drop statements\n const dropStatements = generateStatements(tables, { sequence: false, table: true });\n\n // Execute each statement\n for (const statement of dropStatements) {\n // eslint-disable-next-line no-console\n console.debug(`execute DDL: ${statement}`);\n await sql.executeDDL(statement);\n }\n\n return getHttpResponse<string>(\n 200,\n \"⚠️ All data in these tables has been permanently deleted. This operation cannot be undone.\",\n );\n } catch (error: any) {\n const errorMessage =\n error?.debug?.sqlMessage ??\n error?.debug?.message ??\n error.message ??\n \"Unknown error occurred\";\n // eslint-disable-next-line no-console\n console.error(errorMessage);\n return getHttpResponse<string>(500, errorMessage);\n }\n}\n","import { clearExpiredCache } from \"../utils/cacheUtils\";\nimport { ForgeSqlOrmOptions } from \"../core/ForgeSQLQueryBuilder\";\n\n/**\n * Scheduler trigger for clearing expired cache entries.\n *\n * This trigger should be configured as a Forge scheduler to automatically\n * clean up expired cache entries based on their TTL (Time To Live).\n *\n * @param options - Optional ForgeSQL ORM configuration. If not provided,\n * uses default cache settings with cacheEntityName: \"cache\"\n * @returns Promise that resolves to HTTP response object\n *\n * @example\n * ```typescript\n * // In your index.ts\n * import { clearCacheSchedulerTrigger } from \"forge-sql-orm\";\n *\n * export const clearCache = () => {\n * return clearCacheSchedulerTrigger({\n * cacheEntityName: \"cache\",\n * logRawSqlQuery: true\n * });\n * };\n * ```\n *\n * @example\n * ```yaml\n * # In manifest.yml\n * scheduledTrigger:\n * - key: clear-cache-trigger\n * function: clearCache\n * interval: fiveMinute\n *\n * function:\n * - key: clearCache\n * handler: index.clearCache\n * ```\n */\nexport const clearCacheSchedulerTrigger = async (options?: ForgeSqlOrmOptions) => {\n try {\n const newOptions: ForgeSqlOrmOptions = options ?? {\n logRawSqlQuery: false,\n disableOptimisticLocking: false,\n cacheTTL: 120,\n cacheEntityName: \"cache\",\n cacheEntityQueryName: \"sql\",\n cacheEntityExpirationName: \"expiration\",\n cacheEntityDataName: \"data\",\n };\n if (!newOptions.cacheEntityName) {\n throw new Error(\"cacheEntityName is not configured\");\n }\n await clearExpiredCache(newOptions);\n\n return {\n headers: { \"Content-Type\": [\"application/json\"] },\n statusCode: 200,\n statusText: \"OK\",\n body: JSON.stringify({\n success: true,\n message: \"Cache cleanup completed successfully\",\n timestamp: new Date().toISOString(),\n }),\n };\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\"Error during cache cleanup: \", JSON.stringify(error));\n return {\n headers: { \"Content-Type\": [\"application/json\"] },\n statusCode: 500,\n statusText: \"Internal Server Error\",\n body: JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error during cache cleanup\",\n timestamp: new Date().toISOString(),\n }),\n };\n }\n};\n","import { getHttpResponse, TriggerResponse } from \"./index\";\nimport { slowQueryPerHours } from \"../utils/sqlUtils\";\nimport { ForgeSqlOperation } from \"../core/ForgeSQLQueryBuilder\";\n\n/**\n * Scheduler trigger for analyzing slow queries from the last specified number of hours.\n *\n * This trigger analyzes slow queries from TiDB's slow query log system table and provides\n * detailed performance information including SQL query text, memory usage, execution time,\n * and execution plans. It's designed to be used as a scheduled trigger in Atlassian Forge\n * to monitor query performance over time.\n *\n * The function queries the slow query system table to find queries executed within the\n * specified time window and logs detailed performance information to the console. Results\n * are limited to the top 50 slow queries to prevent excessive output.\n *\n * @param forgeSQLORM - The ForgeSQL operation instance for database access\n * @param options - Configuration options for the slow query analysis\n * @param options.hours - Number of hours to look back for slow queries (default: 1)\n * @param options.timeout - Timeout in milliseconds for the query execution (default: 2000ms)\n *\n * @returns Promise<TriggerResponse<string>> - HTTP response with JSON stringified query results or error message\n *\n * @example\n * ```typescript\n * import ForgeSQL, { slowQuerySchedulerTrigger } from \"forge-sql-orm\";\n *\n * const forgeSQL = new ForgeSQL();\n *\n * // Basic usage with default options (1 hour, 2000ms timeout)\n * export const slowQueryTrigger = () =>\n * slowQuerySchedulerTrigger(forgeSQL, { hours: 1, timeout: 2000 });\n *\n * // Analyze slow queries from the last 6 hours with extended timeout\n * export const sixHourSlowQueryTrigger = () =>\n * slowQuerySchedulerTrigger(forgeSQL, { hours: 6, timeout: 5000 });\n *\n * // Analyze slow queries from the last 24 hours\n * export const dailySlowQueryTrigger = () =>\n * slowQuerySchedulerTrigger(forgeSQL, { hours: 24, timeout: 3000 });\n * ```\n *\n * @example\n * ```yaml\n * # manifest.yml configuration\n * scheduledTrigger:\n * - key: slow-query-trigger\n * function: slowQueryTrigger\n * interval: hour\n *\n * function:\n * - key: slowQueryTrigger\n * handler: index.slowQueryTrigger\n * ```\n *\n * @remarks\n * - Results are automatically logged to the Forge Developer Console via `console.warn()`\n * - The function returns up to 50 slow queries to prevent excessive logging\n * - Transient timeouts are usually fine; repeated timeouts indicate the diagnostic query itself is slow\n * - This trigger is best used with hourly intervals to catch slow queries in a timely manner\n * - Error responses return HTTP 500 with error details\n *\n * @see {@link slowQueryPerHours} - The underlying function that performs the actual query analysis\n */\nexport async function slowQuerySchedulerTrigger(\n forgeSQLORM: ForgeSqlOperation,\n options: {\n hours: number;\n timeout: number;\n },\n): Promise<TriggerResponse<string>> {\n try {\n return getHttpResponse<string>(\n 200,\n JSON.stringify(\n await slowQueryPerHours(forgeSQLORM, options?.hours ?? 1, options?.timeout ?? 3000),\n ),\n );\n } catch (error: any) {\n const errorMessage =\n error?.debug?.sqlMessage ??\n error?.debug?.message ??\n error.message ??\n \"Unknown error occurred\";\n // eslint-disable-next-line no-console\n console.error(errorMessage);\n return getHttpResponse<string>(500, errorMessage);\n }\n}\n","export * from \"./dropMigrationWebTrigger\";\nexport * from \"./applyMigrationsWebTrigger\";\nexport * from \"./fetchSchemaWebTrigger\";\nexport * from \"./dropTablesMigrationWebTrigger\";\nexport * from \"./clearCacheSchedulerTrigger\";\nexport * from \"./slowQuerySchedulerTrigger\";\n\nexport interface TriggerResponse<BODY> {\n body?: BODY;\n headers?: Record<string, string[]>;\n statusCode: number;\n statusText?: string;\n}\n\nexport const getHttpResponse = <Body>(statusCode: number, body: Body): TriggerResponse<Body> => {\n let statusText = \"\";\n if (statusCode === 200) {\n statusText = \"Ok\";\n } else {\n statusText = \"Bad Request\";\n }\n\n return {\n headers: { \"Content-Type\": [\"application/json\"] },\n statusCode,\n statusText,\n body,\n };\n};\n"],"names":["mysqlTable","bigint","varchar","timestamp","mysqlSchema","double","boolean","longtext","text","int","sql","DateTime","table","isTable","isSQLWrapper","fields","timeoutMs","and","isNotNull","not","ilike","notInArray","gte","ne","crypto","kvs","Filter","FilterConditions","WhereConditions","getTableName","AsyncLocalStorage","eq","getTableColumns","formatDateTime","drizzle","customType","generateStatements","migrations","migrationRunner"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeO,MAAM,aAAaA,UAAAA,WAAW,gBAAgB;AAAA,EACnD,IAAIC,UAAAA,OAAO,MAAM,EAAE,MAAM,UAAU,EAAE,WAAA,EAAa,cAAA;AAAA,EAClD,MAAMC,UAAAA,QAAQ,QAAQ,EAAE,QAAQ,IAAA,CAAK,EAAE,QAAA;AAAA,EACvC,YAAYC,UAAAA,UAAU,YAAY,EAAE,WAAA,EAAa,QAAA;AACnD,CAAC;AAED,MAAM,oBAAoBC,UAAAA,YAAY,oBAAoB;AAEnD,MAAM,YAAY,kBAAkB,MAAM,sBAAsB;AAAA,EACrE,MAAMD,UAAAA,UAAU,QAAQ,EAAE,KAAK,GAAG,MAAM,UAAU,EAAE,QAAA;AAAA;AAAA,EAEpD,YAAYF,UAAAA,OAAO,gBAAgB,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EACrE,MAAMC,UAAAA,QAAQ,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EACpC,MAAMA,UAAAA,QAAQ,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EACpC,QAAQD,UAAAA,OAAO,WAAW,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAC5D,cAAcC,UAAAA,QAAQ,iBAAiB,EAAE,QAAQ,IAAI;AAAA;AAAA,EAErD,gBAAgBD,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAC7E,eAAeI,UAAAA,OAAO,iBAAiB;AAAA;AAAA,EACvC,WAAWA,UAAAA,OAAO,YAAY;AAAA;AAAA,EAC9B,WAAWA,UAAAA,OAAO,YAAY;AAAA;AAAA,EAC9B,aAAaA,UAAAA,OAAO,cAAc;AAAA;AAAA,EAClC,aAAaA,UAAAA,OAAO,cAAc;AAAA;AAAA,EAClC,mBAAmBJ,UAAAA,OAAO,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAClF,uBAAuBI,UAAAA,OAAO,yBAAyB;AAAA;AAAA,EACvD,cAAcA,UAAAA,OAAO,eAAe;AAAA;AAAA,EACpC,QAAQA,UAAAA,OAAO,SAAS;AAAA;AAAA,EACxB,cAAcA,UAAAA,OAAO,eAAe;AAAA;AAAA,EACpC,wBAAwBA,UAAAA,OAAO,2BAA2B;AAAA;AAAA,EAC1D,YAAYA,UAAAA,OAAO,aAAa;AAAA;AAAA,EAChC,iBAAiBA,UAAAA,OAAO,oBAAoB;AAAA;AAAA,EAC5C,mBAAmBA,UAAAA,OAAO,qBAAqB;AAAA;AAAA,EAC/C,cAAcH,UAAAA,QAAQ,iBAAiB,EAAE,QAAQ,IAAI;AAAA;AAAA,EACrD,iBAAiBG,UAAAA,OAAO,mBAAmB;AAAA;AAAA,EAC3C,oBAAoBA,UAAAA,OAAO,uBAAuB;AAAA;AAAA,EAElD,WAAWJ,UAAAA,OAAO,cAAc,EAAE,MAAM,UAAU;AAAA;AAAA,EAClD,WAAWA,UAAAA,OAAO,cAAc,EAAE,MAAM,UAAU;AAAA;AAAA,EAClD,gBAAgBA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,UAAU;AAAA;AAAA,EAC5D,UAAUA,UAAAA,OAAO,aAAa,EAAE,MAAM,UAAU;AAAA;AAAA,EAEhD,SAASI,UAAAA,OAAO,UAAU;AAAA;AAAA,EAC1B,aAAaA,UAAAA,OAAO,cAAc;AAAA;AAAA,EAClC,UAAUA,UAAAA,OAAO,WAAW;AAAA;AAAA,EAC5B,aAAaA,UAAAA,OAAO,cAAc;AAAA;AAAA,EAClC,cAAcA,UAAAA,OAAO,eAAe;AAAA;AAAA,EAEpC,cAAcJ,UAAAA,OAAO,iBAAiB,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EACxE,WAAWA,UAAAA,OAAO,cAAc,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAClE,aAAaA,UAAAA,OAAO,gBAAgB,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAEtE,2BAA2BA,UAAAA,OAAO,gCAAgC;AAAA,IAChE,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX;AAAA;AAAA,EACD,wBAAwBA,UAAAA,OAAO,6BAA6B,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAC9F,2BAA2BA,UAAAA,OAAO,iCAAiC;AAAA,IACjE,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX;AAAA;AAAA,EACD,uBAAuBA,UAAAA,OAAO,4BAA4B,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAC5F,sBAAsBA,UAAAA,OAAO,2BAA2B,EAAE,MAAM,UAAU,UAAU,MAAM;AAAA;AAAA,EAE1F,IAAIC,UAAAA,QAAQ,MAAM,EAAE,QAAQ,IAAI;AAAA;AAAA,EAChC,YAAYA,UAAAA,QAAQ,eAAe,EAAE,QAAQ,KAAK;AAAA;AAAA,EAElD,YAAYI,UAAAA,QAAQ,aAAa;AAAA;AAAA,EACjC,QAAQJ,UAAAA,QAAQ,UAAU,EAAE,QAAQ,IAAI;AAAA;AAAA,EACxC,OAAOA,UAAAA,QAAQ,SAAS,EAAE,QAAQ,KAAK;AAAA;AAAA,EAEvC,YAAYG,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,YAAYA,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,YAAYA,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,aAAaH,UAAAA,QAAQ,iBAAiB,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEpD,YAAYG,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,YAAYA,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,YAAYA,UAAAA,OAAO,cAAc;AAAA;AAAA,EACjC,aAAaH,UAAAA,QAAQ,iBAAiB,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEpD,QAAQD,UAAAA,OAAO,WAAW,EAAE,MAAM,UAAU;AAAA;AAAA,EAC5C,SAASA,UAAAA,OAAO,YAAY,EAAE,MAAM,UAAU;AAAA;AAAA,EAE9C,SAASI,UAAAA,OAAO,UAAU;AAAA;AAAA,EAC1B,SAASA,UAAAA,OAAO,UAAU;AAAA;AAAA,EAC1B,cAAcA,UAAAA,OAAO,eAAe;AAAA;AAAA,EACpC,uBAAuBA,UAAAA,OAAO,0BAA0B;AAAA;AAAA,EAExD,YAAYJ,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU;AAAA;AAAA,EACpD,UAAUM,UAAAA,SAAS,UAAU;AAAA;AAAA,EAC7B,eAAeL,UAAAA,QAAQ,kBAAkB,EAAE,QAAQ,MAAM;AAAA;AAAA,EAEzD,UAAUI,UAAAA,QAAQ,UAAU;AAAA;AAAA,EAC5B,MAAMA,UAAAA,QAAQ,MAAM;AAAA;AAAA,EACpB,eAAeA,UAAAA,QAAQ,eAAe;AAAA;AAAA,EACtC,mBAAmBA,UAAAA,QAAQ,mBAAmB;AAAA;AAAA,EAC9C,eAAeA,UAAAA,QAAQ,iBAAiB;AAAA;AAAA,EACxC,iBAAiBA,UAAAA,QAAQ,mBAAmB;AAAA;AAAA,EAC5C,gBAAgBA,UAAAA,QAAQ,kBAAkB;AAAA;AAAA,EAE1C,eAAeJ,UAAAA,QAAQ,kBAAkB,EAAE,QAAQ,IAAI;AAAA;AAAA,EACvD,iBAAiBG,UAAAA,OAAO,mBAAmB;AAAA;AAAA,EAC3C,kBAAkBA,UAAAA,OAAO,oBAAoB;AAAA;AAAA,EAC7C,gBAAgBA,UAAAA,OAAO,mBAAmB;AAAA;AAAA,EAE1C,aAAaA,UAAAA,OAAO,eAAe;AAAA;AAAA,EACnC,aAAaA,UAAAA,OAAO,eAAe;AAAA;AAAA,EAEnC,MAAME,UAAAA,SAAS,MAAM;AAAA;AAAA,EACrB,YAAYL,UAAAA,QAAQ,eAAe,EAAE,QAAQ,KAAK;AAAA;AAAA,EAClD,YAAYK,UAAAA,SAAS,aAAa;AAAA;AAAA,EAClC,UAAUA,UAAAA,SAAS,WAAW;AAAA;AAAA,EAC9B,OAAOA,UAAAA,SAAS,OAAO;AAAA;AACzB,CAAC;AAKD,MAAM,uCAAuC,OAAO;AAAA,EAClD,UAAUL,UAAAA,QAAQ,YAAY,EAAE,QAAQ,IAAI;AAAA;AAAA,EAE5C,kBAAkBC,UAAAA,UAAU,sBAAsB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EACtE,gBAAgBA,UAAAA,UAAU,oBAAoB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAElE,UAAUD,UAAAA,QAAQ,aAAa,EAAE,QAAQ,GAAA,CAAI,EAAE,QAAA;AAAA;AAAA,EAC/C,YAAYA,UAAAA,QAAQ,eAAe,EAAE,QAAQ,IAAI;AAAA;AAAA,EACjD,QAAQA,UAAAA,QAAQ,UAAU,EAAE,QAAQ,IAAI;AAAA;AAAA,EACxC,YAAYM,UAAAA,KAAK,aAAa,EAAE,QAAA;AAAA;AAAA,EAEhC,YAAYA,UAAAA,KAAK,aAAa;AAAA;AAAA,EAC9B,YAAYA,UAAAA,KAAK,aAAa;AAAA;AAAA,EAE9B,YAAYN,UAAAA,QAAQ,eAAe,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEjD,WAAWD,UAAAA,OAAO,cAAc,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACpE,WAAWQ,UAAAA,IAAI,cAAc,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EACjD,aAAaA,UAAAA,IAAI,gBAAgB,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EAErD,YAAYR,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACtE,YAAYA,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACtE,YAAYA,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACtE,YAAYA,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAEtE,iBAAiBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACjF,iBAAiBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACjF,mBAAmBA,UAAAA,OAAO,uBAAuB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACrF,mBAAmBA,UAAAA,OAAO,uBAAuB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAErF,eAAeA,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC9E,mBAAmBA,UAAAA,OAAO,wBAAwB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACtF,sBAAsBC,UAAAA,QAAQ,2BAA2B,EAAE,QAAQ,KAAK;AAAA;AAAA,EACxE,gBAAgBD,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAChF,mBAAmBC,UAAAA,QAAQ,wBAAwB,EAAE,QAAQ,KAAK;AAAA;AAAA,EAElE,gBAAgBD,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC/E,gBAAgBA,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC/E,aAAaA,UAAAA,OAAO,iBAAiB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACzE,aAAaA,UAAAA,OAAO,iBAAiB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAEzE,gBAAgBA,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC/E,gBAAgBA,UAAAA,OAAO,oBAAoB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAE/E,cAAcA,UAAAA,OAAO,kBAAkB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC3E,cAAcA,UAAAA,OAAO,kBAAkB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC3E,kBAAkBA,UAAAA,OAAO,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACnF,kBAAkBA,UAAAA,OAAO,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAEnF,8BAA8BI,UAAAA,OAAO,kCAAkC,EAAE,QAAA;AAAA;AAAA,EACzE,8BAA8BI,UAAAA,IAAI,oCAAoC;AAAA,IACpE,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,2BAA2BJ,UAAAA,OAAO,+BAA+B,EAAE,QAAA;AAAA;AAAA,EACnE,2BAA2BI,UAAAA,IAAI,iCAAiC,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EACpF,8BAA8BJ,UAAAA,OAAO,mCAAmC,EAAE,QAAA;AAAA;AAAA,EAC1E,8BAA8BI,UAAAA,IAAI,qCAAqC;AAAA,IACrE,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,0BAA0BJ,UAAAA,OAAO,8BAA8B,EAAE,QAAA;AAAA;AAAA,EACjE,0BAA0BI,UAAAA,IAAI,gCAAgC,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EAClF,yBAAyBJ,UAAAA,OAAO,6BAA6B,EAAE,QAAA;AAAA;AAAA,EAC/D,yBAAyBI,UAAAA,IAAI,+BAA+B,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EAEhF,iBAAiBR,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACjF,iBAAiBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACjF,eAAeA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC7E,eAAeA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC7E,oBAAoBA,UAAAA,OAAO,0BAA0B;AAAA,IACnD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,oBAAoBA,UAAAA,OAAO,0BAA0B;AAAA,IACnD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,sBAAsBA,UAAAA,OAAO,2BAA2B;AAAA,IACtD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,sBAAsBA,UAAAA,OAAO,2BAA2B;AAAA,IACtD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,oBAAoBA,UAAAA,OAAO,yBAAyB;AAAA,IAClD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,oBAAoBA,UAAAA,OAAO,yBAAyB;AAAA,IAClD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,uBAAuBA,UAAAA,OAAO,6BAA6B;AAAA,IACzD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,uBAAuBA,UAAAA,OAAO,6BAA6B;AAAA,IACzD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EAEH,cAAcI,UAAAA,OAAO,gBAAgB,EAAE,QAAA;AAAA;AAAA,EACvC,cAAcJ,UAAAA,OAAO,kBAAkB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC3E,cAAcI,UAAAA,OAAO,gBAAgB,EAAE,QAAA;AAAA;AAAA,EACvC,cAAcJ,UAAAA,OAAO,kBAAkB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC3E,oBAAoBI,UAAAA,OAAO,sBAAsB,EAAE,QAAA;AAAA;AAAA,EACnD,oBAAoBI,UAAAA,IAAI,wBAAwB,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EACpE,aAAaJ,UAAAA,OAAO,eAAe,EAAE,QAAA;AAAA;AAAA,EACrC,aAAaI,UAAAA,IAAI,iBAAiB,EAAE,UAAU,KAAA,CAAM,EAAE,QAAA;AAAA;AAAA,EAEtD,cAAcR,UAAAA,OAAO,kBAAkB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC3E,kBAAkBA,UAAAA,OAAO,uBAAuB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACpF,iBAAiBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACjF,cAAcC,UAAAA,QAAQ,iBAAiB,EAAE,QAAQ,MAAM;AAAA;AAAA,EAEvD,QAAQD,UAAAA,OAAO,WAAW,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC9D,QAAQA,UAAAA,OAAO,WAAW,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAC9D,SAASA,UAAAA,OAAO,YAAY,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAChE,SAASA,UAAAA,OAAO,YAAY,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAEhE,WAAWA,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACrE,WAAWA,UAAAA,OAAO,eAAe,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EACrE,qBAAqBA,UAAAA,OAAO,0BAA0B;AAAA,IACpD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EACH,qBAAqBA,UAAAA,OAAO,2BAA2B;AAAA,IACrD,MAAM;AAAA,IACN,UAAU;AAAA,EAAA,CACX,EAAE,QAAA;AAAA;AAAA,EAEH,gBAAgBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAChF,gBAAgBA,UAAAA,OAAO,qBAAqB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAEhF,eAAeA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAC7D,eAAeA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAC7D,eAAeA,UAAAA,OAAO,mBAAmB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAE7D,UAAUK,UAAAA,QAAQ,UAAU,EAAE,QAAA;AAAA;AAAA,EAC9B,iBAAiBD,UAAAA,OAAO,mBAAmB,EAAE,QAAA;AAAA;AAAA,EAE7C,WAAWF,UAAAA,UAAU,cAAc,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EACvD,UAAUA,UAAAA,UAAU,aAAa,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAErD,aAAaG,UAAAA,QAAQ,eAAe,EAAE,QAAA;AAAA;AAAA,EACtC,eAAeL,UAAAA,OAAO,mBAAmB,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAC7D,eAAeK,UAAAA,QAAQ,iBAAiB,EAAE,QAAA;AAAA;AAAA,EAE1C,iBAAiBE,UAAAA,KAAK,mBAAmB;AAAA;AAAA,EACzC,gBAAgBA,UAAAA,KAAK,kBAAkB;AAAA;AAAA,EAEvC,YAAYN,UAAAA,QAAQ,eAAe,EAAE,QAAQ,IAAI;AAAA;AAAA,EACjD,MAAMM,UAAAA,KAAK,MAAM;AAAA;AAAA,EACjB,YAAYA,UAAAA,KAAK,aAAa;AAAA;AAAA,EAE9B,SAASN,UAAAA,QAAQ,WAAW,EAAE,QAAQ,IAAI;AAAA;AAAA,EAC1C,WAAWA,UAAAA,QAAQ,aAAa,EAAE,QAAQ,IAAI;AAAA;AAAA,EAC9C,UAAUA,UAAAA,QAAQ,aAAa,EAAE,QAAQ,IAAI;AAAA;AAAA,EAE7C,oBAAoBG,UAAAA,OAAO,uBAAuB,EAAE,QAAA;AAAA;AAAA,EACpD,oBAAoBA,UAAAA,OAAO,uBAAuB,EAAE,QAAA;AAAA;AAAA,EACpD,qBAAqBA,UAAAA,OAAO,wBAAwB,EAAE,QAAA;AAAA;AAAA,EACtD,qBAAqBA,UAAAA,OAAO,wBAAwB,EAAE,QAAA;AAAA;AAAA,EAEtD,iBAAiBJ,UAAAA,OAAO,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAClF,iBAAiBA,UAAAA,OAAO,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM,EAAE,QAAA;AAAA;AAAA,EAElF,eAAeC,UAAAA,QAAQ,kBAAkB,EAAE,QAAQ,IAAI;AAAA;AAAA,EAEvD,sBAAsBD,UAAAA,OAAO,0BAA0B,EAAE,MAAM,SAAA,CAAU,EAAE,QAAA;AAAA;AAAA,EAC3E,gCAAgCO,UAAAA,KAAK,oCAAoC;AAAA;AAC3E;AAEO,MAAM,kCAAkC,kBAAkB;AAAA,EAC/D;AAAA,EACA,qCAAA;AACF;AAKO,MAAM,2BAA2B,kBAAkB;AAAA,EACxD;AAAA,EACA,qCAAA;AACF;AAKO,MAAM,oBAAoB,kBAAkB;AAAA,EACjD;AAAA,EACA,qCAAA;AACF;AAKO,MAAM,2BAA2B,kBAAkB;AAAA,EACxD;AAAA,EACA,qCAAA;AACF;AA8KA,eAAsB,YAA+B;AACnD,QAAM,SAAS,MAAME,QAAI,WAAmB,aAAa;AACzD,SAAO,OAAO,KAAK,QAAQ,CAAC,cAAc,OAAO,OAAO,SAAS,CAAC;AACpE;AAEO,MAAM,oBAA6B,CAAC,UAAU;AC5b9C,MAAM,gBAAgB,CAAC,OAAsB,WAAyB;AAC3E,MAAI;AACJ,MAAI,iBAAiB,MAAM;AACzB,aAAS;AAAA,EACX,OAAO;AAEL,UAAM,KAAKC,MAAAA,SAAS,WAAW,OAAO,MAAM;AAC5C,QAAI,GAAG,SAAS;AACd,eAAS,GAAG,SAAA;AAAA,IACd,OAAO;AAEL,YAAM,QAAQA,MAAAA,SAAS,QAAQ,KAAK;AACpC,UAAI,MAAM,SAAS;AACjB,iBAAS,MAAM,SAAA;AAAA,MACjB,OAAO;AAEL,cAAM,QAAQA,MAAAA,SAAS,YAAY,KAAK;AACxC,YAAI,MAAM,SAAS;AACjB,mBAAS,MAAM,SAAA;AAAA,QACjB,OAAO;AAEL,mBAAS,IAAI,KAAK,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,OAAO,QAAA,CAAS,GAAG;AAC3B,aAAS,IAAI,KAAK,KAAK;AAAA,EACzB;AACA,SAAO;AACT;AASO,SAAS,eACd,OACA,QACA,aACQ;AACR,MAAI,KAAsB;AAE1B,MAAI,iBAAiB,MAAM;AACzB,SAAKA,MAAAA,SAAS,WAAW,KAAK;AAAA,EAChC,WAAW,OAAO,UAAU,UAAU;AACpC,eAAW,UAAU;AAAA,MACnBA,MAAAA,SAAS;AAAA,MACTA,MAAAA,SAAS;AAAA,MACTA,MAAAA,SAAS;AAAA,MACTA,eAAS;AAAA,IAAA,GACR;AACD,WAAK,OAAO,KAAK;AACjB,UAAI,GAAG,QAAS;AAAA,IAClB;AACA,QAAI,CAAC,IAAI,SAAS;AAChB,YAAM,SAAS,OAAO,KAAK;AAC3B,UAAI,CAAC,MAAM,MAAM,GAAG;AAClB,aAAKA,MAAAA,SAAS,WAAW,MAAM;AAAA,MACjC;AAAA,IACF;AAAA,EACF,WAAW,OAAO,UAAU,UAAU;AACpC,SAAKA,MAAAA,SAAS,WAAW,KAAK;AAAA,EAChC,OAAO;AACL,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,MAAI,CAAC,IAAI,SAAS;AAChB,UAAM,IAAI,MAAM,cAAc;AAAA,EAChC;AACA,QAAM,UAAUA,MAAAA,SAAS,YAAY,CAAC;AACtC,QAAM,UAAUA,MAAAA,SAAS,WAAW,aAAa,GAAI;AAErD,MAAI,aAAa;AACf,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AACA,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAEA,SAAO,GAAG,SAAS,MAAM;AAC3B;AAQO,SAAS,eAAwCC,QAAiC;AACvF,QAAM,EAAE,SAAS,gBAAgB,iBAAiBA,MAAK;AAGvD,QAAM,oBAAoB,OAAO,QAAQ,OAAO,EAAE,OAAO,CAAC,GAAG,MAAM,MAAM,OAAO,OAAO;AAKvF,MAAI,kBAAkB,SAAS,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,QAAQ,WAAW,KAAK,YAAY,SAAS,GAAG;AAExD,UAAM,wCAAwB,IAAA;AAE9B,gBAAY,QAAQ,CAAC,sBAAsB;AAEzC,aAAO,QAAQ,OAAO,EACnB,OAAO,CAAC,CAAA,EAAG,MAAM,MAAM;AAEtB,eAAO,kBAAkB,QAAQ,SAAS,MAAM;AAAA,MAClD,CAAC,EACA,QAAQ,CAAC,CAAC,MAAM,MAAM,MAAM;AAC3B,0BAAkB,IAAI,CAAC,MAAM,MAAM,CAAC;AAAA,MACtC,CAAC;AAAA,IACL,CAAC;AAED,WAAO,MAAM,KAAK,iBAAiB;AAAA,EACrC;AAEA,SAAO,CAAA;AACT;AASA,SAAS,mBACPA,QACA,mBACA,aACqB;AACrB,QAAM,cAAmC,CAAA;AAGzC,MAAI,mBAAmB;AAErB,UAAM,UAAiBA,OAAM,iBAAiB;AAC9C,QAAI,SAAS;AACX,cAAQ,QAAQ,CAAC,OAAO;AACtB,YAAI,GAAG,WAAW;AAChB,gBAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,aAAa;AAEf,UAAM,qBAAqBA,OAAM,WAAW;AAC5C,QAAI,sBAAsB,OAAO,uBAAuB,YAAY;AAClE,YAAM,oBAAoB,mBAAmBA,MAAK;AAClD,UAAI,mBAAmB;AACrB,cAAM,iBAAiB,MAAM,QAAQ,iBAAiB,IAClD,oBACA,OAAO,OAAO,iBAAiB,EAAE;AAAA,UAC/B,CAAC,SAAU,KAA2B,SAAS;AAAA,QAAA;AAGrD,uBAAe,QAAQ,CAAC,YAAY;AAClC,cAAI,CAAC,SAAS,YAAa;AAE3B,gBAAM,cAAc,QAAQ,YAAY,KAAK,YAAA;AAC7C,cAAI,YAAY,SAAS,mBAAmB,GAAG;AAC7C,wBAAY,KAAK,OAAO;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,iBAAiBA,QAAoC;AACnE,QAAM,UAAU,OAAO,sBAAsBA,MAAK;AAClD,QAAM,aAAa,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAA,EAAW,SAAS,MAAM,CAAC;AACpE,QAAM,gBAAgB,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAA,EAAW,SAAS,SAAS,CAAC;AAC1E,QAAM,oBAAoB,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAA,EAAW,SAAS,cAAc,CAAC;AACnF,QAAM,cAAc,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAA,EAAW,SAAS,oBAAoB,CAAC;AAGnF,QAAM,WAAW;AAAA,IACf,SAAS,CAAA;AAAA,IACT,QAAQ,CAAA;AAAA,IACR,aAAa,CAAA;AAAA,IACb,aAAa,CAAA;AAAA,IACb,mBAAmB,CAAA;AAAA,IACnB,QAAQ,CAAA;AAAA,EAAC;AAIX,WAAS,cAAc,mBAAmBA,QAAO,mBAAmB,WAAW;AAG/E,MAAI,aAAa;AAEf,UAAM,qBAAqBA,OAAM,WAAW;AAC5C,QAAI,sBAAsB,OAAO,uBAAuB,YAAY;AAClE,YAAM,oBAAoB,mBAAmBA,MAAK;AAClD,UAAI,mBAAmB;AAErB,cAAM,iBAAiB,MAAM,QAAQ,iBAAiB,IAClD,oBACA,OAAO,OAAO,iBAAiB,EAAE;AAAA,UAC/B,CAAC,SAAU,KAA2B,SAAS;AAAA,QAAA;AAIrD,uBAAe,QAAQ,CAAC,YAAY;AAClC,cAAI,CAAC,SAAS,YAAa;AAE3B,gBAAM,cAAc,QAAQ,YAAY,KAAK,YAAA;AAG7C,gBAAM,aAAa;AAAA,YACjB,cAAc,SAAS;AAAA,YACvB,cAAc,SAAS;AAAA,YACvB,mBAAmB,SAAS;AAAA,YAC5B,yBAAyB,SAAS;AAAA,UAAA;AAIpC,qBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACtD,gBAAI,YAAY,SAAS,IAAI,GAAG;AAC9B,oBAAM,KAAK,OAAO;AAClB;AAAA,YACF;AAAA,UACF;AAGA,mBAAS,OAAO,KAAK,OAAO;AAAA,QAC9B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,WAAW,aAAcA,OAAc,UAAU,IAAI;AAAA,IACrD,SAAS,gBAAkBA,OAAc,aAAa,IAAkC,CAAA;AAAA,IACxF,GAAG;AAAA,EAAA;AAEP;AAWO,SAAS,4BACd,QACA,SACU;AACV,QAAM,iBAA2B,CAAA;AACjC,QAAM,eAAe,WAAW,EAAE,UAAU,MAAM,OAAO,KAAA;AACzD,MAAI,CAAC,aAAa,YAAY,CAAC,aAAa,OAAO;AAEjD,YAAQ,KAAK,6EAA6E;AAC1F,WAAO,CAAA;AAAA,EACT;AACA,SAAO,QAAQ,CAAC,cAAc;AAC5B,QAAI,aAAa,OAAO;AACtB,qBAAe,KAAK,0BAA0B,SAAS,KAAK;AAAA,IAC9D;AACA,QAAI,aAAa,UAAU;AACzB,qBAAe,KAAK,6BAA6B,SAAS,KAAK;AAAA,IACjE;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAIA,SAAS,sBACPA,QACA,YACA,UACK;AACL,QAAM,EAAE,SAAS,cAAc,iBAAiBA,MAAK;AACrD,QAAM,wBAAiD,CAAA;AACvD,SAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,SAAS;AACrC,UAAM,SAAS,QAAQ,IAAI;AAC3B,UAAM,WAAW,KAAK,UAAU,IAAI,SAAS,IAAI,OAAO,IAAI,GAAG,YAAA;AAC/D,UAAM,aAAaF,WAAAA,IAAI,IAAI,QAAQ;AACnC,0BAAsB,IAAI,IAAIA,WAAAA,MAAM,MAAM,SAAS,UAAU;AAC7D,aAAS,QAAQ,IAAI;AAAA,EACvB,CAAC;AACD,SAAO;AACT;AAEA,SAAS,gBAAgB,QAAsB;AAC7C,SAAO,UAAU,OAAO,WAAW,YAAY,WAAW;AAC5D;AAEO,SAAS,0BACd,YACA,MACA,UACA,QACA,UACK;AACL,MAAIG,WAAAA,QAAQ,MAAM,GAAG;AACnB,eAAW,IAAI,IAAI,sBAAsB,QAAsB,UAAU,QAAQ;AAAA,EACnF,WAAW,gBAAgB,MAAM,GAAG;AAClC,UAAM,SAAS;AACf,UAAM,gBAAgB,KAAK,QAAQ,IAAI,OAAO,IAAI,GAAG,YAAA;AACrD,QAAI,YAAYH,WAAAA,IAAI,IAAI,aAAa;AACrC,eAAW,IAAI,IAAIA,WAAAA,MAAM,MAAM,SAAS,SAAS;AACjD,aAAS,aAAa,IAAI;AAAA,EAC5B,WAAWI,mBAAa,MAAM,GAAG;AAC/B,eAAW,IAAI,IAAI;AAAA,EACrB,OAAO;AACL,UAAM,kBAAuB,CAAA;AAC7B,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM;AACnD,gCAA0B,iBAAiB,OAAO,GAAG,QAAQ,IAAI,KAAK,IAAI,SAAS,QAAQ;AAAA,IAC7F,CAAC;AACD,eAAW,IAAI,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AACO,SAAS,yBACd,QACsD;AACtD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACA,QAAM,WAA2B,CAAA;AACjC,QAAM,aAAkB,CAAA;AACxB,SAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAMC,OAAM,MAAM;AACjD,8BAA0B,YAAY,MAAM,MAAMA,SAAQ,QAAQ;AAAA,EACpE,CAAC;AACD,SAAO,EAAE,YAAY,SAAA;AACvB;AAEA,SAAS,yBAAyB,OAAoC;AACpE,QAAM,QACJ,UAAU,QAAQ,OAAO,UAAU,YAAYD,mBAAa,KAAK,KAAK,iBAAiB;AACzF,MAAI,OAAO;AACT,UAAMJ,OAAM;AACZ,UAAM,cAAcA,KAAI;AACxB,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,iBAAiB,YAAY,YAAY,SAAS,CAAC;AACzD,UAAII,mBAAa,cAAc,KAAK,iBAAiB,gBAAgB;AACnE,cAAM,oBAAoB;AAC1B,YAAI,kBAAkB,aAAa,WAAW,KAAK,kBAAkB,YAAY,CAAC,GAAG;AACnF,gBAAM,yBAAyB,kBAAkB,YAAY,CAAC;AAC9D,cAAI,WAAW,wBAAwB;AACrC,kBAAM,SAAU,uBAAuC;AACvD,gBAAI,UAAU,OAAO,WAAW,GAAG;AACjC,qBAAO,OAAO,CAAC;AAAA,YACjB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eACP,OACA,OACA,UACS;AACT,QAAM,SAAS,SAAS,KAAK;AAC7B,MAAI,CAAC,OAAQ,QAAO;AAEpB,MAAI,eAAe;AAEnB,QAAM,aAAa,cAAc;AACjC,MAAI,cAAc,UAAU,QAAQ,UAAU,QAAW;AACvD,WAAO,WAAW,KAAK;AAAA,EACzB;AACA,SAAO;AACT;AAEA,SAAS,gBACP,KACA,YACA,UACyB;AACzB,QAAM,SAAkC,CAAA;AAExC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,UAAM,YAAY,WAAW,GAAG;AAChC,UAAM,QAAQ,yBAAyB,SAAS;AAChD,QAAI,SAAS,SAAS,KAAK,GAAG;AAC5B,aAAO,GAAG,IAAI,eAAe,OAAO,OAAO,QAAQ;AAAA,IACrD,WAAW,aAAa,OAAO,cAAc,YAAY,CAACA,MAAAA,aAAa,SAAS,GAAG;AACjF,aAAO,GAAG,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,yBACd,MACA,YACA,UACK;AACL,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,WAAO,oBAAoB,WAAW;AAAA,EACxC,CAAC;AACH;AAEA,SAAS,oBAAoB,KAA8D;AACzF,MAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,eAAe,IAAI,YAAY,SAAS,UAAU;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,SAAkC,CAAA;AACxC,MAAI,UAAU;AAEd,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO,GAAG,IAAI;AACd;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,YAAY,oBAAoB,KAAgC;AACtE,aAAO,GAAG,IAAI;AACd,UAAI,cAAc,MAAM;AACtB,kBAAU;AAAA,MACZ;AAAA,IACF,OAAO;AACL,aAAO,GAAG,IAAI;AACd,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,UAAU,OAAO;AAC1B;AAEO,SAAS,kBAAkB,eAA+B;AAC/D,MAAI,OAAO,kBAAkB,YAAY,MAAM,aAAa,GAAG;AAC7D,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,SAAOJ,WAAAA,IAAI,IAAI,GAAG,aAAa,EAAE;AACnC;AAEO,SAAS,QAAQ,cAA8B;AACpD,SAAOA,WAAAA,IAAI,IAAI,WAAW,YAAY,GAAG;AAC3C;AA4BA,eAAsB,qBACpB,aACA,YACA,SACA;AACA,MAAI;AACF,UAAM,kBAAkB;AACxB,UAAMM,aAAY,WAAW;AAC7B,UAAM,UAAU,MAAM;AAAA,MACpB,YACG,uBAAA,EACA,OAAO;AAAA,QACN,YAAY,aAAa,gBAAgB,UAAU;AAAA,QACnD,YAAY,gBAAgB;AAAA,QAC5B,QAAQ,gBAAgB;AAAA,QACxB,WAAW,gBAAgB;AAAA,QAC3B,MAAM,gBAAgB;AAAA,QACtB,UAAU,gBAAgB;AAAA,MAAA,CAC3B,EACA,KAAK,eAAe,EACpB;AAAA,QACCC,WAAAA;AAAAA,UACEC,WAAAA,UAAU,gBAAgB,MAAM;AAAA,UAChCC,WAAAA,IAAIC,WAAAA,MAAM,gBAAgB,YAAY,sBAAsB,CAAC;AAAA,UAC7DC,WAAAA,WAAW,gBAAgB,UAAU;AAAA,YACnC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA,CACD;AAAA,UACDC,WAAAA;AAAAA,YACE,gBAAgB;AAAA,YAChBZ;;8BAEgB,aAAa,GAAI;AAAA;AAAA;AAAA,UAAA;AAAA,QAGnC;AAAA,MACF;AAAA,MAEJ,WAAWM,UAAS;AAAA,MACpBA,aAAY;AAAA,IAAA;AAGd,YAAQ,QAAQ,CAAC,WAAW;AAE1B,YAAM,YAAY,OAAO,OAAO,UAAU,IAAI;AAC9C,YAAM,WAAW,OAAO,OAAO,MAAM,IAAI;AAIzC,cAAQ;AAAA,QACN,QAAQ,OAAO,UAAU,cAAc,SAAS,QAAQ,CAAC,CAAC,eAAe,UAAU,QAAQ,CAAC,CAAC,mBAAmB,OAAO,QAAQ,kBAAkB,OAAO,SAAS;AAAA,QAAW,OAAO,IAAI;AAAA,MAAA;AAAA,IAE3L,CAAC;AAAA,EACH,SAAS,OAAO;AAEd,YAAQ;AAAA,MACN,yDAAyD,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjH;AAAA,IAAA;AAAA,EAEJ;AACF;AAEA,MAAM,yBAAyB;AA+B/B,eAAsB,kBACpB,aACA,OACA,SACA;AACA,MAAI;AACF,UAAMA,aAAY,WAAW;AAC7B,UAAM,UAAU,MAAM;AAAA,MACpB,YACG,uBAAA,EACA,OAAO;AAAA,QACN,OAAO,aAAa,UAAU,KAAK;AAAA,QACnC,WAAW,UAAU;AAAA,QACrB,QAAQ,UAAU;AAAA,QAClB,MAAM,UAAU;AAAA,MAAA,CACjB,EACA,KAAK,SAAS,EACd;AAAA,QACCC,WAAAA;AAAAA,UACEC,WAAAA,UAAU,UAAU,MAAM;AAAA,UAC1BK,cAAG,UAAU,cAAc,sBAAsB;AAAA,UACjDD,WAAAA;AAAAA,YACE,UAAU;AAAA,YACVZ;;8BAEgB,KAAK;AAAA;AAAA;AAAA,UAAA;AAAA,QAGvB;AAAA,MACF;AAAA,MAEJ,WAAWM,UAAS;AAAA,MACpBA;AAAA,IAAA;AAEF,UAAM,WAAqB,CAAA;AAC3B,YAAQ,QAAQ,CAAC,WAAW;AAE1B,YAAM,WAAW,OAAO,SAAS,OAAO,OAAO,MAAM,IAAI,MAAY;AAErE,YAAM,UAAU,wBAAwB,OAAO,KAAK,cAAc,SAAS,QAAQ,CAAC,CAAC,eAAe,OAAO,SAAS;AAAA,QAAc,OAAO,IAAI;AAC7I,eAAS,KAAK,OAAO;AAGrB,cAAQ,KAAK,OAAO;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,YAAQ;AAAA,MACN,yDAAyD,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjH;AAAA,IAAA;AAEF,WAAO;AAAA,MACL,yDAAyD,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,IAAA;AAAA,EAErH;AACF;AAUA,eAAsB,YACpB,SACA,SACAA,YACY;AACZ,MAAI;AAEJ,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAC3B,aAAO,IAAI,MAAM,OAAO,CAAC;AAAA,IAC3B,GAAGA,UAAS;AAAA,EACd,CAAC;AAED,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,cAAc,CAAC;AAAA,EACrD,UAAA;AACE,QAAI,WAAW;AACb,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AACF;AAEO,SAAS,aAGd,QAA4D;AAG5D,SAAON,gDAAqCA,WAAAA,IAAI,IAAI,GAAG,sBAAsB,EAAE,CAAC,QAAQ,MAAM;AAChG;AC9vBA,MAAM,kBAAkB;AAAA,EACtB,YAAY;AAAA,EACZ,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,aAAa;AACf;AAYA,SAAS,iBAAyB;AAChC,QAAM,KAAKC,MAAAA,SAAS,IAAA;AACpB,SAAO,KAAK,MAAM,GAAG,UAAA,CAAW;AAClC;AAUA,SAAS,eAAe,cAA8B;AACpD,QAAM,KAAKA,MAAAA,SAAS,IAAA,EAAM,KAAK,EAAE,SAAS,cAAc;AACxD,SAAO,KAAK,MAAM,GAAG,UAAA,CAAW;AAClC;AAQA,SAAS,wBAAwBD,MAAqB;AACpD,QAAM,QAAQ;AACd,QAAM,8BAAc,IAAA;AACpB,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAKA,KAAI,YAAA,CAAa,OAAO,MAAM;AACvD,QAAI,CAAC,MAAM,CAAC,EAAE,WAAW,IAAI,GAAG;AAC9B,cAAQ,IAAI,KAAK,MAAM,CAAC,CAAC,IAAI;AAAA,IAC/B;AAAA,EACF;AAGA,SAAO,MAAM,KAAK,OAAO,EAAE,KAAA,EAAO,KAAK,GAAG;AAC5C;AAQO,SAAS,QAAQ,OAAsB;AAC5C,QAAM,IAAIc,kBAAO,WAAW,QAAQ;AACpC,IAAE,OAAO,MAAM,IAAI,YAAA,CAAa;AAChC,IAAE,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AACrC,SAAO,iBAAiB,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,gBAAgB,WAAW;AAC9E;AASA,eAAe,4BACb,SACA,iBACe;AACf,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,gBAAgB,YAAY;AACnE,UAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,gBAAgB,UAAU;AAC7D,QAAI,qBAAqBC,IAAAA,IAAI,SAAA;AAC7B,UAAM,QAAQ,CAAC,WAAW;AACxB,2BAAqB,mBAAmB,OAAO,OAAO,KAAK,EAAE,YAAY,iBAAiB;AAAA,IAC5F,CAAC;AACD,UAAM,mBAAmB,QAAA;AAAA,EAC3B;AACF;AAUA,eAAe,iBACb,QACA,QACA,SACiB;AACjB,QAAM,kBAAkB,QAAQ;AAChC,MAAI,CAAC,iBAAiB;AACpB,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,kBAAkB,QAAQ,wBAAwB,gBAAgB;AACxE,MAAI,UAAU,IAAIC,WAAA;AAIlB,aAAWd,UAAS,QAAQ;AAC1B,UAAM,eAAe,QAAQ,iBAAiB,KAAKA,MAAK,OAAOA;AAC/D,YAAQ,GAAG,iBAAiBe,IAAAA,iBAAiB,SAAS,cAAc,YAAA,CAAa,CAAC;AAAA,EACpF;AAEA,MAAI,qBAAqBF,IAAAA,IACtB,OAEE,eAAe,EACjB,MAAA,EACA,MAAM,eAAe,EACrB,QAAQ,OAAO;AAElB,MAAI,QAAQ;AACV,yBAAqB,mBAAmB,OAAO,MAAM;AAAA,EACvD;AAEA,QAAM,aAAa,MAAM,mBAAmB,MAAM,GAAG,EAAE,QAAA;AAEvD,MAAI,QAAQ,UAAU;AAEpB,YAAQ,KAAK,wBAAwB,KAAK,UAAU,WAAW,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE;AAAA,EAC7F;AAEA,QAAM,4BAA4B,WAAW,SAAS,eAAe;AAErE,MAAI,WAAW,YAAY;AACzB,WACE,WAAW,QAAQ,SAAU,MAAM,iBAAiB,QAAQ,WAAW,YAAY,OAAO;AAAA,EAE9F,OAAO;AACL,WAAO,WAAW,QAAQ;AAAA,EAC5B;AACF;AASA,eAAe,2BACb,QACA,SACiB;AACjB,QAAM,kBAAkB,QAAQ;AAChC,MAAI,CAAC,iBAAiB;AACpB,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,uBACJ,QAAQ,6BAA6B,gBAAgB;AACvD,MAAI,qBAAqBA,IAAAA,IACtB,OAEE,eAAe,EACjB,MAAA,EACA,MAAM,oBAAoB,EAC1B,MAAMG,oBAAgB,SAAS,KAAK,MAAMjB,MAAAA,SAAS,MAAM,UAAA,CAAW,CAAC,CAAC;AAEzE,MAAI,QAAQ;AACV,yBAAqB,mBAAmB,OAAO,MAAM;AAAA,EACvD;AAEA,QAAM,aAAa,MAAM,mBAAmB,MAAM,GAAG,EAAE,QAAA;AAEvD,MAAI,QAAQ,UAAU;AAEpB,YAAQ,KAAK,0BAA0B,KAAK,UAAU,WAAW,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE;AAAA,EAC/F;AAEA,QAAM,4BAA4B,WAAW,SAAS,eAAe;AAErE,MAAI,WAAW,YAAY;AACzB,WACE,WAAW,QAAQ,SAAU,MAAM,2BAA2B,WAAW,YAAY,OAAO;AAAA,EAEhG,OAAO;AACL,WAAO,WAAW,QAAQ;AAAA,EAC5B;AACF;AAUA,eAAe,iBAAoB,WAA6B,eAAmC;AACjG,MAAI,UAAU;AACd,MAAI,QAAQ,gBAAgB;AAE5B,SAAO,UAAU,gBAAgB,oBAAoB;AACnD,QAAI;AACF,aAAO,MAAM,UAAA;AAAA,IACf,SAAS,KAAU;AAEjB,cAAQ,KAAK,gBAAgB,aAAa,KAAK,IAAI,OAAO,WAAW,OAAO,IAAI,GAAG;AACnF;AAEA,UAAI,WAAW,gBAAgB,oBAAoB;AAEjD,gBAAQ,MAAM,gBAAgB,aAAa,KAAK,IAAI,OAAO,IAAI,GAAG;AAClE,cAAM;AAAA,MACR;AAEA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AACzD,eAAS,gBAAgB;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,uCAAuC,aAAa,EAAE;AACxE;AASA,eAAsB,WACpB,QACA,SACe;AACf,QAAM,YAAYkB,MAAAA,aAAa,MAAM;AACrC,MAAI,wBAAwB,YAAY;AACtC,4BAAwB,SAAA,GAAY,OAAO,IAAI,SAAS;AAAA,EAC1D,OAAO;AACL,UAAM,iBAAiB,CAAC,SAAS,GAAG,OAAO;AAAA,EAC7C;AACF;AASA,eAAsB,iBACpB,QACA,SACe;AACf,MAAI,CAAC,QAAQ,iBAAiB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,YAAYlB,MAAAA,SAAS,IAAA;AAC3B,MAAI,eAAe;AAEnB,MAAI;AACF,mBAAe,MAAM;AAAA,MACnB,MAAM,iBAAiB,QAAQ,IAAI,OAAO;AAAA,MAC1C;AAAA,IAAA;AAAA,EAEJ,UAAA;AACE,QAAI,QAAQ,UAAU;AACpB,YAAM,WAAWA,MAAAA,SAAS,IAAA,EAAM,UAAA,IAAc,UAAU,UAAA;AAExD,cAAQ,KAAK,WAAW,YAAY,qBAAqB,QAAQ,UAAU;AAAA,IAC7E;AAAA,EACF;AACF;AAOA,eAAsB,kBAAkB,SAA4C;AAClF,MAAI,CAAC,QAAQ,iBAAiB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,YAAYA,MAAAA,SAAS,IAAA;AAC3B,MAAI,eAAe;AAEnB,MAAI;AACF,mBAAe,MAAM;AAAA,MACnB,MAAM,2BAA2B,IAAI,OAAO;AAAA,MAC5C;AAAA,IAAA;AAAA,EAEJ,UAAA;AACE,UAAM,WAAWA,MAAAA,SAAS,IAAA,EAAM,UAAA,IAAc,UAAU,UAAA;AACxD,QAAI,SAAS,UAAU;AAErB,cAAQ,MAAM,WAAW,YAAY,6BAA6B,QAAQ,UAAU;AAAA,IACtF;AAAA,EACF;AACF;AASA,eAAsB,aACpB,OACA,SACwB;AACxB,MAAI,CAAC,QAAQ,iBAAiB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,kBAAkB,QAAQ,wBAAwB,gBAAgB;AACxE,QAAM,iBACJ,QAAQ,6BAA6B,gBAAgB;AACvD,QAAM,WAAW,QAAQ,uBAAuB,gBAAgB;AAEhE,QAAM,WAAW,MAAM,MAAA;AACvB,QAAM,MAAM,QAAQ,QAAQ;AAG5B,MAAI,MAAM,mCAAmC,SAAS,KAAK,OAAO,GAAG;AACnE,QAAI,QAAQ,UAAU;AAEpB,cAAQ,KAAK,0DAA0D;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,cAAe,MAAMc,IAAAA,IAAI,OAAoB,QAAQ,eAAe,EAAE,IAAI,GAAG;AAInF,QACE,eACC,YAAY,cAAc,KAAgB,eAAA,KAC3C,wBAAwB,SAAS,GAAG,MAAM,YAAY,eAAe,GACrE;AACA,UAAI,QAAQ,UAAU;AAEpB,gBAAQ,KAAK,mCAAmC,GAAG,EAAE;AAAA,MACvD;AACA,YAAM,UAAU,YAAY,QAAQ;AACpC,aAAO,KAAK,MAAM,OAAiB;AAAA,IACrC;AAAA,EACF,SAAS,OAAY;AAEnB,YAAQ,MAAM,6BAA6B,MAAM,OAAO,IAAI,KAAK;AAAA,EACnE;AAEA,SAAO;AACT;AAWA,eAAsB,eACpB,OACA,SACA,SACA,UACe;AACf,MAAI,CAAC,QAAQ,iBAAiB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,MAAI;AACF,UAAM,kBACJ,QAAQ,wBAAwB,gBAAgB;AAClD,UAAM,iBACJ,QAAQ,6BAA6B,gBAAgB;AACvD,UAAM,WAAW,QAAQ,uBAAuB,gBAAgB;AAEhE,UAAM,WAAW,MAAM,MAAA;AAGvB,QAAI,MAAM,mCAAmC,SAAS,KAAK,OAAO,GAAG;AACnE,UAAI,QAAQ,UAAU;AAEpB,gBAAQ,KAAK,0DAA0D;AAAA,MACzE;AACA;AAAA,IACF;AAEA,UAAM,MAAM,QAAQ,QAAQ;AAE5B,UAAMA,IAAAA,IACH,WACA;AAAA,MACC;AAAA,MACA;AAAA,QACE,CAAC,eAAe,GAAG,wBAAwB,SAAS,GAAG;AAAA,QACvD,CAAC,cAAc,GAAG,eAAe,QAAQ;AAAA,QACzC,CAAC,QAAQ,GAAG,KAAK,UAAU,OAAO;AAAA,MAAA;AAAA,MAEpC,EAAE,YAAY,QAAQ,gBAAA;AAAA,IAAgB,EAEvC,QAAA;AAEH,QAAI,QAAQ,UAAU;AAEpB,cAAQ,KAAK,mCAAmC,GAAG,EAAE;AAAA,IACvD;AAAA,EACF,SAAS,OAAY;AAEnB,YAAQ,MAAM,wBAAwB,MAAM,OAAO,IAAI,KAAK;AAAA,EAC9D;AACF;AClZA,SAAS,QAAQ,KAAwB;AACvC,SACE,OAAO,QAAQ,YACf,QAAQ,QACR,OAAO,IAAI,QAAQ,YACnB,MAAM,QAAQ,IAAI,MAAM;AAE5B;AAOO,MAAM,0BAA0B,IAAIK,iBAAAA,kBAAA;AAOpC,MAAM,+BAA+B,IAAIA,iBAAAA,kBAAA;AAehD,eAAsB,8BACpBlB,SACe;AACf,QAAM,UAAU,wBAAwB,SAAA;AACxC,MAAI,SAAS;AACX,UAAM,YAAYiB,MAAAA,aAAajB,OAAK,EAAE,YAAA;AACtC,YAAQ,OAAO,IAAI,SAAS;AAAA,EAC9B;AACF;AAkBA,eAAsB,yBAEpB,OAAU,MAAiB,SAA4C;AACvE,QAAM,UAAU,6BAA6B,SAAA;AAC7C,MAAI,SAAS;AACX,QAAI,CAAC,QAAQ,OAAO;AAClB,cAAQ,QAAQ,CAAA;AAAA,IAClB;AACA,QAAIF;AACJ,QAAI,QAAQ,KAAK,GAAG;AAClB,MAAAA,OAAM,EAAE,OAAO,MAAM,MAAA;AAAA,IACvB,OAAO;AACL,MAAAA,OAAM;AAAA,IACR;AAEA,UAAM,MAAM,QAAQA,KAAI,MAAA,CAAO;AAC/B,YAAQ,MAAM,GAAG,IAAI;AAAA,MACnB,KAAKA,KAAI,QAAQ,IAAI,YAAA;AAAA,MACrB,MAAM;AAAA,IAAA;AAER,QAAI,QAAQ,UAAU;AACpB,YAAM,IAAIA,KAAI,MAAA;AAEd,cAAQ;AAAA,QACN,mEAAmE,EAAE,GAAG,aAAa,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MAAA;AAAA,IAEjH;AAAA,EACF;AACF;AAoBA,eAAsB,wBAEpB,OAAU,SAA6D;AACvE,QAAM,UAAU,6BAA6B,SAAA;AAC7C,MAAI,SAAS;AACX,QAAI,CAAC,QAAQ,OAAO;AAClB,cAAQ,QAAQ,CAAA;AAAA,IAClB;AACA,QAAIA;AACJ,QAAI,QAAQ,KAAK,GAAG;AAClB,MAAAA,OAAM,EAAE,OAAO,MAAM,MAAA;AAAA,IACvB,OAAO;AACL,MAAAA,OAAM;AAAA,IACR;AACA,UAAM,MAAM,QAAQA,KAAI,MAAA,CAAO;AAC/B,QAAI,QAAQ,MAAM,GAAG,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQA,KAAI,MAAA,EAAQ,IAAI,eAAe;AAClF,UAAI,QAAQ,UAAU;AACpB,cAAM,IAAIA,KAAI,MAAA;AAEd,gBAAQ;AAAA,UACN,kEAAkE,EAAE,GAAG,aAAa,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,QAAA;AAAA,MAEhH;AACA,aAAO,QAAQ,MAAM,GAAG,EAAE;AAAA,IAC5B;AAAA,EACF;AACA,SAAO;AACT;AAiBA,eAAsB,qBACpBE,SACA,SACe;AACf,QAAM,UAAU,6BAA6B,SAAA;AAC7C,MAAI,SAAS;AACX,QAAI,CAAC,QAAQ,OAAO;AAClB,cAAQ,QAAQ,CAAA;AAAA,IAClB;AACA,UAAM,YAAYiB,MAAAA,aAAajB,OAAK;AACpC,UAAM,eAAe,QAAQ,iBAAiB,KAAK,SAAS,OAAO;AACnE,UAAM,cAAwB,CAAA;AAC9B,WAAO,KAAK,QAAQ,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAC1C,UAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,SAAS,YAAY,GAAG;AACjD,oBAAY,KAAK,GAAG;AAAA,MACtB;AAAA,IACF,CAAC;AACD,gBAAY,QAAQ,CAAC,QAAQ,OAAO,QAAQ,MAAM,GAAG,CAAC;AAAA,EACxD;AACF;AAmBA,eAAsB,mCACpBF,MACA,SACkB;AAClB,QAAM,UAAU,wBAAwB,SAAA;AACxC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,KAAK,QAAQ,MAAM;AACxC,QAAM,WAAWA,KAAI,YAAA;AAErB,SAAO,OAAO,KAAK,CAACE,WAAU;AAC5B,UAAM,eAAe,QAAQ,iBAAiB,KAAKA,MAAK,OAAOA;AAC/D,WAAO,SAAS,SAAS,YAAY;AAAA,EACvC,CAAC;AACH;AC1OO,MAAM,uBAAgE;AAAA,EAC1D;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YAAY,oBAAuC,SAA6B;AAC9E,SAAK,kBAAkB;AACvB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,OACJ,QACA,QACA,iBAA0B,OACT;AACjB,QAAI,CAAC,QAAQ,OAAQ,QAAO;AAE5B,UAAM,EAAE,WAAW,YAAY,iBAAiB,MAAM;AACtD,UAAM,kBAAkB,KAAK,qBAAqB,WAAW,OAAO;AAGpE,UAAM,iBAAiB,OAAO;AAAA,MAAI,CAAC,UACjC,KAAK,wBAAwB,OAAO,iBAAiB,OAAO;AAAA,IAAA;AAI9D,UAAM,eAAe,KAAK,gBAAgB,OAAO,MAAM,EAAE,OAAO,cAAc;AAG9E,UAAM,aAAa,iBACf,aAAa,qBAAqB;AAAA,MAChC,KAAK,OAAO;AAAA,QACV,OAAO,KAAK,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAM,OAAe,GAAG,CAAC,CAAC;AAAA,MAAA;AAAA,IACzE,CACD,IACD;AAGJ,UAAM,SAAS,MAAM;AACrB,UAAM,8BAA8B,MAAM;AAC1C,WAAO,OAAO,CAAC,EAAE;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,WAAoC,IAAa,QAA4B;AACjF,UAAM,EAAE,WAAW,YAAY,iBAAiB,MAAM;AACtD,UAAM,cAAc,KAAK,eAAe,MAAM;AAE9C,QAAI,YAAY,WAAW,GAAG;AAC5B,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,UAAM,CAAC,gBAAgB,gBAAgB,IAAI,YAAY,CAAC;AACxD,UAAM,kBAAkB,KAAK,qBAAqB,WAAW,OAAO;AAGpE,UAAM,aAA6B,CAACmB,WAAAA,GAAG,kBAAkB,EAAE,CAAC;AAG5D,QAAI,mBAAmB,SAAS;AAC9B,YAAM,eAAe,QAAQ,gBAAgB,SAAS;AACtD,UAAI,cAAc;AAChB,cAAM,WAAW,MAAM,KAAK,YAAY,EAAE,CAAC,cAAc,GAAG,GAAA,GAAM,QAAQ;AAAA,UACxE,gBAAgB;AAAA,UAChB;AAAA,QAAA,CACD;AACD,mBAAW,KAAKA,cAAG,cAAe,SAAiB,gBAAgB,SAAS,CAAC,CAAC;AAAA,MAChF;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,gBAAgB,OAAO,MAAM,EAAE,MAAMd,WAAAA,IAAI,GAAG,UAAU,CAAC;AAEjF,UAAM,SAAS,MAAM;AACrB,QAAI,mBAAmB,OAAO,CAAC,EAAE,iBAAiB,GAAG;AACnD,YAAM,IAAI,MAAM,sDAAsD,EAAE,oBAAoB;AAAA,IAC9F;AACA,UAAM,8BAA8B,MAAM;AAC1C,WAAO,OAAO,CAAC,EAAE;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,WACJ,QACA,QACiB;AACjB,UAAM,EAAE,WAAW,YAAY,iBAAiB,MAAM;AACtD,UAAM,cAAc,KAAK,eAAe,MAAM;AAE9C,QAAI,YAAY,WAAW,GAAG;AAC5B,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,UAAM,CAAC,gBAAgB,gBAAgB,IAAI,YAAY,CAAC;AACxD,UAAM,kBAAkB,KAAK,qBAAqB,WAAW,OAAO;AAGpE,QAAI,EAAE,kBAAkB,SAAS;AAC/B,YAAM,IAAI,MAAM,eAAe,cAAc,iCAAiC;AAAA,IAChF;AAGA,UAAM,iBAAiB,MAAM,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAIF,UAAM,aAAa,KAAK,kBAAkB,QAAQ,iBAAiB,SAAS,cAAc;AAG1F,UAAM,aAA6B;AAAA,MACjCc,cAAG,kBAAkB,OAAO,cAAqC,CAAC;AAAA,IAAA;AAEpE,QAAI,mBAAmB,SAAS;AAC9B,YAAM,eAAe,QAAQ,gBAAgB,SAAS;AACtD,UAAI,cAAc;AAChB,mBAAW,KAAKA,WAAAA,GAAG,cAAc,cAAc,CAAC;AAAA,MAClD;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,gBACvB,OAAO,MAAM,EACb,IAAI,UAAU,EACd,MAAMd,eAAI,GAAG,UAAU,CAAC;AAE3B,UAAM,SAAS,MAAM;AAErB,QAAI,mBAAmB,OAAO,CAAC,EAAE,iBAAiB,GAAG;AACnD,YAAM,IAAI;AAAA,QACR,sDAAsD,OAAO,cAAqC,CAAC;AAAA,MAAA;AAAA,IAEvG;AACA,UAAM,8BAA8B,MAAM;AAC1C,WAAO,OAAO,CAAC,EAAE;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,aACJ,YACA,QACA,OACiB;AACjB,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,UAAM,eAAe,KAAK,gBAAgB,OAAO,MAAM,EAAE,IAAI,UAAU,EAAE,MAAM,KAAK;AAEpF,UAAM,SAAS,MAAM;AACrB,UAAM,8BAA8B,MAAM;AAC1C,WAAO,OAAO,CAAC,EAAE;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,eAAwC,QAAkC;AAChF,UAAM,cAAc,eAAe,MAAM;AACzC,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,qCAAqC,MAAM,EAAE;AAAA,IAC/D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,qBACN,WACA,SACiD;AACjD,QAAI,KAAK,QAAQ,0BAA0B;AACzC,aAAO;AAAA,IACT;AACA,UAAM,kBAAkB,KAAK,QAAQ,qBAAqB,SAAS,GAAG;AACtE,QAAI,CAAC,gBAAiB,QAAO;AAC7B,QAAI,YAAY,gBAAgB;AAEhC,QAAI,eAAe,QAAQ,gBAAgB,SAAS;AACpD,QAAI,CAAC,cAAc;AACjB,YAAM,OAAO,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,CAAA,EAAG,CAAC,MAAM,EAAE,SAAS,gBAAgB,SAAS;AACzF,UAAI,MAAM;AACR,oBAAY,KAAK,CAAC;AAClB,uBAAe,KAAK,CAAC;AAAA,MACvB;AAAA,IACF;AACA,QAAI,CAAC,cAAc;AAEjB,cAAQ;AAAA,QACN,kBAAkB,gBAAgB,SAAS,wBAAwB,SAAS;AAAA,MAAA;AAE9E,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,aAAa,SAAS;AAEzB,cAAQ;AAAA,QACN,kBAAkB,gBAAgB,SAAS,cAAc,SAAS;AAAA,MAAA;AAEpE,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,aAAa,WAAA;AAC/B,UAAM,kBACJ,cAAc,cACd,cAAc,eACd,cAAc,SACd,cAAc,YACd,cAAc;AAEhB,QAAI,CAAC,iBAAiB;AAEpB,cAAQ;AAAA,QACN,kBAAkB,gBAAgB,SAAS,cAAc,SAAS,0BAA0B,SAAS;AAAA,MAAA;AAGvG,aAAO;AAAA,IACT;AAEA,WAAO,EAAE,WAAW,MAAM,UAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAc,kBACZ,QACA,gBACA,iBACA,SACA,QACkB;AAClB,QAAI,CAAC,mBAAmB,CAAC,QAAS,QAAO;AAEzC,UAAM,eAAe,QAAQ,gBAAgB,SAAS;AACtD,QAAI,CAAC,aAAc,QAAO;AAE1B,QAAI,gBAAgB,aAAa,QAAQ;AACvC,aAAO,OAAO,gBAAgB,SAAgC;AAAA,IAChE;AAEA,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,EAAE,CAAC,cAAc,GAAG,OAAO,cAAqC,EAAA;AAAA,MAChE;AAAA,MACA,CAAC,gBAAgB,WAAW,YAAY;AAAA,IAAA;AAG1C,WAAQ,SAAiB,gBAAgB,SAAS;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,wBACN,OACA,iBACA,SACqB;AACrB,QAAI,CAAC,mBAAmB,CAAC,QAAS,QAAO;AACzC,QAAI,YAAY,gBAAgB;AAChC,QAAI,eAAe,QAAQ,gBAAgB,SAAS;AACpD,QAAI,CAAC,cAAc;AACjB,YAAM,OAAO,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,CAAA,EAAG,CAAC,MAAM,EAAE,SAAS,gBAAgB,SAAS;AACzF,UAAI,MAAM;AACR,oBAAY,KAAK,CAAC;AAClB,uBAAe,KAAK,CAAC;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,mBAAmB,EAAE,GAAG,MAAA;AAC9B,UAAM,YAAY,aAAa,WAAA;AAC/B,UAAM,eAAe,cAAc,cAAc,cAAc,cAAc,oBAAI,SAAS;AAC1F,qBAAiB,SAA0C,IAAI;AAE/D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,kBACN,QACA,iBACA,SACA,gBAC8B;AAC9B,UAAM,aAAa,EAAE,GAAG,OAAA;AAExB,QAAI,mBAAmB,SAAS;AAC9B,YAAM,eAAe,QAAQ,gBAAgB,SAAS;AACtD,UAAI,cAAc;AAChB,cAAM,YAAY,aAAa,WAAA;AAC/B,mBAAW,gBAAgB,SAAoC,IAC7D,cAAc,cAAc,cAAc,cACtC,oBAAI,KAAA,IACD,iBAA4B;AAAA,MACvC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,YACZ,kBACA,QACA,cAGA;AACA,UAAM,CAAC,kBAAkB,kBAAkB,IAAI;AAC/C,UAAM,cAAc,KAAK,eAAe,MAAM;AAC9C,UAAM,CAAC,gBAAgB,gBAAgB,IAAI,YAAY,CAAC;AAExD,UAAM,cAAc,KAAK,gBACtB,OAAO;AAAA,MACN,CAAC,cAAc,GAAG;AAAA,MAClB,CAAC,gBAAgB,GAAG;AAAA,IAAA,CACrB,EACA,KAAK,MAAM,EACX,MAAMc,WAAAA,GAAG,kBAAkB,iBAAiB,cAAc,CAAC,CAAC;AAE/D,UAAM,QAAQ,MAAM,KAAK,gBAAgB,MAAA,EAAQ,oBAAoB,WAAW;AAEhF,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,6BAA6B,MAAM,EAAE;AAAA,IACvD;AAEA,WAAO;AAAA,EACT;AACF;ACxbO,MAAM,yBAAsD;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAY,SAA6B;AACvC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,oBACJ,OAGA;AACA,UAAM,UAAsB,MAAM;AAClC,UAAM,QAAQ;AACd,QAAI,CAAC,MAAM,QAAQ;AACjB,aAAO;AAAA,IACT;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,IAAI,MAAM,kCAAkC,MAAM,MAAM,EAAE;AAAA,IAClE;AAEA,WAAO,MAAM,CAAC;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,cAA0C,OAAe,QAAkC;AAC/F,QAAI,KAAK,QAAQ,gBAAgB;AAC/B,YAAM,YAAY,SAAS,kBAAkB,KAAK,UAAU,MAAM,CAAC,KAAK;AAExE,cAAQ,MAAM,sBAAsB,KAAK,GAAG,SAAS,EAAE;AAAA,IACzD;AACA,UAAM,eAAerB,IAAAA,IAAI,QAAW,KAAK;AACzC,QAAI,QAAQ;AACV,mBAAa,WAAW,GAAG,MAAM;AAAA,IACnC;AACA,UAAM,SAAS,MAAM,aAAa,QAAA;AAClC,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,OAAe,QAAkD;AACzF,UAAM,eAAeA,IAAAA,IAAI,QAA6B,KAAK;AAC3D,QAAI,QAAQ;AACV,mBAAa,WAAW,GAAG,MAAM;AAAA,IACnC;AACA,QAAI,KAAK,QAAQ,gBAAgB;AAE/B,cAAQ;AAAA,QACN,6BAA6B,KAAK,MAC/B,SAAS,kBAAkB,KAAK,UAAU,MAAM,CAAC,KAAK;AAAA,MAAA;AAAA,IAE7D;AACA,UAAM,6BAA6B,MAAM,aAAa,QAAA;AACtD,WAAO,2BAA2B;AAAA,EACpC;AACF;AChFO,MAAM,uBAAuB,IAAIoB,iBAAAA,kBAAA;AAExC,eAAsB,sBAAsB,UAA4C;AACtF,QAAM,UAAU,qBAAqB,SAAA;AACrC,MAAI,SAAS;AACX,YAAQ,uBAAuB,YAAY;AACzC,UAAI,QAAQ,IAAI,aAAa,QAAQ;AACnC,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAAA,MAC7C;AACA,YAAM,qBAAqB,QAAQ,aAAa,KAAK,QAAQ,QAAQ,UAAU,SAAS;AAAA,IAC1F;AACA,QAAI,UAAU;AACZ,cAAQ,qBAAqB,SAAS;AACtC,cAAQ,wBAAwB,SAAS;AAAA,IAC3C;AAAA,EAEF;AACF;AAEA,eAAsB,qBAAgE;AACpF,SAAO,qBAAqB,SAAA;AAC9B;AC3BO,MAAM,4BAA4B,IAAIA,iBAAAA,kBAAA;AAE7C,eAAsB,mBAA2C;AAC/D,SAAO,0BAA0B,YAAY,iBAAiB;AAChE;ACLA,MAAM,YAAY;AAClB,MAAM,iBAAiB,yDAAyD,SAAS,OAAO,YAAY,GAAI;AAqDzG,SAAS,sBAAsB,KAA0C;AAC9E,SACE,QAAQ,QACR,OAAO,QAAQ,YACf,OAAQ,IAAY,iBAAiB,YACrC,OAAQ,IAAY,aAAa;AAErC;AAEA,SAAS,aAAapB,MAAa,QAA2B;AAC5D,MAAI,IAAI;AACR,SAAOA,KAAI,QAAQ,OAAO,MAAM;AAC9B,UAAM,MAAM,OAAO,GAAG;AACtB,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,OAAO,QAAQ,SAAU,QAAO,IAAI,SAAA;AACxC,WAAO,IAAI,OAAO,GAAG,EAAE,QAAQ,MAAM,IAAI,CAAC;AAAA,EAC5C,CAAC;AACH;AAQA,eAAe,iBAAiB,QAAqB,QAAyC;AAC5F,MAAI,OAAO,UAAU;AACnB,UAAM,sBAAsB,OAAO,QAA4B;AAAA,EACjE;AAEA,MAAI,CAAC,QAAQ,MAAM;AACjB,WAAO,EAAE,MAAM,GAAC;AAAA,EAClB;AAEA,MAAI,sBAAsB,OAAO,IAAI,GAAG;AACtC,UAAM,SAAS,OAAO;AACtB,WAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,MAAM,EAAA;AAAA,EACnC;AAEA,MAAI,MAAM,QAAQ,OAAO,IAAI,GAAG;AAC9B,QAAI,WAAW,WAAW;AACxB,aAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAA;AAAA,IAC7B,OAAO;AACL,YAAM,OAAQ,OAAO,KAAe,IAAI,CAAC,MAAM,OAAO,OAAO,CAA4B,CAAC;AAC1F,aAAO,EAAE,KAAA;AAAA,IACX;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,GAAC;AAClB;AASA,eAAe,qBAAqB,OAAe,QAA+C;AAChG,QAAM,eAAeA,IAAAA,IAAI,QAA6B,KAAK;AAE3D,MAAI,QAAQ;AACV,iBAAa,WAAW,GAAG,MAAM;AAAA,EACnC;AAEA,QAAM,SAAS,MAAM,YAAY,aAAa,QAAA,GAAW,gBAAgB,SAAS;AAClF,QAAM,sBAAsB,OAAO,QAA4B;AAC/D,MAAI,CAAC,OAAO,MAAM;AAChB,WAAO,EAAE,MAAM,CAAC,CAAA,CAAE,EAAA;AAAA,EACpB;AAEA,SAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAA;AAC7B;AASA,eAAe,iBAAiB,OAAe,QAA+C;AAC5F,QAAM,eAAe,MAAMA,QAAI,QAAiB,KAAK;AAErD,MAAI,QAAQ;AACV,UAAM,aAAa,WAAW,GAAG,MAAM;AAAA,EACzC;AAEA,QAAM,SAAU,MAAM;AAAA,IACpB,aAAa,QAAA;AAAA,IACb;AAAA,IACA;AAAA,EAAA;AAEF,QAAM,sBAAsB,OAAO,QAAQ;AAE3C,MAAI,CAAC,OAAO,MAAM;AAChB,WAAO,EAAE,MAAM,GAAC;AAAA,EAClB;AAEA,QAAM,OAAQ,OAAO,KAAe,IAAI,CAAC,MAAM,OAAO,OAAO,CAA4B,CAAC;AAE1F,SAAO,EAAE,KAAA;AACX;AAyBO,MAAM,cAAc,OACzB,OACA,QACA,WAC+B;AAC/B,QAAM,gBAAgB,MAAM,iBAAA;AAE5B,MAAI,kBAAkB,OAAO;AAC3B,UAAM,SAAS,MAAM;AAAA,MACnBA,IAAAA,IAAI,WAAW,aAAa,OAAO,MAAM,CAAC;AAAA,MAC1C;AAAA,MACA;AAAA,IAAA;AAEF,WAAO,MAAM,iBAAiB,QAAQ,MAAM;AAAA,EAC9C;AAGA,MAAI,WAAW,WAAW;AACxB,WAAO,MAAM,qBAAqB,OAAO,UAAU,CAAA,CAAE;AAAA,EACvD;AAGA,SAAO,MAAM,iBAAiB,OAAO,UAAU,CAAA,CAAE;AACnD;AC7LO,SAAS,eAAe,OAAe,OAA0B;AACtE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAGA,QAAM,kBAAkB,MAAM,KAAA,EAAO,YAAA;AAGrC,MAAI;AAEJ,MAAI,gBAAgB,WAAW,QAAQ,GAAG;AACxC,iBAAa,MAAM;AAAA,EACrB,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,iBAAa,MAAM;AAAA,EACrB,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,iBAAa,MAAM;AAAA,EACrB,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,iBAAa,MAAM;AAAA,EACrB;AAGA,MAAI,CAAC,cAAc,WAAW,WAAW,GAAG;AAC1C,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,WAAW,KAAK,GAAG;AAGvC,MAAI,gBAAgB,WAAW,QAAQ,GAAG;AACxC,WAAO,cAAc,WAAW,OAAO,MAAM,UAAU,CAAC,CAAC;AAAA,EAC3D,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,WAAO,cAAc,WAAW,OAAO,MAAM,UAAU,CAAC,CAAC;AAAA,EAC3D,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,WAAO,cAAc,WAAW,OAAO,MAAM,UAAU,CAAC,CAAC;AAAA,EAC3D,WAAW,gBAAgB,WAAW,QAAQ,GAAG;AAC/C,WAAO,cAAc,WAAW,OAAO,MAAM,UAAU,CAAC,CAAC;AAAA,EAC3D;AAGA,SAAO;AACT;ACtDA,MAAM,oBAAoB;AAAA,EACxB,SAAS;AAAA,EACT,qBAAqB;AACvB;AAKA,MAAM,8BAA8B;AAS7B,SAAS,uBACd,mBACA,SACA,gBACA;AACA,SAAO,OACL,OACA,QACA,WAKI;AAEJ,UAAM,gBAAgB,eAAe,OAAO,OAAO;AAEnD,QAAI,WAAW,kBAAkB,kBAAkB,OAAO;AAExD,cAAQ,MAAM,uBAAuB,aAAa,EAAE;AAAA,IACtD;AAEA,UAAM,iBAAiB,KAAK,IAAA;AAE5B,QAAI;AAEF,aAAO,MAAM,YAAY,eAAe,QAAQ,MAAM;AAAA,IACxD,SAAS,OAAY;AAEnB,YAAM,iBAAiB,MAAM,SAAS,kBAAkB;AACxD,YAAM,qBACJ,OAAO,SAAS,OAAO,UAAU,kBAAkB;AAErD,UAAI,kBAAkB,oBAAoB;AACxC,YAAI,gBAAgB;AAElB,kBAAQ,MAAM,+CAA+C;AAAA,QAC/D,OAAO;AAEL,kBAAQ,MAAM,sDAAsD;AAAA,QACtE;AAGA,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,2BAA2B,CAAC;AAE/E,cAAM,eAAe,KAAK,IAAA;AAC1B,cAAM,gBAAgB,eAAe;AAGrC,cAAM,qBAAqB,mBAAmB,aAAa;AAAA,MAC7D;AAGA,UAAI,gBAAgB;AAElB,gBAAQ,MAAM,sBAAsB,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,MACpE;AAGA,YAAM;AAAA,IACR;AAAA,EACF;AACF;ACrCA,MAAM,iCAAiC,CAAC,oBAAoB,kBAAkB;AAK9E,MAAM,6BAA6B,CAAC,YAAY,qBAAqB,kBAAkB;AAKvF,MAAM,8BAA8B,CAAC,eAAe,aAAa;AAKjE,MAAM,0BAA0B,CAAC,YAAY,aAAa;AAa1D,SAAS,wBAAwB,OAAqB;AAEpD,MAAI,OAAO,QAAQ,+BAA+B,SAAS,MAAM,IAAI,GAAG;AACtE,WAAO;AAAA,EACT;AAEA,MACE,OAAO,WACP,4BAA4B,KAAK,CAAC,YAAY,QAAQ,KAAK,MAAM,OAAO,CAAC,GACzE;AACA,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,QAAQ,2BAA2B,SAAS,MAAM,IAAI,GAAG;AAClE,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,wBAAwB,KAAK,CAAC,YAAY,QAAQ,KAAK,MAAM,OAAO,CAAC,GAAG;AAC5F,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAgLA,eAAe,0BACb,MACA,aACAE,QACA,SACA,UACc;AACd,MAAI;AACF,UAAM,qBAAqBA,QAAO,OAAO;AACzC,UAAM,8BAA8BA,MAAK;AACzC,QAAI,YAAY,CAAC,wBAAwB,YAAY;AACnD,YAAM,WAAWA,QAAO,OAAO;AAAA,IACjC;AACA,UAAM,SAAS,cAAc,YAAY,IAAI,IAAI;AACjD,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,QAAI,wBAAwB,KAAK,GAAG;AAClC,YAAM,qBAAqBA,QAAO,OAAO;AACzC,UAAI,UAAU;AACZ,cAAM,WAAWA,QAAO,OAAO,EAAE,MAAM,CAAC,MAAM;AAE5C,kBAAQ,KAAK,6BAA6B,CAAC;AAAA,QAC7C,CAAC;AAAA,MACH,OAAO;AACL,cAAM,8BAA8BA,MAAK;AAAA,MAC3C;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAaA,SAAS,mBACP,OACA,QACA,MACAA,QACA,SACA,UACK;AACL,QAAM,SAAS,MAAM,MAAM,QAAQ,IAAI;AACvC,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,aAAa,QAAQ;AACxE,WAAO,sBAAsB,QAAwBA,QAAO,SAAS,QAAQ;AAAA,EAC/E;AACA,SAAO;AACT;AAYA,MAAM,wBAAwB,CAC5B,YACAA,QACA,SACA,aACiB;AACjB,SAAO,IAAI,MAAM,YAAY;AAAA,IAC3B,IAAI,QAAQ,MAAM,UAAU;AAC1B,UAAI,SAAS,QAAQ;AACnB,eAAO,CAAC,aAAmB,eACzB,OACG,UACA;AAAA,UACC,CAAC,SACC,0BAA0B,MAAM,aAAaA,QAAO,SAAS,QAAQ;AAAA,UACvE;AAAA,QAAA;AAAA,MAER;AAEA,YAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAEhD,UAAI,OAAO,UAAU,YAAY;AAC/B,eAAO,IAAI,SACT,mBAAmB,OAAO,QAAQ,MAAMA,QAAO,SAAS,QAAQ;AAAA,MACpE;AAEA,aAAO;AAAA,IACT;AAAA,EAAA,CACD;AACH;AAUA,SAAS,2BACP,IACAA,QACA,SACA,UACoF;AACpF,QAAM,UAAU,GAAG,OAAOA,MAAK;AAC/B,SAAO;AAAA,IACL;AAAA,IACAA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAMJ;AAUA,SAAS,2BACP,IACAA,QACA,SACA,UACoF;AACpF,QAAM,UAAU,GAAG,OAAOA,MAAK;AAC/B,SAAO;AAAA,IACL;AAAA,IACAA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAMJ;AAUA,SAAS,2BACP,IACAA,QACA,SACA,UACiF;AACjF,QAAM,UAAU,GAAG,OAAOA,MAAK;AAC/B,SAAO;AAAA,IACL;AAAA,IACAA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAcA,eAAe,kBACb,QACA,SACA,UACA,YACA,UACA,aACA,YACc;AACd,MAAI;AACF,UAAM,cAAc,MAAM,wBAAwB,QAAQ,OAAO;AACjE,QAAI,aAAa;AACf,aAAO,cAAc,YAAY,WAAW,IAAI;AAAA,IAClD;AACA,UAAM,cAAc,MAAM,aAAa,QAAQ,OAAO;AACtD,QAAI,aAAa;AACf,aAAO,cAAc,YAAY,WAAW,IAAI;AAAA,IAClD;AACA,UAAM,OAAO,MAAM,OAAO,QAAA;AAC1B,UAAM,cAAc,yBAAyB,MAAM,YAAY,QAAQ;AACvE,UAAM,yBAAyB,QAAQ,aAAa,OAAO;AAC3D,UAAM,eAAe,QAAQ,SAAS,aAAa,QAAQ,EAAE,MAAM,CAAC,eAAe;AAGjF,cAAQ,KAAK,oBAAoB,UAAU;AAAA,IAC7C,CAAC;AAED,WAAO,cAAc,YAAY,WAAW,IAAI;AAAA,EAClD,SAAS,OAAO;AACd,QAAI,YAAY;AACd,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,UAAM;AAAA,EACR;AACF;AAaA,eAAe,qBACb,QACA,SACA,YACA,UACA,aACA,YACc;AACd,MAAI;AACF,UAAM,cAAc,MAAM,wBAAwB,QAAQ,OAAO;AACjE,QAAI,aAAa;AACf,aAAO,cAAc,YAAY,WAAW,IAAI;AAAA,IAClD;AACA,UAAM,OAAO,MAAM,OAAO,QAAA;AAC1B,UAAM,cAAc,yBAAyB,MAAM,YAAY,QAAQ;AACvE,UAAM,yBAAyB,QAAQ,aAAa,OAAO;AAC3D,WAAO,cAAc,YAAY,WAAW,IAAI;AAAA,EAClD,SAAS,OAAO;AACd,QAAI,YAAY;AACd,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,UAAM;AAAA,EACR;AACF;AAaA,SAAS,2BACP,IACA,QACA,UACA,UACA,SACA,UAC6D;AAC7D,QAAM,EAAE,YAAY,aAAa,yBAAyB,MAAM;AAChE,QAAM,UAAU,SAAS,UAAU;AAEnC,QAAM,cAAc,CAAC,eAAyB;AAC5C,WAAO,IAAI,MAAM,YAAY;AAAA,MAC3B,IAAI,QAAQ,MAAM,UAAU;AAC1B,YAAI,SAAS,WAAW;AACtB,iBAAO,UAAU,SAAgB;AAC/B,kBAAM,OAAO,MAAM,OAAO,QAAQ,GAAG,IAAI;AACzC,mBAAO,yBAAyB,MAAM,YAAY,QAAQ;AAAA,UAC5D;AAAA,QACF;AAEA,YAAI,SAAS,QAAQ;AACnB,iBAAO,CAAC,aAAmB,eAAqB;AAC9C,gBAAI,UAAU;AACZ,oBAAM,MAAM,YAAY,QAAQ,YAAY;AAC5C,qBAAO;AAAA,gBACL;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAEJ,OAAO;AACL,qBAAO;AAAA,gBACL;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAEJ;AAAA,UACF;AAAA,QACF;AAEA,cAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAEhD,YAAI,OAAO,UAAU,YAAY;AAC/B,iBAAO,IAAI,SAAgB;AACzB,kBAAM,SAAS,MAAM,MAAM,QAAQ,IAAI;AAEvC,gBAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,aAAa,QAAQ;AACxE,qBAAO,YAAY,MAAM;AAAA,YAC3B;AAEA,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAO,YAAY,OAAO;AAC5B;AASA,MAAM,kBAAsC;AAAA,EAC1C,gBAAgB;AAAA,EAChB,0BAA0B;AAAA,EAC1B,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,qBAAqB;AACvB;AASA,SAAS,uBACP,IACA,SACA,iBAA0B,OAC1B;AACA,SAAO,eACL,OACA,UAC8B;AAC9B,QAAIF;AAEJ,QAAII,MAAAA,aAAa,KAAK,GAAG;AACvB,YAAM,UAAW,GAA4C;AAC7D,MAAAJ,OAAM,QAAQ,WAAW,KAAY;AAAA,IACvC,OAAO;AACL,MAAAA,OAAM;AAAA,QACJ,KAAK;AAAA,QACL,QAAQ,CAAA;AAAA,MAAC;AAAA,IAEb;AAGA,UAAM,mBAAmB,MAAM,wBAAwBA,MAAK,OAAO;AACnE,QAAI,kBAAkB;AACpB,aAAO;AAAA,IACT;AAGA,QAAI,gBAAgB;AAClB,YAAM,cAAc,MAAM,aAAa,EAAE,OAAO,MAAMA,KAAA,GAAO,OAAO;AACpE,UAAI,aAAa;AACf,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,UAAU,MAAM,GAAG,QAAW,KAAK;AAGzC,UAAM,yBAAyBA,MAAK,SAAS,OAAO;AAGpD,QAAI,gBAAgB;AAClB,YAAM;AAAA,QACJ,EAAE,OAAO,MAAMA,KAAA;AAAA,QACf;AAAA,QACA;AAAA,QACA,YAAY,QAAQ,YAAY;AAAA,MAAA;AAAA,IAEpC;AAEA,WAAO;AAAA,EACT;AACF;AAsBO,SAAS,yBACd,IACA,SAYA;AACA,QAAM,aAAa,EAAE,GAAG,iBAAiB,GAAG,QAAA;AAO5C,KAAG,gBAAgB,SAA6C,QAAoB;AAClF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,CAAC,eAAe,GAAG,OAAO,UAAU;AAAA,MACpC;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAGA,KAAG,yBAAyB,SAC1B,QACA,UACA;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,CAAC,eAAe,GAAG,OAAO,UAAU;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAGA,KAAG,wBAAwB,SAA6C,QAAoB;AAC1F,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,CAAC,eAAe,GAAG,eAAe,UAAU;AAAA,MAC5C;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAGA,KAAG,iCAAiC,SAClC,QACA,UACA;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,CAAC,eAAe,GAAG,eAAe,UAAU;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAiBA,KAAG,aAAa,SACdE,QAqBA;AACA,WAAO,GAAG,cAAcoB,WAAAA,gBAAgBpB,MAAK,CAAC,EAAE,KAAKA,MAAK;AAAA,EAuB5D;AAcA,KAAG,sBAAsB,SACvBA,QACA,UAqBA;AACA,WAAO,GACJ,uBAAuBoB,2BAAgBpB,MAAK,GAAG,QAAQ,EACvD,KAAKA,MAAK;AAAA,EAuBf;AAaA,KAAG,qBAAqB,SACtBA,QAqBA;AACA,WAAO,GACJ,sBAAsBoB,WAAAA,gBAAgBpB,MAAK,CAAC,EAC5C,KAAKA,MAAK;AAAA,EAuBf;AAcA,KAAG,8BAA8B,SAC/BA,QACA,UAqBA;AACA,WAAO,GACJ,+BAA+BoB,2BAAgBpB,MAAK,GAAG,QAAQ,EAC/D,KAAKA,MAAK;AAAA,EAuBf;AAOA,KAAG,yBAAyB,SAAqCA,QAAe;AAC9E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,KAAK;AAAA,EAChE;AAGA,KAAG,sBAAsB,SAAqCA,QAAe;AAC3E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,IAAI;AAAA,EAC/D;AAGA,KAAG,yBAAyB,SAAqCA,QAAe;AAC9E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,KAAK;AAAA,EAChE;AAGA,KAAG,sBAAsB,SAAqCA,QAAe;AAC3E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,IAAI;AAAA,EAC/D;AAGA,KAAG,yBAAyB,SAAqCA,QAAe;AAC9E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,KAAK;AAAA,EAChE;AAGA,KAAG,sBAAsB,SAAqCA,QAAe;AAC3E,WAAO,2BAA2B,IAAIA,QAAO,YAAY,IAAI;AAAA,EAC/D;AAsBA,KAAG,eAAe,uBAAuB,IAAI,YAAY,KAAK;AAoB9D,KAAG,wBAAwB,uBAAuB,IAAI,YAAY,IAAI;AAEtE,SAAO;AACT;ACh6BO,MAAM,yBAA0D;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,YAAY,iBAAoC;AAC9C,SAAK,kBAAkB;AACvB,SAAK,iCAAiC,KAAK,+BAA+B,KAAK,IAAI;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,OAAe,YAAqD;AACnF,UAAM,UAAU,MAAM,KAAK,gBACxB,MAAA,EACA,cAA8B,WAAW,KAAK,IAAI,UAA2B;AAChF,WAAO,QAAQ,IAAI,CAAC,SAAS;AAAA,MAC3B,IAAI,IAAI;AAAA,MACR,SAAS,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,MACb,MAAM,IAAI;AAAA,MACV,cAAc,IAAI,eAAe;AAAA,MACjC,eAAe,IAAI,gBAAgB;AAAA,MACnC,cAAc,IAAI,eAAe;AAAA,MACjC,QAAQ,IAAI;AAAA,MACZ,MAAM,IAAI;AAAA,IAAA,EACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,OAA6D;AACzE,UAAM,EAAE,KAAAF,MAAK,WAAW,MAAM,MAAA;AAC9B,WAAO,KAAK,WAAWA,MAAK,MAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBAAkB,OAAe,YAAqD;AAC1F,UAAM,UAAU,MAAM,KAAK,gBACxB,MAAA,EACA,cAA8B,mBAAmB,KAAK,IAAI,UAA2B;AACxF,WAAO,QAAQ,IAAI,CAAC,SAAS;AAAA,MAC3B,IAAI,IAAI;AAAA,MACR,SAAS,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,MACb,MAAM,IAAI;AAAA,MACV,cAAc,IAAI,eAAe;AAAA,MACjC,eAAe,IAAI,gBAAgB;AAAA,MACnC,cAAc,IAAI,eAAe;AAAA,MACjC,QAAQ,IAAI;AAAA,MACZ,MAAM,IAAI;AAAA,IAAA,EACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,OAA6D;AAChF,UAAM,EAAE,KAAAA,MAAK,WAAW,MAAM,MAAA;AAC9B,WAAO,KAAK,kBAAkBA,MAAK,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,OAAoC;AAC9C,QAAI,CAAC,OAAO;AACV,aAAO,CAAA;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,KAAA,EAAO,MAAM,IAAI;AACrC,QAAI,MAAM,SAAS,EAAG,QAAO,CAAA;AAE7B,UAAM,aAAa,MAAM,CAAC,EACvB,MAAM,GAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO;AACjB,UAAM,UAAU,WAAW,IAAI,CAAC,MAAM;AACpC,aAAO,EACJ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,eAAe,CAAC,GAAG,MAAO,IAAI,EAAE,YAAA,IAAgB,EAAG,EAC3D,QAAQ,MAAM,CAAC,MAAM,EAAE,aAAa;AAAA,IACzC,CAAC;AAED,WAAO,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS;AAClC,YAAM,SAAS,KACZ,MAAM,GAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO;AACjB,YAAM,MAA8B,CAAA;AACpC,cAAQ,QAAQ,CAAC,KAAK,MAAM;AAC1B,YAAI,GAAG,IAAI,OAAO,CAAC,KAAK;AAAA,MAC1B,CAAC;AACD,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,KAAwC;AACzD,WAAO;AAAA,MACL,MAAM,IAAI;AAAA,MACV,YAAY,IAAI;AAAA,MAChB,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,MACZ,IAAI,IAAI;AAAA,MACR,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,WAAW,IAAI;AAAA,MACf,aAAa,IAAI;AAAA,MACjB,cAAc,IAAI;AAAA,MAClB,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,aAAa,IAAI;AAAA,MACjB,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,aAAa,IAAI;AAAA,MACjB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,aAAa,IAAI;AAAA,MACjB,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,WAAW,IAAI;AAAA,MACf,aAAa,IAAI;AAAA,MACjB,cAAc,IAAI;AAAA,MAClB,SAAS,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,2BAA2B,IAAI;AAAA,MAC/B,uBAAuB,IAAI;AAAA,MAC3B,sBAAsB,IAAI;AAAA,MAC1B,MAAM,IAAI;AAAA,MACV,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,YAAY,KAAK,YAAY,IAAI,IAAI;AAAA,IAAA;AAAA,EAEzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,2BAA2B,QAAkB,MAAa,IAAmB;AAC3E,UAAMuB,kBAAiB,CAAC,SACtBtB,MAAAA,SAAS,WAAW,IAAI,EAAE,SAAS,2BAA2B;AAEhE,UAAM,kBAAkB,OACrB,IAAI,CAACC,WAAU,mDAAmDA,MAAK,SAAS,EAChF,KAAK,MAAM;AAEd,UAAM,iBAA2B,CAAA;AACjC,QAAI,MAAM;AACR,qBAAe,KAAK,0BAA0BqB,gBAAe,IAAI,CAAC,GAAG;AAAA,IACvE;AACA,QAAI,IAAI;AACN,qBAAe,KAAK,wBAAwBA,gBAAe,EAAE,CAAC,GAAG;AAAA,IACnE;AAEA,QAAI;AACJ,QAAI,iBAAiB,QAAQ;AAC3B,qBAAe,CAAC,kBAAkB,IAAI,eAAe,MAAM,IAAI,GAAG,cAAc;AAAA,IAClF,OAAO;AACL,qBAAe;AAAA,IACjB;AAEA,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOH,cAAc,SAAS,IAAI,SAAS,aAAa,KAAK,OAAO,CAAC,KAAK,EAAE;AAAA;AAAA,EAE3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAqD;AACzD,UAAM,UAAU,MAAM,KAAK,gBAAgB,MAAA,EAAQ,cAA4B;AAAA;AAAA;AAAA;AAAA,KAI9E;AACD,WAAO,QAAQ,IAAI,CAAC,QAAQ,KAAK,mBAAmB,GAAG,CAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,+BAA+B,OAA0D;AACvF,QAAI,CAAC,OAAO;AACV,aAAO,CAAA;AAAA,IACT;AAEA,UAAM,SAAc,CAAA;AACpB,WAAO,aAAa,KAAK,YAAY,MAAM,MAAM,KAAK,EAAE;AACxD,eAAW,OAAO,OAAO;AACvB,YAAM,WAAW,IAAI,YAAA,EAAc,QAAQ,aAAa,CAAC,GAAG,WAAW,OAAO,YAAA,CAAa;AAC3F,aAAO,QAAQ,IAAI,MAAM,GAAG;AAAA,IAC9B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,yBACJ,QACA,UACA,QACyC;AACzC,UAAM,UAAU,MAAM,KAAK,gBACxB,QACA;AAAA,MACC,KAAK,2BAA2B,UAAU,CAAA,GAAI,UAAU,MAAM;AAAA,IAAA;AAElE,WAAO,QAAQ,IAAI,CAAC,MAAM,KAAK,+BAA+B,CAAC,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,sBACJ,QACA,UACA,QACyC;AACzC,UAAM,aAAa,QAAQ,IAAI,CAACrB,YAAUiB,mBAAajB,OAAK,CAAC,KAAK,CAAA;AAClE,WAAO,KAAK,yBAAyB,YAAY,UAAU,MAAM;AAAA,EACnE;AACF;AC/bO,MAAM,wBAAiD;AAAA,EAC3C;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,YAAY,SAA6B,iBAAoC;AAC3E,SAAK,UAAU;AACf,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAAmB,QAAwC;AAC/D,QAAI,CAAC,KAAK,QAAQ,iBAAiB;AACjC,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,UAAM,KAAK,WAAW,OAAO,IAAI,CAAC,MAAMiB,MAAAA,aAAa,CAAC,CAAC,CAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,QAAiC;AAChD,QAAI,CAAC,KAAK,QAAQ,iBAAiB;AACjC,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,UAAM,iBAAiB,QAAQ,KAAK,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,OACJ,QACA,QACA,gBACiB;AACjB,SAAK,2BAAA;AACL,UAAM,SAAS,MAAM,KAAK,gBACvB,uBACA,OAAO,QAAQ,QAAQ,cAAc;AACxC,UAAM,WAAW,QAAQ,KAAK,OAAO;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,WAAoC,IAAa,QAA4B;AACjF,SAAK,2BAAA;AACL,UAAM,SAAS,MAAM,KAAK,gBAAgB,uBAAuB,WAAW,IAAI,MAAM;AACtF,UAAM,WAAW,QAAQ,KAAK,OAAO;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,WACJ,QACA,QACiB;AACjB,SAAK,2BAAA;AACL,UAAM,SAAS,MAAM,KAAK,gBAAgB,uBAAuB,WAAW,QAAQ,MAAM;AAC1F,UAAM,WAAW,QAAQ,KAAK,OAAO;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,aACJ,YACA,QACA,OACiB;AACjB,SAAK,2BAAA;AACL,UAAM,SAAS,MAAM,KAAK,gBACvB,uBACA,aAAa,YAAY,QAAQ,KAAK;AACzC,UAAM,WAAW,QAAQ,KAAK,OAAO;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,aACJ,OACA,UACqB;AACrB,SAAK,2BAAA;AACL,UAAM,WAAW;AACjB,UAAM,cAAc,MAAM,aAAyB,UAAU,KAAK,OAAO;AACzE,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AACA,UAAM,UAAU,MAAM;AACtB,UAAM,eAAe,UAAU,KAAK,SAAS,SAAS,YAAY,KAAK,QAAQ,YAAY,EAAE;AAC7F,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,6BAAmC;AACzC,QAAI,CAAC,KAAK,QAAQ,iBAAiB;AACjC,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAAA,EACF;AACF;ACjJA,MAAM,gBAA6C;AAAA,EACjD,OAAe,WAAmC;AAAA,EACjC;AAAA,EAYA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,YAAY,SAA8B;AAChD,QAAI;AACF,YAAM,aAAiC,WAAW;AAAA,QAChD,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,0BAA0B;AAAA,QAC1B,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,sBAAsB;AAAA,QACtB,2BAA2B;AAAA,QAC3B,qBAAqB;AAAA,MAAA;AAEvB,WAAK,UAAU;AACf,UAAI,WAAW,gBAAgB;AAE7B,gBAAQ,MAAM,6BAA6B;AAAA,MAC7C;AAEA,YAAM,gBAAgB;AAAA,QACpB;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,MAAA;AAEb,WAAK,UAAU;AAAA,QACbK,WAAAA,QAAQ,eAAe,EAAE,QAAQ,WAAW,gBAAgB;AAAA,QAC5D;AAAA,MAAA;AAEF,WAAK,iBAAiB,IAAI,uBAAuB,MAAM,UAAU;AACjE,WAAK,kBAAkB,IAAI,yBAAyB,UAAU;AAC9D,WAAK,oBAAoB,IAAI,yBAAyB,IAAI;AAC1D,WAAK,kBAAkB,IAAI,wBAAwB,YAAY,IAAI;AAAA,IACrE,SAAS,OAAO;AAEd,cAAQ,MAAM,sCAAsC,KAAK;AACzD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8EA,MAAM,oBACJ,OACA,YAKY;AACZ,WAAO,qBAAqB;AAAA,MAC1B;AAAA,QACE,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,+BAAe,KAAA;AAAA,QACf,aAAa;AAAA,QACb,sBAAsB,YAAY;AAChC;AAAA,QACF;AAAA,MAAA;AAAA,MAEF,YAAY;AACV,cAAM,SAAS,MAAM,MAAA;AACrB,cAAM,WAAW,MAAM,mBAAA;AACvB,YAAI;AACF,cAAI,UAAU;AACZ,kBAAM;AAAA,cACJ,SAAS;AAAA,cACT,SAAS;AAAA,cACT,SAAS;AAAA,YAAA;AAAA,UAEb;AAAA,QACF,SAAS,GAAQ;AAEf,kBAAQ;AAAA,YACN;AAAA,YACA;AAAA,cACE,cAAc,GAAG;AAAA,cACjB,YAAY,GAAG;AAAA,cACf,sBAAsB,UAAU;AAAA,cAChC,mBAAmB,UAAU;AAAA,cAC7B,WAAW,UAAU;AAAA,YAAA;AAAA,YAEvB;AAAA,UAAA;AAAA,QAEJ;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,wBAAwB,cAAkD;AACxE,WAAO,KAAK,sCAA4C,YAAY;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,sCAAyC,cAA4C;AACzF,WAAO,MAAM,KAAK;AAAA,MAChB,YACE,MAAM,wBAAwB;AAAA,QAC5B,wBAAwB,SAAA,KAAc,EAAE,QAAQ,oBAAI,MAAY;AAAA,QAChE,YAAY;AACV,cAAI;AACF,mBAAO,MAAM,aAAA;AAAA,UACf,UAAA;AACE,kBAAM;AAAA,cACJ,MAAM,KAAK,wBAAwB,YAAY,UAAU,CAAA,CAAE;AAAA,cAC3D,KAAK;AAAA,YAAA;AAAA,UAET;AAAA,QACF;AAAA,MAAA;AAAA,IACF;AAAA,EAEN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,2CAA8C,cAA4C;AAC9F,WAAO,MAAM,6BAA6B;AAAA,MACxC,6BAA6B,SAAA,KAAc,EAAE,OAAO,CAAA,EAAC;AAAA,MACrD,YAAY;AACV,eAAO,MAAM,aAAA;AAAA,MACf;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,wBAAwB,cAAkD;AACxE,WAAO,KAAK,2CAAiD,YAAY;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OACEtB,QACoF;AACpF,WAAO,KAAK,QAAQ,uBAAuBA,MAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,oBACEA,QACoF;AACpF,WAAO,KAAK,QAAQ,oBAAoBA,MAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBACEA,QACoF;AACpF,WAAO,KAAK,QAAQ,oBAAoBA,MAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OACEA,QACoF;AACpF,WAAO,KAAK,QAAQ,uBAAuBA,MAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OACEA,QACiF;AACjF,WAAO,KAAK,QAAQ,uBAAuBA,MAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,oBACEA,QACiF;AACjF,WAAO,KAAK,QAAQ,oBAAoBA,MAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAsD;AACpD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,YAAY,SAAiD;AAClE,oBAAgB,aAAa,IAAI,gBAAgB,OAAO;AACxD,WAAO,gBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAA2B;AACzB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,oCAA6D;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,yBAWE;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OACE,QAC6D;AAC7D,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AACA,WAAO,KAAK,QAAQ,cAAc,MAAM;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,eACE,QAC6D;AAC7D,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AACA,WAAO,KAAK,QAAQ,sBAAsB,MAAM;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,gBACE,QACA,UAC6D;AAC7D,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AACA,WAAO,KAAK,QAAQ,uBAAuB,QAAQ,QAAQ;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,wBACE,QACA,UAC6D;AAC7D,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AACA,WAAO,KAAK,QAAQ,+BAA+B,QAAQ,QAAQ;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAiCA,QAAU;AACzC,WAAO,KAAK,QAAQ,WAAWA,MAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,mBAAyCA,QAAU;AACjD,WAAO,KAAK,QAAQ,mBAAmBA,MAAK;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,oBAA0CA,QAAU,UAAmB;AACrE,WAAO,KAAK,QAAQ,oBAAoBA,QAAO,QAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,4BAAkDA,QAAU,UAAmB;AAC7E,WAAO,KAAK,QAAQ,4BAA4BA,QAAO,QAAQ;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,QAAW,OAA4B;AACrC,WAAO,KAAK,QAAQ,aAAgB,KAAK;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCA,MAAM,WAAc,OAA4B;AAC9C,WAAO,KAAK,kBAAkB,YAAY,KAAK,QAAQ,aAAgB,KAAK,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoDA,MAAM,kBAAqB,SAAuC;AAChE,WAAO,0BAA0B,IAAI,EAAE,eAAe,SAAS,YAAY,SAAS;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,iBACE,OACA,UAC6D;AAC7D,WAAO,KAAK,QAAQ,sBAAyB,OAAO,QAAQ;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,IAAI,QAAQ;AACV,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,QAAQ,SAAyB;AAC/B,WAAO,KAAK,QAAQ,KAAK,GAAG,OAAO;AAAA,EACrC;AACF;AAMA,MAAM,YAAyC;AAAA,EAC5B;AAAA,EAEjB,YAAY,SAA8B;AACxC,SAAK,cAAc,gBAAgB,YAAY,OAAO;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8EA,MAAM,oBACJ,OACA,YAKY;AACZ,WAAO,KAAK,YAAY,oBAAoB,OAAO,UAAU;AAAA,EAC/D;AAAA,EAEA,gBACE,QACA,UAC6D;AAC7D,WAAO,KAAK,YAAY,gBAAgB,QAAQ,QAAQ;AAAA,EAC1D;AAAA,EAEA,wBACE,QACA,UAC6D;AAC7D,WAAO,KAAK,YAAY,wBAAwB,QAAQ,QAAQ;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAiCA,QAAU;AACzC,WAAO,KAAK,YAAY,uBAAA,EAAyB,WAAWA,MAAK;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,mBAAyCA,QAAU;AACjD,WAAO,KAAK,YAAY,uBAAA,EAAyB,mBAAmBA,MAAK;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,oBAA0CA,QAAU,UAAmB;AACrE,WAAO,KAAK,YAAY,uBAAA,EAAyB,oBAAoBA,QAAO,QAAQ;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,4BAAkDA,QAAU,UAAmB;AAC7E,WAAO,KAAK,YAAY,uBAAA,EAAyB,4BAA4BA,QAAO,QAAQ;AAAA,EAC9F;AAAA,EAEA,wBAAwB,cAAkD;AACxE,WAAO,KAAK,YAAY,wBAAwB,YAAY;AAAA,EAC9D;AAAA,EACA,sCAAyC,cAA4C;AACnF,WAAO,KAAK,YAAY,sCAAsC,YAAY;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,wBAAwB,cAAkD;AACxE,WAAO,KAAK,YAAY,wBAAwB,YAAY;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,2CAA8C,cAA4C;AACxF,WAAO,KAAK,YAAY,2CAA2C,YAAY;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OACEA,QACoF;AACpF,WAAO,KAAK,YAAY,OAAOA,MAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBACEA,QACoF;AACpF,WAAO,KAAK,YAAY,oBAAoBA,MAAK;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OACEA,QACoF;AACpF,WAAO,KAAK,YAAY,OAAOA,MAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBACEA,QACoF;AACpF,WAAO,KAAK,YAAY,oBAAoBA,MAAK;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OACEA,QACiF;AACjF,WAAO,KAAK,YAAY,OAAOA,MAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBACEA,QACiF;AACjF,WAAO,KAAK,YAAY,oBAAoBA,MAAK;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OACE,QAC6D;AAC7D,WAAO,KAAK,YAAY,OAAO,MAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,eACE,QAC6D;AAC7D,WAAO,KAAK,YAAY,eAAe,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAsD;AACpD,WAAO,KAAK,YAAY,qBAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAA2B;AACzB,WAAO,KAAK,YAAY,MAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAiC;AAC/B,WAAO,KAAK,YAAY,QAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oCAA6D;AAC3D,WAAO,KAAK,YAAY,kCAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyB;AACvB,WAAO,KAAK,YAAY,uBAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,QACE,OAC6D;AAC7D,WAAO,KAAK,YAAY,QAAQ,KAAK;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCA,WAAW,OAA4B;AACrC,WAAO,KAAK,YAAY,WAAW,KAAK;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoDA,kBAAqB,SAAuC;AAC1D,WAAO,KAAK,YAAY,kBAAkB,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,iBACE,OACA,UAC6D;AAC7D,WAAO,KAAK,YAAY,iBAAiB,OAAO,QAAQ;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,IAAI,QAAQ;AACV,WAAO,KAAK,YAAY,uBAAA,EAAyB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,QAAQ,SAAyB;AAC/B,WAAO,KAAK,YAAY,uBAAA,EAAyB,KAAK,GAAG,OAAO;AAAA,EAClE;AACF;AClTO,MAAM,sBAAsBuB,UAAAA,WAIhC;AAAA,EACD,WAAW;AACT,WAAO;AAAA,EACT;AAAA,EACA,SAAS,OAAa;AACpB,WAAO,eAAe,OAAO,6BAA6B,KAAK;AAAA,EACjE;AAAA,EACA,WAAW,OAAgB;AACzB,UAAM,SAAS;AACf,WAAO,cAAc,OAAiB,MAAM;AAAA,EAC9C;AACF,CAAC;AAQM,MAAM,uBAAuBA,UAAAA,WAIjC;AAAA,EACD,WAAW;AACT,WAAO;AAAA,EACT;AAAA,EACA,SAAS,OAAa;AACpB,WAAO,eAAe,OAAO,6BAA6B,IAAI;AAAA,EAChE;AAAA,EACA,WAAW,OAAgB;AACzB,UAAM,SAAS;AACf,WAAO,cAAc,OAAiB,MAAM;AAAA,EAC9C;AACF,CAAC;AAQM,MAAM,kBAAkBA,UAAAA,WAI5B;AAAA,EACD,WAAW;AACT,WAAO;AAAA,EACT;AAAA,EACA,SAAS,OAAa;AACpB,WAAO,eAAe,OAAO,cAAc,KAAK;AAAA,EAClD;AAAA,EACA,WAAW,OAAgB;AACzB,UAAM,SAAS;AACf,WAAO,cAAc,OAAiB,MAAM;AAAA,EAC9C;AACF,CAAC;AAQM,MAAM,kBAAkBA,UAAAA,WAI5B;AAAA,EACD,WAAW;AACT,WAAO;AAAA,EACT;AAAA,EACA,SAAS,OAAa;AACpB,WAAO,eAAe,OAAO,gBAAgB,KAAK;AAAA,EACpD;AAAA,EACA,WAAW,OAAgB;AACzB,WAAO,cAAc,OAAiB,cAAc;AAAA,EACtD;AACF,CAAC;ACrnCD,eAAsB,uBAAyD;AAC7E,MAAI;AACF,UAAM,SAAS,MAAM,UAAA;AAErB,UAAM,iBAAiBC,4BAAmB,QAAQ,EAAE,UAAU,MAAM,OAAO,MAAM;AAGjF,eAAW,aAAa,gBAAgB;AAEtC,cAAQ,MAAM,gBAAgB,SAAS,EAAE;AACzC,YAAM1B,IAAAA,IAAI,WAAW,SAAS;AAAA,IAChC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ,SAAS,OAAY;AACnB,UAAM,eACJ,OAAO,OAAO,cACd,OAAO,OAAO,WACd,MAAM,WACN;AAEF,YAAQ,MAAM,YAAY;AAC1B,WAAO,gBAAwB,KAAK,YAAY;AAAA,EAClD;AACF;AC7BO,MAAM,wBAAwB,OACnC,cACG;AACH,MAAI;AACF,QAAI,OAAO,cAAc,YAAY;AACnC,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AAEA,YAAQ,MAAM,2BAA2B;AACzC,UAAMA,IAAAA,IAAI,WAAA;AAEV,YAAQ,MAAM,2BAA2B;AACzC,UAAM2B,cAAa,MAAM,UAAUC,mBAAe;AAClD,UAAM,uBAAuB,MAAMD,YAAW,IAAA;AAE9C,YAAQ,MAAM,uBAAuB,oBAAoB;AAEzD,UAAM,gBAAgB,MAAMC,IAAAA,gBAAgB,KAAA;AAC5C,QAAI,mBAAmB;AAEvB,QAAI,MAAM,QAAQ,aAAa,KAAK,cAAc,SAAS,GAAG;AAC5D,YAAM,mBAAmB,cAAc;AAAA,QACrC,CAAC,GAAG,MAAM,EAAE,WAAW,YAAY,EAAE,WAAW,QAAA;AAAA,MAAQ;AAG1D,yBAAmB,iBAChB,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,WAAW,YAAA,CAAa,EAAE,EAC9D,KAAK,IAAI;AAAA,IACd;AAEA,YAAQ,MAAM,gDAAgD,gBAAgB;AAE9E,WAAO;AAAA,MACL,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,EAAA;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,MAAM;AAAA,IAAA;AAAA,EAEV,SAAS,OAAY;AACnB,UAAM,eACJ,OAAO,OAAO,SAAS,OAAO,cAC9B,OAAO,OAAO,SAAS,OAAO,WAC9B,OAAO,OAAO,SAAS,cACvB,OAAO,OAAO,SAAS,WACvB,MAAM,WACN;AAEF,YAAQ,MAAM,2BAA2B,YAAY;AACrD,WAAO;AAAA,MACL,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,EAAA;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,MAAM,iBAAiB,QAAQ,eAAe;AAAA,IAAA;AAAA,EAElD;AACF;AC9CA,eAAsB,wBAA0D;AAC9E,MAAI;AACF,UAAM,SAAS,MAAM,UAAA;AACrB,UAAM,wBAAwB,MAAM,8BAA8B,MAAM;AACxE,UAAM,gBAAgB,yBAAyB,qBAAqB;AAEpE,WAAO,gBAAwB,KAAK,cAAc,KAAK,KAAK,CAAC;AAAA,EAC/D,SAAS,OAAY;AACnB,UAAM,eACJ,OAAO,OAAO,cACd,OAAO,OAAO,WACd,MAAM,WACN;AAEF,YAAQ,MAAM,YAAY;AAC1B,WAAO,gBAAwB,KAAK,YAAY;AAAA,EAClD;AACF;AAKA,eAAe,8BAA8B,QAAqC;AAChF,QAAM,aAAuB,CAAA;AAE7B,aAAW1B,UAAS,QAAQ;AAC1B,UAAM,oBAAoB,MAAMF,QAAI,WAA2B,sBAAsBE,MAAK,GAAG;AAE7F,UAAM,wBAAwB,kBAAkB,KAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,IAAI,KAAK,CAAC,EACzC,IAAI,CAAC,QAAQ,2BAA2B,IAAI,cAAc,CAAC,CAAC;AAE/D,eAAW,KAAK,GAAG,qBAAqB;AAAA,EAC1C;AAEA,SAAO;AACT;AAKA,SAAS,cAAc,WAA4B;AACjD,SAAO,kBAAkB,KAAK,CAAC,OAAOiB,MAAAA,aAAa,EAAE,MAAM,SAAS;AACtE;AAKA,SAAS,2BAA2B,WAA2B;AAC7D,SAAO,UAAU,QAAQ,MAAM,EAAE,EAAE,QAAQ,gBAAgB,4BAA4B;AACzF;AAKA,SAAS,yBAAyB,YAAgC;AAChE,SAAO,CAAC,8BAA8B,GAAG,YAAY,4BAA4B;AACnF;AChEA,eAAsB,4BAA8D;AAClF,MAAI;AACF,UAAM,SAAS,MAAM,UAAA;AAErB,UAAM,iBAAiBO,4BAAmB,QAAQ,EAAE,UAAU,OAAO,OAAO,MAAM;AAGlF,eAAW,aAAa,gBAAgB;AAEtC,cAAQ,MAAM,gBAAgB,SAAS,EAAE;AACzC,YAAM1B,IAAAA,IAAI,WAAW,SAAS;AAAA,IAChC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ,SAAS,OAAY;AACnB,UAAM,eACJ,OAAO,OAAO,cACd,OAAO,OAAO,WACd,MAAM,WACN;AAEF,YAAQ,MAAM,YAAY;AAC1B,WAAO,gBAAwB,KAAK,YAAY;AAAA,EAClD;AACF;AChBO,MAAM,6BAA6B,OAAO,YAAiC;AAChF,MAAI;AACF,UAAM,aAAiC,WAAW;AAAA,MAChD,gBAAgB;AAAA,MAChB,0BAA0B;AAAA,MAC1B,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,sBAAsB;AAAA,MACtB,2BAA2B;AAAA,MAC3B,qBAAqB;AAAA,IAAA;AAEvB,QAAI,CAAC,WAAW,iBAAiB;AAC/B,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,UAAM,kBAAkB,UAAU;AAElC,WAAO;AAAA,MACL,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,EAAA;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MAAY,CACnC;AAAA,IAAA;AAAA,EAEL,SAAS,OAAO;AAEd,YAAQ,MAAM,gCAAgC,KAAK,UAAU,KAAK,CAAC;AACnE,WAAO;AAAA,MACL,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,EAAA;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAChD,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MAAY,CACnC;AAAA,IAAA;AAAA,EAEL;AACF;ACfA,eAAsB,0BACpB,aACA,SAIkC;AAClC,MAAI;AACF,WAAO;AAAA,MACL;AAAA,MACA,KAAK;AAAA,QACH,MAAM,kBAAkB,aAAa,SAAS,SAAS,GAAG,SAAS,WAAW,GAAI;AAAA,MAAA;AAAA,IACpF;AAAA,EAEJ,SAAS,OAAY;AACnB,UAAM,eACJ,OAAO,OAAO,cACd,OAAO,OAAO,WACd,MAAM,WACN;AAEF,YAAQ,MAAM,YAAY;AAC1B,WAAO,gBAAwB,KAAK,YAAY;AAAA,EAClD;AACF;AC1EO,MAAM,kBAAkB,CAAO,YAAoB,SAAsC;AAC9F,MAAI,aAAa;AACjB,MAAI,eAAe,KAAK;AACtB,iBAAa;AAAA,EACf,OAAO;AACL,iBAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,EAAA;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|