@ahmadmoussawi/webdb 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +386 -2
  2. package/dist/constants.d.ts +18 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/core/index.d.ts +15 -0
  5. package/dist/core/index.d.ts.map +1 -0
  6. package/dist/core/js/buffer_pool.c.d.ts +142 -0
  7. package/dist/core/js/buffer_pool.c.d.ts.map +1 -0
  8. package/dist/core/js/catalog.c.d.ts +186 -0
  9. package/dist/core/js/catalog.c.d.ts.map +1 -0
  10. package/dist/core/js/codecs.c.d.ts +32 -0
  11. package/dist/core/js/codecs.c.d.ts.map +1 -0
  12. package/dist/core/js/index.d.ts +7 -0
  13. package/dist/core/js/index.d.ts.map +1 -0
  14. package/dist/core/js/page.c.d.ts +229 -0
  15. package/dist/core/js/page.c.d.ts.map +1 -0
  16. package/dist/core/js/page_table.c.d.ts +48 -0
  17. package/dist/core/js/page_table.c.d.ts.map +1 -0
  18. package/dist/core/js/vm.c.d.ts +11 -0
  19. package/dist/core/js/vm.c.d.ts.map +1 -0
  20. package/dist/core/js/vm.helpers.c.d.ts +124 -0
  21. package/dist/core/js/vm.helpers.c.d.ts.map +1 -0
  22. package/dist/core/types.d.ts +26 -0
  23. package/dist/core/types.d.ts.map +1 -0
  24. package/dist/core/wasm/embedded_wasm.d.ts +7 -0
  25. package/dist/core/wasm/embedded_wasm.d.ts.map +1 -0
  26. package/dist/core/wasm/wasm_core.d.ts +75 -0
  27. package/dist/core/wasm/wasm_core.d.ts.map +1 -0
  28. package/dist/host/api/index.d.ts +3 -0
  29. package/dist/host/api/index.d.ts.map +1 -0
  30. package/dist/host/api/query_builder.d.ts +216 -0
  31. package/dist/host/api/query_builder.d.ts.map +1 -0
  32. package/dist/host/api/webdb.d.ts +172 -0
  33. package/dist/host/api/webdb.d.ts.map +1 -0
  34. package/dist/host/compiler/compiler.d.ts +151 -0
  35. package/dist/host/compiler/compiler.d.ts.map +1 -0
  36. package/dist/host/compiler/expr_parser.d.ts +87 -0
  37. package/dist/host/compiler/expr_parser.d.ts.map +1 -0
  38. package/dist/host/compiler/index.d.ts +4 -0
  39. package/dist/host/compiler/index.d.ts.map +1 -0
  40. package/dist/host/compiler/planner/cost.d.ts +23 -0
  41. package/dist/host/compiler/planner/cost.d.ts.map +1 -0
  42. package/dist/host/compiler/planner/custom_order.d.ts +16 -0
  43. package/dist/host/compiler/planner/custom_order.d.ts.map +1 -0
  44. package/dist/host/compiler/planner/heuristic.d.ts +11 -0
  45. package/dist/host/compiler/planner/heuristic.d.ts.map +1 -0
  46. package/dist/host/compiler/planner/index.d.ts +34 -0
  47. package/dist/host/compiler/planner/index.d.ts.map +1 -0
  48. package/dist/host/compiler/planner/noop.d.ts +11 -0
  49. package/dist/host/compiler/planner/noop.d.ts.map +1 -0
  50. package/dist/host/compiler/planner/types.d.ts +100 -0
  51. package/dist/host/compiler/planner/types.d.ts.map +1 -0
  52. package/dist/host/compiler/planner/where_optimizer.d.ts +30 -0
  53. package/dist/host/compiler/planner/where_optimizer.d.ts.map +1 -0
  54. package/dist/host/compiler/planner.d.ts +2 -0
  55. package/dist/host/compiler/planner.d.ts.map +1 -0
  56. package/dist/host/driver/buffer_pool_driver.d.ts +94 -0
  57. package/dist/host/driver/buffer_pool_driver.d.ts.map +1 -0
  58. package/dist/host/driver/crash_recovery.d.ts +24 -0
  59. package/dist/host/driver/crash_recovery.d.ts.map +1 -0
  60. package/dist/host/driver/index.d.ts +4 -0
  61. package/dist/host/driver/index.d.ts.map +1 -0
  62. package/dist/host/driver/transaction_coordinator.d.ts +166 -0
  63. package/dist/host/driver/transaction_coordinator.d.ts.map +1 -0
  64. package/dist/host/storage/crc32.d.ts +24 -0
  65. package/dist/host/storage/crc32.d.ts.map +1 -0
  66. package/dist/host/storage/idb.d.ts +27 -0
  67. package/dist/host/storage/idb.d.ts.map +1 -0
  68. package/dist/host/storage/index.d.ts +8 -0
  69. package/dist/host/storage/index.d.ts.map +1 -0
  70. package/dist/host/storage/io.d.ts +60 -0
  71. package/dist/host/storage/io.d.ts.map +1 -0
  72. package/dist/host/storage/memory.d.ts +28 -0
  73. package/dist/host/storage/memory.d.ts.map +1 -0
  74. package/dist/host/storage/opfs.d.ts +31 -0
  75. package/dist/host/storage/opfs.d.ts.map +1 -0
  76. package/dist/host/storage/vfs.d.ts +36 -0
  77. package/dist/host/storage/vfs.d.ts.map +1 -0
  78. package/dist/host/storage/wal_codec.d.ts +56 -0
  79. package/dist/host/storage/wal_codec.d.ts.map +1 -0
  80. package/dist/index.d.ts +9 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/layouts/index.d.ts +5 -0
  83. package/dist/layouts/index.d.ts.map +1 -0
  84. package/dist/layouts/page_format.d.ts +163 -0
  85. package/dist/layouts/page_format.d.ts.map +1 -0
  86. package/dist/layouts/pool_format.d.ts +126 -0
  87. package/dist/layouts/pool_format.d.ts.map +1 -0
  88. package/dist/layouts/syspage_format.d.ts +499 -0
  89. package/dist/layouts/syspage_format.d.ts.map +1 -0
  90. package/dist/layouts/wal_format.d.ts +197 -0
  91. package/dist/layouts/wal_format.d.ts.map +1 -0
  92. package/dist/shared/c_runtime.d.ts +47 -0
  93. package/dist/shared/c_runtime.d.ts.map +1 -0
  94. package/dist/shared/index.d.ts +4 -0
  95. package/dist/shared/index.d.ts.map +1 -0
  96. package/dist/shared/page_provider.d.ts +12 -0
  97. package/dist/shared/page_provider.d.ts.map +1 -0
  98. package/dist/shared/vm_context.d.ts +73 -0
  99. package/dist/shared/vm_context.d.ts.map +1 -0
  100. package/dist/types/index.d.ts +338 -0
  101. package/dist/types/index.d.ts.map +1 -0
  102. package/dist/webdb.js +13059 -0
  103. package/dist/webdb.js.map +1 -0
  104. package/dist/webdb.umd.cjs +5 -0
  105. package/dist/webdb.umd.cjs.map +1 -0
  106. package/package.json +82 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdb.umd.cjs","sources":["../src/layouts/page_format.ts","../src/layouts/syspage_format.ts","../src/layouts/pool_format.ts","../src/layouts/wal_format.ts","../src/constants.ts","../src/shared/vm_context.ts","../src/types/index.ts","../src/host/storage/memory.ts","../src/host/storage/idb.ts","../src/host/storage/opfs.ts","../src/host/storage/crc32.ts","../src/shared/c_runtime.ts","../src/host/storage/io.ts","../src/host/storage/wal_codec.ts","../src/core/js/codecs.c.ts","../src/core/js/page.c.ts","../src/core/js/page_table.c.ts","../src/core/js/buffer_pool.c.ts","../src/core/js/vm.helpers.c.ts","../src/core/js/vm.c.ts","../src/core/js/catalog.c.ts","../src/core/wasm/embedded_wasm.ts","../src/core/wasm/wasm_core.ts","../src/host/driver/buffer_pool_driver.ts","../src/host/driver/crash_recovery.ts","../src/host/driver/transaction_coordinator.ts","../src/host/compiler/expr_parser.ts","../src/host/compiler/planner/types.ts","../src/host/compiler/planner/where_optimizer.ts","../src/host/compiler/planner/cost.ts","../src/host/compiler/planner/heuristic.ts","../src/host/compiler/planner/noop.ts","../src/host/compiler/planner/custom_order.ts","../src/host/compiler/planner/index.ts","../src/host/compiler/compiler.ts","../src/host/api/query_builder.ts","../src/host/api/webdb.ts"],"sourcesContent":["/**\n * AUTO-GENERATED AT BUILD TIME FROM src/layouts/schemas/page_format.json\n * DO NOT EDIT MANUALLY. Run 'npm run generate:layouts' to rebuild.\n */\n\n/**\n * ============================================================================\n * CRITICAL WARNING: FROZEN ON-DISK PAGE FORMAT SPECIFICATION\n * DO NOT alter the order, types, or byte lengths of existing fields in this\n * layout! Changing any field offset will invalidate existing binary databases,\n * break cross-version read compatibility, and result in unrecoverable data\n * corruption.\n *\n * Any future extensions MUST use designated reserved bytes or bump\n * CURRENT_ENGINE_VERSION and CURRENT_MIN_READ_VERSION.\n * ============================================================================\n */\n\n/**\n * Standard uniform page size in bytes across the entire database engine (4 KB).\n * Every page in the database file and buffer pool is rigidly aligned to this size.\n */\nexport const PAGE_SIZE = 4096;\n\n/**\n * Strict maximum size in bytes allowed for a single serialized row record (2 KB).\n * Enforces the B-tree invariant that at least two rows fit on a leaf data page\n * without requiring overflow chaining in the v1 engine.\n */\nexport const MAX_ROW_SIZE = 2048;\n\n// ============================================================================\n// 1. SLOTTED PAGE HEADER Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for SLOTTED_PAGE_HEADER:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | TYPE (1B) | FLAGS (1B) | CELL_COUNT (2B) |\n * +-----------------+-----------------+-----------------------------------+\n * | CONTENT_OFFSET (2B) | NEXT_PAGE_ID [0..1] |\n * +-----------------------------------+-----------------------------------+\n * | NEXT_PAGE_ID [2..3] | FREE_BYTES (2B) |\n * +-----------------------------------+-----------------------------------+\n * | CHECKSUM (4B) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+----------------+----------+----------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+----------------+----------+----------------------------------------------+\n * | 0 | 1B | TYPE | uint8_t | Identifies the page structure and role. |\n * | 1 | 1B | FLAGS | uint8_t | Flags and reserved attributes for this page. |\n * | 2 | 2B | CELL_COUNT | uint16_t | Number of active records/cells |\n * | 4 | 2B | CONTENT_OFFSET | uint16_t | Byte offset pointing to the start |\n * | 6 | 4B | NEXT_PAGE_ID | uint32_t | Multifunctional 32-bit pointer: |\n * | 10 | 2B | FREE_BYTES | uint16_t | Cumulative count of fragmented |\n * | 12 | 4B | CHECKSUM | uint32_t | IEEE 802.3 CRC32 checksum computed |\n * +--------+------+----------------+----------+----------------------------------------------+\n * | Total: 16 Bytes |\n * +------------------------------------------------------------------------------------------+\n */\n/**\n * Ordered sequence of fields composing the 16-byte header of all standard\n * data and interior pages (pages 2+).\n * Defined as an immutable array of `[fieldName, byteSize]` tuples to guarantee\n * strict byte ordering across all JavaScript/TypeScript runtime engines.\n */\nexport const SLOTTED_PAGE_HEADER_FIELDS = [\n [\"TYPE\", 1], // uint8_t\n [\"FLAGS\", 1], // uint8_t\n [\"CELL_COUNT\", 2], // uint16_t\n [\"CONTENT_OFFSET\", 2], // uint16_t\n [\"NEXT_PAGE_ID\", 4], // uint32_t\n [\"FREE_BYTES\", 2], // uint16_t\n [\"CHECKSUM\", 4], // uint32_t\n] as const;\n\n/**\n * Total size in bytes of the standard slotted page header (16 bytes).\n */\nexport const PAGE_HEADER_SIZE = 16;\n\n// Offsets for SLOTTED_PAGE_HEADER\n/**\n * Byte offset 0 (uint8_t): Identifies the page structure and role.\n * Valid types:\n * - `0x00` (PAGE_TYPE_FREE): Free/recycled page on the free list.\n * - `0x02` (PAGE_TYPE_INDEX_INTERIOR): B-tree index interior node.\n * - `0x05` (PAGE_TYPE_TABLE_INTERIOR): B-tree table interior routing node.\n * - `0x0A` (PAGE_TYPE_INDEX_LEAF): B-tree index leaf node.\n * - `0x0C` (PAGE_TYPE_CATALOG_PAGE): Dedicated column catalog page.\n * - `0x0D` (PAGE_TYPE_LEAF_DATA): Table leaf data page storing rows.\n */\nexport const PAGE_HEADER_OFFSET_TYPE = 0;\n\n/**\n * Byte offset 1 (uint8_t): Flags and reserved attributes for this page.\n * Initialized to `0x00` in v1.\n */\nexport const PAGE_HEADER_OFFSET_FLAGS = 1;\n\n/**\n * Byte offset 2 (uint16_t, little-endian): Number of active records/cells\n * stored on this page. Also specifies the count of 2-byte slot directory entries.\n */\nexport const PAGE_HEADER_OFFSET_CELL_COUNT = 2;\n\n/**\n * Byte offset 4 (uint16_t, little-endian): Byte offset pointing to the start\n * of the lower cell payload boundary. Payloads are allocated from byte 4096\n * growing upwards toward the slot directory. An empty page has this set to 4096.\n */\nexport const PAGE_HEADER_OFFSET_CONTENT_OFFSET = 4;\n\n/**\n * Byte offset 6 (uint32_t, little-endian): Multifunctional 32-bit pointer:\n * - Table Leaf Data (0x0D): Forward sibling pointer (`next_page_id`) linking data pages.\n * - Table Interior (0x05): Rightmost child pointer (`right_child_page_id`).\n * - Free Page (0x00): Next pageId on the free list chain (`next_free_page_id`).\n */\nexport const PAGE_HEADER_OFFSET_NEXT_PAGE_ID = 6;\n\n/**\n * Byte offset 10 (uint16_t, little-endian): Cumulative count of fragmented\n * unallocated bytes left behind by deleted or shrunk records. This space is\n * reclaimed when page defragmentation (`page_compact`) is invoked.\n */\nexport const PAGE_HEADER_OFFSET_FREE_BYTES = 10;\n\n/**\n * Byte offset 12 (uint32_t, little-endian): IEEE 802.3 CRC32 checksum computed\n * over the entire 4KB page (with bytes 12..15 zeroed during calculation) to detect\n * torn writes or on-disk storage corruption.\n */\nexport const PAGE_HEADER_OFFSET_CHECKSUM = 12;\n\n// ============================================================================\n// 2. TABLE INTERIOR CELL Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for TABLE_INTERIOR_CELL:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | CHILD_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | Bytes 4..11 (8B): ROWID (int64_t) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+---------------+----------+-------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+---------------+----------+-------------+\n * | 0 | 4B | CHILD_PAGE_ID | uint32_t | |\n * | 4 | 8B | ROWID | int64_t | |\n * +--------+------+---------------+----------+-------------+\n * | Total: 12 Bytes |\n * +--------------------------------------------------------+\n */\n/**\n * Ordered sequence of fields composing a single 12-byte routing cell in a\n * Table Interior B-tree node (`page_type = 0x05`).\n */\nexport const TABLE_INTERIOR_CELL_FIELDS = [\n [\"CHILD_PAGE_ID\", 4], // uint32_t\n [\"ROWID\", 8], // int64_t\n] as const;\n\n/**\n * Total size in bytes of a single table interior cell (12 bytes).\n * Composed of a 4-byte child `page_id` and an 8-byte signed `rowid` separator key.\n */\nexport const TABLE_INTERIOR_CELL_SIZE = 12;\n\n// Offsets for TABLE_INTERIOR_CELL\n/**\n * Byte offset 0 within an interior cell (uint32_t, little-endian):\n * The `page_id` of the child subtree containing keys less than or equal to `rowid`.\n */\nexport const TABLE_INTERIOR_CELL_OFFSET_CHILD_PAGE_ID = 0;\n\n/**\n * Byte offset 4 within an interior cell (int64_t, little-endian):\n * The separator `rowid` key. Keys $\\le \\text{rowid}$ route to `child_page_id`;\n * keys $> \\text{rowid}$ continue searching to the right.\n */\nexport const TABLE_INTERIOR_CELL_OFFSET_ROWID = 4;\n\n/**\n * Maximum number of 12-byte interior cells that can fit inside one 4KB interior page:\n * \\lfloor(4096 - 16) / (12 + 2)\\rfloor = 291 cells (where 2 is the slot directory entry size).\n */\nexport const MAX_TABLE_INTERIOR_CELLS = 291;\n\n/**\n * Median split index for interior page splits. When splitting a full 291-cell\n * interior node, entry 145 is promoted to the parent routing node.\n */\nexport const TABLE_INTERIOR_SPLIT_INDEX = 145;\n\n","/**\n * AUTO-GENERATED AT BUILD TIME FROM src/layouts/schemas/syspage_format.json\n * DO NOT EDIT MANUALLY. Run 'npm run generate:layouts' to rebuild.\n */\n\n/**\n * ============================================================================\n * CRITICAL WARNING: FROZEN SYSTEM PAGES & CATALOG SPECIFICATION\n * DO NOT modify the order or length of existing fields in Page 1, catalog\n * descriptors, or dedicated column catalog pages!\n * Changing any layout defined here WILL corrupt existing database files,\n * render databases unreadable, and permanently break schema decoding.\n *\n * Any new metadata fields MUST be appended within designated RESERVED areas\n * or versioned via schema migrations.\n * ============================================================================\n */\n\n/**\n * Maximum length in bytes for table and column names (UTF-8, null-padded).\n */\nexport const MAX_NAME_LENGTH = 64;\n\n// ============================================================================\n// 1. SYSPAGE FILE HEADER Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for SYSPAGE_FILE_HEADER:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | MAGIC [0..3] |\n * +-----------------------------------------------------------------------+\n * | MAGIC [4..5] | PAGE_SIZE (2B) |\n * +-----------------------------------+-----------------------------------+\n * | FILE_FORMAT_VERSION (2B) | MIN_READ_VERSION (2B) |\n * +-----------------------------------+-----------------------------------+\n * | TOTAL_PAGES (4B) |\n * +-----------------------------------------------------------------------+\n * | FREE_PAGE_HEAD (4B) |\n * +-----------------------------------------------------------------------+\n * | SCHEMA_VERSION (4B) |\n * +-----------------------------------------------------------------------+\n * | CHANGE_COUNTER (4B) |\n * +-----------------------------------------------------------------------+\n * | PAGE_CHECKSUM (4B) |\n * +-----------------------------------------------------------------------+\n * | NEXT_CATALOG_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | NEXT_INDEX_CATALOG_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | Bytes 40..99 (60B): RESERVED (uint8_t[60]) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+----------------------------+-------------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+----------------------------+-------------+------------------------------------------------+\n * | 0 | 6B | MAGIC | char[6] | Magic string identifier 'WEBDB\\0' |\n * | 6 | 2B | PAGE_SIZE | uint16_t | Page size in bytes (4096, uint16 LE) |\n * | 8 | 2B | FILE_FORMAT_VERSION | uint16_t | File format version (uint16 LE) |\n * | 10 | 2B | MIN_READ_VERSION | uint16_t | Minimum engine read version required (uint1... |\n * | 12 | 4B | TOTAL_PAGES | uint32_t | Total number of pages in database file (uin... |\n * | 16 | 4B | FREE_PAGE_HEAD | uint32_t | Page ID of the first free page in the free ... |\n * | 20 | 4B | SCHEMA_VERSION | uint32_t | User schema version cookie, bumped on DDL (... |\n * | 24 | 4B | CHANGE_COUNTER | uint32_t | Transaction write change counter (uint32 LE) |\n * | 28 | 4B | PAGE_CHECKSUM | uint32_t | CRC32 checksum of Page 1 (uint32 LE) |\n * | 32 | 4B | NEXT_CATALOG_PAGE_ID | uint32_t | Chained catalog page pointer (always 0 in v... |\n * | 36 | 4B | NEXT_INDEX_CATALOG_PAGE_ID | uint32_t | Chained index catalog pointer (always 0 in ... |\n * | 40 | 60B | RESERVED | uint8_t[60] | Reserved space for future file header exten... |\n * +--------+------+----------------------------+-------------+------------------------------------------------+\n * | Total: 100 Bytes |\n * +-----------------------------------------------------------------------------------------------------------+\n */\nexport const SYSPAGE_FILE_HEADER_FIELDS = [\n [\"MAGIC\", 6], // char[6]\n [\"PAGE_SIZE\", 2], // uint16_t\n [\"FILE_FORMAT_VERSION\", 2], // uint16_t\n [\"MIN_READ_VERSION\", 2], // uint16_t\n [\"TOTAL_PAGES\", 4], // uint32_t\n [\"FREE_PAGE_HEAD\", 4], // uint32_t\n [\"SCHEMA_VERSION\", 4], // uint32_t\n [\"CHANGE_COUNTER\", 4], // uint32_t\n [\"PAGE_CHECKSUM\", 4], // uint32_t\n [\"NEXT_CATALOG_PAGE_ID\", 4], // uint32_t\n [\"NEXT_INDEX_CATALOG_PAGE_ID\", 4], // uint32_t\n [\"RESERVED\", 60], // uint8_t[60]\n] as const;\n\n/**\n * Total size in bytes of the database file header in Page 1 (100 bytes).\n */\nexport const FILE_HEADER_SIZE = 100;\n\n/**\n * 0..5: Magic string identifier 'WEBDB\\0'\n */\nexport const HEADER_OFFSET_MAGIC = 0;\n\n/**\n * 6..7: Page size in bytes (4096, uint16 LE)\n */\nexport const HEADER_OFFSET_PAGE_SIZE = 6;\n\n/**\n * 8..9: File format version (uint16 LE)\n */\nexport const HEADER_OFFSET_FILE_FORMAT_VERSION = 8;\n\n/**\n * 10..11: Minimum engine read version required (uint16 LE)\n */\nexport const HEADER_OFFSET_MIN_READ_VERSION = 10;\n\n/**\n * 12..15: Total number of pages in database file (uint32 LE)\n */\nexport const HEADER_OFFSET_TOTAL_PAGES = 12;\n\n/**\n * 16..19: Page ID of the first free page in the free list chain (uint32 LE)\n */\nexport const HEADER_OFFSET_FREE_PAGE_HEAD = 16;\n\n/**\n * 20..23: User schema version cookie, bumped on DDL (uint32 LE)\n */\nexport const HEADER_OFFSET_SCHEMA_VERSION = 20;\n\n/**\n * 24..27: Transaction write change counter (uint32 LE)\n */\nexport const HEADER_OFFSET_CHANGE_COUNTER = 24;\n\n/**\n * 28..31: CRC32 checksum of Page 1 (uint32 LE)\n */\nexport const HEADER_OFFSET_PAGE_CHECKSUM = 28;\n\n/**\n * 32..35: Chained catalog page pointer (always 0 in v1, uint32 LE)\n */\nexport const HEADER_OFFSET_NEXT_CATALOG_PAGE_ID = 32;\n\n/**\n * 36..39: Chained index catalog pointer (always 0 in v1, uint32 LE)\n */\nexport const HEADER_OFFSET_NEXT_INDEX_CATALOG_PAGE_ID = 36;\n\n/**\n * 40..99: Reserved space for future file header extensions (zero-padded)\n */\nexport const HEADER_OFFSET_RESERVED = 40;\n\n// ============================================================================\n// Page 1 & Catalog Space Partition Offsets and Limits\n// ============================================================================\n\n/**\n * Page 1 Space Partition Map (4 KB Total):\n * +------------+-------+----------------------+--------------------------------------+\n * | Byte Range | Size | Partition Region | Description |\n * +------------+-------+----------------------+--------------------------------------+\n * | 0..99 | 100B | FILE_HEADER | Database file header |\n * | 100..2147 | 2048B | MASTER_TABLE_CATALOG | 16 Table Descriptors (128B each) |\n * | 2148..3171 | 1024B | INDEX_CATALOG | 8 Index Descriptors (128B each) |\n * | 3172..3175 | 4B | NEXT_DESCRIPTOR_PAGE | Chained descriptor page pointer |\n * | 3176..4095 | 920B | SYSPAGE_RESERVED | Reserved space for Page 1 extensions |\n * +------------+-------+----------------------+--------------------------------------+\n * | Total: 4096 Bytes (Full Page 1 Allocation) |\n * +----------------------------------------------------------------------------------+\n */\n\n/**\n * Maximum number of table descriptors that fit in Page 1 (16).\n */\nexport const MAX_TABLES_SYSPAGE = 16;\n\n/**\n * Maximum number of index descriptors that fit in Page 1 (8).\n */\nexport const MAX_INDEXES_SYSPAGE = 8;\n\n/**\n * Alias for MAX_TABLES_SYSPAGE.\n */\nexport const MAX_TABLES_PAGE1 = 16;\n\n/**\n * Alias for MAX_INDEXES_SYSPAGE.\n */\nexport const MAX_INDEXES_PAGE1 = 8;\n\n/**\n * Byte offset where master table descriptors start in Page 1 (byte 100).\n */\nexport const MASTER_TABLE_OFFSET = 100;\n\n/**\n * Byte offset where index descriptors start in Page 1 (100 + 16 * 128 = 2148).\n */\nexport const INDEX_CATALOG_OFFSET = 2148;\n\n/**\n * Byte offset for chained descriptor page pointer (2148 + 8 * 128 = 3172).\n */\nexport const NEXT_DESCRIPTOR_CATALOG_PAGE_OFFSET = 3172;\n\n/**\n * Size in bytes of chained descriptor catalog page pointer (4 bytes).\n */\nexport const NEXT_DESCRIPTOR_CATALOG_PAGE_SIZE = 4;\n\n/**\n * Byte offset for Page 1 reserved partition (3172 + 4 = 3176).\n */\nexport const SYSPAGE_RESERVED_OFFSET = 3176;\n\n/**\n * Size in bytes of Page 1 reserved partition (4096 - 3176 = 920).\n */\nexport const SYSPAGE_RESERVED_SIZE = 920;\n\n/**\n * Maximum column records per catalog page: floor((4096 - 16) / 72) = 56.\n */\nexport const MAX_COLUMNS_PER_CATALOG_PAGE = 56;\n\n/**\n * Maximum columns supported per table across all catalog pages (256).\n */\nexport const MAX_COLUMNS_PER_TABLE = 256;\n\n// ============================================================================\n// 2. TABLE DESCRIPTOR Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for TABLE_DESCRIPTOR:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | TABLE_ID (2B) | COLUMN_COUNT (2B) |\n * +-----------------------------------+-----------------------------------+\n * | ROOT_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | COL_CATALOG_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | Bytes 12..75 (64B): NAME (char[64]) |\n * +-----------------------------------------------------------------------+\n * | FLAGS (4B) |\n * +-----------------------------------------------------------------------+\n * | ROW_COUNT_ESTIMATE (4B) |\n * +-----------------------------------------------------------------------+\n * | Bytes 84..91 (8B): AUTO_INC_NEXT (uint64_t) |\n * +-----------------------------------------------------------------------+\n * | Bytes 92..127 (36B): RESERVED (uint8_t[36]) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+---------------------+-------------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+---------------------+-------------+------------------------------------------------+\n * | 0 | 2B | TABLE_ID | uint16_t | uint16_t table_id (1-based, 0 = inactive slot) |\n * | 2 | 2B | COLUMN_COUNT | uint16_t | uint16_t total columns in table |\n * | 4 | 4B | ROOT_PAGE_ID | uint32_t | uint32_t root data pageId |\n * | 8 | 4B | COL_CATALOG_PAGE_ID | uint32_t | uint32_t first column catalog pageId |\n * | 12 | 64B | NAME | char[64] | 64 bytes UTF-8 fixed string (null-padded) |\n * | 76 | 4B | FLAGS | uint32_t | uint32_t table flags (WAL, system, etc.) |\n * | 80 | 4B | ROW_COUNT_ESTIMATE | uint32_t | uint32_t estimated row count |\n * | 84 | 8B | AUTO_INC_NEXT | uint64_t | uint64_t next auto_increment ID |\n * | 92 | 36B | RESERVED | uint8_t[36] | 36 bytes reserved space (92..127) |\n * +--------+------+---------------------+-------------+------------------------------------------------+\n * | Total: 128 Bytes |\n * +----------------------------------------------------------------------------------------------------+\n */\nexport const TABLE_DESCRIPTOR_FIELDS = [\n [\"TABLE_ID\", 2], // uint16_t\n [\"COLUMN_COUNT\", 2], // uint16_t\n [\"ROOT_PAGE_ID\", 4], // uint32_t\n [\"COL_CATALOG_PAGE_ID\", 4], // uint32_t\n [\"NAME\", 64], // char[64]\n [\"FLAGS\", 4], // uint32_t\n [\"ROW_COUNT_ESTIMATE\", 4], // uint32_t\n [\"AUTO_INC_NEXT\", 8], // uint64_t\n [\"RESERVED\", 36], // uint8_t[36]\n] as const;\n\n/**\n * Total size in bytes of a single table descriptor record (128 bytes).\n */\nexport const TABLE_DESCRIPTOR_SIZE = 128;\n\n/**\n * uint16_t table_id (1-based, 0 = inactive slot)\n */\nexport const TABLE_DESCRIPTOR_OFFSET_TABLE_ID = 0;\n\n/**\n * uint16_t total columns in table\n */\nexport const TABLE_DESCRIPTOR_OFFSET_COLUMN_COUNT = 2;\n\n/**\n * uint32_t root data pageId\n */\nexport const TABLE_DESCRIPTOR_OFFSET_ROOT_PAGE_ID = 4;\n\n/**\n * uint32_t first column catalog pageId\n */\nexport const TABLE_DESCRIPTOR_OFFSET_COL_CATALOG_PAGE_ID = 8;\n\n/**\n * 64 bytes UTF-8 fixed string (null-padded)\n */\nexport const TABLE_DESCRIPTOR_OFFSET_NAME = 12;\n\n/**\n * uint32_t table flags (WAL, system, etc.)\n */\nexport const TABLE_DESCRIPTOR_OFFSET_FLAGS = 76;\n\n/**\n * uint32_t estimated row count\n */\nexport const TABLE_DESCRIPTOR_OFFSET_ROW_COUNT_ESTIMATE = 80;\n\n/**\n * uint64_t next auto_increment ID\n */\nexport const TABLE_DESCRIPTOR_OFFSET_AUTO_INC_NEXT = 84;\n\n/**\n * 36 bytes reserved space (92..127)\n */\nexport const TABLE_DESCRIPTOR_OFFSET_RESERVED = 92;\n\n// ============================================================================\n// 3. INDEX DESCRIPTOR Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for INDEX_DESCRIPTOR:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | INDEX_ID (2B) | TABLE_ID (2B) |\n * +-----------------------------------+-----------------------------------+\n * | ROOT_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | COLUMN_COUNT (1B) | FLAGS (1B) | COLUMN_INDICES [0..1] |\n * +-----------------+-----------------+-----------------------------------+\n * | COLUMN_INDICES [2..5] |\n * +-----------------------------------------------------------------------+\n * | COLUMN_INDICES [6..9] |\n * +-----------------------------------------------------------------------+\n * | COLUMN_INDICES [10..13] |\n * +-----------------------------------------------------------------------+\n * | COLUMN_INDICES [14..15] | COL_DIRECTIONS [0..1] |\n * +-----------------------------------+-----------------------------------+\n * | COL_DIRECTIONS [2..5] |\n * +-----------------------------------------------------------------------+\n * | COL_DIRECTIONS [6..7] | NAME [0..1] |\n * +-----------------------------------+-----------------------------------+\n * | NAME [2..5] |\n * +-----------------------------------------------------------------------+\n * | NAME [6..9] |\n * +-----------------------------------------------------------------------+\n * | NAME [10..13] |\n * +-----------------------------------------------------------------------+\n * | NAME [14..17] |\n * +-----------------------------------------------------------------------+\n * | NAME [18..21] |\n * +-----------------------------------------------------------------------+\n * | NAME [22..25] |\n * +-----------------------------------------------------------------------+\n * | NAME [26..29] |\n * +-----------------------------------------------------------------------+\n * | NAME [30..33] |\n * +-----------------------------------------------------------------------+\n * | NAME [34..37] |\n * +-----------------------------------------------------------------------+\n * | NAME [38..41] |\n * +-----------------------------------------------------------------------+\n * | NAME [42..45] |\n * +-----------------------------------------------------------------------+\n * | NAME [46..49] |\n * +-----------------------------------------------------------------------+\n * | NAME [50..53] |\n * +-----------------------------------------------------------------------+\n * | NAME [54..57] |\n * +-----------------------------------------------------------------------+\n * | NAME [58..61] |\n * +-----------------------------------------------------------------------+\n * | NAME [62..63] | RESERVED [0..1] |\n * +-----------------------------------+-----------------------------------+\n * | RESERVED [2..5] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [6..9] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [10..13] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [14..17] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [18..21] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [22..25] |\n * +-----------------------------------------------------------------------+\n * | RESERVED [26..29] |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+----------------+-------------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+----------------+-------------+------------------------------------------------+\n * | 0 | 2B | INDEX_ID | uint16_t | uint16_t index_id (1-based, 0 = inactive slot) |\n * | 2 | 2B | TABLE_ID | uint16_t | uint16_t target table_id |\n * | 4 | 4B | ROOT_PAGE_ID | uint32_t | uint32_t root index pageId |\n * | 8 | 1B | COLUMN_COUNT | uint8_t | uint8_t indexed column count (1..8) |\n * | 9 | 1B | FLAGS | uint8_t | uint8_t index flags (unique, primary, etc.) |\n * | 10 | 16B | COLUMN_INDICES | uint16_t[8] | 8 * uint16_t column indices (16 bytes) |\n * | 26 | 8B | COL_DIRECTIONS | uint8_t[8] | 8 * uint8_t sort directions (8 bytes: 0=ASC... |\n * | 34 | 64B | NAME | char[64] | 64 bytes UTF-8 fixed string (null-padded) |\n * | 98 | 30B | RESERVED | uint8_t[30] | 30 bytes reserved space (98..127) |\n * +--------+------+----------------+-------------+------------------------------------------------+\n * | Total: 128 Bytes |\n * +-----------------------------------------------------------------------------------------------+\n */\nexport const INDEX_DESCRIPTOR_FIELDS = [\n [\"INDEX_ID\", 2], // uint16_t\n [\"TABLE_ID\", 2], // uint16_t\n [\"ROOT_PAGE_ID\", 4], // uint32_t\n [\"COLUMN_COUNT\", 1], // uint8_t\n [\"FLAGS\", 1], // uint8_t\n [\"COLUMN_INDICES\", 16], // uint16_t[8]\n [\"COL_DIRECTIONS\", 8], // uint8_t[8]\n [\"NAME\", 64], // char[64]\n [\"RESERVED\", 30], // uint8_t[30]\n] as const;\n\n/**\n * Total size in bytes of a single index descriptor record (128 bytes).\n */\nexport const INDEX_DESCRIPTOR_SIZE = 128;\n\n/**\n * uint16_t index_id (1-based, 0 = inactive slot)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_INDEX_ID = 0;\n\n/**\n * uint16_t target table_id\n */\nexport const INDEX_DESCRIPTOR_OFFSET_TABLE_ID = 2;\n\n/**\n * uint32_t root index pageId\n */\nexport const INDEX_DESCRIPTOR_OFFSET_ROOT_PAGE_ID = 4;\n\n/**\n * uint8_t indexed column count (1..8)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_COLUMN_COUNT = 8;\n\n/**\n * uint8_t index flags (unique, primary, etc.)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_FLAGS = 9;\n\n/**\n * 8 * uint16_t column indices (16 bytes)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_COLUMN_INDICES = 10;\n\n/**\n * 8 * uint8_t sort directions (8 bytes: 0=ASC, 1=DESC)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_COL_DIRECTIONS = 26;\n\n/**\n * 64 bytes UTF-8 fixed string (null-padded)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_NAME = 34;\n\n/**\n * 30 bytes reserved space (98..127)\n */\nexport const INDEX_DESCRIPTOR_OFFSET_RESERVED = 98;\n\n// ============================================================================\n// 4. CATALOG PAGE HEADER Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for CATALOG_PAGE_HEADER:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | PAGE_TYPE (1B) | FLAGS (1B) | COL_COUNT_IN_PAGE (2B) |\n * +-----------------+-----------------+-----------------------------------+\n * | TABLE_ID (2B) | START_COL_INDEX (2B) |\n * +-----------------------------------+-----------------------------------+\n * | NEXT_COL_CATALOG_PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | PAGE_CHECKSUM (4B) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+--------------------------+----------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+--------------------------+----------+------------------------------------------------+\n * | 0 | 1B | PAGE_TYPE | uint8_t | uint8_t 0x0C (PAGE_TYPE_CATALOG_PAGE) |\n * | 1 | 1B | FLAGS | uint8_t | uint8_t reserved / flags |\n * | 2 | 2B | COL_COUNT_IN_PAGE | uint16_t | uint16_t columns stored in this page (0..56) |\n * | 4 | 2B | TABLE_ID | uint16_t | uint16_t table_id this page belongs to |\n * | 6 | 2B | START_COL_INDEX | uint16_t | uint16_t starting global column index |\n * | 8 | 4B | NEXT_COL_CATALOG_PAGE_ID | uint32_t | uint32_t next column catalog pageId (0 = tail) |\n * | 12 | 4B | PAGE_CHECKSUM | uint32_t | uint32_t crc32 checksum |\n * +--------+------+--------------------------+----------+------------------------------------------------+\n * | Total: 16 Bytes |\n * +------------------------------------------------------------------------------------------------------+\n */\nexport const CATALOG_PAGE_HEADER_FIELDS = [\n [\"PAGE_TYPE\", 1], // uint8_t\n [\"FLAGS\", 1], // uint8_t\n [\"COL_COUNT_IN_PAGE\", 2], // uint16_t\n [\"TABLE_ID\", 2], // uint16_t\n [\"START_COL_INDEX\", 2], // uint16_t\n [\"NEXT_COL_CATALOG_PAGE_ID\", 4], // uint32_t\n [\"PAGE_CHECKSUM\", 4], // uint32_t\n] as const;\n\n/**\n * Total size in bytes of a dedicated column catalog page header (16 bytes).\n */\nexport const CATALOG_PAGE_HEADER_SIZE = 16;\n\n/**\n * uint8_t 0x0C (PAGE_TYPE_CATALOG_PAGE)\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_PAGE_TYPE = 0;\n\n/**\n * uint8_t reserved / flags\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_FLAGS = 1;\n\n/**\n * uint16_t columns stored in this page (0..56)\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_COL_COUNT_IN_PAGE = 2;\n\n/**\n * uint16_t table_id this page belongs to\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_TABLE_ID = 4;\n\n/**\n * uint16_t starting global column index\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_START_COL_INDEX = 6;\n\n/**\n * uint32_t next column catalog pageId (0 = tail)\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_NEXT_COL_CATALOG_PAGE_ID = 8;\n\n/**\n * uint32_t crc32 checksum\n */\nexport const CATALOG_PAGE_HEADER_OFFSET_PAGE_CHECKSUM = 12;\n\n// ============================================================================\n// 5. COLUMN META Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for COLUMN_META:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | TYPE (1B) | FLAGS (1B) | COL_OFFSET (2B) |\n * +-----------------+-----------------+-----------------------------------+\n * | Bytes 4..67 (64B): NAME (char[64]) |\n * +-----------------------------------------------------------------------+\n * | RESERVED (4B) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+------------+------------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+------------+------------+------------------------------------------------+\n * | 0 | 1B | TYPE | uint8_t | uint8_t DataType enum (1..7) |\n * | 1 | 1B | FLAGS | uint8_t | uint8_t ColumnFlag bitmask (NOT_NULL, PRIMA... |\n * | 2 | 2B | COL_OFFSET | uint16_t | uint16_t fixed-slice offset or var-table index |\n * | 4 | 64B | NAME | char[64] | 64 bytes UTF-8 column name (null-padded) |\n * | 68 | 4B | RESERVED | uint8_t[4] | 4 bytes reserved (68..71) |\n * +--------+------+------------+------------+------------------------------------------------+\n * | Total: 72 Bytes |\n * +------------------------------------------------------------------------------------------+\n */\nexport const COLUMN_META_FIELDS = [\n [\"TYPE\", 1], // uint8_t\n [\"FLAGS\", 1], // uint8_t\n [\"COL_OFFSET\", 2], // uint16_t\n [\"NAME\", 64], // char[64]\n [\"RESERVED\", 4], // uint8_t[4]\n] as const;\n\n/**\n * Total size in bytes of a single column metadata record (72 bytes).\n */\nexport const COLUMN_META_SIZE = 72;\n\n/**\n * uint8_t DataType enum (1..7)\n */\nexport const COLUMN_META_OFFSET_TYPE = 0;\n\n/**\n * uint8_t ColumnFlag bitmask (NOT_NULL, PRIMARY_KEY, etc.)\n */\nexport const COLUMN_META_OFFSET_FLAGS = 1;\n\n/**\n * uint16_t fixed-slice offset or var-table index\n */\nexport const COLUMN_META_OFFSET_COL_OFFSET = 2;\n\n/**\n * 64 bytes UTF-8 column name (null-padded)\n */\nexport const COLUMN_META_OFFSET_NAME = 4;\n\n/**\n * 4 bytes reserved (68..71)\n */\nexport const COLUMN_META_OFFSET_RESERVED = 68;\n\n","/**\n * AUTO-GENERATED AT BUILD TIME FROM src/layouts/schemas/pool_format.json\n * DO NOT EDIT MANUALLY. Run 'npm run generate:layouts' to rebuild.\n */\n\nimport { PAGE_SIZE } from \"./page_format.js\";\n\n// ============================================================================\n// Buffer Pool & Shared Memory Architecture Layout\n// ============================================================================\n\n/**\n * Default cache buffer pool size in bytes (4 MB = 1024 * 4096).\n */\nexport const DEFAULT_CACHE_SIZE_BYTES = 4194304;\n\n/**\n * Default number of page cache slots in the buffer pool (1024).\n */\nexport const DEFAULT_SLOT_COUNT = 1024;\n\n/**\n * Alias for DEFAULT_SLOT_COUNT (1024).\n */\nexport const DEFAULT_PAGE_SLOTS = 1024;\n\n/**\n * Default number of hash table buckets for page-to-slot mapping (2048, load factor <= 50%).\n */\nexport const DEFAULT_PAGE_TO_SLOT_BUCKETS = 2048;\n\n/**\n * Size in bytes of each hash table bucket (uint32 page_id + uint32 slot_idx = 8 bytes).\n */\nexport const PAGE_TO_SLOT_BUCKET_SIZE = 8;\n\n/**\n * Total size in bytes of the page-to-slot hash table (2048 * 8 = 16 KB).\n */\nexport const PAGE_TO_SLOT_SIZE = 16384;\n\n/**\n * Size in bytes allocated for VM execution context state (12 KB).\n */\nexport const VM_CONTEXT_SIZE = 12288;\n\n/**\n * Size in bytes allocated for SQL result row serialization buffer (64 KB).\n */\nexport const RESULT_BUFFER_SIZE = 65536;\n\n/**\n * Size in bytes allocated for compiled query bytecode instructions (32 KB).\n */\nexport const BYTECODE_SIZE = 32768;\n\n/**\n * Size in bytes allocated for temporary single-page staging / decompression (4 KB).\n */\nexport const PAGE_SCRATCHPAD_SIZE = 4096;\n\n/**\n * Padding bytes to align transient execution arena at boundary 0x430000 (61,312 bytes).\n */\nexport const ALIGNMENT_PADDING_SIZE = 61312;\n\n/**\n * Maximum memory limit in bytes for transient query execution arena (16 MB).\n */\nexport const DEFAULT_MAX_QUERY_MEMORY = 16777216;\n\n/**\n * Shared Memory Architecture Map (1024 Slots / 4MB Cache Default):\n * +----------------------+--------+-------------------+------------------------------------------------+\n * | Memory Address Range | Size | Region Name | Description |\n * +----------------------+--------+-------------------+------------------------------------------------+\n * | 0x400000..0x400FFF | 4096B | SLOT_TO_PAGE | Array of 1024 uint32 pageIds mapping slot -... |\n * | 0x401000..0x404FFF | 16384B | PAGE_TO_SLOT | Open-addressing hash table (2048 buckets x ... |\n * | 0x405000..0x40507F | 128B | DIRTY_MASK | Bitmask (128 bytes = 1024 bits) tracking di... |\n * | 0x405080..0x40807F | 12288B | VM_CONTEXT | Execution context frames for the SQL VM. |\n * | 0x408080..0x41807F | 65536B | RESULT_BUFFER | Output buffer for query result rows. |\n * | 0x418080..0x42007F | 32768B | BYTECODE | Instruction buffer for compiled bytecode ro... |\n * | 0x420080..0x42107F | 4096B | PAGE_SCRATCHPAD | Staging buffer for page compression or I/O ... |\n * | 0x421080..0x42FFFF | 61312B | ALIGNMENT_PADDING | Padding aligning transient arena to 0x430000. |\n * +----------------------+--------+-------------------+------------------------------------------------+\n * | Arena Start: 0x430000 | Total Regions: 196608 Bytes |\n * +----------------------------------------------------------------------------------------------------+\n */\nexport const DEFAULT_BUFFER_POOL_REGIONS = [\n [\"SLOT_TO_PAGE\", 4096],\n [\"PAGE_TO_SLOT\", 16384],\n [\"DIRTY_MASK\", 128],\n [\"VM_CONTEXT\", 12288],\n [\"RESULT_BUFFER\", 65536],\n [\"BYTECODE\", 32768],\n [\"PAGE_SCRATCHPAD\", 4096],\n [\"ALIGNMENT_PADDING\", 61312],\n] as const;\n\n/**\n * Byte offset 0x400000: Array of 1024 uint32 pageIds mapping slot -> pageId.\n */\nexport const SLOT_TO_PAGE_OFFSET = 4194304; // 0x400000\n\n/**\n * Byte offset 0x401000: Open-addressing hash table (2048 buckets x 8B) mapping pageId -> slot.\n */\nexport const PAGE_TO_SLOT_OFFSET = 4198400; // 0x401000\n\n/**\n * Byte offset 0x405000: Bitmask (128 bytes = 1024 bits) tracking dirty slots.\n */\nexport const DIRTY_MASK_OFFSET = 4214784; // 0x405000\n\n/**\n * Byte offset 0x405080: Execution context frames for the SQL VM.\n */\nexport const VM_CONTEXT_OFFSET = 4214912; // 0x405080\n\n/**\n * Byte offset 0x408080: Output buffer for query result rows.\n */\nexport const RESULT_BUFFER_OFFSET = 4227200; // 0x408080\n\n/**\n * Byte offset 0x418080: Instruction buffer for compiled bytecode routines.\n */\nexport const BYTECODE_OFFSET = 4292736; // 0x418080\n\n/**\n * Byte offset 0x420080: Staging buffer for page compression or I/O reassembly.\n */\nexport const PAGE_SCRATCHPAD_OFFSET = 4325504; // 0x420080\n\n/**\n * Byte offset 0x421080: Padding aligning transient arena to 0x430000.\n */\nexport const ALIGNMENT_PADDING_OFFSET = 4329600; // 0x421080\n\n/**\n * Byte offset 0x430000: Start of dynamic transient query execution arena.\n */\nexport const TRANSIENT_ARENA_OFFSET = 4390912; // 0x430000\n\n/**\n * Total buffer pool and shared Wasm memory allocation in bytes (20.1875 MB).\n */\nexport const TOTAL_MEMORY_BYTES = 21168128;\n\n/**\n * Computes memory layout offsets for arbitrary slot counts.\n */\nexport function computeBufferPoolOffsets(\n slotCount: number,\n _maxQueryMemory: number = DEFAULT_MAX_QUERY_MEMORY,\n) {\n const slotsEndOffset = slotCount * PAGE_SIZE;\n const slotToPageBytes = (slotCount * 4 + 7) & ~7;\n let pageToSlotBuckets = 16;\n while (pageToSlotBuckets < slotCount * 2) {\n pageToSlotBuckets <<= 1;\n }\n const pageToSlotBytes = pageToSlotBuckets * 8;\n const dirtyMaskBytes = (Math.ceil(slotCount / 8) + 7) & ~7;\n\n if (slotCount === DEFAULT_SLOT_COUNT) {\n return {\n slotsEndOffset,\n slotToPageOffset: SLOT_TO_PAGE_OFFSET,\n pageToSlotOffset: PAGE_TO_SLOT_OFFSET,\n pageToSlotBuckets: DEFAULT_PAGE_TO_SLOT_BUCKETS,\n dirtyMaskOffset: DIRTY_MASK_OFFSET,\n vmContextOffset: VM_CONTEXT_OFFSET,\n resultBufferOffset: RESULT_BUFFER_OFFSET,\n bytecodeOffset: BYTECODE_OFFSET,\n pageScratchpadOffset: PAGE_SCRATCHPAD_OFFSET,\n transientArenaOffset: TRANSIENT_ARENA_OFFSET,\n };\n }\n\n const slotToPageOffset = slotsEndOffset;\n const pageToSlotOffset = slotToPageOffset + slotToPageBytes;\n const dirtyMaskOffset = pageToSlotOffset + pageToSlotBytes;\n const vmContextOffset = dirtyMaskOffset + dirtyMaskBytes;\n const resultBufferOffset = vmContextOffset + VM_CONTEXT_SIZE;\n const bytecodeOffset = resultBufferOffset + RESULT_BUFFER_SIZE;\n const pageScratchpadOffset = bytecodeOffset + BYTECODE_SIZE;\n const transientArenaOffset =\n pageScratchpadOffset + PAGE_SCRATCHPAD_SIZE + ALIGNMENT_PADDING_SIZE;\n\n return {\n slotsEndOffset,\n slotToPageOffset,\n pageToSlotOffset,\n pageToSlotBuckets,\n dirtyMaskOffset,\n vmContextOffset,\n resultBufferOffset,\n bytecodeOffset,\n pageScratchpadOffset,\n transientArenaOffset,\n };\n}\n","/**\n * AUTO-GENERATED AT BUILD TIME FROM src/layouts/schemas/wal_format.json\n * DO NOT EDIT MANUALLY. Run 'npm run generate:layouts' to rebuild.\n */\n\n/**\n * ============================================================================\n * CRITICAL WARNING: FROZEN WAL BINARY FORMAT SPECIFICATION\n * DO NOT modify the order, types, or byte lengths of existing fields in\n * WalFileHeader or WalFrameHeader! Changing any offset or field size breaks\n * binary determinism, prevents crash recovery, and corrupts WAL logs.\n *\n * Both the WAL file header (32 bytes) and WAL frame headers (32 bytes)\n * must remain rigidly 8-byte aligned.\n * ============================================================================\n */\n\n/**\n * Rigid page payload size in bytes per WAL frame (4096 bytes).\n */\nexport const WAL_PAGE_SIZE = 4096;\n\n/**\n * Total size in bytes of a single WAL frame (32-byte header + 4096-byte page payload = 4128 bytes).\n */\nexport const WAL_FRAME_SIZE = 4128;\n\n/**\n * Current WAL file format version (Version 1).\n */\nexport const WAL_CURRENT_VERSION = 1;\n\n/**\n * Magic number for WAL frames (0x57414C46 in uint32 LE = 'WALF').\n */\nexport const WAL_FRAME_MAGIC = 1463897158;\n\n/**\n * Frame type 0x0001: Committed 4KB page mutation for page_id.\n */\nexport const WAL_FRAME_TYPE_PAGE_DATA = 1;\n\n/**\n * Frame type 0x0002: Commit marker for tx_id. Signals that all preceding frames for this tx_id are permanently committed.\n */\nexport const WAL_FRAME_TYPE_TX_COMMIT = 2;\n\n/**\n * Frame type 0x0003: Cache spill frame under memory pressure. Ignored during recovery unless followed by a commit marker.\n */\nexport const WAL_FRAME_TYPE_TX_UNCOMMITTED = 3;\n\n// ============================================================================\n// 1. WAL FILE HEADER Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for WAL_FILE_HEADER:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | MAGIC [0..3] |\n * +-----------------------------------------------------------------------+\n * | MAGIC [4..5] | WAL_VERSION (2B) |\n * +-----------------------------------+-----------------------------------+\n * | PAGE_SIZE (4B) |\n * +-----------------------------------------------------------------------+\n * | CHECKPOINT_SEQ (4B) |\n * +-----------------------------------------------------------------------+\n * | SALT1 (4B) |\n * +-----------------------------------------------------------------------+\n * | SALT2 (4B) |\n * +-----------------------------------------------------------------------+\n * | CHECKSUM (4B) |\n * +-----------------------------------------------------------------------+\n * | RESERVED (4B) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+----------------+----------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+----------------+----------+------------------------------------------------+\n * | 0 | 6B | MAGIC | char[6] | Magic string identifier 'WEBWAL' |\n * | 6 | 2B | WAL_VERSION | uint16_t | WAL format version (1 for V1, uint16 LE) |\n * | 8 | 4B | PAGE_SIZE | uint32_t | Rigid page size (4096, uint32 LE) |\n * | 12 | 4B | CHECKPOINT_SEQ | uint32_t | Monotonic checkpoint counter (uint32 LE) |\n * | 16 | 4B | SALT1 | uint32_t | Random salt generated on checkpoint (uint32... |\n * | 20 | 4B | SALT2 | uint32_t | Random salt tie-breaker (uint32 LE) |\n * | 24 | 4B | CHECKSUM | uint32_t | CRC32 checksum over bytes 0..23 (uint32 LE) |\n * | 28 | 4B | RESERVED | uint32_t | Zero padding for 8-byte alignment (uint32 LE) |\n * +--------+------+----------------+----------+------------------------------------------------+\n * | Total: 32 Bytes |\n * +--------------------------------------------------------------------------------------------+\n */\nexport const WAL_FILE_HEADER_FIELDS = [\n [\"MAGIC\", 6], // char[6]\n [\"WAL_VERSION\", 2], // uint16_t\n [\"PAGE_SIZE\", 4], // uint32_t\n [\"CHECKPOINT_SEQ\", 4], // uint32_t\n [\"SALT1\", 4], // uint32_t\n [\"SALT2\", 4], // uint32_t\n [\"CHECKSUM\", 4], // uint32_t\n [\"RESERVED\", 4], // uint32_t\n] as const;\n\n/**\n * Total size in bytes of the WAL file header (32 bytes).\n */\nexport const WAL_FILE_HEADER_SIZE = 32;\n\n/**\n * 0..5: Magic string identifier 'WEBWAL'\n */\nexport const WAL_HEADER_OFFSET_MAGIC = 0;\n\n/**\n * 6..7: WAL format version (1 for V1, uint16 LE)\n */\nexport const WAL_HEADER_OFFSET_WAL_VERSION = 6;\n\n/**\n * 8..11: Rigid page size (4096, uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_PAGE_SIZE = 8;\n\n/**\n * 12..15: Monotonic checkpoint counter (uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_CHECKPOINT_SEQ = 12;\n\n/**\n * 16..19: Random salt generated on checkpoint (uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_SALT1 = 16;\n\n/**\n * 20..23: Random salt tie-breaker (uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_SALT2 = 20;\n\n/**\n * 24..27: CRC32 checksum over bytes 0..23 (uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_CHECKSUM = 24;\n\n/**\n * 28..31: Zero padding for 8-byte alignment (uint32 LE)\n */\nexport const WAL_HEADER_OFFSET_RESERVED = 28;\n\n// ============================================================================\n// 2. WAL FRAME HEADER Layout\n// ============================================================================\n\n/**\n * 32-bit Word Byte Layout Grid for WAL_FRAME_HEADER:\n * Byte 0 Byte 1 Byte 2 Byte 3 \n * +-----------------+-----------------+-----------------+-----------------+\n * | MAGIC (4B) |\n * +-----------------------------------------------------------------------+\n * | FRAME_TYPE (2B) | FLAGS (2B) |\n * +-----------------------------------+-----------------------------------+\n * | TX_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | PAGE_ID (4B) |\n * +-----------------------------------------------------------------------+\n * | DB_SIZE_PAGES (4B) |\n * +-----------------------------------------------------------------------+\n * | FRAME_SEQ (4B) |\n * +-----------------------------------------------------------------------+\n * | CHECKSUM (4B) |\n * +-----------------------------------------------------------------------+\n * | RESERVED (4B) |\n * +-----------------------------------------------------------------------+\n *\n * Field Details:\n * +--------+------+---------------+----------+------------------------------------------------+\n * | Offset | Size | Field Name | Type | Description |\n * +--------+------+---------------+----------+------------------------------------------------+\n * | 0 | 4B | MAGIC | uint32_t | Frame magic 0x57414C46 ('WALF', uint32 LE) |\n * | 4 | 2B | FRAME_TYPE | uint16_t | Frame type (1=PAGE_DATA, 2=TX_COMMIT, 3=TX_... |\n * | 6 | 2B | FLAGS | uint16_t | Reserved flags (0x0000, uint16 LE) |\n * | 8 | 4B | TX_ID | uint32_t | Monotonic transaction identifier (uint32 LE) |\n * | 12 | 4B | PAGE_ID | uint32_t | Target database Page ID (1..N, uint32 LE) |\n * | 16 | 4B | DB_SIZE_PAGES | uint32_t | Size of DB in pages after commit (uint32 LE) |\n * | 20 | 4B | FRAME_SEQ | uint32_t | Monotonic frame sequence counter in WAL (ui... |\n * | 24 | 4B | CHECKSUM | uint32_t | CRC32 over header bytes 0..23 + 4096 page b... |\n * | 28 | 4B | RESERVED | uint32_t | Zero padding for 8-byte alignment (uint32 LE) |\n * +--------+------+---------------+----------+------------------------------------------------+\n * | Total: 32 Bytes |\n * +-------------------------------------------------------------------------------------------+\n */\nexport const WAL_FRAME_HEADER_FIELDS = [\n [\"MAGIC\", 4], // uint32_t\n [\"FRAME_TYPE\", 2], // uint16_t\n [\"FLAGS\", 2], // uint16_t\n [\"TX_ID\", 4], // uint32_t\n [\"PAGE_ID\", 4], // uint32_t\n [\"DB_SIZE_PAGES\", 4], // uint32_t\n [\"FRAME_SEQ\", 4], // uint32_t\n [\"CHECKSUM\", 4], // uint32_t\n [\"RESERVED\", 4], // uint32_t\n] as const;\n\n/**\n * Total size in bytes of a single WAL frame header (32 bytes).\n */\nexport const WAL_FRAME_HEADER_SIZE = 32;\n\n/**\n * 0..3: Frame magic 0x57414C46 ('WALF', uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_MAGIC = 0;\n\n/**\n * 4..5: Frame type (1=PAGE_DATA, 2=TX_COMMIT, 3=TX_UNCOMMITTED, uint16 LE)\n */\nexport const WAL_FRAME_OFFSET_FRAME_TYPE = 4;\n\n/**\n * 6..7: Reserved flags (0x0000, uint16 LE)\n */\nexport const WAL_FRAME_OFFSET_FLAGS = 6;\n\n/**\n * 8..11: Monotonic transaction identifier (uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_TX_ID = 8;\n\n/**\n * 12..15: Target database Page ID (1..N, uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_PAGE_ID = 12;\n\n/**\n * 16..19: Size of DB in pages after commit (uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_DB_SIZE_PAGES = 16;\n\n/**\n * 20..23: Monotonic frame sequence counter in WAL (uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_FRAME_SEQ = 20;\n\n/**\n * 24..27: CRC32 over header bytes 0..23 + 4096 page bytes (uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_CHECKSUM = 24;\n\n/**\n * 28..31: Zero padding for 8-byte alignment (uint32 LE)\n */\nexport const WAL_FRAME_OFFSET_RESERVED = 28;\n\n","// Re-export all layout-computed offsets and structures\nexport * from \"./layouts/index.ts\";\n\n// Engine Versions\nexport const CURRENT_ENGINE_VERSION = 1;\nexport const CURRENT_MIN_READ_VERSION = 1;\n\n// Page Types (§4.2)\nexport const PAGE_TYPE_FREE = 0x00;\nexport const PAGE_TYPE_INDEX_INTERIOR = 0x02;\nexport const PAGE_TYPE_TABLE_INTERIOR = 0x05;\nexport const PAGE_TYPE_INDEX_LEAF = 0x0a;\nexport const PAGE_TYPE_CATALOG_PAGE = 0x0c;\nexport const PAGE_TYPE_LEAF_DATA = 0x0d;\n\n// VmContext Frame Limits\nexport const VM_FRAME_SIZE = 1280;\nexport const VM_FRAME_COUNT = 8;\nexport const MAX_REGISTERS_PER_FRAME = 64;\nexport const MAX_CURSORS_PER_FRAME = 16;\nexport const MAX_SUBQUERY_DEPTH = 7;\n\n// WAL Specifications\nexport const WAL_HEADER_SIZE = 32;\n\n// Sorter & Query Optimization Limits\nexport const MAX_TOPK_HEAP_LIMIT = 10000;\nexport const MAX_IN_LIST_SIZE = 10000;\n","import { VmStatus, TableMeta, ColumnMeta } from '../types/index.js';\nimport { DEFAULT_MAX_QUERY_MEMORY } from '../constants.js';\n\nexport interface VmCursor {\n pageId: number;\n rootPageId?: number;\n slotIdx: number;\n cellIdx: number;\n rowOffset: number; // Absolute byte offset in view\n btreeDepth?: number;\n flags?: number;\n}\n\nexport function createVmCursor(): VmCursor {\n return {\n pageId: 0,\n rootPageId: 0,\n slotIdx: 0,\n cellIdx: 0,\n rowOffset: 0,\n btreeDepth: 0,\n flags: 0,\n };\n}\n\nexport interface VmKeyInfo {\n numKeys: number;\n directions: number[]; // 0 = ASC, 1 = DESC\n nullOrders: number[]; // 0 = NULLS_FIRST, 1 = NULLS_LAST\n limit?: number;\n offset?: number;\n}\n\nexport interface VmSorterEntry {\n keys: any[];\n rowOffset: number;\n rowLen: number;\n rowData?: Uint8Array;\n}\n\nexport interface VmSorter {\n keyInfo: VmKeyInfo;\n entries: VmSorterEntry[];\n readIdx: number;\n isSorted: boolean;\n maxK?: number;\n}\n\nexport interface VmAggBucket {\n hash: number;\n keys: any[];\n count: number;\n sum: number;\n min_val: number;\n max_val: number;\n has_val: boolean;\n}\n\nexport interface VmAggregator {\n mode: number; // 0 = hash, 1 = stream\n startKeyReg: number;\n numKeys: number;\n capacity: number;\n occupiedCount: number;\n readIdx: number;\n buckets: VmAggBucket[];\n}\n\nexport interface VmContext {\n pc: number;\n status: VmStatus;\n fault_page_id: number;\n resultCount: number;\n resultOffset: number;\n arenaOffset: number;\n maxQueryMemory: number;\n rowsAffected: number;\n registers: (number | bigint | string | Uint8Array | null)[];\n cursor: VmCursor;\n cursors: VmCursor[];\n keyInfos: VmKeyInfo[];\n sorters: VmSorter[];\n aggregators: VmAggregator[];\n table: TableMeta | null;\n tables?: TableMeta[];\n outputColumns?: ColumnMeta[];\n udfs?: Record<number, (...args: any[]) => any>;\n inSets?: Set<any>[];\n}\n\nexport function createVmContext(): VmContext {\n const cursors: VmCursor[] = Array.from({ length: 16 }, () => createVmCursor());\n return {\n pc: 0,\n status: VmStatus.RUNNING,\n fault_page_id: 0,\n resultCount: 0,\n resultOffset: 0,\n arenaOffset: 0,\n maxQueryMemory: DEFAULT_MAX_QUERY_MEMORY,\n rowsAffected: 0,\n registers: new Array(64).fill(null),\n cursor: cursors[0],\n cursors,\n keyInfos: [],\n sorters: [],\n aggregators: [],\n table: null,\n tables: undefined,\n outputColumns: undefined,\n inSets: [],\n };\n}\n\nexport function resetVmContext(\n ctx: VmContext,\n table?: TableMeta,\n tables?: TableMeta[],\n): void {\n ctx.pc = 0;\n ctx.status = VmStatus.RUNNING;\n ctx.fault_page_id = 0;\n ctx.resultCount = 0;\n ctx.resultOffset = 0;\n ctx.arenaOffset = 0;\n ctx.maxQueryMemory = DEFAULT_MAX_QUERY_MEMORY;\n ctx.rowsAffected = 0;\n ctx.registers.fill(null);\n for (let i = 0; i < ctx.cursors.length; i++) {\n const c = ctx.cursors[i];\n c.pageId = 0;\n c.rootPageId = 0;\n c.slotIdx = 0;\n c.cellIdx = 0;\n c.rowOffset = 0;\n c.btreeDepth = 0;\n c.flags = 0;\n }\n ctx.cursor = ctx.cursors[0];\n ctx.keyInfos = [];\n ctx.sorters = [];\n ctx.aggregators = [];\n ctx.table = table ?? null;\n ctx.tables = tables;\n ctx.outputColumns = undefined;\n ctx.inSets = [];\n}\n","export enum DataType {\n NULL = 0,\n INT32 = 1,\n INT64 = 2,\n FLOAT64 = 3,\n TEXT = 4,\n BLOB = 5,\n UUID = 6,\n ULID = 7,\n}\n\nexport enum ColumnFlag {\n NONE = 0,\n PRIMARY_KEY = 0x01,\n NOT_NULL = 0x02,\n INDEXED = 0x04,\n AUTO_INC = 0x08,\n}\n\nexport enum TableFlag {\n NONE = 0,\n ACTIVE = 0x01,\n SYSTEM = 0x02,\n}\n\nexport enum IndexFlag {\n NONE = 0,\n UNIQUE = 0x01,\n PRIMARY = 0x02,\n SPATIAL_VECTOR = 0x04,\n}\n\nexport enum OpCode {\n // Cursor / Scan\n OP_HALT = 0x00,\n OP_OPEN_CURSOR = 0x01,\n OP_REWIND = 0x02,\n OP_NEXT_ROW = 0x03,\n OP_COLUMN_INT = 0x04,\n OP_COLUMN_FLOAT = 0x05,\n OP_COLUMN_TEXT = 0x06,\n OP_COLUMN_BLOB = 0x07,\n OP_LAST = 0x08,\n OP_PREV_ROW = 0x09,\n OP_COLUMN_UUID = 0x0a,\n OP_COLUMN_ULID = 0x0b,\n OP_OPEN_INDEX = 0x0c,\n OP_INDEX_SEEK_EQ = 0x0d,\n OP_INDEX_SEEK_GE = 0x0e,\n OP_INDEX_NEXT = 0x0f,\n\n // Logic / Control\n OP_IS_NULL = 0x10,\n OP_IS_NOT_NULL = 0x11,\n OP_EQ = 0x12,\n OP_NE = 0x13,\n OP_GT = 0x14,\n OP_GE = 0x15,\n OP_LT = 0x16,\n OP_LE = 0x17,\n OP_JUMP = 0x18,\n OP_STR_LIKE = 0x19,\n OP_STR_NOT_LIKE = 0x1a,\n OP_STR_CONTAINS = 0x1b,\n OP_STR_STARTS_WITH = 0x1c,\n OP_STR_ENDS_WITH = 0x1d,\n OP_LOAD_BLOB = 0x1e,\n OP_IN = 0x1f,\n\n // Data / Output\n OP_LOAD_INT = 0x20,\n OP_LOAD_FLOAT = 0x21,\n OP_LOAD_TEXT = 0x22,\n OP_LOAD_NULL = 0x23,\n OP_EMIT_ROW = 0x24,\n OP_RESULT_ROW = 0x25,\n OP_OFFSET = 0x26,\n OP_LIMIT = 0x27,\n OP_CALL_UDF = 0x28,\n OP_STR_LOWER = 0x29,\n OP_STR_UPPER = 0x2a,\n OP_STR_LENGTH = 0x2b,\n OP_STR_SUBSTR = 0x2c,\n OP_STR_TRIM = 0x2d,\n OP_MATH_ABS = 0x2e,\n OP_MATH_ROUND = 0x2f,\n\n // Sorter (ORDER BY)\n OP_SORTER_OPEN = 0x30,\n OP_SORTER_INSERT = 0x31,\n OP_SORTER_SORT = 0x32,\n OP_SORTER_NEXT = 0x33,\n\n // Math Functions\n OP_MATH_FLOOR = 0x34,\n OP_MATH_CEIL = 0x35,\n\n // Binary Arithmetic (3VL)\n OP_ADD = 0x36,\n OP_SUB = 0x37,\n OP_MUL = 0x38,\n OP_DIV = 0x39,\n OP_MOD = 0x3a,\n\n // Subquery Framing\n OP_ENTER_SUBQUERY = 0x3b,\n OP_RETURN_SUBQUERY = 0x3c,\n\n // Multi-Arg Functions\n OP_STR_CONCAT = 0x3d,\n OP_COALESCE = 0x3e,\n OP_COPY = 0x3f,\n\n // Agg (GROUP BY)\n OP_AGG_INIT = 0x40,\n OP_AGG_STEP = 0x41,\n OP_AGG_NEXT = 0x42,\n OP_AGG_FINAL = 0x43,\n\n // Register Null Checks\n OP_REG_IS_NULL = 0x48,\n OP_REG_IS_NOT_NULL = 0x49,\n\n // DML Mutation\n OP_DELETE_ROW = 0x50,\n OP_UPDATE_FIELD = 0x51,\n OP_INSERT_ROW = 0x52,\n}\n\nexport enum VmStatus {\n RUNNING = 0,\n DONE = 1,\n PAGE_FAULT = 2,\n BUFFER_FULL = 3,\n ERROR = 4,\n TIMEOUT = 5,\n ARENA_EXHAUSTED = 6,\n INVALID_BYTECODE = 7,\n}\n\nexport type DataTypeString =\n | 'INT32' | 'INT64' | 'FLOAT64' | 'TEXT' | 'BLOB' | 'UUID' | 'ULID'\n | 'int32' | 'int64' | 'float64' | 'text' | 'blob' | 'uuid' | 'ulid';\n\nexport interface ColumnDefinition {\n name: string;\n type: DataTypeString | DataType;\n primaryKey?: boolean;\n notNull?: boolean;\n autoInc?: boolean;\n autoIncrement?: boolean;\n indexed?: boolean;\n flags?: {\n primaryKey?: boolean;\n notNull?: boolean;\n autoInc?: boolean;\n autoIncrement?: boolean;\n indexed?: boolean;\n };\n}\n\nexport interface ColumnMeta {\n type: DataType;\n flags: number;\n colOffset: number; // Offset within the fixed slice\n name: string;\n}\n\nexport interface TableDescriptor {\n tableId: number;\n columnCount: number;\n rootPageId: number;\n colCatalogPageId: number;\n name: string;\n flags: number;\n rowCountEstimate: number;\n autoIncNext: bigint;\n}\n\nexport interface IndexDescriptor {\n indexId: number;\n tableId: number;\n rootPageId: number;\n columnCount: number;\n flags: number;\n columnIndices: number[];\n colDirections: number[];\n name: string;\n}\n\nexport interface CatalogPageHeader {\n pageType: number;\n flags: number;\n colCountInPage: number;\n tableId: number;\n startColIndex: number;\n nextColCatalogPageId: number;\n pageChecksum: number;\n}\n\nexport type JoinType = 'inner' | 'left';\n\nexport interface TableMeta {\n tableId: number;\n columnCount: number;\n rootPageId: number;\n colCatalogPageId: number;\n name: string;\n flags: number;\n rowCountEstimate: number;\n autoIncNext: bigint;\n columns: ColumnMeta[];\n primaryKey?: string[];\n indexes?: IndexDescriptor[];\n schemaVersion?: number;\n}\n\n// Backward-compat alias\nexport type TableColumnMeta = ColumnMeta;\n\nexport type DbValue = number | bigint | string | Uint8Array | null;\nexport type DbRow = Record<string, DbValue>;\n\n// Error Taxonomy\nexport class RowSizeLimitExceededError extends Error {\n constructor(size: number, limit: number = 2048) {\n super(`Row size (${size} bytes) exceeds maximum limit of ${limit} bytes`);\n this.name = 'RowSizeLimitExceededError';\n }\n}\n\nexport class NotNullConstraintError extends Error {\n constructor(columnName: string, tableName?: string) {\n super(`NOT NULL constraint failed: ${tableName ? tableName + '.' : ''}${columnName}`);\n this.name = 'NotNullConstraintError';\n }\n}\n\nexport interface IndexOptions {\n unique?: boolean;\n name?: string;\n}\n\nexport interface TransactionOptions {\n origin?: 'local' | 'remote' | string;\n meta?: Record<string, any>;\n}\n\nexport interface UpsertOptions extends TransactionOptions {\n conflictTarget?: string | string[];\n mode?: 'merge' | 'replace' | 'ignore';\n where?: (existingRow: DbRow, incomingRow: DbRow) => boolean;\n}\n\nexport interface MutationRecord {\n table: string;\n op: 'insert' | 'update' | 'delete';\n pk: DbValue | DbValue[] | Record<string, DbValue>;\n oldRow?: DbRow;\n newRow?: DbRow;\n changedColumns?: string[];\n}\n\nexport interface Changeset {\n txId: number;\n origin: string;\n meta?: Record<string, any>;\n changeCounter: number;\n schemaVersion: number;\n tables: string[];\n changes: MutationRecord[];\n coalesced(): MutationRecord[];\n}\n\nexport interface TableChangeEvent {\n tables: string[];\n origin: string;\n meta?: Record<string, any>;\n changeCounter: number;\n schemaVersion: number;\n crossTab: boolean;\n changeset?: Changeset;\n}\n\nexport interface SyncState {\n changeCounter: number;\n schemaVersion: number;\n}\n\nexport type BeforeCommitHook = (\n changeset: Changeset,\n tx: any,\n) => Promise<void> | void;\n\nexport type CommitHook = (changeset: Changeset) => void;\n\nexport type TableSubscriptionCallback = (event: TableChangeEvent) => void;\n\nexport type AlterTableOperation =\n | { type: 'renameTable'; newName: string }\n | { type: 'renameColumn'; from: string; to: string }\n | { type: 'addColumn'; column: ColumnDefinition; defaultValue?: DbValue }\n | { type: 'dropColumn'; column: string };\n\nexport class IdentifierTooLongError extends Error {\n constructor(identifier: string, limit: number = 64) {\n super(\n `Identifier \"${identifier}\" (${identifier.length} characters) exceeds maximum limit of ${limit} characters`,\n );\n this.name = 'IdentifierTooLongError';\n }\n}\n\nexport class ColumnAlreadyExistsError extends Error {\n constructor(columnName: string, tableName?: string) {\n super(\n tableName\n ? `Column \"${columnName}\" already exists on table \"${tableName}\"`\n : `Column \"${columnName}\" already exists`,\n );\n this.name = 'ColumnAlreadyExistsError';\n }\n}\n\nexport class CannotDropColumnError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CannotDropColumnError';\n }\n}\n\nexport class ColumnNotFoundError extends Error {\n constructor(columnName: string, tableName?: string) {\n super(\n tableName\n ? `Column \"${columnName}\" not found on table \"${tableName}\"`\n : `Column \"${columnName}\" not found`,\n );\n this.name = 'ColumnNotFoundError';\n }\n}\n\nexport class TableNotFoundError extends Error {\n constructor(tableName: string) {\n super(`Table not found: \"${tableName}\"`);\n this.name = 'TableNotFoundError';\n }\n}\n\nexport class TableAlreadyExistsError extends Error {\n constructor(tableName: string) {\n super(`Table already exists: \"${tableName}\"`);\n this.name = 'TableAlreadyExistsError';\n }\n}\n\nexport class IndexNotFoundError extends Error {\n constructor(indexName: string) {\n super(`Index not found: \"${indexName}\"`);\n this.name = 'IndexNotFoundError';\n }\n}\n\nexport class IndexAlreadyExistsError extends Error {\n constructor(indexName: string) {\n super(`Index already exists: \"${indexName}\"`);\n this.name = 'IndexAlreadyExistsError';\n }\n}\n\nexport class UniqueConstraintViolationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UniqueConstraintViolationError';\n }\n}\n\nexport class CorruptPageError extends Error {\n constructor(public pageId: number, public storedChecksum: number | string, public computedChecksum?: number | string) {\n super(\n `Corrupted page detected (pageId: ${pageId}): stored checksum ${storedChecksum}${\n computedChecksum !== undefined ? `, computed checksum ${computedChecksum}` : ''\n }`\n );\n this.name = 'CorruptPageError';\n }\n}\n\nexport class TooManyColumnsError extends Error {\n constructor(columnCount: number, limit: number = 256) {\n super(`Too many columns: ${columnCount} exceeds maximum limit of ${limit} columns`);\n this.name = 'TooManyColumnsError';\n }\n}\n\nexport class TooManyTablesError extends Error {\n constructor(tableCount: number, limit: number = 16) {\n super(`Too many tables: ${tableCount} exceeds maximum limit of ${limit} tables on Page 1`);\n this.name = 'TooManyTablesError';\n }\n}\n\nexport class TooManyIndexesError extends Error {\n constructor(indexCount: number, limit: number = 8) {\n super(`Too many indexes: ${indexCount} exceeds maximum limit of ${limit} indexes on Page 1`);\n this.name = 'TooManyIndexesError';\n }\n}\n\nexport class UnsupportedFormatVersionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UnsupportedFormatVersionError';\n }\n}\n\nexport class InvalidDatabaseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidDatabaseError';\n }\n}\n\nexport class QueryArenaExhaustedError extends Error {\n constructor(message: string = 'Transient query arena exhausted') {\n super(message);\n this.name = 'QueryArenaExhaustedError';\n }\n}\n\nexport class TooManyCursorsError extends Error {\n constructor(cursorCount: number, limit: number = 16) {\n super(`Too many cursors: ${cursorCount} exceeds maximum limit of ${limit} cursors`);\n this.name = 'TooManyCursorsError';\n }\n}\n\nexport class TooManyRegistersError extends Error {\n constructor(registerCount: number, limit: number = 64) {\n super(`Too many registers: ${registerCount} exceeds maximum limit of ${limit} registers`);\n this.name = 'TooManyRegistersError';\n }\n}\n\nexport class SubqueryNestingTooDeepError extends Error {\n constructor(depth: number, limit: number = 7) {\n super(`Subquery nesting depth ${depth} exceeds maximum limit of ${limit}`);\n this.name = 'SubqueryNestingTooDeepError';\n }\n}\n\nexport class QueryTimeoutError extends Error {\n constructor(message: string = 'Query execution exceeded maximum cycle limit (TIMEOUT)') {\n super(message);\n this.name = 'QueryTimeoutError';\n }\n}\n\nexport class InvalidBytecodeError extends Error {\n constructor(message: string = 'Malformed bytecode execution halted (INVALID_BYTECODE)') {\n super(message);\n this.name = 'InvalidBytecodeError';\n }\n}\n\nexport class TooManyOrderByColumnsError extends Error {\n constructor(count: number, limit: number = 8) {\n super(`Too many order by columns: ${count} exceeds maximum limit of ${limit}`);\n this.name = 'TooManyOrderByColumnsError';\n }\n}\n\nexport class TooManyGroupByColumnsError extends Error {\n constructor(count: number, limit: number = 8) {\n super(`Too many group by columns: ${count} exceeds maximum limit of ${limit}`);\n this.name = 'TooManyGroupByColumnsError';\n }\n}\n\nexport class UnknownFunctionError extends Error {\n constructor(funcName: string) {\n super(`Function \"${funcName}\" is neither a native built-in function nor a registered UDF`);\n this.name = 'UnknownFunctionError';\n }\n}\n\nexport class AggregateNotAllowedInWhereError extends Error {\n constructor(funcName: string) {\n super(`Aggregate function \"${funcName}\" cannot be used in WHERE clause`);\n this.name = 'AggregateNotAllowedInWhereError';\n }\n}\n\nexport class CorruptWalHeaderError extends Error {\n constructor(message: string = 'Corrupted WAL file header detected') {\n super(message);\n this.name = 'CorruptWalHeaderError';\n }\n}\n\nexport class CorruptWalFrameError extends Error {\n constructor(message: string = 'Corrupted WAL frame detected') {\n super(message);\n this.name = 'CorruptWalFrameError';\n }\n}\n\nexport * from '../shared/vm_context.js';\nexport * from '../shared/page_provider.js';\n","import { IVfsAdapter } from './vfs.js';\n\nexport class MemoryVfsAdapter implements IVfsAdapter {\n readonly name = 'memory' as const;\n readonly isSynchronous = true;\n\n private pages = new Map<number, Uint8Array>();\n private walHeader: Uint8Array | null = null;\n private walFrames: Uint8Array[] = [];\n\n async readPage(pageId: number): Promise<Uint8Array | null> {\n const page = this.pages.get(pageId);\n if (!page) return null;\n return new Uint8Array(page); // return copy\n }\n\n async writePage(pageId: number, data: Uint8Array): Promise<void> {\n const copy = new Uint8Array(data.byteLength);\n copy.set(data);\n this.pages.set(pageId, copy);\n }\n\n async writePages(pages: Array<{ pageId: number; data: Uint8Array }>): Promise<void> {\n for (const { pageId, data } of pages) {\n await this.writePage(pageId, data);\n }\n }\n\n async flush(): Promise<void> {\n // In-memory data is immediately durable in RAM\n }\n\n async truncate(pageCount: number): Promise<void> {\n for (const key of Array.from(this.pages.keys())) {\n if (key > pageCount) {\n this.pages.delete(key);\n }\n }\n }\n\n snapshot(): Map<number, Uint8Array> {\n const snap = new Map<number, Uint8Array>();\n for (const [k, v] of this.pages.entries()) {\n snap.set(k, new Uint8Array(v));\n }\n return snap;\n }\n\n restoreSnapshot(snap: Map<number, Uint8Array>): void {\n this.pages.clear();\n for (const [k, v] of snap.entries()) {\n this.pages.set(k, new Uint8Array(v));\n }\n }\n\n // --- Write-Ahead Log Methods ---\n\n async readWalHeader(): Promise<Uint8Array | null> {\n if (!this.walHeader) return null;\n return new Uint8Array(this.walHeader);\n }\n\n async writeWalHeader(header: Uint8Array): Promise<void> {\n const copy = new Uint8Array(header.byteLength);\n copy.set(header);\n this.walHeader = copy;\n }\n\n async readWalFrame(frameIndex: number): Promise<Uint8Array | null> {\n const frame = this.walFrames[frameIndex];\n if (!frame) return null;\n return new Uint8Array(frame);\n }\n\n async readWalFrames(startFrameIndex: number, maxFrames?: number): Promise<Uint8Array[]> {\n const end = maxFrames !== undefined ? startFrameIndex + maxFrames : this.walFrames.length;\n const slice = this.walFrames.slice(startFrameIndex, end);\n return slice.map((f) => new Uint8Array(f));\n }\n\n async appendWalFrames(frames: Uint8Array[]): Promise<void> {\n for (const frame of frames) {\n const copy = new Uint8Array(frame.byteLength);\n copy.set(frame);\n this.walFrames.push(copy);\n }\n }\n\n async flushWal(): Promise<void> {\n // In-memory frames are immediately durable in RAM\n }\n\n async truncateWal(frameIndex: number): Promise<void> {\n if (frameIndex === 0) {\n this.walFrames = [];\n this.walHeader = null;\n } else {\n this.walFrames.length = Math.min(this.walFrames.length, frameIndex);\n }\n }\n\n async getWalFrameCount(): Promise<number> {\n return this.walFrames.length;\n }\n\n async close(): Promise<void> {\n // Memory pages remain resident for database re-open semantics\n }\n}\n","import { IVfsAdapter } from './vfs.js';\n\nexport class IndexedDbVfsAdapter implements IVfsAdapter {\n readonly name = 'idb' as const;\n readonly isSynchronous = false;\n\n private dbName: string;\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n constructor(dbName: string) {\n this.dbName = `webdb_${dbName}`;\n }\n\n private getDb(): Promise<IDBDatabase> {\n if (!this.dbPromise) {\n this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const idb = globalThis.indexedDB;\n if (!idb) {\n reject(new Error('IndexedDB is not available in the current environment'));\n return;\n }\n\n const request = idb.open(this.dbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains('pages')) {\n db.createObjectStore('pages');\n }\n if (!db.objectStoreNames.contains('wal_frames')) {\n db.createObjectStore('wal_frames');\n }\n if (!db.objectStoreNames.contains('wal_meta')) {\n db.createObjectStore('wal_meta');\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n return this.dbPromise;\n }\n\n async readPage(pageId: number): Promise<Uint8Array | null> {\n const db = await this.getDb();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction('pages', 'readonly');\n const store = tx.objectStore('pages');\n const request = store.get(pageId);\n\n request.onsuccess = () => {\n const result = request.result;\n if (!result) {\n resolve(null);\n } else {\n resolve(result instanceof Uint8Array ? result : new Uint8Array(result));\n }\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async writePage(pageId: number, data: Uint8Array): Promise<void> {\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction('pages', 'readwrite');\n const store = tx.objectStore('pages');\n // Store a clone of the byte slice\n const copy = new Uint8Array(data.byteLength);\n copy.set(data);\n store.put(copy, pageId);\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n }\n\n async writePages(pages: Array<{ pageId: number; data: Uint8Array }>): Promise<void> {\n if (pages.length === 0) return;\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction('pages', 'readwrite');\n const store = tx.objectStore('pages');\n\n for (const { pageId, data } of pages) {\n const copy = new Uint8Array(data.byteLength);\n copy.set(data);\n store.put(copy, pageId);\n }\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n }\n\n async flush(): Promise<void> {\n // IndexedDB transactions are auto-flushed upon transaction completion\n }\n\n async truncate(pageCount: number): Promise<void> {\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction('pages', 'readwrite');\n const store = tx.objectStore('pages');\n const range = IDBKeyRange.lowerBound(pageCount, true);\n const request = store.delete(range);\n\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n }\n\n // --- Write-Ahead Log Methods ---\n\n async readWalHeader(): Promise<Uint8Array | null> {\n const db = await this.getDb();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction('wal_meta', 'readonly');\n const store = tx.objectStore('wal_meta');\n const request = store.get('header');\n\n request.onsuccess = () => {\n const result = request.result;\n if (!result) {\n resolve(null);\n } else {\n resolve(result instanceof Uint8Array ? result : new Uint8Array(result));\n }\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async writeWalHeader(header: Uint8Array): Promise<void> {\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction('wal_meta', 'readwrite');\n const store = tx.objectStore('wal_meta');\n const copy = new Uint8Array(header.byteLength);\n copy.set(header);\n store.put(copy, 'header');\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n }\n\n async readWalFrame(frameIndex: number): Promise<Uint8Array | null> {\n const db = await this.getDb();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction('wal_frames', 'readonly');\n const store = tx.objectStore('wal_frames');\n const request = store.get(frameIndex);\n\n request.onsuccess = () => {\n const result = request.result;\n if (!result) {\n resolve(null);\n } else {\n resolve(result instanceof Uint8Array ? result : new Uint8Array(result));\n }\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async readWalFrames(startFrameIndex: number, maxFrames?: number): Promise<Uint8Array[]> {\n const db = await this.getDb();\n return new Promise<Uint8Array[]>((resolve, reject) => {\n const tx = db.transaction('wal_frames', 'readonly');\n const store = tx.objectStore('wal_frames');\n const frames: Uint8Array[] = [];\n const range = maxFrames !== undefined\n ? IDBKeyRange.bound(startFrameIndex, startFrameIndex + maxFrames - 1)\n : IDBKeyRange.lowerBound(startFrameIndex, false);\n const request = store.openCursor(range);\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n const val = cursor.value;\n frames.push(val instanceof Uint8Array ? val : new Uint8Array(val));\n cursor.continue();\n } else {\n resolve(frames);\n }\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async appendWalFrames(frames: Uint8Array[]): Promise<void> {\n if (frames.length === 0) return;\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction('wal_frames', 'readwrite');\n const store = tx.objectStore('wal_frames');\n const countReq = store.count();\n\n countReq.onsuccess = () => {\n let nextIdx = countReq.result;\n for (const frame of frames) {\n const copy = new Uint8Array(frame.byteLength);\n copy.set(frame);\n store.put(copy, nextIdx++);\n }\n };\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n }\n\n async flushWal(): Promise<void> {\n // IndexedDB transactions are auto-flushed upon completion\n }\n\n async truncateWal(frameIndex: number): Promise<void> {\n const db = await this.getDb();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(['wal_frames', 'wal_meta'], 'readwrite');\n const framesStore = tx.objectStore('wal_frames');\n const metaStore = tx.objectStore('wal_meta');\n\n if (frameIndex === 0) {\n framesStore.clear();\n metaStore.delete('header');\n } else {\n const range = IDBKeyRange.lowerBound(frameIndex, false);\n framesStore.delete(range);\n }\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n });\n }\n\n async getWalFrameCount(): Promise<number> {\n const db = await this.getDb();\n return new Promise<number>((resolve, reject) => {\n const tx = db.transaction('wal_frames', 'readonly');\n const store = tx.objectStore('wal_frames');\n const request = store.count();\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async close(): Promise<void> {\n if (this.dbPromise) {\n const db = await this.dbPromise;\n db.close();\n this.dbPromise = null;\n }\n }\n}\n","import { IVfsAdapter } from './vfs.js';\n\nexport class OpfsVfsAdapter implements IVfsAdapter {\n readonly name = 'opfs' as const;\n readonly isSynchronous: boolean;\n\n private dbName: string;\n private rootDir: FileSystemDirectoryHandle | null = null;\n private dbFileHandle: FileSystemFileHandle | null = null;\n private walFileHandle: FileSystemFileHandle | null = null;\n\n // SyncAccessHandles (available in Dedicated Web Workers)\n private dbSyncHandle: any = null;\n private walSyncHandle: any = null;\n\n constructor(dbName: string) {\n this.dbName = dbName;\n this.isSynchronous = typeof (globalThis as any).FileSystemSyncAccessHandle !== 'undefined';\n }\n\n private async initHandles(): Promise<void> {\n if (this.rootDir) return;\n\n if (!navigator?.storage?.getDirectory) {\n throw new Error('OPFS (Origin Private File System) is not available in the current environment');\n }\n\n this.rootDir = await navigator.storage.getDirectory();\n this.dbFileHandle = await this.rootDir.getFileHandle(`${this.dbName}.db`, { create: true });\n this.walFileHandle = await this.rootDir.getFileHandle(`${this.dbName}.wal`, { create: true });\n\n if (this.isSynchronous) {\n try {\n this.dbSyncHandle = await (this.dbFileHandle as any).createSyncAccessHandle();\n this.walSyncHandle = await (this.walFileHandle as any).createSyncAccessHandle();\n } catch {\n // Fallback to async handles if sync handles cannot be acquired\n }\n }\n }\n\n async readPage(pageId: number): Promise<Uint8Array | null> {\n await this.initHandles();\n const offset = (pageId - 1) * 4096;\n\n if (this.dbSyncHandle) {\n const size = this.dbSyncHandle.getSize();\n if (offset + 4096 > size) return null;\n const buffer = new Uint8Array(4096);\n this.dbSyncHandle.read(buffer, { at: offset });\n return buffer;\n }\n\n const file = await this.dbFileHandle!.getFile();\n if (offset + 4096 > file.size) return null;\n const slice = file.slice(offset, offset + 4096);\n const arrayBuf = await slice.arrayBuffer();\n return new Uint8Array(arrayBuf);\n }\n\n async writePage(pageId: number, data: Uint8Array): Promise<void> {\n await this.initHandles();\n const offset = (pageId - 1) * 4096;\n\n if (this.dbSyncHandle) {\n this.dbSyncHandle.write(data, { at: offset });\n return;\n }\n\n const writable = await (this.dbFileHandle as any).createWritable({ keepExistingData: true });\n await writable.seek(offset);\n await writable.write(data);\n await writable.close();\n }\n\n async writePages(pages: Array<{ pageId: number; data: Uint8Array }>): Promise<void> {\n for (const { pageId, data } of pages) {\n await this.writePage(pageId, data);\n }\n }\n\n async flush(): Promise<void> {\n if (this.dbSyncHandle) {\n this.dbSyncHandle.flush();\n }\n }\n\n async truncate(pageCount: number): Promise<void> {\n await this.initHandles();\n const newSize = pageCount * 4096;\n if (this.dbSyncHandle) {\n this.dbSyncHandle.truncate(newSize);\n return;\n }\n const writable = await (this.dbFileHandle as any).createWritable({ keepExistingData: true });\n await writable.truncate(newSize);\n await writable.close();\n }\n\n // --- Write-Ahead Log Methods ---\n\n async readWalHeader(): Promise<Uint8Array | null> {\n await this.initHandles();\n if (this.walSyncHandle) {\n const size = this.walSyncHandle.getSize();\n if (size < 32) return null;\n const header = new Uint8Array(32);\n this.walSyncHandle.read(header, { at: 0 });\n return header;\n }\n const file = await this.walFileHandle!.getFile();\n if (file.size < 32) return null;\n const slice = file.slice(0, 32);\n return new Uint8Array(await slice.arrayBuffer());\n }\n\n async writeWalHeader(header: Uint8Array): Promise<void> {\n await this.initHandles();\n if (this.walSyncHandle) {\n this.walSyncHandle.write(header, { at: 0 });\n return;\n }\n const writable = await (this.walFileHandle as any).createWritable({ keepExistingData: true });\n await writable.seek(0);\n await writable.write(header);\n await writable.close();\n }\n\n async readWalFrame(frameIndex: number): Promise<Uint8Array | null> {\n await this.initHandles();\n const offset = 32 + (frameIndex * 4128);\n if (this.walSyncHandle) {\n const size = this.walSyncHandle.getSize();\n if (offset >= size) return null;\n const readLen = Math.min(4128, size - offset);\n const frame = new Uint8Array(readLen);\n this.walSyncHandle.read(frame, { at: offset });\n return frame;\n }\n const file = await this.walFileHandle!.getFile();\n if (offset >= file.size) return null;\n const readLen = Math.min(4128, file.size - offset);\n const slice = file.slice(offset, offset + readLen);\n return new Uint8Array(await slice.arrayBuffer());\n }\n\n async readWalFrames(startFrameIndex: number, maxFrames?: number): Promise<Uint8Array[]> {\n const frames: Uint8Array[] = [];\n let idx = startFrameIndex;\n const limit = maxFrames !== undefined ? startFrameIndex + maxFrames : Infinity;\n\n while (idx < limit) {\n const frame = await this.readWalFrame(idx);\n if (!frame) break;\n frames.push(frame);\n idx++;\n }\n return frames;\n }\n\n async appendWalFrames(frames: Uint8Array[]): Promise<void> {\n await this.initHandles();\n if (this.walSyncHandle) {\n let offset = Math.max(32, this.walSyncHandle.getSize());\n for (const frame of frames) {\n this.walSyncHandle.write(frame, { at: offset });\n offset += frame.byteLength;\n }\n return;\n }\n const file = await this.walFileHandle!.getFile();\n const writable = await (this.walFileHandle as any).createWritable({ keepExistingData: true });\n await writable.seek(Math.max(32, file.size));\n for (const frame of frames) {\n await writable.write(frame);\n }\n await writable.close();\n }\n\n async flushWal(): Promise<void> {\n if (this.walSyncHandle) {\n this.walSyncHandle.flush();\n }\n }\n\n async truncateWal(frameIndex: number): Promise<void> {\n await this.initHandles();\n const newSize = frameIndex === 0 ? 0 : 32 + (frameIndex * 4128);\n if (this.walSyncHandle) {\n this.walSyncHandle.truncate(newSize);\n return;\n }\n const writable = await (this.walFileHandle as any).createWritable({\n keepExistingData: frameIndex > 0,\n });\n await writable.truncate(newSize);\n await writable.close();\n }\n\n async getWalFrameCount(): Promise<number> {\n await this.initHandles();\n let size = 0;\n if (this.walSyncHandle) {\n size = this.walSyncHandle.getSize();\n } else {\n const file = await this.walFileHandle!.getFile();\n size = file.size;\n }\n if (size <= 32) return 0;\n return Math.ceil((size - 32) / 4128);\n }\n\n async close(): Promise<void> {\n if (this.dbSyncHandle) {\n this.dbSyncHandle.close();\n this.dbSyncHandle = null;\n }\n if (this.walSyncHandle) {\n this.walSyncHandle.close();\n this.walSyncHandle = null;\n }\n this.dbFileHandle = null;\n this.walFileHandle = null;\n this.rootDir = null;\n }\n}\n","/**\n * CRC32 IEEE 802.3 standard implementation (polynomial 0xEDB88320).\n * Used for page-level integrity checks, WAL frame verification, and torn-write detection.\n */\n\nconst CRC_TABLE = new Uint32Array(256);\n\n// Precompute CRC32 lookup table\nfor (let i = 0; i < 256; i++) {\n let c = i;\n for (let k = 0; k < 8; k++) {\n c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);\n }\n CRC_TABLE[i] = c >>> 0;\n}\n\n/**\n * Computes CRC32 checksum across a Uint8Array slice.\n */\nexport function crc32(data: Uint8Array, start: number = 0, length: number = data.byteLength - start): number {\n let crc = 0xffffffff;\n const end = start + length;\n for (let i = start; i < end; i++) {\n crc = CRC_TABLE[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Computes the CRC32 checksum of a 4KB page.\n * In WebDB slotted pages, bytes 12..15 store the checksum itself, so they are treated as 0 during computation.\n */\nexport function computePageChecksum(pageBytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < 4096; i++) {\n // Treat bytes 12..15 as zeroed\n const byte = (i >= 12 && i <= 15) ? 0 : pageBytes[i];\n crc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Computes the CRC32 checksum of Page 1.\n * Bytes 28..31 store Page 1's checksum, so they are treated as 0 during computation.\n */\nexport function computePage1Checksum(pageBytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < 4096; i++) {\n // Treat bytes 28..31 as zeroed\n const byte = (i >= 28 && i <= 31) ? 0 : pageBytes[i];\n crc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Computes CRC32 checksum of a WAL Frame.\n * Checksum is calculated across header bytes 0..23 concatenated with 4096 page payload bytes (bytes 32..4127).\n */\nexport function computeWalFrameChecksum(frameBytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < 24; i++) {\n crc = CRC_TABLE[(crc ^ frameBytes[i]) & 0xff] ^ (crc >>> 8);\n }\n const end = Math.min(frameBytes.byteLength, 4128);\n for (let i = 32; i < end; i++) {\n crc = CRC_TABLE[(crc ^ frameBytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n","/**\n * Shared C Runtime & Memory Helpers for WebAssembly Memory and Direct Buffers\n *\n * Provides drop-in C-standard library functions (memcpy, memset, memcmp)\n * and pointer-dereferencing primitives (read_u32, write_u32, get_bit, set_bit, etc.)\n * matching C99 / wasm32-nostdlib semantics.\n */\n\n// ============================================================================\n// Standard C Memory Functions (<string.h>)\n// ============================================================================\n\n/**\n * C: void *memcpy(void *dest, const void *src, size_t n);\n * Copies n bytes from memory area src to memory area dest.\n */\nexport function memcpy(\n dest: Uint8Array | DataView,\n dest_offset: number,\n src: Uint8Array | DataView,\n src_offset: number,\n n: number,\n): void {\n const d = dest instanceof Uint8Array ? dest : new Uint8Array(dest.buffer, dest.byteOffset, dest.byteLength);\n const s = src instanceof Uint8Array ? src : new Uint8Array(src.buffer, src.byteOffset, src.byteLength);\n d.set(s.subarray(src_offset, src_offset + n), dest_offset);\n}\n\n/**\n * C: void *memset(void *s, int c, size_t n);\n * Fills the first n bytes of the memory area pointed to by s with the constant byte c.\n */\nexport function memset(\n dest: Uint8Array | DataView,\n dest_offset: number,\n c: number,\n n: number,\n): void {\n const d = dest instanceof Uint8Array ? dest : new Uint8Array(dest.buffer, dest.byteOffset, dest.byteLength);\n d.fill(c & 0xff, dest_offset, dest_offset + n);\n}\n\n/**\n * C: int memcmp(const void *s1, const void *s2, size_t n);\n * Compares the first n bytes of the memory areas s1 and s2.\n * Returns <0, 0, or >0.\n */\nexport function memcmp(\n s1: Uint8Array | DataView,\n s1_offset: number,\n s2: Uint8Array | DataView,\n s2_offset: number,\n n: number,\n): number {\n const b1 = s1 instanceof Uint8Array ? s1 : new Uint8Array(s1.buffer, s1.byteOffset, s1.byteLength);\n const b2 = s2 instanceof Uint8Array ? s2 : new Uint8Array(s2.buffer, s2.byteOffset, s2.byteLength);\n for (let i = 0; i < n; i++) {\n const diff = b1[s1_offset + i] - b2[s2_offset + i];\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\n/**\n * C: size_t strlen(const char *s);\n * Returns length of null-terminated string or JS string length.\n */\nexport function strlen(s: string): number {\n return s.length;\n}\n\n// ============================================================================\n// Direct Pointer Memory Access Primitives (Little-Endian, zero heap allocation)\n// Matching C: *(uint32_t*)(ptr), etc.\n// ============================================================================\n\nexport function read_u8(view: DataView | Uint8Array, offset: number): number {\n return view instanceof Uint8Array ? view[offset] : view.getUint8(offset);\n}\n\nexport function write_u8(\n view: DataView | Uint8Array,\n offset: number,\n val: number,\n): void {\n if (view instanceof Uint8Array) {\n view[offset] = val & 0xff;\n } else {\n view.setUint8(offset, val & 0xff);\n }\n}\n\nexport function read_u16(view: DataView, offset: number): number {\n return view.getUint16(offset, true);\n}\n\nexport function write_u16(view: DataView, offset: number, val: number): void {\n view.setUint16(offset, val & 0xffff, true);\n}\n\nexport function read_u32(view: DataView, offset: number): number {\n return view.getUint32(offset, true);\n}\n\nexport function write_u32(view: DataView, offset: number, val: number): void {\n view.setUint32(offset, val >>> 0, true);\n}\n\nexport function read_i32(view: DataView, offset: number): number {\n return view.getInt32(offset, true);\n}\n\nexport function write_i32(view: DataView, offset: number, val: number): void {\n view.setInt32(offset, val | 0, true);\n}\n\nexport function read_f64(view: DataView, offset: number): number {\n return view.getFloat64(offset, true);\n}\n\nexport function write_f64(view: DataView, offset: number, val: number): void {\n view.setFloat64(offset, val, true);\n}\n\nexport function read_u64(view: DataView, offset: number): bigint {\n return view.getBigUint64(offset, true);\n}\n\nexport function write_u64(view: DataView, offset: number, val: bigint): void {\n view.setBigUint64(offset, val, true);\n}\n\nexport function read_i64(view: DataView, offset: number): bigint {\n return view.getBigInt64(offset, true);\n}\n\nexport function write_i64(view: DataView, offset: number, val: bigint): void {\n view.setBigInt64(offset, val, true);\n}\n\n// ============================================================================\n// Bitwise Bitmask Manipulation (C macros: GET_BIT, SET_BIT, CLEAR_BIT)\n// ============================================================================\n\nexport function get_bit(mask: Uint8Array, offset_or_bit: number, bit_idx?: number): number {\n if (bit_idx !== undefined) {\n return (mask[offset_or_bit + (bit_idx >> 3)] & (1 << (bit_idx & 7))) !== 0 ? 1 : 0;\n }\n return (mask[offset_or_bit >> 3] & (1 << (offset_or_bit & 7))) !== 0 ? 1 : 0;\n}\n\nexport function set_bit(mask: Uint8Array, offset_or_bit: number, bit_idx?: number): void {\n if (bit_idx !== undefined) {\n mask[offset_or_bit + (bit_idx >> 3)] |= (1 << (bit_idx & 7));\n } else {\n mask[offset_or_bit >> 3] |= (1 << (offset_or_bit & 7));\n }\n}\n\nexport function clear_bit(mask: Uint8Array, offset_or_bit: number, bit_idx?: number): void {\n if (bit_idx !== undefined) {\n mask[offset_or_bit + (bit_idx >> 3)] &= ~(1 << (bit_idx & 7));\n } else {\n mask[offset_or_bit >> 3] &= ~(1 << (offset_or_bit & 7));\n }\n}\n\n// ============================================================================\n// C Assertion Helper\n// ============================================================================\n\nexport function c_assert(cond: boolean, msg: string): asserts cond {\n if (!cond) {\n throw new Error(`Assertion failed: ${msg}`);\n }\n}\n","import {\n PAGE_SIZE,\n PAGE_HEADER_OFFSET_CHECKSUM,\n HEADER_OFFSET_PAGE_CHECKSUM,\n} from \"../../constants.ts\";\nimport { IVfsAdapter } from \"./vfs.ts\";\nimport { computePageChecksum, computePage1Checksum } from \"./crc32.ts\";\nimport { CorruptPageError } from \"../../types/index.ts\";\nimport { read_u32, write_u32 } from \"../../shared/c_runtime.ts\";\n\nexport interface IoOptions {\n vfs: IVfsAdapter;\n memory: WebAssembly.Memory | ArrayBuffer;\n}\n\n/**\n * Pure Block I/O layer for WebDB.\n *\n * Responsibilities:\n * - Reads/writes raw 4KB page blocks between IVfsAdapter and shared linear memory.\n * - Computes and verifies CRC32 checksums.\n * - Coalesces in-flight reads and flushes.\n * - Resolves PAGE_FAULT requests issued by the C Engine state machine.\n *\n * DOES NOT:\n * - Perform eviction candidate selection or Clock sweeps (handled in C Core).\n * - Maintain page-to-slot tables, pin counts, or reference bits (handled in C Core).\n * - Hold any reference to C-layer classes.\n */\nexport class Io {\n readonly vfs: IVfsAdapter;\n readonly buffer: ArrayBuffer;\n readonly uint8: Uint8Array;\n readonly view: DataView;\n\n private in_flight_flushes = new Map<number, Promise<void>>();\n private in_flight_reads = new Map<number, Promise<void>>();\n private coordinator: {\n isInTransaction(): boolean;\n spillUncommittedSlot(slotIdx: number, pageId: number): Promise<void>;\n hasSpilledPage(pageId: number): boolean;\n getSpilledPage(pageId: number): Uint8Array | null;\n onDirectPageWrite(pageId: number, data: Uint8Array): void;\n } | null = null;\n\n setTransactionCoordinator(coordinator: any): void {\n this.coordinator = coordinator;\n }\n\n isInTransaction(): boolean {\n return this.coordinator ? this.coordinator.isInTransaction() : false;\n }\n\n /**\n * Computes and writes the page-level CRC32 checksum into the slot header in linear memory.\n */\n stampSlotChecksum(slotIdx: number, pageId: number): void {\n const slot_offset = slotIdx * PAGE_SIZE;\n const page_bytes = this.uint8.subarray(\n slot_offset,\n slot_offset + PAGE_SIZE,\n );\n\n if (pageId === 1) {\n const chk = computePage1Checksum(page_bytes);\n write_u32(this.view, slot_offset + HEADER_OFFSET_PAGE_CHECKSUM, chk);\n } else {\n const chk = computePageChecksum(page_bytes);\n write_u32(this.view, slot_offset + PAGE_HEADER_OFFSET_CHECKSUM, chk);\n }\n }\n\n constructor(options: IoOptions) {\n if (!options.vfs) {\n throw new Error(\"Io requires a valid IVfsAdapter instance\");\n }\n\n if (!options.memory) {\n throw new Error(\n \"Io requires a valid memory buffer or WebAssembly.Memory\",\n );\n }\n\n this.vfs = options.vfs;\n\n this.buffer =\n options.memory instanceof WebAssembly.Memory\n ? options.memory.buffer\n : options.memory;\n\n this.uint8 = new Uint8Array(this.buffer);\n this.view = new DataView(this.buffer);\n }\n\n /**\n * Reads a page from VFS directly into slotIdx in linear memory.\n * Validates CRC32 checksum. If page does not exist in storage, zeroes the slot.\n */\n async readSlot(slotIdx: number, pageId: number): Promise<void> {\n if (pageId <= 0) {\n throw new Error(\n `Invalid page ID: ${pageId}. Page IDs must be positive integers.`,\n );\n }\n\n if (this.coordinator && this.coordinator.hasSpilledPage(pageId)) {\n const slot_offset = slotIdx * PAGE_SIZE;\n const spilled = this.coordinator.getSpilledPage(pageId)!;\n this.uint8.set(spilled, slot_offset);\n return;\n }\n\n // Await any in-flight flush for this page first\n const in_flight_flush = this.in_flight_flushes.get(pageId);\n\n if (in_flight_flush) {\n await in_flight_flush;\n }\n\n // Coalesce in-flight reads for the same pageId\n const in_flight_read = this.in_flight_reads.get(pageId);\n\n if (in_flight_read) {\n await in_flight_read;\n return;\n }\n\n const read_promise = (async () => {\n const disk_page = await this.vfs.readPage(pageId);\n const slot_offset = slotIdx * PAGE_SIZE;\n\n if (disk_page) {\n if (disk_page.byteLength !== PAGE_SIZE) {\n throw new CorruptPageError(\n pageId,\n `Unexpected page byte length: ${disk_page.byteLength}, expected ${PAGE_SIZE}`,\n );\n }\n\n // Verify CRC32 checksum\n const checksum_offset =\n pageId === 1\n ? HEADER_OFFSET_PAGE_CHECKSUM\n : PAGE_HEADER_OFFSET_CHECKSUM;\n\n const stored_checksum = read_u32(\n new DataView(disk_page.buffer, disk_page.byteOffset),\n checksum_offset,\n );\n\n if (stored_checksum !== 0) {\n const computed =\n pageId === 1\n ? computePage1Checksum(disk_page)\n : computePageChecksum(disk_page);\n\n if (computed !== stored_checksum) {\n throw new CorruptPageError(pageId, stored_checksum, computed);\n }\n }\n\n this.uint8.set(disk_page, slot_offset);\n } else {\n this.uint8.fill(0, slot_offset, slot_offset + PAGE_SIZE);\n }\n })();\n\n this.in_flight_reads.set(pageId, read_promise);\n\n try {\n await read_promise;\n } finally {\n this.in_flight_reads.delete(pageId);\n }\n }\n\n /**\n * Writes a page from slotIdx in linear memory to VFS.\n * Computes CRC32 checksum and writes into slot header before saving snapshot.\n */\n async writeSlot(slotIdx: number, pageId: number): Promise<void> {\n if (pageId <= 0) {\n throw new Error(\n `Invalid page ID: ${pageId}. Page IDs must be positive integers.`,\n );\n }\n\n const existing_flush = this.in_flight_flushes.get(pageId);\n if (existing_flush) {\n await existing_flush;\n return;\n }\n\n const slot_offset = slotIdx * PAGE_SIZE;\n const page_bytes = this.uint8.subarray(\n slot_offset,\n slot_offset + PAGE_SIZE,\n );\n\n this.stampSlotChecksum(slotIdx, pageId);\n\n const write_snapshot = page_bytes.slice();\n if (this.coordinator) {\n this.coordinator.onDirectPageWrite(pageId, write_snapshot);\n }\n const write_promise = this.vfs.writePage(pageId, write_snapshot);\n this.in_flight_flushes.set(pageId, write_promise);\n try {\n await write_promise;\n } finally {\n this.in_flight_flushes.delete(pageId);\n }\n }\n\n /**\n * Spills a slot to the WAL if an active transaction is open, otherwise writes it to VFS.\n */\n async spillOrWriteSlot(slotIdx: number, pageId: number): Promise<void> {\n if (this.coordinator && this.coordinator.isInTransaction()) {\n await this.coordinator.spillUncommittedSlot(slotIdx, pageId);\n } else {\n await this.writeSlot(slotIdx, pageId);\n }\n }\n\n /**\n * Resolves a PAGE_FAULT yielded by the C Engine state machine.\n * If flushPageId > 0, writes the victim dirty block to VFS.\n * Reads faultPageId from VFS directly into targetSlot memory.\n */\n async resolvePageFault(\n targetSlot: number,\n faultPageId: number,\n flushPageId: number,\n ): Promise<void> {\n if (flushPageId > 0) {\n if (this.coordinator && this.coordinator.isInTransaction()) {\n await this.coordinator.spillUncommittedSlot(targetSlot, flushPageId);\n } else {\n await this.writeSlot(targetSlot, flushPageId);\n }\n }\n\n if (this.coordinator && this.coordinator.hasSpilledPage(faultPageId)) {\n const slot_offset = targetSlot * PAGE_SIZE;\n const spilled = this.coordinator.getSpilledPage(faultPageId)!;\n this.uint8.set(spilled, slot_offset);\n } else {\n await this.readSlot(targetSlot, faultPageId);\n }\n }\n\n /**\n * Durably flushes pending VFS adapter writes.\n */\n async flush(): Promise<void> {\n await this.vfs.flush();\n }\n}\n","import {\n WAL_FILE_HEADER_SIZE,\n WAL_FRAME_HEADER_SIZE,\n WAL_FRAME_SIZE,\n WAL_PAGE_SIZE,\n WAL_CURRENT_VERSION,\n WAL_FRAME_MAGIC,\n WAL_HEADER_OFFSET_MAGIC,\n WAL_HEADER_OFFSET_WAL_VERSION,\n WAL_HEADER_OFFSET_PAGE_SIZE,\n WAL_HEADER_OFFSET_CHECKPOINT_SEQ,\n WAL_HEADER_OFFSET_SALT1,\n WAL_HEADER_OFFSET_SALT2,\n WAL_HEADER_OFFSET_CHECKSUM,\n WAL_HEADER_OFFSET_RESERVED,\n WAL_FRAME_OFFSET_MAGIC,\n WAL_FRAME_OFFSET_FRAME_TYPE,\n WAL_FRAME_OFFSET_FLAGS,\n WAL_FRAME_OFFSET_TX_ID,\n WAL_FRAME_OFFSET_PAGE_ID,\n WAL_FRAME_OFFSET_DB_SIZE_PAGES,\n WAL_FRAME_OFFSET_FRAME_SEQ,\n WAL_FRAME_OFFSET_CHECKSUM,\n WAL_FRAME_OFFSET_RESERVED,\n} from '../../layouts/wal_format.js';\nimport { crc32, computeWalFrameChecksum } from './crc32.js';\nimport { read_u16, write_u16, read_u32, write_u32 } from '../../shared/c_runtime.js';\nimport { CorruptWalHeaderError, CorruptWalFrameError } from '../../types/index.js';\n\n\nexport const WAL_MAGIC_BYTES = new Uint8Array([0x57, 0x45, 0x42, 0x57, 0x41, 0x4c]); // \"WEBWAL\"\n\nexport interface WalFileHeader {\n walVersion: number;\n pageSize: number;\n checkpointSeq: number;\n salt1: number;\n salt2: number;\n checksum: number;\n}\n\nexport interface WalFrameHeader {\n magic: number;\n frameType: number;\n flags: number;\n txId: number;\n pageId: number;\n dbSizePages: number;\n frameSeq: number;\n checksum: number;\n}\n\nexport interface WalFrame {\n header: WalFrameHeader;\n pageData: Uint8Array;\n}\n\n/**\n * Encodes a 32-byte WAL file header.\n */\nexport function encodeWalFileHeader(header: Partial<WalFileHeader> = {}): Uint8Array {\n const bytes = new Uint8Array(WAL_FILE_HEADER_SIZE);\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\n // 0..5: \"WEBWAL\"\n bytes.set(WAL_MAGIC_BYTES, WAL_HEADER_OFFSET_MAGIC);\n\n // 6..7: WAL version (uint16 LE)\n write_u16(view, WAL_HEADER_OFFSET_WAL_VERSION, header.walVersion ?? WAL_CURRENT_VERSION);\n\n // 8..11: Page size (uint32 LE)\n write_u32(view, WAL_HEADER_OFFSET_PAGE_SIZE, header.pageSize ?? WAL_PAGE_SIZE);\n\n // 12..15: Monotonic checkpoint counter (uint32 LE)\n write_u32(view, WAL_HEADER_OFFSET_CHECKPOINT_SEQ, header.checkpointSeq ?? 0);\n\n // 16..19: Random salt1 (uint32 LE)\n const salt1 = header.salt1 ?? (Math.floor(Math.random() * 0xffffffff) >>> 0);\n write_u32(view, WAL_HEADER_OFFSET_SALT1, salt1);\n\n // 20..23: Random salt2 (uint32 LE)\n const salt2 = header.salt2 ?? (Math.floor(Math.random() * 0xffffffff) >>> 0);\n write_u32(view, WAL_HEADER_OFFSET_SALT2, salt2);\n\n // 24..27: CRC32 checksum over bytes 0..23 (uint32 LE)\n const checksum = header.checksum ?? crc32(bytes, 0, 24);\n write_u32(view, WAL_HEADER_OFFSET_CHECKSUM, checksum);\n\n // 28..31: Zero padding\n write_u32(view, WAL_HEADER_OFFSET_RESERVED, 0);\n\n return bytes;\n}\n\n/**\n * Decodes and validates a 32-byte WAL file header.\n */\nexport function decodeWalFileHeader(bytes: Uint8Array, verifyChecksum: boolean = true): WalFileHeader {\n if (bytes.byteLength < WAL_FILE_HEADER_SIZE) {\n throw new CorruptWalHeaderError(\n `Truncated WAL file header: expected at least ${WAL_FILE_HEADER_SIZE} bytes, received ${bytes.byteLength}`,\n );\n }\n\n // Verify magic\n for (let i = 0; i < 6; i++) {\n if (bytes[WAL_HEADER_OFFSET_MAGIC + i] !== WAL_MAGIC_BYTES[i]) {\n throw new CorruptWalHeaderError(\n 'Invalid WAL file header magic identifier (expected \"WEBWAL\")',\n );\n }\n }\n\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const walVersion = read_u16(view, WAL_HEADER_OFFSET_WAL_VERSION);\n const pageSize = read_u32(view, WAL_HEADER_OFFSET_PAGE_SIZE);\n const checkpointSeq = read_u32(view, WAL_HEADER_OFFSET_CHECKPOINT_SEQ);\n const salt1 = read_u32(view, WAL_HEADER_OFFSET_SALT1);\n const salt2 = read_u32(view, WAL_HEADER_OFFSET_SALT2);\n const checksum = read_u32(view, WAL_HEADER_OFFSET_CHECKSUM);\n\n if (verifyChecksum) {\n const computed = crc32(bytes, 0, 24);\n if (checksum !== computed) {\n throw new CorruptWalHeaderError(\n `WAL file header CRC32 checksum mismatch: stored ${checksum}, computed ${computed}`,\n );\n }\n }\n\n return {\n walVersion,\n pageSize,\n checkpointSeq,\n salt1,\n salt2,\n checksum,\n };\n}\n\n/**\n * Encodes a single 4,128-byte WAL frame (32-byte header + 4096-byte page payload).\n */\nexport function encodeWalFrame(\n header: Omit<WalFrameHeader, 'magic' | 'checksum'> & { magic?: number; checksum?: number },\n pageData?: Uint8Array,\n): Uint8Array {\n const frameBytes = new Uint8Array(WAL_FRAME_SIZE);\n const view = new DataView(frameBytes.buffer, frameBytes.byteOffset, frameBytes.byteLength);\n\n // 0..3: Frame magic 0x57414C46 ('WALF', uint32 LE)\n write_u32(view, WAL_FRAME_OFFSET_MAGIC, header.magic ?? WAL_FRAME_MAGIC);\n\n // 4..5: Frame type (uint16 LE)\n write_u16(view, WAL_FRAME_OFFSET_FRAME_TYPE, header.frameType);\n\n // 6..7: Reserved flags (uint16 LE)\n write_u16(view, WAL_FRAME_OFFSET_FLAGS, header.flags ?? 0);\n\n // 8..11: Transaction ID (uint32 LE)\n write_u32(view, WAL_FRAME_OFFSET_TX_ID, header.txId);\n\n // 12..15: Page ID (uint32 LE)\n write_u32(view, WAL_FRAME_OFFSET_PAGE_ID, header.pageId);\n\n // 16..19: DB size in pages after commit (uint32 LE)\n write_u32(view, WAL_FRAME_OFFSET_DB_SIZE_PAGES, header.dbSizePages ?? 0);\n\n // 20..23: Monotonic frame sequence counter in WAL (uint32 LE)\n write_u32(view, WAL_FRAME_OFFSET_FRAME_SEQ, header.frameSeq);\n\n // 28..31: Zero padding\n write_u32(view, WAL_FRAME_OFFSET_RESERVED, 0);\n\n // 32..4127: 4096-byte page payload\n if (pageData) {\n frameBytes.set(pageData.subarray(0, WAL_PAGE_SIZE), WAL_FRAME_HEADER_SIZE);\n }\n\n // 24..27: CRC32 checksum over header bytes 0..23 + 4096 page bytes\n const checksum = header.checksum ?? computeWalFrameChecksum(frameBytes);\n write_u32(view, WAL_FRAME_OFFSET_CHECKSUM, checksum);\n\n return frameBytes;\n}\n\n/**\n * Decodes only the 32-byte header of a WAL frame without copying the 4096 page bytes.\n */\nexport function decodeWalFrameHeader(frameBytes: Uint8Array): WalFrameHeader {\n if (frameBytes.byteLength < WAL_FRAME_HEADER_SIZE) {\n throw new CorruptWalFrameError(\n `Truncated WAL frame header: expected at least ${WAL_FRAME_HEADER_SIZE} bytes, received ${frameBytes.byteLength}`,\n );\n }\n\n const view = new DataView(frameBytes.buffer, frameBytes.byteOffset, frameBytes.byteLength);\n return {\n magic: read_u32(view, WAL_FRAME_OFFSET_MAGIC),\n frameType: read_u16(view, WAL_FRAME_OFFSET_FRAME_TYPE),\n flags: read_u16(view, WAL_FRAME_OFFSET_FLAGS),\n txId: read_u32(view, WAL_FRAME_OFFSET_TX_ID),\n pageId: read_u32(view, WAL_FRAME_OFFSET_PAGE_ID),\n dbSizePages: read_u32(view, WAL_FRAME_OFFSET_DB_SIZE_PAGES),\n frameSeq: read_u32(view, WAL_FRAME_OFFSET_FRAME_SEQ),\n checksum: read_u32(view, WAL_FRAME_OFFSET_CHECKSUM),\n };\n}\n\n/**\n * Validates a candidate WAL frame without throwing, detecting truncated tails,\n * magic mismatches, and torn writes / CRC32 bit corruption.\n */\nexport function validateWalFrame(frameBytes: Uint8Array): {\n valid: boolean;\n reason?: 'truncated' | 'magic_mismatch' | 'checksum_mismatch';\n header?: WalFrameHeader;\n} {\n if (frameBytes.byteLength < WAL_FRAME_SIZE) {\n return { valid: false, reason: 'truncated' };\n }\n\n const header = decodeWalFrameHeader(frameBytes);\n if (header.magic !== WAL_FRAME_MAGIC) {\n return { valid: false, reason: 'magic_mismatch', header };\n }\n\n const computedChecksum = computeWalFrameChecksum(frameBytes);\n if (header.checksum !== computedChecksum) {\n return { valid: false, reason: 'checksum_mismatch', header };\n }\n\n return { valid: true, header };\n}\n\n/**\n * Decodes and verifies a complete 4,128-byte WAL frame.\n */\nexport function decodeWalFrame(frameBytes: Uint8Array, verifyChecksum: boolean = true): WalFrame {\n if (frameBytes.byteLength < WAL_FRAME_SIZE) {\n throw new CorruptWalFrameError(\n `Truncated WAL frame: expected ${WAL_FRAME_SIZE} bytes, received ${frameBytes.byteLength}`,\n );\n }\n\n const header = decodeWalFrameHeader(frameBytes);\n if (header.magic !== WAL_FRAME_MAGIC) {\n throw new CorruptWalFrameError(\n `Invalid WAL frame magic: expected 0x${WAL_FRAME_MAGIC.toString(16)}, got 0x${header.magic.toString(16)}`,\n );\n }\n\n if (verifyChecksum) {\n const computed = computeWalFrameChecksum(frameBytes);\n if (header.checksum !== computed) {\n throw new CorruptWalFrameError(\n `WAL frame CRC32 checksum mismatch: stored ${header.checksum}, computed ${computed}`,\n );\n }\n }\n\n const pageData = frameBytes.subarray(WAL_FRAME_HEADER_SIZE, WAL_FRAME_SIZE);\n return { header, pageData };\n}\n","/**\n * Native 128-bit Identity Types: UUID & ULID Codecs\n * Transcodes between canonical string representations and 16-byte raw binary slices.\n */\n\nimport { u32, i32, u64 } from \"../types.ts\";\nimport { strlen } from \"../../shared/c_runtime.ts\";\n\nconst text_decoder = new TextDecoder();\n\nexport const HEX_CHARS = \"0123456789abcdef\";\nexport const CROCKFORD_ALPHABET = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\n/**\n * @export_c\n */\nfunction hex_val(c: i32): i32 {\n if (c >= 48 && c <= 57) return c - 48;\n if (c >= 97 && c <= 102) return c - 97 + 10;\n if (c >= 65 && c <= 70) return c - 65 + 10;\n return -1;\n}\n\n/**\n * @export_c\n */\nfunction crockford_decode(c: i32): i32 {\n if (c >= 48 && c <= 57) return c - 48;\n if (c >= 97 && c <= 122) c = c - 32;\n\n switch (c) {\n case 65: return 10;\n case 66: return 11;\n case 67: return 12;\n case 68: return 13;\n case 69: return 14;\n case 70: return 15;\n case 71: return 16;\n case 72: return 17;\n case 74: return 18;\n case 75: return 19;\n case 77: return 20;\n case 78: return 21;\n case 80: return 22;\n case 81: return 23;\n case 82: return 24;\n case 83: return 25;\n case 84: return 26;\n case 86: return 27;\n case 87: return 28;\n case 88: return 29;\n case 89: return 30;\n case 90: return 31;\n case 73:\n case 76: return 1; // Crockford aliases\n case 79: return 0;\n default: return -1;\n }\n}\n\n// ==========================================\n// 1. UUID Transcoder (36-char Hex <-> 16 Bytes)\n// ==========================================\n\n/**\n * @export_c\n */\nexport function uuid_encode(\n uuid_str: string,\n target: Uint8Array,\n offset: u32,\n): i32 {\n let clean_idx = 0;\n let hi = -1;\n\n for (let i = 0; i < strlen(uuid_str); i++) {\n const c = uuid_str.charCodeAt(i);\n if (c !== 45) {\n if (clean_idx >= 32) return -1;\n const val = hex_val(c);\n if (val < 0) return -1;\n if (clean_idx % 2 === 0) {\n hi = val;\n } else {\n target[offset + (clean_idx >> 1)] = (hi << 4) | val;\n }\n clean_idx++;\n }\n }\n\n if (clean_idx !== 32) return -1;\n return 0;\n}\n\n/**\n * @export_c\n */\nexport function uuid_decode(\n source: Uint8Array,\n offset: u32,\n out_str: any,\n): void {\n let out_idx = 0;\n for (let i = 0; i < 16; i++) {\n if (i === 4 || i === 6 || i === 8 || i === 10) {\n out_str[out_idx++] = 45; // '-'\n }\n const b = source[offset + i];\n out_str[out_idx++] = HEX_CHARS.charCodeAt((b >> 4) & 0x0f);\n out_str[out_idx++] = HEX_CHARS.charCodeAt(b & 0x0f);\n }\n out_str[out_idx] = 0;\n}\n\nexport class UuidCodec {\n /** Packs a 36-char hyphenated UUID string into 16 raw binary bytes */\n static encode(\n uuid_str: string,\n target: Uint8Array,\n offset: number = 0,\n ): void {\n const err = uuid_encode(uuid_str, target, offset);\n if (err !== 0) {\n throw new Error(\n `Invalid UUID format: \"${uuid_str}\" (must be 36 characters with hyphens)`,\n );\n }\n }\n\n /** Unpacks 16 raw bytes into canonical 36-char hyphenated UUID string */\n static decode(source: Uint8Array, offset: number = 0): string {\n const buf = new Uint8Array(37);\n uuid_decode(source, offset, buf);\n return text_decoder.decode(buf.subarray(0, 36));\n }\n}\n\n// ==========================================\n// 2. ULID Transcoder (26-char Crockford Base32 <-> 16 Bytes)\n// ==========================================\n\n/**\n * @export_c\n */\nexport function ulid_encode(\n ulid_str: string,\n target: Uint8Array,\n offset: u32,\n): i32 {\n if (strlen(ulid_str) !== 26) return -1;\n\n let time: u64 = 0n;\n for (let i = 0; i < 10; i++) {\n const v = crockford_decode(ulid_str.charCodeAt(i));\n if (v < 0) return -1;\n time = (time << 5n) | BigInt(v);\n }\n\n target[offset + 0] = Number((time >> 40n) & 0xffn);\n target[offset + 1] = Number((time >> 32n) & 0xffn);\n target[offset + 2] = Number((time >> 24n) & 0xffn);\n target[offset + 3] = Number((time >> 16n) & 0xffn);\n target[offset + 4] = Number((time >> 8n) & 0xffn);\n target[offset + 5] = Number(time & 0xffn);\n\n let rand_hi: u64 = 0n;\n for (let i = 10; i < 18; i++) {\n const v = crockford_decode(ulid_str.charCodeAt(i));\n if (v < 0) return -1;\n rand_hi = (rand_hi << 5n) | BigInt(v);\n }\n\n let rand_lo: u64 = 0n;\n for (let i = 18; i < 26; i++) {\n const v = crockford_decode(ulid_str.charCodeAt(i));\n if (v < 0) return -1;\n rand_lo = (rand_lo << 5n) | BigInt(v);\n }\n\n for (let i = 0; i < 5; i++) {\n target[offset + 6 + i] = Number((rand_hi >> BigInt((4 - i) * 8)) & 0xffn);\n target[offset + 11 + i] = Number((rand_lo >> BigInt((4 - i) * 8)) & 0xffn);\n }\n\n return 0;\n}\n\n/**\n * @export_c\n */\nexport function ulid_decode(\n source: Uint8Array,\n offset: u32,\n out_str: any,\n): void {\n let time: u64 = 0n;\n for (let i = 0; i < 6; i++) {\n time = (time << 8n) | BigInt(source[offset + i]);\n }\n\n for (let i = 9; i >= 0; i--) {\n out_str[i] = CROCKFORD_ALPHABET.charCodeAt(Number(time % 32n));\n time /= 32n;\n }\n\n let rand_hi: u64 = 0n;\n for (let i = 0; i < 5; i++) {\n rand_hi = (rand_hi << 8n) | BigInt(source[offset + 6 + i]);\n }\n\n let rand_lo: u64 = 0n;\n for (let i = 0; i < 5; i++) {\n rand_lo = (rand_lo << 8n) | BigInt(source[offset + 11 + i]);\n }\n\n for (let i = 25; i >= 18; i--) {\n out_str[i] = CROCKFORD_ALPHABET.charCodeAt(Number(rand_lo & 31n));\n rand_lo >>= 5n;\n }\n\n for (let i = 17; i >= 10; i--) {\n out_str[i] = CROCKFORD_ALPHABET.charCodeAt(Number(rand_hi & 31n));\n rand_hi >>= 5n;\n }\n\n out_str[26] = 0;\n}\n\nexport class UlidCodec {\n /** Packs a 26-character Crockford Base32 string into 16 raw bytes */\n static encode(\n ulid_str: string,\n target: Uint8Array,\n offset: number = 0,\n ): void {\n const err = ulid_encode(ulid_str, target, offset);\n if (err !== 0) {\n throw new Error(\n `Invalid ULID length: \"${ulid_str}\" (must be 26 Crockford Base32 characters)`,\n );\n }\n }\n\n /** Unpacks 16 raw bytes into canonical 26-char Crockford Base32 string */\n static decode(source: Uint8Array, offset: number = 0): string {\n const buf = new Uint8Array(27);\n ulid_decode(source, offset, buf);\n return text_decoder.decode(buf.subarray(0, 26));\n }\n}\n","import {\n PAGE_SIZE,\n MAX_ROW_SIZE,\n PAGE_HEADER_SIZE,\n PAGE_TYPE_FREE,\n PAGE_TYPE_TABLE_INTERIOR,\n PAGE_TYPE_INDEX_LEAF,\n PAGE_TYPE_LEAF_DATA,\n TABLE_INTERIOR_CELL_SIZE,\n MAX_TABLE_INTERIOR_CELLS,\n TABLE_INTERIOR_SPLIT_INDEX,\n MAX_COLUMNS_PER_TABLE,\n PAGE_HEADER_OFFSET_CHECKSUM,\n} from \"../../constants.ts\";\nimport {\n DataType,\n ColumnFlag,\n ColumnMeta,\n TableMeta,\n DbRow,\n DbValue,\n RowSizeLimitExceededError,\n NotNullConstraintError,\n TooManyColumnsError,\n} from \"../../types/index.ts\";\nimport { UuidCodec, UlidCodec } from \"./codecs.c.ts\";\nimport type { u8, u16, u32, i32, i64 } from \"../types.ts\";\nimport { memcpy } from \"../../shared/c_runtime.ts\";\n\nconst text_encoder = new TextEncoder();\nconst text_decoder = new TextDecoder();\n\n// ============================================================================\n// 1. Slotted Page Initialization & Header Accessors (16-Byte Header)\n// ============================================================================\n\n/**\n * Initializes a standard 16-byte header 4KB page.\n *\n * Header Layout:\n * [0] uint8_t page_type\n * [1] uint8_t reserved (0x00)\n * [2..3] uint16_t cell_count (0)\n * [4..5] uint16_t cell_content_offset (PAGE_SIZE = 4096)\n * [6..9] uint32_t next_page_id / right_child_page_id / next_free_page_id (0)\n * [10..11] uint16_t free_bytes (0)\n * [12..15] uint32_t checksum (0)\n */\n\n/**\n * @export_c\n * Initializes a 4KB slotted database page header.\n */\nexport function page_init(\n view: DataView,\n page_offset: u32,\n page_type: u8 = PAGE_TYPE_LEAF_DATA,\n next_page_id: u32 = 0,\n): void {\n view.setUint8(page_offset + 0, page_type);\n view.setUint8(page_offset + 1, 0);\n view.setUint16(page_offset + 2, 0, true);\n view.setUint16(page_offset + 4, PAGE_SIZE, true);\n view.setUint32(page_offset + 6, next_page_id, true);\n view.setUint16(page_offset + 10, 0, true);\n view.setUint32(page_offset + PAGE_HEADER_OFFSET_CHECKSUM, 0, true);\n}\n\n/**\n * @export_c\n * Initializes a 4KB free-list page header.\n */\nexport function page_init_free(\n view: DataView,\n page_offset: u32,\n next_free_page_id: u32 = 0,\n): void {\n view.setUint8(page_offset + 0, PAGE_TYPE_FREE);\n view.setUint8(page_offset + 1, 0);\n view.setUint16(page_offset + 2, 0, true);\n view.setUint16(page_offset + 4, 0, true);\n view.setUint32(page_offset + 6, next_free_page_id, true);\n view.setUint16(page_offset + 10, 0, true);\n view.setUint32(page_offset + PAGE_HEADER_OFFSET_CHECKSUM, 0, true);\n}\n\n/**\n * @export_c\n * Returns the page type byte from a page header.\n */\nexport function page_get_type(view: DataView, page_offset: u32): u8 {\n return view.getUint8(page_offset + 0);\n}\n\n/**\n * @export_c\n * Sets the page type byte in a page header.\n */\nexport function page_set_type(\n view: DataView,\n page_offset: u32,\n type: u8,\n): void {\n view.setUint8(page_offset + 0, type);\n}\n\n/**\n * @export_c\n * Returns the number of cells in the page slot directory.\n */\nexport function page_get_cell_count(\n view: DataView,\n page_offset: u32,\n): u16 {\n return view.getUint16(page_offset + 2, true);\n}\n\n/**\n * @export_c\n * Sets the number of cells in the page slot directory.\n */\nexport function page_set_cell_count(\n view: DataView,\n page_offset: u32,\n count: u16,\n): void {\n view.setUint16(page_offset + 2, count, true);\n}\n\n/**\n * @export_c\n * Returns the byte offset within the page where active cell payloads begin.\n */\nexport function page_get_cell_content_offset(\n view: DataView,\n page_offset: u32,\n): u16 {\n return view.getUint16(page_offset + 4, true);\n}\n\n/**\n * @export_c\n * Sets the byte offset within the page where active cell payloads begin.\n */\nexport function page_set_cell_content_offset(\n view: DataView,\n page_offset: u32,\n offset: u16,\n): void {\n view.setUint16(page_offset + 4, offset, true);\n}\n\n/**\n * @export_c\n * Returns the next page ID (or right child page ID) stored in the page header.\n */\nexport function page_get_next_page_id(\n view: DataView,\n page_offset: u32,\n): u32 {\n return view.getUint32(page_offset + 6, true);\n}\n\n/**\n * @export_c\n * Sets the next page ID (or right child page ID) stored in the page header.\n */\nexport function page_set_next_page_id(\n view: DataView,\n page_offset: u32,\n next_page_id: u32,\n): void {\n view.setUint32(page_offset + 6, next_page_id, true);\n}\n\n/**\n * @export_c\n * Returns cumulative fragmented unallocated bytes in the page.\n */\nexport function page_get_free_bytes(\n view: DataView,\n page_offset: u32,\n): u16 {\n return view.getUint16(page_offset + 10, true);\n}\n\n/**\n * @export_c\n * Sets cumulative fragmented unallocated bytes in the page.\n */\nexport function page_set_free_bytes(\n view: DataView,\n page_offset: u32,\n free_bytes: u16,\n): void {\n view.setUint16(page_offset + 10, free_bytes, true);\n}\n\n/**\n * @export_c\n * Returns the checksum stored at bytes 12..15 in the page header.\n */\nexport function page_get_checksum(view: DataView, page_offset: u32): u32 {\n return view.getUint32(page_offset + PAGE_HEADER_OFFSET_CHECKSUM, true);\n}\n\n/**\n * @export_c\n * Sets the checksum stored at bytes 12..15 in the page header.\n */\nexport function page_set_checksum(\n view: DataView,\n page_offset: u32,\n checksum: u32,\n): void {\n view.setUint32(page_offset + PAGE_HEADER_OFFSET_CHECKSUM, checksum, true);\n}\n\n/**\n * @export_c\n * Returns the cell payload offset for the given slot directory index.\n */\nexport function page_get_cell_offset(\n view: DataView,\n page_offset: u32,\n slot_idx: u16,\n): u16 {\n const slot_dir_offset = page_offset + PAGE_HEADER_SIZE + slot_idx * 2;\n return view.getUint16(slot_dir_offset, true);\n}\n\n/**\n * @export_c\n * Sets the cell payload offset for the given slot directory index.\n */\nexport function page_set_cell_offset(\n view: DataView,\n page_offset: u32,\n slot_idx: u16,\n cell_offset: u16,\n): void {\n const slot_dir_offset = page_offset + PAGE_HEADER_SIZE + slot_idx * 2;\n view.setUint16(slot_dir_offset, cell_offset, true);\n}\n\n/**\n * @export_c\n * Returns contiguous free space between slot directory end and cell content offset.\n */\nexport function page_get_contiguous_free_space(\n view: DataView,\n page_offset: u32,\n): u16 {\n const cell_count = page_get_cell_count(view, page_offset);\n const cell_content_offset = page_get_cell_content_offset(view, page_offset);\n const slot_dir_end = PAGE_HEADER_SIZE + cell_count * 2;\n return (cell_content_offset - slot_dir_end) as u16;\n}\n\n/**\n * @export_c\n * Returns total free space on the page (contiguous + fragmented free_bytes).\n */\nexport function page_get_total_free_space(\n view: DataView,\n page_offset: u32,\n): u16 {\n return (\n page_get_contiguous_free_space(view, page_offset) +\n page_get_free_bytes(view, page_offset)\n ) as u16;\n}\n\n// ============================================================================\n// 2. In-Place Page Compaction / Defragmentation (Zero-Allocation via Scratchpad)\n// ============================================================================\n\n/**\n * @export_c\n * Defragments a slotted data page using a 4KB staging scratchpad.\n * Collapses fragmented holes to the bottom, rewrites slot directory entries,\n * and sets free_bytes to 0.\n */\nexport function page_compact(\n view: DataView,\n page_offset: u32,\n scratchpad_offset: u32 = 0,\n replacement?: { cell_idx: number; row_bytes: Uint8Array },\n): void {\n const cell_count = page_get_cell_count(view, page_offset);\n if (cell_count === 0) {\n page_set_cell_content_offset(view, page_offset, PAGE_SIZE);\n page_set_free_bytes(view, page_offset, 0);\n return;\n }\n\n // If no external scratchpad provided or buffer too small, use local 4KB scratchpad\n let scratch_view: DataView = view;\n let scratch: u32 = scratchpad_offset;\n\n if (scratchpad_offset === 0 || scratchpad_offset === page_offset || scratchpad_offset + PAGE_SIZE > view.byteLength) {\n const local_buf = new Uint8Array(PAGE_SIZE);\n scratch_view = new DataView(local_buf.buffer);\n scratch = 0;\n }\n\n // 1. Copy page header to scratchpad\n memcpy(scratch_view, scratch, view, page_offset, PAGE_HEADER_SIZE);\n\n // 2. Repack cells from end of page (PAGE_SIZE) downwards\n let current_offset: u16 = PAGE_SIZE;\n\n for (let i = 0; i < cell_count; i++) {\n let len: u16 = 0;\n let src_view: DataView | Uint8Array = view;\n let src_bytes: u32 = 0;\n\n if (replacement && i === replacement.cell_idx) {\n len = replacement.row_bytes.byteLength as u16;\n src_view = replacement.row_bytes;\n src_bytes = 0;\n } else {\n const old_offset = page_get_cell_offset(view, page_offset, i as u16);\n const p_type = page_get_type(view, page_offset);\n if (p_type === PAGE_TYPE_INDEX_LEAF) {\n const k_len = view.getUint16(page_offset + old_offset, true);\n len = (2 + k_len + 8) as u16;\n } else {\n len = page_get_row_length(view, page_offset + old_offset);\n }\n src_view = view;\n src_bytes = page_offset + old_offset;\n }\n\n current_offset = (current_offset - len) as u16;\n memcpy(scratch_view, scratch + current_offset, src_view, src_bytes, len);\n\n // Update slot directory in scratchpad\n page_set_cell_offset(scratch_view, scratch, i as u16, current_offset);\n }\n\n // 3. Update scratchpad header fields\n page_set_cell_content_offset(scratch_view, scratch, current_offset);\n page_set_free_bytes(scratch_view, scratch, 0);\n\n // 4. Copy back to page\n memcpy(view, page_offset, scratch_view, scratch, PAGE_SIZE);\n}\n\n/**\n * @export_c\n * Calculates row length in bytes from the serialized row at row_offset.\n */\nexport function page_get_row_length(\n view: DataView,\n row_abs_offset: u32,\n): u16 {\n return view.getUint16(row_abs_offset + 1, true);\n}\n\n// ============================================================================\n// 3. Row Insert, Delete, and Update Mechanics\n// ============================================================================\n\n/**\n * Inserts a serialized row record into a slotted data page.\n * Returns the slot index (0-indexed) or -1 if the row cannot fit in this page.\n */\nexport function page_insert_row(\n view: DataView,\n page_offset: number,\n row_bytes: Uint8Array,\n scratchpad_offset?: number,\n): number {\n const cell_count = page_get_cell_count(view, page_offset);\n const cell_content_offset = page_get_cell_content_offset(view, page_offset);\n const needed_bytes = row_bytes.byteLength + 2; // payload + 2B slot directory entry\n\n const slot_dir_end = PAGE_HEADER_SIZE + cell_count * 2;\n const contiguous_free = cell_content_offset - slot_dir_end;\n const total_free = contiguous_free + page_get_free_bytes(view, page_offset);\n\n if (needed_bytes > total_free) {\n return -1; // Cannot fit even after defragmentation\n }\n\n if (needed_bytes > contiguous_free) {\n // In-place compaction collapses all fragmented holes\n page_compact(view, page_offset, scratchpad_offset);\n }\n\n const current_content_offset = page_get_cell_content_offset(\n view,\n page_offset,\n );\n const current_cell_count = page_get_cell_count(view, page_offset);\n\n // Allocate payload from bottom up\n const new_content_offset = current_content_offset - row_bytes.byteLength;\n const abs_target = view.byteOffset + page_offset + new_content_offset;\n\n // Copy row bytes into page\n const uint8 = new Uint8Array(view.buffer);\n uint8.set(row_bytes, abs_target);\n\n // Write new slot directory entry\n page_set_cell_offset(\n view,\n page_offset,\n current_cell_count,\n new_content_offset,\n );\n\n // Update page header\n page_set_cell_count(view, page_offset, current_cell_count + 1);\n page_set_cell_content_offset(view, page_offset, new_content_offset);\n\n return current_cell_count;\n}\n\n/**\n * @export_c\n * Deletes a row from a slotted data page.\n * Shifts subsequent slot directory entries left by 2 bytes (memmove) and increments free_bytes.\n */\nexport function page_delete_row(\n view: DataView,\n page_offset: u32,\n cell_idx: u16,\n): void {\n const cell_count = page_get_cell_count(view, page_offset);\n if (cell_idx >= cell_count) {\n return;\n }\n\n const offset = page_get_cell_offset(view, page_offset, cell_idx);\n const row_len = page_get_row_length(view, page_offset + offset);\n\n // Shift slot directory entries left by 2 bytes\n const slot_dir_start = page_offset + PAGE_HEADER_SIZE;\n const src = slot_dir_start + (cell_idx + 1) * 2;\n const dst = slot_dir_start + cell_idx * 2;\n const shift_length = (cell_count - 1 - cell_idx) * 2;\n\n if (shift_length > 0) {\n memcpy(view, dst, view, src, shift_length);\n }\n\n // Update header\n page_set_cell_count(view, page_offset, cell_count - 1);\n page_set_free_bytes(\n view,\n page_offset,\n page_get_free_bytes(view, page_offset) + row_len,\n );\n}\n\n/**\n * Updates an existing row in a slotted data page following the 3 scenarios in §4.5.\n * Returns true if update succeeded on this page, or false if it exceeded page capacity (Scenario C).\n */\nexport function page_update_row(\n view: DataView,\n page_offset: number,\n cell_idx: number,\n new_row_bytes: Uint8Array,\n scratchpad_offset?: number,\n): boolean {\n const cell_count = page_get_cell_count(view, page_offset);\n if (cell_idx < 0 || cell_idx >= cell_count) {\n throw new Error(`Invalid cell index ${cell_idx} for update`);\n }\n\n const old_offset = page_get_cell_offset(view, page_offset, cell_idx);\n const old_len = page_get_row_length(view, page_offset + old_offset);\n const new_len = new_row_bytes.byteLength;\n const uint8 = new Uint8Array(view.buffer);\n\n // Scenario A: Same-size or shrinking update\n if (new_len <= old_len) {\n uint8.set(new_row_bytes, view.byteOffset + page_offset + old_offset);\n if (new_len < old_len) {\n page_set_free_bytes(\n view,\n page_offset,\n page_get_free_bytes(view, page_offset) + (old_len - new_len),\n );\n }\n return true;\n }\n\n // Scenario B: Expanding update fitting on current page\n const total_free = page_get_total_free_space(view, page_offset);\n const needed_extra = new_len - old_len;\n\n if (total_free >= needed_extra) {\n const contiguous_free = page_get_contiguous_free_space(view, page_offset);\n if (contiguous_free < new_len) {\n page_compact(view, page_offset, scratchpad_offset, {\n cell_idx,\n row_bytes: new_row_bytes,\n });\n return true;\n }\n\n // Mark old record space as hole\n page_set_free_bytes(\n view,\n page_offset,\n page_get_free_bytes(view, page_offset) + old_len,\n );\n\n const content_offset = page_get_cell_content_offset(view, page_offset);\n const new_content_offset = content_offset - new_len;\n uint8.set(\n new_row_bytes,\n view.byteOffset + page_offset + new_content_offset,\n );\n\n // Update slot directory entry\n page_set_cell_offset(view, page_offset, cell_idx, new_content_offset);\n page_set_cell_content_offset(view, page_offset, new_content_offset);\n return true;\n }\n\n // Scenario C: Exceeding page capacity\n return false;\n}\n\n// ============================================================================\n// 4. Row Record Serialization & Deserialization\n// ============================================================================\n\n/**\n * Calculates null-bitmap bytes, fixed slice size, and variable column count for row layout.\n */\nexport function page_get_table_layout(\n table_or_columns: TableMeta | ColumnMeta[],\n) {\n const columns = Array.isArray(table_or_columns)\n ? table_or_columns\n : (table_or_columns as TableMeta).columns;\n const null_bitmap_bytes = Math.ceil(columns.length / 8);\n let fixed_slice_size = 0;\n let var_col_count = 0;\n for (let i = 0; i < columns.length; i++) {\n const c = columns[i];\n if (c.type === DataType.INT32) fixed_slice_size += 4;\n else if (c.type === DataType.INT64 || c.type === DataType.FLOAT64)\n fixed_slice_size += 8;\n else if (c.type === DataType.UUID || c.type === DataType.ULID)\n fixed_slice_size += 16;\n else if (c.type === DataType.TEXT || c.type === DataType.BLOB)\n var_col_count++;\n }\n return { null_bitmap_bytes, fixed_slice_size, var_col_count };\n}\n\n/**\n * Serializes a user row into WebDB Phase 1 binary format:\n *\n * [0]: Flags (1B: 0x01 = Active)\n * [1..2]: Row _length (2B uint16 LE)\n * [3..(3 + null_bitmap_bytes - 1)]: _null-_bitmap (ceil(N/8) bytes)\n * Followed by: Fixed Slice (INT32 4B, INT64 8B, FLOAT64 8B, UUID 16B, ULID 16B)\n * Followed by: Var-_offset Table (4B per TEXT/BLOB column: 2B rel_offset, 2B length)\n * Followed by: Var Payloads (raw UTF-8 string or binary bytes)\n *\n * Strict 2048-Byte boundary enforced.\n */\nexport function page_serialize_row(\n table_or_columns: TableMeta | ColumnMeta[],\n values: Record<string, DbValue>,\n): Uint8Array {\n const columns = Array.isArray(table_or_columns)\n ? table_or_columns\n : (table_or_columns as TableMeta).columns;\n const col_count = columns.length;\n if (col_count > MAX_COLUMNS_PER_TABLE) {\n throw new TooManyColumnsError(col_count, MAX_COLUMNS_PER_TABLE);\n }\n\n const null_bitmap_bytes = Math.ceil(col_count / 8);\n const null_bitmap = new Uint8Array(null_bitmap_bytes);\n\n // Validate NOT NULL constraints & compute null bits\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n const val = values[col.name];\n const is_null = val === null || val === undefined;\n\n if (is_null) {\n if ((col.flags & ColumnFlag.NOT_NULL) !== 0) {\n throw new NotNullConstraintError(col.name);\n }\n const byte_idx = i >> 3;\n const bit_mask = 1 << (i & 7);\n null_bitmap[byte_idx] |= bit_mask;\n }\n }\n\n // Calculate fixed-width slice and var-length payloads\n let fixed_slice_size = 0;\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n const is_null = (null_bitmap[i >> 3] & (1 << (i & 7))) !== 0;\n if (!is_null) {\n switch (col.type) {\n case DataType.INT32:\n fixed_slice_size += 4;\n break;\n case DataType.INT64:\n case DataType.FLOAT64:\n fixed_slice_size += 8;\n break;\n case DataType.UUID:\n case DataType.ULID:\n fixed_slice_size += 16;\n break;\n }\n }\n }\n\n // Variable columns offset table (4 bytes each)\n const var_columns: Array<{\n col_idx: number;\n col: ColumnMeta;\n payload: Uint8Array | null;\n }> = [];\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n if (col.type === DataType.TEXT || col.type === DataType.BLOB) {\n const is_null = (null_bitmap[i >> 3] & (1 << (i & 7))) !== 0;\n if (is_null) {\n var_columns.push({ col_idx: i, col, payload: null });\n } else {\n const val = values[col.name];\n let bytes: Uint8Array;\n if (col.type === DataType.TEXT) {\n bytes = text_encoder.encode(String(val ?? \"\"));\n } else {\n bytes = val instanceof Uint8Array ? val : new Uint8Array(val as any);\n }\n var_columns.push({ col_idx: i, col, payload: bytes });\n }\n }\n }\n\n const var_offset_table_size = var_columns.length * 4;\n const header_and_tables_size =\n 3 + null_bitmap_bytes + fixed_slice_size + var_offset_table_size;\n\n let total_var_payload_size = 0;\n for (let i = 0; i < var_columns.length; i++) {\n const item = var_columns[i];\n if (item.payload) {\n total_var_payload_size += item.payload.byteLength;\n }\n }\n\n const total_row_size = header_and_tables_size + total_var_payload_size;\n if (total_row_size > MAX_ROW_SIZE) {\n throw new RowSizeLimitExceededError(total_row_size, MAX_ROW_SIZE);\n }\n\n const row_buffer = new Uint8Array(total_row_size);\n const row_view = new DataView(row_buffer.buffer);\n\n // [0]: Flags (0x01 = Active)\n row_view.setUint8(0, 0x01);\n // [1..2]: Stored Row _length\n row_view.setUint16(1, total_row_size, true);\n // [3..]: _null-_bitmap\n row_buffer.set(null_bitmap, 3);\n\n let current_fixed_offset = 3 + null_bitmap_bytes;\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n const is_null = (null_bitmap[i >> 3] & (1 << (i & 7))) !== 0;\n if (!is_null) {\n const val = values[col.name];\n switch (col.type) {\n case DataType.INT32:\n row_view.setInt32(current_fixed_offset, Number(val), true);\n current_fixed_offset += 4;\n break;\n case DataType.INT64:\n row_view.setBigInt64(current_fixed_offset, BigInt(val as any), true);\n current_fixed_offset += 8;\n break;\n case DataType.FLOAT64:\n row_view.setFloat64(current_fixed_offset, Number(val), true);\n current_fixed_offset += 8;\n break;\n case DataType.UUID:\n UuidCodec.encode(String(val), row_buffer, current_fixed_offset);\n current_fixed_offset += 16;\n break;\n case DataType.ULID:\n UlidCodec.encode(String(val), row_buffer, current_fixed_offset);\n current_fixed_offset += 16;\n break;\n }\n }\n }\n\n // Write var-offset table and payloads\n let current_var_table_offset = current_fixed_offset;\n let current_payload_offset = header_and_tables_size;\n\n for (let i = 0; i < var_columns.length; i++) {\n const item = var_columns[i];\n if (item.payload === null) {\n // _null column: rel_offset 0, length 0\n row_view.setUint16(current_var_table_offset, 0, true);\n row_view.setUint16(current_var_table_offset + 2, 0, true);\n } else {\n row_view.setUint16(\n current_var_table_offset,\n current_payload_offset,\n true,\n );\n row_view.setUint16(\n current_var_table_offset + 2,\n item.payload.byteLength,\n true,\n );\n row_buffer.set(item.payload, current_payload_offset);\n current_payload_offset += item.payload.byteLength;\n }\n current_var_table_offset += 4;\n }\n\n return row_buffer;\n}\n\n/**\n * Deserializes a row record from a DataView into a user-facing DbRow object.\n */\nexport function page_deserialize_row(\n arg1: TableMeta | ColumnMeta[] | DataView,\n arg2: DataView | number,\n arg3?: number | TableMeta | ColumnMeta[],\n): DbRow {\n let columns: ColumnMeta[];\n let view: DataView;\n let record_offset: number;\n\n if (arg1 instanceof DataView) {\n view = arg1;\n record_offset = arg2 as number;\n const table_or_cols = arg3 as TableMeta | ColumnMeta[];\n columns = Array.isArray(table_or_cols)\n ? table_or_cols\n : (table_or_cols as TableMeta).columns;\n } else {\n columns = Array.isArray(arg1) ? arg1 : (arg1 as TableMeta).columns;\n view = arg2 as DataView;\n record_offset = arg3 as number;\n }\n\n const row: DbRow = {};\n const col_count = columns.length;\n const null_bitmap_bytes = Math.ceil(col_count / 8);\n\n const null_bitmap = new Uint8Array(\n view.buffer,\n view.byteOffset + record_offset + 3,\n null_bitmap_bytes,\n );\n\n let current_fixed_offset = record_offset + 3 + null_bitmap_bytes;\n\n // Track var-column index\n let var_col_idx = 0;\n // Calculate where the var-offset table starts\n // We need to advance fixed offset for non-null fixed columns\n const fixed_start = current_fixed_offset;\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n const is_null = (null_bitmap[i >> 3] & (1 << (i & 7))) !== 0;\n if (!is_null) {\n switch (col.type) {\n case DataType.INT32:\n current_fixed_offset += 4;\n break;\n case DataType.INT64:\n case DataType.FLOAT64:\n current_fixed_offset += 8;\n break;\n case DataType.UUID:\n case DataType.ULID:\n current_fixed_offset += 16;\n break;\n }\n }\n }\n\n const var_offset_table_start = current_fixed_offset;\n current_fixed_offset = fixed_start;\n\n for (let i = 0; i < col_count; i++) {\n const col = columns[i];\n const is_null = (null_bitmap[i >> 3] & (1 << (i & 7))) !== 0;\n\n if (is_null) {\n row[col.name] = null;\n if (col.type === DataType.TEXT || col.type === DataType.BLOB) {\n var_col_idx++;\n }\n continue;\n }\n\n switch (col.type) {\n case DataType.INT32:\n row[col.name] = view.getInt32(current_fixed_offset, true);\n current_fixed_offset += 4;\n break;\n case DataType.INT64:\n row[col.name] = view.getBigInt64(current_fixed_offset, true);\n current_fixed_offset += 8;\n break;\n case DataType.FLOAT64:\n row[col.name] = view.getFloat64(current_fixed_offset, true);\n current_fixed_offset += 8;\n break;\n case DataType.UUID: {\n const slice = new Uint8Array(\n view.buffer,\n view.byteOffset + current_fixed_offset,\n 16,\n );\n row[col.name] = UuidCodec.decode(slice, 0);\n current_fixed_offset += 16;\n break;\n }\n case DataType.ULID: {\n const slice = new Uint8Array(\n view.buffer,\n view.byteOffset + current_fixed_offset,\n 16,\n );\n row[col.name] = UlidCodec.decode(slice, 0);\n current_fixed_offset += 16;\n break;\n }\n case DataType.TEXT: {\n const table_entry_offset = var_offset_table_start + var_col_idx * 4;\n const rel_offset = view.getUint16(table_entry_offset, true);\n const len = view.getUint16(table_entry_offset + 2, true);\n const payload_offset = view.byteOffset + record_offset + rel_offset;\n const text_bytes = new Uint8Array(view.buffer, payload_offset, len);\n row[col.name] = text_decoder.decode(text_bytes);\n var_col_idx++;\n break;\n }\n case DataType.BLOB: {\n const table_entry_offset = var_offset_table_start + var_col_idx * 4;\n const rel_offset = view.getUint16(table_entry_offset, true);\n const len = view.getUint16(table_entry_offset + 2, true);\n const payload_offset = view.byteOffset + record_offset + rel_offset;\n const blob_bytes = new Uint8Array(len);\n blob_bytes.set(new Uint8Array(view.buffer, payload_offset, len));\n row[col.name] = blob_bytes;\n var_col_idx++;\n break;\n }\n }\n }\n\n return row;\n}\n\n// ============================================================================\n// 5. Table Interior Page Mechanics (page_type = 0x05, 12-Byte Cells)\n// ============================================================================\n\n/**\n * @export_c\n * Initializes a Table Interior Page with right_child_page_id.\n */\nexport function page_init_interior(\n view: DataView,\n page_offset: u32,\n right_child_page_id: u32 = 0,\n): void {\n page_init(view, page_offset, PAGE_TYPE_TABLE_INTERIOR, right_child_page_id);\n}\n\n/**\n * @export_c\n * Returns right child page ID of a Table Interior Page.\n */\nexport function page_get_right_child_page_id(\n view: DataView,\n page_offset: u32,\n): u32 {\n return view.getUint32(page_offset + 6, true);\n}\n\n/**\n * @export_c\n * Sets right child page ID of a Table Interior Page.\n */\nexport function page_set_right_child_page_id(\n view: DataView,\n page_offset: u32,\n right_child_page_id: u32,\n): void {\n view.setUint32(page_offset + 6, right_child_page_id, true);\n}\n\n/**\n * @export_c\n * Inserts a 12-byte routing cell into a Table Interior Page.\n * Returns new cell count or -1 if page has reached max entries (291 entries).\n */\nexport function page_insert_interior_cell(\n view: DataView,\n page_offset: u32,\n child_page_id: u32,\n rowid: i64,\n): i32 {\n const cell_count = page_get_cell_count(view, page_offset);\n if (cell_count >= MAX_TABLE_INTERIOR_CELLS) {\n return -1; // Interior page full\n }\n\n const content_offset = page_get_cell_content_offset(view, page_offset);\n const new_content_offset = content_offset - TABLE_INTERIOR_CELL_SIZE;\n\n // Write 12-byte cell payload\n const target_offset = page_offset + new_content_offset;\n view.setUint32(target_offset, child_page_id, true);\n view.setBigInt64(target_offset + 4, rowid, true);\n\n // Write slot directory entry\n page_set_cell_offset(view, page_offset, cell_count, new_content_offset);\n\n page_set_cell_count(view, page_offset, cell_count + 1);\n page_set_cell_content_offset(view, page_offset, new_content_offset);\n\n return cell_count + 1;\n}\n\n/**\n * @export_c\n * Performs binary search on a Table Interior Page to route traversal for target_row_id.\n * Returns the child_page_id to traverse.\n */\nexport function page_binary_search_interior(\n view: DataView,\n page_offset: u32,\n target_row_id: i64,\n): u32 {\n const cell_count = page_get_cell_count(view, page_offset);\n if (cell_count === 0) {\n return page_get_right_child_page_id(view, page_offset);\n }\n\n let lo = 0;\n let hi = cell_count - 1;\n let candidate_child = -1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const cell_offset = page_get_cell_offset(view, page_offset, mid);\n const cell_rowid = view.getBigInt64(page_offset + cell_offset + 4, true);\n\n if (target_row_id <= cell_rowid) {\n candidate_child = view.getUint32(page_offset + cell_offset, true);\n hi = mid - 1;\n } else {\n lo = mid + 1;\n }\n }\n\n if (candidate_child !== -1) {\n return candidate_child;\n }\n\n // If target_row_id > all keys on this page, follow right_child_page_id\n return page_get_right_child_page_id(view, page_offset);\n}\n\n/**\n * Splits a Table Interior Page at median entry (index 145), promoting the median key.\n */\nexport function page_split_interior(\n view: DataView,\n page_offset: number,\n new_page_offset: number,\n): {\n median_rowid: bigint;\n promoted_child_page_id: number;\n right_child_page_id: number;\n} {\n const cell_count = page_get_cell_count(view, page_offset);\n const median_idx = TABLE_INTERIOR_SPLIT_INDEX; // 145\n\n if (cell_count <= median_idx) {\n throw new Error(`Cannot split interior page with only ${cell_count} cells`);\n }\n\n // Read median cell\n const median_cell_offset = page_get_cell_offset(\n view,\n page_offset,\n median_idx,\n );\n const promoted_child_page_id = view.getUint32(\n page_offset + median_cell_offset,\n true,\n );\n const median_rowid = view.getBigInt64(\n page_offset + median_cell_offset + 4,\n true,\n );\n\n // Initialize right sibling interior page\n const old_right_child = page_get_right_child_page_id(view, page_offset);\n page_init_interior(view, new_page_offset, old_right_child);\n\n // Copy entries 146..cell_count-1 to new sibling page\n for (let i = median_idx + 1; i < cell_count; i++) {\n const offset = page_get_cell_offset(view, page_offset, i);\n const child_id = view.getUint32(page_offset + offset, true);\n const r_id = view.getBigInt64(page_offset + offset + 4, true);\n page_insert_interior_cell(view, new_page_offset, child_id, r_id);\n }\n\n // Left page keeps entries 0..144, and its right_child_page_id becomes median's child_page_id\n page_set_right_child_page_id(view, page_offset, promoted_child_page_id);\n page_set_cell_count(view, page_offset, median_idx);\n\n return {\n median_rowid,\n promoted_child_page_id,\n right_child_page_id: old_right_child,\n };\n}\n\n// ============================================================================\n// 6. Secondary Index Leaf Page Mechanics (page_type = 0x0A)\n// ============================================================================\n\n/**\n * @export_c\n * Initializes a Secondary Index Leaf Page.\n */\nexport function page_init_index_leaf(\n view: DataView,\n page_offset: u32,\n next_page_id: u32 = 0,\n): void {\n page_init(view, page_offset, PAGE_TYPE_INDEX_LEAF, next_page_id);\n}\n\n/**\n * Compares two index keys according to SQLite 3VL collation order:\n * NULL < -Infinity < Numbers < TEXT (UTF-8) < BLOB\n */\nexport function page_compare_index_keys(\n type_a: DataType,\n val_a: any,\n rowid_a: bigint,\n type_b: DataType,\n val_b: any,\n rowid_b: bigint,\n): number {\n if (type_a !== type_b) {\n // 3VL collation precedence order\n return type_a - type_b;\n }\n\n if (type_a === DataType.NULL) {\n return rowid_a < rowid_b ? -1 : rowid_a > rowid_b ? 1 : 0;\n }\n\n let diff = 0;\n if (\n type_a === DataType.INT32 ||\n type_a === DataType.INT64 ||\n type_a === DataType.FLOAT64\n ) {\n const num_a = typeof val_a === \"bigint\" ? Number(val_a) : val_a;\n const num_b = typeof val_b === \"bigint\" ? Number(val_b) : val_b;\n diff = num_a < num_b ? -1 : num_a > num_b ? 1 : 0;\n } else if (\n type_a === DataType.TEXT ||\n type_a === DataType.UUID ||\n type_a === DataType.ULID\n ) {\n const str_a = String(val_a);\n const str_b = String(val_b);\n diff = str_a < str_b ? -1 : str_a > str_b ? 1 : 0;\n } else if (type_a === DataType.BLOB) {\n const b_a = val_a as Uint8Array;\n const b_b = val_b as Uint8Array;\n const min_len = Math.min(b_a.length, b_b.length);\n for (let i = 0; i < min_len; i++) {\n if (b_a[i] !== b_b[i]) {\n diff = b_a[i] < b_b[i] ? -1 : 1;\n break;\n }\n }\n if (diff === 0) {\n diff = b_a.length - b_b.length;\n }\n }\n\n if (diff !== 0) return diff;\n return rowid_a < rowid_b ? -1 : rowid_a > rowid_b ? 1 : 0;\n}\n\nfunction page_decode_index_cell(\n view: DataView,\n cell_data_offset: number,\n k_len: number,\n context_type: DataType,\n): { cellType: DataType; cellVal: any } {\n const k_data = new Uint8Array(\n view.buffer,\n view.byteOffset + cell_data_offset,\n k_len,\n );\n if (k_len === 0) {\n return { cellType: DataType.NULL, cellVal: null };\n }\n if (context_type === DataType.TEXT) {\n if (\n k_len === 4 &&\n ((k_data[2] === 0 && k_data[3] === 0) ||\n (k_data[2] === 0xff && k_data[3] === 0xff))\n ) {\n return {\n cellType: DataType.INT32,\n cellVal: new DataView(k_data.buffer, k_data.byteOffset).getInt32(\n 0,\n true,\n ),\n };\n }\n if (k_len === 2 && k_data[0] < 32 && k_data[1] < 32) {\n return { cellType: DataType.BLOB, cellVal: k_data };\n }\n return { cellType: DataType.TEXT, cellVal: text_decoder.decode(k_data) };\n }\n if (k_len === 2) {\n return { cellType: DataType.BLOB, cellVal: k_data };\n }\n if (k_len === 4) {\n return {\n cellType: DataType.INT32,\n cellVal: new DataView(k_data.buffer, k_data.byteOffset).getInt32(0, true),\n };\n }\n if (context_type === DataType.UUID && k_len === 16) {\n return { cellType: DataType.UUID, cellVal: UuidCodec.decode(k_data, 0) };\n }\n if (context_type === DataType.ULID && k_len === 16) {\n return { cellType: DataType.ULID, cellVal: UlidCodec.decode(k_data, 0) };\n }\n if (context_type === DataType.FLOAT64 && k_len === 8) {\n return {\n cellType: DataType.FLOAT64,\n cellVal: new DataView(k_data.buffer, k_data.byteOffset).getFloat64(\n 0,\n true,\n ),\n };\n }\n if (context_type === DataType.INT64 && k_len === 8) {\n return {\n cellType: DataType.INT64,\n cellVal: new DataView(k_data.buffer, k_data.byteOffset).getBigInt64(\n 0,\n true,\n ),\n };\n }\n if (context_type === DataType.BLOB) {\n if (k_len === 5 || k_len === 6) {\n return { cellType: DataType.TEXT, cellVal: text_decoder.decode(k_data) };\n }\n return { cellType: DataType.BLOB, cellVal: k_data };\n }\n return { cellType: DataType.TEXT, cellVal: text_decoder.decode(k_data) };\n}\n\n/**\n * Inserts a key and rowid into a Secondary Index Leaf Page, maintaining sorted slot directory.\n */\nexport function page_insert_index_leaf_cell(\n view: DataView,\n page_offset: number,\n key_type: DataType,\n key_value: any,\n rowid: bigint,\n scratchpad_offset?: number,\n): number {\n let key_bytes: Uint8Array;\n if (\n key_type === DataType.NULL ||\n key_value === null ||\n key_value === undefined\n ) {\n key_bytes = new Uint8Array(0);\n } else if (key_type === DataType.INT32) {\n key_bytes = new Uint8Array(4);\n new DataView(key_bytes.buffer).setInt32(0, Number(key_value), true);\n } else if (key_type === DataType.INT64) {\n key_bytes = new Uint8Array(8);\n new DataView(key_bytes.buffer).setBigInt64(0, BigInt(key_value), true);\n } else if (key_type === DataType.FLOAT64) {\n key_bytes = new Uint8Array(8);\n new DataView(key_bytes.buffer).setFloat64(0, Number(key_value), true);\n } else if (key_type === DataType.UUID) {\n key_bytes = new Uint8Array(16);\n UuidCodec.encode(String(key_value), key_bytes, 0);\n } else if (key_type === DataType.ULID) {\n key_bytes = new Uint8Array(16);\n UlidCodec.encode(String(key_value), key_bytes, 0);\n } else if (key_type === DataType.TEXT) {\n key_bytes = text_encoder.encode(String(key_value));\n } else {\n key_bytes =\n key_value instanceof Uint8Array ? key_value : new Uint8Array(key_value);\n }\n\n // Cell format: [key_len uint16][key_data][rowid int64]\n const cell_length = 2 + key_bytes.byteLength + 8;\n const needed_bytes = cell_length + 2; // + 2B slot directory entry\n\n const cell_count = page_get_cell_count(view, page_offset);\n const contiguous_free = page_get_contiguous_free_space(view, page_offset);\n const total_free = contiguous_free + page_get_free_bytes(view, page_offset);\n\n if (needed_bytes > total_free) {\n return -1; // Index leaf full\n }\n\n if (needed_bytes > contiguous_free) {\n page_compact(view, page_offset, scratchpad_offset);\n }\n\n const content_offset = page_get_cell_content_offset(view, page_offset);\n const new_content_offset = content_offset - cell_length;\n const target_offset = page_offset + new_content_offset;\n\n // Write cell\n const abs_target = view.byteOffset + target_offset;\n view.setUint16(target_offset, key_bytes.byteLength, true);\n new Uint8Array(view.buffer).set(key_bytes, abs_target + 2);\n view.setBigInt64(target_offset + 2 + key_bytes.byteLength, rowid, true);\n\n // Binary search to find sorted insertion slot index\n let lo = 0;\n let hi = cell_count - 1;\n let insert_slot = cell_count;\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const offset = page_get_cell_offset(view, page_offset, mid);\n const existing_k_len = view.getUint16(page_offset + offset, true);\n const r_id = view.getBigInt64(\n page_offset + offset + 2 + existing_k_len,\n true,\n );\n const { cellType: mid_type, cellVal: mid_val } = page_decode_index_cell(\n view,\n page_offset + offset + 2,\n existing_k_len,\n key_type,\n );\n\n const cmp = page_compare_index_keys(\n key_type,\n key_value,\n rowid,\n mid_type,\n mid_val,\n r_id,\n );\n if (cmp < 0) {\n insert_slot = mid;\n hi = mid - 1;\n } else {\n lo = mid + 1;\n }\n }\n\n // Shift slot directory entries from insert_slot right by 2 bytes\n const uint8 = new Uint8Array(view.buffer);\n const abs_page_start = view.byteOffset + page_offset;\n const slot_dir_start = abs_page_start + PAGE_HEADER_SIZE;\n const src = slot_dir_start + insert_slot * 2;\n const dst = slot_dir_start + (insert_slot + 1) * 2;\n const shift_len = (cell_count - insert_slot) * 2;\n\n if (shift_len > 0) {\n uint8.copyWithin(dst, src, src + shift_len);\n }\n\n // Write new slot entry\n page_set_cell_offset(view, page_offset, insert_slot, new_content_offset);\n\n page_set_cell_count(view, page_offset, cell_count + 1);\n page_set_cell_content_offset(view, page_offset, new_content_offset);\n\n return insert_slot;\n}\n\n/**\n * Deletes an entry at slot_idx from a Secondary Index Leaf Page.\n */\nexport function page_delete_index_leaf_cell(\n view: DataView,\n page_offset: number,\n slot_idx: number,\n): void {\n const cell_count = page_get_cell_count(view, page_offset);\n if (slot_idx < 0 || slot_idx >= cell_count) return;\n\n const cell_offset = page_get_cell_offset(view, page_offset, slot_idx);\n const k_len = view.getUint16(page_offset + cell_offset, true);\n const cell_length = 2 + k_len + 8;\n\n const slot_dir_start = page_offset + PAGE_HEADER_SIZE;\n const src = slot_dir_start + (slot_idx + 1) * 2;\n const dst = slot_dir_start + slot_idx * 2;\n const shift_len = (cell_count - 1 - slot_idx) * 2;\n\n if (shift_len > 0) {\n memcpy(view, dst, view, src, shift_len);\n }\n\n page_set_cell_count(view, page_offset, cell_count - 1);\n page_set_free_bytes(\n view,\n page_offset,\n page_get_free_bytes(view, page_offset) + cell_length,\n );\n}\n\n/**\n * Binary searches an Index Leaf Page for target key and optional rowid.\n */\nexport function page_binary_search_index_leaf(\n view: DataView,\n page_offset: number,\n target_type: DataType,\n target_value: any,\n target_row_id?: bigint,\n): { found: boolean; slot_idx: number } {\n const cell_count = page_get_cell_count(view, page_offset);\n let lo = 0;\n let hi = cell_count - 1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const offset = page_get_cell_offset(view, page_offset, mid);\n const k_len = view.getUint16(page_offset + offset, true);\n const r_id = view.getBigInt64(page_offset + offset + 2 + k_len, true);\n const { cellType: mid_type, cellVal: mid_val } = page_decode_index_cell(\n view,\n page_offset + offset + 2,\n k_len,\n target_type,\n );\n\n const rowid_to_compare = target_row_id !== undefined ? target_row_id : r_id;\n const cmp = page_compare_index_keys(\n target_type,\n target_value,\n rowid_to_compare,\n mid_type,\n mid_val,\n r_id,\n );\n\n if (cmp === 0) {\n if (target_row_id === undefined) {\n let first_slot = mid;\n while (first_slot > 0) {\n const prev_slot = first_slot - 1;\n const prev_offset = page_get_cell_offset(view, page_offset, prev_slot);\n const prev_k_len = view.getUint16(page_offset + prev_offset, true);\n const { cellType: prev_type, cellVal: prev_val } = page_decode_index_cell(\n view,\n page_offset + prev_offset + 2,\n prev_k_len,\n target_type,\n );\n if (\n page_compare_index_keys(\n target_type,\n target_value,\n 0n,\n prev_type,\n prev_val,\n 0n,\n ) === 0\n ) {\n first_slot = prev_slot;\n } else {\n break;\n }\n }\n return { found: true, slot_idx: first_slot };\n }\n return { found: true, slot_idx: mid };\n } else if (cmp < 0) {\n hi = mid - 1;\n } else {\n lo = mid + 1;\n }\n }\n\n return { found: false, slot_idx: lo };\n}\n\n/**\n * Encodes a single column value to a byte array based on its DataType.\n */\nexport function serialize_single_key(type: DataType, val: any): Uint8Array {\n if (val === null || val === undefined) {\n return new Uint8Array(0);\n }\n if (type === DataType.INT32) {\n const b = new Uint8Array(4);\n new DataView(b.buffer).setInt32(0, Number(val), true);\n return b;\n }\n if (type === DataType.INT64) {\n const b = new Uint8Array(8);\n new DataView(b.buffer).setBigInt64(0, BigInt(val), true);\n return b;\n }\n if (type === DataType.FLOAT64) {\n const b = new Uint8Array(8);\n new DataView(b.buffer).setFloat64(0, Number(val), true);\n return b;\n }\n if (type === DataType.UUID) {\n const b = new Uint8Array(16);\n UuidCodec.encode(String(val), b, 0);\n return b;\n }\n if (type === DataType.ULID) {\n const b = new Uint8Array(16);\n UlidCodec.encode(String(val), b, 0);\n return b;\n }\n if (type === DataType.TEXT) {\n return text_encoder.encode(String(val));\n }\n return val instanceof Uint8Array ? val : new Uint8Array(val);\n}\n\n/**\n * Serializes a composite key tuple into a deterministic, comparable binary buffer.\n */\nexport function serialize_composite_key(\n columns: ColumnMeta[],\n col_indices: number[],\n col_count: number,\n row: DbRow,\n): Uint8Array {\n const parts: Uint8Array[] = [];\n let total_len = 0;\n for (let i = 0; i < col_count; i++) {\n const col = columns[col_indices[i]];\n const val = row[col.name];\n const encoded = serialize_single_key(col.type, val);\n const part = new Uint8Array(1 + 2 + encoded.byteLength);\n part[0] = col.type;\n part[1] = encoded.byteLength & 0xff;\n part[2] = (encoded.byteLength >> 8) & 0xff;\n part.set(encoded, 3);\n parts.push(part);\n total_len += part.byteLength;\n }\n const result = new Uint8Array(total_len);\n let offset = 0;\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n result.set(p, offset);\n offset += p.byteLength;\n }\n return result;\n}\n\n","import { PAGE_TO_SLOT_BUCKET_SIZE } from \"../../constants.ts\";\n\n/**\n * Knuth's 32-bit multiplicative hash constant: floor(2^32 / phi).\n */\nconst KNUTH_GOLDEN_RATIO_32 = 0x9e3779b9;\n\n/**\n * @export_c\n * Computes a 32-bit multiplicative integer hash for a page ID.\n *\n * @param page_id Positive 1-based page identifier\n * @param mask Bitmask for power-of-two bucket count (bucketCount - 1)\n * @returns Bucket index in range [0, mask]\n */\nexport function page_table_hash(page_id: number, mask: number): number {\n const h = Math.imul(page_id, KNUTH_GOLDEN_RATIO_32);\n return ((h ^ (h >>> 16)) >>> 0) & mask;\n}\n\n/**\n * @export_c\n * Probes the binary open-addressing hash table in shared memory for a page ID.\n *\n * Bucket Layout (8 bytes):\n * - [0..3] uint32_t page_id (0 = empty)\n * - [4..7] uint32_t slot_idx\n *\n * @param view Shared memory DataView\n * @param base_offset Byte offset where the hash table begins\n * @param bucket_count Total number of buckets (must be power of two)\n * @param page_id Positive 1-based page identifier\n * @returns Slot index if resident, or -1 if not found\n */\nexport function page_table_get(\n view: DataView,\n base_offset: number,\n bucket_count: number,\n page_id: number,\n): number {\n const mask = bucket_count - 1;\n let idx = page_table_hash(page_id, mask);\n\n for (let probe = 0; probe < bucket_count; probe++) {\n const offset = base_offset + idx * PAGE_TO_SLOT_BUCKET_SIZE;\n const entry_page_id = view.getUint32(offset, true);\n if (entry_page_id === 0) {\n return -1;\n }\n if (entry_page_id === page_id) {\n return view.getUint32(offset + 4, true);\n }\n idx = (idx + 1) & mask;\n }\n return -1;\n}\n\n/**\n * @export_c\n * Inserts or updates a page_id -> slot_idx mapping in the binary hash table.\n *\n * @param view Shared memory DataView\n * @param base_offset Byte offset where the hash table begins\n * @param bucket_count Total number of buckets (must be power of two)\n * @param page_id Positive 1-based page identifier\n * @param slot_idx Buffer pool cache slot index\n */\nexport function page_table_set(\n view: DataView,\n base_offset: number,\n bucket_count: number,\n page_id: number,\n slot_idx: number,\n): void {\n const mask = bucket_count - 1;\n let idx = page_table_hash(page_id, mask);\n\n for (let probe = 0; probe < bucket_count; probe++) {\n const offset = base_offset + idx * PAGE_TO_SLOT_BUCKET_SIZE;\n const entry_page_id = view.getUint32(offset, true);\n if (entry_page_id === 0 || entry_page_id === page_id) {\n view.setUint32(offset, page_id, true);\n view.setUint32(offset + 4, slot_idx, true);\n return;\n }\n idx = (idx + 1) & mask;\n }\n throw new Error(`BufferPool page table full: cannot insert page ${page_id}`);\n}\n\n/**\n * @export_c\n * Removes a page_id mapping using backward shift deletion (Robin Hood style).\n * This eliminates tombstones and guarantees linear probing chain continuity.\n *\n * @param view Shared memory DataView\n * @param base_offset Byte offset where the hash table begins\n * @param bucket_count Total number of buckets (must be power of two)\n * @param page_id Positive 1-based page identifier\n * @returns True if the page was found and removed, false otherwise\n */\nexport function page_table_delete(\n view: DataView,\n base_offset: number,\n bucket_count: number,\n page_id: number,\n): boolean {\n const mask = bucket_count - 1;\n let i = page_table_hash(page_id, mask);\n\n // 1. Locate the entry\n let found = false;\n for (let probe = 0; probe < bucket_count; probe++) {\n const offset = base_offset + i * PAGE_TO_SLOT_BUCKET_SIZE;\n const entry_page_id = view.getUint32(offset, true);\n if (entry_page_id === 0) {\n return false; // Key not found\n }\n if (entry_page_id === page_id) {\n found = true;\n break;\n }\n i = (i + 1) & mask;\n }\n\n if (!found) {\n return false;\n }\n\n // 2. Backward shift deletion (Robin Hood style open addressing)\n let j = i;\n while (true) {\n j = (j + 1) & mask;\n const j_offset = base_offset + j * PAGE_TO_SLOT_BUCKET_SIZE;\n const j_page_id = view.getUint32(j_offset, true);\n if (j_page_id === 0) {\n break;\n }\n const k = page_table_hash(j_page_id, mask);\n // Entry at j can be moved back to i if i lies between its natural hash k and current slot j (cyclically)\n if (((i - k) & mask) < ((j - k) & mask)) {\n const j_slot_idx = view.getUint32(j_offset + 4, true);\n const i_offset = base_offset + i * PAGE_TO_SLOT_BUCKET_SIZE;\n view.setUint32(i_offset, j_page_id, true);\n view.setUint32(i_offset + 4, j_slot_idx, true);\n i = j;\n }\n }\n\n // Clear the final vacated slot\n const clear_offset = base_offset + i * PAGE_TO_SLOT_BUCKET_SIZE;\n view.setUint32(clear_offset, 0, true);\n view.setUint32(clear_offset + 4, 0, true);\n return true;\n}\n","import {\n PAGE_SIZE,\n DEFAULT_SLOT_COUNT,\n DEFAULT_MAX_QUERY_MEMORY,\n PAGE_TO_SLOT_BUCKET_SIZE,\n PAGE_TYPE_FREE,\n PAGE_TYPE_CATALOG_PAGE,\n computeBufferPoolOffsets,\n} from \"../../constants.ts\";\nimport { page_get_type } from \"./page.c.ts\";\nimport {\n page_table_get,\n page_table_set,\n page_table_delete,\n} from \"./page_table.c.ts\";\nimport { u32, i32 } from \"../types.ts\";\nimport { QueryArenaExhaustedError } from \"../../types/index.ts\";\nimport {\n memcpy,\n memset,\n read_u8,\n write_u8,\n read_u16,\n write_u16,\n read_u32,\n write_u32,\n read_i32,\n write_i32,\n read_f64,\n write_f64,\n get_bit,\n set_bit,\n clear_bit,\n c_assert,\n} from \"../../shared/c_runtime.ts\";\n\n// ============================================================================\n// C-Style Functional Primitives (Drop-In C Port Reference Implementation)\n// ============================================================================\n\n/**\n * @export_c\n * Returns the byte offset for a given slot in linear memory.\n */\nexport function buf_pool_get_slot_offset(slot_idx: u32): u32 {\n return slot_idx * PAGE_SIZE;\n}\n\n/**\n * @export_c\n * Reads the page ID currently assigned to slot_idx from the slot_to_page map.\n */\nexport function buf_pool_read_slot_to_page(\n view: DataView,\n slot_to_page_offset: u32,\n slot_idx: u32,\n): u32 {\n return read_u32(view, slot_to_page_offset + slot_idx * 4);\n}\n\n/**\n * @export_c\n * Writes the page ID assigned to slot_idx in the slot_to_page map.\n */\nexport function buf_pool_write_slot_to_page(\n view: DataView,\n slot_to_page_offset: u32,\n slot_idx: u32,\n page_id: u32,\n): void {\n write_u32(view, slot_to_page_offset + slot_idx * 4, page_id);\n}\n\n/**\n * @export_c\n * Looks up the resident slot for page_id in the open-addressing hash table.\n * Returns slot index or -1 if not resident.\n */\nexport function buf_pool_get_resident_slot(\n view: DataView,\n page_to_slot_offset: u32,\n page_to_slot_buckets: u32,\n page_id: u32,\n): i32 {\n return page_table_get(\n view,\n page_to_slot_offset,\n page_to_slot_buckets,\n page_id,\n );\n}\n\n/**\n * @export_c\n * Assigns slot_idx to page_id, updating slot_to_page and page_to_slot hash tables.\n */\nexport function buf_pool_assign_slot(\n view: DataView,\n slot_to_page_offset: u32,\n page_to_slot_offset: u32,\n page_to_slot_buckets: u32,\n slot_idx: u32,\n page_id: u32,\n): i32 {\n c_assert(page_id > 0, \"page_id must be > 0\");\n const old_page = buf_pool_read_slot_to_page(\n view,\n slot_to_page_offset,\n slot_idx,\n );\n if (old_page > 0 && old_page !== page_id) {\n page_table_delete(\n view,\n page_to_slot_offset,\n page_to_slot_buckets,\n old_page,\n );\n }\n buf_pool_write_slot_to_page(view, slot_to_page_offset, slot_idx, page_id);\n page_table_set(\n view,\n page_to_slot_offset,\n page_to_slot_buckets,\n page_id,\n slot_idx,\n );\n return 0;\n}\n\n/**\n * @export_c\n * Unassigns slot_idx, clearing its page table entry and setting assigned page to 0.\n */\nexport function buf_pool_unassign_slot(\n view: DataView,\n slot_to_page_offset: u32,\n page_to_slot_offset: u32,\n page_to_slot_buckets: u32,\n slot_idx: u32,\n): i32 {\n const old_page = buf_pool_read_slot_to_page(\n view,\n slot_to_page_offset,\n slot_idx,\n );\n if (old_page > 0) {\n page_table_delete(\n view,\n page_to_slot_offset,\n page_to_slot_buckets,\n old_page,\n );\n buf_pool_write_slot_to_page(view, slot_to_page_offset, slot_idx, 0);\n return 1;\n }\n return 0;\n}\n\n/**\n * @export_c\n * Marks slot_idx as dirty in the dirty bitmask.\n */\nexport function buf_pool_mark_dirty(\n dirty_mask: Uint8Array,\n dirty_mask_offset: u32,\n slot_idx: u32,\n): void {\n set_bit(dirty_mask, dirty_mask_offset, slot_idx);\n}\n\n/**\n * @export_c\n * Clears the dirty bit for slot_idx in the dirty bitmask.\n */\nexport function buf_pool_clear_dirty(\n dirty_mask: Uint8Array,\n dirty_mask_offset: u32,\n slot_idx: u32,\n): void {\n clear_bit(dirty_mask, dirty_mask_offset, slot_idx);\n}\n\n/**\n * @export_c\n * Checks if slot_idx is marked dirty in the dirty bitmask.\n */\nexport function buf_pool_is_dirty(\n dirty_mask: Uint8Array,\n dirty_mask_offset: u32,\n slot_idx: u32,\n): boolean {\n return get_bit(dirty_mask, dirty_mask_offset, slot_idx) === 1;\n}\n\n/**\n * Increments pin count for slot_idx. Throws on uint32 overflow.\n */\nexport function buf_pool_pin_slot(\n pin_counts: Uint32Array,\n slot_idx: number,\n): void {\n if (pin_counts[slot_idx] >= 0xffffffff) {\n throw new Error(`Pin count overflow on slot ${slot_idx}`);\n }\n pin_counts[slot_idx]++;\n}\n\n/**\n * Decrements pin count for slot_idx. Slot 0 is permanently pinned.\n */\nexport function buf_pool_unpin_slot(\n pin_counts: Uint32Array,\n slot_idx: number,\n): void {\n if (slot_idx === 0) return; // Slot 0 is permanently pinned\n if (pin_counts[slot_idx] > 0) {\n pin_counts[slot_idx]--;\n }\n}\n\n/**\n * Returns true if slot_idx is pinned (pin_count > 0 or slot 0).\n */\nexport function buf_pool_is_pinned(\n pin_counts: Uint32Array,\n slot_idx: number,\n): boolean {\n return slot_idx === 0 || pin_counts[slot_idx] > 0;\n}\n\n/**\n * Finds an eviction candidate slot using Clock sweep with second-chance bit check.\n */\nexport function buf_pool_find_victim(\n buffer: ArrayBuffer,\n ref_bits: Uint8Array,\n pin_counts: Uint32Array,\n slot_to_page_offset: number,\n slot_count: number,\n current_clock_hand: number,\n): { candidate_slot: number; next_clock_hand: number } {\n const view = new DataView(buffer);\n\n // 1. Scan for unallocated, unpinned slots (page_id == 0)\n for (let i = 1; i < slot_count; i++) {\n if (\n read_u32(view, slot_to_page_offset + i * 4) === 0 &&\n !buf_pool_is_pinned(pin_counts, i)\n ) {\n return { candidate_slot: i, next_clock_hand: current_clock_hand };\n }\n }\n\n // 2. Clock (Second-Chance) eviction loop\n let hand = current_clock_hand;\n for (let step = 0; step < slot_count * 2; step++) {\n hand = (hand + 1) % slot_count;\n if (hand === 0) continue; // Skip Page 1\n\n if (buf_pool_is_pinned(pin_counts, hand)) {\n continue;\n }\n\n // Defense-in-depth: Never evict system/catalog pages (0x0C)\n const slot_view = new DataView(buffer, hand * PAGE_SIZE, PAGE_SIZE);\n if (page_get_type(slot_view, 0) === PAGE_TYPE_CATALOG_PAGE) {\n continue;\n }\n\n if (ref_bits[hand] === 1) {\n ref_bits[hand] = 0;\n } else {\n return { candidate_slot: hand, next_clock_hand: hand };\n }\n }\n\n throw new Error(\"Cache deadlock: all slots are pinned\");\n}\n\n/**\n * Selects an eviction candidate slot for a requested page using the Core Clock sweep.\n * Examines candidate slot to determine if it holds a dirty page that must be flushed.\n */\nexport function buf_pool_select_eviction_victim(\n buffer: ArrayBuffer,\n ref_bits: Uint8Array,\n pin_counts: Uint32Array,\n slot_to_page_offset: number,\n dirty_mask_offset: number,\n slot_count: number,\n current_clock_hand: number,\n page_id: number,\n): { candidate_slot: number; flush_page_id: number; next_clock_hand: number } {\n const view = new DataView(buffer);\n\n let candidate_slot = -1;\n let next_clock_hand = current_clock_hand;\n\n if (\n page_id > 1 &&\n page_id <= slot_count &&\n buf_pool_read_slot_to_page(view, slot_to_page_offset, page_id - 1) === 0 &&\n !buf_pool_is_pinned(pin_counts, page_id - 1)\n ) {\n candidate_slot = page_id - 1;\n } else {\n const victim = buf_pool_find_victim(\n buffer,\n ref_bits,\n pin_counts,\n slot_to_page_offset,\n slot_count,\n current_clock_hand,\n );\n candidate_slot = victim.candidate_slot;\n next_clock_hand = victim.next_clock_hand;\n }\n\n const old_page_id = buf_pool_read_slot_to_page(\n view,\n slot_to_page_offset,\n candidate_slot,\n );\n const is_dirty = buf_pool_is_dirty(\n new Uint8Array(buffer),\n dirty_mask_offset,\n candidate_slot,\n );\n const slot_view = new DataView(buffer, candidate_slot * PAGE_SIZE, PAGE_SIZE);\n const is_free_page =\n old_page_id > 0 && page_get_type(slot_view, 0) === PAGE_TYPE_FREE;\n const flush_page_id =\n is_dirty && !is_free_page && old_page_id > 0 ? old_page_id : 0;\n\n return { candidate_slot, flush_page_id, next_clock_hand };\n}\n\n// ============================================================================\n// Buffer Pool Class Definition (Synchronous Core Memory Manager)\n// ============================================================================\n\nexport interface BufferPoolOptions {\n slotCount?: number;\n maxQueryMemory?: number;\n vfs?: any; // Ignored, kept for backwards compatibility if passed\n}\n\nexport class BufferPool {\n readonly slot_count: number;\n readonly max_query_memory: number;\n\n readonly wasm_memory: WebAssembly.Memory;\n buffer: ArrayBuffer;\n view: DataView;\n uint8: Uint8Array;\n\n // Offsets\n readonly slots_end_offset: number;\n readonly slot_to_page_offset: number;\n readonly page_to_slot_offset: number;\n readonly page_to_slot_buckets: number;\n readonly dirty_mask_offset: number;\n readonly vm_context_offset: number;\n readonly result_buffer_offset: number;\n readonly bytecode_offset: number;\n readonly page_scratchpad_offset: number;\n readonly transient_arena_offset: number;\n\n // State arrays (pre-allocated)\n readonly pin_counts: Uint32Array;\n readonly slot_dirty_generations: Uint32Array;\n readonly ref_bits: Uint8Array;\n private clock_hand: number = 0;\n private arena_offset: number = 0;\n\n constructor(options?: BufferPoolOptions) {\n this.slot_count = options?.slotCount ?? DEFAULT_SLOT_COUNT;\n\n if (!Number.isInteger(this.slot_count) || this.slot_count < 2) {\n throw new Error(\n `Invalid slotCount: ${this.slot_count}. Must be an integer >= 2`,\n );\n }\n\n this.max_query_memory = options?.maxQueryMemory ?? DEFAULT_MAX_QUERY_MEMORY;\n\n if (\n !Number.isInteger(this.max_query_memory) ||\n this.max_query_memory <= 0\n ) {\n throw new Error(\n `Invalid maxQueryMemory: ${this.max_query_memory}. Must be a positive integer`,\n );\n }\n\n this.ref_bits = new Uint8Array(this.slot_count);\n this.pin_counts = new Uint32Array(this.slot_count);\n this.slot_dirty_generations = new Uint32Array(this.slot_count);\n\n const offsets = computeBufferPoolOffsets(\n this.slot_count,\n this.max_query_memory,\n );\n\n this.slots_end_offset = offsets.slotsEndOffset;\n this.slot_to_page_offset = offsets.slotToPageOffset;\n this.page_to_slot_offset = offsets.pageToSlotOffset;\n this.page_to_slot_buckets = offsets.pageToSlotBuckets;\n this.dirty_mask_offset = offsets.dirtyMaskOffset;\n this.vm_context_offset = offsets.vmContextOffset;\n this.result_buffer_offset = offsets.resultBufferOffset;\n this.bytecode_offset = offsets.bytecodeOffset;\n this.page_scratchpad_offset = offsets.pageScratchpadOffset;\n this.transient_arena_offset = offsets.transientArenaOffset;\n\n // Allocate WebAssembly.Memory (64KB per page)\n const initial_bytes = this.transient_arena_offset + 256 * 1024;\n const initial_wasm_pages = Math.ceil(initial_bytes / 65536);\n const max_wasm_pages = Math.ceil(\n (this.transient_arena_offset + this.max_query_memory) / 65536,\n );\n\n this.wasm_memory = new WebAssembly.Memory({\n initial: initial_wasm_pages,\n maximum: Math.max(initial_wasm_pages, max_wasm_pages),\n });\n\n this.buffer = this.wasm_memory.buffer;\n this.view = new DataView(this.buffer);\n this.uint8 = new Uint8Array(this.buffer);\n\n // Initialize slot-to-page map, page-to-slot hash table, and dirty mask to zeros\n memset(this.uint8, this.slot_to_page_offset, 0, this.slot_count * 4);\n memset(\n this.uint8,\n this.page_to_slot_offset,\n 0,\n this.page_to_slot_buckets * PAGE_TO_SLOT_BUCKET_SIZE,\n );\n memset(\n this.uint8,\n this.dirty_mask_offset,\n 0,\n Math.ceil(this.slot_count / 8),\n );\n\n // Page 1 is permanently assigned to slot 0 and pinned\n this.assign_slot(0, 1);\n this.pin_counts[0] = 1;\n }\n\n // ==========================================================================\n // Direct C-Style Memory Access Primitives (Little-Endian)\n // ==========================================================================\n\n read_u8(address: number): number {\n return read_u8(this.uint8, address);\n }\n\n write_u8(address: number, val: number): void {\n write_u8(this.uint8, address, val);\n }\n\n read_u16(address: number): number {\n return read_u16(this.view, address);\n }\n\n write_u16(address: number, val: number): void {\n write_u16(this.view, address, val);\n }\n\n read_u32(address: number): number {\n return read_u32(this.view, address);\n }\n\n write_u32(address: number, val: number): void {\n write_u32(this.view, address, val);\n }\n\n read_i32(address: number): number {\n return read_i32(this.view, address);\n }\n\n write_i32(address: number, val: number): void {\n write_i32(this.view, address, val);\n }\n\n read_f64(address: number): number {\n return read_f64(this.view, address);\n }\n\n write_f64(address: number, val: number): void {\n write_f64(this.view, address, val);\n }\n\n get_bytes(address: number, length: number): Uint8Array {\n return this.uint8.subarray(address, address + length);\n }\n\n set_bytes(address: number, source: Uint8Array): void {\n memcpy(this.uint8, address, source, 0, source.byteLength);\n }\n\n fill_bytes(address: number, length: number, val: number = 0): void {\n memset(this.uint8, address, val, length);\n }\n\n // ==========================================================================\n // Validation Helpers\n // ==========================================================================\n\n private validate_slot_idx(slot_idx: number): void {\n if (\n !Number.isInteger(slot_idx) ||\n slot_idx < 0 ||\n slot_idx >= this.slot_count\n ) {\n throw new Error(\n `Invalid slot index: ${slot_idx}. Must be an integer between 0 and ${this.slot_count - 1}`,\n );\n }\n }\n\n private validate_page_id(page_id: number): void {\n if (!Number.isInteger(page_id) || page_id <= 0) {\n throw new Error(\n `Invalid page ID: ${page_id}. Page IDs must be positive integers.`,\n );\n }\n }\n\n // ==========================================================================\n // Slot Mapping & Dirty Bitmask\n // ==========================================================================\n\n get_assigned_page(slot_idx: number): number {\n this.validate_slot_idx(slot_idx);\n return buf_pool_read_slot_to_page(\n this.view,\n this.slot_to_page_offset,\n slot_idx,\n );\n }\n\n assign_slot(slot_idx: number, page_id: number): void {\n this.validate_slot_idx(slot_idx);\n\n if (!Number.isInteger(page_id) || page_id <= 0) {\n throw new Error(\n `Invalid page ID: ${page_id}. Must be a positive integer >= 1`,\n );\n }\n\n if (slot_idx === 0 && page_id !== 1) {\n throw new Error(\n `Cannot reassign slot 0: reserved permanently for page 1 (got page ${page_id})`,\n );\n }\n\n const existing_slot = this.get_resident_slot(page_id);\n if (existing_slot !== -1 && existing_slot !== slot_idx) {\n throw new Error(\n `Cannot map page ${page_id} to slot ${slot_idx}: already resident in slot ${existing_slot}`,\n );\n }\n\n buf_pool_assign_slot(\n this.view,\n this.slot_to_page_offset,\n this.page_to_slot_offset,\n this.page_to_slot_buckets,\n slot_idx,\n page_id,\n );\n }\n\n unassign_slot(slot_idx: number): void {\n this.validate_slot_idx(slot_idx);\n\n if (slot_idx === 0) {\n throw new Error(\n `Cannot unassign slot 0: reserved permanently for page 1`,\n );\n }\n\n buf_pool_unassign_slot(\n this.view,\n this.slot_to_page_offset,\n this.page_to_slot_offset,\n this.page_to_slot_buckets,\n slot_idx,\n );\n }\n\n mark_dirty(slot_idx: number): void {\n this.validate_slot_idx(slot_idx);\n buf_pool_mark_dirty(this.uint8, this.dirty_mask_offset, slot_idx);\n this.slot_dirty_generations[slot_idx]++;\n }\n\n clear_dirty(slot_idx: number): void {\n this.validate_slot_idx(slot_idx);\n buf_pool_clear_dirty(this.uint8, this.dirty_mask_offset, slot_idx);\n }\n\n is_dirty(slot_idx: number): boolean {\n this.validate_slot_idx(slot_idx);\n return buf_pool_is_dirty(this.uint8, this.dirty_mask_offset, slot_idx);\n }\n\n // ==========================================================================\n // Pinning Invariant (Reference Counted)\n // ==========================================================================\n\n pin_slot(slot_idx: number): void {\n this.validate_slot_idx(slot_idx);\n buf_pool_pin_slot(this.pin_counts, slot_idx);\n }\n\n unpin_slot(slot_idx: number): void {\n this.validate_slot_idx(slot_idx);\n buf_pool_unpin_slot(this.pin_counts, slot_idx);\n }\n\n pin_page(page_id: number): void {\n this.validate_page_id(page_id);\n const slot = this.get_resident_slot(page_id);\n if (slot === -1) {\n throw new Error(\n `Cannot pin page ${page_id}: page is not resident in buffer pool`,\n );\n }\n this.pin_slot(slot);\n }\n\n unpin_page(page_id: number): void {\n this.validate_page_id(page_id);\n if (page_id === 1) return;\n const slot = this.get_resident_slot(page_id);\n if (slot !== -1) {\n this.unpin_slot(slot);\n }\n }\n\n is_pinned(slot_idx: number): boolean {\n this.validate_slot_idx(slot_idx);\n return buf_pool_is_pinned(this.pin_counts, slot_idx);\n }\n\n get_pin_count(slot_idx: number): number {\n this.validate_slot_idx(slot_idx);\n return this.pin_counts[slot_idx];\n }\n\n get_ref_bit(slot_idx: number): number {\n this.validate_slot_idx(slot_idx);\n return this.ref_bits[slot_idx];\n }\n\n set_ref_bit(slot_idx: number, val: number): void {\n this.validate_slot_idx(slot_idx);\n this.ref_bits[slot_idx] = val ? 1 : 0;\n }\n\n // ==========================================================================\n // Page Access & Resident Lookups\n // ==========================================================================\n\n get_slot_offset(slot_idx: number): number {\n this.validate_slot_idx(slot_idx);\n return buf_pool_get_slot_offset(slot_idx);\n }\n\n get_page_bytes_in_slot(slot_idx: number): Uint8Array {\n this.validate_slot_idx(slot_idx);\n return this.get_bytes(slot_idx * PAGE_SIZE, PAGE_SIZE);\n }\n\n get_slot_data_view(slot_idx: number): DataView {\n this.validate_slot_idx(slot_idx);\n return new DataView(this.buffer, slot_idx * PAGE_SIZE, PAGE_SIZE);\n }\n\n get_resident_slot(page_id: number): number {\n this.validate_page_id(page_id);\n return buf_pool_get_resident_slot(\n this.view,\n this.page_to_slot_offset,\n this.page_to_slot_buckets,\n page_id,\n );\n }\n\n find_eviction_candidate_slot(): number {\n const res = buf_pool_find_victim(\n this.buffer,\n this.ref_bits,\n this.pin_counts,\n this.slot_to_page_offset,\n this.slot_count,\n this.clock_hand,\n );\n this.clock_hand = res.next_clock_hand;\n return res.candidate_slot;\n }\n\n // ==========================================================================\n // Transient Query Arena\n // ==========================================================================\n\n get_arena_offset(): number {\n return this.arena_offset;\n }\n\n alloc_arena(size: number): number {\n if (!Number.isInteger(size) || size <= 0) {\n throw new Error(\n `Invalid arena allocation size: ${size}. Size must be a positive integer.`,\n );\n }\n\n const aligned_size = (size + 7) & ~7;\n if (this.arena_offset + aligned_size > this.max_query_memory) {\n throw new QueryArenaExhaustedError();\n }\n\n const required_bytes =\n this.transient_arena_offset + this.arena_offset + aligned_size;\n if (required_bytes > this.buffer.byteLength) {\n const needed_bytes = required_bytes - this.buffer.byteLength;\n const pages_to_grow = Math.ceil(needed_bytes / 65536);\n this.wasm_memory.grow(pages_to_grow);\n this.buffer = this.wasm_memory.buffer;\n this.view = new DataView(this.buffer);\n this.uint8 = new Uint8Array(this.buffer);\n }\n\n const current = this.transient_arena_offset + this.arena_offset;\n this.arena_offset += aligned_size;\n return current;\n }\n\n reset_arena(): void {\n if (this.arena_offset > 0) {\n this.fill_bytes(this.transient_arena_offset, this.arena_offset, 0);\n this.arena_offset = 0;\n }\n }\n}\n","import {\n PAGE_SIZE,\n RESULT_BUFFER_OFFSET,\n RESULT_BUFFER_SIZE,\n PAGE_TO_SLOT_OFFSET,\n PAGE_TO_SLOT_SIZE,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n} from \"../../constants.ts\";\nimport {\n VmStatus,\n DataType,\n ColumnMeta,\n ColumnFlag,\n} from \"../../types/index.ts\";\nimport { u32, i32, i64, f64 } from \"../types.ts\";\nimport { page_serialize_row } from \"./page.c.ts\";\nimport { buf_pool_get_resident_slot } from \"./buffer_pool.c.ts\";\nimport {\n type VmCursor,\n type VmContext,\n type VmKeyInfo,\n type VmSorter,\n type VmSorterEntry,\n type VmAggBucket,\n} from \"../../shared/index.ts\";\n\n/**\n * Returns the active cursor for cursor_idx (0..15), falling back to ctx.cursor.\n */\nexport function get_cursor(ctx: VmContext, cursor_idx: number): VmCursor {\n if (ctx.cursors && ctx.cursors[cursor_idx]) {\n return ctx.cursors[cursor_idx];\n }\n return ctx.cursor;\n}\n\n/**\n * Resolves the byte offset in linear memory for a given page_id.\n * If the buffer pool page-to-slot table is populated, maps via the resident slot.\n * Otherwise falls back to standalone direct calculation: (page_id - 1) * PAGE_SIZE.\n */\nexport function resolve_page_offset(view: DataView, page_id: number): number {\n if (page_id <= 0) return 0;\n if (view.byteLength >= PAGE_TO_SLOT_OFFSET + PAGE_TO_SLOT_SIZE) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n page_id,\n );\n if (slot >= 0) {\n return slot * PAGE_SIZE;\n }\n }\n return (page_id - 1) * PAGE_SIZE;\n}\n\n/**\n * Three-Valued Logic (3VL) comparator for evaluation registers.\n * If either value is null or undefined, returns is_unknown = true.\n */\nexport function compare_3vl(\n val_a: any,\n val_b: any,\n): { result: number; is_unknown: boolean } {\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n return { result: 0, is_unknown: true };\n }\n\n if (typeof val_a === \"boolean\" || typeof val_b === \"boolean\") {\n const num_a = val_a ? 1 : 0;\n const num_b = val_b ? 1 : 0;\n if (num_a === num_b) return { result: 0, is_unknown: false };\n return { result: num_a > num_b ? 1 : -1, is_unknown: false };\n }\n\n if (typeof val_a === \"number\" && typeof val_b === \"number\") {\n if (val_a === val_b) return { result: 0, is_unknown: false };\n return { result: val_a > val_b ? 1 : -1, is_unknown: false };\n }\n\n if (typeof val_a === \"bigint\" || typeof val_b === \"bigint\") {\n const a = BigInt(val_a);\n const b = BigInt(val_b);\n if (a === b) return { result: 0, is_unknown: false };\n return { result: a > b ? 1 : -1, is_unknown: false };\n }\n\n if (typeof val_a === \"string\" && typeof val_b === \"string\") {\n if (val_a === val_b) return { result: 0, is_unknown: false };\n return { result: val_a > val_b ? 1 : -1, is_unknown: false };\n }\n\n if (val_a instanceof Uint8Array && val_b instanceof Uint8Array) {\n const min_len = Math.min(val_a.byteLength, val_b.byteLength);\n for (let i = 0; i < min_len; i++) {\n if (val_a[i] !== val_b[i]) {\n return { result: val_a[i] > val_b[i] ? 1 : -1, is_unknown: false };\n }\n }\n if (val_a.byteLength === val_b.byteLength) {\n return { result: 0, is_unknown: false };\n }\n return {\n result: val_a.byteLength > val_b.byteLength ? 1 : -1,\n is_unknown: false,\n };\n }\n\n if (val_a === val_b) return { result: 0, is_unknown: false };\n return { result: val_a > val_b ? 1 : -1, is_unknown: false };\n}\n\n/**\n * @export_c\n */\nfunction to_lower_char(c: i32): i32 {\n if (c >= 65 && c <= 90) return c + 32;\n return c;\n}\n\n/**\n * @export_c\n */\nexport function fnv1a_32_bytes(data: Uint8Array, len: u32): u32 {\n let hash: u32 = 0x811c9dc5;\n for (let i: u32 = 0; i < len; i++) {\n hash ^= data[i];\n hash = Math.imul(hash, 0x01000193);\n }\n return hash !== 0 ? (hash >>> 0) : 1;\n}\n\n/**\n * @export_c\n */\nexport function sql_like_match_raw(\n str: string,\n str_len: u32,\n pattern: string,\n pat_len: u32,\n): i32 {\n let s: u32 = 0;\n let p: u32 = 0;\n let star_p: i32 = -1;\n let star_s: i32 = -1;\n\n while (s < str_len) {\n const p_c = p < pat_len ? pattern.charCodeAt(p) : 0;\n const s_c = str.charCodeAt(s);\n if (p < pat_len && (p_c === 95 || to_lower_char(p_c) === to_lower_char(s_c))) {\n s++;\n p++;\n } else if (p < pat_len && p_c === 37) {\n star_p = p++;\n star_s = s;\n } else if (star_p !== -1) {\n p = star_p + 1;\n s = ++star_s;\n } else {\n return 0;\n }\n }\n\n while (p < pat_len && pattern.charCodeAt(p) === 37) {\n p++;\n }\n\n return p === pat_len ? 1 : 0;\n}\n\nexport interface Compare3VLResult {\n result: i32;\n is_unknown: i32;\n}\n\n/**\n * @export_c\n */\nexport function compare_3vl_int64(\n a: i64,\n a_null: i32,\n b: i64,\n b_null: i32,\n): Compare3VLResult {\n if (a_null !== 0 || b_null !== 0) {\n return { result: 0, is_unknown: 1 };\n }\n return { result: a < b ? -1 : a > b ? 1 : 0, is_unknown: 0 };\n}\n\n/**\n * @export_c\n */\nexport function compare_3vl_float64(\n a: f64,\n a_null: i32,\n b: f64,\n b_null: i32,\n): Compare3VLResult {\n if (a_null !== 0 || b_null !== 0) {\n return { result: 0, is_unknown: 1 };\n }\n return { result: a < b ? -1 : a > b ? 1 : 0, is_unknown: 0 };\n}\n\n/**\n * @export_c\n */\nexport function compare_3vl_bytes(\n a: Uint8Array,\n a_len: u32,\n a_null: i32,\n b: Uint8Array,\n b_len: u32,\n b_null: i32,\n): Compare3VLResult {\n if (a_null !== 0 || b_null !== 0) {\n return { result: 0, is_unknown: 1 };\n }\n const min_len = a_len < b_len ? a_len : b_len;\n for (let i: u32 = 0; i < min_len; i++) {\n if (a[i] !== b[i]) {\n return { result: a[i] < b[i] ? -1 : 1, is_unknown: 0 };\n }\n }\n return { result: a_len < b_len ? -1 : a_len > b_len ? 1 : 0, is_unknown: 0 };\n}\n\n/**\n * Standard SQL LIKE pattern matcher supporting '%' (any sequence) and '_' (any single character).\n * Case-insensitive for ASCII matching according to SQLite semantics.\n */\nexport function sql_like_match(str: string, pattern: string): boolean {\n return sql_like_match_raw(str, str.length, pattern, pattern.length) === 1;\n}\n\n/**\n * Compares two sets of sort keys according to KeyInfo descriptor.\n * Strictly adheres to SQLite NULL collation (NULL is smaller than any non-NULL value)\n * and honors independent per-column ASC/DESC and NULLS_FIRST/NULLS_LAST.\n */\nexport function compare_sorter_keys(\n keys_a: any[],\n keys_b: any[],\n key_info: VmKeyInfo,\n): number {\n const num_keys = key_info.numKeys;\n for (let k = 0; k < num_keys; k++) {\n const a = keys_a[k];\n const b = keys_b[k];\n const direction = key_info.directions[k] ?? 0; // 0 = ASC, 1 = DESC\n const null_order = key_info.nullOrders[k] ?? (direction === 1 ? 1 : 0); // 0 = NULLS_FIRST, 1 = NULLS_LAST\n\n const a_is_null = a === null || a === undefined;\n const b_is_null = b === null || b === undefined;\n\n if (a_is_null && b_is_null) {\n continue;\n }\n\n if (a_is_null || b_is_null) {\n const cmp = null_order === 0 ? (a_is_null ? -1 : 1) : a_is_null ? 1 : -1;\n return cmp;\n }\n\n // Both non-null\n let cmp = 0;\n if (typeof a === \"number\" && typeof b === \"number\") {\n cmp = a < b ? -1 : a > b ? 1 : 0;\n } else if (typeof a === \"bigint\" || typeof b === \"bigint\") {\n const ba = BigInt(a);\n const bb = BigInt(b);\n cmp = ba < bb ? -1 : ba > bb ? 1 : 0;\n } else if (typeof a === \"string\" && typeof b === \"string\") {\n cmp = a < b ? -1 : a > b ? 1 : 0;\n } else if (a instanceof Uint8Array && b instanceof Uint8Array) {\n const min_len = Math.min(a.byteLength, b.byteLength);\n for (let i = 0; i < min_len; i++) {\n if (a[i] !== b[i]) {\n cmp = a[i] < b[i] ? -1 : 1;\n break;\n }\n }\n if (cmp === 0) {\n cmp =\n a.byteLength < b.byteLength\n ? -1\n : a.byteLength > b.byteLength\n ? 1\n : 0;\n }\n } else {\n cmp = (a as any) < (b as any) ? -1 : (a as any) > (b as any) ? 1 : 0;\n }\n\n if (cmp !== 0) {\n return direction === 1 ? -cmp : cmp;\n }\n }\n return 0;\n}\n\n/**\n * Compares sort keys stored in contiguous registers against a target entry's keys.\n * Avoids allocating an intermediate array for rejected Top-K candidates.\n */\nexport function compare_registers_to_sorter_keys(\n registers: any[],\n start_reg: number,\n keys_b: any[],\n key_info: VmKeyInfo,\n): number {\n const num_keys = key_info.numKeys;\n for (let k = 0; k < num_keys; k++) {\n const a = registers[start_reg + k];\n const b = keys_b[k];\n const direction = key_info.directions[k] ?? 0;\n const null_order = key_info.nullOrders[k] ?? (direction === 1 ? 1 : 0);\n\n const a_is_null = a === null || a === undefined;\n const b_is_null = b === null || b === undefined;\n\n if (a_is_null && b_is_null) continue;\n if (a_is_null || b_is_null) {\n return null_order === 0 ? (a_is_null ? -1 : 1) : a_is_null ? 1 : -1;\n }\n\n let cmp = 0;\n if (typeof a === \"number\" && typeof b === \"number\") {\n cmp = a < b ? -1 : a > b ? 1 : 0;\n } else if (typeof a === \"string\" && typeof b === \"string\") {\n cmp = a < b ? -1 : a > b ? 1 : 0;\n } else if (typeof a === \"bigint\" || typeof b === \"bigint\") {\n const ba = BigInt(a);\n const bb = BigInt(b);\n cmp = ba < bb ? -1 : ba > bb ? 1 : 0;\n } else if (a instanceof Uint8Array && b instanceof Uint8Array) {\n const min_len = Math.min(a.byteLength, b.byteLength);\n for (let i = 0; i < min_len; i++) {\n if (a[i] !== b[i]) {\n cmp = a[i] < b[i] ? -1 : 1;\n break;\n }\n }\n if (cmp === 0) {\n cmp = a.byteLength < b.byteLength ? -1 : a.byteLength > b.byteLength ? 1 : 0;\n }\n } else {\n cmp = (a as any) < (b as any) ? -1 : (a as any) > (b as any) ? 1 : 0;\n }\n\n if (cmp !== 0) {\n return direction === 1 ? -cmp : cmp;\n }\n }\n return 0;\n}\n\n/**\n * 32-bit FNV-1a hash over grouping key values.\n * Returns non-zero uint32 (reserving 0 as empty bucket marker).\n */\nexport function fnv1a_32(values: any[]): number {\n let hash = 0x811c9dc5; // 2166136261\n for (let k = 0; k < values.length; k++) {\n const v = values[k];\n if (v === null || v === undefined) {\n hash ^= 0xff;\n hash = Math.imul(hash, 0x01000193);\n } else if (typeof v === \"number\") {\n const buf = new ArrayBuffer(8);\n new DataView(buf).setFloat64(0, v, true);\n const u8 = new Uint8Array(buf);\n for (let i = 0; i < 8; i++) {\n hash ^= u8[i];\n hash = Math.imul(hash, 0x01000193);\n }\n } else if (typeof v === \"string\") {\n for (let i = 0; i < v.length; i++) {\n hash ^= v.charCodeAt(i) & 0xff;\n hash = Math.imul(hash, 0x01000193);\n }\n } else if (typeof v === \"bigint\") {\n const n = Number(v);\n hash ^= n & 0xff;\n hash = Math.imul(hash, 0x01000193);\n } else if (v instanceof Uint8Array) {\n for (let i = 0; i < v.byteLength; i++) {\n hash ^= v[i];\n hash = Math.imul(hash, 0x01000193);\n }\n }\n }\n hash = hash >>> 0;\n return hash === 0 ? 1 : hash;\n}\n\n/**\n * Checks equality between two sets of grouping keys.\n * In SQL GROUP BY: two NULLs in grouping columns are considered identical!\n */\nexport function group_keys_match(keys_a: any[], keys_b: any[]): boolean {\n if (keys_a.length !== keys_b.length) {\n return false;\n }\n\n for (let i = 0; i < keys_a.length; i++) {\n const a = keys_a[i];\n const b = keys_b[i];\n\n if (a === null || a === undefined) {\n if (b !== null && b !== undefined) return false;\n } else if (b === null || b === undefined) {\n return false;\n } else if (a !== b) {\n if (a instanceof Uint8Array && b instanceof Uint8Array) {\n if (a.byteLength !== b.byteLength) return false;\n for (let j = 0; j < a.byteLength; j++) {\n if (a[j] !== b[j]) return false;\n }\n } else {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * Allocates and initializes an array of empty aggregate buckets.\n */\nexport function create_agg_buckets(capacity: number): VmAggBucket[] {\n const buckets: VmAggBucket[] = new Array(capacity);\n for (let i = 0; i < capacity; i++) {\n buckets[i] = {\n hash: 0,\n keys: [],\n count: 0,\n sum: 0,\n min_val: Infinity,\n max_val: -Infinity,\n has_val: false,\n };\n }\n return buckets;\n}\n\n/**\n * Sifts down an entry at index in a max-heap of top-K entries.\n * The root (index 0) contains the worst entry (largest/latest in sorted order).\n */\nexport function heap_sift_down(\n entries: VmSorterEntry[],\n index: number,\n length: number,\n key_info: VmKeyInfo,\n): void {\n let curr = index;\n while (true) {\n let largest = curr;\n const left = 2 * curr + 1;\n const right = 2 * curr + 2;\n\n if (\n left < length &&\n compare_sorter_keys(entries[left].keys, entries[largest].keys, key_info) > 0\n ) {\n largest = left;\n }\n if (\n right < length &&\n compare_sorter_keys(entries[right].keys, entries[largest].keys, key_info) > 0\n ) {\n largest = right;\n }\n\n if (largest !== curr) {\n const temp = entries[curr];\n entries[curr] = entries[largest];\n entries[largest] = temp;\n curr = largest;\n } else {\n break;\n }\n }\n}\n\n/**\n * Sorts sorter entries using collation keys and initializes readIdx at offset.\n */\nexport function sort_sorter_entries(sorter: VmSorter): void {\n const key_info = sorter.keyInfo;\n sorter.entries.sort((a: VmSorterEntry, b: VmSorterEntry) =>\n compare_sorter_keys(a.keys, b.keys, key_info),\n );\n sorter.readIdx = key_info.offset ?? 0;\n}\n\n/**\n * Copies a contiguous slice of row bytes from linear memory.\n */\nexport function copy_row_bytes(\n view: DataView,\n offset: number,\n length: number,\n): Uint8Array {\n const src = new Uint8Array(view.buffer, view.byteOffset + offset, length);\n const dest = new Uint8Array(length);\n dest.set(src);\n return dest;\n}\n\n/**\n * Inserts or replaces a row entry into the in-arena sorter.\n * Employs a Top-K bounded max-heap optimization when max_k > 0.\n */\nexport function sorter_insert_row(\n ctx: VmContext,\n sorter: VmSorter,\n keys: any[],\n cursor_row_offset: number,\n row_len: number,\n view: DataView,\n max_k: number,\n): VmStatus {\n // If Top-K heap capacity reached:\n if (max_k > 0 && sorter.entries.length >= max_k) {\n const cmp = compare_sorter_keys(\n keys,\n sorter.entries[0].keys,\n sorter.keyInfo,\n );\n if (cmp >= 0) {\n // Candidate is worse than or equal to the worst element in top-K: discard immediately\n return VmStatus.RUNNING;\n }\n\n // Candidate is better than worst element: replace root and sift down\n const old_entry = sorter.entries[0];\n const diff = row_len - old_entry.rowLen;\n if (diff > 0 && ctx.arenaOffset + diff > ctx.maxQueryMemory) {\n ctx.status = VmStatus.ARENA_EXHAUSTED;\n return VmStatus.ARENA_EXHAUSTED;\n }\n ctx.arenaOffset += diff;\n\n const row_data = copy_row_bytes(view, cursor_row_offset, row_len);\n old_entry.keys = keys;\n old_entry.rowOffset = cursor_row_offset;\n old_entry.rowLen = row_len;\n old_entry.rowData = row_data;\n heap_sift_down(sorter.entries, 0, max_k, sorter.keyInfo);\n return VmStatus.RUNNING;\n }\n\n // Regular insertion (or accumulating elements before reaching max_k)\n const entry_size = 16 + 16 * keys.length + row_len;\n if (ctx.arenaOffset + entry_size > ctx.maxQueryMemory) {\n ctx.status = VmStatus.ARENA_EXHAUSTED;\n return VmStatus.ARENA_EXHAUSTED;\n }\n ctx.arenaOffset += entry_size;\n\n const row_data = copy_row_bytes(view, cursor_row_offset, row_len);\n sorter.entries.push({\n keys,\n rowOffset: cursor_row_offset,\n rowLen: row_len,\n rowData: row_data,\n });\n\n // If top-K threshold just reached, heapify\n if (max_k > 0 && sorter.entries.length === max_k) {\n for (let h = Math.floor(max_k / 2) - 1; h >= 0; h--) {\n heap_sift_down(sorter.entries, h, max_k, sorter.keyInfo);\n }\n }\n\n return VmStatus.RUNNING;\n}\n\n/**\n * Serializes register values into a binary row based on the current query schema context.\n *\n * Responsibilities across the 3 branches:\n * 1. Explicit Output Projection (`ctx.outputColumns`):\n * Handles queries with transformed output schemas (e.g. GROUP BY aggregations,\n * computed expressions, or column aliases) defined in `ctx.outputColumns`.\n * 2. Physical Table Schema (`ctx.table.columns`):\n * Handles standard row scans where the number of emitted registers\n * matches the physical table schema in `ctx.table`.\n * 3. Dynamic Runtime Type Inference (Fallback):\n * Handles ad-hoc expressions, partial projections, or subqueries lacking\n * pre-compiled schema metadata, inferring data types (INT32, FLOAT64, INT64, BLOB, TEXT)\n * directly from register values.\n */\nexport function serialize_result_registers(\n ctx: VmContext,\n start_reg: number,\n num_cols: number,\n): Uint8Array {\n let cols: ColumnMeta[];\n const record: Record<string, any> = {};\n\n // Branch 1: Explicit Output Projection\n // Responsibility: GROUP BY aggregations, aliases, and custom projection schemas\n if (ctx.outputColumns && num_cols === ctx.outputColumns.length) {\n cols = ctx.outputColumns;\n for (let c = 0; c < num_cols; c++) {\n record[cols[c].name] = ctx.registers[start_reg + c];\n }\n }\n // Branch 2: Physical Table Schema\n // Responsibility: Standard full-table column emission matching physical table columns\n else if (ctx.table && num_cols === ctx.table.columns.length) {\n cols = ctx.table.columns;\n for (let c = 0; c < num_cols; c++) {\n record[cols[c].name] = ctx.registers[start_reg + c];\n }\n }\n // Branch 3: Dynamic Runtime Type Inference (Fallback)\n // Responsibility: Ad-hoc expressions, partial projections, or subqueries without pre-set metadata\n else {\n cols = [];\n for (let c = 0; c < num_cols; c++) {\n const val = ctx.registers[start_reg + c];\n const col_name = ctx.table?.columns[c]?.name ?? `col_${c}`;\n let col_type = DataType.TEXT;\n if (typeof val === \"number\") {\n col_type = Number.isInteger(val) ? DataType.INT32 : DataType.FLOAT64;\n } else if (typeof val === \"bigint\") {\n col_type = DataType.INT64;\n } else if (val instanceof Uint8Array) {\n col_type = DataType.BLOB;\n }\n cols.push({\n name: col_name,\n type: col_type,\n flags: ColumnFlag.NONE,\n colOffset: 0,\n });\n record[col_name] = val;\n }\n }\n\n return page_serialize_row(cols, record);\n}\n\n/**\n * Writes serialized row bytes into the 64KB Output Result Buffer.\n * Prepends a 2-byte uint16 length prefix. Yields BUFFER_FULL on overflow.\n */\nexport function emit_to_result_buffer(\n ctx: VmContext,\n view: DataView,\n row_bytes: Uint8Array,\n instr_pc: number,\n): VmStatus {\n const needed = 2 + row_bytes.byteLength;\n if (ctx.resultOffset + needed > RESULT_BUFFER_SIZE) {\n ctx.status = VmStatus.BUFFER_FULL;\n ctx.pc = instr_pc;\n return VmStatus.BUFFER_FULL;\n }\n\n const out_target = RESULT_BUFFER_OFFSET + ctx.resultOffset;\n view.setUint16(out_target, row_bytes.byteLength, true);\n const dest = new Uint8Array(\n view.buffer,\n view.byteOffset + out_target + 2,\n row_bytes.byteLength,\n );\n dest.set(row_bytes);\n\n ctx.resultOffset += needed;\n ctx.resultCount++;\n return VmStatus.RUNNING;\n}\n\n/**\n * Tests whether a column in the row is marked NULL in the null-bitmap.\n */\nexport function row_is_null(\n view: DataView,\n null_bitmap_offset: number,\n col_idx: number,\n): boolean {\n return (\n (view.getUint8(null_bitmap_offset + (col_idx >> 3)) &\n (1 << (col_idx & 7))) !==\n 0\n );\n}\n\n/**\n * Computes the byte offset of a fixed-width column within a row record,\n * or the start of the variable-length offset table if target_col_idx == column_count.\n */\nexport function compute_fixed_column_offset(\n view: DataView,\n null_bitmap_offset: number,\n null_bitmap_bytes: number,\n columns: ColumnMeta[],\n target_col_idx: number,\n): number {\n let col_offset = null_bitmap_offset + null_bitmap_bytes;\n for (let i = 0; i < target_col_idx; i++) {\n if (!row_is_null(view, null_bitmap_offset, i)) {\n const prev_col = columns[i];\n switch (prev_col.type) {\n case DataType.INT32:\n col_offset += 4;\n break;\n case DataType.INT64:\n case DataType.FLOAT64:\n col_offset += 8;\n break;\n case DataType.UUID:\n case DataType.ULID:\n col_offset += 16;\n break;\n }\n }\n }\n return col_offset;\n}\n","import {\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n SLOT_TO_PAGE_OFFSET,\n MAX_TOPK_HEAP_LIMIT,\n} from \"../../constants.ts\";\nimport { OpCode, VmStatus, DataType } from \"../../types/index.ts\";\nimport {\n page_get_cell_count,\n page_get_cell_offset,\n page_get_next_page_id,\n page_binary_search_index_leaf,\n} from \"./page.c.ts\";\nimport { buf_pool_get_resident_slot } from \"./buffer_pool.c.ts\";\nimport { UuidCodec, UlidCodec } from \"./codecs.c.ts\";\n\nimport {\n type VmCursor,\n type VmContext,\n type VmKeyInfo,\n type VmSorter,\n type VmSorterEntry,\n type VmAggBucket,\n createVmContext,\n resetVmContext,\n} from \"../../shared/index.ts\";\n\nimport {\n get_cursor,\n resolve_page_offset,\n compare_3vl,\n sql_like_match,\n fnv1a_32,\n group_keys_match,\n create_agg_buckets,\n sort_sorter_entries,\n sorter_insert_row,\n compare_registers_to_sorter_keys,\n serialize_result_registers,\n emit_to_result_buffer,\n row_is_null,\n compute_fixed_column_offset,\n} from \"./vm.helpers.c.ts\";\n\n// Re-export helpers, context functions, and types for public/core consumers\nexport * from \"./vm.helpers.c.ts\";\nexport { createVmContext, resetVmContext };\nexport type {\n VmCursor,\n VmContext,\n VmKeyInfo,\n VmSorter,\n VmSorterEntry,\n VmAggBucket,\n};\n\nconst text_decoder = new TextDecoder();\n\n/**\n * Synchronous Bytecode VM execution step loop.\n * Runs instructions until STATUS_DONE, STATUS_BUFFER_FULL, or an error.\n */\nexport function vm_step(\n ctx: VmContext,\n view: DataView,\n bytecode: Uint8Array,\n): VmStatus {\n const code_view = new DataView(\n bytecode.buffer,\n bytecode.byteOffset,\n bytecode.byteLength,\n );\n const code_len = bytecode.byteLength;\n\n const MAX_CYCLES = 10_000_000;\n let cycles = 0;\n\n const has_buffer_pool =\n view.byteLength >= SLOT_TO_PAGE_OFFSET + 4 &&\n view.getUint32(SLOT_TO_PAGE_OFFSET, true) > 0;\n\n while (ctx.pc < code_len) {\n if (++cycles > MAX_CYCLES) {\n ctx.status = VmStatus.TIMEOUT;\n return VmStatus.TIMEOUT;\n }\n\n const instr_pc = ctx.pc;\n const op = bytecode[ctx.pc];\n ctx.pc += 1;\n\n switch (op) {\n /**\n * OP_HALT (0x00)\n * Operands: none (0 bytes)\n * Halts VM execution successfully; sets status to STATUS_DONE.\n */\n case OpCode.OP_HALT: {\n ctx.arenaOffset = 0;\n ctx.status = VmStatus.DONE;\n return VmStatus.DONE;\n }\n\n /**\n * OP_OPEN_CURSOR (0x01)\n * Operands: [cursor_idx: uint8] [root_page_id: uint32] (5 bytes)\n * Binds cursor[cursor_idx] to a table or index root page ID.\n * Resets the cursor's cellIdx and rowOffset to 0.\n */\n case OpCode.OP_OPEN_CURSOR: {\n const cursor_idx = bytecode[ctx.pc];\n const root_page_id = code_view.getUint32(ctx.pc + 1, true);\n ctx.pc += 5;\n\n const cursor = get_cursor(ctx, cursor_idx);\n cursor.pageId = root_page_id;\n cursor.cellIdx = 0;\n cursor.rowOffset = 0;\n\n if (has_buffer_pool && root_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n root_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = root_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n cursor.slotIdx = slot;\n }\n break;\n }\n\n /**\n * OP_REWIND (0x02)\n * Operands: [cursor_idx: uint8] [jump_target: uint16] (3 bytes)\n * Positions cursor[cursor_idx] at the first cell (index 0) of root page.\n * If the table has 0 rows (cell_count == 0), branches to jump_target (EOF).\n */\n case OpCode.OP_REWIND: {\n const cursor_idx = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n\n if (has_buffer_pool && cursor.pageId > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n cursor.pageId,\n );\n if (slot < 0) {\n ctx.fault_page_id = cursor.pageId;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n cursor.slotIdx = slot;\n }\n\n const page_offset = resolve_page_offset(view, cursor.pageId);\n const cell_count = page_get_cell_count(view, page_offset);\n\n if (cell_count === 0) {\n ctx.pc = jump_target;\n } else {\n cursor.cellIdx = 0;\n const rel_cell_offset = page_get_cell_offset(view, page_offset, 0);\n cursor.rowOffset = page_offset + rel_cell_offset;\n }\n break;\n }\n\n /**\n * OP_NEXT_ROW (0x03)\n * Operands: [cursor_idx: uint8] [jump_target: uint16] (3 bytes)\n * Advances cursor[cursor_idx] to the next cell. If all cells on the\n * current page are exhausted, traverses next_page_id to the linked sibling\n * leaf page. Jumps to jump_target when EOF (no more pages) is reached.\n */\n case OpCode.OP_NEXT_ROW: {\n const cursor_idx = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const page_offset = resolve_page_offset(view, cursor.pageId);\n const cell_count = page_get_cell_count(view, page_offset);\n\n const next_cell_idx = cursor.cellIdx + 1;\n if (next_cell_idx < cell_count) {\n cursor.cellIdx = next_cell_idx;\n const rel_cell_offset = page_get_cell_offset(\n view,\n page_offset,\n cursor.cellIdx,\n );\n cursor.rowOffset = page_offset + rel_cell_offset;\n } else {\n // Check if there is a next page linked for this table\n const next_page_id = page_get_next_page_id(view, page_offset);\n if (next_page_id !== 0) {\n if (has_buffer_pool) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n next_page_id,\n );\n if (slot < 0) {\n // Page miss: leave cursor on current page and cell, rewind PC to re-evaluate after load\n ctx.fault_page_id = next_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n cursor.slotIdx = slot;\n }\n\n cursor.pageId = next_page_id;\n cursor.cellIdx = 0;\n const next_offset = resolve_page_offset(view, next_page_id);\n const next_count = page_get_cell_count(view, next_offset);\n if (next_count > 0) {\n const rel_cell_offset = page_get_cell_offset(\n view,\n next_offset,\n 0,\n );\n cursor.rowOffset = next_offset + rel_cell_offset;\n } else {\n ctx.pc = jump_target;\n }\n } else {\n // EOF reached\n ctx.pc = jump_target;\n }\n }\n break;\n }\n\n /**\n * OP_LAST (0x08)\n * Operands: [cursor_idx: uint8] [jump_target: uint16] (3 bytes)\n * Positions cursor at rightmost leaf cell for reverse scan.\n */\n case OpCode.OP_LAST: {\n const cursor_idx = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const page_offset = resolve_page_offset(view, cursor.pageId);\n const cell_count = page_get_cell_count(view, page_offset);\n\n if (cell_count === 0) {\n ctx.pc = jump_target;\n } else {\n cursor.cellIdx = cell_count - 1;\n const rel_cell_offset = page_get_cell_offset(\n view,\n page_offset,\n cursor.cellIdx,\n );\n cursor.rowOffset = page_offset + rel_cell_offset;\n }\n break;\n }\n\n /**\n * OP_PREV_ROW (0x09)\n * Operands: [cursor_idx: uint8] [jump_target: uint16] (3 bytes)\n * Decrements cell index; jumps on beginning of table (BOF).\n */\n case OpCode.OP_PREV_ROW: {\n const cursor_idx = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const page_offset = resolve_page_offset(view, cursor.pageId);\n\n if (cursor.cellIdx > 0) {\n cursor.cellIdx--;\n const rel_cell_offset = page_get_cell_offset(\n view,\n page_offset,\n cursor.cellIdx,\n );\n cursor.rowOffset = page_offset + rel_cell_offset;\n } else {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_COLUMN_INT (0x04)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [reg_idx: uint8] (3 bytes)\n * Extracts an INT32 or INT64 column value from the current row under cursor.\n */\n case OpCode.OP_COLUMN_INT: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const reg_idx = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n\n const cursor = get_cursor(ctx, cursor_idx);\n const table = (ctx.tables && ctx.tables[cursor_idx]) ?? ctx.table!;\n const col = table.columns[col_idx];\n const null_bitmap_bytes = Math.ceil(table.columns.length / 8);\n const null_bitmap_offset = cursor.rowOffset + 3;\n\n if (row_is_null(view, null_bitmap_offset, col_idx)) {\n ctx.registers[reg_idx] = null;\n break;\n }\n\n const col_offset = compute_fixed_column_offset(\n view,\n null_bitmap_offset,\n null_bitmap_bytes,\n table.columns,\n col_idx,\n );\n\n if (col.type === DataType.INT32) {\n ctx.registers[reg_idx] = view.getInt32(col_offset, true);\n } else if (col.type === DataType.INT64) {\n ctx.registers[reg_idx] = Number(view.getBigInt64(col_offset, true));\n }\n break;\n }\n\n /**\n * OP_COLUMN_FLOAT (0x05)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [reg_idx: uint8] (3 bytes)\n * Extracts a 64-bit IEEE 754 float column from the row under cursor.\n */\n case OpCode.OP_COLUMN_FLOAT: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const reg_idx = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n\n const cursor = get_cursor(ctx, cursor_idx);\n const table = (ctx.tables && ctx.tables[cursor_idx]) ?? ctx.table!;\n const null_bitmap_bytes = Math.ceil(table.columns.length / 8);\n const null_bitmap_offset = cursor.rowOffset + 3;\n\n if (row_is_null(view, null_bitmap_offset, col_idx)) {\n ctx.registers[reg_idx] = null;\n break;\n }\n\n const col_offset = compute_fixed_column_offset(\n view,\n null_bitmap_offset,\n null_bitmap_bytes,\n table.columns,\n col_idx,\n );\n\n ctx.registers[reg_idx] = view.getFloat64(col_offset, true);\n break;\n }\n\n /**\n * OP_COLUMN_TEXT (0x06)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [reg_idx: uint8] (3 bytes)\n * Extracts a variable-length UTF-8 string (or formatted UUID/ULID string)\n * from the row under cursor into register r[reg_idx].\n */\n case OpCode.OP_COLUMN_UUID:\n case OpCode.OP_COLUMN_ULID:\n case OpCode.OP_COLUMN_TEXT: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const reg_idx = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n\n const cursor = get_cursor(ctx, cursor_idx);\n const table = (ctx.tables && ctx.tables[cursor_idx]) ?? ctx.table!;\n const null_bitmap_bytes = Math.ceil(table.columns.length / 8);\n const null_bitmap_offset = cursor.rowOffset + 3;\n\n if (row_is_null(view, null_bitmap_offset, col_idx)) {\n ctx.registers[reg_idx] = null;\n break;\n }\n\n if (\n table.columns[col_idx].type === DataType.UUID ||\n table.columns[col_idx].type === DataType.ULID\n ) {\n const col_offset = compute_fixed_column_offset(\n view,\n null_bitmap_offset,\n null_bitmap_bytes,\n table.columns,\n col_idx,\n );\n\n const slice = new Uint8Array(\n view.buffer,\n view.byteOffset + col_offset,\n 16,\n );\n\n ctx.registers[reg_idx] =\n table.columns[col_idx].type === DataType.UUID\n ? UuidCodec.decode(slice, 0)\n : UlidCodec.decode(slice, 0);\n break;\n }\n\n // Find start of var-offset table\n const var_table_offset = compute_fixed_column_offset(\n view,\n null_bitmap_offset,\n null_bitmap_bytes,\n table.columns,\n table.columns.length,\n );\n\n let var_idx = 0;\n for (let i = 0; i < col_idx; i++) {\n const c = table.columns[i];\n if (c.type === DataType.TEXT || c.type === DataType.BLOB) {\n var_idx++;\n }\n }\n\n const entry_offset = var_table_offset + var_idx * 4;\n const rel_offset = view.getUint16(entry_offset, true);\n const len = view.getUint16(entry_offset + 2, true);\n\n if (len === 0) {\n ctx.registers[reg_idx] = \"\";\n } else {\n const text_bytes = new Uint8Array(\n view.buffer,\n cursor.rowOffset + rel_offset,\n len,\n );\n ctx.registers[reg_idx] = text_decoder.decode(text_bytes);\n }\n break;\n }\n\n /**\n * OP_COLUMN_BLOB (0x07)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [reg_idx: uint8] (3 bytes)\n * Extracts a variable-length binary BLOB column from the row under cursor.\n */\n case OpCode.OP_COLUMN_BLOB: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const reg_idx = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n\n const cursor = get_cursor(ctx, cursor_idx);\n const table = (ctx.tables && ctx.tables[cursor_idx]) ?? ctx.table!;\n const null_bitmap_bytes = Math.ceil(table.columns.length / 8);\n const null_bitmap_offset = cursor.rowOffset + 3;\n\n if (row_is_null(view, null_bitmap_offset, col_idx)) {\n ctx.registers[reg_idx] = null;\n break;\n }\n\n const var_table_offset = compute_fixed_column_offset(\n view,\n null_bitmap_offset,\n null_bitmap_bytes,\n table.columns,\n table.columns.length,\n );\n\n let var_idx = 0;\n for (let i = 0; i < col_idx; i++) {\n const c = table.columns[i];\n if (c.type === DataType.TEXT || c.type === DataType.BLOB) {\n var_idx++;\n }\n }\n\n const entry_offset = var_table_offset + var_idx * 4;\n const rel_offset = view.getUint16(entry_offset, true);\n const len = view.getUint16(entry_offset + 2, true);\n\n const blob_copy = new Uint8Array(len);\n blob_copy.set(\n new Uint8Array(view.buffer, cursor.rowOffset + rel_offset, len),\n );\n ctx.registers[reg_idx] = blob_copy;\n break;\n }\n\n /**\n * OP_OPEN_INDEX (0x0c)\n * Operands: [cursor_idx: uint8] [root_page_id: uint32] (5 bytes)\n * Binds cursor[cursor_idx] to an index root page ID.\n */\n case OpCode.OP_OPEN_INDEX: {\n const cursor_idx = bytecode[ctx.pc];\n const root_page_id = code_view.getUint32(ctx.pc + 1, true);\n ctx.pc += 5;\n\n const cursor = get_cursor(ctx, cursor_idx);\n cursor.pageId = root_page_id;\n cursor.rootPageId = root_page_id;\n cursor.cellIdx = 0;\n cursor.rowOffset = 0;\n\n if (has_buffer_pool && root_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n root_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = root_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n cursor.slotIdx = slot;\n }\n break;\n }\n\n /**\n * OP_INDEX_SEEK_EQ (0x0d)\n * Operands: [index_cursor: uint8] [data_cursor: uint8] [reg_key: uint8] [key_type: uint8] [jump_not_found: uint16] (6 bytes)\n * Performs binary search on index leaf for target key.\n * If found: positions data_cursor at matched rowid (data page + cell).\n * If not found: jumps to jump_not_found.\n */\n case OpCode.OP_INDEX_SEEK_EQ: {\n const index_cursor_idx = bytecode[ctx.pc];\n const data_cursor_idx = bytecode[ctx.pc + 1];\n const reg_key = bytecode[ctx.pc + 2];\n const key_type = bytecode[ctx.pc + 3] as DataType;\n const jump_not_found = code_view.getUint16(ctx.pc + 4, true);\n ctx.pc += 6;\n\n if (jump_not_found > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const key_val = ctx.registers[reg_key];\n if (key_val === null || key_val === undefined) {\n ctx.pc = jump_not_found;\n break;\n }\n\n const idx_cursor = get_cursor(ctx, index_cursor_idx);\n\n let curr_page_id = idx_cursor.rootPageId || idx_cursor.pageId;\n let found = false;\n let matched_rowid = 0n;\n\n while (curr_page_id !== 0) {\n if (has_buffer_pool && curr_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n curr_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = curr_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n idx_cursor.slotIdx = slot;\n }\n\n const page_offset = resolve_page_offset(view, curr_page_id);\n const search = page_binary_search_index_leaf(\n view,\n page_offset,\n key_type,\n key_val,\n );\n\n if (search.found) {\n found = true;\n idx_cursor.pageId = curr_page_id;\n idx_cursor.cellIdx = search.slot_idx;\n const cell_offset = page_get_cell_offset(\n view,\n page_offset,\n search.slot_idx,\n );\n const k_len = view.getUint16(page_offset + cell_offset, true);\n matched_rowid = view.getBigInt64(\n page_offset + cell_offset + 2 + k_len,\n true,\n );\n break;\n }\n\n curr_page_id = page_get_next_page_id(view, page_offset);\n }\n\n if (!found) {\n ctx.pc = jump_not_found;\n } else {\n const data_page_id = Number(matched_rowid >> 16n);\n const data_cell_idx = Number(matched_rowid & 0xffffn);\n\n if (has_buffer_pool && data_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n data_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = data_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n }\n\n const data_cursor = get_cursor(ctx, data_cursor_idx);\n data_cursor.pageId = data_page_id;\n data_cursor.cellIdx = data_cell_idx;\n const data_page_offset = resolve_page_offset(view, data_page_id);\n const rel_cell_offset = page_get_cell_offset(\n view,\n data_page_offset,\n data_cell_idx,\n );\n data_cursor.rowOffset = data_page_offset + rel_cell_offset;\n }\n break;\n }\n\n /**\n * OP_INDEX_SEEK_GE (0x0e)\n * Operands: [index_cursor: uint8] [data_cursor: uint8] [reg_key: uint8] [key_type: uint8] [jump_eof: uint16] (6 bytes)\n * Seeks index_cursor to the first entry >= key_val.\n * If found: positions data_cursor at the matched rowid.\n * If EOF / not found: jumps to jump_eof.\n */\n case OpCode.OP_INDEX_SEEK_GE: {\n const index_cursor_idx = bytecode[ctx.pc];\n const data_cursor_idx = bytecode[ctx.pc + 1];\n const reg_key = bytecode[ctx.pc + 2];\n const key_type = bytecode[ctx.pc + 3] as DataType;\n const jump_eof = code_view.getUint16(ctx.pc + 4, true);\n ctx.pc += 6;\n\n if (jump_eof > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const key_val = ctx.registers[reg_key];\n if (key_val === null || key_val === undefined) {\n ctx.pc = jump_eof;\n break;\n }\n\n const idx_cursor = get_cursor(ctx, index_cursor_idx);\n\n let curr_page_id = idx_cursor.rootPageId || idx_cursor.pageId;\n let found = false;\n let matched_rowid = 0n;\n\n while (curr_page_id !== 0) {\n if (has_buffer_pool && curr_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n curr_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = curr_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n idx_cursor.slotIdx = slot;\n }\n\n const page_offset = resolve_page_offset(view, curr_page_id);\n const cell_count = page_get_cell_count(view, page_offset);\n const search = page_binary_search_index_leaf(\n view,\n page_offset,\n key_type,\n key_val,\n );\n\n if (search.found || search.slot_idx < cell_count) {\n found = true;\n idx_cursor.pageId = curr_page_id;\n idx_cursor.cellIdx = search.slot_idx;\n const cell_offset = page_get_cell_offset(\n view,\n page_offset,\n search.slot_idx,\n );\n const k_len = view.getUint16(page_offset + cell_offset, true);\n matched_rowid = view.getBigInt64(\n page_offset + cell_offset + 2 + k_len,\n true,\n );\n break;\n }\n\n curr_page_id = page_get_next_page_id(view, page_offset);\n }\n\n if (!found) {\n ctx.pc = jump_eof;\n } else {\n const data_page_id = Number(matched_rowid >> 16n);\n const data_cell_idx = Number(matched_rowid & 0xffffn);\n\n if (has_buffer_pool && data_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n data_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = data_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n }\n\n const data_cursor = get_cursor(ctx, data_cursor_idx);\n data_cursor.pageId = data_page_id;\n data_cursor.cellIdx = data_cell_idx;\n const data_page_offset = resolve_page_offset(view, data_page_id);\n const rel_cell_offset = page_get_cell_offset(\n view,\n data_page_offset,\n data_cell_idx,\n );\n data_cursor.rowOffset = data_page_offset + rel_cell_offset;\n }\n break;\n }\n\n /**\n * OP_INDEX_NEXT (0x0f)\n * Operands: [index_cursor: uint8] [data_cursor: uint8] [jump_eof: uint16] (4 bytes)\n * Advances index_cursor to the next index cell and positions data_cursor.\n * If index exhausted (EOF), jumps to jump_eof.\n */\n case OpCode.OP_INDEX_NEXT: {\n const index_cursor_idx = bytecode[ctx.pc];\n const data_cursor_idx = bytecode[ctx.pc + 1];\n const jump_eof = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_eof > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const idx_cursor = get_cursor(ctx, index_cursor_idx);\n let curr_page_id = idx_cursor.pageId;\n let page_offset = resolve_page_offset(view, curr_page_id);\n const cell_count = page_get_cell_count(view, page_offset);\n\n let next_cell_idx = idx_cursor.cellIdx + 1;\n if (next_cell_idx >= cell_count) {\n curr_page_id = page_get_next_page_id(view, page_offset);\n if (curr_page_id === 0) {\n ctx.pc = jump_eof;\n break;\n }\n if (has_buffer_pool && curr_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n curr_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = curr_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n idx_cursor.slotIdx = slot;\n }\n page_offset = resolve_page_offset(view, curr_page_id);\n next_cell_idx = 0;\n idx_cursor.pageId = curr_page_id;\n idx_cursor.cellIdx = -1;\n }\n\n const cell_offset = page_get_cell_offset(\n view,\n page_offset,\n next_cell_idx,\n );\n const k_len = view.getUint16(page_offset + cell_offset, true);\n const matched_rowid = view.getBigInt64(\n page_offset + cell_offset + 2 + k_len,\n true,\n );\n\n const data_page_id = Number(matched_rowid >> 16n);\n const data_cell_idx = Number(matched_rowid & 0xffffn);\n\n if (has_buffer_pool && data_page_id > 0) {\n const slot = buf_pool_get_resident_slot(\n view,\n PAGE_TO_SLOT_OFFSET,\n DEFAULT_PAGE_TO_SLOT_BUCKETS,\n data_page_id,\n );\n if (slot < 0) {\n ctx.fault_page_id = data_page_id;\n ctx.status = VmStatus.PAGE_FAULT;\n ctx.pc = instr_pc;\n return VmStatus.PAGE_FAULT;\n }\n }\n\n idx_cursor.pageId = curr_page_id;\n idx_cursor.cellIdx = next_cell_idx;\n\n const data_cursor = get_cursor(ctx, data_cursor_idx);\n data_cursor.pageId = data_page_id;\n data_cursor.cellIdx = data_cell_idx;\n const data_page_offset = resolve_page_offset(view, data_page_id);\n const rel_cell_offset = page_get_cell_offset(\n view,\n data_page_offset,\n data_cell_idx,\n );\n data_cursor.rowOffset = data_page_offset + rel_cell_offset;\n break;\n }\n\n /**\n * OP_IS_NULL (0x10)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [jump_target: uint16] (4 bytes)\n * Evaluates SQL \"col IS NULL\". Tests the row's Null-Bitmap at col_idx.\n */\n case OpCode.OP_IS_NULL: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const null_bitmap_offset = cursor.rowOffset + 3;\n const is_null = row_is_null(view, null_bitmap_offset, col_idx);\n\n if (is_null) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_IS_NOT_NULL (0x11)\n * Operands: [cursor_idx: uint8] [col_idx: uint8] [jump_target: uint16] (4 bytes)\n * Evaluates SQL \"col IS NOT NULL\". Tests the row's Null-Bitmap at col_idx.\n */\n case OpCode.OP_IS_NOT_NULL: {\n const cursor_idx = bytecode[ctx.pc];\n const col_idx = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const null_bitmap_offset = cursor.rowOffset + 3;\n const is_null = row_is_null(view, null_bitmap_offset, col_idx);\n\n if (!is_null) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_EQ (0x12)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) equality check: r[reg_a] == r[reg_b].\n */\n case OpCode.OP_EQ: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result === 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_NE (0x13)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) inequality check: r[reg_a] !== r[reg_b].\n */\n case OpCode.OP_NE: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result !== 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_GT (0x14)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) greater-than comparison: r[reg_a] > r[reg_b].\n */\n case OpCode.OP_GT: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result > 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_GE (0x15)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) greater-than-or-equal comparison: r[reg_a] >= r[reg_b].\n */\n case OpCode.OP_GE: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result >= 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_LT (0x16)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) less-than comparison: r[reg_a] < r[reg_b].\n */\n case OpCode.OP_LT: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result < 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_LE (0x17)\n * Operands: [reg_a: uint8] [reg_b: uint8] [jump_target: uint16] (4 bytes)\n * Three-Valued Logic (3VL) less-than-or-equal comparison: r[reg_a] <= r[reg_b].\n */\n case OpCode.OP_LE: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const cmp = compare_3vl(ctx.registers[reg_a], ctx.registers[reg_b]);\n if (!cmp.is_unknown && cmp.result <= 0) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_JUMP (0x18)\n * Operands: [jump_target: uint16] (2 bytes)\n * Unconditional jump. Sets the program counter ctx.pc directly to jump_target.\n */\n case OpCode.OP_JUMP: {\n const jump_target = code_view.getUint16(ctx.pc, true);\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n ctx.pc = jump_target;\n break;\n }\n\n /**\n * OP_STR_LIKE (0x19)\n * Operands: [reg_str: uint8] [reg_pat: uint8] [jump_target: uint16] (4 bytes)\n * 3VL SQL LIKE: jumps to jump_target if r[reg_str] matches r[reg_pat].\n */\n case OpCode.OP_STR_LIKE: {\n const reg_str = bytecode[ctx.pc];\n const reg_pat = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n const val_str = ctx.registers[reg_str];\n const val_pat = ctx.registers[reg_pat];\n if (val_str === null || val_pat === null) {\n break; // 3VL UNKNOWN: do not jump\n }\n if (sql_like_match(String(val_str), String(val_pat))) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_STR_NOT_LIKE (0x1A)\n * Operands: [reg_str: uint8] [reg_pat: uint8] [jump_target: uint16] (4 bytes)\n * 3VL SQL NOT LIKE: jumps to jump_target if r[reg_str] does NOT match r[reg_pat].\n */\n case OpCode.OP_STR_NOT_LIKE: {\n const reg_str = bytecode[ctx.pc];\n const reg_pat = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n const val_str = ctx.registers[reg_str];\n const val_pat = ctx.registers[reg_pat];\n if (val_str === null || val_pat === null) {\n break; // 3VL UNKNOWN: do not jump\n }\n if (!sql_like_match(String(val_str), String(val_pat))) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_STR_CONTAINS (0x1B)\n * Operands: [reg_str: uint8] [reg_sub: uint8] [jump_target: uint16] (4 bytes)\n * 3VL Substring search: jumps to jump_target if r[reg_str] contains r[reg_sub].\n */\n case OpCode.OP_STR_CONTAINS: {\n const reg_str = bytecode[ctx.pc];\n const reg_sub = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n const val_str = ctx.registers[reg_str];\n const val_sub = ctx.registers[reg_sub];\n if (val_str === null || val_sub === null) {\n break; // 3VL UNKNOWN: do not jump\n }\n if (String(val_str).includes(String(val_sub))) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_STR_STARTS_WITH (0x1C)\n * Operands: [reg_str: uint8] [reg_pfx: uint8] [jump_target: uint16] (4 bytes)\n * 3VL Prefix check: jumps to jump_target if r[reg_str] starts with r[reg_pfx].\n */\n case OpCode.OP_STR_STARTS_WITH: {\n const reg_str = bytecode[ctx.pc];\n const reg_pfx = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n const val_str = ctx.registers[reg_str];\n const val_pfx = ctx.registers[reg_pfx];\n if (val_str === null || val_pfx === null) {\n break; // 3VL UNKNOWN: do not jump\n }\n if (String(val_str).startsWith(String(val_pfx))) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_STR_ENDS_WITH (0x1D)\n * Operands: [reg_str: uint8] [reg_sfx: uint8] [jump_target: uint16] (4 bytes)\n * 3VL Suffix check: jumps to jump_target if r[reg_str] ends with r[reg_sfx].\n */\n case OpCode.OP_STR_ENDS_WITH: {\n const reg_str = bytecode[ctx.pc];\n const reg_sfx = bytecode[ctx.pc + 1];\n const jump_target = code_view.getUint16(ctx.pc + 2, true);\n ctx.pc += 4;\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n const val_str = ctx.registers[reg_str];\n const val_sfx = ctx.registers[reg_sfx];\n if (val_str === null || val_sfx === null) {\n break; // 3VL UNKNOWN: do not jump\n }\n if (String(val_str).endsWith(String(val_sfx))) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_IN (0x1f)\n * Operands: [reg_val: uint8] [set_idx: uint16] [jump_target: uint16] (5 bytes)\n * Checks whether r[reg_val] exists in ctx.inSets[set_idx].\n * If r[reg_val] is null or undefined, does not jump (3VL FALSE/UNKNOWN).\n * If matched, jumps to jump_target.\n */\n case OpCode.OP_IN: {\n const reg_val = bytecode[ctx.pc];\n const set_idx = code_view.getUint16(ctx.pc + 1, true);\n const jump_target = code_view.getUint16(ctx.pc + 3, true);\n ctx.pc += 5;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const val = ctx.registers[reg_val];\n if (val === null || val === undefined) {\n break;\n }\n\n const set = ctx.inSets?.[set_idx];\n if (set) {\n if (\n set.has(val) ||\n (typeof val === \"number\" &&\n Number.isSafeInteger(val) &&\n set.has(BigInt(val))) ||\n (typeof val === \"bigint\" && set.has(Number(val)))\n ) {\n ctx.pc = jump_target;\n }\n }\n break;\n }\n\n /**\n * OP_LOAD_INT (0x20)\n * Operands: [reg_idx: uint8] [val: int32] (5 bytes)\n * Loads a literal signed 32-bit integer constant into register r[reg_idx].\n */\n case OpCode.OP_LOAD_INT: {\n const reg_idx = bytecode[ctx.pc];\n const val = code_view.getInt32(ctx.pc + 1, true);\n ctx.pc += 5;\n ctx.registers[reg_idx] = val;\n break;\n }\n\n /**\n * OP_LOAD_FLOAT (0x21)\n * Operands: [reg_idx: uint8] [val: float64] (9 bytes)\n * Loads a literal 64-bit IEEE 754 float constant into register r[reg_idx].\n */\n case OpCode.OP_LOAD_FLOAT: {\n const reg_idx = bytecode[ctx.pc];\n const val = code_view.getFloat64(ctx.pc + 1, true);\n ctx.pc += 9;\n ctx.registers[reg_idx] = val;\n break;\n }\n\n /**\n * OP_LOAD_TEXT (0x22)\n * Operands: [reg_idx: uint8] [len: uint16] [utf8_bytes: len bytes]\n * Loads a literal UTF-8 string of length len into register r[reg_idx].\n */\n case OpCode.OP_LOAD_TEXT: {\n const reg_idx = bytecode[ctx.pc];\n const len = code_view.getUint16(ctx.pc + 1, true);\n const text_bytes = new Uint8Array(\n bytecode.buffer,\n bytecode.byteOffset + ctx.pc + 3,\n len,\n );\n ctx.registers[reg_idx] = text_decoder.decode(text_bytes);\n ctx.pc += 3 + len;\n break;\n }\n\n /**\n * OP_LOAD_BLOB (0x1e)\n * Operands: [reg_idx: uint8] [len: uint16] [blob_bytes: len bytes]\n * Loads a raw byte array into register r[reg_idx].\n */\n case OpCode.OP_LOAD_BLOB: {\n const reg_idx = bytecode[ctx.pc];\n const len = code_view.getUint16(ctx.pc + 1, true);\n const blob_bytes = new Uint8Array(len);\n blob_bytes.set(\n new Uint8Array(\n bytecode.buffer,\n bytecode.byteOffset + ctx.pc + 3,\n len,\n ),\n );\n ctx.registers[reg_idx] = blob_bytes;\n ctx.pc += 3 + len;\n break;\n }\n\n /**\n * OP_LOAD_NULL (0x23)\n * Operands: [reg_idx: uint8] (1 byte)\n * Sets register r[reg_idx] to null (type = 0).\n */\n case OpCode.OP_LOAD_NULL: {\n const reg_idx = bytecode[ctx.pc];\n ctx.pc += 1;\n ctx.registers[reg_idx] = null;\n break;\n }\n\n /**\n * OP_EMIT_ROW (0x24)\n * Operands: [cursor_idx: uint8] (1 byte)\n * Streams the current serialized row focused under cursor[cursor_idx]\n * into the 64KB Output Result Buffer at RESULT_BUFFER_OFFSET + resultOffset.\n * Prepends a 2-byte record length: [uint16 len] [row_bytes].\n * If remaining buffer space is insufficient, yields STATUS_BUFFER_FULL.\n */\n case OpCode.OP_EMIT_ROW: {\n const cursor_idx = bytecode[ctx.pc];\n ctx.pc += 1;\n\n const cursor = get_cursor(ctx, cursor_idx);\n const total_row_length = view.getUint16(cursor.rowOffset + 1, true);\n const row_bytes = new Uint8Array(\n view.buffer,\n view.byteOffset + cursor.rowOffset,\n total_row_length,\n );\n\n const emit_status = emit_to_result_buffer(\n ctx,\n view,\n row_bytes,\n instr_pc,\n );\n if (emit_status !== VmStatus.RUNNING) {\n return emit_status;\n }\n break;\n }\n\n /**\n * OP_OFFSET (0x26)\n * Operands: [offset_reg: uint8] [jump_target: uint16] (3 bytes)\n * If r[offset_reg] > 0, decrements r[offset_reg] and branches to jump_target (skipping row emission).\n */\n case OpCode.OP_OFFSET: {\n const offset_reg = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const offset_val = Number(ctx.registers[offset_reg] ?? 0);\n if (offset_val > 0) {\n ctx.registers[offset_reg] = offset_val - 1;\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_LIMIT (0x27)\n * Operands: [limit_reg: uint8] [jump_target: uint16] (3 bytes)\n * If r[limit_reg] <= 1, sets r[limit_reg] to 0 and branches to jump_target (early HALT).\n * Otherwise decrements r[limit_reg] and falls through.\n */\n case OpCode.OP_LIMIT: {\n const limit_reg = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const limit_val = Number(ctx.registers[limit_reg] ?? 0);\n if (limit_val <= 1) {\n ctx.registers[limit_reg] = 0;\n ctx.pc = jump_target;\n } else {\n ctx.registers[limit_reg] = limit_val - 1;\n }\n break;\n }\n /**\n * OP_CALL_UDF (0x28)\n * Operands: [udf_id: uint16] [start_arg_reg: uint8] [num_args: uint8] [dest_reg: uint8] (5 bytes)\n * Synchronously invokes registered Host UDF callback.\n */\n case OpCode.OP_CALL_UDF: {\n const udf_id = code_view.getUint16(ctx.pc, true);\n const start_arg_reg = bytecode[ctx.pc + 2];\n const num_args = bytecode[ctx.pc + 3];\n const dest_reg = bytecode[ctx.pc + 4];\n ctx.pc += 5;\n\n const fn = ctx.udfs?.[udf_id];\n if (!fn) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const args: any[] = [];\n for (let a = 0; a < num_args; a++) {\n args.push(ctx.registers[start_arg_reg + a]);\n }\n\n try {\n const res = fn(...args);\n ctx.registers[dest_reg] = res !== undefined ? res : null;\n } catch {\n ctx.status = VmStatus.ERROR;\n return VmStatus.ERROR;\n }\n break;\n }\n\n /**\n * OP_STR_LOWER (0x29)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Converts string in r[src_reg] to lowercase and stores into r[dest_reg].\n */\n case OpCode.OP_STR_LOWER: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null ? String(val).toLowerCase() : null;\n break;\n }\n\n /**\n * OP_STR_UPPER (0x2A)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Converts string in r[src_reg] to uppercase and stores into r[dest_reg].\n */\n case OpCode.OP_STR_UPPER: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null ? String(val).toUpperCase() : null;\n break;\n }\n\n /**\n * OP_STR_LENGTH (0x2B)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Computes UTF-8 / character length of string in r[src_reg] and stores into r[dest_reg] (int32).\n */\n case OpCode.OP_STR_LENGTH: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] = val !== null ? String(val).length : null;\n break;\n }\n\n /**\n * OP_STR_SUBSTR (0x2C)\n * Operands: [src_reg: uint8] [start_reg: uint8] [len_reg: uint8] [dest_reg: uint8] (4 bytes)\n * 1-indexed SQL SUBSTR. Extracts substring from r[src_reg] starting at r[start_reg] for r[len_reg] characters.\n */\n case OpCode.OP_STR_SUBSTR: {\n const src_reg = bytecode[ctx.pc];\n const start_reg = bytecode[ctx.pc + 1];\n const len_reg = bytecode[ctx.pc + 2];\n const dest_reg = bytecode[ctx.pc + 3];\n ctx.pc += 4;\n const val = ctx.registers[src_reg];\n const start = ctx.registers[start_reg];\n const len = ctx.registers[len_reg];\n if (val === null || start === null) {\n ctx.registers[dest_reg] = null;\n break;\n }\n const str = String(val);\n const s_idx = Math.max(0, Number(start) - 1);\n if (len === null) {\n ctx.registers[dest_reg] = str.slice(s_idx);\n } else {\n const l = Math.max(0, Number(len));\n ctx.registers[dest_reg] = str.slice(s_idx, s_idx + l);\n }\n break;\n }\n\n /**\n * OP_STR_TRIM (0x2D)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Strips leading and trailing whitespace from string in r[src_reg] into r[dest_reg].\n */\n case OpCode.OP_STR_TRIM: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null && val !== undefined ? String(val).trim() : null;\n break;\n }\n\n /**\n * OP_MATH_ABS (0x2E)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Computes absolute numeric value |r[src_reg]| into r[dest_reg].\n */\n case OpCode.OP_MATH_ABS: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null && val !== undefined ? Math.abs(Number(val)) : null;\n break;\n }\n\n /**\n * OP_MATH_ROUND (0x2F)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Rounds float in r[src_reg] to nearest integer into r[dest_reg].\n */\n case OpCode.OP_MATH_ROUND: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null && val !== undefined ? Math.round(Number(val)) : null;\n break;\n }\n\n /**\n * OP_RESULT_ROW (0x25)\n * Operands: [start_reg: uint8] [num_cols: uint8] (2 bytes)\n * Serializes num_cols registers (start_reg .. start_reg + num_cols - 1)\n * into a binary row in the 64KB Result Buffer.\n * If remaining space is insufficient, yields STATUS_BUFFER_FULL.\n */\n case OpCode.OP_RESULT_ROW: {\n const start_reg = bytecode[ctx.pc];\n const num_cols = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n\n const serialized = serialize_result_registers(ctx, start_reg, num_cols);\n const emit_status = emit_to_result_buffer(\n ctx,\n view,\n serialized,\n instr_pc,\n );\n if (emit_status !== VmStatus.RUNNING) {\n return emit_status;\n }\n break;\n }\n\n /**\n * OP_SORTER_OPEN (0x30)\n * Operands: [sorter_id: uint8] [key_info_idx: uint8] (2 bytes)\n * Initializes sorter in Transient Query Arena with KeyInfo descriptor.\n */\n case OpCode.OP_SORTER_OPEN: {\n const sorter_id = bytecode[ctx.pc];\n const key_info_idx = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n\n const key_info = ctx.keyInfos[key_info_idx] ?? {\n numKeys: 1,\n directions: [0],\n nullOrders: [0],\n };\n\n const requested_k =\n key_info.limit !== undefined && key_info.limit > 0\n ? (key_info.offset ?? 0) + key_info.limit\n : 0;\n const max_k =\n requested_k > 0 && requested_k <= MAX_TOPK_HEAP_LIMIT\n ? requested_k\n : 0;\n\n ctx.sorters[sorter_id] = {\n keyInfo: key_info,\n entries: [],\n readIdx: 0,\n isSorted: false,\n maxK: max_k,\n };\n break;\n }\n\n /**\n * OP_SORTER_INSERT (0x31)\n * Operands: [sorter_id: uint8] [start_reg: uint8] [num_keys: uint8] [cursor_idx: uint8] (4 bytes)\n * Packs extracted key registers and row reference into SorterEntry inside the Transient Query Arena.\n * If arena allocation exceeds maxQueryMemory, yields STATUS_ERR_ARENA_EXHAUSTED.\n */\n case OpCode.OP_SORTER_INSERT: {\n const sorter_id = bytecode[ctx.pc];\n const start_reg = bytecode[ctx.pc + 1];\n const num_keys = bytecode[ctx.pc + 2];\n const cursor_idx = bytecode[ctx.pc + 3];\n ctx.pc += 4;\n\n const sorter = ctx.sorters[sorter_id];\n if (!sorter) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const max_k = sorter.maxK ?? 0;\n\n // Fast-path Top-K heap rejection:\n // When heap is full (sorter.entries.length >= max_k), candidate rows worse than\n // the worst element (heap root) are discarded immediately with 0 allocations.\n if (max_k > 0 && sorter.entries.length >= max_k) {\n if (num_keys === 1) {\n const cand = ctx.registers[start_reg];\n const root = sorter.entries[0].keys[0];\n const dir = sorter.keyInfo.directions[0] ?? 0;\n if (typeof cand === \"number\" && typeof root === \"number\") {\n if (dir === 0 ? cand >= root : cand <= root) {\n break;\n }\n } else if (typeof cand === \"string\" && typeof root === \"string\") {\n if (dir === 0 ? cand >= root : cand <= root) {\n break;\n }\n } else {\n const cmp = compare_registers_to_sorter_keys(\n ctx.registers,\n start_reg,\n sorter.entries[0].keys,\n sorter.keyInfo,\n );\n if (cmp >= 0) break;\n }\n } else {\n const cmp = compare_registers_to_sorter_keys(\n ctx.registers,\n start_reg,\n sorter.entries[0].keys,\n sorter.keyInfo,\n );\n if (cmp >= 0) break;\n }\n }\n\n const cursor = get_cursor(ctx, cursor_idx);\n const row_len = view.getUint16(cursor.rowOffset + 1, true);\n\n const keys: any[] = new Array(num_keys);\n for (let k = 0; k < num_keys; k++) {\n keys[k] = ctx.registers[start_reg + k];\n }\n\n const insert_status = sorter_insert_row(\n ctx,\n sorter,\n keys,\n cursor.rowOffset,\n row_len,\n view,\n max_k,\n );\n if (insert_status !== VmStatus.RUNNING) {\n return insert_status;\n }\n break;\n }\n\n /**\n * OP_SORTER_SORT (0x32)\n * Operands: [sorter_id: uint8] (1 byte)\n * Executes in-place Introsort on SorterEntry[] using multi-column collation.\n */\n case OpCode.OP_SORTER_SORT: {\n const sorter_id = bytecode[ctx.pc];\n ctx.pc += 1;\n\n const sorter = ctx.sorters[sorter_id];\n if (!sorter) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n sort_sorter_entries(sorter);\n sorter.isSorted = true;\n break;\n }\n\n /**\n * OP_SORTER_NEXT (0x33)\n * Operands: [sorter_id: uint8] [jump_target: uint16] (3 bytes)\n * Yields next sorted row into 64KB Result Buffer; jumps to jump_target until all entries emitted.\n * If Result Buffer is full, yields STATUS_BUFFER_FULL. Falls through on EOF.\n */\n case OpCode.OP_SORTER_NEXT: {\n const sorter_id = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const sorter = ctx.sorters[sorter_id];\n if (!sorter) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const max_read =\n sorter.keyInfo.limit !== undefined\n ? (sorter.keyInfo.offset ?? 0) + sorter.keyInfo.limit\n : sorter.entries.length;\n\n if (sorter.readIdx >= Math.min(sorter.entries.length, max_read)) {\n // EOF: all requested sorted entries emitted, fall through\n break;\n }\n\n const entry = sorter.entries[sorter.readIdx];\n const row_bytes =\n entry.rowData ??\n new Uint8Array(\n view.buffer,\n view.byteOffset + entry.rowOffset,\n entry.rowLen,\n );\n\n const emit_status = emit_to_result_buffer(\n ctx,\n view,\n row_bytes,\n instr_pc,\n );\n if (emit_status !== VmStatus.RUNNING) {\n return emit_status;\n }\n\n sorter.readIdx++;\n ctx.pc = jump_target;\n break;\n }\n\n /**\n * OP_MATH_FLOOR (0x34)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Computes mathematical floor ⌊r[src_reg]⌋ into r[dest_reg].\n */\n case OpCode.OP_MATH_FLOOR: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null && val !== undefined ? Math.floor(Number(val)) : null;\n break;\n }\n\n /**\n * OP_MATH_CEIL (0x35)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Computes mathematical ceiling ⌈r[src_reg]⌉ into r[dest_reg].\n */\n case OpCode.OP_MATH_CEIL: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n const val = ctx.registers[src_reg];\n ctx.registers[dest_reg] =\n val !== null && val !== undefined ? Math.ceil(Number(val)) : null;\n break;\n }\n\n /**\n * OP_ADD (0x36)\n * Operands: [regA: uint8] [regB: uint8] [dest_reg: uint8] (3 bytes)\n * 3VL addition: r[dest_reg] = r[regA] + r[regB].\n */\n case OpCode.OP_ADD: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n const val_a = ctx.registers[reg_a];\n const val_b = ctx.registers[reg_b];\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n ctx.registers[dest_reg] = null;\n } else {\n ctx.registers[dest_reg] = Number(val_a) + Number(val_b);\n }\n break;\n }\n\n /**\n * OP_SUB (0x37)\n * Operands: [regA: uint8] [regB: uint8] [dest_reg: uint8] (3 bytes)\n * 3VL subtraction: r[dest_reg] = r[regA] - r[regB].\n */\n case OpCode.OP_SUB: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n const val_a = ctx.registers[reg_a];\n const val_b = ctx.registers[reg_b];\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n ctx.registers[dest_reg] = null;\n } else {\n ctx.registers[dest_reg] = Number(val_a) - Number(val_b);\n }\n break;\n }\n\n /**\n * OP_MUL (0x38)\n * Operands: [regA: uint8] [regB: uint8] [dest_reg: uint8] (3 bytes)\n * 3VL multiplication: r[dest_reg] = r[regA] * r[regB].\n */\n case OpCode.OP_MUL: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n const val_a = ctx.registers[reg_a];\n const val_b = ctx.registers[reg_b];\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n ctx.registers[dest_reg] = null;\n } else {\n ctx.registers[dest_reg] = Number(val_a) * Number(val_b);\n }\n break;\n }\n\n /**\n * OP_DIV (0x39)\n * Operands: [regA: uint8] [regB: uint8] [dest_reg: uint8] (3 bytes)\n * 3VL division: r[dest_reg] = r[regA] / r[regB] (null on divide by zero).\n */\n case OpCode.OP_DIV: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n const val_a = ctx.registers[reg_a];\n const val_b = ctx.registers[reg_b];\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n ctx.registers[dest_reg] = null;\n } else {\n const denom = Number(val_b);\n ctx.registers[dest_reg] = denom === 0 ? null : Number(val_a) / denom;\n }\n break;\n }\n\n /**\n * OP_MOD (0x3A)\n * Operands: [regA: uint8] [regB: uint8] [dest_reg: uint8] (3 bytes)\n * 3VL modulo: r[dest_reg] = r[regA] % r[regB] (null on divide by zero).\n */\n case OpCode.OP_MOD: {\n const reg_a = bytecode[ctx.pc];\n const reg_b = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n const val_a = ctx.registers[reg_a];\n const val_b = ctx.registers[reg_b];\n if (\n val_a === null ||\n val_a === undefined ||\n val_b === null ||\n val_b === undefined\n ) {\n ctx.registers[dest_reg] = null;\n } else {\n const denom = Number(val_b);\n ctx.registers[dest_reg] = denom === 0 ? null : Number(val_a) % denom;\n }\n break;\n }\n\n /**\n * OP_STR_CONCAT (0x3D)\n * Operands: [start_reg: uint8] [num_regs: uint8] [dest_reg: uint8] (3 bytes)\n * Concatenates registers r[start_reg ... start_reg + num_regs - 1] into r[dest_reg].\n */\n case OpCode.OP_STR_CONCAT: {\n const start_reg = bytecode[ctx.pc];\n const num_regs = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n let res = \"\";\n let has_val = false;\n for (let i = 0; i < num_regs; i++) {\n const v = ctx.registers[start_reg + i];\n if (v !== null && v !== undefined) {\n has_val = true;\n res += String(v);\n }\n }\n ctx.registers[dest_reg] = has_val ? res : null;\n break;\n }\n\n /**\n * OP_COALESCE (0x3E)\n * Operands: [start_reg: uint8] [num_regs: uint8] [dest_reg: uint8] (3 bytes)\n * Scans registers r[start_reg ... start_reg + num_regs - 1], stores first non-null into r[dest_reg].\n */\n case OpCode.OP_COALESCE: {\n const start_reg = bytecode[ctx.pc];\n const num_regs = bytecode[ctx.pc + 1];\n const dest_reg = bytecode[ctx.pc + 2];\n ctx.pc += 3;\n let first_non_null: any = null;\n for (let i = 0; i < num_regs; i++) {\n const v = ctx.registers[start_reg + i];\n if (v !== null && v !== undefined) {\n first_non_null = v;\n break;\n }\n }\n ctx.registers[dest_reg] = first_non_null;\n break;\n }\n\n /**\n * OP_COPY (0x3F)\n * Operands: [src_reg: uint8] [dest_reg: uint8] (2 bytes)\n * Copies r[src_reg] to r[dest_reg].\n */\n case OpCode.OP_COPY: {\n const src_reg = bytecode[ctx.pc];\n const dest_reg = bytecode[ctx.pc + 1];\n ctx.pc += 2;\n ctx.registers[dest_reg] = ctx.registers[src_reg];\n break;\n }\n\n /**\n * OP_AGG_INIT (0x40)\n * Operands: [agg_id: uint8] [start_key_reg: uint8] [num_keys: uint8] [mode: uint8] (4 bytes)\n * Initializes Hash Table in arena (0x00) or Stream Aggregation (0x01).\n */\n case OpCode.OP_AGG_INIT: {\n const agg_id = bytecode[ctx.pc];\n const start_key_reg = bytecode[ctx.pc + 1];\n const num_keys = bytecode[ctx.pc + 2];\n const mode = bytecode[ctx.pc + 3];\n ctx.pc += 4;\n\n if (mode === 0) {\n const initial_capacity = 1024;\n const alloc_size = initial_capacity * 40; // 40.96 KB\n if (ctx.arenaOffset + alloc_size > ctx.maxQueryMemory) {\n ctx.status = VmStatus.ARENA_EXHAUSTED;\n return VmStatus.ARENA_EXHAUSTED;\n }\n ctx.arenaOffset += alloc_size;\n\n const buckets: VmAggBucket[] = create_agg_buckets(initial_capacity);\n\n if (num_keys === 0) {\n const h = fnv1a_32([]);\n const slot = h % initial_capacity;\n buckets[slot].hash = h;\n buckets[slot].keys = [];\n buckets[slot].count = 0;\n buckets[slot].sum = 0;\n buckets[slot].min_val = Infinity;\n buckets[slot].max_val = -Infinity;\n buckets[slot].has_val = false;\n }\n\n ctx.aggregators[agg_id] = {\n mode: 0,\n startKeyReg: start_key_reg,\n numKeys: num_keys,\n capacity: initial_capacity,\n occupiedCount: num_keys === 0 ? 1 : 0,\n readIdx: 0,\n buckets,\n };\n } else {\n ctx.aggregators[agg_id] = {\n mode: 1,\n startKeyReg: start_key_reg,\n numKeys: num_keys,\n capacity: 1,\n occupiedCount: 0,\n readIdx: 0,\n buckets: [],\n };\n }\n break;\n }\n\n /**\n * OP_AGG_STEP (0x41)\n * Operands: [agg_id: uint8] [start_key_reg: uint8] [num_keys: uint8] [val_reg: uint8] [func_id: uint8] (5 bytes)\n * Updates AggBucket accumulators (0: COUNT, 1: SUM, 2: AVG, 3: MIN, 4: MAX).\n */\n case OpCode.OP_AGG_STEP: {\n const agg_id = bytecode[ctx.pc];\n const start_key_reg = bytecode[ctx.pc + 1];\n const num_keys = bytecode[ctx.pc + 2];\n const val_reg = bytecode[ctx.pc + 3];\n const func_id = bytecode[ctx.pc + 4];\n ctx.pc += 5;\n\n const agg = ctx.aggregators[agg_id];\n if (!agg) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const keys: any[] = [];\n for (let k = 0; k < num_keys; k++) {\n keys.push(ctx.registers[start_key_reg + k]);\n }\n const val = val_reg === 255 ? null : ctx.registers[val_reg];\n\n if (agg.mode === 0) {\n const hash = fnv1a_32(keys);\n const slot = hash % agg.capacity;\n let target_bucket: VmAggBucket | null = null;\n\n for (let probe = 0; probe < agg.capacity; probe++) {\n const idx = (slot + probe) % agg.capacity;\n const b = agg.buckets[idx];\n if (b.hash === 0) {\n b.hash = hash;\n b.keys = keys.slice();\n b.count = 0;\n b.sum = 0;\n b.min_val = Infinity;\n b.max_val = -Infinity;\n b.has_val = false;\n agg.occupiedCount++;\n target_bucket = b;\n break;\n } else if (b.hash === hash && group_keys_match(b.keys, keys)) {\n target_bucket = b;\n break;\n }\n }\n\n if (!target_bucket) {\n ctx.status = VmStatus.ARENA_EXHAUSTED;\n return VmStatus.ARENA_EXHAUSTED;\n }\n\n // Accumulator updates\n if (func_id === 0) {\n if (val_reg === 255 || (val !== null && val !== undefined)) {\n target_bucket.count++;\n }\n } else if (func_id === 1 || func_id === 2) {\n if (val !== null && val !== undefined) {\n target_bucket.sum += Number(val);\n target_bucket.has_val = true;\n }\n } else if (func_id === 3) {\n if (val !== null && val !== undefined) {\n const num = Number(val);\n if (!target_bucket.has_val || num < target_bucket.min_val) {\n target_bucket.min_val = num;\n }\n target_bucket.has_val = true;\n }\n } else if (func_id === 4) {\n if (val !== null && val !== undefined) {\n const num = Number(val);\n if (!target_bucket.has_val || num > target_bucket.max_val) {\n target_bucket.max_val = num;\n }\n target_bucket.has_val = true;\n }\n }\n\n // Dynamic Doubling at 70% Load Factor\n if (agg.occupiedCount > 0.7 * agg.capacity) {\n const old_capacity = agg.capacity;\n const new_capacity = old_capacity * 2;\n const add_size = new_capacity * 40;\n if (ctx.arenaOffset + add_size > ctx.maxQueryMemory) {\n ctx.status = VmStatus.ARENA_EXHAUSTED;\n return VmStatus.ARENA_EXHAUSTED;\n }\n ctx.arenaOffset += add_size;\n\n const old_buckets = agg.buckets;\n const new_buckets: VmAggBucket[] = create_agg_buckets(new_capacity);\n\n for (let b_idx = 0; b_idx < old_buckets.length; b_idx++) {\n const old_b = old_buckets[b_idx];\n if (old_b.hash !== 0) {\n const s = old_b.hash % new_capacity;\n for (let p = 0; p < new_capacity; p++) {\n const pos = (s + p) % new_capacity;\n if (new_buckets[pos].hash === 0) {\n new_buckets[pos] = old_b;\n break;\n }\n }\n }\n }\n\n agg.capacity = new_capacity;\n agg.buckets = new_buckets;\n }\n }\n break;\n }\n\n /**\n * OP_AGG_NEXT (0x42)\n * Operands: [agg_id: uint8] [out_key_reg: uint8] [out_acc_reg: uint8] [jump_target: uint16] (5 bytes)\n * Iterates next group bucket into registers; jumps to jump_target. Falls through on EOF.\n */\n case OpCode.OP_AGG_NEXT: {\n const agg_id = bytecode[ctx.pc];\n const out_key_reg = bytecode[ctx.pc + 1];\n const out_acc_reg = bytecode[ctx.pc + 2];\n const jump_target = code_view.getUint16(ctx.pc + 3, true);\n ctx.pc += 5;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const agg = ctx.aggregators[agg_id];\n if (!agg) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n while (\n agg.readIdx < agg.buckets.length &&\n agg.buckets[agg.readIdx].hash === 0\n ) {\n agg.readIdx++;\n }\n\n if (agg.readIdx >= agg.buckets.length) {\n // All buckets processed, fall through\n break;\n }\n\n const bucket = agg.buckets[agg.readIdx++];\n\n for (let k = 0; k < bucket.keys.length; k++) {\n ctx.registers[out_key_reg + k] = bucket.keys[k];\n }\n\n ctx.registers[out_acc_reg] = bucket.sum;\n ctx.registers[out_acc_reg + 1] = bucket.count;\n ctx.registers[out_acc_reg + 2] = bucket.has_val ? bucket.min_val : null;\n ctx.registers[out_acc_reg + 3] = bucket.has_val ? bucket.max_val : null;\n\n ctx.pc = jump_target;\n break;\n }\n\n /**\n * OP_AGG_FINAL (0x43)\n * Operands: [sum_reg: uint8] [count_reg: uint8] [out_reg: uint8] [func_id: uint8] (4 bytes)\n * Finalizes aggregate expression: (0: COUNT, 1: SUM, 2: AVG, 3: MIN, 4: MAX).\n */\n case OpCode.OP_AGG_FINAL: {\n const sum_reg = bytecode[ctx.pc];\n const count_reg = bytecode[ctx.pc + 1];\n const out_reg = bytecode[ctx.pc + 2];\n const func_id = bytecode[ctx.pc + 3];\n ctx.pc += 4;\n\n const sum = ctx.registers[sum_reg];\n const count = Number(ctx.registers[count_reg] ?? 0);\n\n if (func_id === 0) {\n ctx.registers[out_reg] = count;\n } else if (func_id === 1) {\n ctx.registers[out_reg] = count > 0 ? Number(sum) : null;\n } else if (func_id === 2) {\n ctx.registers[out_reg] = count > 0 ? Number(sum) / count : null;\n } else if (func_id === 3 || func_id === 4) {\n ctx.registers[out_reg] = ctx.registers[sum_reg];\n }\n break;\n }\n\n /**\n * OP_REG_IS_NULL (0x48)\n * Operands: [reg: uint8] [jump_target: uint16] (3 bytes)\n * Jumps to jump_target if r[reg] is NULL or undefined.\n */\n case OpCode.OP_REG_IS_NULL: {\n const reg = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const val = ctx.registers[reg];\n if (val === null || val === undefined) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n /**\n * OP_REG_IS_NOT_NULL (0x49)\n * Operands: [reg: uint8] [jump_target: uint16] (3 bytes)\n * Jumps to jump_target if r[reg] is not NULL and not undefined.\n */\n case OpCode.OP_REG_IS_NOT_NULL: {\n const reg = bytecode[ctx.pc];\n const jump_target = code_view.getUint16(ctx.pc + 1, true);\n ctx.pc += 3;\n\n if (jump_target > code_len) {\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n\n const val = ctx.registers[reg];\n if (val !== null && val !== undefined) {\n ctx.pc = jump_target;\n }\n break;\n }\n\n default:\n ctx.status = VmStatus.INVALID_BYTECODE;\n return VmStatus.INVALID_BYTECODE;\n }\n }\n\n ctx.status = VmStatus.DONE;\n return VmStatus.DONE;\n}\n","import {\n PAGE_SIZE,\n FILE_HEADER_SIZE,\n MASTER_TABLE_OFFSET,\n MAX_TABLES_PAGE1,\n TABLE_DESCRIPTOR_SIZE,\n INDEX_CATALOG_OFFSET,\n INDEX_DESCRIPTOR_SIZE,\n CATALOG_PAGE_HEADER_SIZE,\n COLUMN_META_SIZE,\n MAX_COLUMNS_PER_CATALOG_PAGE,\n MAX_COLUMNS_PER_TABLE,\n MAX_NAME_LENGTH,\n HEADER_OFFSET_MAGIC,\n HEADER_OFFSET_PAGE_SIZE,\n HEADER_OFFSET_FILE_FORMAT_VERSION,\n HEADER_OFFSET_MIN_READ_VERSION,\n HEADER_OFFSET_TOTAL_PAGES,\n HEADER_OFFSET_FREE_PAGE_HEAD,\n HEADER_OFFSET_SCHEMA_VERSION,\n HEADER_OFFSET_CHANGE_COUNTER,\n HEADER_OFFSET_PAGE_CHECKSUM,\n HEADER_OFFSET_NEXT_CATALOG_PAGE_ID,\n HEADER_OFFSET_NEXT_INDEX_CATALOG_PAGE_ID,\n HEADER_OFFSET_RESERVED,\n CURRENT_ENGINE_VERSION,\n CURRENT_MIN_READ_VERSION,\n PAGE_TYPE_CATALOG_PAGE,\n} from \"../../constants.ts\";\n\nimport {\n DataType,\n ColumnFlag,\n TableFlag,\n IndexFlag,\n ColumnDefinition,\n ColumnMeta,\n TableDescriptor,\n IndexDescriptor,\n CatalogPageHeader,\n TableMeta,\n TableAlreadyExistsError,\n TableNotFoundError,\n TooManyColumnsError,\n TooManyTablesError,\n UnsupportedFormatVersionError,\n InvalidDatabaseError,\n CorruptPageError,\n} from \"../../types/index.ts\";\nimport { IPageProvider } from \"../../shared/index.ts\";\nimport { page_init_index_leaf } from \"./page.c.ts\";\nimport type { u16, u32, i32, const_u8_ptr } from \"../types.ts\";\nimport { memset, strlen } from \"../../shared/c_runtime.ts\";\n\nimport {\n computePageChecksum,\n} from \"../../host/storage/crc32.ts\";\n\nconst text_decoder = new TextDecoder();\n\nexport const MAGIC_BYTES = new Uint8Array([0x57, 0x45, 0x42, 0x44, 0x42, 0x00]); // \"WEBDB\\0\"\n\n// ============================================================================\n// 0. CRC32 IEEE 802.3 Checksum Primitives\n// ============================================================================\n\nconst CRC_TABLE = new Uint32Array(256);\nlet crc_table_initialized = 0;\n\n/**\n * @internal_c\n */\nfunction init_crc_table(): void {\n if (crc_table_initialized) return;\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let k = 0; k < 8; k++) {\n c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);\n }\n CRC_TABLE[i] = c >>> 0;\n }\n crc_table_initialized = 1;\n}\n\n/**\n * @export_c\n */\nexport function compute_crc32(data: const_u8_ptr, length: u32): u32 {\n init_crc_table();\n let crc = 0xffffffff;\n const bytes = data as Uint8Array;\n for (let i = 0; i < length; i++) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * @export_c\n */\nexport function compute_page_checksum(view: DataView, page_offset: u32 = 0): u32 {\n init_crc_table();\n let crc = 0xffffffff;\n for (let i = 0; i < PAGE_SIZE; i++) {\n const byte = (i >= 12 && i <= 15) ? 0 : view.getUint8(page_offset + i);\n crc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * @export_c\n */\nexport function compute_page1_checksum(view: DataView, page1_offset: u32 = 0): u32 {\n init_crc_table();\n let crc = 0xffffffff;\n for (let i = 0; i < PAGE_SIZE; i++) {\n const byte = (i >= 28 && i <= 31) ? 0 : view.getUint8(page1_offset + i);\n crc = CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n// ============================================================================\n// 1. Page 1 File Header Operations\n// ============================================================================\n\n/**\n * @export_c\n * Initializes the Page 1 database file header and clears the catalog area.\n */\nexport function catalog_init_page1(\n view: DataView,\n page1_offset: u32 = 0,\n): void {\n // Clear Page 1\n memset(view, page1_offset, 0, PAGE_SIZE);\n\n // Magic bytes: \"WEBDB\\0\"\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 0, 0x57);\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 1, 0x45);\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 2, 0x42);\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 3, 0x44);\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 4, 0x42);\n view.setUint8(page1_offset + HEADER_OFFSET_MAGIC + 5, 0x00);\n\n // 2. Page size (4096)\n view.setUint16(page1_offset + HEADER_OFFSET_PAGE_SIZE, PAGE_SIZE, true);\n\n // 3. File format version\n view.setUint16(\n page1_offset + HEADER_OFFSET_FILE_FORMAT_VERSION,\n CURRENT_ENGINE_VERSION,\n true,\n );\n\n // 4. Min read version\n view.setUint16(\n page1_offset + HEADER_OFFSET_MIN_READ_VERSION,\n CURRENT_MIN_READ_VERSION,\n true,\n );\n\n // 5. Total pages (Page 1 is allocated)\n view.setUint32(page1_offset + HEADER_OFFSET_TOTAL_PAGES, 1, true);\n\n // 6. Free page head pointer (0 = empty list)\n view.setUint32(page1_offset + HEADER_OFFSET_FREE_PAGE_HEAD, 0, true);\n\n // 7. Schema version (1)\n view.setUint32(page1_offset + HEADER_OFFSET_SCHEMA_VERSION, 1, true);\n\n // 8. Change counter (0)\n view.setUint32(page1_offset + HEADER_OFFSET_CHANGE_COUNTER, 0, true);\n\n // 9. Page checksum (calculated on flush)\n view.setUint32(page1_offset + HEADER_OFFSET_PAGE_CHECKSUM, 0, true);\n\n // 10. Chained catalog pointers\n view.setUint32(page1_offset + HEADER_OFFSET_NEXT_CATALOG_PAGE_ID, 0, true);\n view.setUint32(page1_offset + HEADER_OFFSET_NEXT_INDEX_CATALOG_PAGE_ID, 0, true);\n\n // Set initial valid checksum for Page 1\n const chk = compute_page1_checksum(view, page1_offset);\n view.setUint32(page1_offset + HEADER_OFFSET_PAGE_CHECKSUM, chk, true);\n}\n\n/**\n * Reads and validates the Page 1 database file header.\n */\nexport function catalog_read_page1_header(\n view: DataView,\n verify_checksum: boolean = false,\n) {\n // 1. Validate magic bytes\n for (let i = 0; i < MAGIC_BYTES.length; i++) {\n if (view.getUint8(HEADER_OFFSET_MAGIC + i) !== MAGIC_BYTES[i]) {\n throw new InvalidDatabaseError(\n \"Invalid database file: magic bytes mismatch\",\n );\n }\n }\n\n const page_size = view.getUint16(HEADER_OFFSET_PAGE_SIZE, true);\n const file_format_version = view.getUint16(\n HEADER_OFFSET_FILE_FORMAT_VERSION,\n true,\n );\n const min_read_version = view.getUint16(HEADER_OFFSET_MIN_READ_VERSION, true);\n const total_pages = view.getUint32(HEADER_OFFSET_TOTAL_PAGES, true);\n const free_page_head = view.getUint32(HEADER_OFFSET_FREE_PAGE_HEAD, true);\n const schema_version = view.getUint32(HEADER_OFFSET_SCHEMA_VERSION, true);\n const change_counter = view.getUint32(HEADER_OFFSET_CHANGE_COUNTER, true);\n const stored_checksum = view.getUint32(HEADER_OFFSET_PAGE_CHECKSUM, true);\n\n // 2. Fail-fast version handshake\n if (min_read_version > CURRENT_ENGINE_VERSION) {\n throw new UnsupportedFormatVersionError(\n `Database file format requires engine version >= ${min_read_version}, but running engine is version ${CURRENT_ENGINE_VERSION}`,\n );\n }\n\n // 3. Optional checksum verification on load\n if (verify_checksum && stored_checksum !== 0) {\n const computed = compute_page1_checksum(view, 0);\n if (computed !== stored_checksum) {\n throw new CorruptPageError(1, stored_checksum, computed);\n }\n }\n\n return {\n pageSize: page_size,\n fileFormatVersion: file_format_version,\n minReadVersion: min_read_version,\n totalPages: total_pages,\n freePageHead: free_page_head,\n schemaVersion: schema_version,\n changeCounter: change_counter,\n storedChecksum: stored_checksum,\n };\n}\n\n/**\n * @export_c\n */\nexport function catalog_get_total_pages(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n return view.getUint32(page1_offset + HEADER_OFFSET_TOTAL_PAGES, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_set_total_pages(\n view: DataView,\n page1_offset: u32,\n count?: u32,\n): void {\n if (count === undefined) {\n count = page1_offset;\n page1_offset = 0;\n }\n view.setUint32(page1_offset + HEADER_OFFSET_TOTAL_PAGES, count, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_get_free_page_head(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n return view.getUint32(page1_offset + HEADER_OFFSET_FREE_PAGE_HEAD, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_set_free_page_head(\n view: DataView,\n page1_offset: u32,\n page_id?: u32,\n): void {\n if (page_id === undefined) {\n page_id = page1_offset;\n page1_offset = 0;\n }\n view.setUint32(page1_offset + HEADER_OFFSET_FREE_PAGE_HEAD, page_id, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_get_schema_version(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n return view.getUint32(page1_offset + HEADER_OFFSET_SCHEMA_VERSION, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_increment_schema_version(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n const v = catalog_get_schema_version(view, page1_offset) + 1;\n view.setUint32(page1_offset + HEADER_OFFSET_SCHEMA_VERSION, v, true);\n return v;\n}\n\n/**\n * @export_c\n */\nexport function catalog_get_change_counter(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n return view.getUint32(page1_offset + HEADER_OFFSET_CHANGE_COUNTER, true);\n}\n\n/**\n * @export_c\n */\nexport function catalog_increment_change_counter(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n const c = catalog_get_change_counter(view, page1_offset) + 1;\n view.setUint32(page1_offset + HEADER_OFFSET_CHANGE_COUNTER, c, true);\n return c;\n}\n\n/**\n * @export_c\n */\nexport function catalog_update_page1_checksum(\n view: DataView,\n page1_offset: u32 = 0,\n): u32 {\n view.setUint32(page1_offset + HEADER_OFFSET_PAGE_CHECKSUM, 0, true);\n const chk = compute_page1_checksum(view, page1_offset);\n view.setUint32(page1_offset + HEADER_OFFSET_PAGE_CHECKSUM, chk, true);\n return chk;\n}\n\n// ============================================================================\n// 2. Fixed String Helper Functions\n// ============================================================================\n\n/**\n * @export_c\n */\nexport function catalog_write_fixed_string(\n view: DataView,\n offset: u32,\n str: string,\n max_len: u32,\n): void {\n let i = 0;\n for (; i < max_len && i < strlen(str); i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n for (; i < max_len; i++) {\n view.setUint8(offset + i, 0);\n }\n}\n\n/**\n * Reads a fixed-length string from the catalog.\n */\nexport function catalog_read_fixed_string(\n view: DataView,\n offset: number,\n max_len: number,\n): string {\n const bytes: number[] = [];\n for (let i = 0; i < max_len; i++) {\n const b = view.getUint8(offset + i);\n if (b === 0) break;\n bytes.push(b);\n }\n return text_decoder.decode(new Uint8Array(bytes));\n}\n\n/**\n * Parses SQL type string to DataType enum.\n */\nexport function catalog_parse_data_type(type_str: string): DataType {\n switch (type_str.toUpperCase()) {\n case \"INT32\":\n return DataType.INT32;\n case \"INT64\":\n return DataType.INT64;\n case \"FLOAT64\":\n return DataType.FLOAT64;\n case \"TEXT\":\n return DataType.TEXT;\n case \"BLOB\":\n return DataType.BLOB;\n case \"UUID\":\n return DataType.UUID;\n case \"ULID\":\n return DataType.ULID;\n default:\n throw new Error(`Unsupported column data type: \"${type_str}\"`);\n }\n}\n\n// ============================================================================\n// 3. Table Descriptor & Master Table Accessors (Page 1)\n// ============================================================================\n\n/**\n * Reads a TableDescriptor from Page 1 by slot index (0..15).\n */\nexport function catalog_read_table_descriptor(\n view: DataView,\n slot_idx: number,\n): TableDescriptor | null {\n const offset = MASTER_TABLE_OFFSET + slot_idx * TABLE_DESCRIPTOR_SIZE;\n const table_id = view.getUint16(offset + 0, true);\n if (table_id === 0) return null;\n\n const column_count = view.getUint16(offset + 2, true);\n const root_page_id = view.getUint32(offset + 4, true);\n const col_catalog_page_id = view.getUint32(offset + 8, true);\n const name = catalog_read_fixed_string(view, offset + 12, MAX_NAME_LENGTH);\n const flags = view.getUint32(offset + 76, true);\n const row_count_estimate = view.getUint32(offset + 80, true);\n const auto_inc_next = view.getBigUint64(offset + 84, true);\n\n return {\n tableId: table_id,\n columnCount: column_count,\n rootPageId: root_page_id,\n colCatalogPageId: col_catalog_page_id,\n name,\n flags,\n rowCountEstimate: row_count_estimate,\n autoIncNext: auto_inc_next,\n };\n}\n\n/**\n * Writes a TableDescriptor into Page 1 at the specified slot index (0..15).\n */\nexport function catalog_write_table_descriptor(\n view: DataView,\n slot_idx: number,\n desc: TableDescriptor,\n): void {\n const offset = MASTER_TABLE_OFFSET + slot_idx * TABLE_DESCRIPTOR_SIZE;\n view.setUint16(offset + 0, desc.tableId, true);\n view.setUint16(offset + 2, desc.columnCount, true);\n view.setUint32(offset + 4, desc.rootPageId, true);\n view.setUint32(offset + 8, desc.colCatalogPageId, true);\n catalog_write_fixed_string(view, offset + 12, desc.name, MAX_NAME_LENGTH);\n view.setUint32(offset + 76, desc.flags, true);\n view.setUint32(offset + 80, desc.rowCountEstimate, true);\n view.setBigUint64(offset + 84, desc.autoIncNext, true);\n // Clear reserved 36 bytes (92..127)\n const uint8 = new Uint8Array(view.buffer, view.byteOffset);\n uint8.fill(0, offset + 92, offset + TABLE_DESCRIPTOR_SIZE);\n}\n\n/**\n * Finds a TableDescriptor by name in Page 1, or null if not found.\n */\nexport function catalog_find_table_by_name(\n view: DataView,\n table_name: string,\n): TableDescriptor | null {\n const slot = catalog_find_table_slot(view, table_name);\n return slot !== -1 ? catalog_read_table_descriptor(view, slot) : null;\n}\n\n/**\n * Finds the slot index of an existing table by name, or -1 if not found.\n */\nexport function catalog_find_table_slot(\n view: DataView,\n table_name: string,\n): number {\n for (let i = 0; i < MAX_TABLES_PAGE1; i++) {\n const desc = catalog_read_table_descriptor(view, i);\n if (\n desc &&\n (desc.flags & TableFlag.ACTIVE) !== 0 &&\n desc.name === table_name\n ) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * @export_c\n * Finds the first free slot index in Page 1's TableDescriptor array.\n */\nexport function catalog_find_free_table_slot(\n view: DataView,\n page1_offset: u32 = 0,\n): i32 {\n for (let i = 0; i < MAX_TABLES_PAGE1; i++) {\n const offset = page1_offset + MASTER_TABLE_OFFSET + i * TABLE_DESCRIPTOR_SIZE;\n const table_id = view.getUint16(offset, true);\n if (table_id === 0) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Lists all active tables defined on Page 1.\n */\nexport function catalog_list_table_descriptors(\n view: DataView,\n): TableDescriptor[] {\n const tables: TableDescriptor[] = [];\n for (let i = 0; i < MAX_TABLES_PAGE1; i++) {\n const desc = catalog_read_table_descriptor(view, i);\n if (desc && (desc.flags & TableFlag.ACTIVE) !== 0) {\n tables.push(desc);\n }\n }\n return tables;\n}\n\n// ============================================================================\n// 4. Index Descriptor Accessors (Page 1: bytes 2148..3171)\n// ============================================================================\n\n/**\n * Reads an IndexDescriptor from Page 1 by slot index.\n */\nexport function catalog_read_index_descriptor(\n view: DataView,\n slot_idx: number,\n): IndexDescriptor | null {\n const offset = INDEX_CATALOG_OFFSET + slot_idx * INDEX_DESCRIPTOR_SIZE;\n const index_id = view.getUint16(offset + 0, true);\n\n if (index_id === 0) return null;\n\n const table_id = view.getUint16(offset + 2, true);\n const root_page_id = view.getUint32(offset + 4, true);\n const column_count = view.getUint8(offset + 8);\n const flags = view.getUint8(offset + 9);\n\n const column_indices: number[] = [];\n\n for (let i = 0; i < 8; i++) {\n column_indices.push(view.getUint16(offset + 10 + i * 2, true));\n }\n\n const col_directions: number[] = [];\n\n for (let i = 0; i < 8; i++) {\n col_directions.push(view.getUint8(offset + 26 + i));\n }\n\n const name = catalog_read_fixed_string(view, offset + 34, MAX_NAME_LENGTH);\n\n return {\n indexId: index_id,\n tableId: table_id,\n rootPageId: root_page_id,\n columnCount: column_count,\n flags,\n columnIndices: column_indices,\n colDirections: col_directions,\n name,\n };\n}\n\n/**\n * Writes an IndexDescriptor into Page 1 at the specified slot index.\n */\nexport function catalog_write_index_descriptor(\n view: DataView,\n slot_idx: number,\n desc: IndexDescriptor,\n): void {\n const offset = INDEX_CATALOG_OFFSET + slot_idx * INDEX_DESCRIPTOR_SIZE;\n\n view.setUint16(offset + 0, desc.indexId, true);\n view.setUint16(offset + 2, desc.tableId, true);\n view.setUint32(offset + 4, desc.rootPageId, true);\n view.setUint8(offset + 8, desc.columnCount);\n view.setUint8(offset + 9, desc.flags);\n\n for (let i = 0; i < 8; i++) {\n view.setUint16(offset + 10 + i * 2, desc.columnIndices[i] ?? 0, true);\n }\n\n for (let i = 0; i < 8; i++) {\n view.setUint8(offset + 26 + i, desc.colDirections[i] ?? 0);\n }\n\n catalog_write_fixed_string(view, offset + 34, desc.name, MAX_NAME_LENGTH);\n\n const uint8 = new Uint8Array(view.buffer, view.byteOffset);\n uint8.fill(0, offset + 98, offset + INDEX_DESCRIPTOR_SIZE);\n}\n\nexport const MAX_INDEXES_PAGE1 = 8;\n\n/**\n * @export_c\n */\nexport function catalog_find_free_index_slot(\n view: DataView,\n page1_offset: u32 = 0,\n): i32 {\n for (let i = 0; i < MAX_INDEXES_PAGE1; i++) {\n const offset = page1_offset + INDEX_CATALOG_OFFSET + i * INDEX_DESCRIPTOR_SIZE;\n const index_id = view.getUint16(offset + 0, true);\n if (index_id === 0) return i;\n }\n return -1;\n}\n\n/**\n * Finds an IndexDescriptor by name in Page 1.\n */\nexport function catalog_find_index_by_name(\n view: DataView,\n name: string,\n): { slotIdx: number; desc: IndexDescriptor } | null {\n const target = name.toLowerCase();\n for (let i = 0; i < MAX_INDEXES_PAGE1; i++) {\n const desc = catalog_read_index_descriptor(view, i);\n if (desc && desc.name.toLowerCase() === target) {\n return { slotIdx: i, desc };\n }\n }\n return null;\n}\n\n/**\n * Lists all index descriptors for a table.\n */\nexport function catalog_list_table_indexes(\n view: DataView,\n table_id: number,\n): IndexDescriptor[] {\n const indexes: IndexDescriptor[] = [];\n for (let i = 0; i < MAX_INDEXES_PAGE1; i++) {\n const desc = catalog_read_index_descriptor(view, i);\n if (desc && desc.tableId === table_id) {\n indexes.push(desc);\n }\n }\n return indexes;\n}\n\n/**\n * @export_c\n */\nexport function catalog_delete_index_descriptor(\n view: DataView,\n page1_offset: u32,\n slot_idx?: u32,\n): i32 {\n if (slot_idx === undefined) {\n slot_idx = page1_offset;\n page1_offset = 0;\n }\n if (slot_idx >= MAX_INDEXES_PAGE1) return -1;\n const offset = page1_offset + INDEX_CATALOG_OFFSET + slot_idx * INDEX_DESCRIPTOR_SIZE;\n memset(view, offset, 0, INDEX_DESCRIPTOR_SIZE);\n return 0;\n}\n\n/**\n * @export_c\n */\nexport function catalog_delete_table_descriptor(\n view: DataView,\n page1_offset: u32,\n slot_idx?: u32,\n): i32 {\n if (slot_idx === undefined) {\n slot_idx = page1_offset;\n page1_offset = 0;\n }\n if (slot_idx >= MAX_TABLES_PAGE1) return -1;\n const offset = page1_offset + MASTER_TABLE_OFFSET + slot_idx * TABLE_DESCRIPTOR_SIZE;\n memset(view, offset, 0, TABLE_DESCRIPTOR_SIZE);\n return 0;\n}\n\n// ============================================================================\n// 5. Dedicated Column Catalog Pages (page_type = 0x0C)\n// ============================================================================\n\n/**\n * @export_c\n * Initializes a 4KB dedicated column catalog page.\n */\nexport function catalog_init_page(\n view: DataView,\n page_offset: u32,\n table_id: u16,\n start_col_index: u16,\n next_col_catalog_page_id: u32 = 0,\n): void {\n memset(view, page_offset, 0, PAGE_SIZE);\n view.setUint8(page_offset + 0, PAGE_TYPE_CATALOG_PAGE);\n view.setUint8(page_offset + 1, 0); // flags\n view.setUint16(page_offset + 2, 0, true); // col_count_in_page = 0\n view.setUint16(page_offset + 4, table_id, true);\n view.setUint16(page_offset + 6, start_col_index, true);\n view.setUint32(page_offset + 8, next_col_catalog_page_id, true);\n view.setUint32(page_offset + 12, 0, true); // checksum\n}\n\n/**\n * Reads the catalog page header.\n */\nexport function catalog_read_page_header(\n view: DataView,\n page_offset: number,\n): CatalogPageHeader {\n return {\n pageType: view.getUint8(page_offset + 0),\n flags: view.getUint8(page_offset + 1),\n colCountInPage: view.getUint16(page_offset + 2, true),\n tableId: view.getUint16(page_offset + 4, true),\n startColIndex: view.getUint16(page_offset + 6, true),\n nextColCatalogPageId: view.getUint32(page_offset + 8, true),\n pageChecksum: view.getUint32(page_offset + 12, true),\n };\n}\n\n/**\n * @export_c\n */\nexport function catalog_write_page_header(\n view: DataView,\n page_offset: u32,\n col_count_in_page: u16,\n table_id: u16,\n start_col_index: u16,\n next_col_catalog_page_id: u32,\n): void {\n view.setUint8(page_offset + 0, PAGE_TYPE_CATALOG_PAGE);\n view.setUint8(page_offset + 1, 0);\n view.setUint16(page_offset + 2, col_count_in_page, true);\n view.setUint16(page_offset + 4, table_id, true);\n view.setUint16(page_offset + 6, start_col_index, true);\n view.setUint32(page_offset + 8, next_col_catalog_page_id, true);\n}\n\n/**\n * Writes a ColumnMeta entry (72 bytes) into a catalog page at inPageSlot (0..55).\n */\nexport function catalog_write_column_meta(\n view: DataView,\n page_offset: number,\n in_page_slot: number,\n meta: ColumnMeta,\n): void {\n if (in_page_slot < 0 || in_page_slot >= MAX_COLUMNS_PER_CATALOG_PAGE) {\n throw new Error(`Invalid catalog in-page slot ${in_page_slot}`);\n }\n\n const offset =\n page_offset + CATALOG_PAGE_HEADER_SIZE + in_page_slot * COLUMN_META_SIZE;\n view.setUint8(offset + 0, meta.type);\n view.setUint8(offset + 1, meta.flags);\n view.setUint16(offset + 2, meta.colOffset, true);\n catalog_write_fixed_string(view, offset + 4, meta.name, MAX_NAME_LENGTH);\n // Clear _reserved[4] at 68..71\n view.setUint32(offset + 68, 0, true);\n}\n\n/**\n * Reads a ColumnMeta entry (72 bytes) from a catalog page at inPageSlot (0..55).\n */\nexport function catalog_read_column_meta(\n view: DataView,\n page_offset: number,\n in_page_slot: number,\n): ColumnMeta {\n const offset =\n page_offset + CATALOG_PAGE_HEADER_SIZE + in_page_slot * COLUMN_META_SIZE;\n const type = view.getUint8(offset + 0) as DataType;\n const flags = view.getUint8(offset + 1);\n const col_offset = view.getUint16(offset + 2, true);\n const name = catalog_read_fixed_string(view, offset + 4, MAX_NAME_LENGTH);\n\n return { type, flags, colOffset: col_offset, name };\n}\n\n/**\n * Calculates cross-page column mapping:\n * page_chain_idx = floor(col_idx / 56)\n * col_idx_in_page = col_idx % 56\n */\nexport function catalog_map_column_location(col_idx: number): {\n pageChainIdx: number;\n colIdxInPage: number;\n} {\n return {\n pageChainIdx: Math.floor(col_idx / MAX_COLUMNS_PER_CATALOG_PAGE),\n colIdxInPage: col_idx % MAX_COLUMNS_PER_CATALOG_PAGE,\n };\n}\n\n// ============================================================================\n// 6. Schema DDL & Metadata Assembler\n// ============================================================================\n\n/**\n * Creates a new table, allocating a root data page and dedicated column catalog page(s).\n */\nexport function catalog_create_table(\n page1_view: DataView,\n pager: IPageProvider,\n name: string,\n column_def: ColumnDefinition[],\n): TableMeta {\n if (column_def.length === 0) {\n throw new Error(\"Table must have at least one column\");\n }\n\n if (column_def.length > MAX_COLUMNS_PER_TABLE) {\n throw new TooManyColumnsError(column_def.length, MAX_COLUMNS_PER_TABLE);\n }\n\n // Check if table already exists\n if (catalog_find_table_slot(page1_view, name) !== -1) {\n throw new TableAlreadyExistsError(name);\n }\n\n // Find free slot in Page 1 TableDescriptor slots\n const slot_idx = catalog_find_free_table_slot(page1_view);\n\n if (slot_idx === -1) {\n throw new TooManyTablesError(MAX_TABLES_PAGE1, MAX_TABLES_PAGE1);\n }\n\n const table_id = slot_idx + 1;\n const root_page_id = pager.allocateNewPage();\n\n // Initialize the table's root leaf data page (0x0D)\n const root_bytes = pager.getPageBytes(root_page_id);\n const root_view = new DataView(root_bytes.buffer, root_bytes.byteOffset);\n root_view.setUint8(0, 0x0d); // PAGE_TYPE_LEAF_DATA\n root_view.setUint8(1, 0);\n root_view.setUint16(2, 0, true); // cell_count = 0\n root_view.setUint16(4, PAGE_SIZE, true); // cell_content_offset = 4096\n root_view.setUint32(6, 0, true); // next_page_id = 0\n root_view.setUint16(10, 0, true); // free_bytes = 0\n root_view.setUint32(12, 0, true); // checksum\n pager.markPageDirty(root_page_id);\n\n // Compute column metadata & fixed slice offsets\n const columns: ColumnMeta[] = [];\n let current_fixed_offset = 0;\n\n for (let i = 0; i < column_def.length; i++) {\n const def = column_def[i];\n const type =\n typeof def.type === \"string\"\n ? catalog_parse_data_type(def.type)\n : (def.type as DataType);\n\n let flags = 0;\n if (typeof (def as any).flags === \"number\") {\n flags = (def as any).flags;\n } else {\n if (def.primaryKey || def.flags?.primaryKey)\n flags |= ColumnFlag.PRIMARY_KEY;\n if (def.notNull || def.flags?.notNull) flags |= ColumnFlag.NOT_NULL;\n if (def.indexed || def.flags?.indexed) flags |= ColumnFlag.INDEXED;\n if (\n def.autoInc ||\n def.autoIncrement ||\n def.flags?.autoInc ||\n def.flags?.autoIncrement\n )\n flags |= ColumnFlag.AUTO_INC;\n }\n\n const col_offset = current_fixed_offset;\n\n switch (type) {\n case DataType.INT32:\n current_fixed_offset += 4;\n break;\n case DataType.INT64:\n case DataType.FLOAT64:\n current_fixed_offset += 8;\n break;\n case DataType.UUID:\n case DataType.ULID:\n current_fixed_offset += 16;\n break;\n }\n\n columns.push({\n type,\n flags,\n colOffset: col_offset,\n name: def.name,\n });\n }\n\n // Allocate and write dedicated column catalog pages\n const total_cols = columns.length;\n const num_catalog_pages = Math.ceil(\n total_cols / MAX_COLUMNS_PER_CATALOG_PAGE,\n );\n const catalog_page_ids: number[] = [];\n\n for (let i = 0; i < num_catalog_pages; i++) {\n catalog_page_ids.push(pager.allocateNewPage());\n }\n\n for (let p = 0; p < num_catalog_pages; p++) {\n const page_id = catalog_page_ids[p];\n const next_page_id =\n p < num_catalog_pages - 1 ? catalog_page_ids[p + 1] : 0;\n const start_col_index = p * MAX_COLUMNS_PER_CATALOG_PAGE;\n const col_count_in_this_page = Math.min(\n total_cols - start_col_index,\n MAX_COLUMNS_PER_CATALOG_PAGE,\n );\n\n const page_bytes = pager.getPageBytes(page_id);\n const view = new DataView(page_bytes.buffer, page_bytes.byteOffset);\n\n catalog_init_page(view, 0, table_id, start_col_index, next_page_id);\n view.setUint16(2, col_count_in_this_page, true); // col_count_in_page\n\n for (let c = 0; c < col_count_in_this_page; c++) {\n const col = columns[start_col_index + c];\n catalog_write_column_meta(view, 0, c, col);\n }\n\n // Set CRC32 checksum\n const chk = computePageChecksum(page_bytes);\n view.setUint32(12, chk, true);\n pager.markPageDirty(page_id);\n }\n\n const first_catalog_page_id = catalog_page_ids[0];\n\n // Write TableDescriptor into Page 1\n const desc: TableDescriptor = {\n tableId: table_id,\n columnCount: total_cols,\n rootPageId: root_page_id,\n colCatalogPageId: first_catalog_page_id,\n name,\n flags: TableFlag.ACTIVE,\n rowCountEstimate: 0,\n autoIncNext: 1n,\n };\n\n catalog_write_table_descriptor(page1_view, slot_idx, desc);\n\n // Auto-create primary key index if PRIMARY_KEY columns are defined\n const pk_cols: ColumnMeta[] = [];\n for (let i = 0; i < columns.length; i++) {\n if ((columns[i].flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n pk_cols.push(columns[i]);\n }\n }\n\n if (pk_cols.length > 0) {\n const index_slot = catalog_find_free_index_slot(page1_view);\n if (index_slot !== -1) {\n const index_root_page_id = pager.allocateNewPage();\n const index_root_bytes = pager.getPageBytes(index_root_page_id);\n const index_root_view = new DataView(\n index_root_bytes.buffer,\n index_root_bytes.byteOffset,\n );\n page_init_index_leaf(index_root_view, 0, 0);\n pager.markPageDirty(index_root_page_id);\n\n const col_indices = [0, 0, 0, 0, 0, 0, 0, 0];\n const col_directions = [0, 0, 0, 0, 0, 0, 0, 0];\n for (let k = 0; k < pk_cols.length && k < 8; k++) {\n const pk_col_name = pk_cols[k].name;\n let matched_idx = -1;\n for (let c = 0; c < columns.length; c++) {\n if (columns[c].name === pk_col_name) {\n matched_idx = c;\n break;\n }\n }\n col_indices[k] = matched_idx;\n }\n\n const pk_desc: IndexDescriptor = {\n indexId: index_slot + 1,\n tableId: table_id,\n rootPageId: index_root_page_id,\n columnCount: pk_cols.length,\n flags: IndexFlag.PRIMARY | IndexFlag.UNIQUE,\n columnIndices: col_indices,\n colDirections: col_directions,\n name: `pk_${name}`,\n };\n catalog_write_index_descriptor(page1_view, index_slot, pk_desc);\n }\n }\n\n catalog_increment_schema_version(page1_view);\n catalog_increment_change_counter(page1_view);\n catalog_update_page1_checksum(page1_view);\n\n const indexes = catalog_list_table_indexes(page1_view, table_id);\n const primary_key: string[] = [];\n for (let i = 0; i < pk_cols.length; i++) {\n primary_key.push(pk_cols[i].name);\n }\n\n return {\n ...desc,\n columns,\n primaryKey: primary_key.length > 0 ? primary_key : undefined,\n indexes: indexes.length > 0 ? indexes : undefined,\n };\n}\n\n/**\n * Loads the complete TableMeta (including all columns from chained catalog pages) for a table.\n */\nexport function catalog_load_table_meta(\n page1_view: DataView,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n pager: { getPageBytes(pageId: number): Uint8Array },\n table_name: string,\n): TableMeta {\n const slot_idx = catalog_find_table_slot(page1_view, table_name);\n\n if (slot_idx === -1) {\n throw new TableNotFoundError(table_name);\n }\n\n const desc = catalog_read_table_descriptor(page1_view, slot_idx)!;\n const columns: ColumnMeta[] = [];\n\n let current_cat_page_id = desc.colCatalogPageId;\n let loaded_count = 0;\n\n while (current_cat_page_id !== 0 && loaded_count < desc.columnCount) {\n const page_bytes = pager.getPageBytes(current_cat_page_id);\n const view = new DataView(page_bytes.buffer, page_bytes.byteOffset);\n const header = catalog_read_page_header(view, 0);\n\n for (let i = 0; i < header.colCountInPage; i++) {\n const col = catalog_read_column_meta(view, 0, i);\n columns.push(col);\n loaded_count++;\n }\n\n current_cat_page_id = header.nextColCatalogPageId;\n }\n\n const indexes = catalog_list_table_indexes(page1_view, desc.tableId);\n const primary_key: string[] = [];\n for (let i = 0; i < columns.length; i++) {\n if ((columns[i].flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n primary_key.push(columns[i].name);\n }\n }\n\n return {\n ...desc,\n columns,\n primaryKey: primary_key.length > 0 ? primary_key : undefined,\n indexes: indexes.length > 0 ? indexes : undefined,\n };\n}\n\n/**\n * Loads all active tables and their full schemas from Page 1.\n */\nexport function catalog_load_all_tables(\n page1_view: DataView,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n pager: { getPageBytes(pageId: number): Uint8Array },\n): TableMeta[] {\n const descriptors = catalog_list_table_descriptors(page1_view);\n const tables: TableMeta[] = [];\n for (let i = 0; i < descriptors.length; i++) {\n tables.push(\n catalog_load_table_meta(page1_view, pager, descriptors[i].name),\n );\n }\n return tables;\n}\n","/**\n * Embedded WebDB Core WebAssembly binary (Base64 encoded).\n * Auto-generated by scripts/build_wasm.js. Do not edit manually.\n */\nexport const WEBDB_CORE_WASM_BASE64 = \"AGFzbQEAAAABcBFgAX8Bf2ACf38AYAJ/fwF/YAN/f38AYAN/f38Bf2AEf39/fwF/YAAAYAV/f39/fwF/YAN/f34Bf2ACf34Bf2ABfwBgBH9/f38AYAV/f39/fwBgBX9+f35/AGAFf3x/fH8AYAd/f39/f39/AGAAAX8CDwEDZW52Bm1lbW9yeQIAAgNIRwYAAAQAAwQDAgQFBAACAwcFAQECAwEAAQABAAEAAQABAAECAwAAAQABAQgJAQIAAAoAAQAAAAAAAwAAAgILDAACBQ0ODwUQBggBfwFBgIAECwfYDUwPX19zdGFja19wb2ludGVyAwAHaGV4X3ZhbAABEGNyb2NrZm9yZF9kZWNvZGUAAgt1dWlkX2VuY29kZQADBnN0cmxlbgAEC3V1aWRfZGVjb2RlAAULdWxpZF9lbmNvZGUABgt1bGlkX2RlY29kZQAHD3BhZ2VfdGFibGVfaGFzaAAIDnBhZ2VfdGFibGVfZ2V0AAkOcGFnZV90YWJsZV9zZXQAChFwYWdlX3RhYmxlX2RlbGV0ZQALGGJ1Zl9wb29sX2dldF9zbG90X29mZnNldAAMGmJ1Zl9wb29sX3JlYWRfc2xvdF90b19wYWdlAA0bYnVmX3Bvb2xfd3JpdGVfc2xvdF90b19wYWdlAA4aYnVmX3Bvb2xfZ2V0X3Jlc2lkZW50X3Nsb3QACRRidWZfcG9vbF9hc3NpZ25fc2xvdAAPFmJ1Zl9wb29sX3VuYXNzaWduX3Nsb3QAEBNidWZfcG9vbF9tYXJrX2RpcnR5ABEUYnVmX3Bvb2xfY2xlYXJfZGlydHkAEhFidWZfcG9vbF9pc19kaXJ0eQATCXBhZ2VfaW5pdAAUDnBhZ2VfaW5pdF9mcmVlABUNcGFnZV9nZXRfdHlwZQAWDXBhZ2Vfc2V0X3R5cGUAFxNwYWdlX2dldF9jZWxsX2NvdW50ABgTcGFnZV9zZXRfY2VsbF9jb3VudAAZHHBhZ2VfZ2V0X2NlbGxfY29udGVudF9vZmZzZXQAGhxwYWdlX3NldF9jZWxsX2NvbnRlbnRfb2Zmc2V0ABsVcGFnZV9nZXRfbmV4dF9wYWdlX2lkABwVcGFnZV9zZXRfbmV4dF9wYWdlX2lkAB0TcGFnZV9nZXRfZnJlZV9ieXRlcwAeE3BhZ2Vfc2V0X2ZyZWVfYnl0ZXMAHxFwYWdlX2dldF9jaGVja3N1bQAgEXBhZ2Vfc2V0X2NoZWNrc3VtACEUcGFnZV9nZXRfY2VsbF9vZmZzZXQAIhRwYWdlX3NldF9jZWxsX29mZnNldAAjHnBhZ2VfZ2V0X2NvbnRpZ3VvdXNfZnJlZV9zcGFjZQAkGXBhZ2VfZ2V0X3RvdGFsX2ZyZWVfc3BhY2UAJQxwYWdlX2NvbXBhY3QAJhNwYWdlX2dldF9yb3dfbGVuZ3RoACcPcGFnZV9kZWxldGVfcm93ACgScGFnZV9pbml0X2ludGVyaW9yACkccGFnZV9nZXRfcmlnaHRfY2hpbGRfcGFnZV9pZAAcHHBhZ2Vfc2V0X3JpZ2h0X2NoaWxkX3BhZ2VfaWQAHRlwYWdlX2luc2VydF9pbnRlcmlvcl9jZWxsACobcGFnZV9iaW5hcnlfc2VhcmNoX2ludGVyaW9yACsUcGFnZV9pbml0X2luZGV4X2xlYWYALA1jb21wdXRlX2NyYzMyAC0VY29tcHV0ZV9wYWdlX2NoZWNrc3VtAC4WY29tcHV0ZV9wYWdlMV9jaGVja3N1bQAvEmNhdGFsb2dfaW5pdF9wYWdlMQAwF2NhdGFsb2dfZ2V0X3RvdGFsX3BhZ2VzACAXY2F0YWxvZ19zZXRfdG90YWxfcGFnZXMAIRpjYXRhbG9nX2dldF9mcmVlX3BhZ2VfaGVhZAAxGmNhdGFsb2dfc2V0X2ZyZWVfcGFnZV9oZWFkADIaY2F0YWxvZ19nZXRfc2NoZW1hX3ZlcnNpb24AMyBjYXRhbG9nX2luY3JlbWVudF9zY2hlbWFfdmVyc2lvbgA0GmNhdGFsb2dfZ2V0X2NoYW5nZV9jb3VudGVyADUgY2F0YWxvZ19pbmNyZW1lbnRfY2hhbmdlX2NvdW50ZXIANh1jYXRhbG9nX3VwZGF0ZV9wYWdlMV9jaGVja3N1bQA3GmNhdGFsb2dfd3JpdGVfZml4ZWRfc3RyaW5nADgcY2F0YWxvZ19maW5kX2ZyZWVfdGFibGVfc2xvdAA5HGNhdGFsb2dfZmluZF9mcmVlX2luZGV4X3Nsb3QAOh9jYXRhbG9nX2RlbGV0ZV9pbmRleF9kZXNjcmlwdG9yADsfY2F0YWxvZ19kZWxldGVfdGFibGVfZGVzY3JpcHRvcgA8EWNhdGFsb2dfaW5pdF9wYWdlAD0Z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IABBBmooAAALDAAgAEEGaiABNgAACwoAIABBCmovAAALDAAgAEEKaiABOwAACwoAIABBDGooAAALDAAgAEEMaiABNgAACxAAIAAgAUEBdGpBEGovAAALEgAgACABQQF0akEQaiACOwAACx4AIABBBGovAAAgAEECai8AAEEBdGtBEGtB//8DcQsnACAAQQpqLwAAIABBBGovAAAgAEECai8AAEEBdGtqQRBrQf//A3EL0AEBBn8gAEECai8AACIFRQRAIABBCmpBADsAACAAQQRqQYAgOwAADwsgAUEAIAAgAUcbQQAgAUGAYE8bIgIgACkACDcACCACIAApAAA3AAAgAkEQaiEDIABBEGohBEGAICEBA0AgASAAIAQvAABqIgdBAWovAAAiBmshASAGBEAgAiABQf//A3FqIAcgBvwKAAALIAMgATsAACAEQQJqIQQgA0ECaiEDIAVBAWsiBQ0ACyACQQpqQQA7AAAgAkEEaiABOwAAIAAgAkGAIPwKAAALCgAgAEEBai8AAAt0AQN/IABBAmovAAAiAiABSwRAIAAgACABQQF0akEQaiIDLwAAakEBai8AACEEAkAgAkEBayICIAFGDQAgAiABa0EBdCIBRQ0AIAMgA0ECaiAB/AoAAAsgAEECaiACOwAAIABBCmoiACAALwAAIARqOwAACws1ACAAQQU7AAAgAEEMakEANgAAIABBCmpBADsAACAAQQZqIAE2AAAgAEECakGAgICAATYAAAtsAQV/IABBAmoiBS8AACIDQaICTQR/IABBBGoiBi8AAEEMayIEIABqIgcgATYAACAHQQRqIAI3AAAgACADQQF0Qf7/A3FqQRBqIAQ7AAAgBiAEOwAAIAUgA0EBaiIAOwAAIABB//8DcQVBfwsLhwEBBn8CQCAAQQJqLwAAIgIEQCAAQRBqIQcgAkEBayEDQX8hAgNAIAMgBWoiBEEBdiEGAkAgACAHIARB/v8HcWovAABqIgRBBGo1AAAgAVkEQCAGQQFrIQMgBCgAACECDAELIAZBAWohBQsgAyAFTw0ACyACQX9HDQELIABBBmooAAAhAgsgAgs1ACAAQQo7AAAgAEEMakEANgAAIABBCmpBADsAACAAQQZqIAE2AAAgAEECakGAgICAATYAAAu6AgEEf0HAkQQtAABFBEADQCACQcyJBGogBEEIdiID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\";\n\nlet cachedBytes: Uint8Array | null = null;\n\nexport function getWebDbCoreWasmBytes(): Uint8Array {\n if (!cachedBytes) {\n const maybeBuffer = (globalThis as unknown as { Buffer?: { from: (b64: string, enc: string) => Uint8Array } }).Buffer;\n if (typeof maybeBuffer !== \"undefined\" && typeof maybeBuffer.from === \"function\") {\n cachedBytes = new Uint8Array(maybeBuffer.from(WEBDB_CORE_WASM_BASE64, \"base64\"));\n } else {\n const binaryString = atob(WEBDB_CORE_WASM_BASE64);\n const len = binaryString.length;\n cachedBytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n cachedBytes[i] = binaryString.charCodeAt(i);\n }\n }\n }\n return cachedBytes;\n}\n","/**\n * WebDB WebAssembly Core Adapter\n * Wraps compiled C WebAssembly exports with 1:1 API parity to the JS Core.\n */\n\nimport { getWebDbCoreWasmBytes } from \"./embedded_wasm.ts\";\nimport {\n PAGE_TYPE_LEAF_DATA,\n} from \"../../constants.ts\";\nimport * as jsCore from \"../js/index.ts\";\n\nexport interface WasmCoreExports {\n instance: WebAssembly.Instance;\n exports: Record<string, any>;\n memory: WebAssembly.Memory;\n\n // Page\n page_init: (view: DataView, page_offset: number, page_type?: number, next_page_id?: number) => void;\n page_init_free: (view: DataView, page_offset: number, next_free_page_id?: number) => void;\n page_get_type: (view: DataView, page_offset: number) => number;\n page_set_type: (view: DataView, page_offset: number, type: number) => void;\n page_get_cell_count: (view: DataView, page_offset: number) => number;\n page_set_cell_count: (view: DataView, page_offset: number, count: number) => void;\n page_get_cell_content_offset: (view: DataView, page_offset: number) => number;\n page_set_cell_content_offset: (view: DataView, page_offset: number, offset: number) => void;\n page_get_next_page_id: (view: DataView, page_offset: number) => number;\n page_set_next_page_id: (view: DataView, page_offset: number, next_page_id: number) => void;\n page_get_free_bytes: (view: DataView, page_offset: number) => number;\n page_set_free_bytes: (view: DataView, page_offset: number, free_bytes: number) => void;\n page_get_checksum: (view: DataView, page_offset: number) => number;\n page_set_checksum: (view: DataView, page_offset: number, checksum: number) => void;\n page_get_cell_offset: (view: DataView, page_offset: number, slot_idx: number) => number;\n page_set_cell_offset: (view: DataView, page_offset: number, slot_idx: number, cell_offset: number) => void;\n page_get_contiguous_free_space: (view: DataView, page_offset: number) => number;\n page_get_total_free_space: (view: DataView, page_offset: number) => number;\n page_compact: (view: DataView, page_offset: number, scratchpad_offset?: number, replacement?: any) => void;\n page_get_row_length: (view: DataView, row_offset: number) => number;\n page_insert_row: (view: DataView, page_offset: number, row_bytes: Uint8Array, scratchpad_offset?: number) => number;\n page_delete_row: (view: DataView, page_offset: number, cell_idx: number) => void;\n page_update_row: (view: DataView, page_offset: number, cell_idx: number, new_row_bytes: Uint8Array, scratchpad_offset?: number) => boolean;\n\n // Page Table\n page_table_hash: (page_id: number, mask: number) => number;\n page_table_get: (view: DataView, base_offset: number, bucket_count: number, page_id: number) => number;\n page_table_set: (view: DataView, base_offset: number, bucket_count: number, page_id: number, slot_idx: number) => void;\n page_table_delete: (view: DataView, base_offset: number, bucket_count: number, page_id: number) => boolean;\n\n // Buffer Pool\n buf_pool_get_slot_offset: (slot_idx: number) => number;\n buf_pool_read_slot_to_page: (view: DataView, slot_to_page_offset: number, slot_idx: number) => number;\n buf_pool_write_slot_to_page: (view: DataView, slot_to_page_offset: number, slot_idx: number, page_id: number) => void;\n buf_pool_get_resident_slot: (view: DataView, page_to_slot_offset: number, page_to_slot_buckets: number, page_id: number) => number;\n buf_pool_assign_slot: (view: DataView, slot_to_page_offset: number, page_to_slot_offset: number, page_to_slot_buckets: number, slot_idx: number, page_id: number) => void;\n buf_pool_unassign_slot: (view: DataView, slot_to_page_offset: number, page_to_slot_offset: number, page_to_slot_buckets: number, slot_idx: number) => void;\n buf_pool_mark_dirty: (view: DataView | Uint8Array, dirty_mask_offset: number, slot_idx: number) => void;\n buf_pool_clear_dirty: (view: DataView | Uint8Array, dirty_mask_offset: number, slot_idx: number) => void;\n buf_pool_is_dirty: (view: DataView | Uint8Array, dirty_mask_offset: number, slot_idx: number) => boolean;\n buf_pool_pin_slot: (pin_counts: Uint32Array, slot_idx: number) => void;\n buf_pool_unpin_slot: (pin_counts: Uint32Array, slot_idx: number) => void;\n buf_pool_is_pinned: (pin_counts: Uint32Array, slot_idx: number) => boolean;\n buf_pool_find_victim: (buffer: ArrayBuffer, ref_bits: Uint8Array, pin_counts: Uint32Array, slot_to_page_offset: number, slot_count: number, current_clock_hand: number) => { candidate_slot: number; next_clock_hand: number };\n buf_pool_select_eviction_victim: (buffer: ArrayBuffer, ref_bits: Uint8Array, pin_counts: Uint32Array, slot_to_page_offset: number, dirty_mask_offset: number, slot_count: number, current_clock_hand: number, page_id: number) => { candidate_slot: number; flush_page_id: number; next_clock_hand: number };\n\n // Catalog\n catalog_init_page1: (view: DataView) => void;\n catalog_read_page1_header: typeof jsCore.catalog_read_page1_header;\n catalog_get_total_pages: (view: DataView) => number;\n catalog_set_total_pages: (view: DataView, count: number) => void;\n catalog_get_free_page_head: (view: DataView) => number;\n catalog_set_free_page_head: (view: DataView, page_id: number) => void;\n catalog_get_schema_version: (view: DataView) => number;\n catalog_increment_schema_version: (view: DataView) => number;\n catalog_get_change_counter: (view: DataView) => number;\n catalog_increment_change_counter: (view: DataView) => number;\n catalog_update_page1_checksum: (view: DataView) => number;\n\n // VM & Helpers\n sql_like_match: (str: string, pattern: string) => boolean;\n fnv1a_32: (values: any[]) => number;\n compare_sorter_keys: typeof jsCore.compare_sorter_keys;\n vm_step: typeof jsCore.vm_step;\n}\n\nexport function createWasmCore(\n memory: WebAssembly.Memory,\n customBytes?: Uint8Array,\n): WasmCoreExports {\n const bytes = customBytes ?? getWebDbCoreWasmBytes();\n const wasmModule = new WebAssembly.Module(bytes as unknown as BufferSource);\n const instance = new WebAssembly.Instance(wasmModule, {\n env: { memory },\n });\n\n const exp = instance.exports as Record<string, any>;\n\n const getAbsOffset = (view: DataView | Uint8Array, offset: number = 0) => {\n return view.byteOffset + offset;\n };\n\n const wasmExports: WasmCoreExports = {\n instance,\n exports: exp,\n memory,\n\n // Page Operations\n page_init: (view, page_offset, page_type = PAGE_TYPE_LEAF_DATA, next_page_id = 0) => {\n exp.page_init(getAbsOffset(view, page_offset), page_type, next_page_id);\n },\n\n page_init_free: (view, page_offset, next_free_page_id = 0) => {\n exp.page_init_free(getAbsOffset(view, page_offset), next_free_page_id);\n },\n\n page_get_type: (view, page_offset) => {\n return exp.page_get_type(getAbsOffset(view, page_offset));\n },\n\n page_set_type: (view, page_offset, type) => {\n exp.page_set_type(getAbsOffset(view, page_offset), type);\n },\n\n page_get_cell_count: (view, page_offset) => {\n return exp.page_get_cell_count(getAbsOffset(view, page_offset));\n },\n\n page_set_cell_count: (view, page_offset, count) => {\n exp.page_set_cell_count(getAbsOffset(view, page_offset), count);\n },\n\n page_get_cell_content_offset: (view, page_offset) => {\n return exp.page_get_cell_content_offset(getAbsOffset(view, page_offset));\n },\n\n page_set_cell_content_offset: (view, page_offset, offset) => {\n exp.page_set_cell_content_offset(getAbsOffset(view, page_offset), offset);\n },\n\n page_get_next_page_id: (view, page_offset) => {\n return exp.page_get_next_page_id(getAbsOffset(view, page_offset));\n },\n\n page_set_next_page_id: (view, page_offset, next_page_id) => {\n exp.page_set_next_page_id(getAbsOffset(view, page_offset), next_page_id);\n },\n\n page_get_free_bytes: (view, page_offset) => {\n return exp.page_get_free_bytes(getAbsOffset(view, page_offset));\n },\n\n page_set_free_bytes: (view, page_offset, free_bytes) => {\n exp.page_set_free_bytes(getAbsOffset(view, page_offset), free_bytes);\n },\n\n page_get_checksum: (view, page_offset) => {\n return exp.page_get_checksum(getAbsOffset(view, page_offset));\n },\n\n page_set_checksum: (view, page_offset, checksum) => {\n exp.page_set_checksum(getAbsOffset(view, page_offset), checksum);\n },\n\n page_get_cell_offset: (view, page_offset, slot_idx) => {\n return exp.page_get_cell_offset(getAbsOffset(view, page_offset), slot_idx);\n },\n\n page_set_cell_offset: (view, page_offset, slot_idx, cell_offset) => {\n exp.page_set_cell_offset(getAbsOffset(view, page_offset), slot_idx, cell_offset);\n },\n\n page_get_contiguous_free_space: (view, page_offset) => {\n return exp.page_get_contiguous_free_space(getAbsOffset(view, page_offset));\n },\n\n page_get_total_free_space: (view, page_offset) => {\n return exp.page_get_total_free_space(getAbsOffset(view, page_offset));\n },\n\n page_compact: (view, page_offset, scratchpad_offset = 0, replacement) => {\n if (replacement) {\n // Fall back to JS core for replacement cell compaction edge-cases\n jsCore.page_compact(view, page_offset, scratchpad_offset, replacement);\n } else {\n exp.page_compact(getAbsOffset(view, page_offset), scratchpad_offset, -1, 0, 0);\n }\n },\n\n page_get_row_length: (view, row_offset) => {\n return exp.page_get_row_length(getAbsOffset(view, row_offset));\n },\n\n page_insert_row: (view, page_offset, row_bytes, scratchpad_offset = 0) => {\n // Direct call into JS or WASM\n return jsCore.page_insert_row(view, page_offset, row_bytes, scratchpad_offset);\n },\n\n page_delete_row: (view, page_offset, cell_idx) => {\n exp.page_delete_row(getAbsOffset(view, page_offset), cell_idx);\n },\n\n page_update_row: (view, page_offset, cell_idx, new_row_bytes, scratchpad_offset = 0) => {\n return jsCore.page_update_row(view, page_offset, cell_idx, new_row_bytes, scratchpad_offset);\n },\n\n // Page Table\n page_table_hash: (page_id, mask) => {\n return exp.page_table_hash(page_id, mask);\n },\n\n page_table_get: (view, base_offset, bucket_count, page_id) => {\n return exp.page_table_get(getAbsOffset(view, base_offset), bucket_count, page_id);\n },\n\n page_table_set: (view, base_offset, bucket_count, page_id, slot_idx) => {\n const res = exp.page_table_set(getAbsOffset(view, base_offset), bucket_count, page_id, slot_idx);\n if (res < 0) {\n throw new Error(`BufferPool page table full: cannot insert page ${page_id}`);\n }\n },\n\n page_table_delete: (view, base_offset, bucket_count, page_id) => {\n return exp.page_table_delete(getAbsOffset(view, base_offset), bucket_count, page_id) !== 0;\n },\n\n // Buffer Pool\n buf_pool_get_slot_offset: (slot_idx) => {\n return exp.buf_pool_get_slot_offset(slot_idx);\n },\n\n buf_pool_read_slot_to_page: (view, slot_to_page_offset, slot_idx) => {\n return exp.buf_pool_read_slot_to_page(getAbsOffset(view, slot_to_page_offset), slot_idx);\n },\n\n buf_pool_write_slot_to_page: (view, slot_to_page_offset, slot_idx, page_id) => {\n exp.buf_pool_write_slot_to_page(getAbsOffset(view, slot_to_page_offset), slot_idx, page_id);\n },\n\n buf_pool_get_resident_slot: (view, page_to_slot_offset, page_to_slot_buckets, page_id) => {\n return exp.buf_pool_get_resident_slot(getAbsOffset(view, page_to_slot_offset), page_to_slot_buckets, page_id);\n },\n\n buf_pool_assign_slot: (view, slot_to_page_offset, page_to_slot_offset, page_to_slot_buckets, slot_idx, page_id) => {\n exp.buf_pool_assign_slot(\n getAbsOffset(view, slot_to_page_offset),\n getAbsOffset(view, page_to_slot_offset),\n page_to_slot_buckets,\n slot_idx,\n page_id,\n );\n },\n\n buf_pool_unassign_slot: (view, slot_to_page_offset, page_to_slot_offset, page_to_slot_buckets, slot_idx) => {\n exp.buf_pool_unassign_slot(\n getAbsOffset(view, slot_to_page_offset),\n getAbsOffset(view, page_to_slot_offset),\n page_to_slot_buckets,\n slot_idx,\n );\n },\n\n buf_pool_mark_dirty: (view, dirty_mask_offset, slot_idx) => {\n exp.buf_pool_mark_dirty(getAbsOffset(view as any, dirty_mask_offset), slot_idx);\n },\n\n buf_pool_clear_dirty: (view, dirty_mask_offset, slot_idx) => {\n exp.buf_pool_clear_dirty(getAbsOffset(view as any, dirty_mask_offset), slot_idx);\n },\n\n buf_pool_is_dirty: (view, dirty_mask_offset, slot_idx) => {\n return exp.buf_pool_is_dirty(getAbsOffset(view as any, dirty_mask_offset), slot_idx) !== 0;\n },\n\n buf_pool_pin_slot: (pin_counts, slot_idx) => {\n jsCore.buf_pool_pin_slot(pin_counts, slot_idx);\n },\n\n buf_pool_unpin_slot: (pin_counts, slot_idx) => {\n jsCore.buf_pool_unpin_slot(pin_counts, slot_idx);\n },\n\n buf_pool_is_pinned: (pin_counts, slot_idx) => {\n return jsCore.buf_pool_is_pinned(pin_counts, slot_idx);\n },\n\n buf_pool_find_victim: (buffer, ref_bits, pin_counts, slot_to_page_offset, slot_count, current_clock_hand) => {\n return jsCore.buf_pool_find_victim(buffer, ref_bits, pin_counts, slot_to_page_offset, slot_count, current_clock_hand);\n },\n\n buf_pool_select_eviction_victim: (buffer, ref_bits, pin_counts, slot_to_page_offset, dirty_mask_offset, slot_count, current_clock_hand, page_id) => {\n return jsCore.buf_pool_select_eviction_victim(buffer, ref_bits, pin_counts, slot_to_page_offset, dirty_mask_offset, slot_count, current_clock_hand, page_id);\n },\n\n // Catalog Operations\n catalog_init_page1: (view) => {\n exp.catalog_init_page1(getAbsOffset(view));\n },\n\n catalog_read_page1_header: (view, verify_checksum) => {\n return jsCore.catalog_read_page1_header(view, verify_checksum);\n },\n\n catalog_get_total_pages: (view) => {\n return exp.catalog_get_total_pages(getAbsOffset(view));\n },\n\n catalog_set_total_pages: (view, count) => {\n exp.catalog_set_total_pages(getAbsOffset(view), count);\n },\n\n catalog_get_free_page_head: (view) => {\n return exp.catalog_get_free_page_head(getAbsOffset(view));\n },\n\n catalog_set_free_page_head: (view, page_id) => {\n exp.catalog_set_free_page_head(getAbsOffset(view), page_id);\n },\n\n catalog_get_schema_version: (view) => {\n return exp.catalog_get_schema_version(getAbsOffset(view));\n },\n\n catalog_increment_schema_version: (view) => {\n return exp.catalog_increment_schema_version(getAbsOffset(view));\n },\n\n catalog_get_change_counter: (view) => {\n return exp.catalog_get_change_counter(getAbsOffset(view));\n },\n\n catalog_increment_change_counter: (view) => {\n return exp.catalog_increment_change_counter(getAbsOffset(view));\n },\n\n catalog_update_page1_checksum: (view) => {\n return exp.catalog_update_page1_checksum(getAbsOffset(view));\n },\n\n // Helpers\n sql_like_match: (str, pattern) => {\n return jsCore.sql_like_match(str, pattern);\n },\n\n fnv1a_32: (values) => {\n return jsCore.fnv1a_32(values);\n },\n\n compare_sorter_keys: jsCore.compare_sorter_keys,\n vm_step: jsCore.vm_step,\n };\n\n return wasmExports;\n}\n","import {\n PAGE_SIZE,\n DEFAULT_SLOT_COUNT,\n DEFAULT_MAX_QUERY_MEMORY,\n PAGE_TO_SLOT_BUCKET_SIZE,\n PAGE_TYPE_FREE,\n PAGE_TYPE_CATALOG_PAGE,\n HEADER_OFFSET_TOTAL_PAGES,\n HEADER_OFFSET_FREE_PAGE_HEAD,\n PAGE_HEADER_OFFSET_NEXT_PAGE_ID,\n PAGE_HEADER_OFFSET_TYPE,\n PAGE_HEADER_SIZE,\n computeBufferPoolOffsets,\n} from \"../../constants.ts\";\n\nexport type BufferPoolOffsets = ReturnType<typeof computeBufferPoolOffsets>;\n\nimport { IVfsAdapter } from \"../storage/vfs.ts\";\nimport { Io } from \"../storage/io.ts\";\nimport { read_u32, write_u32, read_u8, memset } from \"../../shared/index.ts\";\nimport {\n CorruptPageError,\n QueryArenaExhaustedError,\n VmStatus,\n VmContext,\n} from \"../../types/index.ts\";\nimport {\n page_init,\n page_init_free,\n page_get_type,\n vm_step,\n buf_pool_read_slot_to_page,\n buf_pool_get_resident_slot,\n buf_pool_assign_slot,\n buf_pool_unassign_slot,\n buf_pool_mark_dirty,\n buf_pool_clear_dirty,\n buf_pool_is_dirty,\n buf_pool_pin_slot,\n buf_pool_unpin_slot,\n buf_pool_is_pinned,\n buf_pool_select_eviction_victim,\n} from \"../../core/index.ts\";\n\n// ============================================================================\n// Helper to create Wasm Memory\n// ============================================================================\n\nexport function createWasmMemory(\n slotCount: number = DEFAULT_SLOT_COUNT,\n maxQueryMemory: number = DEFAULT_MAX_QUERY_MEMORY,\n): WebAssembly.Memory {\n const offsets = computeBufferPoolOffsets(slotCount, maxQueryMemory);\n const initial_bytes = offsets.transientArenaOffset + 256 * 1024;\n const initial_wasm_pages = Math.ceil(initial_bytes / 65536);\n const max_wasm_pages = Math.ceil(\n (offsets.transientArenaOffset + maxQueryMemory) / 65536,\n );\n return new WebAssembly.Memory({\n initial: initial_wasm_pages,\n maximum: Math.max(initial_wasm_pages, max_wasm_pages),\n });\n}\n\n// ============================================================================\n// Async I/O Driver Loop (Host Layer)\n// ============================================================================\n\nexport interface BufferPoolDriverOptions {\n vfs?: IVfsAdapter;\n io?: Io;\n memory?: WebAssembly.Memory;\n pool?: {\n wasmMemory: WebAssembly.Memory;\n slotCount?: number;\n maxQueryMemory?: number;\n };\n slotCount?: number;\n maxQueryMemory?: number;\n useDefaultLayoutOffsets?: boolean;\n}\n\n/**\n * Async Buffer Pool Driver Loop.\n *\n * Implemented 100% in TypeScript on the Host Layer.\n * Interacts with the C Engine purely through shared WebAssembly.Memory and layout offsets.\n * Does NOT import or invoke any C-layer classes.\n */\nexport class BufferPoolDriver {\n readonly io: Io;\n readonly wasmMemory: WebAssembly.Memory;\n readonly buffer: ArrayBuffer;\n readonly view: DataView;\n readonly uint8: Uint8Array;\n readonly slotCount: number;\n readonly maxQueryMemory: number;\n readonly offsets: BufferPoolOffsets;\n\n // Offsets shortcuts\n readonly slotsEndOffset: number;\n readonly slotToPageOffset: number;\n readonly pageToSlotOffset: number;\n readonly pageToSlotBuckets: number;\n readonly dirtyMaskOffset: number;\n readonly vmContextOffset: number;\n readonly resultBufferOffset: number;\n readonly bytecodeOffset: number;\n readonly pageScratchpadOffset: number;\n readonly transientArenaOffset: number;\n\n readonly pin_counts: Uint32Array;\n readonly slot_dirty_generations: Uint32Array;\n readonly ref_bits: Uint8Array;\n private clock_hand: number = 0;\n private arena_offset: number = 0;\n\n private in_flight_acquires = new Map<number, Promise<number>>();\n private allocation_lock: Promise<void> = Promise.resolve();\n\n constructor(options: BufferPoolDriverOptions) {\n this.slotCount =\n options.slotCount ?? options.pool?.slotCount ?? DEFAULT_SLOT_COUNT;\n\n this.maxQueryMemory =\n options.maxQueryMemory ??\n options.pool?.maxQueryMemory ??\n DEFAULT_MAX_QUERY_MEMORY;\n\n const memory = options.memory ?? options.pool?.wasmMemory;\n\n if (!memory) {\n throw new Error(\n \"BufferPoolDriver requires a valid WebAssembly.Memory (or pool with wasmMemory)\",\n );\n }\n\n this.wasmMemory = memory;\n this.buffer = this.wasmMemory.buffer;\n this.view = new DataView(this.buffer);\n this.uint8 = new Uint8Array(this.buffer);\n\n this.offsets = computeBufferPoolOffsets(\n options.useDefaultLayoutOffsets ? DEFAULT_SLOT_COUNT : this.slotCount,\n this.maxQueryMemory,\n );\n\n this.slotsEndOffset = this.offsets.slotsEndOffset;\n this.slotToPageOffset = this.offsets.slotToPageOffset;\n this.pageToSlotOffset = this.offsets.pageToSlotOffset;\n this.pageToSlotBuckets = this.offsets.pageToSlotBuckets;\n this.dirtyMaskOffset = this.offsets.dirtyMaskOffset;\n this.vmContextOffset = this.offsets.vmContextOffset;\n this.resultBufferOffset = this.offsets.resultBufferOffset;\n this.bytecodeOffset = this.offsets.bytecodeOffset;\n this.pageScratchpadOffset = this.offsets.pageScratchpadOffset;\n this.transientArenaOffset = this.offsets.transientArenaOffset;\n\n this.ref_bits = new Uint8Array(this.slotCount);\n this.pin_counts = new Uint32Array(this.slotCount);\n this.slot_dirty_generations = new Uint32Array(this.slotCount);\n\n if (options.io) {\n this.io = options.io;\n } else if (options.vfs) {\n this.io = new Io({ vfs: options.vfs, memory: this.wasmMemory });\n } else {\n throw new Error(\n \"BufferPoolDriver requires either an Io instance or IVfsAdapter\",\n );\n }\n\n // Initialize slot-to-page map, page-to-slot hash table, and dirty mask to zeros\n memset(this.uint8, this.slotToPageOffset, 0, this.slotCount * 4);\n memset(\n this.uint8,\n this.pageToSlotOffset,\n 0,\n this.pageToSlotBuckets * PAGE_TO_SLOT_BUCKET_SIZE,\n );\n memset(this.uint8, this.dirtyMaskOffset, 0, Math.ceil(this.slotCount / 8));\n\n // Slot 0 is reserved permanently for Page 1 and pinned\n this.assignSlot(0, 1);\n this.pin_counts[0] = 1;\n }\n\n private validate_slot_idx(slot_idx: number): void {\n if (\n !Number.isInteger(slot_idx) ||\n slot_idx < 0 ||\n slot_idx >= this.slotCount\n ) {\n throw new Error(\n `Invalid slot index: ${slot_idx}. Must be an integer between 0 and ${this.slotCount - 1}`,\n );\n }\n }\n\n private validate_page_id(page_id: number): void {\n if (!Number.isInteger(page_id) || page_id <= 0) {\n throw new Error(\n `Invalid page ID: ${page_id}. Page IDs must be positive integers.`,\n );\n }\n }\n\n private async with_allocation_lock<T>(fn: () => Promise<T>): Promise<T> {\n const prev_lock = this.allocation_lock;\n let release: () => void;\n this.allocation_lock = new Promise<void>((resolve) => {\n release = resolve;\n });\n await prev_lock;\n try {\n return await fn();\n } finally {\n release!();\n }\n }\n\n setTransactionCoordinator(coordinator: any): void {\n this.io.setTransactionCoordinator(coordinator);\n }\n\n // ==========================================================================\n // In-Memory Slot Mapping & Hash Table Primitives\n // ==========================================================================\n\n getSlotOffset(slotIdx: number): number {\n this.validate_slot_idx(slotIdx);\n return slotIdx * PAGE_SIZE;\n }\n\n getPageBytesInSlot(slotIdx: number): Uint8Array {\n this.validate_slot_idx(slotIdx);\n return this.uint8.subarray(slotIdx * PAGE_SIZE, (slotIdx + 1) * PAGE_SIZE);\n }\n\n getSlotDataView(slotIdx: number): DataView {\n this.validate_slot_idx(slotIdx);\n return new DataView(this.buffer, slotIdx * PAGE_SIZE, PAGE_SIZE);\n }\n\n getResidentSlot(pageId: number): number {\n this.validate_page_id(pageId);\n return buf_pool_get_resident_slot(\n this.view,\n this.pageToSlotOffset,\n this.pageToSlotBuckets,\n pageId,\n );\n }\n\n getAssignedPage(slotIdx: number): number {\n this.validate_slot_idx(slotIdx);\n return buf_pool_read_slot_to_page(\n this.view,\n this.slotToPageOffset,\n slotIdx,\n );\n }\n\n assignSlot(slotIdx: number, pageId: number): void {\n this.validate_slot_idx(slotIdx);\n if (!Number.isInteger(pageId) || pageId <= 0) {\n throw new Error(\n `Invalid page ID: ${pageId}. Must be a positive integer >= 1`,\n );\n }\n if (slotIdx === 0 && pageId !== 1) {\n throw new Error(\n `Cannot reassign slot 0: reserved permanently for page 1 (got page ${pageId})`,\n );\n }\n\n const existing_slot = this.getResidentSlot(pageId);\n if (existing_slot !== -1 && existing_slot !== slotIdx) {\n throw new Error(\n `Cannot map page ${pageId} to slot ${slotIdx}: already resident in slot ${existing_slot}`,\n );\n }\n\n buf_pool_assign_slot(\n this.view,\n this.slotToPageOffset,\n this.pageToSlotOffset,\n this.pageToSlotBuckets,\n slotIdx,\n pageId,\n );\n this.ref_bits[slotIdx] = 1;\n }\n\n unassignSlot(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n if (slotIdx === 0) {\n throw new Error(\n `Cannot unassign slot 0: reserved permanently for page 1`,\n );\n }\n\n buf_pool_unassign_slot(\n this.view,\n this.slotToPageOffset,\n this.pageToSlotOffset,\n this.pageToSlotBuckets,\n slotIdx,\n );\n this.ref_bits[slotIdx] = 0;\n }\n\n markDirty(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n buf_pool_mark_dirty(this.uint8, this.dirtyMaskOffset, slotIdx);\n this.slot_dirty_generations[slotIdx]++;\n }\n\n clearDirty(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n buf_pool_clear_dirty(this.uint8, this.dirtyMaskOffset, slotIdx);\n }\n\n isDirty(slotIdx: number): boolean {\n this.validate_slot_idx(slotIdx);\n return buf_pool_is_dirty(this.uint8, this.dirtyMaskOffset, slotIdx);\n }\n\n pinSlot(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n buf_pool_pin_slot(this.pin_counts, slotIdx);\n }\n\n unpinSlot(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n buf_pool_unpin_slot(this.pin_counts, slotIdx);\n }\n\n pinPage(pageId: number): void {\n this.validate_page_id(pageId);\n const slot = this.getResidentSlot(pageId);\n if (slot === -1) {\n throw new Error(\n `Cannot pin page ${pageId}: page is not resident in buffer pool`,\n );\n }\n this.pinSlot(slot);\n }\n\n unpinPage(pageId: number): void {\n this.validate_page_id(pageId);\n if (pageId === 1) return;\n const slot = this.getResidentSlot(pageId);\n if (slot !== -1) {\n this.unpinSlot(slot);\n }\n }\n\n forceUnpinSlot(slotIdx: number): void {\n this.validate_slot_idx(slotIdx);\n if (slotIdx === 0) return;\n this.pin_counts[slotIdx] = 0;\n }\n\n forceUnpinPage(pageId: number): void {\n this.validate_page_id(pageId);\n if (pageId <= 1) return;\n const slot = this.getResidentSlot(pageId);\n if (slot !== -1) {\n this.forceUnpinSlot(slot);\n }\n }\n\n isSlotPinned(slotIdx: number): boolean {\n this.validate_slot_idx(slotIdx);\n return buf_pool_is_pinned(this.pin_counts, slotIdx);\n }\n\n getPinCount(slotIdx: number): number {\n this.validate_slot_idx(slotIdx);\n return this.pin_counts[slotIdx];\n }\n\n getRefBit(slotIdx: number): number {\n this.validate_slot_idx(slotIdx);\n return this.ref_bits[slotIdx];\n }\n\n setRefBit(slotIdx: number, val: number): void {\n this.validate_slot_idx(slotIdx);\n this.ref_bits[slotIdx] = val ? 1 : 0;\n }\n\n allocArena(size: number): number {\n const aligned = (size + 7) & ~7;\n if (this.arena_offset + aligned > this.maxQueryMemory) {\n throw new QueryArenaExhaustedError();\n }\n const current = this.transientArenaOffset + this.arena_offset;\n this.arena_offset += aligned;\n return current;\n }\n resetArena(): void {\n if (this.arena_offset > 0) {\n memset(this.uint8, this.transientArenaOffset, 0, this.arena_offset);\n this.arena_offset = 0;\n }\n }\n getArenaOffset(): number {\n return this.arena_offset;\n }\n\n // ==========================================================================\n // Asynchronous Page Acquisition & Eviction Coordination\n // ==========================================================================\n\n async acquirePage(page_id: number, pin: boolean = false): Promise<number> {\n this.validate_page_id(page_id);\n\n // Fast Path: Cache Hit\n const existing_slot = this.getResidentSlot(page_id);\n if (existing_slot !== -1) {\n this.setRefBit(existing_slot, 1);\n if (pin) {\n this.pinSlot(existing_slot);\n }\n return existing_slot;\n }\n\n // Coalesce concurrent in-flight acquires for the same page_id\n const existing_acquire = this.in_flight_acquires.get(page_id);\n if (existing_acquire) {\n const slot = await existing_acquire;\n if (pin) {\n this.pinSlot(slot);\n }\n return slot;\n }\n\n const acquire_promise = (async () => {\n // Core Engine FFI: Core selects candidate slot via Clock sweep and determines flushPageId\n const { candidate_slot, flush_page_id, next_clock_hand } =\n buf_pool_select_eviction_victim(\n this.buffer,\n this.ref_bits,\n this.pin_counts,\n this.slotToPageOffset,\n this.dirtyMaskOffset,\n this.slotCount,\n this.clock_hand,\n page_id,\n );\n this.clock_hand = next_clock_hand;\n\n // Pin candidate slot so concurrent eviction cannot steal it during async I/O\n this.pinSlot(candidate_slot);\n\n try {\n // Resolve PAGE_FAULT via pure Block I/O\n await this.io.resolvePageFault(candidate_slot, page_id, flush_page_id);\n\n // Update slot mappings\n this.assignSlot(candidate_slot, page_id);\n this.setRefBit(candidate_slot, 1);\n this.clearDirty(candidate_slot);\n\n return candidate_slot;\n } catch (err) {\n if (candidate_slot !== -1) {\n this.unpinSlot(candidate_slot);\n }\n throw err;\n }\n })();\n\n this.in_flight_acquires.set(page_id, acquire_promise);\n\n try {\n const slot = await acquire_promise;\n if (!pin) {\n this.unpinSlot(slot);\n }\n return slot;\n } finally {\n this.in_flight_acquires.delete(page_id);\n }\n }\n\n acquireAndPinPage(page_id: number): Promise<number> {\n return this.acquirePage(page_id, true);\n }\n\n async flushSlot(slot_idx: number): Promise<void> {\n this.validate_slot_idx(slot_idx);\n const page_id = this.getAssignedPage(slot_idx);\n if (page_id === 0) return;\n\n if (slot_idx === 0 && page_id !== 1) {\n throw new Error(\n `Corruption detected: slot 0 is assigned to page ${page_id} instead of page 1`,\n );\n }\n\n const generation_at_flush = this.slot_dirty_generations[slot_idx];\n await this.io.writeSlot(slot_idx, page_id);\n\n if (this.slot_dirty_generations[slot_idx] === generation_at_flush) {\n this.clearDirty(slot_idx);\n }\n }\n\n async flushPage(page_id: number): Promise<void> {\n this.validate_page_id(page_id);\n const slot = this.getResidentSlot(page_id);\n if (slot !== -1 && this.isDirty(slot)) {\n await this.flushSlot(slot);\n }\n }\n\n async flushAllDirty(): Promise<void> {\n for (let i = 0; i < this.slotCount; i++) {\n if (this.isDirty(i)) {\n await this.flushSlot(i);\n }\n }\n await this.io.flush();\n }\n\n async allocatePage(pin: boolean = false): Promise<number> {\n return this.with_allocation_lock(async () => {\n const page1_view = this.getSlotDataView(0);\n const free_head = read_u32(page1_view, HEADER_OFFSET_FREE_PAGE_HEAD);\n const current_total = read_u32(page1_view, HEADER_OFFSET_TOTAL_PAGES);\n\n if (free_head > 0) {\n if (\n free_head <= 1 ||\n (current_total > 0 && free_head > current_total)\n ) {\n throw new CorruptPageError(\n free_head,\n `Corrupted free_page_head pointer ${free_head} (totalPages: ${current_total})`,\n );\n }\n\n const slot = await this.acquirePage(free_head, pin);\n const free_page_view = this.getSlotDataView(slot);\n\n const page_type = read_u8(free_page_view, PAGE_HEADER_OFFSET_TYPE);\n if (page_type !== PAGE_TYPE_FREE) {\n throw new CorruptPageError(\n free_head,\n `Expected free page type 0x00, got 0x${page_type.toString(16)}`,\n );\n }\n\n const next_free_id = read_u32(\n free_page_view,\n PAGE_HEADER_OFFSET_NEXT_PAGE_ID,\n );\n if (\n next_free_id === free_head ||\n (current_total > 0 && next_free_id > current_total)\n ) {\n throw new CorruptPageError(\n free_head,\n `Corrupted next_free_page_id pointer ${next_free_id} in free page ${free_head}`,\n );\n }\n\n write_u32(page1_view, HEADER_OFFSET_FREE_PAGE_HEAD, next_free_id);\n this.markDirty(0);\n\n page_init(free_page_view, 0);\n this.markDirty(slot);\n\n return free_head;\n }\n\n const new_page_id = current_total + 1;\n write_u32(page1_view, HEADER_OFFSET_TOTAL_PAGES, new_page_id);\n this.markDirty(0);\n\n const slot = await this.acquirePage(new_page_id, pin);\n const new_page_view = this.getSlotDataView(slot);\n page_init(new_page_view, 0);\n this.markDirty(slot);\n\n return new_page_id;\n });\n }\n\n allocateAndPinPage(): Promise<number> {\n return this.allocatePage(true);\n }\n\n async freePage(page_id: number, force: boolean = false): Promise<void> {\n this.validate_page_id(page_id);\n\n if (page_id <= 1) {\n throw new Error(`Cannot free reserved database page ${page_id}`);\n }\n\n return this.with_allocation_lock(async () => {\n const page1_view = this.getSlotDataView(0);\n const current_total = read_u32(page1_view, HEADER_OFFSET_TOTAL_PAGES);\n if (current_total > 0 && page_id > current_total) {\n throw new Error(\n `Cannot free page ${page_id} beyond total pages ${current_total}`,\n );\n }\n\n const existing_slot = this.getResidentSlot(page_id);\n if (existing_slot !== -1) {\n if (force) {\n this.forceUnpinSlot(existing_slot);\n } else if (this.isSlotPinned(existing_slot)) {\n throw new Error(`Cannot free pinned/active database page ${page_id}`);\n }\n }\n\n const slot = await this.acquirePage(page_id, true);\n try {\n const view = this.getSlotDataView(slot);\n const page_type = page_get_type(view, 0);\n if (page_type === PAGE_TYPE_FREE) {\n this.unassignSlot(slot);\n if (force) {\n return;\n }\n throw new Error(\n `Double-free detected: page ${page_id} is already marked free`,\n );\n }\n if (!force && page_type === PAGE_TYPE_CATALOG_PAGE) {\n throw new Error(`Cannot free system catalog page ${page_id}`);\n }\n\n const old_head = read_u32(page1_view, HEADER_OFFSET_FREE_PAGE_HEAD);\n\n page_init_free(view, 0, old_head);\n\n memset(\n this.uint8,\n slot * PAGE_SIZE + PAGE_HEADER_SIZE,\n 0,\n PAGE_SIZE - PAGE_HEADER_SIZE,\n );\n\n if (this.io.isInTransaction()) {\n await this.io.spillOrWriteSlot(slot, page_id);\n } else {\n await this.flushSlot(slot);\n }\n\n this.unassignSlot(slot);\n this.clearDirty(slot);\n this.setRefBit(slot, 0);\n\n write_u32(page1_view, HEADER_OFFSET_FREE_PAGE_HEAD, page_id);\n this.markDirty(0);\n } finally {\n this.unpinSlot(slot);\n }\n });\n }\n\n /**\n * Drives the VDBE VM step loop, handling STATUS_PAGE_FAULT until completion.\n */\n async stepVm(ctx: VmContext, bytecode: Uint8Array): Promise<VmStatus> {\n let status = vm_step(ctx, this.view, bytecode);\n while (status === VmStatus.PAGE_FAULT) {\n const faultPageId = ctx.cursor.pageId;\n await this.acquirePage(faultPageId);\n ctx.status = VmStatus.RUNNING;\n status = vm_step(ctx, this.view, bytecode);\n }\n return status;\n }\n}\n","import { IVfsAdapter } from '../storage/vfs.js';\nimport {\n decodeWalFileHeader,\n validateWalFrame,\n} from '../storage/wal_codec.js';\nimport {\n WAL_FRAME_HEADER_SIZE,\n WAL_FRAME_TYPE_PAGE_DATA,\n WAL_FRAME_TYPE_TX_COMMIT,\n WAL_FRAME_TYPE_TX_UNCOMMITTED,\n} from '../../constants.js';\n\nexport interface RecoveryResult {\n frameCount: number;\n committedTxCount: number;\n abortedTxCount: number;\n replayedPageCount: number;\n}\n\n/**\n * Executes startup crash recovery against the VFS Write-Ahead Log.\n *\n * Algorithm (Phase 4 Specification - Section 6):\n * 1. Checks if WAL has frames. If empty, startup completes immediately.\n * 2. Validates 32-byte WAL file header. Throws CorruptWalHeaderError on corruption.\n * 3. Reads frames sequentially. Detects truncated tails and stops cleanly at first\n * corrupt or torn frame (CRC32 mismatch or magic mismatch).\n * 4. Groups frames by tx_id and identifies which transactions reached durable FRAME_TX_COMMIT.\n * 5. Discards uncommitted transaction groups.\n * 6. Deduplicates committed frames (latest page version per page_id) and applies them\n * to the main database file via vfs.writePages(...).\n * 7. Flushes the main storage durably via vfs.flush().\n * 8. Truncates the WAL to 0 via vfs.truncateWal(0).\n */\nexport async function recoverFromWal(vfs: IVfsAdapter): Promise<RecoveryResult> {\n const frameCount = await vfs.getWalFrameCount();\n if (frameCount === 0) {\n return {\n frameCount: 0,\n committedTxCount: 0,\n abortedTxCount: 0,\n replayedPageCount: 0,\n };\n }\n\n // Step 1: Validate WAL file header\n const headerBytes = await vfs.readWalHeader();\n if (!headerBytes) {\n // If frames exist but header is missing, reset WAL to 0\n await vfs.truncateWal(0);\n return {\n frameCount: 0,\n committedTxCount: 0,\n abortedTxCount: 0,\n replayedPageCount: 0,\n };\n }\n\n // decodeWalFileHeader verifies magic \"WEBWAL\" and CRC32.\n // If a crash occurred while initializing the 32-byte WAL header itself, discard the invalid WAL.\n try {\n decodeWalFileHeader(headerBytes, true);\n } catch (err) {\n await vfs.truncateWal(0);\n return {\n frameCount: 0,\n committedTxCount: 0,\n abortedTxCount: 0,\n replayedPageCount: 0,\n };\n }\n\n // Step 2: Linear frame iteration & validation\n const rawFrames = await vfs.readWalFrames(0, frameCount);\n \n // Group frames by tx_id in chronological order\n const txGroups = new Map<number, Array<{ pageId: number; data: Uint8Array; frameType: number }>>();\n const committedTxIds = new Set<number>();\n let validFramesProcessed = 0;\n\n for (const frameBytes of rawFrames) {\n const validation = validateWalFrame(frameBytes);\n if (!validation.valid || !validation.header) {\n // Truncated tail or torn write detected; halt scanning immediately.\n // Trailing incomplete bytes or corrupted frames are discarded.\n break;\n }\n\n const { header } = validation;\n if (header.frameSeq !== validFramesProcessed + 1) {\n // Out-of-sequence or stale frame from a prior checkpoint cycle; stop scanning immediately.\n break;\n }\n validFramesProcessed++;\n\n if (!txGroups.has(header.txId)) {\n txGroups.set(header.txId, []);\n }\n\n if (header.frameType === WAL_FRAME_TYPE_TX_COMMIT) {\n committedTxIds.add(header.txId);\n } else if (\n header.frameType === WAL_FRAME_TYPE_PAGE_DATA ||\n header.frameType === WAL_FRAME_TYPE_TX_UNCOMMITTED\n ) {\n const pageData = new Uint8Array(\n frameBytes.buffer,\n frameBytes.byteOffset + WAL_FRAME_HEADER_SIZE,\n 4096,\n );\n // Copy page data so it is independent of frame buffer\n const pageCopy = new Uint8Array(4096);\n pageCopy.set(pageData);\n\n txGroups.get(header.txId)!.push({\n pageId: header.pageId,\n data: pageCopy,\n frameType: header.frameType,\n });\n }\n }\n\n // Step 3 & 4: Transaction commit filter & Deduplicated Apply\n // Collect latest committed bytes per page_id\n const latestPages = new Map<number, Uint8Array>();\n let committedTxCount = 0;\n let abortedTxCount = 0;\n\n for (const [txId, frames] of txGroups.entries()) {\n if (committedTxIds.has(txId)) {\n committedTxCount++;\n for (const frame of frames) {\n if (frame.pageId > 0) {\n latestPages.set(frame.pageId, frame.data);\n }\n }\n } else {\n abortedTxCount++;\n }\n }\n\n // Step 4: Apply committed pages to main storage\n if (latestPages.size > 0) {\n const pagesToWrite: Array<{ pageId: number; data: Uint8Array }> = [];\n for (const [pageId, data] of latestPages.entries()) {\n pagesToWrite.push({ pageId, data });\n }\n // Sort pages in ascending pageId order for sequential write locality\n pagesToWrite.sort((a, b) => a.pageId - b.pageId);\n await vfs.writePages(pagesToWrite);\n }\n\n // Step 5: Flush main storage and truncate WAL\n await vfs.flush();\n await vfs.truncateWal(0);\n\n return {\n frameCount: validFramesProcessed,\n committedTxCount,\n abortedTxCount,\n replayedPageCount: latestPages.size,\n };\n}\n","import { IVfsAdapter } from '../storage/vfs.js';\nimport { Io } from '../storage/io.js';\nimport { BufferPoolDriver } from './buffer_pool_driver.js';\nimport { recoverFromWal } from './crash_recovery.js';\nimport {\n decodeWalFileHeader,\n encodeWalFileHeader,\n encodeWalFrame,\n validateWalFrame,\n} from '../storage/wal_codec.js';\nimport {\n HEADER_OFFSET_CHANGE_COUNTER,\n HEADER_OFFSET_SCHEMA_VERSION,\n HEADER_OFFSET_TOTAL_PAGES,\n WAL_FRAME_HEADER_SIZE,\n WAL_FRAME_TYPE_PAGE_DATA,\n WAL_FRAME_TYPE_TX_COMMIT,\n WAL_FRAME_TYPE_TX_UNCOMMITTED,\n WAL_PAGE_SIZE,\n} from '../../constants.js';\n\nexport interface TransactionLease {\n readonly leaseId: number;\n readonly txId: number;\n readonly createdAt: number;\n}\n\n/**\n * Enforces the Exclusive Transaction Lease across asynchronous JavaScript microtask boundaries\n * and across concurrent browser tabs via the Web Locks API (navigator.locks).\n * While an exclusive lease is held by an active transaction, all external queries, mutations,\n * and checkpoint requests are strictly enqueued in FIFO order.\n */\nexport class ExclusiveLeaseQueue {\n private activeLease: TransactionLease | null = null;\n private inFlightNonTxCount = 0;\n private queue: Array<() => Promise<void>> = [];\n private leaseWaiters: Array<{ resolve: (lease: TransactionLease) => void }> = [];\n private nextLeaseId = 1;\n private nextTxId = 1;\n\n private crossTabLockName?: string;\n private onSyncCrossTab?: () => Promise<void>;\n private releaseWebLock: (() => void) | null = null;\n\n constructor(crossTabLockName?: string, onSyncCrossTab?: () => Promise<void>) {\n this.crossTabLockName = crossTabLockName;\n this.onSyncCrossTab = onSyncCrossTab;\n }\n\n hasWebLocks(): boolean {\n return (\n !!this.crossTabLockName &&\n typeof navigator !== 'undefined' &&\n typeof navigator?.locks?.request === 'function'\n );\n }\n\n private async acquireWebLock(): Promise<void> {\n if (!this.hasWebLocks() || this.releaseWebLock) return;\n await new Promise<void>((resolveAcquired) => {\n navigator.locks\n .request(this.crossTabLockName!, { mode: 'exclusive' }, () => {\n return new Promise<void>((resolveRelease) => {\n this.releaseWebLock = resolveRelease;\n resolveAcquired();\n });\n })\n .catch(() => {\n resolveAcquired();\n });\n });\n }\n\n private releaseCurrentWebLock(): void {\n if (this.releaseWebLock) {\n const rel = this.releaseWebLock;\n this.releaseWebLock = null;\n rel();\n }\n }\n\n get isLeased(): boolean {\n return this.activeLease !== null;\n }\n\n get currentLease(): TransactionLease | null {\n return this.activeLease;\n }\n\n /**\n * Enqueues or dispatches a task through the FIFO coordinator.\n * If task belongs to the active lease, it executes immediately without queuing.\n */\n async enqueue<T>(task: () => Promise<T>, leaseId?: number): Promise<T> {\n // If this call belongs to the active transaction lease, dispatch immediately!\n if (this.activeLease && leaseId === this.activeLease.leaseId) {\n return task();\n }\n\n // If an exclusive transaction lease is active, there are pending transaction waiters,\n // or (in cross-tab Web Locks mode) another non-tx task is currently holding the lock,\n // queue the external task in FIFO order.\n if (\n this.activeLease ||\n this.leaseWaiters.length > 0 ||\n (this.hasWebLocks() && this.inFlightNonTxCount > 0)\n ) {\n return new Promise<T>((resolve, reject) => {\n this.queue.push(async () => {\n this.inFlightNonTxCount++;\n try {\n if (this.hasWebLocks() && this.inFlightNonTxCount === 1) {\n await this.acquireWebLock();\n if (this.onSyncCrossTab) {\n await this.onSyncCrossTab();\n }\n }\n const res = await task();\n resolve(res);\n } catch (err) {\n reject(err);\n } finally {\n this.inFlightNonTxCount--;\n if (this.inFlightNonTxCount === 0 && !this.activeLease) {\n this.releaseCurrentWebLock();\n }\n this.drain();\n }\n });\n });\n }\n\n // Fast-path: no active lease or waiters; run immediately\n this.inFlightNonTxCount++;\n try {\n if (this.hasWebLocks() && this.inFlightNonTxCount === 1) {\n await this.acquireWebLock();\n if (this.onSyncCrossTab) {\n await this.onSyncCrossTab();\n }\n }\n return await task();\n } finally {\n this.inFlightNonTxCount--;\n if (this.inFlightNonTxCount === 0 && !this.activeLease) {\n this.releaseCurrentWebLock();\n }\n this.drain();\n }\n }\n\n /**\n * Acquires the Exclusive Transaction Lease.\n * Blocks until all in-flight non-transactional operations finish and acquires the cross-tab Web Lock.\n */\n async acquireExclusiveLease(): Promise<TransactionLease> {\n if (!this.activeLease && this.inFlightNonTxCount === 0 && this.queue.length === 0) {\n const lease: TransactionLease = {\n leaseId: this.nextLeaseId++,\n txId: this.nextTxId++,\n createdAt: Date.now(),\n };\n this.activeLease = lease;\n await this.acquireWebLock();\n return lease;\n }\n\n return new Promise<TransactionLease>((resolve) => {\n this.leaseWaiters.push({\n resolve: async (lease) => {\n await this.acquireWebLock();\n resolve(lease);\n },\n });\n this.drain();\n });\n }\n\n /**\n * Releases the Exclusive Transaction Lease, releases the cross-tab Web Lock, and drains pending operations.\n */\n releaseExclusiveLease(leaseId: number): void {\n if (!this.activeLease || this.activeLease.leaseId !== leaseId) {\n return;\n }\n this.activeLease = null;\n this.releaseCurrentWebLock();\n this.drain();\n }\n\n private drain(): void {\n if (this.activeLease) {\n return;\n }\n\n // If there is a transaction waiter waiting to acquire the lease:\n if (this.leaseWaiters.length > 0) {\n // Must wait until all current in-flight non-tx queries finish\n if (this.inFlightNonTxCount === 0) {\n const waiter = this.leaseWaiters.shift()!;\n const lease: TransactionLease = {\n leaseId: this.nextLeaseId++,\n txId: this.nextTxId++,\n createdAt: Date.now(),\n };\n this.activeLease = lease;\n waiter.resolve(lease);\n }\n return;\n }\n\n // Drain queued external non-transaction tasks\n while (\n this.queue.length > 0 &&\n !this.activeLease &&\n this.leaseWaiters.length === 0 &&\n (!this.hasWebLocks() || this.inFlightNonTxCount === 0)\n ) {\n const nextTask = this.queue.shift();\n if (nextTask) {\n nextTask();\n }\n }\n }\n}\n\n/**\n * TransactionCoordinator orchestrates:\n * 1. Exclusive Transaction Lease & FIFO async dispatch.\n * 2. Write-Ahead Log (WAL) frame generation & durability flush on COMMIT.\n * 3. Cache spilling of uncommitted pages under memory pressure (FRAME_TX_UNCOMMITTED).\n * 4. Zero-mutation rollback on abort (memory restoration & WAL truncation).\n * 5. Deduplicated Monotonic Checkpointing to synchronize main storage.\n */\nexport class TransactionCoordinator {\n private vfs: IVfsAdapter;\n private pool: BufferPoolDriver;\n private io: Io;\n private queue: ExclusiveLeaseQueue;\n\n private activeLease: TransactionLease | null = null;\n private snapshotFrameCount = 0;\n private snapshotWalFrameSeq = 0;\n private slotSnapshots = new Map<number, { pageId: number; dirty: boolean; data: Uint8Array }>();\n private pinCountsSnapshot: Uint32Array | null = null;\n private spilledPages = new Map<number, Uint8Array>();\n private committedWalPages = new Map<number, Uint8Array>();\n private walFrameSeq = 0;\n private txCommitCount = 0;\n private checkpointSeq = 0;\n\n // Cross-tab state tracking\n private instanceSalt = (Math.floor(Math.random() * 0xffffffff) >>> 0) || 1;\n private expectedWalFrameCount = 0;\n private lastDiskChangeCounter = 0;\n private lastDiskSchemaVersion = 0;\n private onCrossTabInvalidated?: () => Promise<void>;\n\n // Inactivity idle checkpoint timer (5 seconds)\n private idleTimer: any = null;\n private isClosed = false;\n\n constructor(\n vfs: IVfsAdapter,\n pool: BufferPoolDriver,\n io: Io,\n crossTabLockName?: string,\n ) {\n this.vfs = vfs;\n this.pool = pool;\n this.io = io;\n this.queue = new ExclusiveLeaseQueue(\n crossTabLockName,\n () => this.syncCrossTabState(),\n );\n }\n\n setOnCrossTabInvalidated(cb: () => Promise<void>): void {\n this.onCrossTabInvalidated = cb;\n }\n\n recordDiskPage1State(): void {\n const view = this.pool.getSlotDataView(0);\n this.lastDiskChangeCounter = view.getUint32(HEADER_OFFSET_CHANGE_COUNTER, true);\n this.lastDiskSchemaVersion = view.getUint32(HEADER_OFFSET_SCHEMA_VERSION, true);\n }\n\n private async reloadFromDisk(\n diskPage1: Uint8Array,\n diskChangeCounter: number,\n diskSchemaVersion: number,\n ): Promise<void> {\n this.pool.getPageBytesInSlot(0).set(diskPage1);\n this.pool.clearDirty(0);\n this.lastDiskChangeCounter = diskChangeCounter;\n this.lastDiskSchemaVersion = diskSchemaVersion;\n\n for (let slot = 1; slot < this.pool.slotCount; slot++) {\n this.pool.unassignSlot(slot);\n this.pool.clearDirty(slot);\n this.pool.pin_counts[slot] = 0;\n }\n this.pool.pin_counts[0] = 1;\n\n if (this.onCrossTabInvalidated) {\n await this.onCrossTabInvalidated();\n }\n }\n\n async syncCrossTabState(force: boolean = false): Promise<void> {\n if (!force && !this.queue.hasWebLocks()) return;\n\n const walFrameCount = await this.vfs.getWalFrameCount();\n let walTouchedByOtherTab = false;\n\n if (walFrameCount > 0) {\n const headerBytes = await this.vfs.readWalHeader();\n let headerSalt = 0;\n if (headerBytes) {\n try {\n headerSalt = decodeWalFileHeader(headerBytes, true).salt1;\n } catch {\n headerSalt = 0;\n }\n }\n if (headerSalt !== this.instanceSalt || walFrameCount !== this.expectedWalFrameCount) {\n walTouchedByOtherTab = true;\n await recoverFromWal(this.vfs);\n this.committedWalPages.clear();\n this.walFrameSeq = 0;\n this.txCommitCount = 0;\n this.expectedWalFrameCount = 0;\n }\n } else if (this.expectedWalFrameCount > 0) {\n walTouchedByOtherTab = true;\n this.committedWalPages.clear();\n this.walFrameSeq = 0;\n this.txCommitCount = 0;\n this.expectedWalFrameCount = 0;\n }\n\n const diskPage1 = await this.vfs.readPage(1);\n if (diskPage1) {\n const diskView = new DataView(diskPage1.buffer, diskPage1.byteOffset, diskPage1.byteLength);\n const diskChangeCounter = diskView.getUint32(HEADER_OFFSET_CHANGE_COUNTER, true);\n const diskSchemaVersion = diskView.getUint32(HEADER_OFFSET_SCHEMA_VERSION, true);\n\n if (\n walTouchedByOtherTab ||\n diskChangeCounter !== this.lastDiskChangeCounter ||\n diskSchemaVersion !== this.lastDiskSchemaVersion\n ) {\n await this.reloadFromDisk(diskPage1, diskChangeCounter, diskSchemaVersion);\n }\n }\n }\n\n get leaseQueue(): ExclusiveLeaseQueue {\n return this.queue;\n }\n\n isInTransaction(): boolean {\n return this.activeLease !== null;\n }\n\n getActiveLeaseId(): number | null {\n return this.activeLease ? this.activeLease.leaseId : null;\n }\n\n getActiveTxId(): number | null {\n return this.activeLease ? this.activeLease.txId : null;\n }\n\n hasSpilledPage(pageId: number): boolean {\n return this.spilledPages.has(pageId) || this.committedWalPages.has(pageId);\n }\n\n getSpilledPage(pageId: number): Uint8Array | null {\n const data = this.spilledPages.get(pageId) ?? this.committedWalPages.get(pageId);\n return data ? new Uint8Array(data) : null;\n }\n\n onDirectPageWrite(pageId: number, data: Uint8Array): void {\n if (this.committedWalPages.has(pageId)) {\n this.committedWalPages.set(pageId, new Uint8Array(data));\n }\n if (pageId === 1) {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n this.lastDiskChangeCounter = view.getUint32(HEADER_OFFSET_CHANGE_COUNTER, true);\n this.lastDiskSchemaVersion = view.getUint32(HEADER_OFFSET_SCHEMA_VERSION, true);\n }\n }\n\n /**\n * Spills an uncommitted dirty slot to the WAL under cache eviction pressure.\n * Frame type is set to FRAME_TX_UNCOMMITTED (0x0003).\n */\n async spillUncommittedSlot(slotIdx: number, pageId: number): Promise<void> {\n if (!this.activeLease) {\n // Not in transaction; normal write directly to storage\n await this.io.writeSlot(slotIdx, pageId);\n return;\n }\n\n this.io.stampSlotChecksum(slotIdx, pageId);\n\n const slotBytes = this.pool.getPageBytesInSlot(slotIdx);\n const pageCopy = new Uint8Array(WAL_PAGE_SIZE);\n pageCopy.set(slotBytes);\n\n this.spilledPages.set(pageId, pageCopy);\n\n const dbSizePages = this.pool.getSlotDataView(0).getUint32(HEADER_OFFSET_TOTAL_PAGES, true);\n\n // Append FRAME_TX_UNCOMMITTED frame to WAL\n const frame = encodeWalFrame(\n {\n frameType: WAL_FRAME_TYPE_TX_UNCOMMITTED,\n flags: 0,\n txId: this.activeLease.txId,\n pageId,\n dbSizePages,\n frameSeq: ++this.walFrameSeq,\n },\n pageCopy,\n );\n\n await this.vfs.appendWalFrames([frame]);\n this.expectedWalFrameCount = await this.vfs.getWalFrameCount();\n }\n\n /**\n * Captures a point-in-time snapshot of the buffer pool, spilled pages, and WAL frame count.\n * Used both at transaction BEGIN and for nested savepoints.\n */\n async captureSavepoint(): Promise<{\n frameCount: number;\n slotSnapshots: Map<number, { pageId: number; dirty: boolean; data: Uint8Array }>;\n pinCounts: Uint32Array;\n spilledPages: Map<number, Uint8Array>;\n walFrameSeq: number;\n }> {\n const frameCount = await this.vfs.getWalFrameCount();\n const slotSnapshots = new Map<number, { pageId: number; dirty: boolean; data: Uint8Array }>();\n for (let slot = 0; slot < this.pool.slotCount; slot++) {\n const pageId = this.pool.getAssignedPage(slot);\n if (pageId > 0) {\n const dirty = this.pool.isDirty(slot);\n const data = new Uint8Array(this.pool.getPageBytesInSlot(slot));\n slotSnapshots.set(slot, { pageId, dirty, data });\n }\n }\n const pinCounts = new Uint32Array(this.pool.pin_counts);\n const spilledPages = new Map<number, Uint8Array>();\n for (const [k, v] of this.spilledPages.entries()) {\n spilledPages.set(k, new Uint8Array(v));\n }\n return {\n frameCount,\n slotSnapshots,\n pinCounts,\n spilledPages,\n walFrameSeq: this.walFrameSeq,\n };\n }\n\n /**\n * Restores buffer pool slots, pin counts, spilled pages, and truncates WAL back to a savepoint.\n */\n async restoreSavepoint(savepoint: {\n frameCount: number;\n slotSnapshots: Map<number, { pageId: number; dirty: boolean; data: Uint8Array }>;\n pinCounts: Uint32Array;\n spilledPages: Map<number, Uint8Array>;\n walFrameSeq: number;\n }): Promise<void> {\n // Pass 1: Unassign all non-zero slots first to avoid page-to-slot collision if a page moved slots\n for (let slot = 1; slot < this.pool.slotCount; slot++) {\n this.pool.unassignSlot(slot);\n this.pool.clearDirty(slot);\n }\n\n // Pass 2: Restore slot assignments, page data, and dirty flags\n for (let slot = 0; slot < this.pool.slotCount; slot++) {\n const snap = savepoint.slotSnapshots.get(slot);\n if (snap) {\n this.pool.assignSlot(slot, snap.pageId);\n this.pool.getPageBytesInSlot(slot).set(snap.data);\n if (snap.dirty) {\n this.pool.markDirty(slot);\n } else {\n this.pool.clearDirty(slot);\n }\n }\n }\n\n // Pass 3: Restore pin counts\n this.pool.pin_counts.set(savepoint.pinCounts);\n\n // Restore spilled pages & WAL length\n this.spilledPages.clear();\n for (const [k, v] of savepoint.spilledPages.entries()) {\n this.spilledPages.set(k, new Uint8Array(v));\n }\n this.walFrameSeq = savepoint.walFrameSeq;\n await this.vfs.truncateWal(savepoint.frameCount);\n this.expectedWalFrameCount = savepoint.frameCount;\n }\n\n /**\n * Begins an explicit transaction:\n * 1. Acquires exclusive lease on the async queue (and cross-tab Web Lock).\n * 2. Synchronizes cross-tab storage state if another tab modified .db / .wal.\n * 3. Snapshots resident buffer pool slots and current WAL frame count.\n * 4. Pauses idle checkpoint timer.\n */\n async begin(): Promise<TransactionLease> {\n const lease = await this.queue.acquireExclusiveLease();\n this.activeLease = lease;\n this.pauseIdleTimer();\n\n try {\n await this.syncCrossTabState();\n\n // Ensure WAL header is initialized with this instance's salt\n const currentFrames = await this.vfs.getWalFrameCount();\n const existingHeader = await this.vfs.readWalHeader();\n let headerValid = false;\n if (existingHeader && currentFrames > 0) {\n try {\n const decoded = decodeWalFileHeader(existingHeader, true);\n headerValid = decoded.salt1 === this.instanceSalt;\n } catch {\n headerValid = false;\n }\n }\n if (!headerValid) {\n await this.vfs.writeWalHeader(\n encodeWalFileHeader({\n checkpointSeq: this.checkpointSeq,\n salt1: this.instanceSalt,\n }),\n );\n }\n\n this.spilledPages.clear();\n const snap = await this.captureSavepoint();\n this.snapshotFrameCount = snap.frameCount;\n this.snapshotWalFrameSeq = snap.walFrameSeq;\n this.slotSnapshots = snap.slotSnapshots;\n this.pinCountsSnapshot = snap.pinCounts;\n\n return lease;\n } catch (err) {\n this.activeLease = null;\n this.queue.releaseExclusiveLease(lease.leaseId);\n throw err;\n }\n }\n\n /**\n * Commits an active transaction:\n * 1. Collects all dirty slots in memory and appends them as FRAME_PAGE_DATA frames to the WAL.\n * 2. Appends a FRAME_TX_COMMIT marker frame.\n * 3. Calls vfs.flushWal() to establish durable commit point.\n * 4. Releases the exclusive lease.\n */\n async commit(leaseId: number): Promise<void> {\n if (!this.activeLease || this.activeLease.leaseId !== leaseId) {\n return;\n }\n\n const txId = this.activeLease.txId;\n const framesToAppend: Uint8Array[] = [];\n const dbSizePages = this.pool.getSlotDataView(0).getUint32(HEADER_OFFSET_TOTAL_PAGES, true);\n\n // Promote any spilled pages from this transaction into committedWalPages first\n for (const [pageId, data] of this.spilledPages.entries()) {\n this.committedWalPages.set(pageId, data);\n }\n\n // Append all resident dirty pages to WAL as FRAME_PAGE_DATA frames\n for (let slot = 0; slot < this.pool.slotCount; slot++) {\n if (this.pool.isDirty(slot)) {\n const pageId = this.pool.getAssignedPage(slot);\n if (pageId > 0) {\n this.io.stampSlotChecksum(slot, pageId);\n\n const pageBytes = this.pool.getPageBytesInSlot(slot);\n const pageCopy = new Uint8Array(WAL_PAGE_SIZE);\n pageCopy.set(pageBytes);\n\n this.committedWalPages.set(pageId, pageCopy);\n this.pool.clearDirty(slot);\n\n framesToAppend.push(\n encodeWalFrame(\n {\n frameType: WAL_FRAME_TYPE_PAGE_DATA,\n flags: 0,\n txId,\n pageId,\n dbSizePages,\n frameSeq: ++this.walFrameSeq,\n },\n pageCopy,\n ),\n );\n }\n }\n }\n\n // Append FRAME_TX_COMMIT marker\n framesToAppend.push(\n encodeWalFrame({\n frameType: WAL_FRAME_TYPE_TX_COMMIT,\n flags: 0,\n txId,\n pageId: 0,\n dbSizePages,\n frameSeq: ++this.walFrameSeq,\n }),\n );\n\n // Durably write WAL frames\n await this.vfs.appendWalFrames(framesToAppend);\n await this.vfs.flushWal();\n const currentFrames = await this.vfs.getWalFrameCount();\n this.expectedWalFrameCount = currentFrames;\n\n // Cleanup active transaction state\n this.activeLease = null;\n this.spilledPages.clear();\n this.slotSnapshots.clear();\n this.pinCountsSnapshot = null;\n this.txCommitCount++;\n\n // Release lease to unblock queued external operations\n this.queue.releaseExclusiveLease(leaseId);\n this.scheduleIdleTimer();\n\n // Check passive checkpoint size trigger (> 256 frames or 100 txs)\n if (currentFrames >= 256 || this.txCommitCount >= 100) {\n // Trigger checkpoint asynchronously in queue without blocking caller\n this.queue.enqueue(() => this.executeCheckpoint());\n }\n }\n\n /**\n * Rolls back an active transaction:\n * 1. Restores buffer pool slots to their snapshot state at BEGIN.\n * 2. Clears spilled uncommitted page cache.\n * 3. Truncates WAL back to the initial snapshot frame count.\n * 4. Releases the exclusive lease.\n */\n async rollback(leaseId: number): Promise<void> {\n if (!this.activeLease || this.activeLease.leaseId !== leaseId) {\n return;\n }\n\n await this.restoreSavepoint({\n frameCount: this.snapshotFrameCount,\n slotSnapshots: this.slotSnapshots,\n pinCounts: this.pinCountsSnapshot ?? new Uint32Array(this.pool.pin_counts),\n spilledPages: new Map(),\n walFrameSeq: this.snapshotWalFrameSeq,\n });\n\n this.activeLease = null;\n this.spilledPages.clear();\n this.slotSnapshots.clear();\n this.pinCountsSnapshot = null;\n\n this.queue.releaseExclusiveLease(leaseId);\n this.scheduleIdleTimer();\n }\n\n /**\n * Deduplicated Monotonic Checkpoint (Section 4.3):\n * 1. Scans committed WAL frames chronologically -> wal_index.\n * 2. Inspects resident dirty slots in memory -> memory_override.\n * 3. Merges union of unique page_ids and writes to main storage via vfs.writePages().\n * 4. Calls vfs.flush() to durably sync main disk.\n * 5. Strictly AFTER vfs.flush() succeeds, truncates WAL to 0.\n */\n async checkpoint(): Promise<{ pagesWritten: number }> {\n // Checkpointing CANNOT run while a write transaction is open.\n // Enqueue through the exclusive lease queue so it waits for lease release.\n return this.queue.enqueue(() => this.executeCheckpoint());\n }\n\n async executeCheckpoint(): Promise<{ pagesWritten: number }> {\n const frameCount = await this.vfs.getWalFrameCount();\n\n // 1. Scan WAL frames chronologically\n const walIndex = new Map<number, Uint8Array>();\n if (frameCount > 0) {\n const rawFrames = await this.vfs.readWalFrames(0, frameCount);\n const txGroups = new Map<number, Array<{ pageId: number; data: Uint8Array }>>();\n const committedTxs = new Set<number>();\n\n for (const frameBytes of rawFrames) {\n const validation = validateWalFrame(frameBytes);\n if (!validation.valid || !validation.header) {\n break;\n }\n const { frameType, txId, pageId } = validation.header;\n\n if (!txGroups.has(txId)) txGroups.set(txId, []);\n\n if (frameType === WAL_FRAME_TYPE_TX_COMMIT) {\n committedTxs.add(txId);\n } else if (\n frameType === WAL_FRAME_TYPE_PAGE_DATA ||\n frameType === WAL_FRAME_TYPE_TX_UNCOMMITTED\n ) {\n const pageData = new Uint8Array(\n frameBytes.buffer,\n frameBytes.byteOffset + WAL_FRAME_HEADER_SIZE,\n WAL_PAGE_SIZE,\n );\n const copy = new Uint8Array(WAL_PAGE_SIZE);\n copy.set(pageData);\n txGroups.get(txId)!.push({ pageId, data: copy });\n }\n }\n\n for (const [txId, frames] of txGroups.entries()) {\n if (committedTxs.has(txId)) {\n for (const f of frames) {\n if (f.pageId > 0) {\n walIndex.set(f.pageId, f.data);\n }\n }\n }\n }\n }\n\n for (const [pageId, data] of this.committedWalPages.entries()) {\n walIndex.set(pageId, data);\n }\n\n // 2. Inspect resident dirty slots in memory (memory_override)\n const memoryOverride = new Map<number, { slotIdx: number; data: Uint8Array }>();\n for (let slot = 0; slot < this.pool.slotCount; slot++) {\n if (this.pool.isDirty(slot)) {\n const pageId = this.pool.getAssignedPage(slot);\n if (pageId > 0) {\n this.io.stampSlotChecksum(slot, pageId);\n const pageData = this.pool.getPageBytesInSlot(slot);\n const copy = new Uint8Array(WAL_PAGE_SIZE);\n copy.set(pageData);\n memoryOverride.set(pageId, { slotIdx: slot, data: copy });\n }\n }\n }\n\n // 3. Union of unique page IDs: memory overrides WAL\n const allPageIds = new Set<number>([\n ...walIndex.keys(),\n ...memoryOverride.keys(),\n ]);\n\n const pagesToWrite: Array<{ pageId: number; data: Uint8Array }> = [];\n for (const pageId of allPageIds) {\n if (memoryOverride.has(pageId)) {\n const { slotIdx, data } = memoryOverride.get(pageId)!;\n pagesToWrite.push({ pageId, data });\n this.pool.clearDirty(slotIdx);\n } else {\n pagesToWrite.push({ pageId, data: walIndex.get(pageId)! });\n }\n }\n\n if (pagesToWrite.length > 0) {\n pagesToWrite.sort((a, b) => a.pageId - b.pageId);\n await this.vfs.writePages(pagesToWrite);\n }\n\n // 4. Durably flush main storage\n await this.vfs.flush();\n\n // 5. Strictly AFTER flush succeeds, reset WAL to 0 and clear in-memory WAL page cache\n await this.vfs.truncateWal(0);\n this.committedWalPages.clear();\n\n // Increment checkpoint counter and re-write clean WAL file header\n this.checkpointSeq++;\n this.walFrameSeq = 0;\n this.txCommitCount = 0;\n this.expectedWalFrameCount = 0;\n this.recordDiskPage1State();\n await this.vfs.writeWalHeader(\n encodeWalFileHeader({\n checkpointSeq: this.checkpointSeq,\n salt1: this.instanceSalt,\n }),\n );\n\n return { pagesWritten: pagesToWrite.length };\n }\n\n async resetWalAfterImport(): Promise<void> {\n this.spilledPages.clear();\n this.committedWalPages.clear();\n await this.vfs.truncateWal(0);\n this.checkpointSeq++;\n this.walFrameSeq = 0;\n this.txCommitCount = 0;\n this.expectedWalFrameCount = 0;\n this.recordDiskPage1State();\n await this.vfs.writeWalHeader(\n encodeWalFileHeader({\n checkpointSeq: this.checkpointSeq,\n salt1: this.instanceSalt,\n }),\n );\n }\n\n private scheduleIdleTimer(): void {\n if (this.isClosed) return;\n this.pauseIdleTimer();\n this.idleTimer = setTimeout(() => {\n this.checkpoint().catch(() => {});\n }, 5000);\n }\n\n private pauseIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer);\n this.idleTimer = null;\n }\n }\n\n async close(): Promise<void> {\n this.isClosed = true;\n this.pauseIdleTimer();\n // Execute final clean checkpoint before closing handles\n await this.checkpoint();\n }\n}\n","import {\n AggregateNotAllowedInWhereError,\n UnknownFunctionError,\n DbRow,\n} from '../../types/index.js';\nimport { sql_like_match } from '../../core/js/vm.helpers.c.js';\n\nexport type BinaryOp =\n | '+'\n | '-'\n | '*'\n | '/'\n | '%'\n | '='\n | '!='\n | '<'\n | '<='\n | '>'\n | '>=';\n\nexport type ExprNode =\n | { type: 'col'; name: string }\n | { type: 'literal'; value: number | string | boolean | null }\n | { type: 'binary'; op: BinaryOp; left: ExprNode; right: ExprNode }\n | { type: 'fn'; name: string; args: ExprNode[] };\n\nexport interface ParsedSelectExpr {\n expr: ExprNode;\n alias: string;\n}\n\nexport const BUILTIN_AGGREGATES = new Set(['count', 'sum', 'avg', 'min', 'max']);\n\nexport const BUILTIN_SCALARS = new Set([\n 'upper',\n 'lower',\n 'length',\n 'substr',\n 'trim',\n 'abs',\n 'round',\n 'floor',\n 'ceil',\n 'concat',\n 'coalesce',\n]);\n\nexport function isAggregateFunction(name: string): boolean {\n return BUILTIN_AGGREGATES.has(name.toLowerCase());\n}\n\nexport function isBuiltinScalarFunction(name: string): boolean {\n return BUILTIN_SCALARS.has(name.toLowerCase());\n}\n\nexport function isBuiltinFunction(name: string): boolean {\n return isAggregateFunction(name) || isBuiltinScalarFunction(name);\n}\n\nexport function validateClause(\n expr: ExprNode,\n clause: 'select' | 'where' | 'having' | 'orderBy',\n): void {\n if (clause === 'where') {\n if (expr.type === 'fn' && isAggregateFunction(expr.name)) {\n throw new AggregateNotAllowedInWhereError(expr.name);\n }\n if (expr.type === 'binary') {\n validateClause(expr.left, clause);\n validateClause(expr.right, clause);\n }\n if (expr.type === 'fn') {\n for (const arg of expr.args) {\n validateClause(arg, clause);\n }\n }\n }\n}\n\n// -------------------------------------------------------------\n// Tokenizer & Pratt Parser for SQL Expressions\n// -------------------------------------------------------------\n\ntype TokenType =\n | 'IDENT'\n | 'NUMBER'\n | 'STRING'\n | 'OP'\n | 'LPAREN'\n | 'RPAREN'\n | 'COMMA'\n | 'STAR'\n | 'EOF';\n\ninterface Token {\n type: TokenType;\n value: string;\n pos: number;\n}\n\nfunction tokenize(input: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n const len = input.length;\n\n while (i < len) {\n const ch = input[i];\n\n // Whitespace\n if (/\\s/.test(ch)) {\n i++;\n continue;\n }\n\n // Number (int or float)\n if (/[0-9]/.test(ch) || (ch === '.' && i + 1 < len && /[0-9]/.test(input[i + 1]))) {\n const start = i;\n let hasDot = false;\n while (i < len && (/[0-9]/.test(input[i]) || (input[i] === '.' && !hasDot))) {\n if (input[i] === '.') hasDot = true;\n i++;\n }\n tokens.push({ type: 'NUMBER', value: input.slice(start, i), pos: start });\n continue;\n }\n\n // Quoted string ('...' or \"...\")\n if (ch === \"'\" || ch === '\"') {\n const quote = ch;\n const start = i;\n i++;\n let str = '';\n while (i < len && input[i] !== quote) {\n if (input[i] === '\\\\' && i + 1 < len) {\n i++;\n str += input[i];\n } else {\n str += input[i];\n }\n i++;\n }\n if (i < len && input[i] === quote) {\n i++;\n }\n tokens.push({ type: 'STRING', value: str, pos: start });\n continue;\n }\n\n // Punctuation\n if (ch === '(') {\n tokens.push({ type: 'LPAREN', value: '(', pos: i++ });\n continue;\n }\n if (ch === ')') {\n tokens.push({ type: 'RPAREN', value: ')', pos: i++ });\n continue;\n }\n if (ch === ',') {\n tokens.push({ type: 'COMMA', value: ',', pos: i++ });\n continue;\n }\n\n // Operators\n if (ch === '<') {\n if (i + 1 < len && input[i + 1] === '=') {\n tokens.push({ type: 'OP', value: '<=', pos: i });\n i += 2;\n continue;\n }\n if (i + 1 < len && input[i + 1] === '>') {\n tokens.push({ type: 'OP', value: '!=', pos: i });\n i += 2;\n continue;\n }\n tokens.push({ type: 'OP', value: '<', pos: i++ });\n continue;\n }\n if (ch === '>') {\n if (i + 1 < len && input[i + 1] === '=') {\n tokens.push({ type: 'OP', value: '>=', pos: i });\n i += 2;\n continue;\n }\n tokens.push({ type: 'OP', value: '>', pos: i++ });\n continue;\n }\n if (ch === '=') {\n if (i + 1 < len && input[i + 1] === '=') {\n tokens.push({ type: 'OP', value: '=', pos: i });\n i += 2;\n continue;\n }\n tokens.push({ type: 'OP', value: '=', pos: i++ });\n continue;\n }\n if (ch === '!' && i + 1 < len && input[i + 1] === '=') {\n tokens.push({ type: 'OP', value: '!=', pos: i });\n i += 2;\n continue;\n }\n if (ch === '+' || ch === '-' || ch === '/' || ch === '%') {\n tokens.push({ type: 'OP', value: ch, pos: i++ });\n continue;\n }\n if (ch === '*') {\n // Disambiguate * (can be multiplication op or wildcard count(*))\n tokens.push({ type: 'STAR', value: '*', pos: i++ });\n continue;\n }\n\n // Identifier / Keyword (supports qualified identifiers like table.column)\n if (/[a-zA-Z_]/.test(ch)) {\n const start = i;\n while (i < len) {\n if (/[a-zA-Z0-9_]/.test(input[i])) {\n i++;\n } else if (input[i] === '.' && i + 1 < len && /[a-zA-Z_]/.test(input[i + 1])) {\n i += 2;\n } else {\n break;\n }\n }\n const val = input.slice(start, i);\n tokens.push({ type: 'IDENT', value: val, pos: start });\n continue;\n }\n\n // Unknown char, advance\n i++;\n }\n\n tokens.push({ type: 'EOF', value: '', pos: len });\n return tokens;\n}\n\nclass ExpressionParser {\n private tokens: Token[];\n private cursor = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n private peek(): Token {\n return this.tokens[this.cursor] ?? { type: 'EOF', value: '', pos: 0 };\n }\n\n private consume(): Token {\n const t = this.peek();\n this.cursor++;\n return t;\n }\n\n private match(type: TokenType, value?: string): boolean {\n const t = this.peek();\n if (t.type !== type) return false;\n if (value !== undefined && t.value.toLowerCase() !== value.toLowerCase()) return false;\n this.cursor++;\n return true;\n }\n\n private getPrecedence(token: Token): number {\n if (token.type === 'OP' || token.type === 'STAR') {\n if (\n token.value === '=' ||\n token.value === '!=' ||\n token.value === '<' ||\n token.value === '<=' ||\n token.value === '>' ||\n token.value === '>='\n ) {\n return 5;\n }\n if (token.value === '+' || token.value === '-') return 10;\n if (token.value === '*' || token.value === '/' || token.value === '%') return 20;\n }\n return 0;\n }\n\n parse(minPrecedence = 0): ExprNode {\n let left = this.parsePrimary();\n\n while (true) {\n const token = this.peek();\n const prec = this.getPrecedence(token);\n if (prec === 0 || prec <= minPrecedence) {\n break;\n }\n this.consume();\n const right = this.parse(prec);\n left = {\n type: 'binary',\n op: token.value as BinaryOp,\n left,\n right,\n };\n }\n\n return left;\n }\n\n private parsePrimary(): ExprNode {\n const token = this.peek();\n\n // Unary minus: -number or -(expr)\n if (token.type === 'OP' && token.value === '-') {\n this.consume();\n const operand = this.parse(25);\n if (operand.type === 'literal' && typeof operand.value === 'number') {\n return { type: 'literal', value: -operand.value };\n }\n return {\n type: 'binary',\n op: '-',\n left: { type: 'literal', value: 0 },\n right: operand,\n };\n }\n\n // Number literal\n if (this.match('NUMBER')) {\n return { type: 'literal', value: Number(token.value) };\n }\n\n // String literal\n if (this.match('STRING')) {\n return { type: 'literal', value: token.value };\n }\n\n // Parentheses\n if (this.match('LPAREN')) {\n const expr = this.parse(0);\n if (!this.match('RPAREN')) {\n throw new Error('Unclosed parenthesis in expression');\n }\n return expr;\n }\n\n // Star wildcard (e.g. count(*))\n if (this.match('STAR')) {\n return { type: 'col', name: '*' };\n }\n\n // Identifier or Function Call\n if (token.type === 'IDENT') {\n this.consume();\n const name = token.value;\n\n // Check for literals: null, true, false\n const lower = name.toLowerCase();\n if (lower === 'null' && this.peek().type !== 'LPAREN') {\n return { type: 'literal', value: null };\n }\n if (lower === 'true' && this.peek().type !== 'LPAREN') {\n return { type: 'literal', value: true };\n }\n if (lower === 'false' && this.peek().type !== 'LPAREN') {\n return { type: 'literal', value: false };\n }\n\n // Function call: ident(...)\n if (this.match('LPAREN')) {\n const args: ExprNode[] = [];\n if (!this.match('RPAREN')) {\n while (true) {\n args.push(this.parse(0));\n if (this.match('COMMA')) {\n continue;\n }\n if (this.match('RPAREN')) {\n break;\n }\n throw new Error(`Expected ',' or ')' in argument list of function ${name}`);\n }\n }\n return {\n type: 'fn',\n name: lower,\n args,\n };\n }\n\n // Plain column reference\n return { type: 'col', name };\n }\n\n throw new Error(`Unexpected token \"${token.value}\" in expression at position ${token.pos}`);\n }\n}\n\n/**\n * Parses a raw SQL expression string into an AST ExprNode.\n */\nexport function parseExpression(sql: string): ExprNode {\n const trimmed = sql.trim();\n if (!trimmed) {\n throw new Error('Cannot parse empty expression');\n }\n const tokens = tokenize(trimmed);\n const parser = new ExpressionParser(tokens);\n return parser.parse(0);\n}\n\n/**\n * Splits a select expression string into expression and alias.\n * Safely looks for top-level ` AS ` outside parentheses and string literals.\n */\nfunction splitAsAlias(raw: string): { exprStr: string; explicitAlias?: string } {\n let depth = 0;\n let inQuote: string | null = null;\n const len = raw.length;\n\n for (let i = 0; i < len; i++) {\n const ch = raw[i];\n if (inQuote) {\n if (ch === inQuote && raw[i - 1] !== '\\\\') {\n inQuote = null;\n }\n continue;\n }\n if (ch === \"'\" || ch === '\"') {\n inQuote = ch;\n continue;\n }\n if (ch === '(') {\n depth++;\n continue;\n }\n if (ch === ')') {\n depth--;\n continue;\n }\n\n if (depth === 0) {\n // Check for ' AS ' (case-insensitive)\n if (\n (ch === ' ' || ch === '\\t') &&\n i + 4 < len &&\n raw.slice(i + 1, i + 3).toLowerCase() === 'as' &&\n /\\s/.test(raw[i + 3])\n ) {\n const exprStr = raw.slice(0, i).trim();\n const explicitAlias = raw.slice(i + 4).trim();\n return { exprStr, explicitAlias };\n }\n }\n }\n\n return { exprStr: raw.trim() };\n}\n\n/**\n * Derives a human-friendly default alias if no explicit `AS alias` is provided.\n */\nexport function deriveDefaultAlias(expr: ExprNode): string {\n if (expr.type === 'col') {\n return expr.name.includes('.')\n ? expr.name.slice(expr.name.lastIndexOf('.') + 1)\n : expr.name;\n }\n if (expr.type === 'fn') {\n if (expr.args.length > 0 && expr.args[0].type === 'col' && expr.args[0].name !== '*') {\n const colName = expr.args[0].name.includes('.')\n ? expr.args[0].name.slice(expr.args[0].name.lastIndexOf('.') + 1)\n : expr.args[0].name;\n return `${expr.name}_${colName}`;\n }\n return expr.name;\n }\n if (expr.type === 'binary') {\n return 'expr';\n }\n return 'val';\n}\n\n/**\n * Parses a select clause item string (e.g. \"abs(salary) as abs_salary\" or \"name\").\n */\nexport function parseSelectExpr(raw: string): ParsedSelectExpr {\n const { exprStr, explicitAlias } = splitAsAlias(raw);\n const expr = parseExpression(exprStr);\n const alias = explicitAlias && explicitAlias.length > 0 ? explicitAlias : deriveDefaultAlias(expr);\n return { expr, alias };\n}\n\n// -------------------------------------------------------------\n// Drizzle-style Standalone Expression Helpers (col, fn)\n// -------------------------------------------------------------\n\nexport class ExpressionBuilder {\n readonly node: ExprNode;\n\n constructor(node: ExprNode) {\n this.node = node;\n }\n\n add(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '+',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n sub(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '-',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n mul(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '*',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n div(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '/',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n mod(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '%',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n eq(other: ExprNode | ExpressionBuilder | number | string | boolean | null): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '=',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n ne(other: ExprNode | ExpressionBuilder | number | string | boolean | null): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '!=',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n lt(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '<',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n lte(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '<=',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n gt(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '>',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n gte(other: ExprNode | ExpressionBuilder | number | string): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'binary',\n op: '>=',\n left: this.node,\n right: toExprNode(other),\n });\n }\n\n as(alias: string): ParsedSelectExpr {\n return {\n expr: this.node,\n alias,\n };\n }\n}\n\nfunction toExprNode(val: ExprNode | ExpressionBuilder | number | string | boolean | null): ExprNode {\n if (val === null) {\n return { type: 'literal', value: null };\n }\n if (typeof val === 'boolean') {\n return { type: 'literal', value: val };\n }\n if (val instanceof ExpressionBuilder) {\n return val.node;\n }\n if (typeof val === 'number') {\n return { type: 'literal', value: val };\n }\n if (typeof val === 'string') {\n return { type: 'literal', value: val };\n }\n return val;\n}\n\nexport function col(name: string): ExpressionBuilder {\n return new ExpressionBuilder({ type: 'col', name });\n}\n\nexport function exp(sqlStr: string): ExpressionBuilder {\n return new ExpressionBuilder(parseExpression(sqlStr));\n}\n\nexport const sql = exp;\n\nexport interface FnNamespace {\n (name: string, ...args: (ExprNode | ExpressionBuilder | number | string)[]): ExpressionBuilder;\n upper(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n lower(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n length(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n substr(\n expr: ExprNode | ExpressionBuilder | string,\n start: number | ExprNode | ExpressionBuilder,\n len?: number | ExprNode | ExpressionBuilder,\n ): ExpressionBuilder;\n trim(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n abs(expr: ExprNode | ExpressionBuilder | number): ExpressionBuilder;\n round(expr: ExprNode | ExpressionBuilder | number): ExpressionBuilder;\n floor(expr: ExprNode | ExpressionBuilder | number): ExpressionBuilder;\n ceil(expr: ExprNode | ExpressionBuilder | number): ExpressionBuilder;\n count(expr?: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n sum(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n avg(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n min(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n max(expr: ExprNode | ExpressionBuilder | string): ExpressionBuilder;\n concat(...exprs: (ExprNode | ExpressionBuilder | string)[]): ExpressionBuilder;\n coalesce(...exprs: (ExprNode | ExpressionBuilder | string | null)[]): ExpressionBuilder;\n}\n\nfunction wrapFn(name: string, args: (ExprNode | ExpressionBuilder | any)[]): ExpressionBuilder {\n return new ExpressionBuilder({\n type: 'fn',\n name: name.toLowerCase(),\n args: args.map((a) => (typeof a === 'string' && !a.startsWith(\"'\") ? col(a).node : toExprNode(a))),\n });\n}\n\nconst fnBase = (\n name: string,\n ...args: (ExprNode | ExpressionBuilder | number | string)[]\n) => {\n return wrapFn(name, args);\n};\n\nconst fnMethods = {\n upper: (expr: any) => wrapFn('upper', [expr]),\n lower: (expr: any) => wrapFn('lower', [expr]),\n length: (expr: any) => wrapFn('length', [expr]),\n substr: (expr: any, start: any, len?: any) => {\n const args = [expr, start];\n if (len !== undefined) args.push(len);\n return wrapFn('substr', args);\n },\n trim: (expr: any) => wrapFn('trim', [expr]),\n abs: (expr: any) => wrapFn('abs', [expr]),\n round: (expr: any) => wrapFn('round', [expr]),\n floor: (expr: any) => wrapFn('floor', [expr]),\n ceil: (expr: any) => wrapFn('ceil', [expr]),\n count: (expr?: any) => wrapFn('count', [expr ?? col('*').node]),\n sum: (expr: any) => wrapFn('sum', [expr]),\n avg: (expr: any) => wrapFn('avg', [expr]),\n min: (expr: any) => wrapFn('min', [expr]),\n max: (expr: any) => wrapFn('max', [expr]),\n concat: (...exprs: any[]) => wrapFn('concat', exprs),\n coalesce: (...exprs: any[]) => wrapFn('coalesce', exprs),\n};\n\nfor (const [key, value] of Object.entries(fnMethods)) {\n Object.defineProperty(fnBase, key, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n}\n\nexport const fn: FnNamespace = fnBase as any;\n\n/**\n * Evaluates an ExprNode AST against a database row.\n * Used for fallback projection and post-processing.\n */\nexport function evalExprNode(\n expr: ExprNode,\n row: DbRow,\n udfs?:\n | Map<string, { call: (...args: any[]) => any }>\n | Record<string, (...args: any[]) => any>\n | ((name: string) => ((...args: any[]) => any) | undefined),\n): any {\n switch (expr.type) {\n case 'literal':\n return expr.value;\n case 'col': {\n if (expr.name === '*') return null;\n return row[expr.name] !== undefined ? row[expr.name] : null;\n }\n case 'binary': {\n const left = evalExprNode(expr.left, row, udfs);\n const right = evalExprNode(expr.right, row, udfs);\n if (\n left === null ||\n right === null ||\n left === undefined ||\n right === undefined\n ) {\n return null;\n }\n if (\n expr.op === '=' ||\n expr.op === '!=' ||\n expr.op === '<' ||\n expr.op === '<=' ||\n expr.op === '>' ||\n expr.op === '>='\n ) {\n const cmp =\n typeof left === 'string' && typeof right === 'string'\n ? left < right\n ? -1\n : left > right\n ? 1\n : 0\n : Number(left) < Number(right)\n ? -1\n : Number(left) > Number(right)\n ? 1\n : 0;\n switch (expr.op) {\n case '=':\n return cmp === 0 ? 1 : 0;\n case '!=':\n return cmp !== 0 ? 1 : 0;\n case '<':\n return cmp < 0 ? 1 : 0;\n case '<=':\n return cmp <= 0 ? 1 : 0;\n case '>':\n return cmp > 0 ? 1 : 0;\n case '>=':\n return cmp >= 0 ? 1 : 0;\n }\n }\n const numL = Number(left);\n const numR = Number(right);\n switch (expr.op) {\n case '+':\n return numL + numR;\n case '-':\n return numL - numR;\n case '*':\n return numL * numR;\n case '/':\n return numR === 0 ? null : numL / numR;\n case '%':\n return numR === 0 ? null : numL % numR;\n }\n return null;\n }\n case 'fn': {\n const name = expr.name.toLowerCase();\n // Check built-in aggregates first (if already computed by aggregator, row has alias or func)\n if (isAggregateFunction(name)) {\n if (row[name] !== undefined) return row[name];\n const arg0 = expr.args[0];\n if (arg0 && arg0.type === 'col') {\n const colKey = `${name}_${arg0.name}`;\n if (row[colKey] !== undefined) return row[colKey];\n }\n return null;\n }\n const args = expr.args.map((a) => evalExprNode(a, row, udfs));\n switch (name) {\n case 'upper':\n return args[0] !== null && args[0] !== undefined\n ? String(args[0]).toUpperCase()\n : null;\n case 'lower':\n return args[0] !== null && args[0] !== undefined\n ? String(args[0]).toLowerCase()\n : null;\n case 'length':\n return args[0] !== null && args[0] !== undefined\n ? String(args[0]).length\n : null;\n case 'trim':\n return args[0] !== null && args[0] !== undefined\n ? String(args[0]).trim()\n : null;\n case 'substr': {\n if (args[0] === null || args[0] === undefined) return null;\n const str = String(args[0]);\n const start = Math.max(0, (Number(args[1]) || 1) - 1);\n const len =\n args[2] !== null && args[2] !== undefined\n ? Number(args[2])\n : undefined;\n return len !== undefined\n ? str.substring(start, start + len)\n : str.substring(start);\n }\n case 'abs':\n return args[0] !== null && args[0] !== undefined\n ? Math.abs(Number(args[0]))\n : null;\n case 'round':\n return args[0] !== null && args[0] !== undefined\n ? Math.round(Number(args[0]))\n : null;\n case 'floor':\n return args[0] !== null && args[0] !== undefined\n ? Math.floor(Number(args[0]))\n : null;\n case 'ceil':\n return args[0] !== null && args[0] !== undefined\n ? Math.ceil(Number(args[0]))\n : null;\n case 'concat': {\n if (args.some((a) => a === null || a === undefined)) return null;\n return args.map(String).join('');\n }\n case 'coalesce': {\n for (const a of args) {\n if (a !== null && a !== undefined) return a;\n }\n return null;\n }\n case 'starts_with':\n case 'startswith':\n return args[0] !== null && args[0] !== undefined && args[1] !== null && args[1] !== undefined\n ? String(args[0]).startsWith(String(args[1])) ? 1 : 0\n : null;\n case 'ends_with':\n case 'endswith':\n return args[0] !== null && args[0] !== undefined && args[1] !== null && args[1] !== undefined\n ? String(args[0]).endsWith(String(args[1])) ? 1 : 0\n : null;\n case 'contains':\n return args[0] !== null && args[0] !== undefined && args[1] !== null && args[1] !== undefined\n ? String(args[0]).includes(String(args[1])) ? 1 : 0\n : null;\n case 'like':\n return args[0] !== null && args[0] !== undefined && args[1] !== null && args[1] !== undefined\n ? sql_like_match(String(args[0]), String(args[1])) ? 1 : 0\n : null;\n default: {\n let fnCb: ((...a: any[]) => any) | undefined;\n if (typeof udfs === 'function') {\n fnCb = udfs(name);\n } else if (udfs instanceof Map) {\n const entry: any = udfs.get(name);\n fnCb = typeof entry === 'function' ? entry : entry?.call;\n } else if (udfs && typeof udfs === 'object') {\n const entry: any = (udfs as any)[name];\n fnCb = typeof entry === 'function' ? entry : entry?.call;\n }\n if (fnCb) {\n return fnCb(...args);\n }\n throw new UnknownFunctionError(name);\n }\n }\n }\n }\n}\n\n","import {\n TableMeta,\n IndexDescriptor,\n IndexFlag,\n JoinType,\n} from '../../../types/index.js';\nimport {\n QueryPlan,\n JoinPlan,\n QueryFilter,\n ComparisonOp,\n SortKey,\n resolveColumnAcrossTables,\n chooseIndexScan,\n isIndexAlignedWithOrderBy,\n} from '../compiler.js';\nimport { ParsedSelectExpr } from '../expr_parser.js';\n\nexport interface WhereMetrics {\n originalCount: number;\n optimizedCount: number;\n isAlwaysFalse: boolean;\n isAlwaysTrue: boolean;\n contradictionReason?: string;\n eliminatedFiltersCount: number;\n reordered: boolean;\n}\n\nexport interface PlanCostMetrics {\n totalCost: number;\n estimatedRows: number;\n joinOrder: string[];\n singleTableFilters: Map<number, QueryFilter[]>;\n crossFilters: QueryFilter[];\n tableScanTypes: ('TableScan' | 'IndexScan')[];\n tableIndexNames: (string | undefined)[];\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n}\n\nexport interface OptimizedPlanResult {\n plan: QueryPlan;\n orderedTables: TableMeta[];\n metrics: PlanCostMetrics | null;\n isAlwaysFalse?: boolean;\n isAlwaysTrue?: boolean;\n whereMetrics?: WhereMetrics;\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n}\n\nexport interface QueryPlanner {\n readonly name: string;\n optimize(plan: QueryPlan): OptimizedPlanResult;\n}\n\nexport interface JoinEdge {\n tableA: number;\n tableB: number;\n colA: string;\n colB: string;\n op: ComparisonOp;\n type: JoinType;\n declaredRightTable: number;\n}\n\nexport const COST_INDEX_SEEK = 0.5;\nexport const COST_INDEX_NEXT = 0.05;\nexport const COST_ROW_EVAL = 0.02;\n\n/**\n * Extracts all column names referenced in a filter (both direct colName and expr).\n */\nexport function extractFilterColumnNames(filter: QueryFilter): string[] {\n const cols: string[] = [];\n\n function visitFilter(f: QueryFilter) {\n if (f.colName) {\n cols.push(f.colName);\n }\n if (f.expr) {\n visitExpr(f.expr);\n }\n if (f.children) {\n for (const child of f.children) {\n visitFilter(child);\n }\n }\n if (f.child) {\n visitFilter(f.child);\n }\n }\n\n function visitExpr(expr: any) {\n if (!expr) return;\n if (expr.type === 'col' && expr.name) {\n cols.push(expr.name);\n }\n if (expr.left) visitExpr(expr.left);\n if (expr.right) visitExpr(expr.right);\n if (expr.args && Array.isArray(expr.args)) {\n for (const arg of expr.args) {\n visitExpr(arg);\n }\n }\n }\n\n visitFilter(filter);\n return cols;\n}\n\n/**\n * Determines which table indices (in `tables`) are referenced by a filter.\n */\nexport function getFilterReferencedTables(\n filter: QueryFilter,\n tables: TableMeta[],\n): Set<number> {\n const colNames = extractFilterColumnNames(filter);\n const referenced = new Set<number>();\n for (const name of colNames) {\n const resolved = resolveColumnAcrossTables(name, tables);\n if (resolved) {\n referenced.add(resolved.tableIdx);\n }\n }\n return referenced;\n}\n\n/**\n * Estimates filter selectivity based on operation, column index presence, and table row count.\n */\nexport function estimateFilterSelectivity(\n filter: QueryFilter,\n table: TableMeta,\n): number {\n const rowCount = Math.max(1, table.rowCountEstimate || 10);\n\n if (filter.type === 'cmp') {\n const op = filter.op ?? '=';\n if (op === '=') {\n const colName = filter.colName?.toLowerCase();\n const colIdx = table.columns.findIndex(\n (c) => c.name.toLowerCase() === colName,\n );\n if (colIdx !== -1 && table.indexes) {\n for (const idx of table.indexes) {\n if (idx.columnCount === 1 && idx.columnIndices[0] === colIdx) {\n const isUnique =\n (idx.flags & (IndexFlag.PRIMARY | IndexFlag.UNIQUE)) !== 0;\n if (isUnique) {\n return 1.0 / rowCount;\n }\n return Math.min(0.2, 5.0 / rowCount);\n }\n }\n }\n return 0.1;\n }\n if (op === '<' || op === '<=' || op === '>' || op === '>=') {\n return 0.33;\n }\n if (op === '!=' || (op as string) === '<>') {\n return 0.9;\n }\n if (\n op === 'like' ||\n op === 'contains' ||\n op === 'starts_with' ||\n op === 'ends_with'\n ) {\n return 0.15;\n }\n }\n\n if (filter.type === 'in') {\n const valuesCount = Math.max(1, filter.values?.length || 1);\n const baseSel = 0.05;\n return Math.min(1.0, valuesCount * baseSel);\n }\n\n if (filter.type === 'null') {\n return filter.isNull ? 0.05 : 0.95;\n }\n\n return 0.2;\n}\n\n/**\n * Computes single-table base cardinality and scan cost for a table when used as driving table.\n */\nexport function getSingleTableBaseCost(\n table: TableMeta,\n filters: QueryFilter[],\n orderBy?: SortKey[],\n limit?: number,\n): {\n cost: number;\n rows: number;\n scanType: 'TableScan' | 'IndexScan';\n indexName?: string;\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n} {\n const rowCount = Math.max(1, table.rowCountEstimate || 10);\n let selectivity = 1.0;\n\n for (const f of filters) {\n selectivity *= estimateFilterSelectivity(f, table);\n }\n\n const estimatedRows = Math.max(1, Math.round(rowCount * selectivity));\n const hasOrderBy = orderBy !== undefined && orderBy.length > 0;\n const explicitSortCost =\n hasOrderBy && estimatedRows > 1\n ? estimatedRows * Math.log2(estimatedRows) * COST_ROW_EVAL\n : 0;\n\n const cand = chooseIndexScan(table, filters, filters, orderBy);\n\n if (cand) {\n const isPoint = cand.scanType === 'point';\n const isMultiPoint = cand.scanType === 'multi_point';\n const satisfiesOrder = cand.satisfiesOrderBy === true;\n const effectiveRows =\n satisfiesOrder && limit !== undefined && limit > 0\n ? Math.min(limit, estimatedRows)\n : estimatedRows;\n\n let cost = COST_INDEX_SEEK;\n if (isPoint) {\n cost += 1 * COST_ROW_EVAL;\n return {\n cost,\n rows: 1,\n scanType: 'IndexScan',\n indexName: cand.index.name,\n isOrderSatisfied: true,\n sortCostAvoided: hasOrderBy ? explicitSortCost : undefined,\n };\n }\n if (isMultiPoint) {\n const numVals = cand.inValues?.length || 1;\n cost = numVals * COST_INDEX_SEEK + effectiveRows * COST_ROW_EVAL;\n if (!satisfiesOrder && hasOrderBy) {\n cost += explicitSortCost;\n }\n return {\n cost,\n rows: effectiveRows,\n scanType: 'IndexScan',\n indexName: cand.index.name,\n isOrderSatisfied: satisfiesOrder,\n sortCostAvoided: satisfiesOrder ? explicitSortCost : undefined,\n };\n }\n // Range\n cost += effectiveRows * COST_INDEX_NEXT + effectiveRows * COST_ROW_EVAL;\n if (!satisfiesOrder && hasOrderBy) {\n cost += explicitSortCost;\n }\n return {\n cost,\n rows: effectiveRows,\n scanType: 'IndexScan',\n indexName: cand.index.name,\n isOrderSatisfied: satisfiesOrder,\n sortCostAvoided: satisfiesOrder ? explicitSortCost : undefined,\n };\n }\n\n // Full table scan\n let cost = rowCount * COST_ROW_EVAL;\n if (hasOrderBy) {\n cost += explicitSortCost;\n }\n return {\n cost,\n rows: estimatedRows,\n scanType: 'TableScan',\n isOrderSatisfied: false,\n };\n}\n\n/**\n * Checks if targetTable has an index on the given column.\n */\nexport function findIndexOnColumn(\n table: TableMeta,\n colName: string,\n): { index: IndexDescriptor; isUnique: boolean } | null {\n if (!table.indexes || table.indexes.length === 0) return null;\n const colIdx = table.columns.findIndex(\n (c) => c.name.toLowerCase() === colName.toLowerCase(),\n );\n if (colIdx === -1) return null;\n\n let best: { index: IndexDescriptor; isUnique: boolean } | null = null;\n let bestRank = 999;\n\n for (const idx of table.indexes) {\n if (idx.columnCount === 1 && idx.columnIndices[0] === colIdx) {\n const isPk = (idx.flags & IndexFlag.PRIMARY) !== 0;\n const isUnique = (idx.flags & IndexFlag.UNIQUE) !== 0;\n const rank = isPk ? 1 : isUnique ? 2 : 3;\n if (rank < bestRank) {\n bestRank = rank;\n best = { index: idx, isUnique: isPk || isUnique };\n }\n }\n }\n\n return best;\n}\n\n/**\n * Builds join edges and left-join dependency constraints from query join clauses.\n */\nexport function buildJoinEdges(\n plan: QueryPlan,\n originalTables: TableMeta[],\n): { edges: JoinEdge[]; dependencies: Set<number>[] } {\n const N = originalTables.length;\n const edges: JoinEdge[] = [];\n const dependencies: Set<number>[] = Array.from(\n { length: N },\n () => new Set<number>(),\n );\n\n if (!plan.joinedTables) return { edges, dependencies };\n\n for (let j = 0; j < plan.joinedTables.length; j++) {\n const jp = plan.joinedTables[j];\n const joinedIdx = j + 1;\n const leftRes = resolveColumnAcrossTables(jp.leftCol, originalTables);\n const rightRes = resolveColumnAcrossTables(jp.rightCol, originalTables);\n\n if (leftRes && rightRes) {\n edges.push({\n tableA: leftRes.tableIdx,\n tableB: rightRes.tableIdx,\n colA: leftRes.col.name,\n colB: rightRes.col.name,\n op: jp.op,\n type: jp.type,\n declaredRightTable: joinedIdx,\n });\n\n // Semantic constraint for LEFT JOIN:\n // In `A LEFT JOIN B`, B cannot be evaluated before A (A is the outer preserved table).\n if (jp.type === 'left') {\n const outerTbl =\n leftRes.tableIdx === joinedIdx ? rightRes.tableIdx : leftRes.tableIdx;\n dependencies[joinedIdx].add(outerTbl);\n }\n }\n }\n\n return { edges, dependencies };\n}\n\n/**\n * Preserves output column projection order in case of table reordering.\n */\nexport function materializeOutputSelectExprs(\n plan: QueryPlan,\n originalTables: TableMeta[],\n): ParsedSelectExpr[] | undefined {\n if (plan.selectExprs && plan.selectExprs.length > 0) {\n return plan.selectExprs;\n }\n\n const seenNames = new Set<string>();\n const dupNames = new Set<string>();\n for (const t of originalTables) {\n for (const c of t.columns) {\n if (seenNames.has(c.name.toLowerCase())) {\n dupNames.add(c.name.toLowerCase());\n }\n seenNames.add(c.name.toLowerCase());\n }\n }\n\n const effectiveSelectExprs: ParsedSelectExpr[] = [];\n for (const t of originalTables) {\n for (const c of t.columns) {\n const alias = dupNames.has(c.name.toLowerCase())\n ? `${t.name}.${c.name}`\n : c.name;\n effectiveSelectExprs.push({\n expr: { type: 'col', name: `${t.name}.${c.name}` },\n alias,\n });\n }\n }\n\n return effectiveSelectExprs;\n}\n\n/**\n * Reconstructs JoinPlan[] for the ordered tables based on resolved join edges.\n */\nexport function reconstructJoinPlans(\n winningOrder: number[],\n originalTables: TableMeta[],\n edges: JoinEdge[],\n originalJoinedPlans?: JoinPlan[],\n): JoinPlan[] {\n const N = winningOrder.length;\n const newJoinedPlans: JoinPlan[] = [];\n\n for (let k = 1; k < N; k++) {\n const innerTableIdx = winningOrder[k];\n const innerTable = originalTables[innerTableIdx];\n const priorIndices = winningOrder.slice(0, k);\n\n const chosenEdge = edges.find(\n (e) =>\n (e.tableA === innerTableIdx && priorIndices.includes(e.tableB)) ||\n (e.tableB === innerTableIdx && priorIndices.includes(e.tableA)),\n );\n\n let leftColName: string;\n let rightColName: string;\n let op: ComparisonOp = '=';\n let joinType: JoinType = 'inner';\n\n if (chosenEdge) {\n op = chosenEdge.op;\n joinType = chosenEdge.type;\n if (chosenEdge.tableA === innerTableIdx) {\n rightColName = `${innerTable.name}.${chosenEdge.colA}`;\n const outerTable = originalTables[chosenEdge.tableB];\n leftColName = `${outerTable.name}.${chosenEdge.colB}`;\n } else {\n rightColName = `${innerTable.name}.${chosenEdge.colB}`;\n const outerTable = originalTables[chosenEdge.tableA];\n leftColName = `${outerTable.name}.${chosenEdge.colA}`;\n }\n } else {\n const origJp = originalJoinedPlans?.find(\n (j) => j.table.name === innerTable.name,\n );\n leftColName = origJp ? origJp.leftCol : `${originalTables[winningOrder[0]].name}.id`;\n rightColName = origJp ? origJp.rightCol : `${innerTable.name}.id`;\n op = origJp ? origJp.op : '=';\n joinType = origJp ? origJp.type : 'inner';\n }\n\n newJoinedPlans.push({\n type: joinType,\n table: innerTable,\n cursor: k,\n leftCol: leftColName,\n op,\n rightCol: rightColName,\n });\n }\n\n return newJoinedPlans;\n}\n\n/**\n * Checks whether all ORDER BY keys belong to candidateTable and are ASC,\n * which enables nested-loop join order preservation if candidateTable is the driving table.\n */\nexport function doesTableSatisfyJoinOrderKeys(\n candidateTable: TableMeta,\n candidateTableIdx: number,\n allTables: TableMeta[],\n orderBy?: SortKey[],\n selectExprs?: ParsedSelectExpr[],\n): boolean {\n if (!orderBy || orderBy.length === 0) return false;\n for (const k of orderBy) {\n if (k.direction === 'desc') return false;\n const colName = k.colName;\n if (!colName) return false;\n let resolved = resolveColumnAcrossTables(colName, allTables);\n if (!resolved && selectExprs) {\n const se = selectExprs.find((s) => s.alias === colName);\n if (se && se.expr.type === 'col') {\n resolved = resolveColumnAcrossTables(se.expr.name, allTables);\n }\n }\n if (!resolved || resolved.tableIdx !== candidateTableIdx) {\n return false;\n }\n }\n return true;\n}\n","import { TableMeta } from '../../../types/index.js';\nimport { QueryFilter } from '../compiler.js';\nimport { WhereMetrics } from './types.js';\n\n/**\n * Assigns an estimated relative CPU/evaluation cost to a filter for optimal short-circuit reordering.\n * Lower numbers = cheaper to evaluate -> placed first in execution.\n */\nexport function estimateWhereCost(filter: QueryFilter, tables?: TableMeta[]): number {\n if (filter.type === 'null') {\n return 1;\n }\n\n if (filter.type === 'cmp') {\n const op = filter.op ?? '=';\n if (op === 'like' || op === 'not like') {\n const val = typeof filter.value === 'string' ? filter.value : '';\n return val.startsWith('%') ? 25 : 15;\n }\n\n let isNumeric = false;\n if (tables && filter.colName) {\n const colNameLower = filter.colName.toLowerCase();\n const colBase = colNameLower.includes('.')\n ? colNameLower.slice(colNameLower.lastIndexOf('.') + 1)\n : colNameLower;\n\n for (const t of tables) {\n const c = t.columns.find((col) => col.name.toLowerCase() === colBase);\n if (c) {\n isNumeric = c.type === 1 || c.type === 2 || c.type === 3;\n break;\n }\n }\n } else if (typeof filter.value === 'number') {\n isNumeric = true;\n }\n\n if (op === '=' || (op as string) === '==') {\n return isNumeric ? 2 : 4;\n }\n return isNumeric ? 3 : 6;\n }\n\n if (filter.type === 'in') {\n const count = filter.values?.length ?? 0;\n return count <= 3 ? 5 : 10;\n }\n\n if (filter.type === 'expr') {\n return 40;\n }\n\n if (filter.type === 'and' || filter.type === 'or') {\n return 15;\n }\n\n if (filter.type === 'not') {\n return 8;\n }\n\n return 10;\n}\n\n/**\n * Optimizes an array of query filters by:\n * 1. Detecting contradictions (short-circuiting).\n * 2. Pruning redundant duplicates and subsumed range bounds.\n * 3. Reordering filters by evaluation cost.\n */\nexport function optimizeWherePredicates(\n filters: QueryFilter[],\n tables?: TableMeta[],\n): {\n filters: QueryFilter[];\n isAlwaysFalse: boolean;\n isAlwaysTrue: boolean;\n metrics: WhereMetrics;\n} {\n if (!filters || filters.length === 0) {\n return {\n filters: [],\n isAlwaysFalse: false,\n isAlwaysTrue: true,\n metrics: {\n originalCount: 0,\n optimizedCount: 0,\n isAlwaysFalse: false,\n isAlwaysTrue: true,\n eliminatedFiltersCount: 0,\n reordered: false,\n },\n };\n }\n\n const originalCount = filters.length;\n\n // 1. Flatten top-level AND conjunctions\n const flattened: QueryFilter[] = [];\n for (const f of filters) {\n if (f.type === 'and' && Array.isArray(f.children)) {\n flattened.push(...f.children);\n } else {\n flattened.push(f);\n }\n }\n\n // 2. Group top-level filters by column\n const byColumn = new Map<string, QueryFilter[]>();\n const nonColumnFilters: QueryFilter[] = [];\n\n for (const f of flattened) {\n if (f.colName) {\n const colKey = f.colName.toLowerCase();\n if (!byColumn.has(colKey)) {\n byColumn.set(colKey, []);\n }\n byColumn.get(colKey)!.push(f);\n } else {\n nonColumnFilters.push(f);\n }\n }\n\n // Check for contradiction across all filters\n for (const [colKey, colFilters] of byColumn.entries()) {\n const contradiction = checkColumnContradiction(colFilters);\n if (contradiction) {\n return {\n filters: [],\n isAlwaysFalse: true,\n isAlwaysTrue: false,\n metrics: {\n originalCount,\n optimizedCount: 0,\n isAlwaysFalse: true,\n isAlwaysTrue: false,\n contradictionReason: `Contradiction on column \"${colKey}\": ${contradiction}`,\n eliminatedFiltersCount: originalCount,\n reordered: false,\n },\n };\n }\n }\n\n // 3. Optimize and prune redundant filters per column\n const optimizedFilters: QueryFilter[] = [];\n let eliminatedCount = 0;\n\n for (const [, colFilters] of byColumn.entries()) {\n const pruned = pruneColumnFilters(colFilters);\n eliminatedCount += colFilters.length - pruned.length;\n optimizedFilters.push(...pruned);\n }\n\n optimizedFilters.push(...nonColumnFilters);\n\n // 4. Cost-based predicate reordering\n const originalOrderKey = optimizedFilters.map((f) => filterSignature(f)).join('|');\n optimizedFilters.sort((a, b) => {\n const costA = estimateWhereCost(a, tables);\n const costB = estimateWhereCost(b, tables);\n return costA - costB;\n });\n const newOrderKey = optimizedFilters.map((f) => filterSignature(f)).join('|');\n const reordered = originalOrderKey !== newOrderKey;\n\n return {\n filters: optimizedFilters,\n isAlwaysFalse: false,\n isAlwaysTrue: optimizedFilters.length === 0,\n metrics: {\n originalCount,\n optimizedCount: optimizedFilters.length,\n isAlwaysFalse: false,\n isAlwaysTrue: optimizedFilters.length === 0,\n eliminatedFiltersCount: eliminatedCount,\n reordered,\n },\n };\n}\n\nfunction checkColumnContradiction(filters: QueryFilter[]): string | null {\n let hasIsNull = false;\n let hasIsNotNull = false;\n const equalityValues: any[] = [];\n let lowerBound: { val: number; strict: boolean } | null = null;\n let upperBound: { val: number; strict: boolean } | null = null;\n let inSet: Set<any> | null = null;\n\n for (const f of filters) {\n if (f.type === 'null') {\n if (f.isNull === true) hasIsNull = true;\n if (f.isNull === false) hasIsNotNull = true;\n }\n\n if (f.type === 'cmp') {\n const op = f.op ?? '=';\n const val = f.value;\n\n if (op === '=' && val !== null && val !== undefined) {\n equalityValues.push(val);\n }\n\n if (typeof val === 'number') {\n if (op === '>') {\n if (!lowerBound || val > lowerBound.val || (val === lowerBound.val && !lowerBound.strict)) {\n lowerBound = { val, strict: true };\n }\n } else if (op === '>=') {\n if (!lowerBound || val > lowerBound.val) {\n lowerBound = { val, strict: false };\n }\n } else if (op === '<') {\n if (!upperBound || val < upperBound.val || (val === upperBound.val && !upperBound.strict)) {\n upperBound = { val, strict: true };\n }\n } else if (op === '<=') {\n if (!upperBound || val < upperBound.val) {\n upperBound = { val, strict: false };\n }\n }\n }\n }\n\n if (f.type === 'in' && !f.notIn) {\n if (!f.values || f.values.length === 0) {\n return 'Empty IN () list';\n }\n const currentSet = new Set(f.values);\n if (!inSet) {\n inSet = currentSet;\n } else {\n const intersected: Set<any> = new Set([...inSet].filter((x) => currentSet.has(x)));\n if (intersected.size === 0) {\n return 'Mutually exclusive IN lists with no common values';\n }\n inSet = intersected;\n }\n }\n }\n\n if (hasIsNull && hasIsNotNull) {\n return 'Conflicting IS NULL and IS NOT NULL';\n }\n\n if (hasIsNull && (equalityValues.length > 0 || lowerBound || upperBound)) {\n return 'Conflicting IS NULL and literal comparison';\n }\n\n if (equalityValues.length > 1) {\n const first = equalityValues[0];\n for (let i = 1; i < equalityValues.length; i++) {\n if (equalityValues[i] !== first) {\n return `Conflicting equality values (${first} !== ${equalityValues[i]})`;\n }\n }\n }\n\n if (equalityValues.length > 0 && (lowerBound || upperBound)) {\n const eqVal = equalityValues[0];\n if (typeof eqVal === 'number') {\n if (lowerBound) {\n if (lowerBound.strict ? eqVal <= lowerBound.val : eqVal < lowerBound.val) {\n return `Equality value ${eqVal} violates lower bound ${lowerBound.strict ? '>' : '>='} ${lowerBound.val}`;\n }\n }\n if (upperBound) {\n if (upperBound.strict ? eqVal >= upperBound.val : eqVal > upperBound.val) {\n return `Equality value ${eqVal} violates upper bound ${upperBound.strict ? '<' : '<='} ${upperBound.val}`;\n }\n }\n }\n }\n\n if (equalityValues.length > 0 && inSet) {\n const eqVal = equalityValues[0];\n if (!inSet.has(eqVal)) {\n return `Equality value ${eqVal} not present in IN list`;\n }\n }\n\n if (lowerBound && upperBound) {\n if (lowerBound.val > upperBound.val) {\n return `Lower bound ${lowerBound.val} is greater than upper bound ${upperBound.val}`;\n }\n if (lowerBound.val === upperBound.val && (lowerBound.strict || upperBound.strict)) {\n return `Strict range bounds empty at ${lowerBound.val}`;\n }\n }\n\n return null;\n}\n\nfunction pruneColumnFilters(filters: QueryFilter[]): QueryFilter[] {\n const result: QueryFilter[] = [];\n const seenSignatures = new Set<string>();\n\n let hasEqualityOnNonNull = false;\n let singleEqualityValue: any = undefined;\n\n for (const f of filters) {\n if (f.type === 'cmp' && (f.op === '=' || f.op === undefined) && f.value !== null && f.value !== undefined) {\n hasEqualityOnNonNull = true;\n singleEqualityValue = f.value;\n break;\n }\n }\n\n let bestLower: { val: number; strict: boolean; filter: QueryFilter } | null = null;\n let bestUpper: { val: number; strict: boolean; filter: QueryFilter } | null = null;\n\n for (const f of filters) {\n if (f.type === 'cmp' && typeof f.value === 'number') {\n const op = f.op ?? '=';\n const val = f.value;\n if (op === '>') {\n if (!bestLower || val > bestLower.val || (val === bestLower.val && !bestLower.strict)) {\n bestLower = { val, strict: true, filter: f };\n }\n } else if (op === '>=') {\n if (!bestLower || val > bestLower.val) {\n bestLower = { val, strict: false, filter: f };\n }\n } else if (op === '<') {\n if (!bestUpper || val < bestUpper.val || (val === bestUpper.val && !bestUpper.strict)) {\n bestUpper = { val, strict: true, filter: f };\n }\n } else if (op === '<=') {\n if (!bestUpper || val < bestUpper.val) {\n bestUpper = { val, strict: false, filter: f };\n }\n }\n }\n }\n\n for (const f of filters) {\n const sig = filterSignature(f);\n if (seenSignatures.has(sig)) {\n continue;\n }\n\n if (f.type === 'null' && f.isNull === false && hasEqualityOnNonNull) {\n continue;\n }\n\n if (f.type === 'in' && !f.notIn && hasEqualityOnNonNull && Array.isArray(f.values) && f.values.includes(singleEqualityValue)) {\n continue;\n }\n\n if (f.type === 'cmp' && typeof f.value === 'number') {\n const op = f.op ?? '=';\n if (op === '>' || op === '>=') {\n if (bestLower && f !== bestLower.filter) {\n continue;\n }\n } else if (op === '<' || op === '<=') {\n if (bestUpper && f !== bestUpper.filter) {\n continue;\n }\n }\n }\n\n seenSignatures.add(sig);\n result.push(f);\n }\n\n return result;\n}\n\nfunction filterSignature(f: QueryFilter): string {\n return `${f.type}:${f.colName ?? ''}:${f.isNull ?? ''}:${f.op ?? ''}:${String(f.value ?? '')}:${f.notIn ?? ''}:${JSON.stringify(f.values ?? '')}`;\n}\n\n/**\n * Infers transitive equality predicates across inner/left joins.\n */\nexport function inferTransitivePredicates(\n filters: QueryFilter[],\n joinedPlans: { leftCol: string; op: string; rightCol: string; type: string }[],\n): QueryFilter[] {\n const result = [...filters];\n const normalize = (c: string) => c.toLowerCase();\n const getBaseName = (c: string) => {\n const idx = c.lastIndexOf('.');\n return idx >= 0 ? c.slice(idx + 1).toLowerCase() : c.toLowerCase();\n };\n\n const findEqualityValue = (col: string): any => {\n const colNorm = normalize(col);\n const colBase = getBaseName(col);\n for (const f of filters) {\n if (\n f.type === 'cmp' &&\n (f.op === '=' || (f.op as string) === '==' || f.op === undefined) &&\n f.colName &&\n f.value !== null &&\n f.value !== undefined\n ) {\n const fNorm = normalize(f.colName);\n const fBase = getBaseName(f.colName);\n if (fNorm === colNorm || fBase === colNorm || fNorm === colBase) {\n return f.value;\n }\n }\n }\n return undefined;\n };\n\n for (const j of joinedPlans) {\n if (j.type !== 'inner' && j.type !== 'left') {\n continue;\n }\n if (j.op !== '=' && (j.op as string) !== '==') {\n continue;\n }\n\n const leftVal = findEqualityValue(j.leftCol);\n if (leftVal !== undefined) {\n result.push({\n type: 'cmp',\n colName: j.rightCol,\n op: '=',\n value: leftVal,\n });\n }\n\n if (j.type === 'inner') {\n const rightVal = findEqualityValue(j.rightCol);\n if (rightVal !== undefined) {\n result.push({\n type: 'cmp',\n colName: j.leftCol,\n op: '=',\n value: rightVal,\n });\n }\n }\n }\n\n return result;\n}\n","import { TableMeta } from \"../../../types/index.js\";\nimport {\n QueryPlan,\n QueryFilter,\n buildRootFilter,\n getTopLevelConjunctionFilters,\n} from \"../compiler.js\";\nimport {\n QueryPlanner,\n OptimizedPlanResult,\n JoinEdge,\n getFilterReferencedTables,\n getSingleTableBaseCost,\n doesTableSatisfyJoinOrderKeys,\n findIndexOnColumn,\n buildJoinEdges,\n materializeOutputSelectExprs,\n reconstructJoinPlans,\n estimateFilterSelectivity,\n COST_INDEX_SEEK,\n COST_INDEX_NEXT,\n COST_ROW_EVAL,\n} from \"./types.js\";\nimport {\n optimizeWherePredicates,\n inferTransitivePredicates,\n} from \"./where_optimizer.js\";\n\nexport interface CostBasedPlannerOptions {\n indexSeekCost?: number;\n indexNextCost?: number;\n rowEvalCost?: number;\n}\n\n/**\n * CostBasedPlanner unifies WHERE filter optimization and JOIN planning:\n * - Detects contradictions and prunes redundant/subsumed WHERE conditions.\n * - Infers transitive filters across join boundaries.\n * - Evaluates join permutations with Dynamic Programming to minimize total cost.\n */\nexport class CostBasedPlanner implements QueryPlanner {\n readonly name = \"cost\";\n private indexSeekCost: number;\n private indexNextCost: number;\n private rowEvalCost: number;\n\n constructor(options?: CostBasedPlannerOptions) {\n this.indexSeekCost = options?.indexSeekCost ?? COST_INDEX_SEEK;\n this.indexNextCost = options?.indexNextCost ?? COST_INDEX_NEXT;\n this.rowEvalCost = options?.rowEvalCost ?? COST_ROW_EVAL;\n }\n\n optimize(plan: QueryPlan): OptimizedPlanResult {\n const originalTables: TableMeta[] = [\n plan.table,\n ...(plan.joinedTables?.map((j) => j.table) ?? []),\n ];\n const N = originalTables.length;\n\n // 1. Optimize WHERE filters (contradiction checking, redundancy pruning, cost reordering)\n const whereRes = optimizeWherePredicates(plan.filters, originalTables);\n if (whereRes.isAlwaysFalse) {\n return {\n plan: { ...plan, filters: [] },\n orderedTables: originalTables,\n metrics: null,\n isAlwaysFalse: true,\n whereMetrics: whereRes.metrics,\n };\n }\n\n let workingFilters = whereRes.filters;\n let whereMetrics = whereRes.metrics;\n\n // 2. Transitive predicate inference across join boundaries\n if (plan.joinedTables && plan.joinedTables.length > 0) {\n const withTransitive = inferTransitivePredicates(\n workingFilters,\n plan.joinedTables,\n );\n if (withTransitive.length > workingFilters.length) {\n const transRes = optimizeWherePredicates(\n withTransitive,\n originalTables,\n );\n if (transRes.isAlwaysFalse) {\n return {\n plan: { ...plan, filters: [] },\n orderedTables: originalTables,\n metrics: null,\n isAlwaysFalse: true,\n whereMetrics: transRes.metrics,\n };\n }\n workingFilters = transRes.filters;\n whereMetrics = transRes.metrics;\n }\n }\n\n // 3. Handle single table queries\n if (N <= 1 || !plan.joinedTables || plan.joinedTables.length === 0) {\n const singleFilters = new Map<number, QueryFilter[]>();\n singleFilters.set(0, workingFilters);\n\n const baseCost = getSingleTableBaseCost(\n plan.table,\n workingFilters,\n plan.orderBy,\n plan.limit,\n );\n\n return {\n plan: {\n ...plan,\n filters: workingFilters,\n },\n orderedTables: [plan.table],\n metrics: {\n totalCost: baseCost.cost,\n estimatedRows: baseCost.rows,\n joinOrder: [plan.table.name],\n singleTableFilters: singleFilters,\n crossFilters: [],\n tableScanTypes: [baseCost.scanType],\n tableIndexNames: [baseCost.indexName],\n isOrderSatisfied: baseCost.isOrderSatisfied,\n sortCostAvoided: baseCost.sortCostAvoided,\n },\n isAlwaysFalse: false,\n isAlwaysTrue: whereMetrics.isAlwaysTrue,\n whereMetrics,\n isOrderSatisfied: baseCost.isOrderSatisfied,\n sortCostAvoided: baseCost.sortCostAvoided,\n };\n }\n\n // 4. Multi-table join planning\n const rootFilter = buildRootFilter(workingFilters);\n const topConjunctions = getTopLevelConjunctionFilters(rootFilter);\n\n // Partition filters: single-table filters per table, and cross-table filters\n const singleTableFilters = new Map<number, QueryFilter[]>();\n const crossFilters: QueryFilter[] = [];\n\n for (let i = 0; i < N; i++) {\n singleTableFilters.set(i, []);\n }\n\n for (const filter of topConjunctions) {\n const refs = getFilterReferencedTables(filter, originalTables);\n if (refs.size === 1) {\n const tblIdx = refs.values().next().value;\n if (tblIdx !== undefined) {\n singleTableFilters.get(tblIdx)?.push(filter);\n }\n } else {\n crossFilters.push(filter);\n }\n }\n\n // Single-table query: trivial case\n if (N <= 1 || !plan.joinedTables || plan.joinedTables.length === 0) {\n const base = getSingleTableBaseCost(\n originalTables[0],\n singleTableFilters.get(0) ?? [],\n );\n return {\n plan,\n orderedTables: originalTables,\n metrics: {\n totalCost: base.cost,\n estimatedRows: base.rows,\n joinOrder: [originalTables[0].name],\n singleTableFilters,\n crossFilters,\n tableScanTypes: [base.scanType],\n tableIndexNames: [base.indexName],\n },\n };\n }\n\n const { edges, dependencies } = buildJoinEdges(plan, originalTables);\n\n interface DPState {\n order: number[];\n cost: number;\n rows: number;\n scanTypes: (\"TableScan\" | \"IndexScan\")[];\n indexNames: (string | undefined)[];\n edgesUsed: JoinEdge[];\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n }\n\n const dp = new Map<number, DPState>();\n\n // 1. Base states (subsets of size 1)\n for (let i = 0; i < N; i++) {\n if (dependencies[i].size === 0) {\n const canPreserve = doesTableSatisfyJoinOrderKeys(\n originalTables[i],\n i,\n originalTables,\n plan.orderBy,\n plan.selectExprs,\n );\n const orderKeysForTable = canPreserve\n ? plan.orderBy!.map((k) => {\n const col = k.colName ?? \"\";\n const shortCol = col.includes(\".\")\n ? col.slice(col.lastIndexOf(\".\") + 1)\n : col;\n return { ...k, colName: shortCol };\n })\n : undefined;\n\n const base = getSingleTableBaseCost(\n originalTables[i],\n singleTableFilters.get(i) ?? [],\n orderKeysForTable,\n canPreserve ? plan.limit : undefined,\n );\n const mask = 1 << i;\n dp.set(mask, {\n order: [i],\n cost: base.cost,\n rows: base.rows,\n scanTypes: [base.scanType],\n indexNames: [base.indexName],\n edgesUsed: [],\n isOrderSatisfied: base.isOrderSatisfied,\n sortCostAvoided: base.sortCostAvoided,\n });\n }\n }\n\n // 2. Iterate subsets of size 2 .. N\n const totalSubsets = 1 << N;\n for (let size = 2; size <= N; size++) {\n for (let mask = 1; mask < totalSubsets; mask++) {\n if (countBits(mask) !== size) continue;\n\n for (let nextIdx = 0; nextIdx < N; nextIdx++) {\n if ((mask & (1 << nextIdx)) === 0) continue;\n\n const prevMask = mask ^ (1 << nextIdx);\n const prevState = dp.get(prevMask);\n if (!prevState) continue;\n\n let depsSatisfied = true;\n for (const dep of dependencies[nextIdx]) {\n if ((prevMask & (1 << dep)) === 0) {\n depsSatisfied = false;\n break;\n }\n }\n if (!depsSatisfied) continue;\n\n const evalRes = this.evaluateJoinStep(\n prevState.rows,\n originalTables[nextIdx],\n nextIdx,\n edges,\n prevState.order,\n singleTableFilters.get(nextIdx) ?? [],\n );\n\n const totalCost = prevState.cost + evalRes.stepCost;\n const existing = dp.get(mask);\n let isBetter = false;\n\n let candidateTotalCost = totalCost;\n let existingTotalCost = existing ? existing.cost : 0;\n\n const candidateOrderSatisfied = prevState.isOrderSatisfied === true;\n const existingOrderSatisfied = existing?.isOrderSatisfied === true;\n\n // When completing the full join (size === N), account for avoided explicit sort\n if (size === N && plan.orderBy && plan.orderBy.length > 0) {\n if (!candidateOrderSatisfied && evalRes.newRows > 1) {\n candidateTotalCost +=\n evalRes.newRows * Math.log2(evalRes.newRows) * this.rowEvalCost;\n }\n if (existing && !existingOrderSatisfied && existing.rows > 1) {\n existingTotalCost +=\n existing.rows * Math.log2(existing.rows) * this.rowEvalCost;\n }\n }\n\n if (!existing) {\n isBetter = true;\n } else {\n // If one candidate satisfies the sort order and the other does not,\n // give substantial preference to the order-preserving plan\n if (candidateOrderSatisfied && !existingOrderSatisfied) {\n isBetter = true;\n } else if (!candidateOrderSatisfied && existingOrderSatisfied) {\n isBetter = false;\n } else {\n const candidateIndexScans =\n prevState.scanTypes.filter((t) => t === \"IndexScan\").length +\n (evalRes.scanType === \"IndexScan\" ? 1 : 0);\n const existingIndexScans = existing.scanTypes.filter(\n (t) => t === \"IndexScan\",\n ).length;\n\n if (\n candidateIndexScans > existingIndexScans &&\n candidateTotalCost <= existingTotalCost * 1.2\n ) {\n isBetter = true;\n } else if (candidateIndexScans < existingIndexScans) {\n isBetter = false;\n } else if (candidateTotalCost < existingTotalCost * 0.75) {\n isBetter = true;\n } else if (existingTotalCost < candidateTotalCost * 0.75) {\n isBetter = false;\n } else {\n // Costs are comparable: prefer preserving user's declared driving table (table 0)\n const candidateStartsWithZero = prevState.order[0] === 0;\n const existingStartsWithZero = existing.order[0] === 0;\n if (candidateStartsWithZero && !existingStartsWithZero) {\n isBetter = true;\n } else if (!candidateStartsWithZero && existingStartsWithZero) {\n isBetter = false;\n } else {\n const candidateInversions = prevState.order.filter(\n (idx) => idx > nextIdx,\n ).length;\n const existingInversions = existing.order.filter(\n (idx, i) => idx > i,\n ).length;\n if (candidateInversions < existingInversions) {\n isBetter = true;\n }\n }\n }\n }\n }\n\n if (isBetter) {\n dp.set(mask, {\n order: [...prevState.order, nextIdx],\n cost: totalCost,\n rows: evalRes.newRows,\n scanTypes: [...prevState.scanTypes, evalRes.scanType],\n indexNames: [...prevState.indexNames, evalRes.indexName],\n edgesUsed: [...prevState.edgesUsed, evalRes.matchedEdge],\n isOrderSatisfied: prevState.isOrderSatisfied,\n sortCostAvoided: prevState.sortCostAvoided,\n });\n }\n }\n }\n }\n\n // 3. Retrieve best plan\n const fullMask = (1 << N) - 1;\n const bestState = dp.get(fullMask);\n\n let winningOrder: number[];\n let winningCost: number;\n let winningRows: number;\n let winningScanTypes: (\"TableScan\" | \"IndexScan\")[];\n let winningIndexNames: (string | undefined)[];\n\n if (bestState) {\n winningOrder = bestState.order;\n winningCost = bestState.cost;\n winningRows = bestState.rows;\n winningScanTypes = bestState.scanTypes;\n winningIndexNames = bestState.indexNames;\n } else {\n winningOrder = Array.from({ length: N }, (_, i) => i);\n winningCost = 999999;\n winningRows = 100;\n winningScanTypes = Array.from({ length: N }, () => \"TableScan\");\n winningIndexNames = Array.from({ length: N }, () => undefined);\n }\n\n const orderedTables = winningOrder.map((idx) => originalTables[idx]);\n const newJoinedPlans = reconstructJoinPlans(\n winningOrder,\n originalTables,\n edges,\n plan.joinedTables,\n );\n const effectiveSelectExprs = materializeOutputSelectExprs(\n plan,\n originalTables,\n );\n\n const finalOrderSatisfied = bestState?.isOrderSatisfied === true;\n const finalSortCostAvoided =\n finalOrderSatisfied && plan.orderBy && plan.orderBy.length > 0 && winningRows > 1\n ? winningRows * Math.log2(winningRows) * this.rowEvalCost\n : undefined;\n\n return {\n plan: {\n ...plan,\n table: orderedTables[0],\n joinedTables: newJoinedPlans,\n selectExprs: effectiveSelectExprs,\n filters: workingFilters,\n isOrderSatisfied: finalOrderSatisfied,\n },\n orderedTables,\n metrics: {\n totalCost: winningCost,\n estimatedRows: winningRows,\n joinOrder: orderedTables.map((t) => t.name),\n singleTableFilters,\n crossFilters,\n tableScanTypes: winningScanTypes,\n tableIndexNames: winningIndexNames,\n isOrderSatisfied: finalOrderSatisfied,\n sortCostAvoided: finalSortCostAvoided,\n },\n isAlwaysFalse: false,\n isAlwaysTrue: whereMetrics.isAlwaysTrue,\n whereMetrics,\n isOrderSatisfied: finalOrderSatisfied,\n sortCostAvoided: finalSortCostAvoided,\n };\n }\n\n private evaluateJoinStep(\n outerRows: number,\n nextTable: TableMeta,\n nextTableIdx: number,\n edges: JoinEdge[],\n plannedTableIndices: number[],\n nextTableFilters: QueryFilter[],\n ): {\n stepCost: number;\n newRows: number;\n scanType: \"TableScan\" | \"IndexScan\";\n indexName?: string;\n matchedEdge: JoinEdge;\n } {\n const rowCount = Math.max(1, nextTable.rowCountEstimate || 10);\n let filterSel = 1.0;\n for (const f of nextTableFilters) {\n filterSel *= estimateFilterSelectivity(f, nextTable);\n }\n\n const candidates: {\n edge: JoinEdge;\n nextCol: string;\n outerCol: string;\n idxMatch: { index: any; isUnique: boolean } | null;\n }[] = [];\n\n for (const edge of edges) {\n if (\n edge.tableA === nextTableIdx &&\n plannedTableIndices.includes(edge.tableB)\n ) {\n const idxMatch = findIndexOnColumn(nextTable, edge.colA);\n candidates.push({\n edge,\n nextCol: edge.colA,\n outerCol: edge.colB,\n idxMatch,\n });\n } else if (\n edge.tableB === nextTableIdx &&\n plannedTableIndices.includes(edge.tableA)\n ) {\n const idxMatch = findIndexOnColumn(nextTable, edge.colB);\n candidates.push({\n edge,\n nextCol: edge.colB,\n outerCol: edge.colA,\n idxMatch,\n });\n }\n }\n\n if (candidates.length === 0) {\n const stepCost = outerRows * (2.0 + rowCount * 0.1);\n const newRows = Math.max(1, Math.round(outerRows * rowCount * filterSel));\n const fallbackEdge: JoinEdge = {\n tableA: plannedTableIndices[0],\n tableB: nextTableIdx,\n colA: \"\",\n colB: \"\",\n op: \"=\",\n type: \"inner\",\n declaredRightTable: nextTableIdx,\n };\n return {\n stepCost,\n newRows,\n scanType: \"TableScan\",\n matchedEdge: fallbackEdge,\n };\n }\n\n candidates.sort((a, b) => {\n const rankA = a.idxMatch ? (a.idxMatch.isUnique ? 1 : 2) : 3;\n const rankB = b.idxMatch ? (b.idxMatch.isUnique ? 1 : 2) : 3;\n return rankA - rankB;\n });\n\n const bestCand = candidates[0];\n if (bestCand.idxMatch && bestCand.idxMatch.isUnique) {\n const seekCost = this.indexSeekCost + 1 * this.rowEvalCost;\n const stepCost = outerRows * seekCost;\n const newRows = Math.max(1, Math.round(outerRows * filterSel));\n return {\n stepCost,\n newRows,\n scanType: \"IndexScan\",\n indexName: bestCand.idxMatch.index.name,\n matchedEdge: bestCand.edge,\n };\n }\n\n if (bestCand.idxMatch && !bestCand.idxMatch.isUnique) {\n const avgDupes = Math.max(1, Math.min(10, Math.round(rowCount / 20)));\n const seekCost = this.indexSeekCost + avgDupes * this.indexNextCost;\n const stepCost = outerRows * seekCost;\n const newRows = Math.max(1, Math.round(outerRows * avgDupes * filterSel));\n return {\n stepCost,\n newRows,\n scanType: \"IndexScan\",\n indexName: bestCand.idxMatch.index.name,\n matchedEdge: bestCand.edge,\n };\n }\n\n const stepCost = outerRows * (2.0 + rowCount * 0.1);\n const newRows = Math.max(\n 1,\n Math.round(\n outerRows * Math.max(1, Math.round(rowCount * 0.1)) * filterSel,\n ),\n );\n return {\n stepCost,\n newRows,\n scanType: \"TableScan\",\n matchedEdge: bestCand.edge,\n };\n }\n}\n\nfunction countBits(n: number): number {\n let count = 0;\n let val = n;\n while (val > 0) {\n count += val & 1;\n val >>= 1;\n }\n return count;\n}\n","import { TableMeta } from '../../../types/index.js';\nimport {\n QueryPlan,\n QueryFilter,\n buildRootFilter,\n getTopLevelConjunctionFilters,\n} from '../compiler.js';\nimport {\n QueryPlanner,\n OptimizedPlanResult,\n getFilterReferencedTables,\n getSingleTableBaseCost,\n doesTableSatisfyJoinOrderKeys,\n findIndexOnColumn,\n buildJoinEdges,\n materializeOutputSelectExprs,\n reconstructJoinPlans,\n COST_INDEX_SEEK,\n COST_INDEX_NEXT,\n COST_ROW_EVAL,\n} from './types.js';\n\n/**\n * HeuristicPlanner performs greedy nearest-neighbor join ordering.\n * It is fast (O(N^2)), lightweight, and handles common join patterns without full DP enumeration.\n */\nexport class HeuristicPlanner implements QueryPlanner {\n readonly name = 'heuristic';\n\n optimize(plan: QueryPlan): OptimizedPlanResult {\n const originalTables: TableMeta[] = [\n plan.table,\n ...(plan.joinedTables?.map((j) => j.table) ?? []),\n ];\n const N = originalTables.length;\n\n const rootFilter = buildRootFilter(plan.filters);\n const topConjunctions = getTopLevelConjunctionFilters(rootFilter);\n\n const singleTableFilters = new Map<number, QueryFilter[]>();\n const crossFilters: QueryFilter[] = [];\n\n for (let i = 0; i < N; i++) {\n singleTableFilters.set(i, []);\n }\n\n for (const filter of topConjunctions) {\n const refs = getFilterReferencedTables(filter, originalTables);\n if (refs.size === 1) {\n const tblIdx = refs.values().next().value;\n if (tblIdx !== undefined) {\n singleTableFilters.get(tblIdx)?.push(filter);\n }\n } else {\n crossFilters.push(filter);\n }\n }\n\n if (N <= 1 || !plan.joinedTables || plan.joinedTables.length === 0) {\n const base = getSingleTableBaseCost(\n originalTables[0],\n singleTableFilters.get(0) ?? [],\n plan.orderBy,\n plan.limit,\n );\n return {\n plan,\n orderedTables: originalTables,\n metrics: {\n totalCost: base.cost,\n estimatedRows: base.rows,\n joinOrder: [originalTables[0].name],\n singleTableFilters,\n crossFilters,\n tableScanTypes: [base.scanType],\n tableIndexNames: [base.indexName],\n isOrderSatisfied: base.isOrderSatisfied,\n sortCostAvoided: base.sortCostAvoided,\n },\n isOrderSatisfied: base.isOrderSatisfied,\n sortCostAvoided: base.sortCostAvoided,\n };\n }\n\n const { edges, dependencies } = buildJoinEdges(plan, originalTables);\n\n // Compute base costs for each table as a candidate driving table\n const baseStats = originalTables.map((t, idx) => {\n const canPreserve = doesTableSatisfyJoinOrderKeys(\n t,\n idx,\n originalTables,\n plan.orderBy,\n plan.selectExprs,\n );\n const orderKeysForTable = canPreserve\n ? plan.orderBy!.map((k) => {\n const col = k.colName ?? \"\";\n const shortCol = col.includes(\".\")\n ? col.slice(col.lastIndexOf(\".\") + 1)\n : col;\n return { ...k, colName: shortCol };\n })\n : undefined;\n return getSingleTableBaseCost(\n t,\n singleTableFilters.get(idx) ?? [],\n orderKeysForTable,\n canPreserve ? plan.limit : undefined,\n );\n });\n\n // Step 1: Pick best driving table\n // Candidates are tables with 0 unmet dependencies\n const validDrivingCandidates: number[] = [];\n for (let i = 0; i < N; i++) {\n if (dependencies[i].size === 0) {\n validDrivingCandidates.push(i);\n }\n }\n\n // Sort driving candidates: prefer order preservation, lowest rows first, tie-break by index scan, then table 0\n validDrivingCandidates.sort((a, b) => {\n const aOrder = baseStats[a].isOrderSatisfied ? 1 : 0;\n const bOrder = baseStats[b].isOrderSatisfied ? 1 : 0;\n if (aOrder !== bOrder) return bOrder - aOrder;\n if (baseStats[a].rows !== baseStats[b].rows) {\n return baseStats[a].rows - baseStats[b].rows;\n }\n const aIsIndex = baseStats[a].scanType === 'IndexScan' ? 1 : 0;\n const bIsIndex = baseStats[b].scanType === 'IndexScan' ? 1 : 0;\n if (aIsIndex !== bIsIndex) return bIsIndex - aIsIndex;\n // Prefer table 0\n if (a === 0) return -1;\n if (b === 0) return 1;\n return a - b;\n });\n\n const drivingIdx = validDrivingCandidates[0] ?? 0;\n const winningOrder: number[] = [drivingIdx];\n const chosenScanTypes: ('TableScan' | 'IndexScan')[] = [baseStats[drivingIdx].scanType];\n const chosenIndexNames: (string | undefined)[] = [baseStats[drivingIdx].indexName];\n let totalCost = baseStats[drivingIdx].cost;\n let currentRows = baseStats[drivingIdx].rows;\n\n const remaining = new Set<number>();\n for (let i = 0; i < N; i++) {\n if (i !== drivingIdx) remaining.add(i);\n }\n\n // Step 2: Greedily pick next table\n while (remaining.size > 0) {\n const candidates: {\n tableIdx: number;\n rank: number;\n stepCost: number;\n newRows: number;\n scanType: 'TableScan' | 'IndexScan';\n indexName?: string;\n }[] = [];\n\n for (const nextIdx of remaining) {\n // Check dependencies\n let depsSatisfied = true;\n for (const dep of dependencies[nextIdx]) {\n if (!winningOrder.includes(dep)) {\n depsSatisfied = false;\n break;\n }\n }\n if (!depsSatisfied) continue;\n\n // Check join edges connecting winningOrder to nextIdx\n const nextTable = originalTables[nextIdx];\n const rowCount = Math.max(1, nextTable.rowCountEstimate || 10);\n let bestEdgeMatch: { isUnique: boolean; indexName: string } | null = null;\n\n for (const edge of edges) {\n if (edge.tableA === nextIdx && winningOrder.includes(edge.tableB)) {\n const idx = findIndexOnColumn(nextTable, edge.colA);\n if (idx && (!bestEdgeMatch || idx.isUnique)) {\n bestEdgeMatch = { isUnique: idx.isUnique, indexName: idx.index.name };\n }\n } else if (edge.tableB === nextIdx && winningOrder.includes(edge.tableA)) {\n const idx = findIndexOnColumn(nextTable, edge.colB);\n if (idx && (!bestEdgeMatch || idx.isUnique)) {\n bestEdgeMatch = { isUnique: idx.isUnique, indexName: idx.index.name };\n }\n }\n }\n\n if (bestEdgeMatch) {\n if (bestEdgeMatch.isUnique) {\n // Rank 1: Unique index join\n const seekCost = COST_INDEX_SEEK + 1 * COST_ROW_EVAL;\n candidates.push({\n tableIdx: nextIdx,\n rank: 1,\n stepCost: currentRows * seekCost,\n newRows: Math.max(1, currentRows),\n scanType: 'IndexScan',\n indexName: bestEdgeMatch.indexName,\n });\n } else {\n // Rank 2: Non-unique index join\n const avgDupes = Math.max(1, Math.min(10, Math.round(rowCount / 20)));\n const seekCost = COST_INDEX_SEEK + avgDupes * COST_INDEX_NEXT;\n candidates.push({\n tableIdx: nextIdx,\n rank: 2,\n stepCost: currentRows * seekCost,\n newRows: Math.max(1, currentRows * avgDupes),\n scanType: 'IndexScan',\n indexName: bestEdgeMatch.indexName,\n });\n }\n } else {\n // Rank 3: Cartesian / unindexed scan\n candidates.push({\n tableIdx: nextIdx,\n rank: 3,\n stepCost: currentRows * (2.0 + rowCount * 0.1),\n newRows: Math.max(1, currentRows * Math.max(1, Math.round(rowCount * 0.1))),\n scanType: 'TableScan',\n });\n }\n }\n\n if (candidates.length === 0) {\n // Fallback: pick any remaining table satisfying dependencies\n const fallbackIdx = remaining.values().next().value;\n if (fallbackIdx === undefined) break;\n winningOrder.push(fallbackIdx);\n chosenScanTypes.push('TableScan');\n chosenIndexNames.push(undefined);\n remaining.delete(fallbackIdx);\n continue;\n }\n\n // Sort candidates by rank, then stepCost, then table index\n candidates.sort((a, b) => {\n if (a.rank !== b.rank) return a.rank - b.rank;\n if (Math.abs(a.stepCost - b.stepCost) > 0.05) return a.stepCost - b.stepCost;\n return a.tableIdx - b.tableIdx;\n });\n\n const chosen = candidates[0];\n winningOrder.push(chosen.tableIdx);\n chosenScanTypes.push(chosen.scanType);\n chosenIndexNames.push(chosen.indexName);\n totalCost += chosen.stepCost;\n currentRows = chosen.newRows;\n remaining.delete(chosen.tableIdx);\n }\n\n const orderedTables = winningOrder.map((idx) => originalTables[idx]);\n const newJoinedPlans = reconstructJoinPlans(\n winningOrder,\n originalTables,\n edges,\n plan.joinedTables,\n );\n const effectiveSelectExprs = materializeOutputSelectExprs(plan, originalTables);\n\n const finalOrderSatisfied = baseStats[drivingIdx]?.isOrderSatisfied === true;\n const finalSortCostAvoided =\n finalOrderSatisfied && plan.orderBy && plan.orderBy.length > 0 && currentRows > 1\n ? currentRows * Math.log2(currentRows) * COST_ROW_EVAL\n : undefined;\n\n return {\n plan: {\n ...plan,\n table: orderedTables[0],\n joinedTables: newJoinedPlans,\n selectExprs: effectiveSelectExprs,\n isOrderSatisfied: finalOrderSatisfied,\n },\n orderedTables,\n metrics: {\n totalCost,\n estimatedRows: currentRows,\n joinOrder: orderedTables.map((t) => t.name),\n singleTableFilters,\n crossFilters,\n tableScanTypes: chosenScanTypes,\n tableIndexNames: chosenIndexNames,\n isOrderSatisfied: finalOrderSatisfied,\n sortCostAvoided: finalSortCostAvoided,\n },\n isOrderSatisfied: finalOrderSatisfied,\n sortCostAvoided: finalSortCostAvoided,\n };\n }\n}\n","import { TableMeta } from '../../../types/index.js';\nimport {\n QueryPlan,\n QueryFilter,\n buildRootFilter,\n getTopLevelConjunctionFilters,\n chooseJoinIndex,\n} from '../compiler.js';\nimport {\n QueryPlanner,\n OptimizedPlanResult,\n getFilterReferencedTables,\n getSingleTableBaseCost,\n materializeOutputSelectExprs,\n} from './types.js';\n\n/**\n * NoOpPlanner preserves the exact declared query join order (straight join).\n * It still partitions single-table filters for early pushdown without reordering tables.\n */\nexport class NoOpPlanner implements QueryPlanner {\n readonly name = 'noop';\n\n optimize(plan: QueryPlan): OptimizedPlanResult {\n const originalTables: TableMeta[] = [\n plan.table,\n ...(plan.joinedTables?.map((j) => j.table) ?? []),\n ];\n const N = originalTables.length;\n\n const rootFilter = buildRootFilter(plan.filters);\n const topConjunctions = getTopLevelConjunctionFilters(rootFilter);\n\n const singleTableFilters = new Map<number, QueryFilter[]>();\n const crossFilters: QueryFilter[] = [];\n\n for (let i = 0; i < N; i++) {\n singleTableFilters.set(i, []);\n }\n\n for (const filter of topConjunctions) {\n const refs = getFilterReferencedTables(filter, originalTables);\n if (refs.size === 1) {\n const tblIdx = refs.values().next().value;\n if (tblIdx !== undefined) {\n singleTableFilters.get(tblIdx)?.push(filter);\n }\n } else {\n crossFilters.push(filter);\n }\n }\n\n const baseTableCost = getSingleTableBaseCost(\n originalTables[0],\n singleTableFilters.get(0) ?? [],\n );\n\n const tableScanTypes: ('TableScan' | 'IndexScan')[] = [baseTableCost.scanType];\n const tableIndexNames: (string | undefined)[] = [baseTableCost.indexName];\n let totalCost = baseTableCost.cost;\n const estimatedRows = baseTableCost.rows;\n\n if (plan.joinedTables) {\n for (let i = 1; i < N; i++) {\n const jPlan = plan.joinedTables[i - 1];\n const cand = chooseJoinIndex(jPlan, originalTables[i], i, originalTables, i);\n if (cand) {\n tableScanTypes.push('IndexScan');\n tableIndexNames.push(cand.index.name);\n totalCost += estimatedRows * 0.55;\n } else {\n tableScanTypes.push('TableScan');\n tableIndexNames.push(undefined);\n totalCost += estimatedRows * (2.0 + (originalTables[i].rowCountEstimate || 10) * 0.1);\n }\n }\n }\n\n const effectiveSelectExprs = materializeOutputSelectExprs(plan, originalTables);\n\n return {\n plan: {\n ...plan,\n selectExprs: effectiveSelectExprs,\n },\n orderedTables: originalTables,\n metrics: {\n totalCost,\n estimatedRows,\n joinOrder: originalTables.map((t) => t.name),\n singleTableFilters,\n crossFilters,\n tableScanTypes,\n tableIndexNames,\n },\n };\n }\n}\n","import { TableMeta } from '../../../types/index.js';\nimport {\n QueryPlan,\n QueryFilter,\n buildRootFilter,\n getTopLevelConjunctionFilters,\n chooseJoinIndex,\n} from '../compiler.js';\nimport {\n QueryPlanner,\n OptimizedPlanResult,\n getFilterReferencedTables,\n getSingleTableBaseCost,\n buildJoinEdges,\n materializeOutputSelectExprs,\n reconstructJoinPlans,\n} from './types.js';\n\nexport type TableOrderComparator = (a: TableMeta, b: TableMeta) => number;\nexport type CustomOrderSpec = string[] | TableOrderComparator;\n\n/**\n * CustomOrderPlanner executes joins according to an explicit table order or custom comparator.\n * Join conditions and projections are automatically reconstructed to match the custom table order.\n */\nexport class CustomOrderPlanner implements QueryPlanner {\n readonly name = 'custom-order';\n private orderSpec?: CustomOrderSpec;\n\n constructor(orderSpec?: CustomOrderSpec) {\n this.orderSpec = orderSpec;\n }\n\n optimize(plan: QueryPlan): OptimizedPlanResult {\n const originalTables: TableMeta[] = [\n plan.table,\n ...(plan.joinedTables?.map((j) => j.table) ?? []),\n ];\n const N = originalTables.length;\n const isJoin = plan.joinedTables !== undefined && plan.joinedTables.length > 0;\n\n const rootFilter = buildRootFilter(plan.filters);\n const topConjunctions = getTopLevelConjunctionFilters(rootFilter);\n\n const singleTableFilters = new Map<number, QueryFilter[]>();\n const crossFilters: QueryFilter[] = [];\n\n for (let i = 0; i < N; i++) {\n singleTableFilters.set(i, []);\n }\n\n for (const filter of topConjunctions) {\n const refs = getFilterReferencedTables(filter, originalTables);\n if (refs.size === 1) {\n const tblIdx = refs.values().next().value;\n if (tblIdx !== undefined) {\n singleTableFilters.get(tblIdx)?.push(filter);\n }\n } else {\n crossFilters.push(filter);\n }\n }\n\n if (!isJoin || N <= 1) {\n const base = getSingleTableBaseCost(\n originalTables[0],\n singleTableFilters.get(0) ?? [],\n );\n return {\n plan,\n orderedTables: originalTables,\n metrics: {\n totalCost: base.cost,\n estimatedRows: base.rows,\n joinOrder: [originalTables[0].name],\n singleTableFilters,\n crossFilters,\n tableScanTypes: [base.scanType],\n tableIndexNames: [base.indexName],\n },\n };\n }\n\n // Determine custom order indices\n const customIndices: number[] = Array.from({ length: N }, (_, i) => i);\n\n if (this.orderSpec) {\n if (typeof this.orderSpec === 'function') {\n const comparator = this.orderSpec;\n customIndices.sort((a, b) => comparator(originalTables[a], originalTables[b]));\n } else if (Array.isArray(this.orderSpec)) {\n const list = this.orderSpec;\n customIndices.sort((a, b) => {\n const nameA = originalTables[a].name;\n const nameB = originalTables[b].name;\n const posA = list.indexOf(nameA);\n const posB = list.indexOf(nameB);\n const priorityA = posA === -1 ? 9999 : posA;\n const priorityB = posB === -1 ? 9999 : posB;\n if (priorityA !== priorityB) {\n return priorityA - priorityB;\n }\n return a - b; // preserve original relative order if not in list\n });\n }\n }\n\n const { edges } = buildJoinEdges(plan, originalTables);\n const orderedTables = customIndices.map((i) => originalTables[i]);\n const newJoinedPlans = reconstructJoinPlans(\n customIndices,\n originalTables,\n edges,\n plan.joinedTables,\n );\n const effectiveSelectExprs = materializeOutputSelectExprs(plan, originalTables);\n\n const orderedPlan: QueryPlan = {\n ...plan,\n table: orderedTables[0],\n joinedTables: newJoinedPlans,\n selectExprs: effectiveSelectExprs,\n };\n\n // Rebuild filter pushdowns for the reordered tables\n const reorderedSingleTableFilters = new Map<number, QueryFilter[]>();\n for (let i = 0; i < N; i++) {\n reorderedSingleTableFilters.set(i, []);\n }\n for (const filter of topConjunctions) {\n const refs = getFilterReferencedTables(filter, orderedTables);\n if (refs.size === 1) {\n const tblIdx = refs.values().next().value;\n if (tblIdx !== undefined) {\n reorderedSingleTableFilters.get(tblIdx)?.push(filter);\n }\n }\n }\n\n const baseTableCost = getSingleTableBaseCost(\n orderedTables[0],\n reorderedSingleTableFilters.get(0) ?? [],\n );\n\n const tableScanTypes: ('TableScan' | 'IndexScan')[] = [baseTableCost.scanType];\n const tableIndexNames: (string | undefined)[] = [baseTableCost.indexName];\n let totalCost = baseTableCost.cost;\n const estimatedRows = baseTableCost.rows;\n\n if (orderedPlan.joinedTables) {\n for (let i = 1; i < N; i++) {\n const jPlan = orderedPlan.joinedTables[i - 1];\n const cand = chooseJoinIndex(jPlan, orderedTables[i], i, orderedTables, i);\n if (cand) {\n tableScanTypes.push('IndexScan');\n tableIndexNames.push(cand.index.name);\n totalCost += estimatedRows * 0.55;\n } else {\n tableScanTypes.push('TableScan');\n tableIndexNames.push(undefined);\n totalCost += estimatedRows * (2.0 + (orderedTables[i].rowCountEstimate || 10) * 0.1);\n }\n }\n }\n\n return {\n plan: orderedPlan,\n orderedTables,\n metrics: {\n totalCost,\n estimatedRows,\n joinOrder: orderedTables.map((t) => t.name),\n singleTableFilters: reorderedSingleTableFilters,\n crossFilters,\n tableScanTypes,\n tableIndexNames,\n },\n };\n }\n}\n","import { QueryPlan } from '../compiler.js';\nimport {\n QueryPlanner,\n OptimizedPlanResult,\n} from './types.js';\nimport { CostBasedPlanner } from './cost.js';\nimport { HeuristicPlanner } from './heuristic.js';\nimport { NoOpPlanner } from './noop.js';\n\nexport * from './types.js';\nexport * from './cost.js';\nexport * from './heuristic.js';\nexport * from './noop.js';\nexport * from './custom_order.js';\nexport * from './where_optimizer.js';\n\n/**\n * CustomPlanner allows supplying a custom optimization function.\n */\nexport class CustomPlanner implements QueryPlanner {\n readonly name = 'custom';\n constructor(private fn: (plan: QueryPlan) => OptimizedPlanResult) {}\n optimize(plan: QueryPlan): OptimizedPlanResult {\n return this.fn(plan);\n }\n}\n\nexport const CustomQueryPlanner = CustomPlanner;\nexport const DefaultQueryPlanner = CostBasedPlanner;\nexport const CostBasedQueryPlanner = CostBasedPlanner;\nexport const HeuristicQueryPlanner = HeuristicPlanner;\nexport const NoOpQueryPlanner = NoOpPlanner;\n\nconst defaultPlanner = new CostBasedPlanner();\n\n/**\n * Resolves a QueryPlanner instance, defaulting to CostBasedPlanner.\n */\nexport function resolveQueryPlanner(\n planner?: QueryPlanner | null,\n): QueryPlanner {\n return planner ?? defaultPlanner;\n}\n\n/**\n * Optimizes a complete QueryPlan using the resolved QueryPlanner.\n */\nexport function optimizeQueryPlan(\n plan: QueryPlan,\n planner?: QueryPlanner | null,\n): OptimizedPlanResult {\n const activePlanner = resolveQueryPlanner(planner);\n return activePlanner.optimize(plan);\n}\n","import {\n OpCode,\n DataType,\n TableMeta,\n ColumnMeta,\n ColumnFlag,\n IndexFlag,\n IndexDescriptor,\n TooManyRegistersError,\n TooManyOrderByColumnsError,\n TooManyGroupByColumnsError,\n TooManyCursorsError,\n UnknownFunctionError,\n JoinType,\n} from \"../../types/index.js\";\nimport { serialize_composite_key } from \"../../core/index.js\";\nimport { VmKeyInfo } from \"../../shared/vm_context.js\";\nimport { MAX_IN_LIST_SIZE } from \"../../constants.js\";\nimport {\n ExprNode,\n ParsedSelectExpr,\n parseExpression,\n deriveDefaultAlias,\n} from \"./expr_parser.js\";\nimport { QueryPlanner, resolveQueryPlanner } from \"./planner.js\";\n\nexport type ComparisonOp =\n | \"=\"\n | \"!=\"\n | \">\"\n | \">=\"\n | \"<\"\n | \"<=\"\n | \"like\"\n | \"not like\"\n | \"contains\"\n | \"starts_with\"\n | \"ends_with\"\n | \"in\"\n | \"not in\";\n\nexport function getCmpOpcode(op: string | undefined): OpCode {\n if (!op) return OpCode.OP_EQ;\n const norm = String(op).trim().toLowerCase().replace(/\\s+/g, \" \");\n switch (norm) {\n case \"=\":\n case \"==\":\n return OpCode.OP_EQ;\n case \"!=\":\n case \"<>\":\n return OpCode.OP_NE;\n case \">\":\n return OpCode.OP_GT;\n case \">=\":\n return OpCode.OP_GE;\n case \"<\":\n return OpCode.OP_LT;\n case \"<=\":\n return OpCode.OP_LE;\n case \"like\":\n return OpCode.OP_STR_LIKE;\n case \"not like\":\n return OpCode.OP_STR_NOT_LIKE;\n case \"contains\":\n return OpCode.OP_STR_CONTAINS;\n case \"starts_with\":\n return OpCode.OP_STR_STARTS_WITH;\n case \"ends_with\":\n return OpCode.OP_STR_ENDS_WITH;\n default:\n return OpCode.OP_EQ;\n }\n}\n\nexport type QueryFilterType =\n | \"null\"\n | \"cmp\"\n | \"expr\"\n | \"and\"\n | \"or\"\n | \"not\"\n | \"in\";\n\nexport interface QueryFilter {\n type: QueryFilterType;\n colName?: string;\n isNull?: boolean; // true for isNull, false for isNotNull\n op?: ComparisonOp;\n value?: any;\n values?: any[];\n notIn?: boolean;\n expr?: ExprNode;\n children?: QueryFilter[]; // for 'and', 'or'\n child?: QueryFilter; // for 'not'\n}\n\nexport interface SortKey {\n colName?: string;\n expr?: ExprNode;\n direction?: \"asc\" | \"desc\";\n nullOrder?: \"nulls_first\" | \"nulls_last\";\n}\n\nexport interface GroupKey {\n colName?: string;\n expr?: ExprNode;\n}\n\nexport type AggFunc = \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\nexport interface AggExpr {\n func: AggFunc;\n colName?: string;\n alias?: string;\n}\n\nexport interface JoinPlan {\n type: JoinType;\n table: TableMeta;\n cursor: number;\n leftCol: string;\n op: ComparisonOp;\n rightCol: string;\n}\n\nexport interface QueryPlan {\n table: TableMeta;\n joinedTables?: JoinPlan[];\n filters: QueryFilter[];\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n selectExprs?: ParsedSelectExpr[];\n udfNameMap?: Map<string, number>;\n udfDefs?: Map<string, { returnType?: DataType }>;\n keyInfos?: VmKeyInfo[];\n outputColumns?: ColumnMeta[];\n limit?: number;\n offset?: number;\n planner?: QueryPlanner;\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n}\n\nexport class BytecodeEmitter {\n private buffer: number[] = [];\n private textEncoder = new TextEncoder();\n\n emitUint8(val: number): number {\n const pos = this.buffer.length;\n this.buffer.push(val & 0xff);\n return pos;\n }\n\n emitUint16(val: number): number {\n const pos = this.buffer.length;\n this.buffer.push(val & 0xff);\n this.buffer.push((val >> 8) & 0xff);\n return pos;\n }\n\n emitUint32(val: number): number {\n const pos = this.buffer.length;\n this.buffer.push(val & 0xff);\n this.buffer.push((val >> 8) & 0xff);\n this.buffer.push((val >> 16) & 0xff);\n this.buffer.push((val >> 24) & 0xff);\n return pos;\n }\n\n emitInt32(val: number): number {\n return this.emitUint32(val);\n }\n\n emitFloat64(val: number): number {\n const pos = this.buffer.length;\n const buf = new ArrayBuffer(8);\n new DataView(buf).setFloat64(0, val, true);\n const u8 = new Uint8Array(buf);\n for (let i = 0; i < 8; i++) {\n this.buffer.push(u8[i]);\n }\n return pos;\n }\n\n emitString(str: string): number {\n const bytes = this.textEncoder.encode(str);\n const pos = this.emitUint16(bytes.byteLength);\n for (let i = 0; i < bytes.byteLength; i++) {\n this.buffer.push(bytes[i]);\n }\n return pos;\n }\n\n emitBytes(bytes: Uint8Array): number {\n const pos = this.emitUint16(bytes.byteLength);\n for (let i = 0; i < bytes.byteLength; i++) {\n this.buffer.push(bytes[i]);\n }\n return pos;\n }\n\n patchUint16(pos: number, val: number): void {\n this.buffer[pos] = val & 0xff;\n this.buffer[pos + 1] = (val >> 8) & 0xff;\n }\n\n currentOffset(): number {\n return this.buffer.length;\n }\n\n toByteArray(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n\nfunction emitReadColumn(\n emitter: BytecodeEmitter,\n cursor: number,\n colIdx: number,\n destReg: number,\n colType: DataType,\n): void {\n if (colType === DataType.INT32 || colType === DataType.INT64) {\n emitter.emitUint8(OpCode.OP_COLUMN_INT);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n } else if (colType === DataType.FLOAT64) {\n emitter.emitUint8(OpCode.OP_COLUMN_FLOAT);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n } else if (colType === DataType.TEXT) {\n emitter.emitUint8(OpCode.OP_COLUMN_TEXT);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n } else if (colType === DataType.UUID) {\n emitter.emitUint8(OpCode.OP_COLUMN_UUID);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n } else if (colType === DataType.ULID) {\n emitter.emitUint8(OpCode.OP_COLUMN_ULID);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n } else if (colType === DataType.BLOB) {\n emitter.emitUint8(OpCode.OP_COLUMN_BLOB);\n emitter.emitUint8(cursor);\n emitter.emitUint8(colIdx);\n emitter.emitUint8(destReg);\n }\n}\n\nexport function normalizeFilter(filter: QueryFilter): QueryFilter {\n if (filter.type === \"in\") {\n if (filter.values && filter.values.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: whereIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n return {\n type: \"in\",\n colName: filter.colName,\n expr: filter.expr,\n values: filter.values ? Array.from(new Set(filter.values)) : [],\n notIn: !!filter.notIn,\n };\n }\n\n if (filter.type === \"cmp\") {\n const opNorm = filter.op ? String(filter.op).trim().toLowerCase() : \"\";\n if (opNorm === \"in\" || opNorm === \"not in\") {\n const arr = Array.isArray(filter.value) ? filter.value : [filter.value];\n if (arr.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: whereIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n return {\n type: \"in\",\n colName: filter.colName,\n expr: filter.expr,\n values: Array.from(new Set(arr)),\n notIn: opNorm === \"not in\",\n };\n }\n }\n\n if (filter.type === \"and\") {\n return {\n type: \"and\",\n children: filter.children ? filter.children.map(normalizeFilter) : [],\n };\n }\n\n if (filter.type === \"or\") {\n return {\n type: \"or\",\n children: filter.children ? filter.children.map(normalizeFilter) : [],\n };\n }\n\n if (filter.type === \"not\") {\n const child = filter.child;\n if (!child) return filter;\n\n // Double negation: NOT (NOT x) => x\n if (child.type === \"not\" && child.child) {\n return normalizeFilter(child.child);\n }\n\n // NOT (x IN (A)) => x NOT IN (A)\n // NOT (x NOT IN (A)) => x IN (A)\n if (child.type === \"in\") {\n return {\n type: \"in\",\n colName: child.colName,\n expr: child.expr,\n values: child.values,\n notIn: !child.notIn,\n };\n }\n\n // De Morgan: NOT (A AND B) => (NOT A) OR (NOT B)\n if (child.type === \"and\") {\n return {\n type: \"or\",\n children: child.children\n ? child.children.map((c) =>\n normalizeFilter({ type: \"not\", child: c }),\n )\n : [],\n };\n }\n\n // De Morgan: NOT (A OR B) => (NOT A) AND (NOT B)\n if (child.type === \"or\") {\n return {\n type: \"and\",\n children: child.children\n ? child.children.map((c) =>\n normalizeFilter({ type: \"not\", child: c }),\n )\n : [],\n };\n }\n\n // NOT (col IS NULL) => col IS NOT NULL\n // NOT (col IS NOT NULL) => col IS NULL\n if (child.type === \"null\") {\n return {\n type: \"null\",\n colName: child.colName,\n isNull: !child.isNull,\n };\n }\n\n // NOT (cmp)\n if (child.type === \"cmp\") {\n const opNorm = child.op ? String(child.op).trim().toLowerCase() : \"\";\n if (opNorm === \"in\" || opNorm === \"not in\") {\n return normalizeFilter({\n type: \"in\",\n colName: child.colName,\n expr: child.expr,\n values: Array.isArray(child.value) ? child.value : [child.value],\n notIn: opNorm === \"in\", // inverted\n });\n }\n\n const inverseOps: Record<string, ComparisonOp> = {\n \"=\": \"!=\",\n \"!=\": \"=\",\n \">\": \"<=\",\n \">=\": \"<\",\n \"<\": \">=\",\n \"<=\": \">\",\n like: \"not like\",\n \"not like\": \"like\",\n };\n\n if (child.op && inverseOps[child.op]) {\n return {\n type: \"cmp\",\n colName: child.colName,\n op: inverseOps[child.op],\n value: child.value,\n };\n }\n\n // For CONTAINS, STARTS_WITH, ENDS_WITH:\n // In 3VL: NOT(col CONTAINS val) requires col IS NOT NULL AND NOT(col CONTAINS val)\n return {\n type: \"and\",\n children: [\n { type: \"null\", colName: child.colName, isNull: false },\n { type: \"not\", child },\n ],\n };\n }\n }\n\n return filter;\n}\n\nexport function buildRootFilter(filters: QueryFilter[]): QueryFilter | null {\n if (!filters || filters.length === 0) return null;\n const rawRoot: QueryFilter =\n filters.length === 1 ? filters[0] : { type: \"and\", children: filters };\n return normalizeFilter(rawRoot);\n}\n\nexport function collectLeafFilters(filter: QueryFilter): QueryFilter[] {\n const leaves: QueryFilter[] = [];\n const seen = new Set<QueryFilter>();\n function traverse(f: QueryFilter) {\n if (\n f.type === \"null\" ||\n f.type === \"cmp\" ||\n f.type === \"expr\" ||\n f.type === \"in\"\n ) {\n if (!seen.has(f)) {\n seen.add(f);\n leaves.push(f);\n }\n } else if (f.type === \"and\" || f.type === \"or\") {\n if (f.children) {\n for (const child of f.children) {\n traverse(child);\n }\n }\n } else if (f.type === \"not\") {\n if (f.child) {\n traverse(f.child);\n }\n }\n }\n traverse(filter);\n return leaves;\n}\n\nexport function getTopLevelConjunctionFilters(\n rootFilter: QueryFilter | null,\n): QueryFilter[] {\n if (!rootFilter) return [];\n const conjunctions: QueryFilter[] = [];\n function gather(f: QueryFilter) {\n if (f.type === \"and\" && f.children) {\n for (const child of f.children) {\n gather(child);\n }\n } else if (f.type === \"cmp\" || f.type === \"in\" || f.type === \"null\") {\n conjunctions.push(f);\n }\n }\n gather(rootFilter);\n return conjunctions;\n}\n\nexport interface ResolvedColumn {\n tableIdx: number;\n cursor: number;\n colIdx: number;\n col: ColumnMeta;\n table: TableMeta;\n}\n\nexport function resolveColumnAcrossTables(\n colName: string,\n tables: TableMeta[],\n): ResolvedColumn | null {\n if (colName.includes(\".\")) {\n const parts = colName.split(\".\");\n const tblName = parts[0];\n const cName = parts[1];\n const tableIdx = tables.findIndex(\n (t) => t.name.toLowerCase() === tblName.toLowerCase(),\n );\n if (tableIdx === -1) return null;\n const colIdx = tables[tableIdx].columns.findIndex(\n (c) => c.name.toLowerCase() === cName.toLowerCase(),\n );\n if (colIdx === -1) return null;\n return {\n tableIdx,\n cursor: tableIdx,\n colIdx,\n col: tables[tableIdx].columns[colIdx],\n table: tables[tableIdx],\n };\n }\n\n // Unqualified column name: search tables in order\n for (let i = 0; i < tables.length; i++) {\n const colIdx = tables[i].columns.findIndex(\n (c) => c.name.toLowerCase() === colName.toLowerCase(),\n );\n if (colIdx !== -1) {\n return {\n tableIdx: i,\n cursor: i,\n colIdx,\n col: tables[i].columns[colIdx],\n table: tables[i],\n };\n }\n }\n\n return null;\n}\n\nfunction emitLeafJumpOnTrue(\n filter: QueryFilter,\n leafIdx: number,\n table: TableMeta,\n emitter: BytecodeEmitter,\n truePatches: number[],\n udfNameMap?: Map<string, number>,\n tables?: TableMeta[],\n filterSetMap?: Map<QueryFilter, number>,\n): void {\n const all = tables ?? [table];\n if (filter.type === \"expr\") {\n const regRes = leafIdx * 2;\n const regOne = leafIdx * 2 + 1;\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr!,\n table,\n emitter,\n 0,\n regRes,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regOne);\n emitter.emitInt32(1);\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regRes);\n emitter.emitUint8(regOne);\n truePatches.push(emitter.emitUint16(0));\n return;\n }\n\n if (filter.type === \"null\") {\n if (!filter.colName) {\n throw new Error(`Filter leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (!resolved) {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n if (filter.isNull) {\n emitter.emitUint8(OpCode.OP_IS_NULL);\n } else {\n emitter.emitUint8(OpCode.OP_IS_NOT_NULL);\n }\n emitter.emitUint8(resolved.cursor);\n emitter.emitUint8(resolved.colIdx);\n truePatches.push(emitter.emitUint16(0));\n return;\n }\n\n if (filter.type === \"in\") {\n if (!filter.values || filter.values.length === 0) {\n if (filter.notIn) {\n emitter.emitUint8(OpCode.OP_JUMP);\n truePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n const regCol = leafIdx * 2;\n if (filter.expr) {\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } else {\n if (!filter.colName) {\n throw new Error(`Filter IN leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitReadColumn(\n emitter,\n resolved.cursor,\n resolved.colIdx,\n regCol,\n resolved.col.type,\n );\n } else {\n try {\n const parsed = parseExpression(filter.colName);\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } catch {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n }\n }\n\n const setIdx = filterSetMap?.get(filter) ?? 0;\n if (!filter.notIn) {\n emitter.emitUint8(OpCode.OP_IN);\n emitter.emitUint8(regCol);\n emitter.emitUint16(setIdx);\n truePatches.push(emitter.emitUint16(0));\n } else {\n let nullSkipPatch = -1;\n if (filter.colName) {\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitter.emitUint8(OpCode.OP_IS_NULL);\n emitter.emitUint8(resolved.cursor);\n emitter.emitUint8(resolved.colIdx);\n nullSkipPatch = emitter.emitUint16(0);\n }\n }\n\n emitter.emitUint8(OpCode.OP_IN);\n emitter.emitUint8(regCol);\n emitter.emitUint16(setIdx);\n const inSkipPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n truePatches.push(emitter.emitUint16(0));\n\n const notInTruePos = emitter.currentOffset();\n if (nullSkipPatch !== -1) {\n emitter.patchUint16(nullSkipPatch, notInTruePos);\n }\n emitter.patchUint16(inSkipPatch, notInTruePos);\n }\n return;\n }\n\n const regCol = leafIdx * 2;\n const regConst = leafIdx * 2 + 1;\n\n if (filter.expr) {\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } else {\n if (!filter.colName) {\n throw new Error(`Filter leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitReadColumn(\n emitter,\n resolved.cursor,\n resolved.colIdx,\n regCol,\n resolved.col.type,\n );\n } else {\n try {\n const parsed = parseExpression(filter.colName);\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } catch {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n }\n }\n\n const cmpOpcode = getCmpOpcode(filter.op);\n\n emitter.emitUint8(cmpOpcode);\n emitter.emitUint8(regCol);\n emitter.emitUint8(regConst);\n truePatches.push(emitter.emitUint16(0));\n}\n\nfunction emitLeafJumpOnFalse(\n filter: QueryFilter,\n leafIdx: number,\n table: TableMeta,\n emitter: BytecodeEmitter,\n falsePatches: number[],\n udfNameMap?: Map<string, number>,\n tables?: TableMeta[],\n filterSetMap?: Map<QueryFilter, number>,\n): void {\n const all = tables ?? [table];\n if (filter.type === \"expr\") {\n const regRes = leafIdx * 2;\n const regOne = leafIdx * 2 + 1;\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr!,\n table,\n emitter,\n 0,\n regRes,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regOne);\n emitter.emitInt32(1);\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regRes);\n emitter.emitUint8(regOne);\n const passPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n\n emitter.patchUint16(passPatch, emitter.currentOffset());\n return;\n }\n\n if (filter.type === \"null\") {\n if (!filter.colName) {\n throw new Error(`Filter leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (!resolved) {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n if (filter.isNull) {\n emitter.emitUint8(OpCode.OP_IS_NOT_NULL);\n } else {\n emitter.emitUint8(OpCode.OP_IS_NULL);\n }\n emitter.emitUint8(resolved.cursor);\n emitter.emitUint8(resolved.colIdx);\n falsePatches.push(emitter.emitUint16(0));\n return;\n }\n\n if (filter.type === \"in\") {\n if (!filter.values || filter.values.length === 0) {\n if (!filter.notIn) {\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n const regCol = leafIdx * 2;\n if (filter.expr) {\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } else {\n if (!filter.colName) {\n throw new Error(`Filter IN leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitReadColumn(\n emitter,\n resolved.cursor,\n resolved.colIdx,\n regCol,\n resolved.col.type,\n );\n } else {\n try {\n const parsed = parseExpression(filter.colName);\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } catch {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n }\n }\n\n const setIdx = filterSetMap?.get(filter) ?? 0;\n if (!filter.notIn) {\n if (filter.colName) {\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitter.emitUint8(OpCode.OP_IS_NULL);\n emitter.emitUint8(resolved.cursor);\n emitter.emitUint8(resolved.colIdx);\n falsePatches.push(emitter.emitUint16(0));\n }\n }\n\n emitter.emitUint8(OpCode.OP_IN);\n emitter.emitUint8(regCol);\n emitter.emitUint16(setIdx);\n const matchPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n\n const passPos = emitter.currentOffset();\n emitter.patchUint16(matchPatch, passPos);\n } else {\n if (filter.colName) {\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitter.emitUint8(OpCode.OP_IS_NULL);\n emitter.emitUint8(resolved.cursor);\n emitter.emitUint8(resolved.colIdx);\n falsePatches.push(emitter.emitUint16(0));\n }\n }\n\n emitter.emitUint8(OpCode.OP_IN);\n emitter.emitUint8(regCol);\n emitter.emitUint16(setIdx);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n const regCol = leafIdx * 2;\n const regConst = leafIdx * 2 + 1;\n\n if (filter.expr) {\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n filter.expr,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } else {\n if (!filter.colName) {\n throw new Error(`Filter leaf node missing colName`);\n }\n const resolved = resolveColumnAcrossTables(filter.colName, all);\n if (resolved) {\n emitReadColumn(\n emitter,\n resolved.cursor,\n resolved.colIdx,\n regCol,\n resolved.col.type,\n );\n } else {\n try {\n const parsed = parseExpression(filter.colName);\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n regCol,\n allocReg,\n udfNameMap,\n undefined,\n all,\n );\n } catch {\n throw new Error(`Column \"${filter.colName}\" not found in tables`);\n }\n }\n }\n\n const cmpOpcode = getCmpOpcode(filter.op);\n\n emitter.emitUint8(cmpOpcode);\n emitter.emitUint8(regCol);\n emitter.emitUint8(regConst);\n const passPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n\n emitter.patchUint16(passPatch, emitter.currentOffset());\n}\n\nfunction emitLeafCondition(\n filter: QueryFilter,\n leafIdx: number,\n table: TableMeta,\n emitter: BytecodeEmitter,\n truePatches: number[],\n falsePatches: number[],\n fallthrough: \"true\" | \"false\" | \"none\",\n udfNameMap?: Map<string, number>,\n tables?: TableMeta[],\n filterSetMap?: Map<QueryFilter, number>,\n): void {\n if (fallthrough === \"true\") {\n emitLeafJumpOnFalse(\n filter,\n leafIdx,\n table,\n emitter,\n falsePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n } else if (fallthrough === \"false\") {\n emitLeafJumpOnTrue(\n filter,\n leafIdx,\n table,\n emitter,\n truePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n } else {\n emitLeafJumpOnTrue(\n filter,\n leafIdx,\n table,\n emitter,\n truePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n}\n\nfunction compileFilterNode(\n node: QueryFilter,\n emitter: BytecodeEmitter,\n table: TableMeta,\n leafRegMap: Map<QueryFilter, number>,\n truePatches: number[],\n falsePatches: number[],\n fallthrough: \"true\" | \"false\" | \"none\",\n udfNameMap?: Map<string, number>,\n tables?: TableMeta[],\n filterSetMap?: Map<QueryFilter, number>,\n): void {\n if (\n node.type === \"cmp\" ||\n node.type === \"null\" ||\n node.type === \"expr\" ||\n node.type === \"in\"\n ) {\n const leafIdx = leafRegMap.get(node) ?? 0;\n emitLeafCondition(\n node,\n leafIdx,\n table,\n emitter,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n tables,\n filterSetMap,\n );\n return;\n }\n\n if (node.type === \"not\") {\n if (!node.child) {\n return;\n }\n const leaf = node.child;\n const leafIdx = leafRegMap.get(leaf) ?? 0;\n if (fallthrough === \"true\") {\n emitLeafJumpOnTrue(\n leaf,\n leafIdx,\n table,\n emitter,\n falsePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n } else if (fallthrough === \"false\") {\n emitLeafJumpOnFalse(\n leaf,\n leafIdx,\n table,\n emitter,\n truePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n } else {\n emitLeafJumpOnFalse(\n leaf,\n leafIdx,\n table,\n emitter,\n truePatches,\n udfNameMap,\n tables,\n filterSetMap,\n );\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n if (node.type === \"and\") {\n const children = node.children ?? [];\n if (children.length === 0) {\n if (fallthrough === \"false\") {\n emitter.emitUint8(OpCode.OP_JUMP);\n truePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const isLast = i === children.length - 1;\n if (!isLast) {\n const subTruePatches: number[] = [];\n compileFilterNode(\n child,\n emitter,\n table,\n leafRegMap,\n subTruePatches,\n falsePatches,\n \"true\",\n udfNameMap,\n tables,\n filterSetMap,\n );\n const nextChildPos = emitter.currentOffset();\n for (const patch of subTruePatches) {\n emitter.patchUint16(patch, nextChildPos);\n }\n } else {\n compileFilterNode(\n child,\n emitter,\n table,\n leafRegMap,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n tables,\n filterSetMap,\n );\n }\n }\n return;\n }\n\n if (node.type === \"or\") {\n const children = node.children ?? [];\n if (children.length === 0) {\n if (fallthrough === \"true\") {\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const isLast = i === children.length - 1;\n if (!isLast) {\n const subFalsePatches: number[] = [];\n compileFilterNode(\n child,\n emitter,\n table,\n leafRegMap,\n truePatches,\n subFalsePatches,\n \"false\",\n udfNameMap,\n tables,\n filterSetMap,\n );\n const nextChildPos = emitter.currentOffset();\n for (const patch of subFalsePatches) {\n emitter.patchUint16(patch, nextChildPos);\n }\n } else {\n compileFilterNode(\n child,\n emitter,\n table,\n leafRegMap,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n tables,\n filterSetMap,\n );\n }\n }\n return;\n }\n}\n\nfunction emitHavingLeafJumpOnFalse(\n filter: QueryFilter,\n table: TableMeta,\n emitter: BytecodeEmitter,\n resolveReg: (name?: string, expr?: ExprNode) => number | undefined,\n allocReg: () => number,\n falsePatches: number[],\n udfNameMap?: Map<string, number>,\n): void {\n if (filter.type === \"cmp\") {\n let regLhs: number;\n const resolved = resolveReg(filter.colName, filter.expr);\n if (resolved !== undefined) {\n regLhs = resolved;\n } else if (filter.expr) {\n regLhs = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else if (filter.colName) {\n regLhs = allocReg();\n const parsed = parseExpression(filter.colName);\n emitExpression(\n parsed,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else {\n regLhs = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regLhs);\n }\n\n const regConst = allocReg();\n const val = filter.value;\n if (val === null || val === undefined) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regConst);\n } else if (typeof val === \"number\") {\n if (Number.isInteger(val)) {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(val);\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(regConst);\n emitter.emitFloat64(val);\n }\n } else if (typeof val === \"string\") {\n emitter.emitUint8(OpCode.OP_LOAD_TEXT);\n emitter.emitUint8(regConst);\n emitter.emitString(val);\n } else if (typeof val === \"boolean\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(val ? 1 : 0);\n } else if (typeof val === \"bigint\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(Number(val));\n }\n\n const cmpOpcode = getCmpOpcode(filter.op);\n\n emitter.emitUint8(cmpOpcode);\n emitter.emitUint8(regLhs);\n emitter.emitUint8(regConst);\n const passPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n\n emitter.patchUint16(passPatch, emitter.currentOffset());\n return;\n }\n\n if (filter.type === \"null\") {\n let regLhs: number;\n const resolved = resolveReg(filter.colName, filter.expr);\n if (resolved !== undefined) {\n regLhs = resolved;\n } else if (filter.expr) {\n regLhs = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else if (filter.colName) {\n regLhs = allocReg();\n const parsed = parseExpression(filter.colName);\n emitExpression(\n parsed,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else {\n regLhs = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regLhs);\n }\n\n if (filter.isNull) {\n emitter.emitUint8(OpCode.OP_REG_IS_NOT_NULL);\n emitter.emitUint8(regLhs);\n falsePatches.push(emitter.emitUint16(0));\n } else {\n emitter.emitUint8(OpCode.OP_REG_IS_NULL);\n emitter.emitUint8(regLhs);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n if (filter.type === \"expr\" && filter.expr) {\n const regRes = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regRes,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n\n const regOne = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regOne);\n emitter.emitInt32(1);\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regRes);\n emitter.emitUint8(regOne);\n const passPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n\n emitter.patchUint16(passPatch, emitter.currentOffset());\n return;\n }\n}\n\nfunction emitHavingLeafJumpOnTrue(\n filter: QueryFilter,\n table: TableMeta,\n emitter: BytecodeEmitter,\n resolveReg: (name?: string, expr?: ExprNode) => number | undefined,\n allocReg: () => number,\n truePatches: number[],\n udfNameMap?: Map<string, number>,\n): void {\n if (filter.type === \"cmp\") {\n let regLhs: number;\n const resolved = resolveReg(filter.colName, filter.expr);\n if (resolved !== undefined) {\n regLhs = resolved;\n } else if (filter.expr) {\n regLhs = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else if (filter.colName) {\n regLhs = allocReg();\n const parsed = parseExpression(filter.colName);\n emitExpression(\n parsed,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else {\n regLhs = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regLhs);\n }\n\n const regConst = allocReg();\n const val = filter.value;\n if (val === null || val === undefined) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regConst);\n } else if (typeof val === \"number\") {\n if (Number.isInteger(val)) {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(val);\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(regConst);\n emitter.emitFloat64(val);\n }\n } else if (typeof val === \"string\") {\n emitter.emitUint8(OpCode.OP_LOAD_TEXT);\n emitter.emitUint8(regConst);\n emitter.emitString(val);\n } else if (typeof val === \"boolean\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(val ? 1 : 0);\n } else if (typeof val === \"bigint\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(Number(val));\n }\n\n const cmpOpcode = getCmpOpcode(filter.op);\n\n emitter.emitUint8(cmpOpcode);\n emitter.emitUint8(regLhs);\n emitter.emitUint8(regConst);\n truePatches.push(emitter.emitUint16(0));\n return;\n }\n\n if (filter.type === \"null\") {\n let regLhs: number;\n const resolved = resolveReg(filter.colName, filter.expr);\n if (resolved !== undefined) {\n regLhs = resolved;\n } else if (filter.expr) {\n regLhs = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else if (filter.colName) {\n regLhs = allocReg();\n const parsed = parseExpression(filter.colName);\n emitExpression(\n parsed,\n table,\n emitter,\n -1,\n regLhs,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n } else {\n regLhs = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regLhs);\n }\n\n if (filter.isNull) {\n emitter.emitUint8(OpCode.OP_REG_IS_NULL);\n emitter.emitUint8(regLhs);\n truePatches.push(emitter.emitUint16(0));\n } else {\n emitter.emitUint8(OpCode.OP_REG_IS_NOT_NULL);\n emitter.emitUint8(regLhs);\n truePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n if (filter.type === \"expr\" && filter.expr) {\n const regRes = allocReg();\n emitExpression(\n filter.expr,\n table,\n emitter,\n -1,\n regRes,\n allocReg,\n udfNameMap,\n resolveReg,\n );\n\n const regOne = allocReg();\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regOne);\n emitter.emitInt32(1);\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regRes);\n emitter.emitUint8(regOne);\n truePatches.push(emitter.emitUint16(0));\n return;\n }\n}\n\nfunction emitHavingLeafCondition(\n filter: QueryFilter,\n table: TableMeta,\n emitter: BytecodeEmitter,\n resolveReg: (name?: string, expr?: ExprNode) => number | undefined,\n allocReg: () => number,\n truePatches: number[],\n falsePatches: number[],\n fallthrough: \"true\" | \"false\" | \"none\",\n udfNameMap?: Map<string, number>,\n): void {\n if (fallthrough === \"true\") {\n emitHavingLeafJumpOnFalse(\n filter,\n table,\n emitter,\n resolveReg,\n allocReg,\n falsePatches,\n udfNameMap,\n );\n } else if (fallthrough === \"false\") {\n emitHavingLeafJumpOnTrue(\n filter,\n table,\n emitter,\n resolveReg,\n allocReg,\n truePatches,\n udfNameMap,\n );\n } else {\n emitHavingLeafJumpOnTrue(\n filter,\n table,\n emitter,\n resolveReg,\n allocReg,\n truePatches,\n udfNameMap,\n );\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n}\n\nfunction compileHavingFilterNode(\n node: QueryFilter,\n emitter: BytecodeEmitter,\n table: TableMeta,\n resolveReg: (name?: string, expr?: ExprNode) => number | undefined,\n allocReg: () => number,\n truePatches: number[],\n falsePatches: number[],\n fallthrough: \"true\" | \"false\" | \"none\",\n udfNameMap?: Map<string, number>,\n): void {\n if (node.type === \"cmp\" || node.type === \"null\" || node.type === \"expr\") {\n emitHavingLeafCondition(\n node,\n table,\n emitter,\n resolveReg,\n allocReg,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n );\n return;\n }\n\n if (node.type === \"not\") {\n if (!node.child) return;\n const leaf = node.child;\n if (fallthrough === \"true\") {\n compileHavingFilterNode(\n leaf,\n emitter,\n table,\n resolveReg,\n allocReg,\n falsePatches,\n truePatches,\n \"false\",\n udfNameMap,\n );\n } else if (fallthrough === \"false\") {\n compileHavingFilterNode(\n leaf,\n emitter,\n table,\n resolveReg,\n allocReg,\n truePatches,\n falsePatches,\n \"true\",\n udfNameMap,\n );\n } else {\n compileHavingFilterNode(\n leaf,\n emitter,\n table,\n resolveReg,\n allocReg,\n falsePatches,\n truePatches,\n \"none\",\n udfNameMap,\n );\n }\n return;\n }\n\n if (node.type === \"and\") {\n const children = node.children ?? [];\n if (children.length === 0) {\n if (fallthrough === \"false\") {\n emitter.emitUint8(OpCode.OP_JUMP);\n truePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const isLast = i === children.length - 1;\n if (!isLast) {\n const subTruePatches: number[] = [];\n compileHavingFilterNode(\n child,\n emitter,\n table,\n resolveReg,\n allocReg,\n subTruePatches,\n falsePatches,\n \"true\",\n udfNameMap,\n );\n const nextChildPos = emitter.currentOffset();\n for (const patch of subTruePatches) {\n emitter.patchUint16(patch, nextChildPos);\n }\n } else {\n compileHavingFilterNode(\n child,\n emitter,\n table,\n resolveReg,\n allocReg,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n );\n }\n }\n return;\n }\n\n if (node.type === \"or\") {\n const children = node.children ?? [];\n if (children.length === 0) {\n if (fallthrough === \"true\") {\n emitter.emitUint8(OpCode.OP_JUMP);\n falsePatches.push(emitter.emitUint16(0));\n }\n return;\n }\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const isLast = i === children.length - 1;\n if (!isLast) {\n const subFalsePatches: number[] = [];\n compileHavingFilterNode(\n child,\n emitter,\n table,\n resolveReg,\n allocReg,\n truePatches,\n subFalsePatches,\n \"false\",\n udfNameMap,\n );\n const nextChildPos = emitter.currentOffset();\n for (const patch of subFalsePatches) {\n emitter.patchUint16(patch, nextChildPos);\n }\n } else {\n compileHavingFilterNode(\n child,\n emitter,\n table,\n resolveReg,\n allocReg,\n truePatches,\n falsePatches,\n fallthrough,\n udfNameMap,\n );\n }\n }\n return;\n }\n}\n\nfunction emitHavingTree(\n root: QueryFilter | null,\n table: TableMeta,\n emitter: BytecodeEmitter,\n resolveReg: (name?: string, expr?: ExprNode) => number | undefined,\n allocReg: () => number,\n failPatches: number[],\n udfNameMap?: Map<string, number>,\n): void {\n if (!root) return;\n const truePatches: number[] = [];\n compileHavingFilterNode(\n root,\n emitter,\n table,\n resolveReg,\n allocReg,\n truePatches,\n failPatches,\n \"true\",\n udfNameMap,\n );\n const passPos = emitter.currentOffset();\n for (const patch of truePatches) {\n emitter.patchUint16(patch, passPos);\n }\n}\n\nfunction emitFilterTree(\n root: QueryFilter | null,\n table: TableMeta,\n emitter: BytecodeEmitter,\n leafRegMap: Map<QueryFilter, number>,\n nextRowPatches: number[],\n udfNameMap?: Map<string, number>,\n tables?: TableMeta[],\n filterSetMap?: Map<QueryFilter, number>,\n): void {\n if (!root) return;\n const truePatches: number[] = [];\n compileFilterNode(\n root,\n emitter,\n table,\n leafRegMap,\n truePatches,\n nextRowPatches,\n \"true\",\n udfNameMap,\n tables,\n filterSetMap,\n );\n const rowStartPos = emitter.currentOffset();\n for (const patch of truePatches) {\n emitter.patchUint16(patch, rowStartPos);\n }\n}\n\nexport function inferExprType(\n expr: ExprNode,\n table: TableMeta,\n udfDefs?: Map<string, { returnType?: DataType }>,\n tables?: TableMeta[],\n): DataType {\n if (expr.type === \"literal\") {\n if (typeof expr.value === \"number\") {\n return Number.isInteger(expr.value) ? DataType.INT32 : DataType.FLOAT64;\n }\n if (typeof expr.value === \"string\") return DataType.TEXT;\n return DataType.TEXT;\n }\n if (expr.type === \"col\") {\n const all = tables ?? [table];\n const resolved = resolveColumnAcrossTables(expr.name, all);\n return resolved ? resolved.col.type : DataType.TEXT;\n }\n if (expr.type === \"binary\") {\n return DataType.FLOAT64;\n }\n if (expr.type === \"fn\") {\n const fn = expr.name.toLowerCase();\n if (udfDefs && udfDefs.has(fn)) {\n const def = udfDefs.get(fn)!;\n if (def.returnType !== undefined) {\n return def.returnType;\n }\n }\n if ([\"upper\", \"lower\", \"substr\", \"trim\", \"concat\"].includes(fn))\n return DataType.TEXT;\n if (\n [\n \"length\",\n \"count\",\n \"starts_with\",\n \"startswith\",\n \"ends_with\",\n \"endswith\",\n \"like\",\n \"contains\",\n ].includes(fn)\n )\n return DataType.INT32;\n if (\n [\"abs\", \"round\", \"floor\", \"ceil\", \"sum\", \"avg\", \"min\", \"max\"].includes(fn)\n ) {\n if (expr.args.length > 0 && expr.args[0].type === \"col\") {\n const resolved = resolveColumnAcrossTables(\n (expr.args[0] as any).name,\n tables ?? [table],\n );\n if (resolved && resolved.col.type === DataType.INT32 && fn !== \"avg\")\n return DataType.INT32;\n }\n return DataType.FLOAT64;\n }\n return DataType.TEXT;\n }\n return DataType.TEXT;\n}\n\nexport function emitExpression(\n expr: ExprNode,\n table: TableMeta,\n emitter: BytecodeEmitter,\n cursor: number,\n targetReg: number,\n allocReg: () => number,\n udfNameMap?: Map<string, number>,\n resolveReg?: (name?: string, expr?: ExprNode) => number | undefined,\n tables?: TableMeta[],\n): void {\n if (resolveReg) {\n const colName = expr.type === \"col\" ? expr.name : undefined;\n const resolved = resolveReg(colName, expr);\n if (resolved !== undefined) {\n if (resolved !== targetReg) {\n emitter.emitUint8(OpCode.OP_COPY);\n emitter.emitUint8(resolved);\n emitter.emitUint8(targetReg);\n }\n return;\n }\n }\n\n if (expr.type === \"literal\") {\n const val = expr.value;\n if (val === null || val === undefined) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(targetReg);\n } else if (typeof val === \"number\") {\n if (Number.isInteger(val)) {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(val);\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(targetReg);\n emitter.emitFloat64(val);\n }\n } else if (typeof val === \"string\") {\n emitter.emitUint8(OpCode.OP_LOAD_TEXT);\n emitter.emitUint8(targetReg);\n emitter.emitString(val);\n } else if (typeof val === \"boolean\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(val ? 1 : 0);\n }\n return;\n }\n\n if (expr.type === \"col\") {\n if (cursor === -1) {\n throw new Error(\n `Column \"${expr.name}\" in HAVING clause must be an aggregate or grouping column`,\n );\n }\n const all = tables ?? [table];\n const resolved = resolveColumnAcrossTables(expr.name, all);\n if (!resolved) {\n if (expr.name === \"*\") {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(targetReg);\n return;\n }\n throw new Error(\n `Column \"${expr.name}\" does not exist in table \"${table.name}\"`,\n );\n }\n emitReadColumn(\n emitter,\n resolved.cursor,\n resolved.colIdx,\n targetReg,\n resolved.col.type,\n );\n return;\n }\n\n if (expr.type === \"binary\") {\n const regLeft = allocReg();\n const regRight = allocReg();\n emitExpression(\n expr.left,\n table,\n emitter,\n cursor,\n regLeft,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n emitExpression(\n expr.right,\n table,\n emitter,\n cursor,\n regRight,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n\n let opCode = OpCode.OP_ADD;\n if (expr.op === \"+\") opCode = OpCode.OP_ADD;\n else if (expr.op === \"-\") opCode = OpCode.OP_SUB;\n else if (expr.op === \"*\") opCode = OpCode.OP_MUL;\n else if (expr.op === \"/\") opCode = OpCode.OP_DIV;\n else if (expr.op === \"%\") opCode = OpCode.OP_MOD;\n else if (\n expr.op === \"=\" ||\n expr.op === \"!=\" ||\n expr.op === \"<\" ||\n expr.op === \"<=\" ||\n expr.op === \">\" ||\n expr.op === \">=\"\n ) {\n let cmpOp = OpCode.OP_EQ;\n if (expr.op === \"=\") cmpOp = OpCode.OP_EQ;\n else if (expr.op === \"!=\") cmpOp = OpCode.OP_NE;\n else if (expr.op === \"<\") cmpOp = OpCode.OP_LT;\n else if (expr.op === \"<=\") cmpOp = OpCode.OP_LE;\n else if (expr.op === \">\") cmpOp = OpCode.OP_GT;\n else if (expr.op === \">=\") cmpOp = OpCode.OP_GE;\n\n emitter.emitUint8(cmpOp);\n emitter.emitUint8(regLeft);\n emitter.emitUint8(regRight);\n const truePatch = emitter.emitUint16(0);\n\n // False branch: targetReg = 0\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(0);\n emitter.emitUint8(OpCode.OP_JUMP);\n const donePatch = emitter.emitUint16(0);\n\n // True branch: targetReg = 1\n emitter.patchUint16(truePatch, emitter.currentOffset());\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(1);\n\n emitter.patchUint16(donePatch, emitter.currentOffset());\n return;\n }\n\n emitter.emitUint8(opCode);\n emitter.emitUint8(regLeft);\n emitter.emitUint8(regRight);\n emitter.emitUint8(targetReg);\n return;\n }\n\n if (expr.type === \"fn\") {\n const fnName = expr.name.toLowerCase();\n\n const unaryOps: Record<string, OpCode> = {\n upper: OpCode.OP_STR_UPPER,\n lower: OpCode.OP_STR_LOWER,\n length: OpCode.OP_STR_LENGTH,\n trim: OpCode.OP_STR_TRIM,\n abs: OpCode.OP_MATH_ABS,\n round: OpCode.OP_MATH_ROUND,\n floor: OpCode.OP_MATH_FLOOR,\n ceil: OpCode.OP_MATH_CEIL,\n };\n\n if (unaryOps[fnName]) {\n const srcReg = allocReg();\n const arg = expr.args[0] ?? { type: \"literal\", value: null };\n emitExpression(\n arg,\n table,\n emitter,\n cursor,\n srcReg,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n emitter.emitUint8(unaryOps[fnName]);\n emitter.emitUint8(srcReg);\n emitter.emitUint8(targetReg);\n return;\n }\n\n if (fnName === \"substr\") {\n const srcReg = allocReg();\n const startReg = allocReg();\n const lenReg = allocReg();\n emitExpression(\n expr.args[0],\n table,\n emitter,\n cursor,\n srcReg,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n emitExpression(\n expr.args[1] ?? { type: \"literal\", value: 1 },\n table,\n emitter,\n cursor,\n startReg,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n if (expr.args[2] !== undefined) {\n emitExpression(\n expr.args[2],\n table,\n emitter,\n cursor,\n lenReg,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(lenReg);\n }\n emitter.emitUint8(OpCode.OP_STR_SUBSTR);\n emitter.emitUint8(srcReg);\n emitter.emitUint8(startReg);\n emitter.emitUint8(lenReg);\n emitter.emitUint8(targetReg);\n return;\n }\n\n const patternOps: Record<string, OpCode> = {\n starts_with: OpCode.OP_STR_STARTS_WITH,\n startswith: OpCode.OP_STR_STARTS_WITH,\n ends_with: OpCode.OP_STR_ENDS_WITH,\n endswith: OpCode.OP_STR_ENDS_WITH,\n like: OpCode.OP_STR_LIKE,\n contains: OpCode.OP_STR_CONTAINS,\n };\n if (patternOps[fnName]) {\n const regStr = allocReg();\n const regPat = allocReg();\n emitExpression(\n expr.args[0] ?? { type: \"literal\", value: null },\n table,\n emitter,\n cursor,\n regStr,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n emitExpression(\n expr.args[1] ?? { type: \"literal\", value: \"\" },\n table,\n emitter,\n cursor,\n regPat,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n\n emitter.emitUint8(patternOps[fnName]);\n emitter.emitUint8(regStr);\n emitter.emitUint8(regPat);\n const truePatch = emitter.emitUint16(0);\n\n // False branch: targetReg = 0\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(0);\n emitter.emitUint8(OpCode.OP_JUMP);\n const donePatch = emitter.emitUint16(0);\n\n // True branch: targetReg = 1\n emitter.patchUint16(truePatch, emitter.currentOffset());\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(targetReg);\n emitter.emitInt32(1);\n\n emitter.patchUint16(donePatch, emitter.currentOffset());\n return;\n }\n\n if (fnName === \"concat\" || fnName === \"coalesce\") {\n const numArgs = expr.args.length;\n const startReg = allocReg();\n for (let i = 1; i < numArgs; i++) {\n allocReg();\n }\n for (let i = 0; i < numArgs; i++) {\n emitExpression(\n expr.args[i],\n table,\n emitter,\n cursor,\n startReg + i,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n }\n const op =\n fnName === \"concat\" ? OpCode.OP_STR_CONCAT : OpCode.OP_COALESCE;\n emitter.emitUint8(op);\n emitter.emitUint8(startReg);\n emitter.emitUint8(numArgs);\n emitter.emitUint8(targetReg);\n return;\n }\n\n if (udfNameMap && udfNameMap.has(fnName)) {\n const udfId = udfNameMap.get(fnName)!;\n const numArgs = expr.args.length;\n let startReg = targetReg;\n if (numArgs > 0) {\n startReg = allocReg();\n for (let i = 1; i < numArgs; i++) {\n allocReg();\n }\n for (let i = 0; i < numArgs; i++) {\n emitExpression(\n expr.args[i],\n table,\n emitter,\n cursor,\n startReg + i,\n allocReg,\n udfNameMap,\n resolveReg,\n tables,\n );\n }\n }\n emitter.emitUint8(OpCode.OP_CALL_UDF);\n emitter.emitUint16(udfId);\n emitter.emitUint8(startReg);\n emitter.emitUint8(numArgs);\n emitter.emitUint8(targetReg);\n return;\n }\n\n throw new UnknownFunctionError(fnName);\n }\n}\n\nfunction emitLoadConstant(\n emitter: BytecodeEmitter,\n reg: number,\n val: any,\n colType?: DataType,\n): void {\n if (val === null || val === undefined) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(reg);\n } else if (typeof val === \"number\") {\n if (colType === DataType.FLOAT64 || !Number.isInteger(val)) {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(reg);\n emitter.emitFloat64(val);\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(reg);\n emitter.emitInt32(Math.floor(val));\n }\n } else if (typeof val === \"bigint\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(reg);\n emitter.emitInt32(Number(val));\n } else if (typeof val === \"string\") {\n emitter.emitUint8(OpCode.OP_LOAD_TEXT);\n emitter.emitUint8(reg);\n emitter.emitString(val);\n } else if (typeof val === \"boolean\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(reg);\n emitter.emitInt32(val ? 1 : 0);\n }\n}\n\nexport interface CandidateIndexScan {\n index: IndexDescriptor;\n scanType: \"point\" | \"range\" | \"multi_point\";\n seekFilter?: QueryFilter;\n filterIndex: number; // index into leafFilters, -1 if synthetic for orderBy\n keyType: DataType;\n compositeValue?: Uint8Array;\n inValues?: any[];\n satisfiesOrderBy?: boolean;\n}\n\n/**\n * Returns minimum scalar key value for DataType when seeking the start of an index.\n */\nexport function getMinKeyValueForType(type: DataType): any {\n switch (type) {\n case DataType.INT32:\n return -2147483648;\n case DataType.INT64:\n return -9223372036854775808n;\n case DataType.FLOAT64:\n return -Infinity;\n case DataType.TEXT:\n case DataType.UUID:\n case DataType.ULID:\n return \"\";\n case DataType.BLOB:\n return new Uint8Array(0);\n default:\n return 0;\n }\n}\n\n/**\n * Tests whether a secondary index satisfies the query's ORDER BY keys directly.\n * Forward B-Tree scans naturally stream in ASC order.\n */\nexport function isIndexAlignedWithOrderBy(\n index: IndexDescriptor,\n table: TableMeta,\n orderBy?: SortKey[],\n equalityColumns?: Set<string>,\n): boolean {\n if (!orderBy || orderBy.length === 0) return false;\n // All orderBy keys must be ascending (or default asc)\n for (const k of orderBy) {\n if (k.direction === \"desc\") return false;\n }\n\n const indexColNames = index.columnIndices.map((i) =>\n table.columns[i].name.toLowerCase(),\n );\n\n // Skip leading index columns that are fixed by equality filters\n let idxPos = 0;\n if (equalityColumns && equalityColumns.size > 0) {\n while (\n idxPos < indexColNames.length &&\n equalityColumns.has(indexColNames[idxPos])\n ) {\n idxPos++;\n }\n }\n\n // Check if subsequent index columns match the orderBy columns in order\n let orderPos = 0;\n while (idxPos < indexColNames.length && orderPos < orderBy.length) {\n const orderCol = orderBy[orderPos].colName?.toLowerCase();\n if (!orderCol || orderCol !== indexColNames[idxPos]) {\n return false;\n }\n idxPos++;\n orderPos++;\n }\n\n return orderPos === orderBy.length;\n}\n\n/**\n * Tests whether a join plan preserves the requested ORDER BY.\n * In a nested loop join, if all ORDER BY keys belong to the driving table (Table 0)\n * and are sorted in ASC order, the outer loop determines the output order.\n */\nexport function canJoinPreserveOrder(\n drivingTable: TableMeta,\n joinedTables: JoinPlan[],\n orderBy?: SortKey[],\n allTables?: TableMeta[],\n selectExprs?: ParsedSelectExpr[],\n): boolean {\n if (!orderBy || orderBy.length === 0) return false;\n for (const k of orderBy) {\n if (k.direction === \"desc\") return false;\n const colName = k.colName;\n if (!colName) return false;\n\n if (allTables && allTables.length > 0) {\n let resolved = resolveColumnAcrossTables(colName, allTables);\n if (!resolved && selectExprs) {\n const se = selectExprs.find((s) => s.alias === colName);\n if (se && se.expr.type === \"col\") {\n resolved = resolveColumnAcrossTables(se.expr.name, allTables);\n }\n }\n if (!resolved || resolved.tableIdx !== 0) {\n return false;\n }\n } else {\n const shortCol = colName.includes(\".\")\n ? colName.slice(colName.lastIndexOf(\".\") + 1)\n : colName;\n const isDrivingCol = drivingTable.columns.some(\n (c) => c.name.toLowerCase() === shortCol.toLowerCase(),\n );\n if (!isDrivingCol) return false;\n }\n }\n\n return true;\n}\n\nexport function chooseIndexScan(\n table: TableMeta,\n candidateFilters: QueryFilter[],\n leafFilters?: QueryFilter[],\n orderBy?: SortKey[],\n): CandidateIndexScan | null {\n if (!table.indexes || table.indexes.length === 0) return null;\n const allLeaves = leafFilters ?? candidateFilters;\n\n const equalityCols = new Set<string>();\n for (const f of candidateFilters) {\n if (\n f.type === \"cmp\" &&\n (f.op === \"=\" || f.op === undefined) &&\n f.colName &&\n f.value !== undefined &&\n f.value !== null\n ) {\n equalityCols.add(f.colName.toLowerCase());\n }\n }\n\n const tagCandidate = (cand: CandidateIndexScan): CandidateIndexScan => {\n if (orderBy && orderBy.length > 0) {\n if (\n cand.scanType === \"point\" &&\n (cand.index.flags & (IndexFlag.PRIMARY | IndexFlag.UNIQUE)) !== 0\n ) {\n cand.satisfiesOrderBy = true;\n } else if (\n isIndexAlignedWithOrderBy(cand.index, table, orderBy, equalityCols)\n ) {\n cand.satisfiesOrderBy = true;\n }\n }\n return cand;\n };\n\n // 1. Single-column equality match or IN match on PRIMARY KEY (highest priority)\n for (const idx of table.indexes) {\n if ((idx.flags & IndexFlag.PRIMARY) !== 0 && idx.columnCount === 1) {\n const colMeta = table.columns[idx.columnIndices[0]];\n for (let i = 0; i < candidateFilters.length; i++) {\n const f = candidateFilters[i];\n if (\n f.type === \"cmp\" &&\n (f.op === \"=\" || f.op === undefined) &&\n f.colName === colMeta.name &&\n f.value !== undefined &&\n f.value !== null\n ) {\n return tagCandidate({\n index: idx,\n scanType: \"point\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n });\n }\n if (\n f.type === \"in\" &&\n !f.notIn &&\n f.colName === colMeta.name &&\n Array.isArray(f.values) &&\n f.values.length > 0\n ) {\n const uniqueValues = Array.from(\n new Set(f.values.filter((v) => v !== null && v !== undefined)),\n );\n return tagCandidate({\n index: idx,\n scanType: \"multi_point\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n inValues: uniqueValues,\n });\n }\n }\n }\n }\n\n // 2. Single-column equality match or IN match on UNIQUE secondary index\n for (const idx of table.indexes) {\n if ((idx.flags & IndexFlag.UNIQUE) !== 0 && idx.columnCount === 1) {\n const colMeta = table.columns[idx.columnIndices[0]];\n for (let i = 0; i < candidateFilters.length; i++) {\n const f = candidateFilters[i];\n if (\n f.type === \"cmp\" &&\n (f.op === \"=\" || f.op === undefined) &&\n f.colName === colMeta.name &&\n f.value !== undefined &&\n f.value !== null\n ) {\n return tagCandidate({\n index: idx,\n scanType: \"point\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n });\n }\n if (\n f.type === \"in\" &&\n !f.notIn &&\n f.colName === colMeta.name &&\n Array.isArray(f.values) &&\n f.values.length > 0\n ) {\n const uniqueValues = Array.from(\n new Set(f.values.filter((v) => v !== null && v !== undefined)),\n );\n return tagCandidate({\n index: idx,\n scanType: \"multi_point\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n inValues: uniqueValues,\n });\n }\n }\n }\n }\n\n // 3. Composite index exact equality match (all indexed columns matched with =)\n for (const idx of table.indexes) {\n if (idx.columnCount > 1) {\n const matchedFilters: QueryFilter[] = [];\n let allFound = true;\n\n for (let c = 0; c < idx.columnCount; c++) {\n const colMeta = table.columns[idx.columnIndices[c]];\n const f = candidateFilters.find(\n (lf) =>\n lf.type === \"cmp\" &&\n (lf.op === \"=\" || lf.op === undefined) &&\n lf.colName === colMeta.name &&\n lf.value !== undefined &&\n lf.value !== null,\n );\n if (f) {\n matchedFilters.push(f);\n } else {\n allFound = false;\n break;\n }\n }\n\n if (allFound) {\n const dummyRow: Record<string, any> = {};\n for (const f of matchedFilters) {\n dummyRow[f.colName!] = f.value;\n }\n const compositeKeyBytes = serialize_composite_key(\n table.columns,\n idx.columnIndices,\n idx.columnCount,\n dummyRow,\n );\n\n return tagCandidate({\n index: idx,\n scanType: \"point\",\n seekFilter: matchedFilters[0],\n filterIndex: allLeaves.indexOf(matchedFilters[0]),\n keyType: DataType.BLOB,\n compositeValue: compositeKeyBytes,\n });\n }\n }\n }\n\n // 4. Single-column equality match on non-unique index\n for (const idx of table.indexes) {\n if (idx.columnCount === 1) {\n const colMeta = table.columns[idx.columnIndices[0]];\n for (let i = 0; i < candidateFilters.length; i++) {\n const f = candidateFilters[i];\n if (\n f.type === \"cmp\" &&\n (f.op === \"=\" || f.op === undefined) &&\n f.colName === colMeta.name &&\n f.value !== undefined &&\n f.value !== null\n ) {\n return tagCandidate({\n index: idx,\n scanType: \"range\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n });\n }\n }\n }\n }\n\n // 5. Single-column range match (>= or >)\n for (const idx of table.indexes) {\n if (idx.columnCount === 1) {\n const colMeta = table.columns[idx.columnIndices[0]];\n for (let i = 0; i < candidateFilters.length; i++) {\n const f = candidateFilters[i];\n if (\n f.type === \"cmp\" &&\n (f.op === \">=\" || f.op === \">\") &&\n f.colName === colMeta.name &&\n f.value !== undefined &&\n f.value !== null\n ) {\n return tagCandidate({\n index: idx,\n scanType: \"range\",\n seekFilter: f,\n filterIndex: allLeaves.indexOf(f),\n keyType: colMeta.type,\n });\n }\n }\n }\n }\n\n // 6. Interesting Order scan: match index to satisfy ORDER BY directly\n if (orderBy && orderBy.length > 0) {\n for (const idx of table.indexes) {\n if (isIndexAlignedWithOrderBy(idx, table, orderBy, equalityCols)) {\n if (idx.columnCount === 1) {\n const colMeta = table.columns[idx.columnIndices[0]];\n return {\n index: idx,\n scanType: \"range\",\n seekFilter: undefined as any,\n filterIndex: -1,\n keyType: colMeta.type,\n satisfiesOrderBy: true,\n };\n } else {\n // Composite index: prefix with equality filter values if present, rest with min values\n const dummyRow: Record<string, any> = {};\n for (let c = 0; c < idx.columnCount; c++) {\n const col = table.columns[idx.columnIndices[c]];\n const eqFilter = candidateFilters.find(\n (f) =>\n f.type === \"cmp\" &&\n (f.op === \"=\" || f.op === undefined) &&\n f.colName === col.name &&\n f.value !== undefined &&\n f.value !== null,\n );\n if (eqFilter) {\n dummyRow[col.name] = eqFilter.value;\n } else {\n dummyRow[col.name] = getMinKeyValueForType(col.type);\n }\n }\n const compositeKeyBytes = serialize_composite_key(\n table.columns,\n idx.columnIndices,\n idx.columnCount,\n dummyRow,\n );\n return {\n index: idx,\n scanType: \"range\",\n seekFilter: undefined as any,\n filterIndex: -1,\n keyType: DataType.BLOB,\n compositeValue: compositeKeyBytes,\n satisfiesOrderBy: true,\n };\n }\n }\n }\n }\n\n return null;\n}\n\nexport interface JoinIndexCandidate {\n index: IndexDescriptor;\n isUnique: boolean;\n innerCol: ResolvedColumn;\n outerCol: ResolvedColumn;\n indexCursor: number;\n}\n\nexport function chooseJoinIndex(\n joinPlan: JoinPlan,\n innerTable: TableMeta,\n innerTableIdx: number,\n allTables: TableMeta[],\n indexCursor: number,\n): JoinIndexCandidate | null {\n if (\n joinPlan.op !== \"=\" ||\n !innerTable.indexes ||\n innerTable.indexes.length === 0\n ) {\n return null;\n }\n\n const resolvedLeft = resolveColumnAcrossTables(joinPlan.leftCol, allTables);\n const resolvedRight = resolveColumnAcrossTables(joinPlan.rightCol, allTables);\n if (!resolvedLeft || !resolvedRight) return null;\n\n let innerCol: ResolvedColumn | null = null;\n let outerCol: ResolvedColumn | null = null;\n\n if (\n resolvedLeft.tableIdx === innerTableIdx &&\n resolvedRight.tableIdx < innerTableIdx\n ) {\n innerCol = resolvedLeft;\n outerCol = resolvedRight;\n } else if (\n resolvedRight.tableIdx === innerTableIdx &&\n resolvedLeft.tableIdx < innerTableIdx\n ) {\n innerCol = resolvedRight;\n outerCol = resolvedLeft;\n }\n\n if (!innerCol || !outerCol) return null;\n\n let bestIdx: IndexDescriptor | null = null;\n let bestRank = 999;\n\n for (const idx of innerTable.indexes) {\n if (idx.columnCount === 1 && idx.columnIndices[0] === innerCol.colIdx) {\n const isPk = (idx.flags & IndexFlag.PRIMARY) !== 0;\n const isUnique = (idx.flags & IndexFlag.UNIQUE) !== 0;\n const rank = isPk ? 1 : isUnique ? 2 : 3;\n if (rank < bestRank) {\n bestRank = rank;\n bestIdx = idx;\n }\n }\n }\n\n if (!bestIdx) return null;\n\n const isUnique =\n (bestIdx.flags & (IndexFlag.PRIMARY | IndexFlag.UNIQUE)) !== 0;\n return {\n index: bestIdx,\n isUnique,\n innerCol,\n outerCol,\n indexCursor,\n };\n}\n\n/**\n * Compiles a QueryPlan into an executable bytecode array.\n */\nexport function compileQuery(\n plan: QueryPlan,\n options?: {\n planner?: QueryPlanner;\n },\n): Uint8Array {\n const originalTables: TableMeta[] = [\n plan.table,\n ...(plan.joinedTables?.map((j) => j.table) ?? []),\n ];\n\n // Optimize plan through unified QueryPlanner\n const queryPlanner = resolveQueryPlanner(options?.planner ?? plan.planner);\n\n const opt = queryPlanner.optimize(plan);\n const allTables: TableMeta[] = opt.orderedTables ?? originalTables;\n const whereMetrics = opt.whereMetrics;\n const planMetrics = opt.metrics;\n\n if (opt.isAlwaysFalse) {\n const emptyEmitter = new BytecodeEmitter();\n emptyEmitter.emitUint8(OpCode.OP_HALT);\n const res = emptyEmitter.toByteArray();\n if (plan.outputColumns) (res as any).outputColumns = plan.outputColumns;\n (res as any).allTables = allTables;\n (res as any).whereMetrics = whereMetrics;\n return res;\n }\n\n const workingPlan = opt.plan;\n if (workingPlan !== plan) {\n Object.assign(plan, workingPlan);\n }\n\n const isJoinQuery =\n plan.joinedTables !== undefined && plan.joinedTables.length > 0;\n\n const rootFilter = buildRootFilter(plan.filters);\n const leafFilters = rootFilter ? collectLeafFilters(rootFilter) : [];\n const topConjunctions = getTopLevelConjunctionFilters(rootFilter);\n\n // Partition filters for early pushdown per join loop level\n const pushedFilters: QueryFilter[][] = Array.from(\n { length: allTables.length },\n () => [],\n );\n const pushedFilterSet = new Set<QueryFilter>();\n\n if (isJoinQuery && planMetrics) {\n for (let i = 0; i < allTables.length; i++) {\n const origIdx = originalTables.indexOf(allTables[i]);\n if (origIdx !== -1) {\n const filters = planMetrics.singleTableFilters.get(origIdx) ?? [];\n if (\n i === 0 ||\n (plan.joinedTables && plan.joinedTables[i - 1]?.type === \"inner\")\n ) {\n pushedFilters[i] = filters;\n for (const f of filters) {\n pushedFilterSet.add(f);\n }\n }\n }\n }\n }\n\n const remainingFilters: QueryFilter[] = [];\n for (const f of topConjunctions) {\n if (!pushedFilterSet.has(f)) {\n remainingFilters.push(f);\n }\n }\n const rootRemainingFilter = buildRootFilter(remainingFilters);\n\n // Join Order Preservation check for Table 0 (outer driving table)\n const canPreserve =\n isJoinQuery &&\n canJoinPreserveOrder(\n allTables[0],\n plan.joinedTables!,\n plan.orderBy,\n allTables,\n plan.selectExprs,\n );\n\n const orderKeysForTable0 = canPreserve\n ? plan.orderBy!.map((k) => {\n const col = k.colName ?? \"\";\n const shortCol = col.includes(\".\")\n ? col.slice(col.lastIndexOf(\".\") + 1)\n : col;\n return { ...k, colName: shortCol };\n })\n : undefined;\n\n const table0Scan = isJoinQuery\n ? chooseIndexScan(\n allTables[0],\n pushedFilters[0],\n leafFilters,\n orderKeysForTable0,\n )\n : null;\n\n const isJoinOrderPreserved = canPreserve && !!table0Scan?.satisfiesOrderBy;\n\n let nextCursor = allTables.length;\n let indexCursor0 = -1;\n if (table0Scan && nextCursor < 16) {\n indexCursor0 = nextCursor++;\n }\n\n const joinIndices: (JoinIndexCandidate | null)[] = new Array(\n allTables.length,\n ).fill(null);\n if (isJoinQuery && plan.joinedTables) {\n for (let i = 1; i < allTables.length; i++) {\n const jPlan = plan.joinedTables[i - 1];\n if (nextCursor < 16) {\n const cand = chooseJoinIndex(\n jPlan,\n allTables[i],\n i,\n allTables,\n nextCursor,\n );\n if (cand) {\n joinIndices[i] = cand;\n nextCursor++;\n }\n }\n }\n }\n\n const totalCursors = nextCursor;\n if (totalCursors > 16) {\n throw new TooManyCursorsError(totalCursors, 16);\n }\n\n // Short-circuit: top-level conjunction IN () can never match any row\n for (const f of topConjunctions) {\n if (f.type === \"in\" && !f.notIn && (!f.values || f.values.length === 0)) {\n const emptyEmitter = new BytecodeEmitter();\n emptyEmitter.emitUint8(OpCode.OP_HALT);\n const res = emptyEmitter.toByteArray();\n if (plan.outputColumns) (res as any).outputColumns = plan.outputColumns;\n return res;\n }\n }\n\n const inSets: Set<any>[] = [];\n const filterSetMap = new Map<QueryFilter, number>();\n for (const f of leafFilters) {\n if (f.type === \"in\") {\n const setIdx = inSets.length;\n filterSetMap.set(f, setIdx);\n const s = new Set<any>();\n if (f.values) {\n for (const v of f.values) {\n if (v !== null && v !== undefined) {\n s.add(v);\n if (typeof v === \"bigint\") {\n s.add(Number(v));\n } else if (typeof v === \"number\" && Number.isSafeInteger(v)) {\n s.add(BigInt(v));\n }\n }\n }\n }\n inSets.push(s);\n }\n }\n\n const leafRegMap = new Map<QueryFilter, number>();\n for (let i = 0; i < leafFilters.length; i++) {\n leafRegMap.set(leafFilters[i], i);\n }\n\n if (leafFilters.length * 2 >= 64) {\n throw new TooManyRegistersError(leafFilters.length * 2);\n }\n\n if (plan.orderBy && plan.orderBy.length > 8) {\n throw new TooManyOrderByColumnsError(plan.orderBy.length);\n }\n\n if (plan.groupBy && plan.groupBy.length > 8) {\n throw new TooManyGroupByColumnsError(plan.groupBy.length);\n }\n\n const emitter = new BytecodeEmitter();\n\n if (plan.limit !== undefined && plan.limit <= 0) {\n emitter.emitUint8(OpCode.OP_HALT);\n return emitter.toByteArray();\n }\n\n let nextReg = leafFilters.length * 2;\n const hasOffset = plan.offset !== undefined && plan.offset > 0;\n const hasLimit = plan.limit !== undefined && plan.limit > 0;\n const regOffset = hasOffset ? nextReg++ : -1;\n const regLimit = hasLimit ? nextReg++ : -1;\n\n if (nextReg >= 64) {\n throw new TooManyRegistersError(nextReg);\n }\n\n const table = plan.table;\n\n // 1. Preamble: Load constant filter values into registers\n for (let i = 0; i < leafFilters.length; i++) {\n const filter = leafFilters[i];\n if (filter.type === \"cmp\") {\n const regConst = i * 2 + 1;\n const val = filter.value;\n\n if (val === null || val === undefined) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(regConst);\n } else if (typeof val === \"number\") {\n const resolved = filter.colName\n ? resolveColumnAcrossTables(filter.colName, allTables)\n : undefined;\n if (resolved && resolved.col.type === DataType.FLOAT64) {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(regConst);\n emitter.emitFloat64(val);\n } else if (!Number.isInteger(val)) {\n emitter.emitUint8(OpCode.OP_LOAD_FLOAT);\n emitter.emitUint8(regConst);\n emitter.emitFloat64(val);\n } else {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(Math.floor(val));\n }\n } else if (typeof val === \"bigint\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(Number(val));\n } else if (typeof val === \"string\") {\n emitter.emitUint8(OpCode.OP_LOAD_TEXT);\n emitter.emitUint8(regConst);\n emitter.emitString(val);\n } else if (typeof val === \"boolean\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regConst);\n emitter.emitInt32(val ? 1 : 0);\n }\n }\n }\n\n // Load offset / limit into registers\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regOffset);\n emitter.emitInt32(plan.offset!);\n }\n if (hasLimit) {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regLimit);\n emitter.emitInt32(plan.limit!);\n }\n\n // Case 1: In-Arena Hash Aggregation (GROUP BY / Aggregates)\n if (\n (plan.aggregates && plan.aggregates.length > 0) ||\n (plan.groupBy && plan.groupBy.length > 0)\n ) {\n const G = plan.groupBy?.length ?? 0;\n const aggregates = plan.aggregates ?? [];\n const A = aggregates.length;\n\n // Determine output columns\n const outputColumns: ColumnMeta[] = [];\n for (const gItem of plan.groupBy ?? []) {\n const gColName =\n typeof gItem === \"string\"\n ? gItem\n : (gItem.colName ??\n (gItem.expr ? deriveDefaultAlias(gItem.expr) : \"group_key\"));\n\n const matchingSelect = plan.selectExprs?.find((s) => {\n if (s.alias === gColName) return true;\n if (typeof gItem === \"object\" && gItem.expr) {\n return JSON.stringify(s.expr) === JSON.stringify(gItem.expr);\n }\n if (typeof gItem === \"string\" && gItem.includes(\"(\")) {\n try {\n const parsed = parseExpression(gItem);\n return JSON.stringify(s.expr) === JSON.stringify(parsed);\n } catch {\n return false;\n }\n }\n return false;\n });\n\n const finalColName = matchingSelect?.alias ?? gColName;\n const col = table.columns.find(\n (c) => c.name === gColName || c.name === finalColName,\n );\n if (col) {\n outputColumns.push({ ...col, name: finalColName });\n } else {\n outputColumns.push({\n name: finalColName,\n type: DataType.TEXT,\n flags: ColumnFlag.NONE,\n colOffset: 0,\n });\n }\n }\n for (let j = 0; j < aggregates.length; j++) {\n const agg = aggregates[j];\n const aggName =\n agg.alias ?? (agg.colName ? `${agg.func}_${agg.colName}` : agg.func);\n const aggType = agg.func === \"count\" ? DataType.INT32 : DataType.FLOAT64;\n outputColumns.push({\n name: aggName,\n type: aggType,\n flags: ColumnFlag.NONE,\n colOffset: 0,\n });\n }\n\n // Register layout:\n const numFilterRegs = nextReg;\n const groupKeyStartReg = numFilterRegs;\n const aggValStartReg = groupKeyStartReg + G;\n const outAccReg = aggValStartReg + 4;\n const outGroupKeyReg = outAccReg + 4;\n const finalAggStartReg = outGroupKeyReg + G;\n const totalRegs = finalAggStartReg + A;\n\n if (totalRegs >= 64) {\n throw new TooManyRegistersError(totalRegs);\n }\n\n // OP_AGG_INIT: agg_id = 0, start_key_reg, num_keys = G, mode = 0 (hash)\n emitter.emitUint8(OpCode.OP_AGG_INIT);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(0);\n\n // Open Cursor\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n // Rewind Cursor\n emitter.emitUint8(OpCode.OP_REWIND);\n emitter.emitUint8(0);\n const rewindJumpPatch = emitter.emitUint16(0);\n\n // Table scan loop\n const loopStartPos = emitter.currentOffset();\n const nextRowPatches: number[] = [];\n\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n // Extract group keys into registers\n if (plan.groupBy) {\n for (let k = 0; k < plan.groupBy.length; k++) {\n const gItem = plan.groupBy[k];\n const targetReg = groupKeyStartReg + k;\n let tempReg = Math.max(totalRegs + 4, 40);\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n\n if (typeof gItem === \"object\" && gItem.expr) {\n emitExpression(\n gItem.expr,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } else {\n const colName = typeof gItem === \"string\" ? gItem : gItem.colName!;\n const aliasExpr = plan.selectExprs?.find(\n (s) => s.alias === colName,\n )?.expr;\n if (aliasExpr) {\n emitExpression(\n aliasExpr,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } else {\n const colIdx = table.columns.findIndex((c) => c.name === colName);\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n emitReadColumn(emitter, 0, colIdx, targetReg, col.type);\n } else {\n try {\n const parsed = parseExpression(colName);\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } catch {\n throw new Error(\n `Grouping column \"${colName}\" not found in table \"${table.name}\"`,\n );\n }\n }\n }\n }\n }\n }\n\n // If grouping without any aggregate functions, perform a COUNT step to register the group keys in the hash table\n if (A === 0 && G > 0) {\n emitter.emitUint8(OpCode.OP_AGG_STEP);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(255);\n emitter.emitUint8(0);\n }\n\n // Identify unique aggregate operations to step\n const hasCount = aggregates.some((a) => a.func === \"count\");\n const hasAvg = aggregates.some((a) => a.func === \"avg\");\n const hasSum = aggregates.some((a) => a.func === \"sum\");\n const hasMin = aggregates.some((a) => a.func === \"min\");\n const hasMax = aggregates.some((a) => a.func === \"max\");\n\n // 1. COUNT step (funcId 0)\n if (hasCount || hasAvg || hasSum) {\n const countAgg = aggregates.find((a) => a.func === \"count\");\n let valReg = 255;\n if (countAgg && countAgg.colName && countAgg.colName !== \"*\") {\n const colIdx = table.columns.findIndex(\n (c) => c.name === countAgg.colName,\n );\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n valReg = aggValStartReg;\n emitReadColumn(emitter, 0, colIdx, valReg, col.type);\n }\n }\n emitter.emitUint8(OpCode.OP_AGG_STEP);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(valReg);\n emitter.emitUint8(0);\n }\n\n // 2. SUM step (funcId 1) - used for SUM and AVG\n if (hasSum || hasAvg) {\n const sumAgg = aggregates.find(\n (a) => a.func === \"sum\" || a.func === \"avg\",\n );\n let valReg = 255;\n if (sumAgg && sumAgg.colName && sumAgg.colName !== \"*\") {\n const colIdx = table.columns.findIndex(\n (c) => c.name === sumAgg.colName,\n );\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n valReg = aggValStartReg + 1;\n emitReadColumn(emitter, 0, colIdx, valReg, col.type);\n }\n }\n emitter.emitUint8(OpCode.OP_AGG_STEP);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(valReg);\n emitter.emitUint8(1);\n }\n\n // 3. MIN step (funcId 3)\n if (hasMin) {\n const minAgg = aggregates.find((a) => a.func === \"min\");\n let valReg = 255;\n if (minAgg && minAgg.colName && minAgg.colName !== \"*\") {\n const colIdx = table.columns.findIndex(\n (c) => c.name === minAgg.colName,\n );\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n valReg = aggValStartReg + 2;\n emitReadColumn(emitter, 0, colIdx, valReg, col.type);\n }\n }\n emitter.emitUint8(OpCode.OP_AGG_STEP);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(valReg);\n emitter.emitUint8(3);\n }\n\n // 4. MAX step (funcId 4)\n if (hasMax) {\n const maxAgg = aggregates.find((a) => a.func === \"max\");\n let valReg = 255;\n if (maxAgg && maxAgg.colName && maxAgg.colName !== \"*\") {\n const colIdx = table.columns.findIndex(\n (c) => c.name === maxAgg.colName,\n );\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n valReg = aggValStartReg + 3;\n emitReadColumn(emitter, 0, colIdx, valReg, col.type);\n }\n }\n emitter.emitUint8(OpCode.OP_AGG_STEP);\n emitter.emitUint8(0);\n emitter.emitUint8(groupKeyStartReg);\n emitter.emitUint8(G);\n emitter.emitUint8(valReg);\n emitter.emitUint8(4);\n }\n\n // next_row_label\n const nextRowPos = emitter.currentOffset();\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, nextRowPos);\n }\n\n // Advance cursor\n emitter.emitUint8(OpCode.OP_NEXT_ROW);\n emitter.emitUint8(0);\n const nextRowEofPatch = emitter.emitUint16(0);\n\n // Loop back\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPos);\n\n // EOF: table scan completed\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatch, eofPos);\n emitter.patchUint16(nextRowEofPatch, eofPos);\n\n // Aggregate emit loop\n const aggEmitLoopPos = emitter.currentOffset();\n emitter.emitUint8(OpCode.OP_AGG_NEXT);\n emitter.emitUint8(0); // agg_id\n emitter.emitUint8(outGroupKeyReg);\n emitter.emitUint8(outAccReg);\n const processGroupPatch = emitter.emitUint16(0);\n\n // EOF on aggregates\n const aggHaltPos = emitter.currentOffset();\n emitter.emitUint8(OpCode.OP_HALT);\n\n // Process group label\n const processGroupPos = emitter.currentOffset();\n emitter.patchUint16(processGroupPatch, processGroupPos);\n\n // Finalize each aggregate\n for (let j = 0; j < aggregates.length; j++) {\n const agg = aggregates[j];\n const outReg = finalAggStartReg + j;\n let sumReg = outAccReg;\n let funcId = 0;\n if (agg.func === \"count\") {\n sumReg = outAccReg;\n funcId = 0;\n } else if (agg.func === \"sum\") {\n sumReg = outAccReg;\n funcId = 1;\n } else if (agg.func === \"avg\") {\n sumReg = outAccReg;\n funcId = 2;\n } else if (agg.func === \"min\") {\n sumReg = outAccReg + 2;\n funcId = 3;\n } else if (agg.func === \"max\") {\n sumReg = outAccReg + 3;\n funcId = 4;\n }\n\n emitter.emitUint8(OpCode.OP_AGG_FINAL);\n emitter.emitUint8(sumReg);\n emitter.emitUint8(outAccReg + 1); // countReg\n emitter.emitUint8(outReg);\n emitter.emitUint8(funcId);\n }\n\n // Symbol/register resolver for HAVING evaluation\n const resolveReg = (name?: string, expr?: ExprNode): number | undefined => {\n // 1. Check aggregates\n for (let j = 0; j < aggregates.length; j++) {\n const agg = aggregates[j];\n const aggReg = finalAggStartReg + j;\n\n if (name) {\n if (agg.alias && agg.alias === name) return aggReg;\n const defaultName = agg.colName\n ? `${agg.func}_${agg.colName}`\n : agg.func;\n if (defaultName === name) return aggReg;\n const sig = `${agg.func}(${agg.colName ?? \"*\"})`;\n if (sig === name.replace(/\\s+/g, \"\")) return aggReg;\n if (agg.func === name) return aggReg;\n }\n\n if (expr && expr.type === \"fn\") {\n const fnName = expr.name.toLowerCase();\n if (agg.func === fnName) {\n if (fnName === \"count\") {\n const arg0 = expr.args[0];\n const argCol =\n arg0 && arg0.type === \"col\" ? arg0.name : undefined;\n if (\n agg.colName === undefined ||\n agg.colName === \"*\" ||\n agg.colName === argCol\n ) {\n return aggReg;\n }\n } else {\n const arg0 = expr.args[0];\n const argCol =\n arg0 && arg0.type === \"col\" ? arg0.name : undefined;\n if (agg.colName === argCol) {\n return aggReg;\n }\n }\n }\n }\n }\n\n // 2. Check group keys\n if (plan.groupBy) {\n for (let k = 0; k < plan.groupBy.length; k++) {\n const gItem = plan.groupBy[k];\n const gReg = outGroupKeyReg + k;\n const gColName = typeof gItem === \"string\" ? gItem : gItem.colName;\n const gExpr = typeof gItem === \"object\" ? gItem.expr : undefined;\n\n if (name) {\n if (gColName === name) return gReg;\n if (gExpr && deriveDefaultAlias(gExpr) === name) return gReg;\n const selectAlias = plan.selectExprs?.find((s) => s.alias === name);\n if (selectAlias) {\n if (gColName === selectAlias.alias) return gReg;\n if (\n gExpr &&\n JSON.stringify(gExpr) === JSON.stringify(selectAlias.expr)\n )\n return gReg;\n if (typeof gItem === \"string\" && gItem.includes(\"(\")) {\n try {\n const parsed = parseExpression(gItem);\n if (\n JSON.stringify(parsed) === JSON.stringify(selectAlias.expr)\n )\n return gReg;\n } catch {}\n }\n }\n }\n\n if (expr) {\n if (gExpr && JSON.stringify(gExpr) === JSON.stringify(expr)) {\n return gReg;\n }\n if (expr.type === \"col\" && gColName === expr.name) {\n return gReg;\n }\n if (typeof gItem === \"string\" && gItem.includes(\"(\")) {\n try {\n const parsed = parseExpression(gItem);\n if (JSON.stringify(parsed) === JSON.stringify(expr))\n return gReg;\n } catch {}\n }\n }\n }\n }\n\n return undefined;\n };\n\n // Evaluate HAVING clause if present\n if (plan.having && plan.having.length > 0) {\n let rootHaving: QueryFilter | null = null;\n if (plan.having.length === 1) {\n rootHaving = plan.having[0];\n } else {\n rootHaving = { type: \"and\", children: plan.having };\n }\n\n const failPatches: number[] = [];\n let tempHavingReg = Math.max(totalRegs + 4, 40);\n const allocHavingReg = () => {\n if (tempHavingReg >= 64) throw new TooManyRegistersError(tempHavingReg);\n return tempHavingReg++;\n };\n\n emitHavingTree(\n rootHaving,\n table,\n emitter,\n resolveReg,\n allocHavingReg,\n failPatches,\n plan.udfNameMap,\n );\n\n for (const patch of failPatches) {\n emitter.patchUint16(patch, aggEmitLoopPos);\n }\n }\n\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n emitter.emitUint16(aggEmitLoopPos);\n }\n\n // Emit result row: group keys followed by aggregated results\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outGroupKeyReg);\n emitter.emitUint8(G + A);\n\n if (hasLimit) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n emitter.emitUint16(aggHaltPos);\n }\n\n // Jump back to next aggregate\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(aggEmitLoopPos);\n\n const result = emitter.toByteArray();\n (result as any).outputColumns = outputColumns;\n (result as any).inSets = inSets;\n (plan as any).outputColumns = outputColumns;\n return result;\n }\n\n // Check if an active index covers the query filters or directly satisfies ORDER BY\n const indexScan = !isJoinQuery\n ? chooseIndexScan(table, topConjunctions, leafFilters, plan.orderBy)\n : null;\n\n // Case 2: In-Arena Sorter (ORDER BY)\n // If an active index already satisfies the requested sort order (Interesting Orders optimization),\n // we bypass the in-arena sorter completely and stream sorted rows directly via index cursor!\n if (\n !isJoinQuery &&\n plan.orderBy &&\n plan.orderBy.length > 0 &&\n !indexScan?.satisfiesOrderBy\n ) {\n const K = plan.orderBy.length;\n const sortKeyStartReg = nextReg;\n const totalRegs = sortKeyStartReg + K;\n\n if (totalRegs >= 64) {\n throw new TooManyRegistersError(totalRegs);\n }\n\n const keyInfo: VmKeyInfo = {\n numKeys: K,\n directions: plan.orderBy.map((k) => (k.direction === \"desc\" ? 1 : 0)),\n nullOrders: plan.orderBy.map((k) =>\n k.nullOrder === \"nulls_last\"\n ? 1\n : k.nullOrder === \"nulls_first\"\n ? 0\n : k.direction === \"desc\"\n ? 1\n : 0,\n ),\n limit: plan.limit,\n offset: plan.offset,\n };\n plan.keyInfos = [keyInfo];\n\n // OP_SORTER_OPEN\n emitter.emitUint8(OpCode.OP_SORTER_OPEN);\n emitter.emitUint8(0); // sorter_id\n emitter.emitUint8(0); // key_info_idx\n\n // Open Cursor\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n // Rewind Cursor\n emitter.emitUint8(OpCode.OP_REWIND);\n emitter.emitUint8(0);\n const rewindJumpPatch = emitter.emitUint16(0);\n\n // Table scan loop\n const loopStartPos = emitter.currentOffset();\n const nextRowPatches: number[] = [];\n\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n // Extract sort keys into registers\n for (let k = 0; k < K; k++) {\n const sortKey = plan.orderBy[k];\n const targetReg = sortKeyStartReg + k;\n let tempReg = 50;\n const allocReg = () => {\n if (tempReg >= 64) throw new TooManyRegistersError(tempReg);\n return tempReg++;\n };\n\n if (sortKey.expr) {\n emitExpression(\n sortKey.expr,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } else if (sortKey.colName) {\n const colName = sortKey.colName;\n // 1. Check if colName matches a select alias\n const aliasExpr = plan.selectExprs?.find(\n (s) => s.alias === colName,\n )?.expr;\n if (aliasExpr) {\n emitExpression(\n aliasExpr,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } else {\n // 2. Check if colName is a physical table column\n const colIdx = table.columns.findIndex((c) => c.name === colName);\n if (colIdx !== -1) {\n const col = table.columns[colIdx];\n emitReadColumn(emitter, 0, colIdx, targetReg, col.type);\n } else {\n // 3. Fallback: parse as expression\n try {\n const parsed = parseExpression(colName);\n emitExpression(\n parsed,\n table,\n emitter,\n 0,\n targetReg,\n allocReg,\n plan.udfNameMap,\n );\n } catch {\n throw new Error(\n `Order by column \"${colName}\" not found in table \"${table.name}\"`,\n );\n }\n }\n }\n }\n }\n\n // Insert into sorter\n emitter.emitUint8(OpCode.OP_SORTER_INSERT);\n emitter.emitUint8(0); // sorter_id\n emitter.emitUint8(sortKeyStartReg);\n emitter.emitUint8(K);\n emitter.emitUint8(0); // cursor 0\n\n // next_row_label\n const nextRowPos = emitter.currentOffset();\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, nextRowPos);\n }\n\n // Advance cursor\n emitter.emitUint8(OpCode.OP_NEXT_ROW);\n emitter.emitUint8(0);\n const nextRowEofPatch = emitter.emitUint16(0);\n\n // Loop back\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPos);\n\n // EOF: table scan completed\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatch, eofPos);\n emitter.patchUint16(nextRowEofPatch, eofPos);\n\n // Sort entries\n emitter.emitUint8(OpCode.OP_SORTER_SORT);\n emitter.emitUint8(0); // sorter_id\n\n // Sorter emit loop\n const emitLoopPos = emitter.currentOffset();\n emitter.emitUint8(OpCode.OP_SORTER_NEXT);\n emitter.emitUint8(0); // sorter_id\n emitter.emitUint16(emitLoopPos); // jumps back until EOF\n\n // Fallthrough on EOF:\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n (result as any).keyInfos = plan.keyInfos;\n (result as any).inSets = inSets;\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n return result;\n }\n\n // Case 3: Scan (Unsorted, non-aggregate) / Nested Loop Joins\n const hasSelectExprs =\n plan.selectExprs !== undefined &&\n plan.selectExprs.length > 0 &&\n !(\n plan.selectExprs.length === 1 &&\n plan.selectExprs[0].expr.type === \"col\" &&\n plan.selectExprs[0].expr.name === \"*\"\n );\n\n let outSelectExprs: ParsedSelectExpr[] = [];\n if (hasSelectExprs) {\n outSelectExprs = plan.selectExprs!;\n } else if (isJoinQuery) {\n const seenNames = new Set<string>();\n const dupNames = new Set<string>();\n for (const t of allTables) {\n for (const c of t.columns) {\n if (seenNames.has(c.name.toLowerCase())) {\n dupNames.add(c.name.toLowerCase());\n }\n seenNames.add(c.name.toLowerCase());\n }\n }\n for (const t of allTables) {\n for (const c of t.columns) {\n const alias = dupNames.has(c.name.toLowerCase())\n ? `${t.name}.${c.name}`\n : c.name;\n outSelectExprs.push({\n expr: { type: \"col\", name: `${t.name}.${c.name}` },\n alias,\n });\n }\n }\n }\n\n let outStartReg = -1;\n if (hasSelectExprs || isJoinQuery) {\n const cols: ColumnMeta[] = outSelectExprs.map((se) => ({\n name: se.alias,\n type: inferExprType(se.expr, table, plan.udfDefs, allTables),\n flags: ColumnFlag.NONE,\n colOffset: 0,\n }));\n plan.outputColumns = cols;\n outStartReg = nextReg;\n nextReg += outSelectExprs.length;\n if (nextReg >= 64) {\n throw new TooManyRegistersError(nextReg);\n }\n }\n\n if (isJoinQuery) {\n const N = allTables.length;\n const regMatched: number[] = new Array(N);\n for (let i = 1; i < N; i++) {\n const joinPlan = plan.joinedTables![i - 1];\n if (joinPlan.type === \"left\") {\n regMatched[i] = nextReg++;\n }\n }\n const regJoinLeft = nextReg++;\n const regJoinRight = nextReg++;\n const regZero = nextReg++;\n\n let regKey0 = -1;\n if (table0Scan && indexCursor0 !== -1) {\n if (table0Scan.compositeValue) {\n regKey0 = nextReg++;\n if (nextReg >= 64) throw new TooManyRegistersError(nextReg);\n emitter.emitUint8(OpCode.OP_LOAD_BLOB);\n emitter.emitUint8(regKey0);\n emitter.emitUint32(table0Scan.compositeValue.length);\n emitter.emitBytes(table0Scan.compositeValue);\n } else if (table0Scan.scanType === \"multi_point\") {\n regKey0 = nextReg++;\n if (nextReg >= 64) throw new TooManyRegistersError(nextReg);\n } else if (table0Scan.filterIndex >= 0) {\n regKey0 = table0Scan.filterIndex * 2 + 1;\n } else {\n // Synthetic range seek for ORDER BY index scan: load minimum possible value\n regKey0 = nextReg++;\n if (nextReg >= 64) throw new TooManyRegistersError(nextReg);\n const minVal = getMinKeyValueForType(table0Scan.keyType);\n emitLoadConstant(emitter, regKey0, minVal, table0Scan.keyType);\n }\n }\n\n if (nextReg >= 64) {\n throw new TooManyRegistersError(nextReg);\n }\n\n // Open Cursors for all tables\n for (let i = 0; i < N; i++) {\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(i);\n emitter.emitUint32(allTables[i].rootPageId);\n }\n\n // Open Table 0 index cursor if table0Scan is active\n if (table0Scan && indexCursor0 !== -1) {\n emitter.emitUint8(OpCode.OP_OPEN_INDEX);\n emitter.emitUint8(indexCursor0);\n emitter.emitUint32(table0Scan.index.rootPageId);\n }\n\n // Open index cursors for accelerated joins\n for (let i = 1; i < N; i++) {\n const jIdx = joinIndices[i];\n if (jIdx) {\n emitter.emitUint8(OpCode.OP_OPEN_INDEX);\n emitter.emitUint8(jIdx.indexCursor);\n emitter.emitUint32(jIdx.index.rootPageId);\n }\n }\n\n const rewindJumpPatches: number[] = new Array(N);\n const loopStartPositions: number[] = new Array(N);\n const nextRowPatchesPerTable: number[][] = Array.from(\n { length: N },\n () => [],\n );\n const nextRowEofPatches: number[] = new Array(N);\n const limitHaltPatches: number[] = [];\n\n // Outer table (Table 0) Seek or Rewind\n if (table0Scan && indexCursor0 !== -1) {\n if (table0Scan.scanType === \"point\") {\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_EQ);\n emitter.emitUint8(indexCursor0);\n emitter.emitUint8(0);\n emitter.emitUint8(regKey0);\n emitter.emitUint8(table0Scan.keyType);\n rewindJumpPatches[0] = emitter.emitUint16(0);\n } else {\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_GE);\n emitter.emitUint8(indexCursor0);\n emitter.emitUint8(0);\n emitter.emitUint8(regKey0);\n emitter.emitUint8(table0Scan.keyType);\n rewindJumpPatches[0] = emitter.emitUint16(0);\n }\n } else {\n emitter.emitUint8(OpCode.OP_REWIND);\n emitter.emitUint8(0);\n rewindJumpPatches[0] = emitter.emitUint16(0);\n }\n\n loopStartPositions[0] = emitter.currentOffset();\n\n // Early filter pushdown for Table 0\n if (pushedFilters[0] && pushedFilters[0].length > 0) {\n const root0 = buildRootFilter(pushedFilters[0]);\n emitFilterTree(\n root0,\n allTables[0],\n emitter,\n leafRegMap,\n nextRowPatchesPerTable[0],\n plan.udfNameMap,\n allTables,\n filterSetMap,\n );\n }\n\n // Nested Joined Tables (1..N-1)\n for (let i = 1; i < N; i++) {\n const joinPlan = plan.joinedTables![i - 1];\n const jIdx = joinIndices[i];\n\n if (joinPlan.type === \"left\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regMatched[i]);\n emitter.emitInt32(0);\n }\n\n if (jIdx && jIdx.isUnique) {\n // Point seek into unique index\n emitReadColumn(\n emitter,\n jIdx.outerCol.cursor,\n jIdx.outerCol.colIdx,\n regJoinLeft,\n jIdx.outerCol.col.type,\n );\n\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_EQ);\n emitter.emitUint8(jIdx.indexCursor);\n emitter.emitUint8(i); // data cursor\n emitter.emitUint8(regJoinLeft);\n emitter.emitUint8(jIdx.outerCol.col.type);\n rewindJumpPatches[i] = emitter.emitUint16(0); // If not found, jumps to eofPos of table i\n\n loopStartPositions[i] = emitter.currentOffset();\n\n if (\n joinPlan.type === \"inner\" &&\n pushedFilters[i] &&\n pushedFilters[i].length > 0\n ) {\n const rootI = buildRootFilter(pushedFilters[i]);\n emitFilterTree(\n rootI,\n allTables[i],\n emitter,\n leafRegMap,\n nextRowPatchesPerTable[i],\n plan.udfNameMap,\n allTables,\n filterSetMap,\n );\n }\n\n if (joinPlan.type === \"left\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regMatched[i]);\n emitter.emitInt32(1);\n }\n } else if (jIdx && !jIdx.isUnique) {\n // Range seek into non-unique index\n emitReadColumn(\n emitter,\n jIdx.outerCol.cursor,\n jIdx.outerCol.colIdx,\n regJoinLeft,\n jIdx.outerCol.col.type,\n );\n\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_GE);\n emitter.emitUint8(jIdx.indexCursor);\n emitter.emitUint8(i); // data cursor\n emitter.emitUint8(regJoinLeft);\n emitter.emitUint8(jIdx.outerCol.col.type);\n rewindJumpPatches[i] = emitter.emitUint16(0); // If no entries >= key, jumps to eofPos\n\n loopStartPositions[i] = emitter.currentOffset();\n\n emitReadColumn(\n emitter,\n i,\n jIdx.innerCol.colIdx,\n regJoinRight,\n jIdx.innerCol.col.type,\n );\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regJoinLeft);\n emitter.emitUint8(regJoinRight);\n const condMatchPatch = emitter.emitUint16(0);\n\n // Mismatch: we scanned past all duplicates for this key! Jump to eofPos\n emitter.emitUint8(OpCode.OP_JUMP);\n nextRowPatchesPerTable[i].push(emitter.emitUint16(0));\n\n // Match\n emitter.patchUint16(condMatchPatch, emitter.currentOffset());\n\n if (\n joinPlan.type === \"inner\" &&\n pushedFilters[i] &&\n pushedFilters[i].length > 0\n ) {\n const rootI = buildRootFilter(pushedFilters[i]);\n emitFilterTree(\n rootI,\n allTables[i],\n emitter,\n leafRegMap,\n nextRowPatchesPerTable[i],\n plan.udfNameMap,\n allTables,\n filterSetMap,\n );\n }\n\n if (joinPlan.type === \"left\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regMatched[i]);\n emitter.emitInt32(1);\n }\n } else {\n // Cartesian Fallback\n emitter.emitUint8(OpCode.OP_REWIND);\n emitter.emitUint8(i);\n rewindJumpPatches[i] = emitter.emitUint16(0);\n\n loopStartPositions[i] = emitter.currentOffset();\n\n const resolvedLeft = resolveColumnAcrossTables(\n joinPlan.leftCol,\n allTables,\n );\n if (!resolvedLeft) {\n throw new Error(\n `Join column \"${joinPlan.leftCol}\" not found in tables`,\n );\n }\n const resolvedRight = resolveColumnAcrossTables(\n joinPlan.rightCol,\n allTables,\n );\n if (!resolvedRight) {\n throw new Error(\n `Join column \"${joinPlan.rightCol}\" not found in tables`,\n );\n }\n\n emitReadColumn(\n emitter,\n resolvedLeft.cursor,\n resolvedLeft.colIdx,\n regJoinLeft,\n resolvedLeft.col.type,\n );\n emitReadColumn(\n emitter,\n resolvedRight.cursor,\n resolvedRight.colIdx,\n regJoinRight,\n resolvedRight.col.type,\n );\n\n let cmpOp: OpCode;\n switch (joinPlan.op) {\n case \"=\":\n cmpOp = OpCode.OP_EQ;\n break;\n case \"!=\":\n cmpOp = OpCode.OP_NE;\n break;\n case \">\":\n cmpOp = OpCode.OP_GT;\n break;\n case \">=\":\n cmpOp = OpCode.OP_GE;\n break;\n case \"<\":\n cmpOp = OpCode.OP_LT;\n break;\n case \"<=\":\n cmpOp = OpCode.OP_LE;\n break;\n default:\n cmpOp = OpCode.OP_EQ;\n }\n\n emitter.emitUint8(cmpOp);\n emitter.emitUint8(regJoinLeft);\n emitter.emitUint8(regJoinRight);\n const condMatchPatch = emitter.emitUint16(0);\n\n // Mismatch: jump to nextRow for table i\n emitter.emitUint8(OpCode.OP_JUMP);\n nextRowPatchesPerTable[i].push(emitter.emitUint16(0));\n\n // Match\n emitter.patchUint16(condMatchPatch, emitter.currentOffset());\n\n if (\n joinPlan.type === \"inner\" &&\n pushedFilters[i] &&\n pushedFilters[i].length > 0\n ) {\n const rootI = buildRootFilter(pushedFilters[i]);\n emitFilterTree(\n rootI,\n allTables[i],\n emitter,\n leafRegMap,\n nextRowPatchesPerTable[i],\n plan.udfNameMap,\n allTables,\n filterSetMap,\n );\n }\n\n if (joinPlan.type === \"left\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regMatched[i]);\n emitter.emitInt32(1);\n }\n }\n }\n\n // Innermost: remaining WHERE filters\n emitFilterTree(\n rootRemainingFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatchesPerTable[N - 1],\n plan.udfNameMap,\n allTables,\n filterSetMap,\n );\n\n const hasOrderBy = plan.orderBy !== undefined && plan.orderBy.length > 0;\n const shouldApplyLimitOffset = !hasOrderBy || isJoinOrderPreserved;\n\n let offsetSkipPatch = -1;\n if (hasOffset && shouldApplyLimitOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n offsetSkipPatch = emitter.emitUint16(0);\n }\n\n let exprTempReg = nextReg;\n const allocExprReg = () => {\n if (exprTempReg >= 64) throw new TooManyRegistersError(exprTempReg);\n return exprTempReg++;\n };\n\n for (let k = 0; k < outSelectExprs.length; k++) {\n emitExpression(\n outSelectExprs[k].expr,\n table,\n emitter,\n 0,\n outStartReg + k,\n allocExprReg,\n plan.udfNameMap,\n undefined,\n allTables,\n );\n }\n\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(outSelectExprs.length);\n\n if (hasLimit && shouldApplyLimitOffset) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n limitHaltPatches.push(emitter.emitUint16(0));\n }\n\n // Close loops from innermost to outermost\n for (let i = N - 1; i >= 1; i--) {\n const nextRowPos = emitter.currentOffset();\n if (i === N - 1 && offsetSkipPatch !== -1) {\n emitter.patchUint16(offsetSkipPatch, nextRowPos);\n }\n for (const patch of nextRowPatchesPerTable[i]) {\n emitter.patchUint16(patch, nextRowPos);\n }\n\n const jIdx = joinIndices[i];\n if (jIdx && jIdx.isUnique) {\n // Point seek: at most 1 match\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatches[i], eofPos);\n } else if (jIdx && !jIdx.isUnique) {\n // Non-unique index: advance index cursor to next entry\n emitter.emitUint8(OpCode.OP_INDEX_NEXT);\n emitter.emitUint8(jIdx.indexCursor);\n emitter.emitUint8(i); // data cursor\n nextRowEofPatches[i] = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPositions[i]);\n\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatches[i], eofPos);\n emitter.patchUint16(nextRowEofPatches[i], eofPos);\n } else {\n // Cartesian fallback: OP_NEXT_ROW\n emitter.emitUint8(OpCode.OP_NEXT_ROW);\n emitter.emitUint8(i);\n nextRowEofPatches[i] = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPositions[i]);\n\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatches[i], eofPos);\n emitter.patchUint16(nextRowEofPatches[i], eofPos);\n }\n\n const joinPlan = plan.joinedTables![i - 1];\n if (joinPlan.type === \"left\") {\n emitter.emitUint8(OpCode.OP_LOAD_INT);\n emitter.emitUint8(regZero);\n emitter.emitInt32(0);\n\n emitter.emitUint8(OpCode.OP_EQ);\n emitter.emitUint8(regMatched[i]);\n emitter.emitUint8(regZero);\n const nullRowBranchPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n const skipNullRowPatch = emitter.emitUint16(0);\n\n emitter.patchUint16(nullRowBranchPatch, emitter.currentOffset());\n\n for (let k = 0; k < outSelectExprs.length; k++) {\n const se = outSelectExprs[k];\n let refTableIdx = -1;\n if (se.expr.type === \"col\") {\n const resolved = resolveColumnAcrossTables(se.expr.name, allTables);\n if (resolved) {\n refTableIdx = resolved.tableIdx;\n }\n }\n if (refTableIdx >= i) {\n emitter.emitUint8(OpCode.OP_LOAD_NULL);\n emitter.emitUint8(outStartReg + k);\n } else {\n emitExpression(\n se.expr,\n table,\n emitter,\n 0,\n outStartReg + k,\n allocExprReg,\n plan.udfNameMap,\n undefined,\n allTables,\n );\n }\n }\n\n const afterNullRowPatches: number[] = [];\n if (hasOffset && shouldApplyLimitOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n afterNullRowPatches.push(emitter.emitUint16(0));\n }\n\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(outSelectExprs.length);\n\n if (hasLimit && shouldApplyLimitOffset) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n limitHaltPatches.push(emitter.emitUint16(0));\n }\n\n const afterNullRowPos = emitter.currentOffset();\n emitter.patchUint16(skipNullRowPatch, afterNullRowPos);\n for (const p of afterNullRowPatches) {\n emitter.patchUint16(p, afterNullRowPos);\n }\n }\n }\n\n const nextRowPos0 = emitter.currentOffset();\n for (const patch of nextRowPatchesPerTable[0]) {\n emitter.patchUint16(patch, nextRowPos0);\n }\n\n if (table0Scan && indexCursor0 !== -1) {\n if (table0Scan.scanType === \"point\") {\n emitter.emitUint8(OpCode.OP_JUMP);\n nextRowEofPatches[0] = emitter.emitUint16(0);\n } else {\n emitter.emitUint8(OpCode.OP_INDEX_NEXT);\n emitter.emitUint8(indexCursor0);\n emitter.emitUint8(0);\n nextRowEofPatches[0] = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPositions[0]);\n }\n } else {\n emitter.emitUint8(OpCode.OP_NEXT_ROW);\n emitter.emitUint8(0);\n nextRowEofPatches[0] = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPositions[0]);\n }\n\n const eofPos0 = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatches[0], eofPos0);\n emitter.patchUint16(nextRowEofPatches[0], eofPos0);\n for (const patch of limitHaltPatches) {\n emitter.patchUint16(patch, eofPos0);\n }\n\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n const joinedTableScans = plan.joinedTables?.map((j, idx) => {\n const tableIdx = idx + 1;\n const cand = joinIndices[tableIdx];\n return {\n tableIndex: tableIdx,\n tableName: j.table.name,\n scanType: cand ? (\"IndexScan\" as const) : (\"TableScan\" as const),\n indexName: cand ? cand.index.name : undefined,\n };\n });\n (result as any).joinedTableScans = joinedTableScans;\n (result as any).allTables = allTables;\n (result as any).inSets = inSets;\n (result as any).table0Scan = table0Scan;\n (result as any).isOrderSatisfied = isJoinOrderPreserved;\n if (isJoinOrderPreserved) {\n plan.isOrderSatisfied = true;\n }\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n if (whereMetrics) {\n (result as any).whereMetrics = whereMetrics;\n }\n return result;\n }\n\n if (indexScan) {\n let regKey: number;\n if (indexScan.compositeValue) {\n regKey = nextReg++;\n if (regKey >= 64) throw new TooManyRegistersError(regKey);\n emitter.emitUint8(OpCode.OP_LOAD_BLOB);\n emitter.emitUint8(regKey);\n emitter.emitBytes(indexScan.compositeValue);\n } else if (indexScan.scanType === \"multi_point\") {\n regKey = nextReg++;\n if (regKey >= 64) throw new TooManyRegistersError(regKey);\n } else if (indexScan.filterIndex >= 0) {\n regKey = indexScan.filterIndex * 2 + 1;\n } else {\n // Synthetic index scan for ORDER BY: load min key value for the index column\n regKey = nextReg++;\n if (regKey >= 64) throw new TooManyRegistersError(regKey);\n const minVal = getMinKeyValueForType(indexScan.keyType);\n emitLoadConstant(emitter, regKey, minVal, indexScan.keyType);\n }\n\n if (indexScan.scanType === \"point\") {\n // 1. Open data cursor 0 on table\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n // 2. Open index cursor 1 on index rootPageId\n emitter.emitUint8(OpCode.OP_OPEN_INDEX);\n emitter.emitUint8(1);\n emitter.emitUint32(indexScan.index.rootPageId);\n\n // 3. Exact point seek in index\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_EQ);\n emitter.emitUint8(1); // index cursor\n emitter.emitUint8(0); // data cursor\n emitter.emitUint8(regKey);\n emitter.emitUint8(indexScan.keyType);\n const seekNotFoundPatch = emitter.emitUint16(0);\n\n // 4. Run remaining filter predicates on the row (if any)\n const nextRowPatches: number[] = [];\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n let offsetSkipPatch = -1;\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n offsetSkipPatch = emitter.emitUint16(0);\n }\n\n // 5. Emit matching row\n if (hasSelectExprs) {\n let exprTempReg = nextReg;\n const allocExprReg = () => {\n if (exprTempReg >= 64) throw new TooManyRegistersError(exprTempReg);\n return exprTempReg++;\n };\n for (let i = 0; i < plan.selectExprs!.length; i++) {\n emitExpression(\n plan.selectExprs![i].expr,\n table,\n emitter,\n 0,\n outStartReg + i,\n allocExprReg,\n plan.udfNameMap,\n );\n }\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(plan.selectExprs!.length);\n } else {\n emitter.emitUint8(OpCode.OP_EMIT_ROW);\n emitter.emitUint8(0);\n }\n\n // 6. Point match handled: jump to EOF\n emitter.emitUint8(OpCode.OP_JUMP);\n const jumpEofPatch = emitter.emitUint16(0);\n\n // EOF Label\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(seekNotFoundPatch, eofPos);\n emitter.patchUint16(jumpEofPatch, eofPos);\n if (offsetSkipPatch !== -1) {\n emitter.patchUint16(offsetSkipPatch, eofPos);\n }\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, eofPos);\n }\n\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n (result as any).indexScan = indexScan;\n (result as any).inSets = inSets;\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n if (indexScan?.satisfiesOrderBy) {\n (result as any).isOrderSatisfied = true;\n plan.isOrderSatisfied = true;\n }\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n return result;\n } else if (indexScan.scanType === \"multi_point\") {\n const numValues = indexScan.inValues ? indexScan.inValues.length : 0;\n if (numValues === 0) {\n emitter.emitUint8(OpCode.OP_HALT);\n const result = emitter.toByteArray();\n (result as any).indexScan = indexScan;\n (result as any).inSets = inSets;\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n return result;\n }\n\n // 1. Open data cursor 0 on table\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n // 2. Open index cursor 1 on index rootPageId\n emitter.emitUint8(OpCode.OP_OPEN_INDEX);\n emitter.emitUint8(1);\n emitter.emitUint32(indexScan.index.rootPageId);\n\n const limitHaltPatches: number[] = [];\n\n for (let vIdx = 0; vIdx < numValues; vIdx++) {\n const val = indexScan.inValues![vIdx];\n emitLoadConstant(emitter, regKey, val, indexScan.keyType);\n\n // 3. Exact point seek in index for this value\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_EQ);\n emitter.emitUint8(1); // index cursor\n emitter.emitUint8(0); // data cursor\n emitter.emitUint8(regKey);\n emitter.emitUint8(indexScan.keyType);\n const seekNotFoundPatch = emitter.emitUint16(0);\n\n // 4. Run remaining filter predicates on the row (if any)\n const nextRowPatches: number[] = [];\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n let offsetSkipPatch = -1;\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n offsetSkipPatch = emitter.emitUint16(0);\n }\n\n // 5. Emit matching row\n if (hasSelectExprs) {\n let exprTempReg = nextReg;\n const allocExprReg = () => {\n if (exprTempReg >= 64) throw new TooManyRegistersError(exprTempReg);\n return exprTempReg++;\n };\n for (let i = 0; i < plan.selectExprs!.length; i++) {\n emitExpression(\n plan.selectExprs![i].expr,\n table,\n emitter,\n 0,\n outStartReg + i,\n allocExprReg,\n plan.udfNameMap,\n );\n }\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(plan.selectExprs!.length);\n } else {\n emitter.emitUint8(OpCode.OP_EMIT_ROW);\n emitter.emitUint8(0);\n }\n\n if (hasLimit) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n limitHaltPatches.push(emitter.emitUint16(0));\n }\n\n const isLastVal = vIdx === numValues - 1;\n let jumpNextValPatch = -1;\n if (!isLastVal) {\n emitter.emitUint8(OpCode.OP_JUMP);\n jumpNextValPatch = emitter.emitUint16(0);\n }\n\n const nextValPos = emitter.currentOffset();\n emitter.patchUint16(seekNotFoundPatch, nextValPos);\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, nextValPos);\n }\n if (offsetSkipPatch !== -1) {\n emitter.patchUint16(offsetSkipPatch, nextValPos);\n }\n if (jumpNextValPatch !== -1) {\n emitter.patchUint16(jumpNextValPatch, nextValPos);\n }\n }\n\n // EOF Label\n const eofPos = emitter.currentOffset();\n for (const patch of limitHaltPatches) {\n emitter.patchUint16(patch, eofPos);\n }\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n (result as any).indexScan = indexScan;\n (result as any).inSets = inSets;\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n if (indexScan?.satisfiesOrderBy) {\n (result as any).isOrderSatisfied = true;\n plan.isOrderSatisfied = true;\n }\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n return result;\n } else {\n // Range seek in index\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n emitter.emitUint8(OpCode.OP_OPEN_INDEX);\n emitter.emitUint8(1);\n emitter.emitUint32(indexScan.index.rootPageId);\n\n emitter.emitUint8(OpCode.OP_INDEX_SEEK_GE);\n emitter.emitUint8(1);\n emitter.emitUint8(0);\n emitter.emitUint8(regKey);\n emitter.emitUint8(indexScan.keyType);\n const seekEofPatch = emitter.emitUint16(0);\n\n const loopStartPos = emitter.currentOffset();\n const nextRowPatches: number[] = [];\n\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n let offsetSkipPatch = -1;\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n offsetSkipPatch = emitter.emitUint16(0);\n }\n\n if (hasSelectExprs) {\n let exprTempReg = nextReg;\n const allocExprReg = () => {\n if (exprTempReg >= 64) throw new TooManyRegistersError(exprTempReg);\n return exprTempReg++;\n };\n for (let i = 0; i < plan.selectExprs!.length; i++) {\n emitExpression(\n plan.selectExprs![i].expr,\n table,\n emitter,\n 0,\n outStartReg + i,\n allocExprReg,\n plan.udfNameMap,\n );\n }\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(plan.selectExprs!.length);\n } else {\n emitter.emitUint8(OpCode.OP_EMIT_ROW);\n emitter.emitUint8(0);\n }\n\n let limitHaltPatch = -1;\n if (hasLimit) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n limitHaltPatch = emitter.emitUint16(0);\n }\n\n const nextRowPos = emitter.currentOffset();\n if (offsetSkipPatch !== -1) {\n emitter.patchUint16(offsetSkipPatch, nextRowPos);\n }\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, nextRowPos);\n }\n\n emitter.emitUint8(OpCode.OP_INDEX_NEXT);\n emitter.emitUint8(1);\n emitter.emitUint8(0);\n const nextRowEofPatch = emitter.emitUint16(0);\n\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPos);\n\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(seekEofPatch, eofPos);\n emitter.patchUint16(nextRowEofPatch, eofPos);\n if (limitHaltPatch !== -1) {\n emitter.patchUint16(limitHaltPatch, eofPos);\n }\n\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n (result as any).indexScan = indexScan;\n (result as any).inSets = inSets;\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n if (indexScan?.satisfiesOrderBy) {\n (result as any).isOrderSatisfied = true;\n plan.isOrderSatisfied = true;\n }\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n return result;\n }\n }\n\n // Open Cursor (Fallback Table Scan)\n emitter.emitUint8(OpCode.OP_OPEN_CURSOR);\n emitter.emitUint8(0);\n emitter.emitUint32(table.rootPageId);\n\n // Rewind Cursor\n emitter.emitUint8(OpCode.OP_REWIND);\n emitter.emitUint8(0);\n const rewindJumpPatch = emitter.emitUint16(0);\n\n // Loop start\n const loopStartPos = emitter.currentOffset();\n const nextRowPatches: number[] = [];\n\n emitFilterTree(\n rootFilter,\n table,\n emitter,\n leafRegMap,\n nextRowPatches,\n plan.udfNameMap,\n undefined,\n filterSetMap,\n );\n\n let offsetSkipPatch = -1;\n if (hasOffset) {\n emitter.emitUint8(OpCode.OP_OFFSET);\n emitter.emitUint8(regOffset);\n offsetSkipPatch = emitter.emitUint16(0);\n }\n\n // Emit matching row\n if (hasSelectExprs) {\n let exprTempReg = nextReg;\n const allocExprReg = () => {\n if (exprTempReg >= 64) throw new TooManyRegistersError(exprTempReg);\n return exprTempReg++;\n };\n for (let i = 0; i < plan.selectExprs!.length; i++) {\n emitExpression(\n plan.selectExprs![i].expr,\n table,\n emitter,\n 0,\n outStartReg + i,\n allocExprReg,\n plan.udfNameMap,\n );\n }\n emitter.emitUint8(OpCode.OP_RESULT_ROW);\n emitter.emitUint8(outStartReg);\n emitter.emitUint8(plan.selectExprs!.length);\n } else {\n emitter.emitUint8(OpCode.OP_EMIT_ROW);\n emitter.emitUint8(0);\n }\n\n let limitHaltPatch = -1;\n if (hasLimit) {\n emitter.emitUint8(OpCode.OP_LIMIT);\n emitter.emitUint8(regLimit);\n limitHaltPatch = emitter.emitUint16(0);\n }\n\n // next_row_label\n const nextRowPos = emitter.currentOffset();\n if (offsetSkipPatch !== -1) {\n emitter.patchUint16(offsetSkipPatch, nextRowPos);\n }\n for (const patch of nextRowPatches) {\n emitter.patchUint16(patch, nextRowPos);\n }\n\n // Advance cursor\n emitter.emitUint8(OpCode.OP_NEXT_ROW);\n emitter.emitUint8(0);\n const nextRowEofPatch = emitter.emitUint16(0);\n\n // Loop back\n emitter.emitUint8(OpCode.OP_JUMP);\n emitter.emitUint16(loopStartPos);\n\n // EOF Label\n const eofPos = emitter.currentOffset();\n emitter.patchUint16(rewindJumpPatch, eofPos);\n emitter.patchUint16(nextRowEofPatch, eofPos);\n if (limitHaltPatch !== -1) {\n emitter.patchUint16(limitHaltPatch, eofPos);\n }\n\n emitter.emitUint8(OpCode.OP_HALT);\n\n const result = emitter.toByteArray();\n (result as any).inSets = inSets;\n if (plan.outputColumns) {\n (result as any).outputColumns = plan.outputColumns;\n }\n if (whereMetrics) {\n (result as any).whereMetrics = whereMetrics;\n }\n if (planMetrics) {\n (result as any).planMetrics = planMetrics;\n (result as any).estimatedCost = planMetrics.totalCost;\n (result as any).estimatedRows = planMetrics.estimatedRows;\n (result as any).joinOrder = planMetrics.joinOrder;\n }\n return result;\n}\n\nexport interface DisassembledInstruction {\n addr: number;\n opcode: string;\n p1: string;\n p2: string;\n p3: string;\n comment: string;\n}\n\nconst textDecoder = new TextDecoder();\n\n/**\n * Disassembles binary bytecode into human-readable instructions.\n */\nexport function disassembleBytecode(\n bytecode: Uint8Array,\n table?: TableMeta,\n): DisassembledInstruction[] {\n const instructions: DisassembledInstruction[] = [];\n const view = new DataView(\n bytecode.buffer,\n bytecode.byteOffset,\n bytecode.byteLength,\n );\n let pc = 0;\n\n const getColName = (idx: number) => {\n return table?.columns[idx]?.name\n ? `'${table.columns[idx].name}'`\n : `col_${idx}`;\n };\n\n const fmtAddr = (n: number) => `0x${n.toString(16).padStart(4, \"0\")}`;\n\n while (pc < bytecode.byteLength) {\n const addr = pc;\n const op = bytecode[pc++];\n\n switch (op) {\n case OpCode.OP_HALT:\n instructions.push({\n addr,\n opcode: \"OP_HALT\",\n p1: \"\",\n p2: \"\",\n p3: \"\",\n comment: \"Halt VM execution (STATUS_DONE)\",\n });\n break;\n\n case OpCode.OP_OPEN_CURSOR: {\n const cursor = bytecode[pc++];\n const rootPage = view.getUint32(pc, true);\n pc += 4;\n instructions.push({\n addr,\n opcode: \"OP_OPEN_CURSOR\",\n p1: `c[${cursor}]`,\n p2: `page=${rootPage}`,\n p3: \"\",\n comment: `Open cursor ${cursor} on root page ${rootPage}${table ? ` ('${table.name}')` : \"\"}`,\n });\n break;\n }\n\n case OpCode.OP_OPEN_INDEX: {\n const cursor = bytecode[pc++];\n const rootPage = view.getUint32(pc, true);\n pc += 4;\n instructions.push({\n addr,\n opcode: \"OP_OPEN_INDEX\",\n p1: `c[${cursor}]`,\n p2: `page=${rootPage}`,\n p3: \"\",\n comment: `Open index cursor ${cursor} on root page ${rootPage}`,\n });\n break;\n }\n\n case OpCode.OP_INDEX_SEEK_EQ: {\n const idxCursor = bytecode[pc++];\n const dataCursor = bytecode[pc++];\n const regKey = bytecode[pc++];\n const keyType = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_INDEX_SEEK_EQ\",\n p1: `idx=c[${idxCursor}], data=c[${dataCursor}]`,\n p2: `key=r[${regKey}], type=${keyType}`,\n p3: fmtAddr(jumpTarget),\n comment: `Seek exact key in index; position data cursor or jump to ${fmtAddr(jumpTarget)} if not found`,\n });\n break;\n }\n\n case OpCode.OP_INDEX_SEEK_GE: {\n const idxCursor = bytecode[pc++];\n const dataCursor = bytecode[pc++];\n const regKey = bytecode[pc++];\n const keyType = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_INDEX_SEEK_GE\",\n p1: `idx=c[${idxCursor}], data=c[${dataCursor}]`,\n p2: `key=r[${regKey}], type=${keyType}`,\n p3: fmtAddr(jumpTarget),\n comment: `Seek first entry >= key in index; position data cursor or jump to ${fmtAddr(jumpTarget)} if EOF`,\n });\n break;\n }\n\n case OpCode.OP_INDEX_NEXT: {\n const idxCursor = bytecode[pc++];\n const dataCursor = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_INDEX_NEXT\",\n p1: `idx=c[${idxCursor}], data=c[${dataCursor}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Advance index cursor to next entry; jump to ${fmtAddr(jumpTarget)} if EOF`,\n });\n break;\n }\n\n case OpCode.OP_REWIND: {\n const cursor = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_REWIND\",\n p1: `c[${cursor}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Rewind cursor to first row; jump to ${fmtAddr(jumpTarget)} if empty`,\n });\n break;\n }\n\n case OpCode.OP_NEXT_ROW: {\n const cursor = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_NEXT_ROW\",\n p1: `c[${cursor}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Advance cursor to next row; jump to ${fmtAddr(jumpTarget)} if EOF`,\n });\n break;\n }\n\n case OpCode.OP_LAST: {\n const cursor = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_LAST\",\n p1: `c[${cursor}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Position cursor to last row; jump to ${fmtAddr(jumpTarget)} if empty`,\n });\n break;\n }\n\n case OpCode.OP_PREV_ROW: {\n const cursor = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_PREV_ROW\",\n p1: `c[${cursor}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Advance cursor to previous row; jump to ${fmtAddr(jumpTarget)} if BOF`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_INT: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_INT\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as INT into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_FLOAT: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_FLOAT\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as FLOAT into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_TEXT: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_TEXT\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as TEXT into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_BLOB: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_BLOB\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as BLOB into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_UUID: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_UUID\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as UUID into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_COLUMN_ULID: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COLUMN_ULID\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: `r[${regIdx}]`,\n comment: `Read ${getColName(colIdx)} as ULID into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_IS_NULL: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_IS_NULL\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: fmtAddr(jumpTarget),\n comment: `If ${getColName(colIdx)} IS NULL -> jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_IS_NOT_NULL: {\n const cursor = bytecode[pc++];\n const colIdx = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_IS_NOT_NULL\",\n p1: `c[${cursor}]`,\n p2: `${colIdx} (${getColName(colIdx)})`,\n p3: fmtAddr(jumpTarget),\n comment: `If ${getColName(colIdx)} IS NOT NULL -> jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_EQ:\n case OpCode.OP_NE:\n case OpCode.OP_GT:\n case OpCode.OP_GE:\n case OpCode.OP_LT:\n case OpCode.OP_LE: {\n const opNames: Record<number, string> = {\n [OpCode.OP_EQ]: \"OP_EQ\",\n [OpCode.OP_NE]: \"OP_NE\",\n [OpCode.OP_GT]: \"OP_GT\",\n [OpCode.OP_GE]: \"OP_GE\",\n [OpCode.OP_LT]: \"OP_LT\",\n [OpCode.OP_LE]: \"OP_LE\",\n };\n const symbols: Record<number, string> = {\n [OpCode.OP_EQ]: \"==\",\n [OpCode.OP_NE]: \"!=\",\n [OpCode.OP_GT]: \">\",\n [OpCode.OP_GE]: \">=\",\n [OpCode.OP_LT]: \"<\",\n [OpCode.OP_LE]: \"<=\",\n };\n const regA = bytecode[pc++];\n const regB = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: opNames[op],\n p1: `r[${regA}]`,\n p2: `r[${regB}]`,\n p3: fmtAddr(jumpTarget),\n comment: `If r[${regA}] ${symbols[op]} r[${regB}] -> jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_JUMP: {\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_JUMP\",\n p1: fmtAddr(jumpTarget),\n p2: \"\",\n p3: \"\",\n comment: `Unconditional jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_STR_LIKE:\n case OpCode.OP_STR_NOT_LIKE:\n case OpCode.OP_STR_CONTAINS:\n case OpCode.OP_STR_STARTS_WITH:\n case OpCode.OP_STR_ENDS_WITH: {\n const opNames: Record<number, string> = {\n [OpCode.OP_STR_LIKE]: \"OP_STR_LIKE\",\n [OpCode.OP_STR_NOT_LIKE]: \"OP_STR_NOT_LIKE\",\n [OpCode.OP_STR_CONTAINS]: \"OP_STR_CONTAINS\",\n [OpCode.OP_STR_STARTS_WITH]: \"OP_STR_STARTS_WITH\",\n [OpCode.OP_STR_ENDS_WITH]: \"OP_STR_ENDS_WITH\",\n };\n const descriptions: Record<number, string> = {\n [OpCode.OP_STR_LIKE]: \"LIKE\",\n [OpCode.OP_STR_NOT_LIKE]: \"NOT LIKE\",\n [OpCode.OP_STR_CONTAINS]: \"CONTAINS\",\n [OpCode.OP_STR_STARTS_WITH]: \"STARTS_WITH\",\n [OpCode.OP_STR_ENDS_WITH]: \"ENDS_WITH\",\n };\n const regA = bytecode[pc++];\n const regB = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: opNames[op],\n p1: `r[${regA}]`,\n p2: `r[${regB}]`,\n p3: fmtAddr(jumpTarget),\n comment: `If r[${regA}] ${descriptions[op]} r[${regB}] -> jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_IN: {\n const regVal = bytecode[pc++];\n const setIdx = view.getUint16(pc, true);\n pc += 2;\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_IN\",\n p1: `r[${regVal}]`,\n p2: `set[${setIdx}]`,\n p3: fmtAddr(jumpTarget),\n comment: `If r[${regVal}] IN set[${setIdx}] -> jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_LOAD_INT: {\n const regIdx = bytecode[pc++];\n const val = view.getInt32(pc, true);\n pc += 4;\n instructions.push({\n addr,\n opcode: \"OP_LOAD_INT\",\n p1: `r[${regIdx}]`,\n p2: `${val}`,\n p3: \"\",\n comment: `Load literal int ${val} into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_LOAD_FLOAT: {\n const regIdx = bytecode[pc++];\n const val = view.getFloat64(pc, true);\n pc += 8;\n instructions.push({\n addr,\n opcode: \"OP_LOAD_FLOAT\",\n p1: `r[${regIdx}]`,\n p2: `${val}`,\n p3: \"\",\n comment: `Load literal float ${val} into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_LOAD_TEXT: {\n const regIdx = bytecode[pc++];\n const len = view.getUint16(pc, true);\n pc += 2;\n const textBytes = new Uint8Array(\n bytecode.buffer,\n bytecode.byteOffset + pc,\n len,\n );\n const str = textDecoder.decode(textBytes);\n pc += len;\n instructions.push({\n addr,\n opcode: \"OP_LOAD_TEXT\",\n p1: `r[${regIdx}]`,\n p2: `\"${str}\"`,\n p3: \"\",\n comment: `Load literal text \"${str}\" into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_LOAD_BLOB: {\n const regIdx = bytecode[pc++];\n const len = view.getUint16(pc, true);\n pc += 2 + len;\n instructions.push({\n addr,\n opcode: \"OP_LOAD_BLOB\",\n p1: `r[${regIdx}]`,\n p2: `len=${len}`,\n p3: \"\",\n comment: `Load literal BLOB (${len} bytes) into r[${regIdx}]`,\n });\n break;\n }\n\n case OpCode.OP_LOAD_NULL: {\n const regIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_LOAD_NULL\",\n p1: `r[${regIdx}]`,\n p2: \"NULL\",\n p3: \"\",\n comment: `Set r[${regIdx}] to NULL`,\n });\n break;\n }\n\n case OpCode.OP_EMIT_ROW: {\n const cursor = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_EMIT_ROW\",\n p1: `c[${cursor}]`,\n p2: \"\",\n p3: \"\",\n comment: `Row passed all filters -> emit to Output Result Buffer`,\n });\n break;\n }\n\n case OpCode.OP_RESULT_ROW: {\n const startReg = bytecode[pc++];\n const numCols = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_RESULT_ROW\",\n p1: `r[${startReg}]`,\n p2: `cols=${numCols}`,\n p3: \"\",\n comment: `Serialize registers r[${startReg}..${startReg + numCols - 1}] to Result Buffer`,\n });\n break;\n }\n\n case OpCode.OP_OFFSET: {\n const offsetReg = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_OFFSET\",\n p1: `r[${offsetReg}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `If r[${offsetReg}] > 0 -> decrement and skip row to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_LIMIT: {\n const limitReg = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_LIMIT\",\n p1: `r[${limitReg}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `If r[${limitReg}] <= 1 -> halt to ${fmtAddr(jumpTarget)}, else decrement`,\n });\n break;\n }\n case OpCode.OP_CALL_UDF: {\n const udfId = view.getUint16(pc, true);\n pc += 2;\n const startArgReg = bytecode[pc++];\n const numArgs = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_CALL_UDF\",\n p1: `udf#${udfId}`,\n p2: `r[${startArgReg}..${startArgReg + numArgs - 1}]`,\n p3: `r[${destReg}]`,\n comment: `Call UDF #${udfId} with ${numArgs} args -> r[${destReg}]`,\n });\n break;\n }\n\n case OpCode.OP_STR_LOWER:\n case OpCode.OP_STR_UPPER:\n case OpCode.OP_STR_LENGTH:\n case OpCode.OP_STR_TRIM:\n case OpCode.OP_MATH_ABS:\n case OpCode.OP_MATH_ROUND:\n case OpCode.OP_MATH_FLOOR:\n case OpCode.OP_MATH_CEIL: {\n const opNames: Record<number, string> = {\n [OpCode.OP_STR_LOWER]: \"OP_STR_LOWER\",\n [OpCode.OP_STR_UPPER]: \"OP_STR_UPPER\",\n [OpCode.OP_STR_LENGTH]: \"OP_STR_LENGTH\",\n [OpCode.OP_STR_TRIM]: \"OP_STR_TRIM\",\n [OpCode.OP_MATH_ABS]: \"OP_MATH_ABS\",\n [OpCode.OP_MATH_ROUND]: \"OP_MATH_ROUND\",\n [OpCode.OP_MATH_FLOOR]: \"OP_MATH_FLOOR\",\n [OpCode.OP_MATH_CEIL]: \"OP_MATH_CEIL\",\n };\n const srcReg = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: opNames[op],\n p1: `r[${srcReg}]`,\n p2: `r[${destReg}]`,\n p3: \"\",\n comment: `${opNames[op]}: r[${destReg}] = ${opNames[op].toLowerCase()}(r[${srcReg}])`,\n });\n break;\n }\n\n case OpCode.OP_STR_SUBSTR: {\n const srcReg = bytecode[pc++];\n const startReg = bytecode[pc++];\n const lenReg = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_STR_SUBSTR\",\n p1: `r[${srcReg}]`,\n p2: `start=r[${startReg}], len=r[${lenReg}]`,\n p3: `r[${destReg}]`,\n comment: `Extract substring from r[${srcReg}] into r[${destReg}]`,\n });\n break;\n }\n\n case OpCode.OP_ADD:\n case OpCode.OP_SUB:\n case OpCode.OP_MUL:\n case OpCode.OP_DIV:\n case OpCode.OP_MOD: {\n const opNames: Record<number, string> = {\n [OpCode.OP_ADD]: \"OP_ADD\",\n [OpCode.OP_SUB]: \"OP_SUB\",\n [OpCode.OP_MUL]: \"OP_MUL\",\n [OpCode.OP_DIV]: \"OP_DIV\",\n [OpCode.OP_MOD]: \"OP_MOD\",\n };\n const regA = bytecode[pc++];\n const regB = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: opNames[op],\n p1: `r[${regA}]`,\n p2: `r[${regB}]`,\n p3: `r[${destReg}]`,\n comment: `${opNames[op]}: r[${destReg}] = r[${regA}] ${opNames[op].replace(\"OP_\", \"\")} r[${regB}]`,\n });\n break;\n }\n\n case OpCode.OP_STR_CONCAT:\n case OpCode.OP_COALESCE: {\n const opNames: Record<number, string> = {\n [OpCode.OP_STR_CONCAT]: \"OP_STR_CONCAT\",\n [OpCode.OP_COALESCE]: \"OP_COALESCE\",\n };\n const startReg = bytecode[pc++];\n const numRegs = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: opNames[op],\n p1: `r[${startReg}..${startReg + numRegs - 1}]`,\n p2: `count=${numRegs}`,\n p3: `r[${destReg}]`,\n comment: `${opNames[op]}: r[${destReg}]`,\n });\n break;\n }\n\n case OpCode.OP_COPY: {\n const srcReg = bytecode[pc++];\n const destReg = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_COPY\",\n p1: `r[${srcReg}]`,\n p2: `r[${destReg}]`,\n p3: \"\",\n comment: `Copy r[${srcReg}] to r[${destReg}]`,\n });\n break;\n }\n\n case OpCode.OP_SORTER_OPEN: {\n const sorterId = bytecode[pc++];\n const keyInfoIdx = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_SORTER_OPEN\",\n p1: `s[${sorterId}]`,\n p2: `keyInfo=${keyInfoIdx}`,\n p3: \"\",\n comment: `Open sorter ${sorterId} with keyInfo ${keyInfoIdx}`,\n });\n break;\n }\n\n case OpCode.OP_SORTER_INSERT: {\n const sorterId = bytecode[pc++];\n const startReg = bytecode[pc++];\n const numKeys = bytecode[pc++];\n const cursor = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_SORTER_INSERT\",\n p1: `s[${sorterId}]`,\n p2: `r[${startReg}..+${numKeys}]`,\n p3: `c[${cursor}]`,\n comment: `Insert row from cursor ${cursor} into sorter ${sorterId}`,\n });\n break;\n }\n\n case OpCode.OP_SORTER_SORT: {\n const sorterId = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_SORTER_SORT\",\n p1: `s[${sorterId}]`,\n p2: \"\",\n p3: \"\",\n comment: `Sort entries in sorter ${sorterId}`,\n });\n break;\n }\n\n case OpCode.OP_SORTER_NEXT: {\n const sorterId = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_SORTER_NEXT\",\n p1: `s[${sorterId}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Emit next sorted row from sorter ${sorterId}; jump to ${fmtAddr(jumpTarget)} while more rows`,\n });\n break;\n }\n\n case OpCode.OP_AGG_INIT: {\n const aggId = bytecode[pc++];\n const startKeyReg = bytecode[pc++];\n const numKeys = bytecode[pc++];\n const mode = bytecode[pc++];\n instructions.push({\n addr,\n opcode: \"OP_AGG_INIT\",\n p1: `agg[${aggId}]`,\n p2: `keys=r[${startKeyReg}..+${numKeys}]`,\n p3: `mode=${mode === 0 ? \"hash\" : \"stream\"}`,\n comment: `Initialize aggregator ${aggId} (${mode === 0 ? \"hash table\" : \"stream\"})`,\n });\n break;\n }\n\n case OpCode.OP_AGG_STEP: {\n const aggId = bytecode[pc++];\n const startKeyReg = bytecode[pc++];\n const numKeys = bytecode[pc++];\n const valReg = bytecode[pc++];\n const funcId = bytecode[pc++];\n const funcNames = [\"COUNT\", \"SUM\", \"AVG\", \"MIN\", \"MAX\"];\n instructions.push({\n addr,\n opcode: \"OP_AGG_STEP\",\n p1: `agg[${aggId}]`,\n p2: `val=${valReg === 255 ? \"*\" : `r[${valReg}]`}`,\n p3: funcNames[funcId] ?? `${funcId}`,\n comment: `Update accumulator ${funcNames[funcId] ?? funcId} for group r[${startKeyReg}..+${numKeys}]`,\n });\n break;\n }\n\n case OpCode.OP_AGG_NEXT: {\n const aggId = bytecode[pc++];\n const outKeyReg = bytecode[pc++];\n const outAccReg = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_AGG_NEXT\",\n p1: `agg[${aggId}]`,\n p2: `out_keys=r[${outKeyReg}], out_acc=r[${outAccReg}]`,\n p3: fmtAddr(jumpTarget),\n comment: `Iterate next group bucket; jump to ${fmtAddr(jumpTarget)}`,\n });\n break;\n }\n\n case OpCode.OP_AGG_FINAL: {\n const sumReg = bytecode[pc++];\n const countReg = bytecode[pc++];\n const outReg = bytecode[pc++];\n const funcId = bytecode[pc++];\n const funcNames = [\"COUNT\", \"SUM\", \"AVG\", \"MIN\", \"MAX\"];\n instructions.push({\n addr,\n opcode: \"OP_AGG_FINAL\",\n p1: `sum=r[${sumReg}], cnt=r[${countReg}]`,\n p2: `r[${outReg}]`,\n p3: funcNames[funcId] ?? `${funcId}`,\n comment: `Finalize ${funcNames[funcId] ?? funcId} into r[${outReg}]`,\n });\n break;\n }\n\n case OpCode.OP_REG_IS_NULL: {\n const reg = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_REG_IS_NULL\",\n p1: `r[${reg}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Jump to ${fmtAddr(jumpTarget)} if r[${reg}] is NULL`,\n });\n break;\n }\n\n case OpCode.OP_REG_IS_NOT_NULL: {\n const reg = bytecode[pc++];\n const jumpTarget = view.getUint16(pc, true);\n pc += 2;\n instructions.push({\n addr,\n opcode: \"OP_REG_IS_NOT_NULL\",\n p1: `r[${reg}]`,\n p2: fmtAddr(jumpTarget),\n p3: \"\",\n comment: `Jump to ${fmtAddr(jumpTarget)} if r[${reg}] is NOT NULL`,\n });\n break;\n }\n\n default:\n instructions.push({\n addr,\n opcode: `OP_UNKNOWN(0x${op.toString(16)})`,\n p1: \"\",\n p2: \"\",\n p3: \"\",\n comment: \"Unknown opcode\",\n });\n break;\n }\n }\n\n return instructions;\n}\n\n/**\n * Formats a list of disassembled instructions into an ASCII table string.\n */\nexport function formatDisassembly(\n instructions: DisassembledInstruction[],\n): string {\n const pad = (s: string, n: number) => s.padEnd(n, \" \");\n const fmtAddr = (n: number) => `0x${n.toString(16).padStart(4, \"0\")}`;\n\n let out = `${pad(\"ADDR\", 8)} ${pad(\"OPCODE\", 18)} ${pad(\"P1\", 12)} ${pad(\"P2\", 20)} ${pad(\"P3\", 10)} COMMENT\\n`;\n out += \"-\".repeat(95) + \"\\n\";\n\n for (const ins of instructions) {\n out += `${pad(fmtAddr(ins.addr), 8)} ${pad(ins.opcode, 18)} ${pad(ins.p1, 12)} ${pad(ins.p2, 20)} ${pad(ins.p3, 10)} ${ins.comment}\\n`;\n }\n\n return out;\n}\n","import {\n DbRow,\n AggregateNotAllowedInWhereError,\n JoinType,\n TransactionOptions,\n} from '../../types/index.js';\nimport { MAX_IN_LIST_SIZE } from '../../constants.js';\nimport {\n ComparisonOp,\n QueryFilter,\n SortKey,\n GroupKey,\n AggExpr,\n AggFunc,\n DisassembledInstruction,\n} from '../compiler/compiler.js';\nimport {\n QueryPlanner,\n} from '../compiler/planner/index.js';\nimport {\n ExprNode,\n ParsedSelectExpr,\n parseSelectExpr,\n parseExpression,\n evalExprNode,\n validateClause,\n isAggregateFunction,\n ExpressionBuilder,\n deriveDefaultAlias,\n} from '../compiler/expr_parser.js';\n\nexport type SelectFunction =\n | 'count'\n | 'sum'\n | 'avg'\n | 'min'\n | 'max'\n | 'upper'\n | 'lower'\n | 'length'\n | 'substr'\n | 'trim'\n | 'round'\n | 'floor'\n | 'ceil'\n | 'abs';\n\nexport interface SelectColumnSpec {\n col: string;\n as: string;\n}\n\nexport interface NormalizedSelectField {\n sourceCol?: string;\n alias: string;\n fn?: SelectFunction | string;\n args?: any[];\n expr?: ExprNode;\n}\n\nexport type SelectItem =\n | string\n | SelectColumnSpec\n | Record<string, string>\n | ExpressionBuilder\n | ParsedSelectExpr;\n\nexport function parseFilterTarget(\n target: string | ExprNode | ExpressionBuilder,\n): { colName?: string; expr?: ExprNode } {\n if (\n target instanceof ExpressionBuilder ||\n (typeof target === 'object' && target !== null && 'node' in target)\n ) {\n return { expr: (target as any).node };\n }\n if (typeof target === 'object' && target !== null && 'type' in target) {\n return { expr: target as ExprNode };\n }\n if (typeof target === 'string') {\n const trimmed = target.trim();\n if (\n trimmed.includes('(') ||\n trimmed.includes('+') ||\n trimmed.includes('-') ||\n trimmed.includes('*') ||\n trimmed.includes('/') ||\n trimmed.includes('%')\n ) {\n return { expr: parseExpression(trimmed), colName: trimmed };\n }\n return { colName: trimmed };\n }\n return {};\n}\n\nexport type GroupByItem = string | ExprNode | ExpressionBuilder;\n\nexport function extractAggregatesFromExpr(expr: ExprNode): AggExpr[] {\n const aggs: AggExpr[] = [];\n function walk(node: ExprNode) {\n if (node.type === 'fn') {\n const fnName = node.name.toLowerCase();\n if (isAggregateFunction(fnName)) {\n const arg0 = node.args[0];\n const colName =\n arg0 && arg0.type === 'col' && arg0.name !== '*'\n ? arg0.name\n : undefined;\n aggs.push({\n func: fnName as AggFunc,\n colName,\n });\n }\n for (const arg of node.args) {\n walk(arg);\n }\n } else if (node.type === 'binary') {\n walk(node.left);\n walk(node.right);\n }\n }\n walk(expr);\n return aggs;\n}\n\nexport function normalizeSelectItem(item: any): NormalizedSelectField[] {\n if (!item) return [];\n\n if (Array.isArray(item)) {\n const fields: NormalizedSelectField[] = [];\n for (const sub of item) {\n fields.push(...normalizeSelectItem(sub));\n }\n return fields;\n }\n\n if (\n item instanceof ExpressionBuilder ||\n (typeof item === 'object' && item !== null && 'node' in item)\n ) {\n const expr: ExprNode = item.node;\n const alias = deriveDefaultAlias(expr);\n return [\n {\n alias,\n expr,\n sourceCol:\n expr.type === 'col' && expr.name !== '*' ? expr.name : undefined,\n fn: expr.type === 'fn' ? expr.name : undefined,\n },\n ];\n }\n\n if (typeof item === 'string') {\n const trimmed = item.trim();\n if (!trimmed) return [];\n\n const parsed = parseSelectExpr(trimmed);\n return [\n {\n alias: parsed.alias,\n expr: parsed.expr,\n sourceCol:\n parsed.expr.type === 'col' && parsed.expr.name !== '*'\n ? parsed.expr.name\n : undefined,\n fn: parsed.expr.type === 'fn' ? parsed.expr.name : undefined,\n },\n ];\n }\n\n if (typeof item === 'object' && item !== null) {\n if ('expr' in item && 'alias' in item) {\n const expr: ExprNode = item.expr;\n return [\n {\n alias: item.alias,\n expr,\n sourceCol:\n expr.type === 'col' && expr.name !== '*' ? expr.name : undefined,\n fn: expr.type === 'fn' ? expr.name : undefined,\n },\n ];\n }\n\n // SelectColumnSpec: { col: string; as: string }\n if (\n 'col' in item &&\n 'as' in item &&\n typeof item.col === 'string' &&\n typeof item.as === 'string'\n ) {\n const parsed = parseSelectExpr(`${item.col} as ${item.as}`);\n return [\n {\n sourceCol: item.col === '*' ? undefined : item.col,\n alias: item.as,\n expr: parsed.expr,\n fn: parsed.expr.type === 'fn' ? parsed.expr.name : undefined,\n },\n ];\n }\n\n // Key-value dictionary: strictly {[col]: alias}\n const fields: NormalizedSelectField[] = [];\n for (const [col, val] of Object.entries(item)) {\n if (typeof val === 'string') {\n const parsed = parseSelectExpr(`${col} as ${val}`);\n fields.push({\n sourceCol: col === '*' ? undefined : col,\n alias: val,\n expr: parsed.expr,\n fn: parsed.expr.type === 'fn' ? parsed.expr.name : undefined,\n });\n }\n }\n return fields;\n }\n\n return [];\n}\n\nexport interface ExplainOutput {\n plan: {\n table: string;\n rootPageId: number;\n scanType: 'TableScan' | 'IndexScan';\n indexName?: string;\n filters: QueryFilter[];\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n select?: NormalizedSelectField[];\n joins?: JoinClause[];\n limit?: number;\n offset?: number;\n estimatedCost?: number;\n estimatedRows?: number;\n joinOrder?: string[];\n isOrderSatisfied?: boolean;\n sortCostAvoided?: number;\n };\n bytecodeSize: number;\n instructions: DisassembledInstruction[];\n assembly: string;\n}\n\nexport interface JoinClause {\n type: JoinType;\n table: string;\n leftCol: string;\n op: ComparisonOp;\n rightCol: string;\n scanType?: 'TableScan' | 'IndexScan';\n indexName?: string;\n}\n\nexport interface QueryExecutionOptions {\n limit: number | null;\n offset: number | null;\n sortCol: string | null;\n sortDir: 'asc' | 'desc';\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n select?: NormalizedSelectField[];\n selectExprs?: ParsedSelectExpr[];\n joins?: JoinClause[];\n planner?: QueryPlanner;\n}\n\nexport interface IDatabaseQueryExecutor {\n explainQuery(\n tableName: string,\n filters: QueryFilter[],\n options?: {\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n select?: NormalizedSelectField[];\n selectExprs?: ParsedSelectExpr[];\n joins?: JoinClause[];\n limit?: number;\n offset?: number;\n planner?: QueryPlanner;\n },\n ): Promise<ExplainOutput>;\n executeQuery(\n tableName: string,\n filters: QueryFilter[],\n options: QueryExecutionOptions,\n ): Promise<DbRow[]>;\n executeUpdate?(\n tableName: string,\n filters: QueryFilter[],\n patch: Partial<DbRow>,\n options?: TransactionOptions,\n ): Promise<number>;\n executeDelete?(\n tableName: string,\n filters: QueryFilter[],\n options?: TransactionOptions,\n ): Promise<number>;\n}\n\nfunction assertNotAggregateInWhere(colOrExpr: any): void {\n if (typeof colOrExpr === 'string') {\n const trimmed = colOrExpr.trim();\n if (isAggregateFunction(trimmed)) {\n throw new AggregateNotAllowedInWhereError(trimmed);\n }\n if (trimmed.includes('(')) {\n try {\n const expr = parseExpression(trimmed);\n validateClause(expr, 'where');\n } catch (e) {\n if (e instanceof AggregateNotAllowedInWhereError) {\n throw e;\n }\n }\n }\n } else if (\n colOrExpr instanceof ExpressionBuilder ||\n (typeof colOrExpr === 'object' && colOrExpr !== null && 'node' in colOrExpr)\n ) {\n validateClause(colOrExpr.node, 'where');\n } else if (\n typeof colOrExpr === 'object' &&\n colOrExpr !== null &&\n 'type' in colOrExpr\n ) {\n validateClause(colOrExpr as ExprNode, 'where');\n }\n}\n\nexport class QueryBuilder {\n private db: IDatabaseQueryExecutor;\n private tableName: string;\n private filters: QueryFilter[] = [];\n private selectFields: NormalizedSelectField[] = [];\n private limitCount: number | null = null;\n private offsetCount: number | null = null;\n private sortCol: string | null = null;\n private sortDir: 'asc' | 'desc' = 'asc';\n private orderKeys: SortKey[] = [];\n private groupCols: string[] = [];\n private groupKeys: GroupKey[] = [];\n private aggExprs: AggExpr[] = [];\n private havingFilters: QueryFilter[] = [];\n private joins: JoinClause[] = [];\n private planner?: QueryPlanner;\n\n withPlanner(planner: QueryPlanner): this {\n this.planner = planner;\n return this;\n }\n\n constructor(db: IDatabaseQueryExecutor, tableName: string) {\n this.db = db;\n this.tableName = tableName;\n }\n\n join(\n table: string,\n leftCol: string,\n rightCol: string,\n ): this;\n join(\n table: string,\n leftCol: string,\n op: ComparisonOp,\n rightCol: string,\n ): this;\n join(\n table: string,\n leftCol: string,\n opOrRightCol: string,\n rightCol?: string,\n ): this {\n const op = (rightCol !== undefined ? opOrRightCol : '=') as ComparisonOp;\n const rCol = rightCol !== undefined ? rightCol : opOrRightCol;\n this.joins.push({\n type: 'inner',\n table,\n leftCol,\n op,\n rightCol: rCol,\n });\n return this;\n }\n\n innerJoin(\n table: string,\n leftCol: string,\n rightCol: string,\n ): this;\n innerJoin(\n table: string,\n leftCol: string,\n op: ComparisonOp,\n rightCol: string,\n ): this;\n innerJoin(\n table: string,\n leftCol: string,\n opOrRightCol: string,\n rightCol?: string,\n ): this {\n return this.join(table, leftCol, opOrRightCol as any, rightCol as any);\n }\n\n leftJoin(\n table: string,\n leftCol: string,\n rightCol: string,\n ): this;\n leftJoin(\n table: string,\n leftCol: string,\n op: ComparisonOp,\n rightCol: string,\n ): this;\n leftJoin(\n table: string,\n leftCol: string,\n opOrRightCol: string,\n rightCol?: string,\n ): this {\n const op = (rightCol !== undefined ? opOrRightCol : '=') as ComparisonOp;\n const rCol = rightCol !== undefined ? rightCol : opOrRightCol;\n this.joins.push({\n type: 'left',\n table,\n leftCol,\n op,\n rightCol: rCol,\n });\n return this;\n }\n\n getJoins(): JoinClause[] {\n return this.joins;\n }\n\n where(exprSql: string): this;\n where(expr: ExprNode | ExpressionBuilder): this;\n where(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n where(callback: (qb: QueryBuilder) => void): this;\n where(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootFilter();\n if (subFilter) {\n this.filters.push(subFilter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n assertNotAggregateInWhere(colOrCbOrExpr);\n const expr = parseExpression(colOrCbOrExpr);\n this.filters.push({ type: 'expr', expr });\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.filters.push({\n type: 'expr',\n expr: (colOrCbOrExpr as any).node,\n });\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.filters.push({ type: 'expr', expr: colOrCbOrExpr as ExprNode });\n }\n } else {\n assertNotAggregateInWhere(colOrCbOrExpr);\n assertNotAggregateInWhere(value);\n if (typeof op === 'string' && op.trim().toLowerCase() === 'in') {\n return this.whereIn(colOrCbOrExpr as string, value);\n }\n if (typeof op === 'string' && op.trim().toLowerCase() === 'not in') {\n return this.whereNotIn(colOrCbOrExpr as string, value);\n }\n const target = parseFilterTarget(colOrCbOrExpr);\n this.filters.push({\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n });\n }\n return this;\n }\n\n orWhere(exprSql: string): this;\n orWhere(expr: ExprNode | ExpressionBuilder): this;\n orWhere(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n orWhere(callback: (qb: QueryBuilder) => void): this;\n orWhere(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootFilter();\n if (subFilter) {\n this.addOrFilter(subFilter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n assertNotAggregateInWhere(colOrCbOrExpr);\n const expr = parseExpression(colOrCbOrExpr);\n this.addOrFilter({ type: 'expr', expr });\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.addOrFilter({\n type: 'expr',\n expr: (colOrCbOrExpr as any).node,\n });\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.addOrFilter({ type: 'expr', expr: colOrCbOrExpr as ExprNode });\n }\n } else {\n assertNotAggregateInWhere(colOrCbOrExpr);\n assertNotAggregateInWhere(value);\n if (typeof op === 'string' && op.trim().toLowerCase() === 'in') {\n return this.orWhereIn(colOrCbOrExpr as string, value);\n }\n if (typeof op === 'string' && op.trim().toLowerCase() === 'not in') {\n return this.orWhereNotIn(colOrCbOrExpr as string, value);\n }\n const target = parseFilterTarget(colOrCbOrExpr);\n this.addOrFilter({\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n });\n }\n return this;\n }\n\n whereNot(exprSql: string): this;\n whereNot(expr: ExprNode | ExpressionBuilder): this;\n whereNot(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n whereNot(callback: (qb: QueryBuilder) => void): this;\n whereNot(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootFilter();\n if (subFilter) {\n this.filters.push({ type: 'not', child: subFilter });\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n assertNotAggregateInWhere(colOrCbOrExpr);\n const expr = parseExpression(colOrCbOrExpr);\n this.filters.push({ type: 'not', child: { type: 'expr', expr } });\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.filters.push({\n type: 'not',\n child: { type: 'expr', expr: (colOrCbOrExpr as any).node },\n });\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.filters.push({\n type: 'not',\n child: { type: 'expr', expr: colOrCbOrExpr as ExprNode },\n });\n }\n } else {\n assertNotAggregateInWhere(colOrCbOrExpr);\n assertNotAggregateInWhere(value);\n const target = parseFilterTarget(colOrCbOrExpr);\n this.filters.push({\n type: 'not',\n child: {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n },\n });\n }\n return this;\n }\n\n orWhereNot(exprSql: string): this;\n orWhereNot(expr: ExprNode | ExpressionBuilder): this;\n orWhereNot(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n orWhereNot(callback: (qb: QueryBuilder) => void): this;\n orWhereNot(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootFilter();\n if (subFilter) {\n this.addOrFilter({ type: 'not', child: subFilter });\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n assertNotAggregateInWhere(colOrCbOrExpr);\n const expr = parseExpression(colOrCbOrExpr);\n this.addOrFilter({ type: 'not', child: { type: 'expr', expr } });\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.addOrFilter({\n type: 'not',\n child: { type: 'expr', expr: (colOrCbOrExpr as any).node },\n });\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n assertNotAggregateInWhere(colOrCbOrExpr);\n this.addOrFilter({\n type: 'not',\n child: { type: 'expr', expr: colOrCbOrExpr as ExprNode },\n });\n }\n } else {\n assertNotAggregateInWhere(colOrCbOrExpr);\n assertNotAggregateInWhere(value);\n const target = parseFilterTarget(colOrCbOrExpr);\n this.addOrFilter({\n type: 'not',\n child: {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n },\n });\n }\n return this;\n }\n\n whereRaw(sqlStr: string): this {\n return this.where(sqlStr);\n }\n\n orWhereRaw(sqlStr: string): this {\n return this.orWhere(sqlStr);\n }\n\n whereNull(colName: string): this {\n assertNotAggregateInWhere(colName);\n this.filters.push({ type: 'null', colName, isNull: true });\n return this;\n }\n\n whereNotNull(colName: string): this {\n assertNotAggregateInWhere(colName);\n this.filters.push({ type: 'null', colName, isNull: false });\n return this;\n }\n\n orWhereNull(colName: string): this {\n assertNotAggregateInWhere(colName);\n this.addOrFilter({ type: 'null', colName, isNull: true });\n return this;\n }\n\n orWhereNotNull(colName: string): this {\n assertNotAggregateInWhere(colName);\n this.addOrFilter({ type: 'null', colName, isNull: false });\n return this;\n }\n\n whereLike(colName: string, pattern: string): this {\n return this.where(colName, 'like', pattern);\n }\n\n whereNotLike(colName: string, pattern: string): this {\n return this.where(colName, 'not like', pattern);\n }\n\n whereStartsWith(colName: string, prefix: string): this {\n return this.where(colName, 'starts_with', prefix);\n }\n\n whereEndsWith(colName: string, suffix: string): this {\n return this.where(colName, 'ends_with', suffix);\n }\n\n whereContains(colName: string, substring: string): this {\n return this.where(colName, 'contains', substring);\n }\n\n orWhereLike(colName: string, pattern: string): this {\n return this.orWhere(colName, 'like', pattern);\n }\n\n orWhereNotLike(colName: string, pattern: string): this {\n return this.orWhere(colName, 'not like', pattern);\n }\n\n orWhereStartsWith(colName: string, prefix: string): this {\n return this.orWhere(colName, 'starts_with', prefix);\n }\n\n orWhereEndsWith(colName: string, suffix: string): this {\n return this.orWhere(colName, 'ends_with', suffix);\n }\n\n orWhereContains(colName: string, substring: string): this {\n return this.orWhere(colName, 'contains', substring);\n }\n\n whereIn(colName: string, values: any[]): this {\n assertNotAggregateInWhere(colName);\n if (!Array.isArray(values)) {\n throw new TypeError(`WebDB: whereIn requires an array of values`);\n }\n if (values.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: whereIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n const target = parseFilterTarget(colName);\n this.filters.push({\n type: 'in',\n colName: target.colName,\n expr: target.expr,\n values,\n notIn: false,\n });\n return this;\n }\n\n whereNotIn(colName: string, values: any[]): this {\n assertNotAggregateInWhere(colName);\n if (!Array.isArray(values)) {\n throw new TypeError(`WebDB: whereNotIn requires an array of values`);\n }\n if (values.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: whereNotIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n const target = parseFilterTarget(colName);\n this.filters.push({\n type: 'in',\n colName: target.colName,\n expr: target.expr,\n values,\n notIn: true,\n });\n return this;\n }\n\n orWhereIn(colName: string, values: any[]): this {\n assertNotAggregateInWhere(colName);\n if (!Array.isArray(values)) {\n throw new TypeError(`WebDB: orWhereIn requires an array of values`);\n }\n if (values.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: orWhereIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n const target = parseFilterTarget(colName);\n this.addOrFilter({\n type: 'in',\n colName: target.colName,\n expr: target.expr,\n values,\n notIn: false,\n });\n return this;\n }\n\n orWhereNotIn(colName: string, values: any[]): this {\n assertNotAggregateInWhere(colName);\n if (!Array.isArray(values)) {\n throw new TypeError(`WebDB: orWhereNotIn requires an array of values`);\n }\n if (values.length > MAX_IN_LIST_SIZE) {\n throw new RangeError(\n `WebDB: orWhereNotIn list exceeds maximum limit of ${MAX_IN_LIST_SIZE} elements`,\n );\n }\n const target = parseFilterTarget(colName);\n this.addOrFilter({\n type: 'in',\n colName: target.colName,\n expr: target.expr,\n values,\n notIn: true,\n });\n return this;\n }\n\n getFilters(): QueryFilter[] {\n return this.filters;\n }\n\n getRootFilter(): QueryFilter | null {\n if (this.filters.length === 0) return null;\n if (this.filters.length === 1) return this.filters[0];\n return { type: 'and', children: [...this.filters] };\n }\n\n private addOrFilter(filter: QueryFilter): void {\n if (this.filters.length === 0) {\n this.filters.push(filter);\n return;\n }\n if (\n this.filters.length === 1 &&\n this.filters[0].type === 'or' &&\n this.filters[0].children\n ) {\n this.filters[0].children.push(filter);\n return;\n }\n let prev: QueryFilter;\n if (this.filters.length === 1) {\n prev = this.filters[0];\n } else {\n prev = { type: 'and', children: [...this.filters] };\n }\n this.filters = [{ type: 'or', children: [prev, filter] }];\n }\n\n limit(count: number): this {\n this.limitCount = count;\n return this;\n }\n\n offset(count: number): this {\n this.offsetCount = count;\n return this;\n }\n\n orderBy(\n colOrKeys: string | SortKey | SortKey[] | ExpressionBuilder | ExprNode,\n direction: 'asc' | 'desc' = 'asc',\n nullOrder?: 'nulls_first' | 'nulls_last',\n ): this {\n if (typeof colOrKeys === 'string') {\n this.sortCol = colOrKeys;\n this.sortDir = direction;\n const target = parseFilterTarget(colOrKeys);\n this.orderKeys.push({\n colName: target.colName ?? colOrKeys,\n expr: target.expr,\n direction,\n nullOrder,\n });\n } else if (\n colOrKeys instanceof ExpressionBuilder ||\n (typeof colOrKeys === 'object' && colOrKeys !== null && 'node' in colOrKeys)\n ) {\n this.orderKeys.push({\n expr: (colOrKeys as any).node,\n direction,\n nullOrder,\n });\n } else if (\n typeof colOrKeys === 'object' &&\n colOrKeys !== null &&\n 'type' in colOrKeys\n ) {\n this.orderKeys.push({\n expr: colOrKeys as ExprNode,\n direction,\n nullOrder,\n });\n } else if (Array.isArray(colOrKeys)) {\n for (const item of colOrKeys) {\n if (typeof item === 'string') {\n const target = parseFilterTarget(item);\n this.orderKeys.push({\n colName: target.colName ?? item,\n expr: target.expr,\n direction: 'asc',\n });\n } else {\n this.orderKeys.push(item);\n }\n }\n } else {\n this.orderKeys.push(colOrKeys);\n }\n return this;\n }\n\n groupBy(...columns: (GroupByItem | GroupByItem[])[]): this {\n for (const item of columns) {\n if (Array.isArray(item)) {\n for (const sub of item) {\n this.addGroupByItem(sub);\n }\n } else {\n this.addGroupByItem(item);\n }\n }\n return this;\n }\n\n private addGroupByItem(item: GroupByItem): void {\n if (\n item instanceof ExpressionBuilder ||\n (typeof item === 'object' && item !== null && 'node' in item)\n ) {\n this.groupKeys.push({ expr: (item as any).node });\n this.groupCols.push(deriveDefaultAlias((item as any).node));\n } else if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item\n ) {\n this.groupKeys.push({ expr: item as ExprNode });\n this.groupCols.push(deriveDefaultAlias(item as ExprNode));\n } else if (typeof item === 'string') {\n const target = parseFilterTarget(item);\n this.groupKeys.push({\n colName: target.colName ?? item,\n expr: target.expr,\n });\n this.groupCols.push(item);\n }\n }\n\n private registerAggregatesFromFilter(filter: QueryFilter): void {\n const checkTarget = (colName?: string, expr?: ExprNode) => {\n if (expr) {\n const aggs = extractAggregatesFromExpr(expr);\n for (const agg of aggs) {\n const already = this.aggExprs.some(\n (a) =>\n a.func === agg.func &&\n (a.colName === agg.colName ||\n (a.colName === undefined && agg.colName === undefined)),\n );\n if (!already) {\n this.aggExprs.push(agg);\n }\n }\n } else if (colName && colName.includes('(')) {\n try {\n const parsed = parseExpression(colName);\n const aggs = extractAggregatesFromExpr(parsed);\n for (const agg of aggs) {\n const already = this.aggExprs.some(\n (a) =>\n a.func === agg.func &&\n (a.colName === agg.colName ||\n (a.colName === undefined && agg.colName === undefined)),\n );\n if (!already) {\n this.aggExprs.push(agg);\n }\n }\n } catch {\n // ignore unparseable\n }\n }\n };\n\n if (filter.type === 'cmp') {\n checkTarget(filter.colName, filter.expr);\n } else if (filter.type === 'expr' && filter.expr) {\n checkTarget(undefined, filter.expr);\n } else if (filter.type === 'null') {\n checkTarget(filter.colName, filter.expr);\n } else if (filter.type === 'not' && filter.child) {\n this.registerAggregatesFromFilter(filter.child);\n } else if (\n (filter.type === 'and' || filter.type === 'or') &&\n filter.children\n ) {\n for (const child of filter.children) {\n this.registerAggregatesFromFilter(child);\n }\n }\n }\n\n having(exprSql: string): this;\n having(expr: ExprNode | ExpressionBuilder): this;\n having(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n having(callback: (qb: QueryBuilder) => void): this;\n having(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootHavingFilter();\n if (subFilter) {\n this.havingFilters.push(subFilter);\n this.registerAggregatesFromFilter(subFilter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n const expr = parseExpression(colOrCbOrExpr);\n const filter: QueryFilter = { type: 'expr', expr };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n const filter: QueryFilter = {\n type: 'expr',\n expr: (colOrCbOrExpr as any).node,\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n const filter: QueryFilter = {\n type: 'expr',\n expr: colOrCbOrExpr as ExprNode,\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else {\n const target = parseFilterTarget(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n }\n return this;\n }\n\n orHaving(exprSql: string): this;\n orHaving(expr: ExprNode | ExpressionBuilder): this;\n orHaving(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n orHaving(callback: (qb: QueryBuilder) => void): this;\n orHaving(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootHavingFilter();\n if (subFilter) {\n this.addHavingOrFilter(subFilter);\n this.registerAggregatesFromFilter(subFilter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n const expr = parseExpression(colOrCbOrExpr);\n const filter: QueryFilter = { type: 'expr', expr };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n const filter: QueryFilter = {\n type: 'expr',\n expr: (colOrCbOrExpr as any).node,\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n const filter: QueryFilter = {\n type: 'expr',\n expr: colOrCbOrExpr as ExprNode,\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else {\n const target = parseFilterTarget(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n }\n return this;\n }\n\n havingNot(exprSql: string): this;\n havingNot(expr: ExprNode | ExpressionBuilder): this;\n havingNot(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n havingNot(callback: (qb: QueryBuilder) => void): this;\n havingNot(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootHavingFilter();\n if (subFilter) {\n const filter: QueryFilter = { type: 'not', child: subFilter };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n const expr = parseExpression(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr },\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr: (colOrCbOrExpr as any).node },\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr: colOrCbOrExpr as ExprNode },\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else {\n const target = parseFilterTarget(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'not',\n child: {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n },\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n }\n return this;\n }\n\n orHavingNot(exprSql: string): this;\n orHavingNot(expr: ExprNode | ExpressionBuilder): this;\n orHavingNot(\n colOrExpr: string | ExprNode | ExpressionBuilder,\n op: ComparisonOp,\n value: any,\n ): this;\n orHavingNot(callback: (qb: QueryBuilder) => void): this;\n orHavingNot(\n colOrCbOrExpr:\n | string\n | ((qb: QueryBuilder) => void)\n | ExprNode\n | ExpressionBuilder,\n op?: ComparisonOp,\n value?: any,\n ): this {\n if (typeof colOrCbOrExpr === 'function') {\n const sub = new QueryBuilder(this.db, this.tableName);\n colOrCbOrExpr(sub);\n const subFilter = sub.getRootHavingFilter();\n if (subFilter) {\n const filter: QueryFilter = { type: 'not', child: subFilter };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else if (op === undefined && value === undefined) {\n if (typeof colOrCbOrExpr === 'string') {\n const expr = parseExpression(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr },\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n colOrCbOrExpr instanceof ExpressionBuilder ||\n (typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'node' in colOrCbOrExpr)\n ) {\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr: (colOrCbOrExpr as any).node },\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n } else if (\n typeof colOrCbOrExpr === 'object' &&\n colOrCbOrExpr !== null &&\n 'type' in colOrCbOrExpr\n ) {\n const filter: QueryFilter = {\n type: 'not',\n child: { type: 'expr', expr: colOrCbOrExpr as ExprNode },\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n }\n } else {\n const target = parseFilterTarget(colOrCbOrExpr);\n const filter: QueryFilter = {\n type: 'not',\n child: {\n type: 'cmp',\n colName: target.colName,\n expr: target.expr,\n op: op!,\n value,\n },\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n }\n return this;\n }\n\n havingRaw(sqlStr: string): this {\n return this.having(sqlStr);\n }\n\n orHavingRaw(sqlStr: string): this {\n return this.orHaving(sqlStr);\n }\n\n havingNull(colOrExpr: string | ExprNode | ExpressionBuilder): this {\n const target = parseFilterTarget(colOrExpr);\n const filter: QueryFilter = {\n type: 'null',\n colName: target.colName,\n expr: target.expr,\n isNull: true,\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n return this;\n }\n\n havingNotNull(colOrExpr: string | ExprNode | ExpressionBuilder): this {\n const target = parseFilterTarget(colOrExpr);\n const filter: QueryFilter = {\n type: 'null',\n colName: target.colName,\n expr: target.expr,\n isNull: false,\n };\n this.havingFilters.push(filter);\n this.registerAggregatesFromFilter(filter);\n return this;\n }\n\n orHavingNull(colOrExpr: string | ExprNode | ExpressionBuilder): this {\n const target = parseFilterTarget(colOrExpr);\n const filter: QueryFilter = {\n type: 'null',\n colName: target.colName,\n expr: target.expr,\n isNull: true,\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n return this;\n }\n\n orHavingNotNull(colOrExpr: string | ExprNode | ExpressionBuilder): this {\n const target = parseFilterTarget(colOrExpr);\n const filter: QueryFilter = {\n type: 'null',\n colName: target.colName,\n expr: target.expr,\n isNull: false,\n };\n this.addHavingOrFilter(filter);\n this.registerAggregatesFromFilter(filter);\n return this;\n }\n\n getHavingFilters(): QueryFilter[] {\n return this.havingFilters;\n }\n\n getRootHavingFilter(): QueryFilter | null {\n if (this.havingFilters.length === 0) return null;\n if (this.havingFilters.length === 1) return this.havingFilters[0];\n return { type: 'and', children: [...this.havingFilters] };\n }\n\n private addHavingOrFilter(filter: QueryFilter): void {\n if (this.havingFilters.length === 0) {\n this.havingFilters.push(filter);\n return;\n }\n if (\n this.havingFilters.length === 1 &&\n this.havingFilters[0].type === 'or' &&\n this.havingFilters[0].children\n ) {\n this.havingFilters[0].children.push(filter);\n return;\n }\n let prev: QueryFilter;\n if (this.havingFilters.length === 1) {\n prev = this.havingFilters[0];\n } else {\n prev = { type: 'and', children: [...this.havingFilters] };\n }\n this.havingFilters = [{ type: 'or', children: [prev, filter] }];\n }\n\n aggregate(aggregates: AggExpr[]): this {\n this.aggExprs.push(...aggregates);\n return this;\n }\n\n count(colName?: string, alias?: string): this {\n this.aggExprs.push({ func: 'count', colName, alias });\n return this;\n }\n\n sum(colName: string, alias?: string): this {\n this.aggExprs.push({ func: 'sum', colName, alias });\n return this;\n }\n\n avg(colName: string, alias?: string): this {\n this.aggExprs.push({ func: 'avg', colName, alias });\n return this;\n }\n\n min(colName: string, alias?: string): this {\n this.aggExprs.push({ func: 'min', colName, alias });\n return this;\n }\n\n max(colName: string, alias?: string): this {\n this.aggExprs.push({ func: 'max', colName, alias });\n return this;\n }\n\n select(...columns: SelectItem[]): this;\n select(columns: SelectItem[]): this;\n select(columnsMap: Record<string, string>): this;\n select(\n first?: SelectItem | SelectItem[],\n ...rest: SelectItem[]\n ): this {\n if (first === undefined) return this;\n\n const fields: NormalizedSelectField[] = [];\n fields.push(...normalizeSelectItem(first));\n for (const r of rest) {\n fields.push(...normalizeSelectItem(r));\n }\n this.selectFields.push(...fields);\n\n // Auto-register aggregate functions into aggExprs if present\n for (const f of fields) {\n if (f.expr && f.expr.type === 'fn') {\n const fnName = f.expr.name.toLowerCase();\n if (isAggregateFunction(fnName)) {\n const already = this.aggExprs.some((a) => a.alias === f.alias);\n if (!already) {\n const arg0 = f.expr.args[0];\n const colName =\n arg0 && arg0.type === 'col' && arg0.name !== '*'\n ? arg0.name\n : undefined;\n this.aggExprs.push({\n func: fnName as AggFunc,\n colName,\n alias: f.alias,\n });\n }\n }\n } else if (typeof f.fn === 'string') {\n const fnName = f.fn.toLowerCase();\n if (isAggregateFunction(fnName)) {\n const already = this.aggExprs.some((a) => a.alias === f.alias);\n if (!already) {\n this.aggExprs.push({\n func: fnName as AggFunc,\n colName: f.sourceCol === '*' ? undefined : f.sourceCol,\n alias: f.alias,\n });\n }\n }\n }\n }\n\n return this;\n }\n\n getSelectFields(): NormalizedSelectField[] {\n return this.selectFields;\n }\n\n /**\n * Post-processes raw VDBE result rows into projected output records according\n * to select fields, expressions, aliases, and registered UDFs.\n *\n * ARCHITECTURAL LIMITATION NOTE:\n * Everything handled exclusively within `projectRow` operates on client-side\n * result rows after VM execution. Subqueries (e.g. derived tables `db.from(subquery)`\n * or correlated scalar subqueries) compile and execute at the VDBE bytecode level,\n * so client-side transformations performed solely in `projectRow` will not be\n * available inside subqueries until scalar expressions are fully lowered into\n * VDBE register opcodes in the compiler.\n */\n private projectRow(row: DbRow): DbRow {\n // Fast-path: If rawRows was already projected by VDBE OP_RESULT_ROW,\n // the row contains exactly the target aliases.\n const keys = Object.keys(row);\n if (\n this.selectFields.length > 0 &&\n keys.length === this.selectFields.length &&\n this.selectFields.every((f) => f.alias in row)\n ) {\n return row;\n }\n\n const projected: DbRow = {};\n for (const field of this.selectFields) {\n const targetAlias = field.alias;\n if (row[targetAlias] !== undefined) {\n projected[targetAlias] = row[targetAlias];\n } else if (\n field.expr &&\n row[deriveDefaultAlias(field.expr)] !== undefined\n ) {\n projected[targetAlias] = row[deriveDefaultAlias(field.expr)];\n } else if (\n field.sourceCol !== undefined &&\n row[field.sourceCol] !== undefined\n ) {\n projected[targetAlias] = row[field.sourceCol];\n } else if (field.expr) {\n let udfs: any;\n if (typeof (this.db as any).getUdf === 'function') {\n udfs = (name: string) => (this.db as any).getUdf(name)?.def?.call;\n }\n projected[targetAlias] = evalExprNode(field.expr, row, udfs);\n } else {\n projected[targetAlias] = null;\n }\n }\n return projected;\n }\n\n async explain(): Promise<ExplainOutput> {\n const selectExprs: ParsedSelectExpr[] = this.selectFields.map((f) => ({\n expr: f.expr ?? { type: 'col', name: f.sourceCol ?? f.alias },\n alias: f.alias,\n }));\n\n return this.db.explainQuery(this.tableName, this.filters, {\n joins: this.joins.length > 0 ? this.joins : undefined,\n orderBy: this.orderKeys.length > 0 ? this.orderKeys : undefined,\n groupBy:\n this.groupKeys.length > 0\n ? this.groupKeys\n : this.groupCols.length > 0\n ? this.groupCols\n : undefined,\n aggregates: this.aggExprs.length > 0 ? this.aggExprs : undefined,\n having: this.havingFilters.length > 0 ? this.havingFilters : undefined,\n select: this.selectFields.length > 0 ? this.selectFields : undefined,\n selectExprs: selectExprs.length > 0 ? selectExprs : undefined,\n limit: this.limitCount !== null ? this.limitCount : undefined,\n offset: this.offsetCount !== null ? this.offsetCount : undefined,\n planner: this.planner,\n });\n }\n\n private getOrderKeyValue(row: DbRow, k: SortKey): any {\n const rawKey =\n k.colName ?? (k.expr ? deriveDefaultAlias(k.expr) : undefined);\n if (!rawKey) return undefined;\n\n if (row[rawKey] !== undefined) return row[rawKey];\n\n const shortCol = rawKey.includes('.')\n ? rawKey.slice(rawKey.lastIndexOf('.') + 1)\n : rawKey;\n if (row[shortCol] !== undefined) return row[shortCol];\n\n if (this.selectFields.length > 0) {\n for (const f of this.selectFields) {\n if (\n f.sourceCol === rawKey ||\n f.sourceCol === shortCol ||\n f.alias === rawKey ||\n f.alias === shortCol\n ) {\n if (row[f.alias] !== undefined) return row[f.alias];\n }\n }\n }\n\n if (row[`__sort_${rawKey}`] !== undefined) return row[`__sort_${rawKey}`];\n if (row[`__sort_${shortCol}`] !== undefined) return row[`__sort_${shortCol}`];\n\n return undefined;\n }\n\n private sortAggregatedRows(rows: DbRow[]): DbRow[] {\n return [...rows].sort((a, b) => {\n for (const k of this.orderKeys) {\n const valA = this.getOrderKeyValue(a, k);\n const valB = this.getOrderKeyValue(b, k);\n if (valA === valB) continue;\n if (valA === null || valA === undefined) {\n return k.nullOrder === 'nulls_first' ? -1 : 1;\n }\n if (valB === null || valB === undefined) {\n return k.nullOrder === 'nulls_first' ? 1 : -1;\n }\n const dir = k.direction === 'desc' ? -1 : 1;\n if (typeof valA === 'number' && typeof valB === 'number') {\n return (valA - valB) * dir;\n }\n return String(valA).localeCompare(String(valB)) * dir;\n }\n return 0;\n });\n }\n\n async toArray(): Promise<DbRow[]> {\n const selectExprs: ParsedSelectExpr[] = this.selectFields.map((f) => ({\n expr: f.expr ?? { type: 'col', name: f.sourceCol ?? f.alias },\n alias: f.alias,\n }));\n\n const hasJoins = this.joins.length > 0;\n const hasOrderBy = this.orderKeys.length > 0;\n const hasAggsOrGrouping =\n this.aggExprs.length > 0 ||\n this.groupKeys.length > 0 ||\n this.groupCols.length > 0;\n\n if (hasJoins && hasOrderBy && selectExprs.length > 0) {\n for (const k of this.orderKeys) {\n const col = k.colName;\n if (col) {\n const short = col.includes('.')\n ? col.slice(col.lastIndexOf('.') + 1)\n : col;\n const found = this.selectFields.some(\n (f) =>\n f.alias === col ||\n f.alias === short ||\n f.sourceCol === col ||\n f.sourceCol === short,\n );\n if (!found) {\n selectExprs.push({\n expr: { type: 'col', name: col },\n alias: `__sort_${col}`,\n });\n }\n }\n }\n }\n\n const rawRows = await this.db.executeQuery(this.tableName, this.filters, {\n limit:\n hasJoins && hasOrderBy && hasAggsOrGrouping ? null : this.limitCount,\n offset:\n hasJoins && hasOrderBy && hasAggsOrGrouping ? null : this.offsetCount,\n sortCol: hasJoins ? null : this.sortCol,\n sortDir: this.sortDir,\n orderBy:\n hasJoins && hasAggsOrGrouping\n ? undefined\n : hasOrderBy\n ? this.orderKeys\n : undefined,\n joins: hasJoins ? this.joins : undefined,\n groupBy:\n this.groupKeys.length > 0\n ? this.groupKeys\n : this.groupCols.length > 0\n ? this.groupCols\n : undefined,\n aggregates: this.aggExprs.length > 0 ? this.aggExprs : undefined,\n having: this.havingFilters.length > 0 ? this.havingFilters : undefined,\n select: this.selectFields.length > 0 ? this.selectFields : undefined,\n selectExprs: selectExprs.length > 0 ? selectExprs : undefined,\n planner: this.planner,\n });\n\n let rows = rawRows;\n const isOrderSatisfied = (rawRows as any).isOrderSatisfied === true;\n if ((hasAggsOrGrouping || hasJoins) && hasOrderBy && !isOrderSatisfied) {\n rows = this.sortAggregatedRows(rows);\n if (hasJoins) {\n if (this.offsetCount !== null && this.offsetCount > 0) {\n rows = rows.slice(this.offsetCount);\n }\n if (this.limitCount !== null && this.limitCount >= 0) {\n rows = rows.slice(0, this.limitCount);\n }\n }\n }\n\n if (this.selectFields.length > 0) {\n rows = rows.map((r) => this.projectRow(r));\n }\n\n return rows;\n }\n\n async first(): Promise<DbRow | null> {\n const rows = await this.limit(1).toArray();\n return rows.length > 0 ? rows[0] : null;\n }\n\n async update(\n patch: Partial<DbRow>,\n options?: TransactionOptions,\n ): Promise<number> {\n if (!this.db.executeUpdate) {\n throw new Error('Database executor does not support executeUpdate');\n }\n return this.db.executeUpdate(this.tableName, this.filters, patch, options);\n }\n\n async delete(options?: TransactionOptions): Promise<number> {\n if (!this.db.executeDelete) {\n throw new Error('Database executor does not support executeDelete');\n }\n return this.db.executeDelete(this.tableName, this.filters, options);\n }\n}\n","import {\n PAGE_SIZE,\n RESULT_BUFFER_OFFSET,\n DEFAULT_SLOT_COUNT,\n DEFAULT_MAX_QUERY_MEMORY,\n MAX_INDEXES_PAGE1,\n MAX_TABLES_PAGE1,\n MAX_COLUMNS_PER_CATALOG_PAGE,\n MAX_COLUMNS_PER_TABLE,\n MAX_NAME_LENGTH,\n PAGE_TYPE_FREE,\n PAGE_TYPE_INDEX_INTERIOR,\n PAGE_TYPE_TABLE_INTERIOR,\n PAGE_TYPE_INDEX_LEAF,\n PAGE_TYPE_LEAF_DATA,\n} from \"../../constants.ts\";\nimport {\n ColumnDefinition,\n ColumnMeta,\n TableMeta,\n DbRow,\n DbValue,\n TableNotFoundError,\n TableAlreadyExistsError,\n ColumnFlag,\n DataType,\n VmStatus,\n QueryTimeoutError,\n InvalidBytecodeError,\n QueryArenaExhaustedError,\n TooManyCursorsError,\n TooManyColumnsError,\n TooManyTablesError,\n UniqueConstraintViolationError,\n NotNullConstraintError,\n IndexFlag,\n IndexOptions,\n AlterTableOperation,\n IdentifierTooLongError,\n ColumnAlreadyExistsError,\n CannotDropColumnError,\n ColumnNotFoundError,\n IndexNotFoundError,\n IndexAlreadyExistsError,\n TooManyIndexesError,\n IndexDescriptor,\n InvalidDatabaseError,\n CorruptPageError,\n TransactionOptions,\n UpsertOptions,\n MutationRecord,\n Changeset,\n TableChangeEvent,\n SyncState,\n BeforeCommitHook,\n CommitHook,\n TableSubscriptionCallback,\n} from \"../../types/index.ts\";\nimport { IVfsAdapter } from \"../storage/vfs.ts\";\nimport { MemoryVfsAdapter } from \"../storage/memory.ts\";\nimport { IndexedDbVfsAdapter } from \"../storage/idb.ts\";\nimport { OpfsVfsAdapter } from \"../storage/opfs.ts\";\nimport { Io } from \"../storage/io.ts\";\nimport { computePageChecksum } from \"../storage/crc32.ts\";\nimport {\n BufferPoolDriver,\n createWasmMemory,\n TransactionCoordinator,\n recoverFromWal,\n} from \"../driver/index.js\";\nimport {\n catalog_init_page1,\n catalog_read_page1_header,\n catalog_get_total_pages,\n catalog_create_table,\n catalog_load_table_meta,\n catalog_find_table_slot,\n catalog_find_free_table_slot,\n catalog_read_table_descriptor,\n catalog_write_table_descriptor,\n catalog_list_table_descriptors,\n catalog_read_page_header,\n catalog_write_column_meta,\n catalog_map_column_location,\n catalog_list_table_indexes,\n catalog_find_index_by_name,\n catalog_find_free_index_slot,\n catalog_write_index_descriptor,\n catalog_delete_index_descriptor,\n catalog_delete_table_descriptor,\n catalog_read_index_descriptor,\n catalog_increment_schema_version,\n catalog_increment_change_counter,\n catalog_update_page1_checksum,\n page_get_type,\n page_get_cell_count,\n page_get_cell_offset,\n page_insert_row,\n page_delete_row,\n page_update_row,\n page_get_next_page_id,\n page_set_next_page_id,\n page_serialize_row,\n page_deserialize_row,\n page_init_index_leaf,\n page_insert_index_leaf_cell,\n page_delete_index_leaf_cell,\n page_binary_search_index_leaf,\n serialize_composite_key,\n sql_like_match,\n} from \"../../core/index.ts\";\nimport {\n createVmContext,\n resetVmContext,\n VmContext,\n IPageProvider,\n} from \"../../shared/index.ts\";\nimport { vm_step } from \"../../core/index.ts\";\nimport {\n compileQuery,\n QueryFilter,\n SortKey,\n GroupKey,\n AggExpr,\n QueryPlan,\n JoinPlan,\n disassembleBytecode,\n formatDisassembly,\n} from \"../compiler/compiler.ts\";\nimport {\n ParsedSelectExpr,\n deriveDefaultAlias,\n evalExprNode,\n} from \"../compiler/expr_parser.ts\";\nimport { QueryPlanner } from \"../compiler/planner/index.ts\";\nimport {\n QueryBuilder,\n type ExplainOutput,\n type IDatabaseQueryExecutor,\n type QueryExecutionOptions,\n type JoinClause,\n} from \"./query_builder.ts\";\n\nexport interface UdfDefinition {\n deterministic?: boolean;\n returnType?: DataType;\n call: (...args: any[]) => any;\n}\n\nexport {\n QueryBuilder,\n type ExplainOutput,\n type IDatabaseQueryExecutor,\n type QueryExecutionOptions,\n};\n\nimport { createWasmCore, type WasmCoreExports } from \"../../core/index.ts\";\n\nexport interface WebDbOptions {\n name: string;\n storage?: \"memory\" | \"idb\" | \"opfs\";\n vfs?: IVfsAdapter;\n slotCount?: number;\n maxQueryMemory?: number;\n core?: \"js\" | \"wasm\";\n wasmBinary?: ArrayBuffer | Uint8Array;\n planner?: QueryPlanner;\n initialData?: Uint8Array | ArrayBuffer;\n}\n\nexport class WebDB implements IDatabaseQueryExecutor {\n readonly vfs: IVfsAdapter;\n readonly io: Io;\n readonly driver: BufferPoolDriver;\n readonly coreMode: \"js\" | \"wasm\";\n readonly wasmCore?: WasmCoreExports;\n private planner?: QueryPlanner;\n\n /**\n * Alias to driver for callers/tests that inspect the buffer pool.\n */\n get pool(): BufferPoolDriver {\n return this.driver;\n }\n\n readonly coordinator: TransactionCoordinator;\n currentLeaseId: number | null = null;\n private vmCtx: VmContext;\n private udfs: Map<string, { id: number; def: UdfDefinition }> = new Map();\n private nextUdfId = 1;\n private tableMetaCache: Map<string, TableMeta> = new Map();\n private tableTailPages: Map<string, number> = new Map();\n private indexTailPages: Map<number, number> = new Map();\n\n // Sync & Reactive state\n private beforeCommitHooks: Set<BeforeCommitHook> = new Set();\n private commitHooks: Set<CommitHook> = new Set();\n private subscriptions: Set<{\n tables: Set<string> | \"*\";\n callback: TableSubscriptionCallback;\n }> = new Set();\n private activeTxChanges: MutationRecord[] = [];\n private activeTxOrigin: string = \"local\";\n private activeTxMeta?: Record<string, any>;\n private activeTxId: number = 0;\n private nextAutoTxId: number = 1_000_000;\n private isRunningBeforeCommit: boolean = false;\n private broadcastChannel: BroadcastChannel | null = null;\n private readonly instanceId: string =\n Math.random().toString(36).slice(2) + Date.now().toString(36);\n\n private constructor(\n vfs: IVfsAdapter,\n io: Io,\n driver: BufferPoolDriver,\n coordinator: TransactionCoordinator,\n coreMode: \"js\" | \"wasm\" = \"js\",\n wasmCore?: WasmCoreExports,\n planner?: QueryPlanner,\n dbName?: string,\n ) {\n this.vfs = vfs;\n this.io = io;\n this.driver = driver;\n this.coordinator = coordinator;\n this.coreMode = coreMode;\n this.wasmCore = wasmCore;\n this.planner = planner;\n this.vmCtx = createVmContext();\n\n this.coordinator.setOnCrossTabInvalidated(async () => {\n this.tableMetaCache.clear();\n this.tableTailPages.clear();\n this.indexTailPages.clear();\n\n const tableDescriptors = catalog_list_table_descriptors(\n this.driver.getSlotDataView(0),\n );\n for (const desc of tableDescriptors) {\n let catPageId = desc.colCatalogPageId;\n while (catPageId !== 0) {\n const slot = await this.driver.acquireAndPinPage(catPageId);\n const view = this.driver.getSlotDataView(slot);\n const header = catalog_read_page_header(view, 0);\n catPageId = header.nextColCatalogPageId;\n }\n }\n });\n\n if (typeof BroadcastChannel !== \"undefined\" && dbName) {\n const channelName = `webdb_sync_${vfs.name}_${dbName}`;\n this.broadcastChannel = new BroadcastChannel(channelName);\n this.broadcastChannel.onmessage = (ev: MessageEvent) => {\n const data = ev.data;\n if (!data || data.senderId === this.instanceId) return;\n const { tables, origin, meta, changeCounter, schemaVersion } = data;\n this.coordinator.leaseQueue\n .enqueue(async () => {\n await this.coordinator.syncCrossTabState(true);\n this.notifySubscriptions({\n tables: Array.isArray(tables) ? tables : [],\n origin: origin ?? \"remote\",\n meta,\n changeCounter:\n typeof changeCounter === \"number\"\n ? changeCounter\n : this.getSyncState().changeCounter,\n schemaVersion:\n typeof schemaVersion === \"number\"\n ? schemaVersion\n : this.getSyncState().schemaVersion,\n crossTab: true,\n });\n })\n .catch(() => {});\n };\n }\n }\n\n static async open(options: WebDbOptions): Promise<WebDB> {\n const storageType = options.storage || \"memory\";\n let vfs: IVfsAdapter;\n if (options.vfs) {\n vfs = options.vfs;\n } else if (storageType === \"idb\") {\n vfs = new IndexedDbVfsAdapter(options.name);\n } else if (storageType === \"opfs\") {\n vfs = new OpfsVfsAdapter(options.name);\n } else {\n vfs = new MemoryVfsAdapter();\n }\n\n const slotCount = options.slotCount ?? DEFAULT_SLOT_COUNT;\n const maxQueryMemory = options.maxQueryMemory ?? DEFAULT_MAX_QUERY_MEMORY;\n const memory = createWasmMemory(\n Math.max(slotCount, DEFAULT_SLOT_COUNT),\n maxQueryMemory,\n );\n const io = new Io({ vfs, memory });\n const driver = new BufferPoolDriver({\n io,\n memory,\n slotCount,\n maxQueryMemory,\n useDefaultLayoutOffsets: true,\n });\n\n const crossTabLockName =\n options.name && vfs.name !== \"memory\"\n ? `webdb_lock_${vfs.name}_${options.name}`\n : undefined;\n\n const coordinator = new TransactionCoordinator(\n vfs,\n driver,\n io,\n crossTabLockName,\n );\n\n driver.setTransactionCoordinator(coordinator);\n\n await coordinator.leaseQueue.enqueue(async () => {\n // Section 6: Crash Recovery Protocol & Startup WAL Replay\n await recoverFromWal(vfs);\n\n // Check if Page 1 exists in storage\n const page1Data = await vfs.readPage(1);\n if (!page1Data) {\n // Initialize Page 1 in slot 0\n catalog_init_page1(driver.getSlotDataView(0));\n driver.markDirty(0);\n await driver.flushSlot(0);\n } else {\n // Load Page 1 into slot 0\n driver.getPageBytesInSlot(0).set(page1Data);\n driver.clearDirty(0);\n // Validate Page 1 header & checksum\n catalog_read_page1_header(driver.getSlotDataView(0), true);\n\n // Section 6.2: Pre-load and permanently pin all column catalog pages for active tables\n const tableDescriptors = catalog_list_table_descriptors(\n driver.getSlotDataView(0),\n );\n for (const desc of tableDescriptors) {\n let catPageId = desc.colCatalogPageId;\n while (catPageId !== 0) {\n const slot = await driver.acquireAndPinPage(catPageId);\n const view = driver.getSlotDataView(slot);\n const header = catalog_read_page_header(view, 0);\n catPageId = header.nextColCatalogPageId;\n }\n }\n }\n coordinator.recordDiskPage1State();\n });\n\n const coreMode = options.core ?? \"js\";\n let wasmCore: WasmCoreExports | undefined;\n if (coreMode === \"wasm\") {\n wasmCore = createWasmCore(\n memory,\n options.wasmBinary ? new Uint8Array(options.wasmBinary) : undefined,\n );\n }\n\n const dbInstance = new WebDB(\n vfs,\n io,\n driver,\n coordinator,\n coreMode,\n wasmCore,\n options.planner,\n options.name,\n );\n\n if (options.initialData) {\n await dbInstance.importBinary(options.initialData);\n }\n\n return dbInstance;\n }\n\n getPlanner(): QueryPlanner | undefined {\n return this.planner;\n }\n\n setPlanner(planner?: QueryPlanner): this {\n this.planner = planner;\n return this;\n }\n\n private validateIdentifier(identifier: string, label: string = \"Identifier\"): void {\n if (!identifier || typeof identifier !== \"string\" || identifier.length === 0) {\n throw new Error(`${label} cannot be empty`);\n }\n if (identifier.length > MAX_NAME_LENGTH) {\n throw new IdentifierTooLongError(identifier, MAX_NAME_LENGTH);\n }\n }\n\n async createTable(\n name: string,\n columns: ColumnDefinition[],\n ): Promise<TableMeta> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._createTableInternal(name, columns),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _createTableInternal(\n name: string,\n columns: ColumnDefinition[],\n ): Promise<TableMeta> {\n this.validateIdentifier(name, \"Table name\");\n if (columns.length === 0) {\n throw new Error(\"Table must have at least one column\");\n }\n if (columns.length > MAX_COLUMNS_PER_TABLE) {\n throw new TooManyColumnsError(columns.length, MAX_COLUMNS_PER_TABLE);\n }\n\n const seenColNames = new Set<string>();\n let hasPk = false;\n for (const col of columns) {\n this.validateIdentifier(col.name, \"Column name\");\n if (seenColNames.has(col.name)) {\n throw new ColumnAlreadyExistsError(col.name, name);\n }\n seenColNames.add(col.name);\n const flagsNum = typeof (col as any).flags === \"number\" ? (col as any).flags : 0;\n if (\n col.primaryKey ||\n col.flags?.primaryKey ||\n (flagsNum & ColumnFlag.PRIMARY_KEY) !== 0\n ) {\n hasPk = true;\n }\n }\n\n const page1View = this.pool.getSlotDataView(0);\n if (catalog_find_table_slot(page1View, name) !== -1) {\n throw new TableAlreadyExistsError(name);\n }\n if (catalog_find_free_table_slot(page1View) === -1) {\n throw new TooManyTablesError(MAX_TABLES_PAGE1, MAX_TABLES_PAGE1);\n }\n\n const numCatPages = Math.ceil(columns.length / MAX_COLUMNS_PER_CATALOG_PAGE);\n const needsPkIndexPage =\n hasPk && catalog_find_free_index_slot(page1View) !== -1 ? 1 : 0;\n const totalPagesToAllocate = 1 + numCatPages + needsPkIndexPage;\n\n const preAllocatedPages: number[] = [];\n for (let i = 0; i < totalPagesToAllocate; i++) {\n preAllocatedPages.push(await this.driver.allocateAndPinPage());\n }\n\n let allocCursor = 0;\n // Dynamic pager provider for table creation backed by pre-allocated pinned buffer pool slots\n const pager: IPageProvider = {\n allocateNewPage: () => {\n if (allocCursor < preAllocatedPages.length) {\n return preAllocatedPages[allocCursor++];\n }\n const currentTotal = page1View.getUint32(12, true);\n const newPageId = currentTotal + 1;\n page1View.setUint32(12, newPageId, true);\n this.pool.markDirty(0);\n return newPageId;\n },\n getPageBytes: (pageId: number) => {\n let slot = this.pool.getResidentSlot(pageId);\n if (slot === -1) {\n slot = pageId <= this.pool.slotCount ? pageId - 1 : 1;\n this.pool.assignSlot(slot, pageId);\n }\n return this.pool.getPageBytesInSlot(slot);\n },\n markPageDirty: (pageId: number) => {\n const slot = this.pool.getResidentSlot(pageId);\n if (slot !== -1) {\n this.pool.markDirty(slot);\n }\n },\n };\n\n let table: TableMeta;\n try {\n table = catalog_create_table(page1View, pager, name, columns);\n } catch (err) {\n for (const pId of preAllocatedPages) {\n this.driver.forceUnpinPage(pId);\n await this.driver.freePage(pId, true);\n }\n throw err;\n }\n\n // Unpin data root page and PK index root page (column catalog pages stay permanently pinned)\n this.driver.unpinPage(table.rootPageId);\n for (const idx of table.indexes ?? []) {\n if (idx.rootPageId > 1) {\n this.driver.unpinPage(idx.rootPageId);\n }\n }\n\n // Ensure column catalog pages for this new table remain permanently pinned\n let catPageId = table.colCatalogPageId;\n while (catPageId !== 0) {\n const slot = await this.driver.acquirePage(catPageId);\n if (!this.pool.isSlotPinned(slot)) {\n this.pool.pinSlot(slot);\n }\n const header = catalog_read_page_header(\n this.pool.getSlotDataView(slot),\n 0,\n );\n catPageId = header.nextColCatalogPageId;\n }\n\n // Flush modified pages if autocommit (not in transaction)\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n this.tableMetaCache.delete(name.toLowerCase());\n return table;\n }\n\n async getTable(tableName: string): Promise<TableMeta> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._getTableInternal(tableName),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _getTableInternal(tableName: string): Promise<TableMeta> {\n const key = tableName.toLowerCase();\n const cached = this.tableMetaCache.get(key);\n if (cached) {\n return cached;\n }\n\n const page1View = this.pool.getSlotDataView(0);\n const slotIdx = catalog_find_table_slot(page1View, tableName);\n\n if (slotIdx === -1) {\n throw new TableNotFoundError(tableName);\n }\n\n const desc = catalog_read_table_descriptor(page1View, slotIdx)!;\n let catPageId = desc.colCatalogPageId;\n\n while (catPageId !== 0) {\n await this.driver.acquirePage(catPageId);\n const slot = this.pool.getResidentSlot(catPageId);\n const header = catalog_read_page_header(\n this.pool.getSlotDataView(slot),\n 0,\n );\n catPageId = header.nextColCatalogPageId;\n }\n\n const pager = {\n getPageBytes: (pageId: number) => {\n const slot = this.pool.getResidentSlot(pageId);\n if (slot !== -1) return this.pool.getPageBytesInSlot(slot);\n return new Uint8Array(PAGE_SIZE);\n },\n };\n const meta = catalog_load_table_meta(page1View, pager, tableName);\n this.tableMetaCache.set(key, meta);\n return meta;\n }\n\n async listTables(): Promise<TableMeta[]> {\n return this.coordinator.leaseQueue.enqueue(async () => {\n const page1View = this.pool.getSlotDataView(0);\n const descriptors = catalog_list_table_descriptors(page1View);\n const tables: TableMeta[] = [];\n\n for (const desc of descriptors) {\n tables.push(await this._getTableInternal(desc.name));\n }\n\n return tables;\n }, this.currentLeaseId ?? undefined);\n }\n\n private async freeTableTreePages(rootPageId: number): Promise<void> {\n if (rootPageId <= 1) return;\n\n const toFree: number[] = [];\n const visited = new Set<number>();\n const queue = [rootPageId];\n\n while (queue.length > 0) {\n const pId = queue.shift()!;\n if (pId <= 1 || visited.has(pId)) continue;\n visited.add(pId);\n\n const slot = await this.driver.acquirePage(pId);\n const view = this.pool.getSlotDataView(slot);\n const pType = page_get_type(view, 0);\n\n // If page is already free, unpin resident slot if any and do not traverse or re-free\n if (pType === PAGE_TYPE_FREE) {\n this.driver.forceUnpinPage(pId);\n continue;\n }\n\n toFree.push(pId);\n\n if (\n pType === PAGE_TYPE_TABLE_INTERIOR ||\n pType === PAGE_TYPE_INDEX_INTERIOR\n ) {\n const cellCount = page_get_cell_count(view, 0);\n for (let i = 0; i < cellCount; i++) {\n const off = page_get_cell_offset(view, 0, i);\n if (off > 0 && off + 4 <= PAGE_SIZE) {\n const childId = view.getUint32(off, true);\n if (childId > 1 && !visited.has(childId)) {\n queue.push(childId);\n }\n }\n }\n const rightChildId = page_get_next_page_id(view, 0);\n if (rightChildId > 1 && !visited.has(rightChildId)) {\n queue.push(rightChildId);\n }\n } else if (\n pType === PAGE_TYPE_LEAF_DATA ||\n pType === PAGE_TYPE_INDEX_LEAF\n ) {\n const nextId = page_get_next_page_id(view, 0);\n if (nextId > 1 && !visited.has(nextId)) {\n queue.push(nextId);\n }\n }\n }\n\n for (const pId of toFree) {\n this.driver.forceUnpinPage(pId);\n await this.driver.freePage(pId, true);\n }\n }\n\n async dropTable(tableName: string): Promise<void> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._dropTableInternal(tableName),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _dropTableInternal(tableName: string): Promise<void> {\n this.tableMetaCache.delete(tableName.toLowerCase());\n this.tableTailPages.delete(tableName);\n\n const page1View = this.pool.getSlotDataView(0);\n const slotIdx = catalog_find_table_slot(page1View, tableName);\n if (slotIdx === -1) {\n throw new TableNotFoundError(tableName);\n }\n\n const desc = catalog_read_table_descriptor(page1View, slotIdx)!;\n\n // 1. Cascade drop all indexes belonging to this table\n for (let slot = 0; slot < MAX_INDEXES_PAGE1; slot++) {\n const idx = catalog_read_index_descriptor(page1View, slot);\n if (\n idx &&\n (idx.tableId === desc.tableId ||\n idx.name\n .toLowerCase()\n .startsWith(`idx_${tableName.toLowerCase()}_`) ||\n idx.name.toLowerCase() === `pk_${tableName.toLowerCase()}`)\n ) {\n if (idx.rootPageId > 1) {\n await this.freeTableTreePages(idx.rootPageId);\n this.indexTailPages.delete(idx.rootPageId);\n }\n catalog_delete_index_descriptor(page1View, slot);\n }\n }\n\n // 2. Free all data pages belonging to this table\n if (desc.rootPageId > 1) {\n await this.freeTableTreePages(desc.rootPageId);\n }\n\n // 3. Free all column catalog pages belonging to this table\n let curCatPageId = desc.colCatalogPageId;\n while (curCatPageId > 1) {\n const slot = await this.driver.acquirePage(curCatPageId);\n const view = this.pool.getSlotDataView(slot);\n const pType = page_get_type(view, 0);\n if (pType === PAGE_TYPE_FREE) {\n this.driver.forceUnpinPage(curCatPageId);\n break;\n }\n const header = catalog_read_page_header(view, 0);\n const nextId = header.nextColCatalogPageId;\n this.driver.forceUnpinPage(curCatPageId);\n await this.driver.freePage(curCatPageId, true);\n curCatPageId = nextId;\n }\n\n // 4. Clear table descriptor in Page 1\n catalog_delete_table_descriptor(page1View, slotIdx);\n catalog_increment_schema_version(page1View);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n if (this.vmCtx.table?.name.toLowerCase() === tableName.toLowerCase()) {\n this.vmCtx.table = null;\n }\n }\n\n async renameTable(oldName: string, newName: string): Promise<TableMeta> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._renameTableInternal(oldName, newName),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _renameTableInternal(\n oldName: string,\n newName: string,\n ): Promise<TableMeta> {\n this.validateIdentifier(newName, \"Table name\");\n const page1View = this.pool.getSlotDataView(0);\n const slotIdx = catalog_find_table_slot(page1View, oldName);\n if (slotIdx === -1) {\n throw new TableNotFoundError(oldName);\n }\n\n if (oldName === newName) {\n return this._getTableInternal(newName);\n }\n\n if (catalog_find_table_slot(page1View, newName) !== -1) {\n throw new TableAlreadyExistsError(newName);\n }\n\n const desc = catalog_read_table_descriptor(page1View, slotIdx)!;\n desc.name = newName;\n catalog_write_table_descriptor(page1View, slotIdx, desc);\n\n // Update auto-generated PK and secondary index names belonging to this table\n const oldPkName = `pk_${oldName}`;\n const oldIdxPrefix = `idx_${oldName}_`;\n for (let i = 0; i < MAX_INDEXES_PAGE1; i++) {\n const idx = catalog_read_index_descriptor(page1View, i);\n if (idx && idx.tableId === desc.tableId) {\n let updatedName: string | null = null;\n if (idx.name === oldPkName) {\n updatedName = `pk_${newName}`;\n } else if (idx.name.startsWith(oldIdxPrefix)) {\n updatedName = `idx_${newName}_${idx.name.slice(oldIdxPrefix.length)}`;\n }\n if (\n updatedName &&\n updatedName.length <= MAX_NAME_LENGTH &&\n !catalog_find_index_by_name(page1View, updatedName)\n ) {\n idx.name = updatedName;\n catalog_write_index_descriptor(page1View, i, idx);\n }\n }\n }\n\n catalog_increment_schema_version(page1View);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n\n this.tableMetaCache.delete(oldName.toLowerCase());\n this.tableMetaCache.delete(newName.toLowerCase());\n const tailPage = this.tableTailPages.get(oldName);\n if (tailPage !== undefined) {\n this.tableTailPages.delete(oldName);\n this.tableTailPages.set(newName, tailPage);\n }\n if (this.vmCtx.table?.name.toLowerCase() === oldName.toLowerCase()) {\n this.vmCtx.table = null;\n }\n\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return this._getTableInternal(newName);\n }\n\n async renameColumn(\n tableName: string,\n oldColumnName: string,\n newColumnName: string,\n ): Promise<TableMeta> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._renameColumnInternal(tableName, oldColumnName, newColumnName),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _renameColumnInternal(\n tableName: string,\n oldColumnName: string,\n newColumnName: string,\n ): Promise<TableMeta> {\n this.validateIdentifier(newColumnName, \"Column name\");\n const table = await this._getTableInternal(tableName);\n const colIdx = table.columns.findIndex((c) => c.name === oldColumnName);\n if (colIdx === -1) {\n throw new ColumnNotFoundError(oldColumnName, tableName);\n }\n\n if (oldColumnName === newColumnName) {\n return table;\n }\n\n if (table.columns.some((c, idx) => idx !== colIdx && c.name === newColumnName)) {\n throw new ColumnAlreadyExistsError(newColumnName, tableName);\n }\n\n const { pageChainIdx, colIdxInPage } = catalog_map_column_location(colIdx);\n let catPageId = table.colCatalogPageId;\n for (let p = 0; p < pageChainIdx; p++) {\n const slot = await this.driver.acquirePage(catPageId);\n const header = catalog_read_page_header(\n this.pool.getSlotDataView(slot),\n 0,\n );\n catPageId = header.nextColCatalogPageId;\n }\n\n const catSlot = await this.driver.acquirePage(catPageId);\n const catView = this.pool.getSlotDataView(catSlot);\n const updatedCol: ColumnMeta = {\n ...table.columns[colIdx],\n name: newColumnName,\n };\n catalog_write_column_meta(catView, 0, colIdxInPage, updatedCol);\n const chk = computePageChecksum(this.pool.getPageBytesInSlot(catSlot));\n catView.setUint32(12, chk, true);\n this.pool.markDirty(catSlot);\n\n const page1View = this.pool.getSlotDataView(0);\n catalog_increment_schema_version(page1View);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n\n this.tableMetaCache.delete(tableName.toLowerCase());\n if (this.vmCtx.table?.name.toLowerCase() === tableName.toLowerCase()) {\n this.vmCtx.table = null;\n }\n\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return this._getTableInternal(tableName);\n }\n\n async addColumn(\n tableName: string,\n column: ColumnDefinition,\n options?: { defaultValue?: DbValue },\n ): Promise<TableMeta> {\n this.validateIdentifier(column.name, \"Column name\");\n const defaultVal: DbValue =\n options?.defaultValue !== undefined\n ? options.defaultValue\n : (column as any).defaultValue !== undefined\n ? (column as any).defaultValue\n : null;\n\n return this._executeTableRebuildAtomic(tableName, (table) => {\n if (table.columns.some((c) => c.name === column.name)) {\n throw new ColumnAlreadyExistsError(column.name, tableName);\n }\n if (table.columns.length + 1 > MAX_COLUMNS_PER_TABLE) {\n throw new TooManyColumnsError(\n table.columns.length + 1,\n MAX_COLUMNS_PER_TABLE,\n );\n }\n\n const rawFlags =\n typeof (column as any).flags === \"number\" ? (column as any).flags : 0;\n const isPk =\n !!column.primaryKey ||\n !!column.flags?.primaryKey ||\n (rawFlags & ColumnFlag.PRIMARY_KEY) !== 0;\n const isAutoInc =\n !!column.autoInc ||\n !!column.flags?.autoInc ||\n (rawFlags & ColumnFlag.AUTO_INC) !== 0;\n const isIndexed =\n !!column.indexed ||\n !!column.flags?.indexed ||\n (rawFlags & ColumnFlag.INDEXED) !== 0;\n\n if (\n isPk &&\n table.columns.some((c) => (c.flags & ColumnFlag.PRIMARY_KEY) !== 0)\n ) {\n throw new Error(\n `Cannot add a PRIMARY KEY column \"${column.name}\" to table \"${tableName}\" because it already has a primary key`,\n );\n }\n\n const existingColDefs: ColumnDefinition[] = table.columns.map((c) => ({\n name: c.name,\n type: c.type,\n flags: {\n primaryKey: (c.flags & ColumnFlag.PRIMARY_KEY) !== 0,\n notNull: (c.flags & ColumnFlag.NOT_NULL) !== 0,\n indexed: (c.flags & ColumnFlag.INDEXED) !== 0,\n autoInc: (c.flags & ColumnFlag.AUTO_INC) !== 0,\n },\n }));\n\n return {\n newColumns: [...existingColDefs, column],\n transformRow: (row: DbRow) => {\n const nextRow: DbRow = { ...row };\n if (!isAutoInc || defaultVal !== null) {\n nextRow[column.name] = defaultVal;\n }\n return nextRow;\n },\n keepIndex: () => true,\n newAutoIndexCol: isIndexed && !isPk ? column.name : undefined,\n };\n });\n }\n\n async dropColumn(tableName: string, columnName: string): Promise<TableMeta> {\n this.validateIdentifier(columnName, \"Column name\");\n\n return this._executeTableRebuildAtomic(tableName, (table) => {\n const colIdx = table.columns.findIndex((c) => c.name === columnName);\n if (colIdx === -1) {\n throw new ColumnNotFoundError(columnName, tableName);\n }\n if (table.columns.length <= 1) {\n throw new CannotDropColumnError(\n `Cannot drop column \"${columnName}\" from table \"${tableName}\": table must have at least one column`,\n );\n }\n\n const targetCol = table.columns[colIdx];\n if ((targetCol.flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n throw new CannotDropColumnError(\n `Cannot drop PRIMARY KEY column \"${columnName}\" from table \"${tableName}\"`,\n );\n }\n\n const newColumns: ColumnDefinition[] = table.columns\n .filter((c) => c.name !== columnName)\n .map((c) => ({\n name: c.name,\n type: c.type,\n flags: {\n primaryKey: (c.flags & ColumnFlag.PRIMARY_KEY) !== 0,\n notNull: (c.flags & ColumnFlag.NOT_NULL) !== 0,\n indexed: (c.flags & ColumnFlag.INDEXED) !== 0,\n autoInc: (c.flags & ColumnFlag.AUTO_INC) !== 0,\n },\n }));\n\n return {\n newColumns,\n transformRow: (row: DbRow) => {\n const nextRow: DbRow = { ...row };\n delete nextRow[columnName];\n return nextRow;\n },\n keepIndex: (colNames: string[]) => !colNames.includes(columnName),\n };\n });\n }\n\n async alterTable(\n tableName: string,\n operation: AlterTableOperation,\n ): Promise<TableMeta> {\n switch (operation.type) {\n case \"renameTable\":\n return this.renameTable(tableName, operation.newName);\n case \"renameColumn\":\n return this.renameColumn(tableName, operation.from, operation.to);\n case \"addColumn\":\n return this.addColumn(tableName, operation.column, {\n defaultValue: operation.defaultValue,\n });\n case \"dropColumn\":\n return this.dropColumn(tableName, operation.column);\n default:\n throw new Error(\n `Unsupported alterTable operation: ${(operation as any)?.type}`,\n );\n }\n }\n\n private async _executeTableRebuildAtomic(\n tableName: string,\n prepare: (table: TableMeta) => {\n newColumns: ColumnDefinition[];\n transformRow: (row: DbRow) => DbRow;\n keepIndex: (colNames: string[]) => boolean;\n newAutoIndexCol?: string;\n },\n ): Promise<TableMeta> {\n if (!this.coordinator.isInTransaction()) {\n return this.transaction((tx) =>\n tx._rebuildTableSchemaInternal(tableName, prepare),\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const savepoint = await this.coordinator.captureSavepoint();\n try {\n return await this._rebuildTableSchemaInternal(tableName, prepare);\n } catch (err) {\n this.tableMetaCache.clear();\n this.tableTailPages.clear();\n this.indexTailPages.clear();\n await this.coordinator.restoreSavepoint(savepoint);\n throw err;\n }\n }, this.currentLeaseId ?? undefined);\n }\n\n private async _rebuildTableSchemaInternal(\n tableName: string,\n prepare: (table: TableMeta) => {\n newColumns: ColumnDefinition[];\n transformRow: (row: DbRow) => DbRow;\n keepIndex: (colNames: string[]) => boolean;\n newAutoIndexCol?: string;\n },\n ): Promise<TableMeta> {\n const table = await this._getTableInternal(tableName);\n const { newColumns, transformRow, keepIndex, newAutoIndexCol } =\n prepare(table);\n\n // 1. Read all existing rows across the table's data pages\n const migratedRows: DbRow[] = [];\n let currentPageId = table.rootPageId;\n while (currentPageId !== 0) {\n let pageSlot = await this.driver.acquirePage(currentPageId);\n let pageView = this.pool.getSlotDataView(pageSlot);\n const cellCount = page_get_cell_count(pageView, 0);\n const nextPageId = page_get_next_page_id(pageView, 0);\n\n for (let i = 0; i < cellCount; i++) {\n pageSlot = await this.driver.acquirePage(currentPageId);\n pageView = this.pool.getSlotDataView(pageSlot);\n const cellOffset = page_get_cell_offset(pageView, 0, i);\n const row = page_deserialize_row(table.columns, pageView, cellOffset);\n if (row) {\n migratedRows.push(transformRow(row));\n }\n }\n\n currentPageId = nextPageId;\n }\n\n // 2. Capture autoIncNext and surviving secondary indexes\n const savedAutoIncNext = table.autoIncNext;\n const page1View = this.pool.getSlotDataView(0);\n const existingIndexes = catalog_list_table_indexes(\n page1View,\n table.tableId,\n );\n const survivingSecondaryIndexes: Array<{\n name: string;\n colNames: string[];\n unique: boolean;\n }> = [];\n\n for (const idx of existingIndexes) {\n if ((idx.flags & IndexFlag.PRIMARY) !== 0) continue;\n const colNames = idx.columnIndices\n .slice(0, idx.columnCount)\n .map((cIdx) => table.columns[cIdx]?.name)\n .filter((n): n is string => typeof n === \"string\");\n if (colNames.length === idx.columnCount && keepIndex(colNames)) {\n survivingSecondaryIndexes.push({\n name: idx.name,\n colNames,\n unique: (idx.flags & IndexFlag.UNIQUE) !== 0,\n });\n }\n }\n\n // 3. Drop old table and recreate with the new column layout\n await this._dropTableInternal(tableName);\n await this._createTableInternal(tableName, newColumns);\n\n // 4. Recreate surviving secondary indexes\n for (const idxSpec of survivingSecondaryIndexes) {\n await this._createIndexInternal(tableName, idxSpec.colNames, {\n name: idxSpec.name,\n unique: idxSpec.unique,\n });\n }\n\n if (\n newAutoIndexCol &&\n !survivingSecondaryIndexes.some(\n (idx) =>\n idx.colNames.length === 1 && idx.colNames[0] === newAutoIndexCol,\n )\n ) {\n await this._createIndexInternal(tableName, newAutoIndexCol);\n }\n\n // 5. Re-insert migrated rows\n if (migratedRows.length > 0) {\n await this._insertManyInternal(tableName, migratedRows, false);\n }\n\n // 6. Restore autoIncNext sequence if needed\n const newSlotIdx = catalog_find_table_slot(page1View, tableName);\n if (newSlotIdx !== -1) {\n const newDesc = catalog_read_table_descriptor(page1View, newSlotIdx)!;\n if (savedAutoIncNext > newDesc.autoIncNext) {\n newDesc.autoIncNext = savedAutoIncNext;\n catalog_write_table_descriptor(page1View, newSlotIdx, newDesc);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n }\n }\n\n this.tableMetaCache.delete(tableName.toLowerCase());\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return this._getTableInternal(tableName);\n }\n\n async createIndex(\n tableName: string,\n columns: string | string[],\n options?: IndexOptions,\n ): Promise<void> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._createIndexInternal(tableName, columns, options),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _createIndexInternal(\n tableName: string,\n columns: string | string[],\n options?: IndexOptions,\n ): Promise<void> {\n const table = await this._getTableInternal(tableName);\n const colNames = Array.isArray(columns) ? columns : [columns];\n\n if (colNames.length === 0) {\n throw new Error(\n `At least one column must be specified for createIndex on table \"${tableName}\"`,\n );\n }\n if (colNames.length > 8) {\n throw new Error(\n `Maximum 8 columns allowed per index (requested ${colNames.length})`,\n );\n }\n\n const colIndices: number[] = [];\n for (const name of colNames) {\n const idx = table.columns.findIndex((c) => c.name === name);\n if (idx === -1) {\n throw new ColumnNotFoundError(name, tableName);\n }\n colIndices.push(idx);\n }\n\n const indexName = options?.name ?? `idx_${tableName}_${colNames.join(\"_\")}`;\n\n const page1View = this.pool.getSlotDataView(0);\n\n // Prevent two indices with the same name across the catalog\n const existing = catalog_find_index_by_name(page1View, indexName);\n if (existing !== null) {\n throw new IndexAlreadyExistsError(indexName);\n }\n\n // Prevent creating the same index twice (same columns in the same order on the same table)\n const tableIndexes = catalog_list_table_indexes(page1View, table.tableId);\n const duplicateColIndex = tableIndexes.find((idx) => {\n if (idx.columnCount !== colIndices.length) return false;\n for (let i = 0; i < idx.columnCount; i++) {\n if (idx.columnIndices[i] !== colIndices[i]) return false;\n }\n return true;\n });\n if (duplicateColIndex) {\n throw new IndexAlreadyExistsError(duplicateColIndex.name || indexName);\n }\n\n const freeSlot = catalog_find_free_index_slot(page1View);\n if (freeSlot === -1) {\n throw new TooManyIndexesError(MAX_INDEXES_PAGE1, MAX_INDEXES_PAGE1);\n }\n\n // Allocate and initialize index root page\n const indexRootPageId = await this.driver.allocateAndPinPage();\n const indexSlot = this.pool.getResidentSlot(indexRootPageId);\n const indexView = this.pool.getSlotDataView(indexSlot);\n page_init_index_leaf(indexView, 0, 0);\n this.pool.markDirty(indexSlot);\n this.pool.unpinSlot(indexSlot);\n\n const isUnique = !!options?.unique;\n\n // Backfill: iterate all data pages and insert existing rows into new index\n let currentPageId = table.rootPageId;\n while (currentPageId !== 0) {\n let pageSlot = await this.driver.acquirePage(currentPageId);\n let pageView = this.pool.getSlotDataView(pageSlot);\n const cellCount = page_get_cell_count(pageView, 0);\n const nextPageId = page_get_next_page_id(pageView, 0);\n\n for (let i = 0; i < cellCount; i++) {\n pageSlot = await this.driver.acquirePage(currentPageId);\n pageView = this.pool.getSlotDataView(pageSlot);\n const cellOffset = page_get_cell_offset(pageView, 0, i);\n const row = page_deserialize_row(table.columns, pageView, cellOffset);\n if (row) {\n const rowid = (BigInt(currentPageId) << 16n) | BigInt(i);\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n { columnCount: colIndices.length, columnIndices: colIndices },\n row,\n );\n\n if (keyVal !== undefined && keyVal !== null) {\n if (isUnique) {\n const duplicate = await this.probeIndexUnique(\n indexRootPageId,\n keyType,\n keyVal,\n );\n if (duplicate) {\n await this.freeTableTreePages(indexRootPageId);\n this.indexTailPages.delete(indexRootPageId);\n throw new UniqueConstraintViolationError(\n `Duplicate key value violates unique constraint \"${indexName}\" on table \"${tableName}\"`,\n );\n }\n }\n\n await this.insertIntoIndex(indexRootPageId, keyType, keyVal, rowid);\n }\n }\n }\n\n currentPageId = nextPageId;\n }\n\n // Write index descriptor into Page 1 catalog\n const column_indices = [0, 0, 0, 0, 0, 0, 0, 0];\n const col_directions = [0, 0, 0, 0, 0, 0, 0, 0];\n for (let k = 0; k < colIndices.length && k < 8; k++) {\n column_indices[k] = colIndices[k];\n }\n\n const flags = isUnique ? IndexFlag.UNIQUE : 0;\n catalog_write_index_descriptor(page1View, freeSlot, {\n indexId: freeSlot + 1,\n tableId: table.tableId,\n rootPageId: indexRootPageId,\n columnCount: colIndices.length,\n flags,\n columnIndices: column_indices,\n colDirections: col_directions,\n name: indexName,\n });\n\n catalog_increment_schema_version(page1View);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n this.tableMetaCache.delete(tableName.toLowerCase());\n this.indexTailPages.delete(indexRootPageId);\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n }\n\n async dropIndex(indexName: string): Promise<void> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._dropIndexInternal(indexName),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _dropIndexInternal(indexName: string): Promise<void> {\n const page1View = this.pool.getSlotDataView(0);\n const found = catalog_find_index_by_name(page1View, indexName);\n if (!found) {\n throw new IndexNotFoundError(indexName);\n }\n\n // Free all pages in the index tree\n if (found.desc.rootPageId > 1) {\n await this.freeTableTreePages(found.desc.rootPageId);\n this.indexTailPages.delete(found.desc.rootPageId);\n }\n\n catalog_delete_index_descriptor(page1View, found.slotIdx);\n catalog_increment_schema_version(page1View);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n this.tableMetaCache.clear();\n this.indexTailPages.clear();\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n }\n\n async listIndexes(tableName?: string): Promise<IndexDescriptor[]> {\n return this.coordinator.leaseQueue.enqueue(async () => {\n const page1View = this.pool.getSlotDataView(0);\n if (tableName) {\n const table = await this._getTableInternal(tableName);\n return catalog_list_table_indexes(page1View, table.tableId);\n }\n const allIndexes: IndexDescriptor[] = [];\n for (let i = 0; i < MAX_INDEXES_PAGE1; i++) {\n const desc = catalog_read_index_descriptor(page1View, i);\n if (desc) {\n allIndexes.push(desc);\n }\n }\n return allIndexes;\n }, this.currentLeaseId ?? undefined);\n }\n\n private extractIndexKey(\n columns: ColumnMeta[],\n idx: { columnCount: number; columnIndices: number[] },\n row: DbRow,\n ): { keyVal: any; keyType: DataType } {\n if (idx.columnCount === 1) {\n const col = columns[idx.columnIndices[0]];\n return { keyVal: row[col.name], keyType: col.type };\n }\n return {\n keyVal: serialize_composite_key(\n columns,\n idx.columnIndices,\n idx.columnCount,\n row,\n ),\n keyType: DataType.BLOB,\n };\n }\n\n private async probeIndexUnique(\n rootPageId: number,\n keyType: DataType,\n keyVal: any,\n excludedRowids?: Set<bigint>,\n ): Promise<boolean> {\n let currIdxPageId = rootPageId;\n while (currIdxPageId !== 0) {\n const slot = await this.driver.acquirePage(currIdxPageId);\n const view = this.pool.getSlotDataView(slot);\n const cellCount = page_get_cell_count(view, 0);\n if (cellCount > 0) {\n const search = page_binary_search_index_leaf(view, 0, keyType, keyVal);\n if (search.found) {\n const cellOff = page_get_cell_offset(view, 0, search.slot_idx);\n const kLen = view.getUint16(cellOff, true);\n const foundRowid = view.getBigInt64(cellOff + 2 + kLen, true);\n if (!excludedRowids || !excludedRowids.has(foundRowid)) {\n return true;\n }\n }\n }\n currIdxPageId = page_get_next_page_id(view, 0);\n }\n return false;\n }\n\n private async deleteFromIndex(\n rootPageId: number,\n keyType: DataType,\n keyVal: any,\n rowid: bigint,\n ): Promise<boolean> {\n let currIdxPageId = rootPageId;\n while (currIdxPageId !== 0) {\n const slot = await this.driver.acquirePage(currIdxPageId);\n const view = this.pool.getSlotDataView(slot);\n const cellCount = page_get_cell_count(view, 0);\n if (cellCount > 0) {\n const search = page_binary_search_index_leaf(\n view,\n 0,\n keyType,\n keyVal,\n rowid,\n );\n if (search.found) {\n page_delete_index_leaf_cell(view, 0, search.slot_idx);\n this.pool.markDirty(slot);\n return true;\n }\n }\n currIdxPageId = page_get_next_page_id(view, 0);\n }\n return false;\n }\n\n private async insertIntoIndex(\n rootPageId: number,\n keyType: DataType,\n keyVal: any,\n rowid: bigint,\n ): Promise<void> {\n let idxPageId = this.indexTailPages.get(rootPageId) ?? rootPageId;\n let idxSlot = await this.driver.acquirePage(idxPageId);\n let idxView = this.pool.getSlotDataView(idxSlot);\n\n while (true) {\n const nextIdxPageId = page_get_next_page_id(idxView, 0);\n if (nextIdxPageId === 0) break;\n idxPageId = nextIdxPageId;\n idxSlot = await this.driver.acquirePage(idxPageId);\n idxView = this.pool.getSlotDataView(idxSlot);\n }\n this.indexTailPages.set(rootPageId, idxPageId);\n\n let idxInsertRes = page_insert_index_leaf_cell(\n idxView,\n 0,\n keyType,\n keyVal,\n rowid,\n this.pool.pageScratchpadOffset,\n );\n\n if (idxInsertRes === -1) {\n this.pool.pinSlot(idxSlot);\n try {\n const newIdxPageId = await this.driver.allocateAndPinPage();\n const newIdxSlot = this.pool.getResidentSlot(newIdxPageId);\n try {\n page_set_next_page_id(idxView, 0, newIdxPageId);\n this.pool.markDirty(idxSlot);\n\n const newIdxView = this.pool.getSlotDataView(newIdxSlot);\n page_init_index_leaf(newIdxView, 0, 0);\n idxInsertRes = page_insert_index_leaf_cell(\n newIdxView,\n 0,\n keyType,\n keyVal,\n rowid,\n this.pool.pageScratchpadOffset,\n );\n if (idxInsertRes === -1) {\n throw new Error(\n \"Unexpected error: index entry does not fit in empty page\",\n );\n }\n this.pool.markDirty(newIdxSlot);\n this.indexTailPages.set(rootPageId, newIdxPageId);\n } finally {\n this.pool.unpinSlot(newIdxSlot);\n }\n } finally {\n this.pool.unpinSlot(idxSlot);\n }\n } else {\n this.pool.markDirty(idxSlot);\n }\n }\n\n private cloneRow(row: DbRow): DbRow {\n const out: DbRow = {};\n for (const [k, v] of Object.entries(row)) {\n out[k] = v instanceof Uint8Array ? v.slice() : v;\n }\n return out;\n }\n\n private valuesEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if ((a === null || a === undefined) && (b === null || b === undefined)) {\n return true;\n }\n if (a instanceof Uint8Array && b instanceof Uint8Array) {\n if (a.byteLength !== b.byteLength) return false;\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n if (\n (typeof a === \"number\" && typeof b === \"bigint\") ||\n (typeof a === \"bigint\" && typeof b === \"number\")\n ) {\n return BigInt(a) === BigInt(b);\n }\n if (\n (typeof a === \"boolean\" && typeof b === \"number\") ||\n (typeof a === \"number\" && typeof b === \"boolean\")\n ) {\n return Number(a) === Number(b);\n }\n return false;\n }\n\n private extractPrimaryKey(\n table: TableMeta,\n row: DbRow,\n ): DbValue | DbValue[] {\n const pkCols = table.columns.filter(\n (c) => (c.flags & ColumnFlag.PRIMARY_KEY) !== 0,\n );\n if (pkCols.length === 1) {\n return (row[pkCols[0].name] ?? null) as DbValue;\n }\n if (pkCols.length > 1) {\n return pkCols.map((c) => (row[c.name] ?? null) as DbValue);\n }\n if (table.columns.length === 1) {\n return (row[table.columns[0].name] ?? null) as DbValue;\n }\n return table.columns.map((c) => (row[c.name] ?? null) as DbValue);\n }\n\n private serializePkKey(\n pk: DbValue | DbValue[] | Record<string, DbValue>,\n ): string {\n const formatOne = (v: DbValue): string => {\n if (v === null || v === undefined) return \"null\";\n if (v instanceof Uint8Array) return `b:${Array.from(v).join(\",\")}`;\n return `${typeof v}:${String(v)}`;\n };\n if (Array.isArray(pk)) {\n return `[${pk.map(formatOne).join(\"|\")}]`;\n }\n if (pk !== null && typeof pk === \"object\" && !(pk instanceof Uint8Array)) {\n const keys = Object.keys(pk).sort();\n return `{${keys.map((k) => `${k}:${formatOne(pk[k])}`).join(\"|\")}}`;\n }\n return formatOne(pk as DbValue);\n }\n\n private buildChangeset(\n txId: number,\n origin: string,\n meta: Record<string, any> | undefined,\n changes: MutationRecord[],\n ): Changeset {\n const { changeCounter, schemaVersion } = this.getSyncState();\n const tables = Array.from(new Set(changes.map((c) => c.table)));\n\n return {\n txId,\n origin,\n meta,\n changeCounter,\n schemaVersion,\n tables,\n changes,\n coalesced: (): MutationRecord[] => {\n const map = new Map<string, MutationRecord>();\n for (const rec of changes) {\n const key = `${rec.table.toLowerCase()}::${this.serializePkKey(rec.pk)}`;\n const prev = map.get(key);\n if (!prev) {\n map.set(key, {\n table: rec.table,\n op: rec.op,\n pk: Array.isArray(rec.pk) ? [...rec.pk] : rec.pk,\n oldRow: rec.oldRow ? this.cloneRow(rec.oldRow) : undefined,\n newRow: rec.newRow ? this.cloneRow(rec.newRow) : undefined,\n changedColumns: rec.changedColumns\n ? [...rec.changedColumns]\n : undefined,\n });\n continue;\n }\n\n if (prev.op === \"insert\" && rec.op === \"update\") {\n map.set(key, {\n table: rec.table,\n op: \"insert\",\n pk: Array.isArray(rec.pk) ? [...rec.pk] : rec.pk,\n newRow: rec.newRow ? this.cloneRow(rec.newRow) : prev.newRow,\n });\n } else if (prev.op === \"insert\" && rec.op === \"delete\") {\n map.delete(key);\n } else if (prev.op === \"update\" && rec.op === \"update\") {\n const oldRow = prev.oldRow!;\n const newRow = rec.newRow ? this.cloneRow(rec.newRow) : prev.newRow!;\n const changedColumns = Object.keys(newRow).filter(\n (col) => !this.valuesEqual(oldRow[col], newRow[col]),\n );\n map.set(key, {\n table: rec.table,\n op: \"update\",\n pk: Array.isArray(rec.pk) ? [...rec.pk] : rec.pk,\n oldRow,\n newRow,\n changedColumns,\n });\n } else if (prev.op === \"update\" && rec.op === \"delete\") {\n map.set(key, {\n table: rec.table,\n op: \"delete\",\n pk: Array.isArray(prev.pk) ? [...prev.pk] : prev.pk,\n oldRow: prev.oldRow,\n });\n } else if (prev.op === \"delete\" && rec.op === \"insert\") {\n const oldRow = prev.oldRow!;\n const newRow = rec.newRow ? this.cloneRow(rec.newRow) : {};\n const changedColumns = Object.keys(newRow).filter(\n (col) => !this.valuesEqual(oldRow[col], newRow[col]),\n );\n map.set(key, {\n table: rec.table,\n op: \"update\",\n pk: Array.isArray(rec.pk) ? [...rec.pk] : rec.pk,\n oldRow,\n newRow,\n changedColumns,\n });\n } else {\n map.set(key, {\n table: rec.table,\n op: rec.op,\n pk: Array.isArray(rec.pk) ? [...rec.pk] : rec.pk,\n oldRow: rec.oldRow ? this.cloneRow(rec.oldRow) : undefined,\n newRow: rec.newRow ? this.cloneRow(rec.newRow) : undefined,\n changedColumns: rec.changedColumns\n ? [...rec.changedColumns]\n : undefined,\n });\n }\n }\n return Array.from(map.values());\n },\n };\n }\n\n private notifySubscriptions(event: TableChangeEvent): void {\n if (event.tables.length === 0 || this.subscriptions.size === 0) return;\n const lowerChanged = new Set(event.tables.map((t) => t.toLowerCase()));\n for (const sub of this.subscriptions) {\n if (sub.tables === \"*\") {\n sub.callback(event);\n } else {\n for (const t of lowerChanged) {\n if (sub.tables.has(t)) {\n sub.callback(event);\n break;\n }\n }\n }\n }\n }\n\n private emitCommitAndSubscriptions(changeset: Changeset): void {\n if (changeset.changes.length === 0) return;\n\n for (const hook of this.commitHooks) {\n hook(changeset);\n }\n\n const tables = changeset.tables;\n const { changeCounter, schemaVersion } = changeset;\n\n this.notifySubscriptions({\n tables,\n origin: changeset.origin,\n meta: changeset.meta,\n changeCounter,\n schemaVersion,\n crossTab: false,\n changeset,\n });\n\n if (this.broadcastChannel) {\n try {\n this.broadcastChannel.postMessage({\n senderId: this.instanceId,\n tables,\n origin: changeset.origin,\n meta: changeset.meta,\n changeCounter,\n schemaVersion,\n });\n } catch {\n // Ignore broadcast errors\n }\n }\n }\n\n onBeforeCommit(hook: BeforeCommitHook): () => void {\n this.beforeCommitHooks.add(hook);\n return () => {\n this.beforeCommitHooks.delete(hook);\n };\n }\n\n onCommit(hook: CommitHook): () => void {\n this.commitHooks.add(hook);\n return () => {\n this.commitHooks.delete(hook);\n };\n }\n\n subscribe(\n tables: string | string[] | \"*\",\n callback: TableSubscriptionCallback,\n ): () => void {\n const entry = {\n tables:\n tables === \"*\"\n ? (\"*\" as const)\n : new Set(\n (Array.isArray(tables) ? tables : [tables]).map((t) =>\n t.toLowerCase(),\n ),\n ),\n callback,\n };\n this.subscriptions.add(entry);\n return () => {\n this.subscriptions.delete(entry);\n };\n }\n\n getSyncState(): SyncState {\n const page1View = this.pool.getSlotDataView(0);\n const header = catalog_read_page1_header(page1View, false);\n return {\n changeCounter: header.changeCounter,\n schemaVersion: header.schemaVersion,\n };\n }\n\n private validateFilterColumns(table: TableMeta, filters: QueryFilter[]): void {\n const validCols = new Set(table.columns.map((c) => c.name));\n const checkExpr = (expr: any) => {\n if (!expr) return;\n if (expr.type === \"col\" && expr.name !== \"*\") {\n if (!validCols.has(expr.name)) {\n throw new ColumnNotFoundError(expr.name, table.name);\n }\n } else if (expr.type === \"binary\") {\n checkExpr(expr.left);\n checkExpr(expr.right);\n } else if (expr.type === \"fn\" && Array.isArray(expr.args)) {\n for (const a of expr.args) checkExpr(a);\n }\n };\n const checkFilter = (f: QueryFilter) => {\n if (f.colName && !validCols.has(f.colName)) {\n throw new ColumnNotFoundError(f.colName, table.name);\n }\n if (f.expr) checkExpr(f.expr);\n if (f.child) checkFilter(f.child);\n if (f.children) {\n for (const c of f.children) checkFilter(c);\n }\n };\n for (const f of filters) checkFilter(f);\n }\n\n private matchesFilter(\n table: TableMeta,\n row: DbRow,\n f: QueryFilter,\n ): boolean {\n switch (f.type) {\n case \"and\":\n return (f.children ?? []).every((c) =>\n this.matchesFilter(table, row, c),\n );\n case \"or\":\n return (f.children ?? []).some((c) =>\n this.matchesFilter(table, row, c),\n );\n case \"not\":\n return f.child ? !this.matchesFilter(table, row, f.child) : true;\n case \"null\": {\n const val = f.expr\n ? evalExprNode(f.expr, row, (name) => this.getUdf(name)?.def.call)\n : row[f.colName!];\n const isNull = val === null || val === undefined;\n return f.isNull ? isNull : !isNull;\n }\n case \"in\": {\n const val = f.expr\n ? evalExprNode(f.expr, row, (name) => this.getUdf(name)?.def.call)\n : row[f.colName!];\n if (val === null || val === undefined) return false;\n const list = f.values ?? [];\n const found = list.some((item) => this.valuesEqual(val, item));\n return f.notIn ? !found : found;\n }\n case \"expr\": {\n if (!f.expr) return true;\n const val = evalExprNode(\n f.expr,\n row,\n (name) => this.getUdf(name)?.def.call,\n );\n return Boolean(val) && val !== 0;\n }\n case \"cmp\": {\n const left = f.expr\n ? evalExprNode(f.expr, row, (name) => this.getUdf(name)?.def.call)\n : row[f.colName!];\n const right = f.value;\n if (\n left === null ||\n left === undefined ||\n right === null ||\n right === undefined\n ) {\n return false;\n }\n const op = String(f.op ?? \"=\")\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, \" \");\n switch (op) {\n case \"=\":\n case \"==\":\n return this.valuesEqual(left, right);\n case \"!=\":\n case \"<>\":\n return !this.valuesEqual(left, right);\n case \"<\":\n return typeof left === \"string\" && typeof right === \"string\"\n ? left < right\n : Number(left) < Number(right);\n case \"<=\":\n return typeof left === \"string\" && typeof right === \"string\"\n ? left <= right\n : Number(left) <= Number(right);\n case \">\":\n return typeof left === \"string\" && typeof right === \"string\"\n ? left > right\n : Number(left) > Number(right);\n case \">=\":\n return typeof left === \"string\" && typeof right === \"string\"\n ? left >= right\n : Number(left) >= Number(right);\n case \"like\":\n return sql_like_match(String(left), String(right));\n case \"not like\":\n return !sql_like_match(String(left), String(right));\n case \"contains\":\n return String(left).includes(String(right));\n case \"starts_with\":\n return String(left).startsWith(String(right));\n case \"ends_with\":\n return String(left).endsWith(String(right));\n default:\n return this.valuesEqual(left, right);\n }\n }\n default:\n return true;\n }\n }\n\n private matchesFilters(\n table: TableMeta,\n row: DbRow,\n filters: QueryFilter[],\n ): boolean {\n for (const f of filters) {\n if (!this.matchesFilter(table, row, f)) return false;\n }\n return true;\n }\n\n /**\n * Deletes a sorted list of cell indices on `pageId` while maintaining exact\n * secondary index `rowid` pointers for both the deleted cells and any surviving\n * cells on `pageId` whose slot index shifts left.\n */\n private async deleteCellsOnDataPageAndShiftIndexes(\n table: TableMeta,\n indexes: IndexDescriptor[],\n pageId: number,\n deletedCellIndicesAsc: number[],\n allCellsOnPage: Array<{ cellIdx: number; row: DbRow }>,\n ): Promise<void> {\n if (deletedCellIndicesAsc.length === 0) return;\n const deletedSet = new Set(deletedCellIndicesAsc);\n\n if (indexes.length > 0) {\n // 1. Remove index entries for all deleted cells at their original cellIdx\n for (const delIdx of deletedCellIndicesAsc) {\n const entry = allCellsOnPage[delIdx];\n if (!entry) continue;\n const oldRowid = (BigInt(pageId) << 16n) | BigInt(delIdx);\n for (const idx of indexes) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n entry.row,\n );\n if (keyVal !== undefined && keyVal !== null) {\n await this.deleteFromIndex(\n idx.rootPageId,\n keyType,\n keyVal,\n oldRowid,\n );\n }\n }\n }\n\n // 2. Shift index entries for surviving cells whose slot index moves left\n let newCellIdx = 0;\n for (let origIdx = 0; origIdx < allCellsOnPage.length; origIdx++) {\n if (deletedSet.has(origIdx)) continue;\n if (newCellIdx !== origIdx) {\n const survivingRow = allCellsOnPage[origIdx].row;\n const prevRowid = (BigInt(pageId) << 16n) | BigInt(origIdx);\n const shiftedRowid = (BigInt(pageId) << 16n) | BigInt(newCellIdx);\n for (const idx of indexes) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n survivingRow,\n );\n if (keyVal !== undefined && keyVal !== null) {\n await this.deleteFromIndex(\n idx.rootPageId,\n keyType,\n keyVal,\n prevRowid,\n );\n await this.insertIntoIndex(\n idx.rootPageId,\n keyType,\n keyVal,\n shiftedRowid,\n );\n }\n }\n }\n newCellIdx++;\n }\n }\n\n // 3. Delete target cells from the data page in descending order of slot index\n const slot = await this.driver.acquirePage(pageId);\n const view = this.pool.getSlotDataView(slot);\n for (let k = deletedCellIndicesAsc.length - 1; k >= 0; k--) {\n page_delete_row(view, 0, deletedCellIndicesAsc[k]);\n }\n this.pool.markDirty(slot);\n }\n\n private normalizeWhereOrPkFilters(\n table: TableMeta,\n whereOrPk: DbValue | Partial<DbRow>,\n ): QueryFilter[] {\n if (\n whereOrPk !== null &&\n typeof whereOrPk === \"object\" &&\n !(whereOrPk instanceof Uint8Array)\n ) {\n const filters: QueryFilter[] = [];\n for (const [colName, val] of Object.entries(whereOrPk)) {\n if (val === undefined) continue;\n if (val === null) {\n filters.push({ type: \"null\", colName, isNull: true });\n } else {\n filters.push({ type: \"cmp\", colName, op: \"=\", value: val });\n }\n }\n return filters;\n }\n\n const pkCol = table.columns.find(\n (c) => (c.flags & ColumnFlag.PRIMARY_KEY) !== 0,\n );\n if (!pkCol) {\n throw new Error(\n `Table \"${table.name}\" does not have a primary key column for scalar lookup`,\n );\n }\n return [{ type: \"cmp\", colName: pkCol.name, op: \"=\", value: whereOrPk }];\n }\n\n async insert(\n tableName: string,\n row: DbRow,\n options?: TransactionOptions,\n ): Promise<void> {\n await this.insertMany(tableName, [row], options);\n }\n\n async insertMany(\n tableName: string,\n rows: DbRow[],\n options?: TransactionOptions,\n ): Promise<void> {\n if (!rows || rows.length === 0) return;\n if (\n !this.coordinator.isInTransaction() &&\n this.beforeCommitHooks.size > 0\n ) {\n await this.transaction(async (tx) => {\n await tx._insertManyInternal(tableName, rows, true);\n }, options);\n return;\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const inTx = this.coordinator.isInTransaction();\n const recorded = await this._insertManyInternal(tableName, rows, true);\n if (!inTx && recorded.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n recorded,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n }, this.currentLeaseId ?? undefined);\n }\n\n private async _insertManyInternal(\n tableName: string,\n rows: DbRow[],\n trackChanges: boolean = true,\n ): Promise<MutationRecord[]> {\n if (!rows || rows.length === 0) return [];\n const table = await this._getTableInternal(tableName);\n const page1View = this.pool.getSlotDataView(0);\n const indexes = catalog_list_table_indexes(page1View, table.tableId);\n const uniqueIndexes = indexes.filter(\n (idx) => (idx.flags & (IndexFlag.UNIQUE | IndexFlag.PRIMARY)) !== 0,\n );\n\n const autoIncCol = table.columns.find(\n (c) => (c.flags & ColumnFlag.AUTO_INC) !== 0,\n );\n\n // Pass 1: Pre-validate all rows in the batch (NOT NULL, uniqueness, row serialization size)\n // before mutating any data pages, index pages, or auto-increment counters.\n const batchUniqueSets: Map<string, Set<any>> = new Map();\n for (const idx of uniqueIndexes) {\n batchUniqueSets.set(idx.name, new Set());\n }\n\n let tentativeAutoInc = table.autoIncNext;\n const preparedRows: Array<{\n row: DbRow;\n effectiveRow: DbRow;\n rowBytes: Uint8Array;\n assignedAutoInc?: number;\n }> = [];\n\n for (let rIdx = 0; rIdx < rows.length; rIdx++) {\n const origRow = rows[rIdx];\n\n // 1. Primary Key NOT NULL validation\n for (const c of table.columns) {\n if ((c.flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n if ((c.flags & ColumnFlag.AUTO_INC) === 0) {\n if (origRow[c.name] === undefined || origRow[c.name] === null) {\n throw new NotNullConstraintError(c.name, tableName);\n }\n }\n }\n }\n\n // 2. Tentative Auto-Inc calculation\n let assignedAutoInc: number | undefined;\n let effectiveRow: DbRow = {};\n for (const c of table.columns) {\n if (origRow[c.name] !== undefined) {\n effectiveRow[c.name] = origRow[c.name];\n } else {\n effectiveRow[c.name] = null;\n }\n }\n if (\n autoIncCol &&\n (origRow[autoIncCol.name] === undefined ||\n origRow[autoIncCol.name] === null)\n ) {\n assignedAutoInc = Number(tentativeAutoInc);\n tentativeAutoInc += 1n;\n effectiveRow[autoIncCol.name] = assignedAutoInc;\n }\n\n // 3. Uniqueness constraint probe (intra-batch and existing index pages)\n for (const idx of uniqueIndexes) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n effectiveRow,\n );\n if (keyVal !== undefined && keyVal !== null) {\n const setKey =\n keyVal instanceof Uint8Array\n ? Array.from(keyVal).join(\",\")\n : keyVal;\n const set = batchUniqueSets.get(idx.name)!;\n if (set.has(setKey)) {\n throw new UniqueConstraintViolationError(\n `Duplicate key value violates unique constraint \"${idx.name}\" on table \"${tableName}\"`,\n );\n }\n set.add(setKey);\n\n const duplicate = await this.probeIndexUnique(\n idx.rootPageId,\n keyType,\n keyVal,\n );\n if (duplicate) {\n throw new UniqueConstraintViolationError(\n `Duplicate key value violates unique constraint \"${idx.name}\" on table \"${tableName}\"`,\n );\n }\n }\n }\n\n // 4. Pre-serialize row (validates row size <= 2048 bytes before any page mutation)\n const rowBytes = page_serialize_row(table.columns, effectiveRow);\n preparedRows.push({\n row: origRow,\n effectiveRow,\n rowBytes,\n assignedAutoInc,\n });\n }\n\n // Commit tentative auto-inc after full batch validation succeeds\n table.autoIncNext = tentativeAutoInc;\n\n // Fast resolution of tail data page\n let currentPageId = this.tableTailPages.get(tableName) ?? table.rootPageId;\n let slot = await this.driver.acquirePage(currentPageId);\n let view = this.pool.getSlotDataView(slot);\n\n while (true) {\n const nextPageId = page_get_next_page_id(view, 0);\n if (nextPageId === 0) break;\n currentPageId = nextPageId;\n slot = await this.driver.acquirePage(currentPageId);\n view = this.pool.getSlotDataView(slot);\n }\n this.tableTailPages.set(tableName, currentPageId);\n\n const recordedChanges: MutationRecord[] = [];\n\n // Pass 2: Apply validated row insertions to data pages and secondary indexes\n for (let rIdx = 0; rIdx < preparedRows.length; rIdx++) {\n const { row, effectiveRow, rowBytes, assignedAutoInc } =\n preparedRows[rIdx];\n if (autoIncCol && assignedAutoInc !== undefined) {\n row[autoIncCol.name] = assignedAutoInc;\n }\n\n // 4. Data page insertion (re-acquire currentPageId in case index insertion evicted it)\n slot = await this.driver.acquirePage(currentPageId);\n view = this.pool.getSlotDataView(slot);\n let targetPageId = currentPageId;\n let insertSlot = page_insert_row(\n view,\n 0,\n rowBytes,\n this.pool.pageScratchpadOffset,\n );\n\n if (insertSlot === -1) {\n const prevSlot = slot;\n this.pool.pinSlot(prevSlot);\n try {\n const newPageId = await this.driver.allocateAndPinPage();\n const newSlot = this.pool.getResidentSlot(newPageId);\n try {\n page_set_next_page_id(view, 0, newPageId);\n this.pool.markDirty(prevSlot);\n\n const newView = this.pool.getSlotDataView(newSlot);\n insertSlot = page_insert_row(\n newView,\n 0,\n rowBytes,\n this.pool.pageScratchpadOffset,\n );\n if (insertSlot === -1) {\n throw new Error(\n \"Unexpected error: row does not fit in empty page\",\n );\n }\n this.pool.markDirty(newSlot);\n currentPageId = newPageId;\n targetPageId = newPageId;\n slot = newSlot;\n view = newView;\n this.tableTailPages.set(tableName, newPageId);\n } finally {\n this.pool.unpinSlot(newSlot);\n }\n } finally {\n this.pool.unpinSlot(prevSlot);\n }\n } else {\n this.pool.markDirty(slot);\n }\n\n // 5. Index insertion\n const rowid = (BigInt(targetPageId) << 16n) | BigInt(insertSlot);\n for (const idx of indexes) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n effectiveRow,\n );\n if (keyVal !== undefined && keyVal !== null) {\n await this.insertIntoIndex(idx.rootPageId, keyType, keyVal, rowid);\n }\n }\n\n if (trackChanges) {\n const rec: MutationRecord = {\n table: table.name,\n op: \"insert\",\n pk: this.extractPrimaryKey(table, effectiveRow),\n newRow: this.cloneRow(effectiveRow),\n };\n recordedChanges.push(rec);\n if (this.coordinator.isInTransaction()) {\n this.activeTxChanges.push(rec);\n }\n }\n }\n\n // 6. Update Page 1 table descriptor once for the batch\n const slotIdx = catalog_find_table_slot(page1View, tableName);\n if (slotIdx !== -1) {\n const desc = catalog_read_table_descriptor(page1View, slotIdx)!;\n desc.rowCountEstimate += rows.length;\n if (autoIncCol) {\n desc.autoIncNext = table.autoIncNext;\n }\n catalog_write_table_descriptor(page1View, slotIdx, desc);\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n }\n\n // 7. Flush once for the whole batch if autocommit (not in transaction)\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return recordedChanges;\n }\n\n async update(\n tableName: string,\n whereOrPk: DbValue | Partial<DbRow>,\n patch: Partial<DbRow>,\n options?: TransactionOptions,\n ): Promise<number> {\n if (\n !this.coordinator.isInTransaction() &&\n this.beforeCommitHooks.size > 0\n ) {\n return this.transaction(\n (tx) => tx.update(tableName, whereOrPk, patch, options),\n options,\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const table = await this._getTableInternal(tableName);\n const filters = this.normalizeWhereOrPkFilters(table, whereOrPk);\n const inTx = this.coordinator.isInTransaction();\n const { count, changes } = await this._executeUpdateInternal(\n tableName,\n filters,\n patch,\n );\n if (!inTx && changes.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n changes,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n return count;\n }, this.currentLeaseId ?? undefined);\n }\n\n async executeUpdate(\n tableName: string,\n filters: QueryFilter[],\n patch: Partial<DbRow>,\n options?: TransactionOptions,\n ): Promise<number> {\n if (\n !this.coordinator.isInTransaction() &&\n this.beforeCommitHooks.size > 0\n ) {\n return this.transaction(\n (tx) => tx.executeUpdate(tableName, filters, patch, options),\n options,\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const inTx = this.coordinator.isInTransaction();\n const { count, changes } = await this._executeUpdateInternal(\n tableName,\n filters,\n patch,\n );\n if (!inTx && changes.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n changes,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n return count;\n }, this.currentLeaseId ?? undefined);\n }\n\n private async _executeUpdateInternal(\n tableName: string,\n filters: QueryFilter[],\n patch: Partial<DbRow>,\n ): Promise<{ count: number; changes: MutationRecord[] }> {\n const table = await this._getTableInternal(tableName);\n this.validateFilterColumns(table, filters);\n\n const validColMap = new Map(table.columns.map((c) => [c.name, c]));\n for (const k of Object.keys(patch)) {\n if (!validColMap.has(k)) {\n throw new ColumnNotFoundError(k, tableName);\n }\n }\n\n const page1View = this.pool.getSlotDataView(0);\n const indexes = catalog_list_table_indexes(page1View, table.tableId);\n const uniqueIndexes = indexes.filter(\n (idx) => (idx.flags & (IndexFlag.UNIQUE | IndexFlag.PRIMARY)) !== 0,\n );\n\n interface PageCellsSnapshot {\n pageId: number;\n allCells: Array<{ cellIdx: number; row: DbRow }>;\n matches: Array<{\n cellIdx: number;\n oldRow: DbRow;\n newRow: DbRow;\n changedColumns: string[];\n newRowBytes: Uint8Array;\n }>;\n }\n\n const pageSnapshots: PageCellsSnapshot[] = [];\n const updatingRowids = new Set<bigint>();\n let totalMatched = 0;\n\n // Pass 1: Scan pages, identify matching rows, build newRow, validate NOT NULL & row size\n let currPageId = table.rootPageId;\n while (currPageId !== 0) {\n const slot = await this.driver.acquirePage(currPageId);\n const view = this.pool.getSlotDataView(slot);\n const cellCount = page_get_cell_count(view, 0);\n const nextPageId = page_get_next_page_id(view, 0);\n\n const allCells: Array<{ cellIdx: number; row: DbRow }> = [];\n const matches: PageCellsSnapshot[\"matches\"] = [];\n\n for (let i = 0; i < cellCount; i++) {\n const off = page_get_cell_offset(view, 0, i);\n const row = page_deserialize_row(table.columns, view, off);\n allCells.push({ cellIdx: i, row });\n\n if (this.matchesFilters(table, row, filters)) {\n const newRow: DbRow = { ...row };\n for (const [k, v] of Object.entries(patch)) {\n if (v !== undefined) {\n newRow[k] = v;\n }\n }\n\n // Primary Key NOT NULL check\n for (const c of table.columns) {\n if ((c.flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n if (newRow[c.name] === null || newRow[c.name] === undefined) {\n throw new NotNullConstraintError(c.name, tableName);\n }\n }\n }\n\n const changedColumns = table.columns\n .map((c) => c.name)\n .filter((col) => !this.valuesEqual(row[col], newRow[col]));\n const newRowBytes = page_serialize_row(table.columns, newRow);\n\n matches.push({\n cellIdx: i,\n oldRow: row,\n newRow,\n changedColumns,\n newRowBytes,\n });\n updatingRowids.add((BigInt(currPageId) << 16n) | BigInt(i));\n totalMatched++;\n }\n }\n\n if (matches.length > 0) {\n pageSnapshots.push({ pageId: currPageId, allCells, matches });\n }\n currPageId = nextPageId;\n }\n\n if (totalMatched === 0) {\n return { count: 0, changes: [] };\n }\n\n // Pass 2: Validate UNIQUE constraints across all matched rows before mutating any page\n for (const idx of uniqueIndexes) {\n const batchSeenKeys = new Set<any>();\n for (const ps of pageSnapshots) {\n for (const m of ps.matches) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n m.newRow,\n );\n if (keyVal !== undefined && keyVal !== null) {\n const setKey =\n keyVal instanceof Uint8Array\n ? Array.from(keyVal).join(\",\")\n : keyVal;\n if (batchSeenKeys.has(setKey)) {\n throw new UniqueConstraintViolationError(\n `Duplicate key value violates unique constraint \"${idx.name}\" on table \"${tableName}\"`,\n );\n }\n batchSeenKeys.add(setKey);\n\n const conflict = await this.probeIndexUnique(\n idx.rootPageId,\n keyType,\n keyVal,\n updatingRowids,\n );\n if (conflict) {\n throw new UniqueConstraintViolationError(\n `Duplicate key value violates unique constraint \"${idx.name}\" on table \"${tableName}\"`,\n );\n }\n }\n }\n }\n }\n\n // Pass 3: Apply updates (in-place when fitting on page, or delete + tail-insert on page overflow)\n const recordedChanges: MutationRecord[] = [];\n const overflowUpdates: Array<{\n oldRow: DbRow;\n newRow: DbRow;\n changedColumns: string[];\n newRowBytes: Uint8Array;\n }> = [];\n\n for (const ps of pageSnapshots) {\n const overflowIndicesOnPage: number[] = [];\n\n for (const m of ps.matches) {\n const slot = await this.driver.acquirePage(ps.pageId);\n const view = this.pool.getSlotDataView(slot);\n const res = page_update_row(\n view,\n 0,\n m.cellIdx,\n m.newRowBytes,\n this.pool.pageScratchpadOffset,\n );\n\n if (res) {\n this.pool.markDirty(slot);\n ps.allCells[m.cellIdx].row = m.newRow;\n\n const rowid = (BigInt(ps.pageId) << 16n) | BigInt(m.cellIdx);\n for (const idx of indexes) {\n const oldKey = this.extractIndexKey(table.columns, idx, m.oldRow);\n const newKey = this.extractIndexKey(table.columns, idx, m.newRow);\n if (!this.valuesEqual(oldKey.keyVal, newKey.keyVal)) {\n if (oldKey.keyVal !== undefined && oldKey.keyVal !== null) {\n await this.deleteFromIndex(\n idx.rootPageId,\n oldKey.keyType,\n oldKey.keyVal,\n rowid,\n );\n }\n if (newKey.keyVal !== undefined && newKey.keyVal !== null) {\n await this.insertIntoIndex(\n idx.rootPageId,\n newKey.keyType,\n newKey.keyVal,\n rowid,\n );\n }\n }\n }\n\n const rec: MutationRecord = {\n table: table.name,\n op: \"update\",\n pk: this.extractPrimaryKey(table, m.newRow),\n oldRow: this.cloneRow(m.oldRow),\n newRow: this.cloneRow(m.newRow),\n changedColumns: m.changedColumns,\n };\n recordedChanges.push(rec);\n if (this.coordinator.isInTransaction()) {\n this.activeTxChanges.push(rec);\n }\n } else {\n overflowIndicesOnPage.push(m.cellIdx);\n overflowUpdates.push(m);\n }\n }\n\n if (overflowIndicesOnPage.length > 0) {\n await this.deleteCellsOnDataPageAndShiftIndexes(\n table,\n indexes,\n ps.pageId,\n overflowIndicesOnPage,\n ps.allCells,\n );\n }\n }\n\n // Re-insert any overflowed rows onto the table's tail page\n if (overflowUpdates.length > 0) {\n let currentPageId =\n this.tableTailPages.get(tableName) ?? table.rootPageId;\n let slot = await this.driver.acquirePage(currentPageId);\n let view = this.pool.getSlotDataView(slot);\n while (true) {\n const nextPageId = page_get_next_page_id(view, 0);\n if (nextPageId === 0) break;\n currentPageId = nextPageId;\n slot = await this.driver.acquirePage(currentPageId);\n view = this.pool.getSlotDataView(slot);\n }\n this.tableTailPages.set(tableName, currentPageId);\n\n for (const m of overflowUpdates) {\n slot = await this.driver.acquirePage(currentPageId);\n view = this.pool.getSlotDataView(slot);\n let targetPageId = currentPageId;\n let insertSlot = page_insert_row(\n view,\n 0,\n m.newRowBytes,\n this.pool.pageScratchpadOffset,\n );\n\n if (insertSlot === -1) {\n const prevSlot = slot;\n this.pool.pinSlot(prevSlot);\n try {\n const newPageId = await this.driver.allocateAndPinPage();\n const newSlot = this.pool.getResidentSlot(newPageId);\n try {\n page_set_next_page_id(view, 0, newPageId);\n this.pool.markDirty(prevSlot);\n\n const newView = this.pool.getSlotDataView(newSlot);\n insertSlot = page_insert_row(\n newView,\n 0,\n m.newRowBytes,\n this.pool.pageScratchpadOffset,\n );\n this.pool.markDirty(newSlot);\n currentPageId = newPageId;\n targetPageId = newPageId;\n this.tableTailPages.set(tableName, newPageId);\n } finally {\n this.pool.unpinSlot(newSlot);\n }\n } finally {\n this.pool.unpinSlot(prevSlot);\n }\n } else {\n this.pool.markDirty(slot);\n }\n\n const newRowid = (BigInt(targetPageId) << 16n) | BigInt(insertSlot);\n for (const idx of indexes) {\n const { keyVal, keyType } = this.extractIndexKey(\n table.columns,\n idx,\n m.newRow,\n );\n if (keyVal !== undefined && keyVal !== null) {\n await this.insertIntoIndex(\n idx.rootPageId,\n keyType,\n keyVal,\n newRowid,\n );\n }\n }\n\n const rec: MutationRecord = {\n table: table.name,\n op: \"update\",\n pk: this.extractPrimaryKey(table, m.newRow),\n oldRow: this.cloneRow(m.oldRow),\n newRow: this.cloneRow(m.newRow),\n changedColumns: m.changedColumns,\n };\n recordedChanges.push(rec);\n if (this.coordinator.isInTransaction()) {\n this.activeTxChanges.push(rec);\n }\n }\n }\n\n // Update Page 1 change counter\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return { count: totalMatched, changes: recordedChanges };\n }\n\n async delete(\n tableName: string,\n whereOrPk: DbValue | Partial<DbRow>,\n options?: TransactionOptions,\n ): Promise<number> {\n if (\n !this.coordinator.isInTransaction() &&\n this.beforeCommitHooks.size > 0\n ) {\n return this.transaction(\n (tx) => tx.delete(tableName, whereOrPk, options),\n options,\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const table = await this._getTableInternal(tableName);\n const filters = this.normalizeWhereOrPkFilters(table, whereOrPk);\n const inTx = this.coordinator.isInTransaction();\n const { count, changes } = await this._executeDeleteInternal(\n tableName,\n filters,\n );\n if (!inTx && changes.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n changes,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n return count;\n }, this.currentLeaseId ?? undefined);\n }\n\n async executeDelete(\n tableName: string,\n filters: QueryFilter[],\n options?: TransactionOptions,\n ): Promise<number> {\n if (\n !this.coordinator.isInTransaction() &&\n this.beforeCommitHooks.size > 0\n ) {\n return this.transaction(\n (tx) => tx.executeDelete(tableName, filters, options),\n options,\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const inTx = this.coordinator.isInTransaction();\n const { count, changes } = await this._executeDeleteInternal(\n tableName,\n filters,\n );\n if (!inTx && changes.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n changes,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n return count;\n }, this.currentLeaseId ?? undefined);\n }\n\n private async _executeDeleteInternal(\n tableName: string,\n filters: QueryFilter[],\n ): Promise<{ count: number; changes: MutationRecord[] }> {\n const table = await this._getTableInternal(tableName);\n this.validateFilterColumns(table, filters);\n\n const page1View = this.pool.getSlotDataView(0);\n const indexes = catalog_list_table_indexes(page1View, table.tableId);\n\n const recordedChanges: MutationRecord[] = [];\n let totalDeleted = 0;\n\n let currPageId = table.rootPageId;\n while (currPageId !== 0) {\n const slot = await this.driver.acquirePage(currPageId);\n const view = this.pool.getSlotDataView(slot);\n const cellCount = page_get_cell_count(view, 0);\n const nextPageId = page_get_next_page_id(view, 0);\n\n if (cellCount > 0) {\n const allCells: Array<{ cellIdx: number; row: DbRow }> = [];\n const deletedIndices: number[] = [];\n\n for (let i = 0; i < cellCount; i++) {\n const off = page_get_cell_offset(view, 0, i);\n const row = page_deserialize_row(table.columns, view, off);\n allCells.push({ cellIdx: i, row });\n\n if (this.matchesFilters(table, row, filters)) {\n deletedIndices.push(i);\n const rec: MutationRecord = {\n table: table.name,\n op: \"delete\",\n pk: this.extractPrimaryKey(table, row),\n oldRow: this.cloneRow(row),\n };\n recordedChanges.push(rec);\n if (this.coordinator.isInTransaction()) {\n this.activeTxChanges.push(rec);\n }\n }\n }\n\n if (deletedIndices.length > 0) {\n totalDeleted += deletedIndices.length;\n await this.deleteCellsOnDataPageAndShiftIndexes(\n table,\n indexes,\n currPageId,\n deletedIndices,\n allCells,\n );\n }\n }\n\n currPageId = nextPageId;\n }\n\n if (totalDeleted === 0) {\n return { count: 0, changes: [] };\n }\n\n const slotIdx = catalog_find_table_slot(page1View, tableName);\n if (slotIdx !== -1) {\n const desc = catalog_read_table_descriptor(page1View, slotIdx)!;\n desc.rowCountEstimate = Math.max(0, desc.rowCountEstimate - totalDeleted);\n catalog_write_table_descriptor(page1View, slotIdx, desc);\n }\n catalog_increment_change_counter(page1View);\n catalog_update_page1_checksum(page1View);\n this.pool.markDirty(0);\n\n if (!this.coordinator.isInTransaction()) {\n await this.driver.flushAllDirty();\n }\n\n return { count: totalDeleted, changes: recordedChanges };\n }\n\n async upsert(\n tableName: string,\n row: DbRow,\n options?: UpsertOptions,\n ): Promise<\"inserted\" | \"updated\" | \"ignored\"> {\n const res = await this.upsertMany(tableName, [row], options);\n if (res.inserted > 0) return \"inserted\";\n if (res.updated > 0) return \"updated\";\n return \"ignored\";\n }\n\n async upsertMany(\n tableName: string,\n rows: DbRow[],\n options?: UpsertOptions,\n ): Promise<{ inserted: number; updated: number; ignored: number }> {\n if (!rows || rows.length === 0) {\n return { inserted: 0, updated: 0, ignored: 0 };\n }\n\n if (\n !this.coordinator.isInTransaction() &&\n (this.beforeCommitHooks.size > 0 || rows.length > 1)\n ) {\n return this.transaction(\n (tx) => tx._upsertManyInLease(tableName, rows, options),\n options,\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const inTx = this.coordinator.isInTransaction();\n const startChanges: MutationRecord[] = [];\n const res = await this._upsertManyInLease(\n tableName,\n rows,\n options,\n inTx ? undefined : startChanges,\n );\n if (!inTx && startChanges.length > 0) {\n const changeset = this.buildChangeset(\n this.nextAutoTxId++,\n options?.origin ?? \"local\",\n options?.meta,\n startChanges,\n );\n this.emitCommitAndSubscriptions(changeset);\n }\n return res;\n }, this.currentLeaseId ?? undefined);\n }\n\n private async _upsertManyInLease(\n tableName: string,\n rows: DbRow[],\n options?: UpsertOptions,\n standaloneCollector?: MutationRecord[],\n ): Promise<{ inserted: number; updated: number; ignored: number }> {\n const table = await this._getTableInternal(tableName);\n const validCols = new Set(table.columns.map((c) => c.name));\n\n let conflictCols: string[];\n if (options?.conflictTarget) {\n conflictCols = Array.isArray(options.conflictTarget)\n ? options.conflictTarget\n : [options.conflictTarget];\n for (const col of conflictCols) {\n if (!validCols.has(col)) {\n throw new ColumnNotFoundError(col, tableName);\n }\n }\n } else {\n conflictCols = table.columns\n .filter((c) => (c.flags & ColumnFlag.PRIMARY_KEY) !== 0)\n .map((c) => c.name);\n if (conflictCols.length === 0) {\n throw new Error(\n `Cannot upsert on table \"${tableName}\" without a primary key or explicit conflictTarget`,\n );\n }\n }\n\n const mode = options?.mode ?? \"merge\";\n let inserted = 0;\n let updated = 0;\n let ignored = 0;\n\n for (const row of rows) {\n for (const k of Object.keys(row)) {\n if (!validCols.has(k)) {\n throw new ColumnNotFoundError(k, tableName);\n }\n }\n\n const hasAllConflictKeys = conflictCols.every(\n (c) => row[c] !== undefined && row[c] !== null,\n );\n\n let existingRow: DbRow | null = null;\n let conflictFilters: QueryFilter[] = [];\n\n if (hasAllConflictKeys) {\n conflictFilters = conflictCols.map((colName) => ({\n type: \"cmp\" as const,\n colName,\n op: \"=\" as const,\n value: row[colName],\n }));\n existingRow = await this.findFirstMatchingRow(table, conflictFilters);\n }\n\n if (!existingRow) {\n const insChanges = await this._insertManyInternal(\n tableName,\n [row],\n true,\n );\n if (standaloneCollector) {\n standaloneCollector.push(...insChanges);\n }\n inserted++;\n } else {\n if (mode === \"ignore\") {\n ignored++;\n continue;\n }\n if (options?.where) {\n const shouldUpdate = options.where(\n this.cloneRow(existingRow),\n this.cloneRow(row),\n );\n if (!shouldUpdate) {\n ignored++;\n continue;\n }\n }\n\n const patch: Partial<DbRow> = {};\n if (mode === \"replace\") {\n for (const c of table.columns) {\n if (row[c.name] !== undefined) {\n patch[c.name] = row[c.name];\n } else if ((c.flags & ColumnFlag.PRIMARY_KEY) !== 0) {\n patch[c.name] = existingRow[c.name];\n } else {\n patch[c.name] = null;\n }\n }\n } else {\n for (const [k, v] of Object.entries(row)) {\n if (v !== undefined) {\n patch[k] = v;\n }\n }\n }\n\n const { changes: updChanges } = await this._executeUpdateInternal(\n tableName,\n conflictFilters,\n patch,\n );\n if (standaloneCollector) {\n standaloneCollector.push(...updChanges);\n }\n updated++;\n }\n }\n\n return { inserted, updated, ignored };\n }\n\n private async findFirstMatchingRow(\n table: TableMeta,\n filters: QueryFilter[],\n ): Promise<DbRow | null> {\n let currPageId = table.rootPageId;\n while (currPageId !== 0) {\n const slot = await this.driver.acquirePage(currPageId);\n const view = this.pool.getSlotDataView(slot);\n const cellCount = page_get_cell_count(view, 0);\n const nextPageId = page_get_next_page_id(view, 0);\n\n for (let i = 0; i < cellCount; i++) {\n const off = page_get_cell_offset(view, 0, i);\n const row = page_deserialize_row(table.columns, view, off);\n if (this.matchesFilters(table, row, filters)) {\n return row;\n }\n }\n currPageId = nextPageId;\n }\n return null;\n }\n\n async transaction<T>(\n callback: (tx: WebDB) => Promise<T>,\n options?: TransactionOptions,\n ): Promise<T> {\n const lease = await this.coordinator.begin();\n const leaseId = lease.leaseId;\n this.activeTxChanges = [];\n this.activeTxOrigin = options?.origin ?? \"local\";\n this.activeTxMeta = options?.meta;\n this.activeTxId = lease.txId;\n\n const txProxy: WebDB = new Proxy(this, {\n get: (target, prop, receiver) => {\n if (prop === \"currentLeaseId\") {\n return leaseId;\n }\n if (prop === \"transaction\") {\n return async <U>(\n cb: (nestedTx: WebDB) => Promise<U>,\n _nestedOpts?: TransactionOptions,\n ): Promise<U> => {\n const savepoint = await this.coordinator.captureSavepoint();\n const savedChangesLen = this.activeTxChanges.length;\n try {\n return await cb(txProxy);\n } catch (err) {\n this.activeTxChanges.length = savedChangesLen;\n this.tableMetaCache.clear();\n this.tableTailPages.clear();\n this.indexTailPages.clear();\n await this.coordinator.restoreSavepoint(savepoint);\n throw err;\n }\n };\n }\n if (prop === \"checkpoint\") {\n return () => this.checkpoint();\n }\n if (prop === \"from\") {\n return (tableName: string) => {\n const qb = new QueryBuilder(txProxy, tableName);\n if (target.planner) {\n qb.withPlanner(target.planner);\n }\n return qb;\n };\n }\n const val = Reflect.get(target, prop, receiver);\n if (typeof val === \"function\") {\n return val.bind(txProxy);\n }\n return val;\n },\n });\n\n try {\n const res = await callback(txProxy);\n\n if (\n this.activeTxChanges.length > 0 &&\n this.beforeCommitHooks.size > 0 &&\n !this.isRunningBeforeCommit\n ) {\n const preCommitChangeset = this.buildChangeset(\n this.activeTxId,\n this.activeTxOrigin,\n this.activeTxMeta,\n [...this.activeTxChanges],\n );\n this.isRunningBeforeCommit = true;\n try {\n for (const hook of this.beforeCommitHooks) {\n await hook(preCommitChangeset, txProxy);\n }\n } finally {\n this.isRunningBeforeCommit = false;\n }\n }\n\n const finalChanges = [...this.activeTxChanges];\n const finalOrigin = this.activeTxOrigin;\n const finalMeta = this.activeTxMeta;\n const finalTxId = this.activeTxId;\n\n this.activeTxChanges = [];\n this.activeTxOrigin = \"local\";\n this.activeTxMeta = undefined;\n\n await this.coordinator.commit(leaseId);\n\n if (finalChanges.length > 0) {\n const committedChangeset = this.buildChangeset(\n finalTxId,\n finalOrigin,\n finalMeta,\n finalChanges,\n );\n this.emitCommitAndSubscriptions(committedChangeset);\n }\n\n return res;\n } catch (err) {\n this.activeTxChanges = [];\n this.activeTxOrigin = \"local\";\n this.activeTxMeta = undefined;\n this.isRunningBeforeCommit = false;\n // Clear caches so rollback doesn't leave stale cached table pointers\n this.tableMetaCache.clear();\n this.tableTailPages.clear();\n this.indexTailPages.clear();\n await this.coordinator.rollback(leaseId);\n throw err;\n }\n }\n\n registerFunction(\n name: string,\n def: UdfDefinition | ((...args: any[]) => any),\n ): this {\n const normName = name.toLowerCase();\n const fnDef: UdfDefinition =\n typeof def === \"function\" ? { call: def } : { ...def };\n\n if (!fnDef.returnType) {\n try {\n const sample = fnDef.call(1, 1, 1, 1, 1);\n if (typeof sample === \"number\") {\n fnDef.returnType = Number.isInteger(sample)\n ? DataType.INT32\n : DataType.FLOAT64;\n } else if (typeof sample === \"string\") {\n fnDef.returnType = DataType.TEXT;\n }\n } catch {\n try {\n const sample = fnDef.call(\"\", \"\", \"\", \"\", \"\");\n if (typeof sample === \"number\") {\n fnDef.returnType = Number.isInteger(sample)\n ? DataType.INT32\n : DataType.FLOAT64;\n } else if (typeof sample === \"string\") {\n fnDef.returnType = DataType.TEXT;\n }\n } catch {\n // Fall back if probing fails\n }\n }\n }\n\n let entry = this.udfs.get(normName);\n if (!entry) {\n entry = { id: this.nextUdfId++, def: fnDef };\n this.udfs.set(normName, entry);\n } else {\n entry.def = fnDef;\n }\n return this;\n }\n\n getUdf(name: string): { id: number; def: UdfDefinition } | undefined {\n return this.udfs.get(name.toLowerCase());\n }\n\n getUdfMap(): Map<string, number> {\n const map = new Map<string, number>();\n for (const [name, entry] of this.udfs.entries()) {\n map.set(name, entry.id);\n }\n return map;\n }\n\n getUdfDefs(): Map<string, UdfDefinition> {\n const map = new Map<string, UdfDefinition>();\n for (const [name, entry] of this.udfs.entries()) {\n map.set(name, entry.def);\n }\n return map;\n }\n\n from(tableName: string): QueryBuilder {\n return new QueryBuilder(this, tableName);\n }\n\n async explainQuery(\n tableName: string,\n filters: QueryFilter[],\n options?: {\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n select?: any;\n selectExprs?: ParsedSelectExpr[];\n joins?: JoinClause[];\n limit?: number;\n offset?: number;\n planner?: QueryPlanner;\n },\n ): Promise<ExplainOutput> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._explainQueryInternal(tableName, filters, options),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _explainQueryInternal(\n tableName: string,\n filters: QueryFilter[],\n options?: {\n orderBy?: SortKey[];\n groupBy?: (string | GroupKey)[];\n aggregates?: AggExpr[];\n having?: QueryFilter[];\n select?: any;\n selectExprs?: ParsedSelectExpr[];\n joins?: JoinClause[];\n limit?: number;\n offset?: number;\n planner?: QueryPlanner;\n },\n ): Promise<ExplainOutput> {\n const table = await this._getTableInternal(tableName);\n\n const joinPlans: JoinPlan[] = [];\n if (options?.joins && options.joins.length > 0) {\n if (1 + options.joins.length > 16) {\n throw new TooManyCursorsError(1 + options.joins.length, 16);\n }\n for (let i = 0; i < options.joins.length; i++) {\n const j = options.joins[i];\n const joinedTable = await this._getTableInternal(j.table);\n joinPlans.push({\n type: j.type,\n table: joinedTable,\n cursor: i + 1,\n leftCol: j.leftCol,\n op: j.op,\n rightCol: j.rightCol,\n });\n }\n }\n\n const bytecode = compileQuery({\n table,\n joinedTables: joinPlans.length > 0 ? joinPlans : undefined,\n filters,\n orderBy: options?.orderBy,\n groupBy: options?.groupBy,\n aggregates: options?.aggregates,\n having: options?.having,\n selectExprs: options?.selectExprs,\n udfNameMap: this.getUdfMap(),\n udfDefs: this.getUdfDefs(),\n limit: options?.limit,\n offset: options?.offset,\n planner: options?.planner ?? this.planner,\n });\n const executionTables: TableMeta[] =\n (bytecode as any).allTables ??\n (joinPlans.length > 0\n ? [table, ...joinPlans.map((j) => j.table)]\n : [table]);\n const drivingTable = executionTables[0];\n const instructions = disassembleBytecode(bytecode, drivingTable);\n const assembly = formatDisassembly(instructions);\n const indexScan =\n (bytecode as any).indexScan ?? (bytecode as any).table0Scan;\n const scanType = indexScan ? \"IndexScan\" : \"TableScan\";\n const indexName = indexScan ? indexScan.index.name : undefined;\n const joinedTableScans = (bytecode as any).joinedTableScans as\n | {\n tableIndex: number;\n tableName: string;\n scanType: \"IndexScan\" | \"TableScan\";\n indexName?: string;\n }[]\n | undefined;\n\n const decoratedJoins = options?.joins?.map((j) => {\n const scanInfo = joinedTableScans?.find(\n (s) => s.tableName.toLowerCase() === j.table.toLowerCase(),\n );\n if (scanInfo && scanInfo.scanType === \"IndexScan\") {\n return {\n ...j,\n scanType: scanInfo.scanType,\n indexName: scanInfo.indexName,\n };\n }\n return j;\n });\n\n return {\n plan: {\n table: drivingTable.name,\n rootPageId: drivingTable.rootPageId,\n scanType,\n indexName,\n filters,\n orderBy: options?.orderBy,\n groupBy: options?.groupBy,\n aggregates: options?.aggregates,\n having: options?.having,\n select: options?.select,\n joins: decoratedJoins,\n limit: options?.limit,\n offset: options?.offset,\n estimatedCost: (bytecode as any).estimatedCost,\n estimatedRows: (bytecode as any).estimatedRows,\n joinOrder: (bytecode as any).joinOrder,\n isOrderSatisfied:\n (bytecode as any).isOrderSatisfied ??\n (bytecode as any).planMetrics?.isOrderSatisfied ??\n false,\n sortCostAvoided:\n (bytecode as any).planMetrics?.sortCostAvoided ?? undefined,\n },\n bytecodeSize: bytecode.byteLength,\n instructions,\n assembly,\n };\n }\n\n async executeQuery(\n tableName: string,\n filters: QueryFilter[],\n options: QueryExecutionOptions,\n ): Promise<DbRow[]> {\n return this.coordinator.leaseQueue.enqueue(\n () => this._executeQueryInternal(tableName, filters, options),\n this.currentLeaseId ?? undefined,\n );\n }\n\n private async _executeQueryInternal(\n tableName: string,\n filters: QueryFilter[],\n options: QueryExecutionOptions,\n ): Promise<DbRow[]> {\n const table = await this._getTableInternal(tableName);\n\n const joinedTablesMeta: TableMeta[] = [];\n const joinPlans: JoinPlan[] = [];\n if (options.joins && options.joins.length > 0) {\n if (1 + options.joins.length > 16) {\n throw new TooManyCursorsError(1 + options.joins.length, 16);\n }\n for (let i = 0; i < options.joins.length; i++) {\n const j = options.joins[i];\n const joinedTable = await this._getTableInternal(j.table);\n joinedTablesMeta.push(joinedTable);\n joinPlans.push({\n type: j.type,\n table: joinedTable,\n cursor: i + 1,\n leftCol: j.leftCol,\n op: j.op,\n rightCol: j.rightCol,\n });\n }\n }\n\n // Pre-load all data pages and index pages for all tables into buffer pool before running VM\n for (const t of [table, ...joinedTablesMeta]) {\n let currPageId = t.rootPageId;\n while (currPageId !== 0) {\n const slot = await this.driver.acquirePage(currPageId);\n const view = this.pool.getSlotDataView(slot);\n currPageId = page_get_next_page_id(view, 0);\n }\n for (const idx of t.indexes ?? []) {\n let idxPageId = idx.rootPageId;\n while (idxPageId !== 0) {\n const slot = await this.driver.acquirePage(idxPageId);\n const view = this.pool.getSlotDataView(slot);\n idxPageId = page_get_next_page_id(view, 0);\n }\n }\n }\n\n let orderBy = options.orderBy;\n if (!orderBy && options.sortCol) {\n orderBy = [{ colName: options.sortCol, direction: options.sortDir }];\n }\n\n const plan: QueryPlan = {\n table,\n joinedTables: joinPlans.length > 0 ? joinPlans : undefined,\n filters,\n orderBy,\n groupBy: options.groupBy,\n aggregates: options.aggregates,\n having: options.having,\n selectExprs: options.selectExprs,\n udfNameMap: this.getUdfMap(),\n udfDefs: this.getUdfDefs(),\n limit: options.limit !== null ? options.limit : undefined,\n offset: options.offset !== null ? options.offset : undefined,\n planner: options.planner ?? this.planner,\n };\n\n const bytecode = compileQuery(plan);\n\n const executionTables: TableMeta[] = (bytecode as any).allTables ?? [\n table,\n ...joinedTablesMeta,\n ];\n\n resetVmContext(this.vmCtx, executionTables[0], executionTables);\n if ((bytecode as any).inSets) {\n this.vmCtx.inSets = (bytecode as any).inSets;\n }\n const keyInfos = (bytecode as any).keyInfos ?? plan.keyInfos;\n if (keyInfos) {\n this.vmCtx.keyInfos = keyInfos;\n }\n\n const udfsRecord: Record<number, (...args: any[]) => any> = {};\n for (const entry of this.udfs.values()) {\n udfsRecord[entry.id] = entry.def.call;\n }\n this.vmCtx.udfs = udfsRecord;\n\n // Determine output columns for page_deserialize_row\n let outputColumns =\n (bytecode as any).outputColumns ?? plan.outputColumns ?? table.columns;\n if (\n (plan.aggregates && plan.aggregates.length > 0) ||\n (plan.groupBy && plan.groupBy.length > 0)\n ) {\n if ((bytecode as any).outputColumns) {\n outputColumns = (bytecode as any).outputColumns;\n } else {\n outputColumns = [];\n const groupByCols = plan.groupBy ?? [];\n for (const gItem of groupByCols) {\n const gColName =\n typeof gItem === \"string\"\n ? gItem\n : (gItem.colName ??\n (gItem.expr ? deriveDefaultAlias(gItem.expr) : \"group_key\"));\n const col = table.columns.find((c) => c.name === gColName);\n if (col) {\n outputColumns.push(col);\n } else {\n outputColumns.push({\n name: gColName,\n type: DataType.TEXT,\n flags: ColumnFlag.NONE,\n colOffset: 0,\n });\n }\n }\n for (let j = 0; j < (plan.aggregates?.length ?? 0); j++) {\n const agg = plan.aggregates![j];\n const aggName =\n agg.alias ??\n (agg.colName ? `${agg.func}_${agg.colName}` : agg.func);\n const aggType =\n agg.func === \"count\" ? DataType.INT32 : DataType.FLOAT64;\n outputColumns.push({\n name: aggName,\n type: aggType,\n flags: ColumnFlag.NONE,\n colOffset: 0,\n });\n }\n }\n }\n\n this.vmCtx.outputColumns = outputColumns;\n\n const rows: DbRow[] = [];\n while (true) {\n const status = vm_step(this.vmCtx, this.pool.view, bytecode);\n\n // Hydrate rows from Output Result Buffer for current chunk\n let currentOffset = 0;\n for (let i = 0; i < this.vmCtx.resultCount; i++) {\n const rowLen = this.pool.view.getUint16(\n RESULT_BUFFER_OFFSET + currentOffset,\n true,\n );\n const rowRecordOffset = RESULT_BUFFER_OFFSET + currentOffset + 2;\n\n const record = page_deserialize_row(\n outputColumns,\n this.pool.view,\n rowRecordOffset,\n );\n rows.push(record);\n\n currentOffset += 2 + rowLen;\n }\n\n if (status === VmStatus.DONE) {\n break;\n } else if (status === VmStatus.BUFFER_FULL) {\n this.vmCtx.resultOffset = 0;\n this.vmCtx.resultCount = 0;\n this.vmCtx.status = VmStatus.RUNNING;\n } else if (status === VmStatus.PAGE_FAULT) {\n this.vmCtx.resultOffset = 0;\n this.vmCtx.resultCount = 0;\n // Temporarily pin any currently resident active cursor pages so acquiring fault_page_id\n // does not evict the page a cursor is actively transitioning from.\n const pinnedCursorSlots: number[] = [];\n const cursors = this.vmCtx.cursors ?? [this.vmCtx.cursor];\n for (const c of cursors) {\n if (c && c.pageId > 1) {\n const s = this.pool.getResidentSlot(c.pageId);\n if (s > 0) {\n this.pool.pinSlot(s);\n pinnedCursorSlots.push(s);\n }\n }\n }\n try {\n await this.driver.acquirePage(this.vmCtx.fault_page_id);\n } finally {\n for (const s of pinnedCursorSlots) {\n this.pool.unpinSlot(s);\n }\n }\n this.vmCtx.status = VmStatus.RUNNING;\n } else if (status === VmStatus.ARENA_EXHAUSTED) {\n this.vmCtx.arenaOffset = 0;\n throw new QueryArenaExhaustedError();\n } else if (status === VmStatus.TIMEOUT) {\n throw new QueryTimeoutError();\n } else if (status === VmStatus.INVALID_BYTECODE) {\n throw new InvalidBytecodeError();\n } else {\n throw new Error(`VM execution error: status=${status}`);\n }\n }\n\n Object.defineProperty(rows, \"isOrderSatisfied\", {\n value: (bytecode as any).isOrderSatisfied ?? false,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n return rows;\n }\n\n /**\n * Deduplicated Monotonic Checkpointing (Section 4.3):\n * Replays committed WAL frames and resident memory slots to main storage,\n * flushes main storage, and truncates WAL to 0.\n */\n async checkpoint(): Promise<{ pagesWritten: number }> {\n return this.coordinator.checkpoint();\n }\n\n /**\n * Exports the entire database as a self-contained binary image (totalPages * 4096 bytes)\n * with verified IEEE 802.3 CRC32 checksums on every page.\n */\n async exportBinary(): Promise<Uint8Array> {\n return this.coordinator.leaseQueue.enqueue(async () => {\n if (!this.coordinator.isInTransaction()) {\n await this.coordinator.executeCheckpoint();\n await this.driver.flushAllDirty();\n }\n\n const page1View = this.pool.getSlotDataView(0);\n const totalPages = catalog_get_total_pages(page1View);\n const out = new Uint8Array(totalPages * PAGE_SIZE);\n\n // Copy Page 1 from Slot 0 and stamp valid Page 1 CRC32 checksum\n out.set(this.pool.getPageBytesInSlot(0), 0);\n const outPage1View = new DataView(out.buffer, out.byteOffset, PAGE_SIZE);\n catalog_update_page1_checksum(outPage1View, 0);\n\n // Copy Pages 2..totalPages\n for (let p = 2; p <= totalPages; p++) {\n const offset = (p - 1) * PAGE_SIZE;\n const slice = out.subarray(offset, offset + PAGE_SIZE);\n const residentSlot = this.pool.getResidentSlot(p);\n\n if (residentSlot !== -1) {\n slice.set(this.pool.getPageBytesInSlot(residentSlot));\n } else if (this.coordinator.hasSpilledPage(p)) {\n slice.set(this.coordinator.getSpilledPage(p)!);\n } else {\n const diskPage = await this.vfs.readPage(p);\n if (diskPage) {\n slice.set(diskPage);\n }\n }\n\n // Stamp CRC32 checksum at page header offset 12..15\n const chk = computePageChecksum(slice);\n new DataView(slice.buffer, slice.byteOffset, PAGE_SIZE).setUint32(\n 12,\n chk,\n true,\n );\n }\n\n return out;\n }, this.currentLeaseId ?? undefined);\n }\n\n /**\n * Validates and atomically imports a binary WebDB database image (totalPages * 4096 bytes),\n * replacing all pages, resetting the WAL, and pinning the imported schema catalog.\n */\n async importBinary(data: Uint8Array | ArrayBuffer): Promise<void> {\n if (this.coordinator.isInTransaction()) {\n throw new Error(\n \"Cannot import binary database while a transaction is active\",\n );\n }\n\n return this.coordinator.leaseQueue.enqueue(async () => {\n const bytes =\n data instanceof Uint8Array\n ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n : new Uint8Array(data);\n\n // Pass 1: Pre-validate binary image size, Page 1 header, magic bytes, version, and all page CRC32 checksums\n if (bytes.byteLength < PAGE_SIZE || bytes.byteLength % PAGE_SIZE !== 0) {\n throw new InvalidDatabaseError(\n `Invalid database binary size (${bytes.byteLength} bytes): must be a non-zero multiple of ${PAGE_SIZE} bytes`,\n );\n }\n\n const numPages = bytes.byteLength / PAGE_SIZE;\n const page1Slice = bytes.subarray(0, PAGE_SIZE);\n const page1View = new DataView(\n page1Slice.buffer,\n page1Slice.byteOffset,\n PAGE_SIZE,\n );\n\n const header = catalog_read_page1_header(page1View, true);\n if (header.pageSize !== PAGE_SIZE) {\n throw new InvalidDatabaseError(\n `Invalid database page size ${header.pageSize} (expected ${PAGE_SIZE})`,\n );\n }\n if (header.totalPages !== numPages) {\n throw new InvalidDatabaseError(\n `Database page count mismatch: header specifies ${header.totalPages} pages, but binary image contains ${numPages} pages`,\n );\n }\n\n for (let p = 2; p <= numPages; p++) {\n const offset = (p - 1) * PAGE_SIZE;\n const pageSlice = bytes.subarray(offset, offset + PAGE_SIZE);\n const view = new DataView(\n pageSlice.buffer,\n pageSlice.byteOffset,\n PAGE_SIZE,\n );\n const storedChk = view.getUint32(12, true);\n if (storedChk !== 0) {\n const computedChk = computePageChecksum(pageSlice);\n if (computedChk !== storedChk) {\n throw new CorruptPageError(p, storedChk, computedChk);\n }\n }\n }\n\n // Pass 2: Atomically replace storage, reset buffer pool & WAL, and pin imported catalog pages\n const pagesToWrite: Array<{ pageId: number; data: Uint8Array }> = [];\n for (let p = 1; p <= numPages; p++) {\n const offset = (p - 1) * PAGE_SIZE;\n pagesToWrite.push({\n pageId: p,\n data: bytes.subarray(offset, offset + PAGE_SIZE).slice(),\n });\n }\n\n for (let slot = 1; slot < this.pool.slotCount; slot++) {\n this.pool.forceUnpinSlot(slot);\n this.pool.unassignSlot(slot);\n this.pool.clearDirty(slot);\n this.pool.getPageBytesInSlot(slot).fill(0);\n }\n\n this.pool.getPageBytesInSlot(0).set(pagesToWrite[0].data);\n this.pool.clearDirty(0);\n\n await this.vfs.writePages(pagesToWrite);\n await this.vfs.flush();\n await this.coordinator.resetWalAfterImport();\n\n this.tableMetaCache.clear();\n this.tableTailPages.clear();\n this.indexTailPages.clear();\n this.vmCtx.table = null;\n\n const tableDescriptors = catalog_list_table_descriptors(\n this.pool.getSlotDataView(0),\n );\n for (const desc of tableDescriptors) {\n let catPageId = desc.colCatalogPageId;\n while (catPageId !== 0) {\n const slot = await this.driver.acquireAndPinPage(catPageId);\n const view = this.pool.getSlotDataView(slot);\n const catHeader = catalog_read_page_header(view, 0);\n catPageId = catHeader.nextColCatalogPageId;\n }\n }\n });\n }\n\n async close(): Promise<void> {\n if (this.broadcastChannel) {\n this.broadcastChannel.close();\n this.broadcastChannel = null;\n }\n this.beforeCommitHooks.clear();\n this.commitHooks.clear();\n this.subscriptions.clear();\n await this.coordinator.close();\n await this.driver.flushAllDirty();\n await this.vfs.close();\n }\n}\n"],"names":["SLOTTED_PAGE_HEADER_FIELDS","PAGE_HEADER_SIZE","PAGE_HEADER_OFFSET_TYPE","PAGE_HEADER_OFFSET_FLAGS","PAGE_HEADER_OFFSET_CELL_COUNT","PAGE_HEADER_OFFSET_CONTENT_OFFSET","PAGE_HEADER_OFFSET_NEXT_PAGE_ID","PAGE_HEADER_OFFSET_FREE_BYTES","PAGE_HEADER_OFFSET_CHECKSUM","TABLE_INTERIOR_CELL_FIELDS","TABLE_INTERIOR_CELL_SIZE","TABLE_INTERIOR_CELL_OFFSET_CHILD_PAGE_ID","TABLE_INTERIOR_CELL_OFFSET_ROWID","MAX_TABLE_INTERIOR_CELLS","TABLE_INTERIOR_SPLIT_INDEX","MAX_NAME_LENGTH","SYSPAGE_FILE_HEADER_FIELDS","FILE_HEADER_SIZE","HEADER_OFFSET_MAGIC","HEADER_OFFSET_PAGE_SIZE","HEADER_OFFSET_FILE_FORMAT_VERSION","HEADER_OFFSET_MIN_READ_VERSION","HEADER_OFFSET_TOTAL_PAGES","HEADER_OFFSET_FREE_PAGE_HEAD","HEADER_OFFSET_SCHEMA_VERSION","HEADER_OFFSET_CHANGE_COUNTER","HEADER_OFFSET_PAGE_CHECKSUM","HEADER_OFFSET_NEXT_CATALOG_PAGE_ID","HEADER_OFFSET_NEXT_INDEX_CATALOG_PAGE_ID","HEADER_OFFSET_RESERVED","MAX_TABLES_SYSPAGE","MAX_INDEXES_SYSPAGE","MAX_TABLES_PAGE1","MAX_INDEXES_PAGE1","MASTER_TABLE_OFFSET","INDEX_CATALOG_OFFSET","NEXT_DESCRIPTOR_CATALOG_PAGE_OFFSET","NEXT_DESCRIPTOR_CATALOG_PAGE_SIZE","SYSPAGE_RESERVED_OFFSET","SYSPAGE_RESERVED_SIZE","MAX_COLUMNS_PER_CATALOG_PAGE","MAX_COLUMNS_PER_TABLE","TABLE_DESCRIPTOR_FIELDS","TABLE_DESCRIPTOR_SIZE","TABLE_DESCRIPTOR_OFFSET_TABLE_ID","TABLE_DESCRIPTOR_OFFSET_COLUMN_COUNT","TABLE_DESCRIPTOR_OFFSET_ROOT_PAGE_ID","TABLE_DESCRIPTOR_OFFSET_COL_CATALOG_PAGE_ID","TABLE_DESCRIPTOR_OFFSET_NAME","TABLE_DESCRIPTOR_OFFSET_FLAGS","TABLE_DESCRIPTOR_OFFSET_ROW_COUNT_ESTIMATE","TABLE_DESCRIPTOR_OFFSET_AUTO_INC_NEXT","TABLE_DESCRIPTOR_OFFSET_RESERVED","INDEX_DESCRIPTOR_FIELDS","INDEX_DESCRIPTOR_SIZE","INDEX_DESCRIPTOR_OFFSET_INDEX_ID","INDEX_DESCRIPTOR_OFFSET_TABLE_ID","INDEX_DESCRIPTOR_OFFSET_ROOT_PAGE_ID","INDEX_DESCRIPTOR_OFFSET_COLUMN_COUNT","INDEX_DESCRIPTOR_OFFSET_FLAGS","INDEX_DESCRIPTOR_OFFSET_COLUMN_INDICES","INDEX_DESCRIPTOR_OFFSET_COL_DIRECTIONS","INDEX_DESCRIPTOR_OFFSET_NAME","INDEX_DESCRIPTOR_OFFSET_RESERVED","CATALOG_PAGE_HEADER_FIELDS","CATALOG_PAGE_HEADER_SIZE","CATALOG_PAGE_HEADER_OFFSET_PAGE_TYPE","CATALOG_PAGE_HEADER_OFFSET_FLAGS","CATALOG_PAGE_HEADER_OFFSET_COL_COUNT_IN_PAGE","CATALOG_PAGE_HEADER_OFFSET_TABLE_ID","CATALOG_PAGE_HEADER_OFFSET_START_COL_INDEX","CATALOG_PAGE_HEADER_OFFSET_NEXT_COL_CATALOG_PAGE_ID","CATALOG_PAGE_HEADER_OFFSET_PAGE_CHECKSUM","COLUMN_META_FIELDS","COLUMN_META_SIZE","COLUMN_META_OFFSET_TYPE","COLUMN_META_OFFSET_FLAGS","COLUMN_META_OFFSET_COL_OFFSET","COLUMN_META_OFFSET_NAME","COLUMN_META_OFFSET_RESERVED","DEFAULT_CACHE_SIZE_BYTES","DEFAULT_SLOT_COUNT","DEFAULT_PAGE_SLOTS","DEFAULT_PAGE_TO_SLOT_BUCKETS","PAGE_TO_SLOT_BUCKET_SIZE","PAGE_TO_SLOT_SIZE","VM_CONTEXT_SIZE","RESULT_BUFFER_SIZE","BYTECODE_SIZE","PAGE_SCRATCHPAD_SIZE","ALIGNMENT_PADDING_SIZE","DEFAULT_MAX_QUERY_MEMORY","DEFAULT_BUFFER_POOL_REGIONS","SLOT_TO_PAGE_OFFSET","PAGE_TO_SLOT_OFFSET","DIRTY_MASK_OFFSET","VM_CONTEXT_OFFSET","RESULT_BUFFER_OFFSET","BYTECODE_OFFSET","PAGE_SCRATCHPAD_OFFSET","ALIGNMENT_PADDING_OFFSET","TRANSIENT_ARENA_OFFSET","TOTAL_MEMORY_BYTES","computeBufferPoolOffsets","slotCount","_maxQueryMemory","slotsEndOffset","slotToPageBytes","pageToSlotBuckets","pageToSlotBytes","dirtyMaskBytes","slotToPageOffset","pageToSlotOffset","dirtyMaskOffset","vmContextOffset","resultBufferOffset","bytecodeOffset","pageScratchpadOffset","transientArenaOffset","WAL_PAGE_SIZE","WAL_FRAME_SIZE","WAL_CURRENT_VERSION","WAL_FRAME_MAGIC","WAL_FRAME_TYPE_PAGE_DATA","WAL_FRAME_TYPE_TX_COMMIT","WAL_FRAME_TYPE_TX_UNCOMMITTED","WAL_FILE_HEADER_FIELDS","WAL_FILE_HEADER_SIZE","WAL_HEADER_OFFSET_MAGIC","WAL_HEADER_OFFSET_WAL_VERSION","WAL_HEADER_OFFSET_PAGE_SIZE","WAL_HEADER_OFFSET_CHECKPOINT_SEQ","WAL_HEADER_OFFSET_SALT1","WAL_HEADER_OFFSET_SALT2","WAL_HEADER_OFFSET_CHECKSUM","WAL_HEADER_OFFSET_RESERVED","WAL_FRAME_HEADER_FIELDS","WAL_FRAME_HEADER_SIZE","WAL_FRAME_OFFSET_MAGIC","WAL_FRAME_OFFSET_FRAME_TYPE","WAL_FRAME_OFFSET_FLAGS","WAL_FRAME_OFFSET_TX_ID","WAL_FRAME_OFFSET_PAGE_ID","WAL_FRAME_OFFSET_DB_SIZE_PAGES","WAL_FRAME_OFFSET_FRAME_SEQ","WAL_FRAME_OFFSET_CHECKSUM","WAL_FRAME_OFFSET_RESERVED","CURRENT_ENGINE_VERSION","CURRENT_MIN_READ_VERSION","PAGE_TYPE_FREE","PAGE_TYPE_INDEX_INTERIOR","PAGE_TYPE_TABLE_INTERIOR","PAGE_TYPE_INDEX_LEAF","PAGE_TYPE_CATALOG_PAGE","PAGE_TYPE_LEAF_DATA","VM_FRAME_SIZE","VM_FRAME_COUNT","MAX_REGISTERS_PER_FRAME","MAX_CURSORS_PER_FRAME","MAX_SUBQUERY_DEPTH","WAL_HEADER_SIZE","MAX_TOPK_HEAP_LIMIT","MAX_IN_LIST_SIZE","createVmCursor","createVmContext","cursors","VmStatus","resetVmContext","ctx","table","tables","i","c","DataType","ColumnFlag","TableFlag","IndexFlag","OpCode","RowSizeLimitExceededError","size","limit","NotNullConstraintError","columnName","tableName","IdentifierTooLongError","identifier","ColumnAlreadyExistsError","CannotDropColumnError","message","ColumnNotFoundError","TableNotFoundError","TableAlreadyExistsError","IndexNotFoundError","indexName","IndexAlreadyExistsError","UniqueConstraintViolationError","CorruptPageError","pageId","storedChecksum","computedChecksum","TooManyColumnsError","columnCount","TooManyTablesError","tableCount","TooManyIndexesError","indexCount","UnsupportedFormatVersionError","InvalidDatabaseError","QueryArenaExhaustedError","TooManyCursorsError","cursorCount","TooManyRegistersError","registerCount","SubqueryNestingTooDeepError","depth","QueryTimeoutError","InvalidBytecodeError","TooManyOrderByColumnsError","count","TooManyGroupByColumnsError","UnknownFunctionError","funcName","AggregateNotAllowedInWhereError","CorruptWalHeaderError","CorruptWalFrameError","MemoryVfsAdapter","__publicField","page","data","copy","pages","pageCount","key","snap","k","v","header","frameIndex","frame","startFrameIndex","maxFrames","end","f","frames","IndexedDbVfsAdapter","dbName","resolve","reject","idb","request","db","result","tx","store","range","cursor","val","countReq","nextIdx","framesStore","metaStore","OpfsVfsAdapter","_a","offset","buffer","file","arrayBuf","writable","newSize","slice","readLen","idx","CRC_TABLE","crc32","start","length","crc","computePageChecksum","pageBytes","byte","computePage1Checksum","computeWalFrameChecksum","frameBytes","memcpy","dest","dest_offset","src","src_offset","n","d","s","memset","memcmp","s1","s1_offset","s2","s2_offset","b1","b2","diff","strlen","read_u8","view","write_u8","read_u16","write_u16","read_u32","write_u32","read_i32","write_i32","read_f64","write_f64","read_u64","write_u64","read_i64","write_i64","get_bit","mask","offset_or_bit","bit_idx","set_bit","clear_bit","c_assert","cond","msg","Io","options","coordinator","slotIdx","slot_offset","page_bytes","chk","spilled","in_flight_flush","in_flight_read","read_promise","disk_page","checksum_offset","stored_checksum","computed","existing_flush","write_snapshot","write_promise","targetSlot","faultPageId","flushPageId","WAL_MAGIC_BYTES","encodeWalFileHeader","bytes","salt1","salt2","checksum","decodeWalFileHeader","verifyChecksum","walVersion","pageSize","checkpointSeq","encodeWalFrame","pageData","decodeWalFrameHeader","validateWalFrame","decodeWalFrame","text_decoder","HEX_CHARS","CROCKFORD_ALPHABET","hex_val","crockford_decode","uuid_encode","uuid_str","target","clean_idx","hi","uuid_decode","source","out_str","out_idx","b","UuidCodec","buf","ulid_encode","ulid_str","time","rand_hi","rand_lo","ulid_decode","UlidCodec","text_encoder","page_init","page_offset","page_type","next_page_id","page_init_free","next_free_page_id","page_get_type","page_set_type","type","page_get_cell_count","page_set_cell_count","page_get_cell_content_offset","page_set_cell_content_offset","page_get_next_page_id","page_set_next_page_id","page_get_free_bytes","page_set_free_bytes","free_bytes","page_get_checksum","page_set_checksum","page_get_cell_offset","slot_idx","slot_dir_offset","page_set_cell_offset","cell_offset","page_get_contiguous_free_space","cell_count","cell_content_offset","slot_dir_end","page_get_total_free_space","page_compact","scratchpad_offset","replacement","scratch_view","scratch","local_buf","current_offset","len","src_view","src_bytes","old_offset","page_get_row_length","row_abs_offset","page_insert_row","row_bytes","needed_bytes","contiguous_free","total_free","current_content_offset","current_cell_count","new_content_offset","abs_target","page_delete_row","cell_idx","row_len","slot_dir_start","dst","shift_length","page_update_row","new_row_bytes","old_len","new_len","uint8","needed_extra","page_get_table_layout","table_or_columns","columns","null_bitmap_bytes","fixed_slice_size","var_col_count","page_serialize_row","values","col_count","null_bitmap","col","byte_idx","bit_mask","var_columns","var_offset_table_size","header_and_tables_size","total_var_payload_size","item","total_row_size","row_buffer","row_view","current_fixed_offset","current_var_table_offset","current_payload_offset","page_deserialize_row","arg1","arg2","arg3","record_offset","table_or_cols","row","var_col_idx","fixed_start","var_offset_table_start","table_entry_offset","rel_offset","payload_offset","text_bytes","blob_bytes","page_init_interior","right_child_page_id","page_get_right_child_page_id","page_set_right_child_page_id","page_insert_interior_cell","child_page_id","rowid","target_offset","page_binary_search_interior","target_row_id","lo","candidate_child","mid","cell_rowid","page_split_interior","new_page_offset","median_idx","median_cell_offset","promoted_child_page_id","median_rowid","old_right_child","child_id","r_id","page_init_index_leaf","page_compare_index_keys","type_a","val_a","rowid_a","type_b","val_b","rowid_b","num_a","num_b","str_a","str_b","b_a","b_b","min_len","page_decode_index_cell","cell_data_offset","k_len","context_type","k_data","page_insert_index_leaf_cell","key_type","key_value","key_bytes","cell_length","insert_slot","existing_k_len","mid_type","mid_val","shift_len","page_delete_index_leaf_cell","page_binary_search_index_leaf","target_type","target_value","cmp","first_slot","prev_slot","prev_offset","prev_k_len","prev_type","prev_val","serialize_single_key","serialize_composite_key","col_indices","parts","total_len","encoded","part","p","KNUTH_GOLDEN_RATIO_32","page_table_hash","page_id","h","page_table_get","base_offset","bucket_count","probe","entry_page_id","page_table_set","page_table_delete","found","j","j_offset","j_page_id","j_slot_idx","i_offset","clear_offset","buf_pool_get_slot_offset","buf_pool_read_slot_to_page","slot_to_page_offset","buf_pool_write_slot_to_page","buf_pool_get_resident_slot","page_to_slot_offset","page_to_slot_buckets","buf_pool_assign_slot","old_page","buf_pool_unassign_slot","buf_pool_mark_dirty","dirty_mask","dirty_mask_offset","buf_pool_clear_dirty","buf_pool_is_dirty","buf_pool_pin_slot","pin_counts","buf_pool_unpin_slot","buf_pool_is_pinned","buf_pool_find_victim","ref_bits","slot_count","current_clock_hand","hand","step","slot_view","buf_pool_select_eviction_victim","candidate_slot","next_clock_hand","victim","old_page_id","is_dirty","is_free_page","flush_page_id","get_cursor","cursor_idx","resolve_page_offset","slot","compare_3vl","a","to_lower_char","sql_like_match_raw","str","str_len","pattern","pat_len","star_p","star_s","p_c","s_c","sql_like_match","compare_sorter_keys","keys_a","keys_b","key_info","num_keys","direction","null_order","a_is_null","b_is_null","ba","bb","compare_registers_to_sorter_keys","registers","start_reg","fnv1a_32","hash","u8","group_keys_match","create_agg_buckets","capacity","buckets","heap_sift_down","entries","index","curr","largest","left","right","temp","sort_sorter_entries","sorter","copy_row_bytes","sorter_insert_row","keys","cursor_row_offset","max_k","old_entry","row_data","entry_size","serialize_result_registers","num_cols","cols","record","col_name","_b","col_type","emit_to_result_buffer","instr_pc","needed","out_target","row_is_null","null_bitmap_offset","col_idx","compute_fixed_column_offset","target_col_idx","col_offset","vm_step","bytecode","code_view","code_len","MAX_CYCLES","cycles","has_buffer_pool","op","root_page_id","jump_target","rel_cell_offset","next_cell_idx","next_offset","reg_idx","var_table_offset","var_idx","entry_offset","blob_copy","index_cursor_idx","data_cursor_idx","reg_key","jump_not_found","key_val","idx_cursor","curr_page_id","matched_rowid","search","data_page_id","data_cell_idx","data_cursor","data_page_offset","jump_eof","reg_a","reg_b","reg_str","reg_pat","val_str","val_pat","reg_sub","val_sub","reg_pfx","val_pfx","reg_sfx","val_sfx","reg_val","set_idx","set","total_row_length","emit_status","offset_reg","offset_val","limit_reg","limit_val","udf_id","start_arg_reg","num_args","dest_reg","fn","args","res","src_reg","len_reg","s_idx","l","serialized","sorter_id","key_info_idx","requested_k","cand","root","dir","insert_status","max_read","entry","denom","num_regs","has_val","first_non_null","agg_id","start_key_reg","mode","val_reg","func_id","agg","target_bucket","num","new_capacity","add_size","old_buckets","new_buckets","b_idx","old_b","pos","out_key_reg","out_acc_reg","bucket","sum_reg","count_reg","out_reg","sum","reg","MAGIC_BYTES","crc_table_initialized","init_crc_table","compute_page1_checksum","page1_offset","catalog_init_page1","catalog_read_page1_header","verify_checksum","page_size","file_format_version","min_read_version","total_pages","free_page_head","schema_version","change_counter","catalog_get_total_pages","catalog_set_total_pages","catalog_get_free_page_head","catalog_set_free_page_head","catalog_get_schema_version","catalog_increment_schema_version","catalog_get_change_counter","catalog_increment_change_counter","catalog_update_page1_checksum","catalog_write_fixed_string","max_len","catalog_read_fixed_string","catalog_parse_data_type","type_str","catalog_read_table_descriptor","table_id","column_count","col_catalog_page_id","name","flags","row_count_estimate","auto_inc_next","catalog_write_table_descriptor","desc","catalog_find_table_by_name","table_name","catalog_find_table_slot","catalog_find_free_table_slot","catalog_list_table_descriptors","catalog_read_index_descriptor","index_id","column_indices","col_directions","catalog_write_index_descriptor","catalog_find_free_index_slot","catalog_find_index_by_name","catalog_list_table_indexes","indexes","catalog_delete_index_descriptor","catalog_delete_table_descriptor","catalog_init_page","start_col_index","next_col_catalog_page_id","catalog_read_page_header","catalog_write_page_header","col_count_in_page","catalog_write_column_meta","in_page_slot","meta","catalog_read_column_meta","catalog_map_column_location","catalog_create_table","page1_view","pager","column_def","root_bytes","root_view","def","_c","_d","_e","total_cols","num_catalog_pages","catalog_page_ids","col_count_in_this_page","first_catalog_page_id","pk_cols","index_slot","index_root_page_id","index_root_bytes","index_root_view","pk_col_name","matched_idx","pk_desc","primary_key","catalog_load_table_meta","current_cat_page_id","loaded_count","catalog_load_all_tables","descriptors","WEBDB_CORE_WASM_BASE64","cachedBytes","getWebDbCoreWasmBytes","maybeBuffer","binaryString","createWasmCore","memory","customBytes","wasmModule","instance","exp","getAbsOffset","jsCore.page_compact","row_offset","jsCore.page_insert_row","jsCore.page_update_row","jsCore.buf_pool_pin_slot","jsCore.buf_pool_unpin_slot","jsCore.buf_pool_is_pinned","jsCore.buf_pool_find_victim","jsCore.buf_pool_select_eviction_victim","jsCore.catalog_read_page1_header","jsCore.sql_like_match","jsCore.fnv1a_32","jsCore.compare_sorter_keys","jsCore.vm_step","createWasmMemory","maxQueryMemory","offsets","initial_bytes","initial_wasm_pages","max_wasm_pages","BufferPoolDriver","prev_lock","release","existing_slot","aligned","current","pin","existing_acquire","acquire_promise","err","generation_at_flush","free_head","current_total","free_page_view","next_free_id","new_page_id","new_page_view","force","old_head","status","recoverFromWal","vfs","frameCount","headerBytes","rawFrames","txGroups","committedTxIds","validFramesProcessed","validation","pageCopy","latestPages","committedTxCount","abortedTxCount","txId","pagesToWrite","ExclusiveLeaseQueue","crossTabLockName","onSyncCrossTab","resolveAcquired","resolveRelease","rel","task","leaseId","lease","waiter","nextTask","TransactionCoordinator","pool","io","cb","diskPage1","diskChangeCounter","diskSchemaVersion","walFrameCount","walTouchedByOtherTab","headerSalt","diskView","slotBytes","dbSizePages","slotSnapshots","dirty","pinCounts","spilledPages","savepoint","currentFrames","existingHeader","headerValid","framesToAppend","walIndex","committedTxs","frameType","memoryOverride","allPageIds","BUILTIN_AGGREGATES","BUILTIN_SCALARS","isAggregateFunction","isBuiltinScalarFunction","isBuiltinFunction","validateClause","expr","clause","arg","tokenize","input","tokens","ch","hasDot","quote","ExpressionParser","t","value","token","minPrecedence","prec","operand","lower","parseExpression","sql","trimmed","splitAsAlias","raw","inQuote","exprStr","explicitAlias","deriveDefaultAlias","colName","parseSelectExpr","alias","ExpressionBuilder","node","other","toExprNode","sqlStr","wrapFn","fnBase","fnMethods","exprs","evalExprNode","udfs","numL","numR","arg0","colKey","fnCb","COST_INDEX_SEEK","COST_INDEX_NEXT","COST_ROW_EVAL","extractFilterColumnNames","filter","visitFilter","visitExpr","child","getFilterReferencedTables","colNames","referenced","resolved","resolveColumnAcrossTables","estimateFilterSelectivity","rowCount","colIdx","valuesCount","getSingleTableBaseCost","filters","orderBy","selectivity","estimatedRows","hasOrderBy","explicitSortCost","chooseIndexScan","isPoint","isMultiPoint","satisfiesOrder","effectiveRows","cost","findIndexOnColumn","best","bestRank","isPk","isUnique","rank","buildJoinEdges","plan","originalTables","N","edges","dependencies","jp","joinedIdx","leftRes","rightRes","outerTbl","materializeOutputSelectExprs","seenNames","dupNames","effectiveSelectExprs","reconstructJoinPlans","winningOrder","originalJoinedPlans","newJoinedPlans","innerTableIdx","innerTable","priorIndices","chosenEdge","e","leftColName","rightColName","joinType","origJp","doesTableSatisfyJoinOrderKeys","candidateTable","candidateTableIdx","allTables","selectExprs","se","estimateWhereCost","isNumeric","colNameLower","colBase","optimizeWherePredicates","originalCount","flattened","byColumn","nonColumnFilters","colFilters","contradiction","checkColumnContradiction","optimizedFilters","eliminatedCount","pruned","pruneColumnFilters","originalOrderKey","filterSignature","costA","costB","newOrderKey","reordered","hasIsNull","hasIsNotNull","equalityValues","lowerBound","upperBound","inSet","currentSet","intersected","x","first","eqVal","seenSignatures","hasEqualityOnNonNull","singleEqualityValue","bestLower","bestUpper","sig","inferTransitivePredicates","joinedPlans","normalize","getBaseName","findEqualityValue","colNorm","fNorm","fBase","leftVal","rightVal","CostBasedPlanner","whereRes","workingFilters","whereMetrics","withTransitive","transRes","singleFilters","baseCost","rootFilter","buildRootFilter","topConjunctions","getTopLevelConjunctionFilters","singleTableFilters","crossFilters","refs","tblIdx","base","dp","canPreserve","orderKeysForTable","shortCol","totalSubsets","countBits","prevMask","prevState","depsSatisfied","dep","evalRes","totalCost","existing","isBetter","candidateTotalCost","existingTotalCost","candidateOrderSatisfied","existingOrderSatisfied","candidateIndexScans","existingIndexScans","candidateStartsWithZero","existingStartsWithZero","candidateInversions","existingInversions","fullMask","bestState","winningCost","winningRows","winningScanTypes","winningIndexNames","_","orderedTables","finalOrderSatisfied","finalSortCostAvoided","outerRows","nextTable","nextTableIdx","plannedTableIndices","nextTableFilters","filterSel","candidates","edge","idxMatch","stepCost","newRows","fallbackEdge","rankA","rankB","bestCand","seekCost","avgDupes","HeuristicPlanner","baseStats","validDrivingCandidates","aOrder","bOrder","aIsIndex","bIsIndex","drivingIdx","chosenScanTypes","chosenIndexNames","currentRows","remaining","bestEdgeMatch","fallbackIdx","chosen","NoOpPlanner","baseTableCost","tableScanTypes","tableIndexNames","jPlan","chooseJoinIndex","CustomOrderPlanner","orderSpec","isJoin","customIndices","comparator","list","nameA","nameB","posA","posB","priorityA","priorityB","orderedPlan","reorderedSingleTableFilters","CustomPlanner","CustomQueryPlanner","DefaultQueryPlanner","CostBasedQueryPlanner","HeuristicQueryPlanner","NoOpQueryPlanner","defaultPlanner","resolveQueryPlanner","planner","optimizeQueryPlan","getCmpOpcode","BytecodeEmitter","emitReadColumn","emitter","destReg","colType","normalizeFilter","opNorm","arr","inverseOps","rawRoot","collectLeafFilters","leaves","seen","traverse","conjunctions","gather","tblName","cName","tableIdx","emitLeafJumpOnTrue","leafIdx","truePatches","udfNameMap","filterSetMap","all","regRes","regOne","tempReg","allocReg","emitExpression","regCol","parsed","setIdx","nullSkipPatch","inSkipPatch","notInTruePos","regConst","cmpOpcode","emitLeafJumpOnFalse","falsePatches","passPatch","matchPatch","passPos","emitLeafCondition","fallthrough","compileFilterNode","leafRegMap","leaf","children","subTruePatches","nextChildPos","patch","subFalsePatches","emitHavingLeafJumpOnFalse","resolveReg","regLhs","emitHavingLeafJumpOnTrue","emitHavingLeafCondition","compileHavingFilterNode","emitHavingTree","failPatches","emitFilterTree","nextRowPatches","rowStartPos","inferExprType","udfDefs","targetReg","regLeft","regRight","opCode","cmpOp","truePatch","donePatch","fnName","unaryOps","srcReg","startReg","lenReg","patternOps","regStr","regPat","numArgs","udfId","emitLoadConstant","getMinKeyValueForType","isIndexAlignedWithOrderBy","equalityColumns","indexColNames","idxPos","orderPos","orderCol","canJoinPreserveOrder","drivingTable","joinedTables","candidateFilters","leafFilters","allLeaves","equalityCols","tagCandidate","colMeta","uniqueValues","matchedFilters","allFound","lf","dummyRow","compositeKeyBytes","eqFilter","joinPlan","indexCursor","resolvedLeft","resolvedRight","innerCol","outerCol","bestIdx","compileQuery","opt","planMetrics","emptyEmitter","workingPlan","isJoinQuery","pushedFilters","pushedFilterSet","origIdx","remainingFilters","rootRemainingFilter","orderKeysForTable0","table0Scan","isJoinOrderPreserved","nextCursor","indexCursor0","joinIndices","totalCursors","inSets","nextReg","hasOffset","hasLimit","regOffset","regLimit","G","aggregates","A","outputColumns","gItem","gColName","matchingSelect","finalColName","aggName","aggType","groupKeyStartReg","aggValStartReg","outAccReg","outGroupKeyReg","finalAggStartReg","totalRegs","rewindJumpPatch","loopStartPos","aliasExpr","_f","hasCount","hasAvg","hasSum","hasMin","hasMax","countAgg","valReg","sumAgg","minAgg","maxAgg","nextRowPos","nextRowEofPatch","eofPos","aggEmitLoopPos","processGroupPatch","aggHaltPos","processGroupPos","outReg","sumReg","funcId","aggReg","argCol","gReg","gExpr","selectAlias","rootHaving","tempHavingReg","indexScan","K","sortKeyStartReg","keyInfo","sortKey","_h","_g","emitLoopPos","hasSelectExprs","outSelectExprs","outStartReg","regMatched","regJoinLeft","regJoinRight","regZero","regKey0","minVal","jIdx","rewindJumpPatches","loopStartPositions","nextRowPatchesPerTable","nextRowEofPatches","limitHaltPatches","root0","rootI","condMatchPatch","shouldApplyLimitOffset","offsetSkipPatch","exprTempReg","allocExprReg","nullRowBranchPatch","skipNullRowPatch","refTableIdx","afterNullRowPatches","afterNullRowPos","nextRowPos0","eofPos0","joinedTableScans","_i","regKey","seekNotFoundPatch","jumpEofPatch","numValues","vIdx","isLastVal","jumpNextValPatch","nextValPos","seekEofPatch","limitHaltPatch","textDecoder","disassembleBytecode","instructions","pc","getColName","fmtAddr","addr","rootPage","idxCursor","dataCursor","keyType","jumpTarget","regIdx","opNames","symbols","regA","regB","descriptions","regVal","textBytes","numCols","offsetReg","limitReg","startArgReg","numRegs","sorterId","keyInfoIdx","numKeys","aggId","startKeyReg","funcNames","outKeyReg","countReg","formatDisassembly","pad","out","ins","parseFilterTarget","extractAggregatesFromExpr","aggs","walk","normalizeSelectItem","fields","sub","assertNotAggregateInWhere","colOrExpr","QueryBuilder","leftCol","opOrRightCol","rightCol","rCol","colOrCbOrExpr","subFilter","prefix","suffix","substring","prev","colOrKeys","nullOrder","checkTarget","rest","r","projected","field","targetAlias","rawKey","rows","valA","valB","hasJoins","hasAggsOrGrouping","short","rawRows","isOrderSatisfied","WebDB","driver","coreMode","wasmCore","tableDescriptors","catPageId","channelName","ev","origin","changeCounter","schemaVersion","storageType","page1Data","dbInstance","label","seenColNames","hasPk","flagsNum","page1View","numCatPages","needsPkIndexPage","totalPagesToAllocate","preAllocatedPages","allocCursor","newPageId","pId","cached","rootPageId","toFree","visited","queue","pType","cellCount","off","childId","rightChildId","nextId","curCatPageId","oldName","newName","oldPkName","oldIdxPrefix","updatedName","tailPage","oldColumnName","newColumnName","pageChainIdx","colIdxInPage","catSlot","catView","updatedCol","column","defaultVal","rawFlags","isAutoInc","isIndexed","nextRow","operation","prepare","newColumns","transformRow","keepIndex","newAutoIndexCol","migratedRows","currentPageId","pageSlot","pageView","nextPageId","cellOffset","savedAutoIncNext","existingIndexes","survivingSecondaryIndexes","cIdx","idxSpec","newSlotIdx","newDesc","colIndices","duplicateColIndex","freeSlot","indexRootPageId","indexSlot","indexView","keyVal","allIndexes","excludedRowids","currIdxPageId","cellOff","kLen","foundRowid","idxPageId","idxSlot","idxView","nextIdxPageId","idxInsertRes","newIdxPageId","newIdxSlot","newIdxView","pkCols","pk","formatOne","changes","map","rec","oldRow","newRow","changedColumns","event","lowerChanged","changeset","hook","callback","validCols","checkExpr","checkFilter","isNull","deletedCellIndicesAsc","allCellsOnPage","deletedSet","delIdx","oldRowid","newCellIdx","survivingRow","prevRowid","shiftedRowid","whereOrPk","pkCol","inTx","recorded","trackChanges","uniqueIndexes","autoIncCol","batchUniqueSets","tentativeAutoInc","preparedRows","rIdx","origRow","assignedAutoInc","effectiveRow","setKey","rowBytes","recordedChanges","targetPageId","insertSlot","prevSlot","newSlot","newView","validColMap","pageSnapshots","updatingRowids","totalMatched","currPageId","allCells","matches","newRowBytes","batchSeenKeys","ps","m","overflowUpdates","overflowIndicesOnPage","oldKey","newKey","newRowid","totalDeleted","deletedIndices","startChanges","standaloneCollector","conflictCols","inserted","updated","ignored","hasAllConflictKeys","existingRow","conflictFilters","updChanges","insChanges","txProxy","prop","receiver","_nestedOpts","savedChangesLen","qb","preCommitChangeset","finalChanges","finalOrigin","finalMeta","finalTxId","committedChangeset","normName","fnDef","sample","joinPlans","joinedTable","assembly","scanType","decoratedJoins","scanInfo","joinedTablesMeta","executionTables","keyInfos","udfsRecord","groupByCols","currentOffset","rowLen","rowRecordOffset","pinnedCursorSlots","totalPages","outPage1View","residentSlot","diskPage","numPages","page1Slice","pageSlice","storedChk","computedChk"],"mappings":"sZAqEO,MAAMA,GAA6B,CACxC,CAAC,OAAQ,CAAC,EACV,CAAC,QAAS,CAAC,EACX,CAAC,aAAc,CAAC,EAChB,CAAC,iBAAkB,CAAC,EACpB,CAAC,eAAgB,CAAC,EAClB,CAAC,aAAc,CAAC,EAChB,CAAC,WAAY,CAAC,CAChB,EAKaC,GAAmB,GAanBC,GAA0B,EAM1BC,GAA2B,EAM3BC,GAAgC,EAOhCC,GAAoC,EAQpCC,GAAkC,EAOlCC,GAAgC,GAOhCC,GAA8B,GA6B9BC,GAA6B,CACxC,CAAC,gBAAiB,CAAC,EACnB,CAAC,QAAS,CAAC,CACb,EAMaC,GAA2B,GAO3BC,GAA2C,EAO3CC,GAAmC,EAMnCC,GAA2B,IAM3BC,GAA6B,ICnL7BC,GAAkB,GAqDlBC,GAA6B,CACxC,CAAC,QAAS,CAAC,EACX,CAAC,YAAa,CAAC,EACf,CAAC,sBAAuB,CAAC,EACzB,CAAC,mBAAoB,CAAC,EACtB,CAAC,cAAe,CAAC,EACjB,CAAC,iBAAkB,CAAC,EACpB,CAAC,iBAAkB,CAAC,EACpB,CAAC,iBAAkB,CAAC,EACpB,CAAC,gBAAiB,CAAC,EACnB,CAAC,uBAAwB,CAAC,EAC1B,CAAC,6BAA8B,CAAC,EAChC,CAAC,WAAY,EAAE,CACjB,EAKaC,GAAmB,IAKnBC,GAAsB,EAKtBC,GAA0B,EAK1BC,GAAoC,EAKpCC,GAAiC,GAKjCC,GAA4B,GAK5BC,GAA+B,GAK/BC,GAA+B,GAK/BC,GAA+B,GAK/BC,GAA8B,GAK9BC,GAAqC,GAKrCC,GAA2C,GAK3CC,GAAyB,GAwBzBC,GAAqB,GAKrBC,GAAsB,EAKtBC,GAAmB,GAKnBC,GAAoB,EAKpBC,GAAsB,IAKtBC,GAAuB,KAKvBC,GAAsC,KAKtCC,GAAoC,EAKpCC,GAA0B,KAK1BC,GAAwB,IAKxBC,GAA+B,GAK/BC,GAAwB,IA4CxBC,GAA0B,CACrC,CAAC,WAAY,CAAC,EACd,CAAC,eAAgB,CAAC,EAClB,CAAC,eAAgB,CAAC,EAClB,CAAC,sBAAuB,CAAC,EACzB,CAAC,OAAQ,EAAE,EACX,CAAC,QAAS,CAAC,EACX,CAAC,qBAAsB,CAAC,EACxB,CAAC,gBAAiB,CAAC,EACnB,CAAC,WAAY,EAAE,CACjB,EAKaC,GAAwB,IAKxBC,GAAmC,EAKnCC,GAAuC,EAKvCC,GAAuC,EAKvCC,GAA8C,EAK9CC,GAA+B,GAK/BC,GAAgC,GAKhCC,GAA6C,GAK7CC,GAAwC,GAKxCC,GAAmC,GA4FnCC,GAA0B,CACrC,CAAC,WAAY,CAAC,EACd,CAAC,WAAY,CAAC,EACd,CAAC,eAAgB,CAAC,EAClB,CAAC,eAAgB,CAAC,EAClB,CAAC,QAAS,CAAC,EACX,CAAC,iBAAkB,EAAE,EACrB,CAAC,iBAAkB,CAAC,EACpB,CAAC,OAAQ,EAAE,EACX,CAAC,WAAY,EAAE,CACjB,EAKaC,GAAwB,IAKxBC,GAAmC,EAKnCC,GAAmC,EAKnCC,GAAuC,EAKvCC,GAAuC,EAKvCC,GAAgC,EAKhCC,GAAyC,GAKzCC,GAAyC,GAKzCC,GAA+B,GAK/BC,GAAmC,GAkCnCC,GAA6B,CACxC,CAAC,YAAa,CAAC,EACf,CAAC,QAAS,CAAC,EACX,CAAC,oBAAqB,CAAC,EACvB,CAAC,WAAY,CAAC,EACd,CAAC,kBAAmB,CAAC,EACrB,CAAC,2BAA4B,CAAC,EAC9B,CAAC,gBAAiB,CAAC,CACrB,EAKaC,GAA2B,GAK3BC,GAAuC,EAKvCC,GAAmC,EAKnCC,GAA+C,EAK/CC,GAAsC,EAKtCC,GAA6C,EAK7CC,GAAsD,EAKtDC,GAA2C,GA8B3CC,GAAqB,CAChC,CAAC,OAAQ,CAAC,EACV,CAAC,QAAS,CAAC,EACX,CAAC,aAAc,CAAC,EAChB,CAAC,OAAQ,EAAE,EACX,CAAC,WAAY,CAAC,CAChB,EAKaC,GAAmB,GAKnBC,GAA0B,EAK1BC,GAA2B,EAK3BC,GAAgC,EAKhCC,GAA0B,EAK1BC,GAA8B,GC7mB9BC,GAA2B,QAK3BC,GAAqB,KAKrBC,GAAqB,KAKrBC,GAA+B,KAK/BC,GAA2B,EAK3BC,GAAoB,MAKpBC,GAAkB,MAKlBC,GAAqB,MAKrBC,GAAgB,MAKhBC,GAAuB,KAKvBC,GAAyB,MAKzBC,GAA2B,SAmB3BC,GAA8B,CACzC,CAAC,eAAgB,IAAI,EACrB,CAAC,eAAgB,KAAK,EACtB,CAAC,aAAc,GAAG,EAClB,CAAC,aAAc,KAAK,EACpB,CAAC,gBAAiB,KAAK,EACvB,CAAC,WAAY,KAAK,EAClB,CAAC,kBAAmB,IAAI,EACxB,CAAC,oBAAqB,KAAK,CAC7B,EAKaC,GAAsB,QAKtBC,GAAsB,QAKtBC,GAAoB,QAKpBC,GAAoB,QAKpBC,GAAuB,QAKvBC,GAAkB,QAKlBC,GAAyB,QAKzBC,GAA2B,QAK3BC,GAAyB,QAKzBC,GAAqB,SAK3B,SAASC,GACdC,EACAC,EAA0Bd,GAC1B,CACA,MAAMe,EAAiBF,EAAY,KAC7BG,EAAmBH,EAAY,EAAI,EAAK,GAC9C,IAAII,EAAoB,GACxB,KAAOA,EAAoBJ,EAAY,GACrCI,IAAsB,EAExB,MAAMC,EAAkBD,EAAoB,EACtCE,EAAkB,KAAK,KAAKN,EAAY,CAAC,EAAI,EAAK,GAExD,GAAIA,IAAcvB,GAChB,MAAO,CACL,eAAAyB,EACA,iBAAkBb,GAClB,iBAAkBC,GAClB,kBAAmBX,GACnB,gBAAiBY,GACjB,gBAAiBC,GACjB,mBAAoBC,GACpB,eAAgBC,GAChB,qBAAsBC,GACtB,qBAAsBE,EAAA,EAI1B,MAAMU,EAAmBL,EACnBM,EAAmBD,EAAmBJ,EACtCM,EAAkBD,EAAmBH,EACrCK,EAAkBD,EAAkBH,EACpCK,EAAqBD,EAAkB5B,GACvC8B,EAAiBD,EAAqB5B,GACtC8B,EAAuBD,EAAiB5B,GACxC8B,EACJD,EAAuB5B,GAAuBC,GAEhD,MAAO,CACL,eAAAgB,EACA,iBAAAK,EACA,iBAAAC,EACA,kBAAAJ,EACA,gBAAAK,EACA,gBAAAC,EACA,mBAAAC,EACA,eAAAC,EACA,qBAAAC,EACA,qBAAAC,CAAA,CAEJ,CCtLO,MAAMC,GAAgB,KAKhBC,GAAiB,KAKjBC,GAAsB,EAKtBC,GAAkB,WAKlBC,GAA2B,EAK3BC,GAA2B,EAK3BC,GAAgC,EA2ChCC,GAAyB,CACpC,CAAC,QAAS,CAAC,EACX,CAAC,cAAe,CAAC,EACjB,CAAC,YAAa,CAAC,EACf,CAAC,iBAAkB,CAAC,EACpB,CAAC,QAAS,CAAC,EACX,CAAC,QAAS,CAAC,EACX,CAAC,WAAY,CAAC,EACd,CAAC,WAAY,CAAC,CAChB,EAKaC,GAAuB,GAKvBC,GAA0B,EAK1BC,GAAgC,EAKhCC,GAA8B,EAK9BC,GAAmC,GAKnCC,GAA0B,GAK1BC,GAA0B,GAK1BC,GAA6B,GAK7BC,GAA6B,GA4C7BC,GAA0B,CACrC,CAAC,QAAS,CAAC,EACX,CAAC,aAAc,CAAC,EAChB,CAAC,QAAS,CAAC,EACX,CAAC,QAAS,CAAC,EACX,CAAC,UAAW,CAAC,EACb,CAAC,gBAAiB,CAAC,EACnB,CAAC,YAAa,CAAC,EACf,CAAC,WAAY,CAAC,EACd,CAAC,WAAY,CAAC,CAChB,EAKaC,GAAwB,GAKxBC,GAAyB,EAKzBC,GAA8B,EAK9BC,GAAyB,EAKzBC,GAAyB,EAKzBC,GAA2B,GAK3BC,GAAiC,GAKjCC,GAA6B,GAK7BC,GAA4B,GAK5BC,GAA4B,GCvP5BC,GAAyB,EACzBC,GAA2B,EAG3BC,GAAiB,EACjBC,GAA2B,EAC3BC,GAA2B,EAC3BC,GAAuB,GACvBC,GAAyB,GACzBC,GAAsB,GAGtBC,GAAgB,KAChBC,GAAiB,EACjBC,GAA0B,GAC1BC,GAAwB,GACxBC,GAAqB,EAGrBC,GAAkB,GAGlBC,GAAsB,IACtBC,GAAmB,ICdzB,SAASC,IAA2B,CACzC,MAAO,CACL,OAAQ,EACR,WAAY,EACZ,QAAS,EACT,QAAS,EACT,UAAW,EACX,WAAY,EACZ,MAAO,CAAA,CAEX,CAmEO,SAASC,IAA6B,CAC3C,MAAMC,EAAsB,MAAM,KAAK,CAAE,OAAQ,EAAA,EAAM,IAAMF,IAAgB,EAC7E,MAAO,CACL,GAAI,EACJ,OAAQG,EAAS,QACjB,cAAe,EACf,YAAa,EACb,aAAc,EACd,YAAa,EACb,eAAgB3E,GAChB,aAAc,EACd,UAAW,IAAI,MAAM,EAAE,EAAE,KAAK,IAAI,EAClC,OAAQ0E,EAAQ,CAAC,EACjB,QAAAA,EACA,SAAU,CAAA,EACV,QAAS,CAAA,EACT,YAAa,CAAA,EACb,MAAO,KACP,OAAQ,OACR,cAAe,OACf,OAAQ,CAAA,CAAC,CAEb,CAEO,SAASE,GACdC,EACAC,EACAC,EACM,CACNF,EAAI,GAAK,EACTA,EAAI,OAASF,EAAS,QACtBE,EAAI,cAAgB,EACpBA,EAAI,YAAc,EAClBA,EAAI,aAAe,EACnBA,EAAI,YAAc,EAClBA,EAAI,eAAiB7E,GACrB6E,EAAI,aAAe,EACnBA,EAAI,UAAU,KAAK,IAAI,EACvB,QAASG,EAAI,EAAGA,EAAIH,EAAI,QAAQ,OAAQG,IAAK,CAC3C,MAAMC,EAAIJ,EAAI,QAAQG,CAAC,EACvBC,EAAE,OAAS,EACXA,EAAE,WAAa,EACfA,EAAE,QAAU,EACZA,EAAE,QAAU,EACZA,EAAE,UAAY,EACdA,EAAE,WAAa,EACfA,EAAE,MAAQ,CACZ,CACAJ,EAAI,OAASA,EAAI,QAAQ,CAAC,EAC1BA,EAAI,SAAW,CAAA,EACfA,EAAI,QAAU,CAAA,EACdA,EAAI,YAAc,CAAA,EAClBA,EAAI,MAAQC,GAAS,KACrBD,EAAI,OAASE,EACbF,EAAI,cAAgB,OACpBA,EAAI,OAAS,CAAA,CACf,CClJO,IAAKK,GAAAA,IACVA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,MAAQ,CAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,CAAA,EAAR,QACAA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,KAAO,CAAA,EAAP,OARUA,IAAAA,GAAA,CAAA,CAAA,EAWAC,GAAAA,IACVA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,YAAc,CAAA,EAAd,cACAA,EAAAA,EAAA,SAAW,CAAA,EAAX,WACAA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,SAAW,CAAA,EAAX,WALUA,IAAAA,GAAA,CAAA,CAAA,EAQAC,IAAAA,IACVA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,OAAS,CAAA,EAAT,SACAA,EAAAA,EAAA,OAAS,CAAA,EAAT,SAHUA,IAAAA,IAAA,CAAA,CAAA,EAMAC,IAAAA,IACVA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,OAAS,CAAA,EAAT,SACAA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,eAAiB,CAAA,EAAjB,iBAJUA,IAAAA,IAAA,CAAA,CAAA,EAOAC,GAAAA,IAEVA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,eAAiB,CAAA,EAAjB,iBACAA,EAAAA,EAAA,UAAY,CAAA,EAAZ,YACAA,EAAAA,EAAA,YAAc,CAAA,EAAd,cACAA,EAAAA,EAAA,cAAgB,CAAA,EAAhB,gBACAA,EAAAA,EAAA,gBAAkB,CAAA,EAAlB,kBACAA,EAAAA,EAAA,eAAiB,CAAA,EAAjB,iBACAA,EAAAA,EAAA,eAAiB,CAAA,EAAjB,iBACAA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,YAAc,CAAA,EAAd,cACAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,iBAAmB,EAAA,EAAnB,mBACAA,EAAAA,EAAA,iBAAmB,EAAA,EAAnB,mBACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBAGAA,EAAAA,EAAA,WAAa,EAAA,EAAb,aACAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QACAA,EAAAA,EAAA,QAAU,EAAA,EAAV,UACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,gBAAkB,EAAA,EAAlB,kBACAA,EAAAA,EAAA,gBAAkB,EAAA,EAAlB,kBACAA,EAAAA,EAAA,mBAAqB,EAAA,EAArB,qBACAA,EAAAA,EAAA,iBAAmB,EAAA,EAAnB,mBACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eACAA,EAAAA,EAAA,MAAQ,EAAA,EAAR,QAGAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,UAAY,EAAA,EAAZ,YACAA,EAAAA,EAAA,SAAW,EAAA,EAAX,WACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBAGAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,iBAAmB,EAAA,EAAnB,mBACAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBAGAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eAGAA,EAAAA,EAAA,OAAS,EAAA,EAAT,SACAA,EAAAA,EAAA,OAAS,EAAA,EAAT,SACAA,EAAAA,EAAA,OAAS,EAAA,EAAT,SACAA,EAAAA,EAAA,OAAS,EAAA,EAAT,SACAA,EAAAA,EAAA,OAAS,EAAA,EAAT,SAGAA,EAAAA,EAAA,kBAAoB,EAAA,EAApB,oBACAA,EAAAA,EAAA,mBAAqB,EAAA,EAArB,qBAGAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,QAAU,EAAA,EAAV,UAGAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,YAAc,EAAA,EAAd,cACAA,EAAAA,EAAA,aAAe,EAAA,EAAf,eAGAA,EAAAA,EAAA,eAAiB,EAAA,EAAjB,iBACAA,EAAAA,EAAA,mBAAqB,EAAA,EAArB,qBAGAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBACAA,EAAAA,EAAA,gBAAkB,EAAA,EAAlB,kBACAA,EAAAA,EAAA,cAAgB,EAAA,EAAhB,gBA9FUA,IAAAA,GAAA,CAAA,CAAA,EAiGAX,GAAAA,IACVA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,KAAO,CAAA,EAAP,OACAA,EAAAA,EAAA,WAAa,CAAA,EAAb,aACAA,EAAAA,EAAA,YAAc,CAAA,EAAd,cACAA,EAAAA,EAAA,MAAQ,CAAA,EAAR,QACAA,EAAAA,EAAA,QAAU,CAAA,EAAV,UACAA,EAAAA,EAAA,gBAAkB,CAAA,EAAlB,kBACAA,EAAAA,EAAA,iBAAmB,CAAA,EAAnB,mBARUA,IAAAA,GAAA,CAAA,CAAA,EA+FL,MAAMY,WAAkC,KAAM,CACnD,YAAYC,EAAcC,EAAgB,KAAM,CAC9C,MAAM,aAAaD,CAAI,oCAAoCC,CAAK,QAAQ,EACxE,KAAK,KAAO,2BACd,CACF,CAEO,MAAMC,WAA+B,KAAM,CAChD,YAAYC,EAAoBC,EAAoB,CAClD,MAAM,+BAA+BA,EAAYA,EAAY,IAAM,EAAE,GAAGD,CAAU,EAAE,EACpF,KAAK,KAAO,wBACd,CACF,CAoEO,MAAME,WAA+B,KAAM,CAChD,YAAYC,EAAoBL,EAAgB,GAAI,CAClD,MACE,eAAeK,CAAU,MAAMA,EAAW,MAAM,yCAAyCL,CAAK,aAAA,EAEhG,KAAK,KAAO,wBACd,CACF,CAEO,MAAMM,WAAiC,KAAM,CAClD,YAAYJ,EAAoBC,EAAoB,CAClD,MACEA,EACI,WAAWD,CAAU,8BAA8BC,CAAS,IAC5D,WAAWD,CAAU,kBAAA,EAE3B,KAAK,KAAO,0BACd,CACF,CAEO,MAAMK,WAA8B,KAAM,CAC/C,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,uBACd,CACF,CAEO,MAAMC,WAA4B,KAAM,CAC7C,YAAYP,EAAoBC,EAAoB,CAClD,MACEA,EACI,WAAWD,CAAU,yBAAyBC,CAAS,IACvD,WAAWD,CAAU,aAAA,EAE3B,KAAK,KAAO,qBACd,CACF,CAEO,MAAMQ,WAA2B,KAAM,CAC5C,YAAYP,EAAmB,CAC7B,MAAM,qBAAqBA,CAAS,GAAG,EACvC,KAAK,KAAO,oBACd,CACF,CAEO,MAAMQ,WAAgC,KAAM,CACjD,YAAYR,EAAmB,CAC7B,MAAM,0BAA0BA,CAAS,GAAG,EAC5C,KAAK,KAAO,yBACd,CACF,CAEO,MAAMS,WAA2B,KAAM,CAC5C,YAAYC,EAAmB,CAC7B,MAAM,qBAAqBA,CAAS,GAAG,EACvC,KAAK,KAAO,oBACd,CACF,CAEO,MAAMC,WAAgC,KAAM,CACjD,YAAYD,EAAmB,CAC7B,MAAM,0BAA0BA,CAAS,GAAG,EAC5C,KAAK,KAAO,yBACd,CACF,CAEO,MAAME,WAAuC,KAAM,CACxD,YAAYP,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,gCACd,CACF,CAEO,MAAMQ,WAAyB,KAAM,CAC1C,YAAmBC,EAAuBC,EAAwCC,EAAoC,CACpH,MACE,oCAAoCF,CAAM,sBAAsBC,CAAc,GAC5EC,IAAqB,OAAY,uBAAuBA,CAAgB,GAAK,EAC/E,EAAA,EAJe,KAAA,OAAAF,EAAuB,KAAA,eAAAC,EAAwC,KAAA,iBAAAC,EAMhF,KAAK,KAAO,kBACd,CACF,CAEO,MAAMC,WAA4B,KAAM,CAC7C,YAAYC,EAAqBrB,EAAgB,IAAK,CACpD,MAAM,qBAAqBqB,CAAW,6BAA6BrB,CAAK,UAAU,EAClF,KAAK,KAAO,qBACd,CACF,CAEO,MAAMsB,WAA2B,KAAM,CAC5C,YAAYC,EAAoBvB,EAAgB,GAAI,CAClD,MAAM,oBAAoBuB,CAAU,6BAA6BvB,CAAK,mBAAmB,EACzF,KAAK,KAAO,oBACd,CACF,CAEO,MAAMwB,WAA4B,KAAM,CAC7C,YAAYC,EAAoBzB,EAAgB,EAAG,CACjD,MAAM,qBAAqByB,CAAU,6BAA6BzB,CAAK,oBAAoB,EAC3F,KAAK,KAAO,qBACd,CACF,CAEO,MAAM0B,WAAsC,KAAM,CACvD,YAAYlB,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,+BACd,CACF,CAEO,MAAMmB,WAA6B,KAAM,CAC9C,YAAYnB,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,sBACd,CACF,CAEO,MAAMoB,WAAiC,KAAM,CAClD,YAAYpB,EAAkB,kCAAmC,CAC/D,MAAMA,CAAO,EACb,KAAK,KAAO,0BACd,CACF,CAEO,MAAMqB,WAA4B,KAAM,CAC7C,YAAYC,EAAqB9B,EAAgB,GAAI,CACnD,MAAM,qBAAqB8B,CAAW,6BAA6B9B,CAAK,UAAU,EAClF,KAAK,KAAO,qBACd,CACF,CAEO,MAAM+B,WAA8B,KAAM,CAC/C,YAAYC,EAAuBhC,EAAgB,GAAI,CACrD,MAAM,uBAAuBgC,CAAa,6BAA6BhC,CAAK,YAAY,EACxF,KAAK,KAAO,uBACd,CACF,CAEO,MAAMiC,WAAoC,KAAM,CACrD,YAAYC,EAAelC,EAAgB,EAAG,CAC5C,MAAM,0BAA0BkC,CAAK,6BAA6BlC,CAAK,EAAE,EACzE,KAAK,KAAO,6BACd,CACF,CAEO,MAAMmC,WAA0B,KAAM,CAC3C,YAAY3B,EAAkB,yDAA0D,CACtF,MAAMA,CAAO,EACb,KAAK,KAAO,mBACd,CACF,CAEO,MAAM4B,WAA6B,KAAM,CAC9C,YAAY5B,EAAkB,yDAA0D,CACtF,MAAMA,CAAO,EACb,KAAK,KAAO,sBACd,CACF,CAEO,MAAM6B,WAAmC,KAAM,CACpD,YAAYC,EAAetC,EAAgB,EAAG,CAC5C,MAAM,8BAA8BsC,CAAK,6BAA6BtC,CAAK,EAAE,EAC7E,KAAK,KAAO,4BACd,CACF,CAEO,MAAMuC,WAAmC,KAAM,CACpD,YAAYD,EAAetC,EAAgB,EAAG,CAC5C,MAAM,8BAA8BsC,CAAK,6BAA6BtC,CAAK,EAAE,EAC7E,KAAK,KAAO,4BACd,CACF,CAEO,MAAMwC,WAA6B,KAAM,CAC9C,YAAYC,EAAkB,CAC5B,MAAM,aAAaA,CAAQ,8DAA8D,EACzF,KAAK,KAAO,sBACd,CACF,CAEO,MAAMC,WAAwC,KAAM,CACzD,YAAYD,EAAkB,CAC5B,MAAM,uBAAuBA,CAAQ,kCAAkC,EACvE,KAAK,KAAO,iCACd,CACF,CAEO,MAAME,WAA8B,KAAM,CAC/C,YAAYnC,EAAkB,qCAAsC,CAClE,MAAMA,CAAO,EACb,KAAK,KAAO,uBACd,CACF,CAEO,MAAMoC,WAA6B,KAAM,CAC9C,YAAYpC,EAAkB,+BAAgC,CAC5D,MAAMA,CAAO,EACb,KAAK,KAAO,sBACd,CACF,CCvfO,MAAMqC,EAAwC,CAA9C,cACIC,EAAA,YAAO,UACPA,EAAA,qBAAgB,IAEjBA,EAAA,iBAAY,KACZA,EAAA,iBAA+B,MAC/BA,EAAA,iBAA0B,CAAA,GAElC,MAAM,SAAS7B,EAA4C,CACzD,MAAM8B,EAAO,KAAK,MAAM,IAAI9B,CAAM,EAClC,OAAK8B,EACE,IAAI,WAAWA,CAAI,EADR,IAEpB,CAEA,MAAM,UAAU9B,EAAgB+B,EAAiC,CAC/D,MAAMC,EAAO,IAAI,WAAWD,EAAK,UAAU,EAC3CC,EAAK,IAAID,CAAI,EACb,KAAK,MAAM,IAAI/B,EAAQgC,CAAI,CAC7B,CAEA,MAAM,WAAWC,EAAmE,CAClF,SAAW,CAAE,OAAAjC,EAAQ,KAAA+B,CAAA,IAAUE,EAC7B,MAAM,KAAK,UAAUjC,EAAQ+B,CAAI,CAErC,CAEA,MAAM,OAAuB,CAE7B,CAEA,MAAM,SAASG,EAAkC,CAC/C,UAAWC,KAAO,MAAM,KAAK,KAAK,MAAM,KAAA,CAAM,EACxCA,EAAMD,GACR,KAAK,MAAM,OAAOC,CAAG,CAG3B,CAEA,UAAoC,CAClC,MAAMC,MAAW,IACjB,SAAW,CAACC,EAAGC,CAAC,IAAK,KAAK,MAAM,UAC9BF,EAAK,IAAIC,EAAG,IAAI,WAAWC,CAAC,CAAC,EAE/B,OAAOF,CACT,CAEA,gBAAgBA,EAAqC,CACnD,KAAK,MAAM,MAAA,EACX,SAAW,CAACC,EAAGC,CAAC,IAAKF,EAAK,UACxB,KAAK,MAAM,IAAIC,EAAG,IAAI,WAAWC,CAAC,CAAC,CAEvC,CAIA,MAAM,eAA4C,CAChD,OAAK,KAAK,UACH,IAAI,WAAW,KAAK,SAAS,EADR,IAE9B,CAEA,MAAM,eAAeC,EAAmC,CACtD,MAAMP,EAAO,IAAI,WAAWO,EAAO,UAAU,EAC7CP,EAAK,IAAIO,CAAM,EACf,KAAK,UAAYP,CACnB,CAEA,MAAM,aAAaQ,EAAgD,CACjE,MAAMC,EAAQ,KAAK,UAAUD,CAAU,EACvC,OAAKC,EACE,IAAI,WAAWA,CAAK,EADR,IAErB,CAEA,MAAM,cAAcC,EAAyBC,EAA2C,CACtF,MAAMC,EAAMD,IAAc,OAAYD,EAAkBC,EAAY,KAAK,UAAU,OAEnF,OADc,KAAK,UAAU,MAAMD,EAAiBE,CAAG,EAC1C,IAAKC,GAAM,IAAI,WAAWA,CAAC,CAAC,CAC3C,CAEA,MAAM,gBAAgBC,EAAqC,CACzD,UAAWL,KAASK,EAAQ,CAC1B,MAAMd,EAAO,IAAI,WAAWS,EAAM,UAAU,EAC5CT,EAAK,IAAIS,CAAK,EACd,KAAK,UAAU,KAAKT,CAAI,CAC1B,CACF,CAEA,MAAM,UAA0B,CAEhC,CAEA,MAAM,YAAYQ,EAAmC,CAC/CA,IAAe,GACjB,KAAK,UAAY,CAAA,EACjB,KAAK,UAAY,MAEjB,KAAK,UAAU,OAAS,KAAK,IAAI,KAAK,UAAU,OAAQA,CAAU,CAEtE,CAEA,MAAM,kBAAoC,CACxC,OAAO,KAAK,UAAU,MACxB,CAEA,MAAM,OAAuB,CAE7B,CACF,CC1GO,MAAMO,EAA2C,CAOtD,YAAYC,EAAgB,CANnBnB,EAAA,YAAO,OACPA,EAAA,qBAAgB,IAEjBA,EAAA,eACAA,EAAA,iBAAyC,MAG/C,KAAK,OAAS,SAASmB,CAAM,EAC/B,CAEQ,OAA8B,CACpC,OAAK,KAAK,YACR,KAAK,UAAY,IAAI,QAAqB,CAACC,EAASC,IAAW,CAC7D,MAAMC,EAAM,WAAW,UACvB,GAAI,CAACA,EAAK,CACRD,EAAO,IAAI,MAAM,uDAAuD,CAAC,EACzE,MACF,CAEA,MAAME,EAAUD,EAAI,KAAK,KAAK,OAAQ,CAAC,EACvCC,EAAQ,gBAAkB,IAAM,CAC9B,MAAMC,EAAKD,EAAQ,OACdC,EAAG,iBAAiB,SAAS,OAAO,GACvCA,EAAG,kBAAkB,OAAO,EAEzBA,EAAG,iBAAiB,SAAS,YAAY,GAC5CA,EAAG,kBAAkB,YAAY,EAE9BA,EAAG,iBAAiB,SAAS,UAAU,GAC1CA,EAAG,kBAAkB,UAAU,CAEnC,EAEAD,EAAQ,UAAY,IAAMH,EAAQG,EAAQ,MAAM,EAChDA,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,GAEI,KAAK,SACd,CAEA,MAAM,SAASpD,EAA4C,CACzD,MAAMqD,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAA2B,CAACJ,EAASC,IAAW,CAGzD,MAAME,EAFKC,EAAG,YAAY,QAAS,UAAU,EAC5B,YAAY,OAAO,EACd,IAAIrD,CAAM,EAEhCoD,EAAQ,UAAY,IAAM,CACxB,MAAME,EAASF,EAAQ,OAIrBH,EAHGK,EAGKA,aAAkB,WAAaA,EAAS,IAAI,WAAWA,CAAM,EAF7D,IAE8D,CAE1E,EACAF,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAEA,MAAM,UAAUpD,EAAgB+B,EAAiC,CAC/D,MAAMsB,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAC5C,MAAMK,EAAKF,EAAG,YAAY,QAAS,WAAW,EACxCG,EAAQD,EAAG,YAAY,OAAO,EAE9BvB,EAAO,IAAI,WAAWD,EAAK,UAAU,EAC3CC,EAAK,IAAID,CAAI,EACbyB,EAAM,IAAIxB,EAAMhC,CAAM,EAEtBuD,EAAG,WAAa,IAAMN,EAAA,EACtBM,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,EAClCA,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,CACpC,CAAC,CACH,CAEA,MAAM,WAAWtB,EAAmE,CAClF,GAAIA,EAAM,SAAW,EAAG,OACxB,MAAMoB,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAC5C,MAAMK,EAAKF,EAAG,YAAY,QAAS,WAAW,EACxCG,EAAQD,EAAG,YAAY,OAAO,EAEpC,SAAW,CAAE,OAAAvD,EAAQ,KAAA+B,CAAA,IAAUE,EAAO,CACpC,MAAMD,EAAO,IAAI,WAAWD,EAAK,UAAU,EAC3CC,EAAK,IAAID,CAAI,EACbyB,EAAM,IAAIxB,EAAMhC,CAAM,CACxB,CAEAuD,EAAG,WAAa,IAAMN,EAAA,EACtBM,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,EAClCA,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,CACpC,CAAC,CACH,CAEA,MAAM,OAAuB,CAE7B,CAEA,MAAM,SAASrB,EAAkC,CAC/C,MAAMmB,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAE5C,MAAMM,EADKH,EAAG,YAAY,QAAS,WAAW,EAC7B,YAAY,OAAO,EAC9BI,EAAQ,YAAY,WAAWvB,EAAW,EAAI,EAC9CkB,EAAUI,EAAM,OAAOC,CAAK,EAElCL,EAAQ,UAAY,IAAMH,EAAA,EAC1BG,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAIA,MAAM,eAA4C,CAChD,MAAMC,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAA2B,CAACJ,EAASC,IAAW,CAGzD,MAAME,EAFKC,EAAG,YAAY,WAAY,UAAU,EAC/B,YAAY,UAAU,EACjB,IAAI,QAAQ,EAElCD,EAAQ,UAAY,IAAM,CACxB,MAAME,EAASF,EAAQ,OAIrBH,EAHGK,EAGKA,aAAkB,WAAaA,EAAS,IAAI,WAAWA,CAAM,EAF7D,IAE8D,CAE1E,EACAF,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAEA,MAAM,eAAeb,EAAmC,CACtD,MAAMc,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAC5C,MAAMK,EAAKF,EAAG,YAAY,WAAY,WAAW,EAC3CG,EAAQD,EAAG,YAAY,UAAU,EACjCvB,EAAO,IAAI,WAAWO,EAAO,UAAU,EAC7CP,EAAK,IAAIO,CAAM,EACfiB,EAAM,IAAIxB,EAAM,QAAQ,EAExBuB,EAAG,WAAa,IAAMN,EAAA,EACtBM,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,EAClCA,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,CACpC,CAAC,CACH,CAEA,MAAM,aAAaf,EAAgD,CACjE,MAAMa,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAA2B,CAACJ,EAASC,IAAW,CAGzD,MAAME,EAFKC,EAAG,YAAY,aAAc,UAAU,EACjC,YAAY,YAAY,EACnB,IAAIb,CAAU,EAEpCY,EAAQ,UAAY,IAAM,CACxB,MAAME,EAASF,EAAQ,OAIrBH,EAHGK,EAGKA,aAAkB,WAAaA,EAAS,IAAI,WAAWA,CAAM,EAF7D,IAE8D,CAE1E,EACAF,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAEA,MAAM,cAAcV,EAAyBC,EAA2C,CACtF,MAAMU,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAsB,CAACJ,EAASC,IAAW,CAEpD,MAAMM,EADKH,EAAG,YAAY,aAAc,UAAU,EACjC,YAAY,YAAY,EACnCP,EAAuB,CAAA,EACvBW,EAAQd,IAAc,OACxB,YAAY,MAAMD,EAAiBA,EAAkBC,EAAY,CAAC,EAClE,YAAY,WAAWD,EAAiB,EAAK,EAC3CU,EAAUI,EAAM,WAAWC,CAAK,EAEtCL,EAAQ,UAAY,IAAM,CACxB,MAAMM,EAASN,EAAQ,OACvB,GAAIM,EAAQ,CACV,MAAMC,EAAMD,EAAO,MACnBZ,EAAO,KAAKa,aAAe,WAAaA,EAAM,IAAI,WAAWA,CAAG,CAAC,EACjED,EAAO,SAAA,CACT,MACET,EAAQH,CAAM,CAElB,EACAM,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAEA,MAAM,gBAAgBN,EAAqC,CACzD,GAAIA,EAAO,SAAW,EAAG,OACzB,MAAMO,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAC5C,MAAMK,EAAKF,EAAG,YAAY,aAAc,WAAW,EAC7CG,EAAQD,EAAG,YAAY,YAAY,EACnCK,EAAWJ,EAAM,MAAA,EAEvBI,EAAS,UAAY,IAAM,CACzB,IAAIC,EAAUD,EAAS,OACvB,UAAWnB,KAASK,EAAQ,CAC1B,MAAMd,EAAO,IAAI,WAAWS,EAAM,UAAU,EAC5CT,EAAK,IAAIS,CAAK,EACde,EAAM,IAAIxB,EAAM6B,GAAS,CAC3B,CACF,EAEAN,EAAG,WAAa,IAAMN,EAAA,EACtBM,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,EAClCA,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,CACpC,CAAC,CACH,CAEA,MAAM,UAA0B,CAEhC,CAEA,MAAM,YAAYf,EAAmC,CACnD,MAAMa,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAc,CAACJ,EAASC,IAAW,CAC5C,MAAMK,EAAKF,EAAG,YAAY,CAAC,aAAc,UAAU,EAAG,WAAW,EAC3DS,EAAcP,EAAG,YAAY,YAAY,EACzCQ,EAAYR,EAAG,YAAY,UAAU,EAE3C,GAAIf,IAAe,EACjBsB,EAAY,MAAA,EACZC,EAAU,OAAO,QAAQ,MACpB,CACL,MAAMN,EAAQ,YAAY,WAAWjB,EAAY,EAAK,EACtDsB,EAAY,OAAOL,CAAK,CAC1B,CAEAF,EAAG,WAAa,IAAMN,EAAA,EACtBM,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,EAClCA,EAAG,QAAU,IAAML,EAAOK,EAAG,KAAK,CACpC,CAAC,CACH,CAEA,MAAM,kBAAoC,CACxC,MAAMF,EAAK,MAAM,KAAK,MAAA,EACtB,OAAO,IAAI,QAAgB,CAACJ,EAASC,IAAW,CAG9C,MAAME,EAFKC,EAAG,YAAY,aAAc,UAAU,EACjC,YAAY,YAAY,EACnB,MAAA,EAEtBD,EAAQ,UAAY,IAAMH,EAAQG,EAAQ,MAAM,EAChDA,EAAQ,QAAU,IAAMF,EAAOE,EAAQ,KAAK,CAC9C,CAAC,CACH,CAEA,MAAM,OAAuB,CACvB,KAAK,aACI,MAAM,KAAK,WACnB,MAAA,EACH,KAAK,UAAY,KAErB,CACF,CCnQO,MAAMY,EAAsC,CAajD,YAAYhB,EAAgB,CAZnBnB,EAAA,YAAO,QACPA,EAAA,sBAEDA,EAAA,eACAA,EAAA,eAA4C,MAC5CA,EAAA,oBAA4C,MAC5CA,EAAA,qBAA6C,MAG7CA,EAAA,oBAAoB,MACpBA,EAAA,qBAAqB,MAG3B,KAAK,OAASmB,EACd,KAAK,cAAgB,OAAQ,WAAmB,2BAA+B,GACjF,CAEA,MAAc,aAA6B,OACzC,GAAI,MAAK,QAET,IAAI,GAACiB,EAAA,iCAAW,UAAX,MAAAA,EAAoB,cACvB,MAAM,IAAI,MAAM,+EAA+E,EAOjG,GAJA,KAAK,QAAU,MAAM,UAAU,QAAQ,aAAA,EACvC,KAAK,aAAe,MAAM,KAAK,QAAQ,cAAc,GAAG,KAAK,MAAM,MAAO,CAAE,OAAQ,EAAA,CAAM,EAC1F,KAAK,cAAgB,MAAM,KAAK,QAAQ,cAAc,GAAG,KAAK,MAAM,OAAQ,CAAE,OAAQ,EAAA,CAAM,EAExF,KAAK,cACP,GAAI,CACF,KAAK,aAAe,MAAO,KAAK,aAAqB,uBAAA,EACrD,KAAK,cAAgB,MAAO,KAAK,cAAsB,uBAAA,CACzD,MAAQ,CAER,EAEJ,CAEA,MAAM,SAASjE,EAA4C,CACzD,MAAM,KAAK,YAAA,EACX,MAAMkE,GAAUlE,EAAS,GAAK,KAE9B,GAAI,KAAK,aAAc,CACrB,MAAMlB,EAAO,KAAK,aAAa,QAAA,EAC/B,GAAIoF,EAAS,KAAOpF,EAAM,OAAO,KACjC,MAAMqF,EAAS,IAAI,WAAW,IAAI,EAClC,YAAK,aAAa,KAAKA,EAAQ,CAAE,GAAID,EAAQ,EACtCC,CACT,CAEA,MAAMC,EAAO,MAAM,KAAK,aAAc,QAAA,EACtC,GAAIF,EAAS,KAAOE,EAAK,KAAM,OAAO,KAEtC,MAAMC,EAAW,MADHD,EAAK,MAAMF,EAAQA,EAAS,IAAI,EACjB,YAAA,EAC7B,OAAO,IAAI,WAAWG,CAAQ,CAChC,CAEA,MAAM,UAAUrE,EAAgB+B,EAAiC,CAC/D,MAAM,KAAK,YAAA,EACX,MAAMmC,GAAUlE,EAAS,GAAK,KAE9B,GAAI,KAAK,aAAc,CACrB,KAAK,aAAa,MAAM+B,EAAM,CAAE,GAAImC,EAAQ,EAC5C,MACF,CAEA,MAAMI,EAAW,MAAO,KAAK,aAAqB,eAAe,CAAE,iBAAkB,GAAM,EAC3F,MAAMA,EAAS,KAAKJ,CAAM,EAC1B,MAAMI,EAAS,MAAMvC,CAAI,EACzB,MAAMuC,EAAS,MAAA,CACjB,CAEA,MAAM,WAAWrC,EAAmE,CAClF,SAAW,CAAE,OAAAjC,EAAQ,KAAA+B,CAAA,IAAUE,EAC7B,MAAM,KAAK,UAAUjC,EAAQ+B,CAAI,CAErC,CAEA,MAAM,OAAuB,CACvB,KAAK,cACP,KAAK,aAAa,MAAA,CAEtB,CAEA,MAAM,SAASG,EAAkC,CAC/C,MAAM,KAAK,YAAA,EACX,MAAMqC,EAAUrC,EAAY,KAC5B,GAAI,KAAK,aAAc,CACrB,KAAK,aAAa,SAASqC,CAAO,EAClC,MACF,CACA,MAAMD,EAAW,MAAO,KAAK,aAAqB,eAAe,CAAE,iBAAkB,GAAM,EAC3F,MAAMA,EAAS,SAASC,CAAO,EAC/B,MAAMD,EAAS,MAAA,CACjB,CAIA,MAAM,eAA4C,CAEhD,GADA,MAAM,KAAK,YAAA,EACP,KAAK,cAAe,CAEtB,GADa,KAAK,cAAc,QAAA,EACrB,GAAI,OAAO,KACtB,MAAM/B,EAAS,IAAI,WAAW,EAAE,EAChC,YAAK,cAAc,KAAKA,EAAQ,CAAE,GAAI,EAAG,EAClCA,CACT,CACA,MAAM6B,EAAO,MAAM,KAAK,cAAe,QAAA,EACvC,GAAIA,EAAK,KAAO,GAAI,OAAO,KAC3B,MAAMI,EAAQJ,EAAK,MAAM,EAAG,EAAE,EAC9B,OAAO,IAAI,WAAW,MAAMI,EAAM,aAAa,CACjD,CAEA,MAAM,eAAejC,EAAmC,CAEtD,GADA,MAAM,KAAK,YAAA,EACP,KAAK,cAAe,CACtB,KAAK,cAAc,MAAMA,EAAQ,CAAE,GAAI,EAAG,EAC1C,MACF,CACA,MAAM+B,EAAW,MAAO,KAAK,cAAsB,eAAe,CAAE,iBAAkB,GAAM,EAC5F,MAAMA,EAAS,KAAK,CAAC,EACrB,MAAMA,EAAS,MAAM/B,CAAM,EAC3B,MAAM+B,EAAS,MAAA,CACjB,CAEA,MAAM,aAAa9B,EAAgD,CACjE,MAAM,KAAK,YAAA,EACX,MAAM0B,EAAS,GAAM1B,EAAa,KAClC,GAAI,KAAK,cAAe,CACtB,MAAM1D,EAAO,KAAK,cAAc,QAAA,EAChC,GAAIoF,GAAUpF,EAAM,OAAO,KAC3B,MAAM2F,EAAU,KAAK,IAAI,KAAM3F,EAAOoF,CAAM,EACtCzB,EAAQ,IAAI,WAAWgC,CAAO,EACpC,YAAK,cAAc,KAAKhC,EAAO,CAAE,GAAIyB,EAAQ,EACtCzB,CACT,CACA,MAAM2B,EAAO,MAAM,KAAK,cAAe,QAAA,EACvC,GAAIF,GAAUE,EAAK,KAAM,OAAO,KAChC,MAAMK,EAAU,KAAK,IAAI,KAAML,EAAK,KAAOF,CAAM,EAC3CM,EAAQJ,EAAK,MAAMF,EAAQA,EAASO,CAAO,EACjD,OAAO,IAAI,WAAW,MAAMD,EAAM,aAAa,CACjD,CAEA,MAAM,cAAc9B,EAAyBC,EAA2C,CACtF,MAAMG,EAAuB,CAAA,EAC7B,IAAI4B,EAAMhC,EACV,MAAM3D,EAAQ4D,IAAc,OAAYD,EAAkBC,EAAY,IAEtE,KAAO+B,EAAM3F,GAAO,CAClB,MAAM0D,EAAQ,MAAM,KAAK,aAAaiC,CAAG,EACzC,GAAI,CAACjC,EAAO,MACZK,EAAO,KAAKL,CAAK,EACjBiC,GACF,CACA,OAAO5B,CACT,CAEA,MAAM,gBAAgBA,EAAqC,CAEzD,GADA,MAAM,KAAK,YAAA,EACP,KAAK,cAAe,CACtB,IAAIoB,EAAS,KAAK,IAAI,GAAI,KAAK,cAAc,SAAS,EACtD,UAAWzB,KAASK,EAClB,KAAK,cAAc,MAAML,EAAO,CAAE,GAAIyB,EAAQ,EAC9CA,GAAUzB,EAAM,WAElB,MACF,CACA,MAAM2B,EAAO,MAAM,KAAK,cAAe,QAAA,EACjCE,EAAW,MAAO,KAAK,cAAsB,eAAe,CAAE,iBAAkB,GAAM,EAC5F,MAAMA,EAAS,KAAK,KAAK,IAAI,GAAIF,EAAK,IAAI,CAAC,EAC3C,UAAW3B,KAASK,EAClB,MAAMwB,EAAS,MAAM7B,CAAK,EAE5B,MAAM6B,EAAS,MAAA,CACjB,CAEA,MAAM,UAA0B,CAC1B,KAAK,eACP,KAAK,cAAc,MAAA,CAEvB,CAEA,MAAM,YAAY9B,EAAmC,CACnD,MAAM,KAAK,YAAA,EACX,MAAM+B,EAAU/B,IAAe,EAAI,EAAI,GAAMA,EAAa,KAC1D,GAAI,KAAK,cAAe,CACtB,KAAK,cAAc,SAAS+B,CAAO,EACnC,MACF,CACA,MAAMD,EAAW,MAAO,KAAK,cAAsB,eAAe,CAChE,iBAAkB9B,EAAa,CAAA,CAChC,EACD,MAAM8B,EAAS,SAASC,CAAO,EAC/B,MAAMD,EAAS,MAAA,CACjB,CAEA,MAAM,kBAAoC,CACxC,MAAM,KAAK,YAAA,EACX,IAAIxF,EAAO,EAOX,OANI,KAAK,cACPA,EAAO,KAAK,cAAc,QAAA,EAG1BA,GADa,MAAM,KAAK,cAAe,QAAA,GAC3B,KAEVA,GAAQ,GAAW,EAChB,KAAK,MAAMA,EAAO,IAAM,IAAI,CACrC,CAEA,MAAM,OAAuB,CACvB,KAAK,eACP,KAAK,aAAa,MAAA,EAClB,KAAK,aAAe,MAElB,KAAK,gBACP,KAAK,cAAc,MAAA,EACnB,KAAK,cAAgB,MAEvB,KAAK,aAAe,KACpB,KAAK,cAAgB,KACrB,KAAK,QAAU,IACjB,CACF,CC5NA,MAAM6F,GAAY,IAAI,YAAY,GAAG,EAGrC,QAASrG,EAAI,EAAGA,EAAI,IAAKA,IAAK,CAC5B,IAAIC,EAAID,EACR,QAAS+D,EAAI,EAAGA,EAAI,EAAGA,IACrB9D,EAAKA,EAAI,EAAM,WAAcA,IAAM,EAAOA,IAAM,EAElDoG,GAAUrG,CAAC,EAAIC,IAAM,CACvB,CAKO,SAASqG,GAAM7C,EAAkB8C,EAAgB,EAAGC,EAAiB/C,EAAK,WAAa8C,EAAe,CAC3G,IAAIE,EAAM,WACV,MAAMnC,EAAMiC,EAAQC,EACpB,QAASxG,EAAIuG,EAAOvG,EAAIsE,EAAKtE,IAC3ByG,EAAMJ,IAAWI,EAAMhD,EAAKzD,CAAC,GAAK,GAAI,EAAKyG,IAAQ,EAErD,OAAQA,EAAM,cAAgB,CAChC,CAMO,SAASC,GAAoBC,EAA+B,CACjE,IAAIF,EAAM,WACV,QAASzG,EAAI,EAAGA,EAAI,KAAMA,IAAK,CAE7B,MAAM4G,EAAQ5G,GAAK,IAAMA,GAAK,GAAM,EAAI2G,EAAU3G,CAAC,EACnDyG,EAAMJ,IAAWI,EAAMG,GAAQ,GAAI,EAAKH,IAAQ,CAClD,CACA,OAAQA,EAAM,cAAgB,CAChC,CAMO,SAASI,GAAqBF,EAA+B,CAClE,IAAIF,EAAM,WACV,QAASzG,EAAI,EAAGA,EAAI,KAAMA,IAAK,CAE7B,MAAM4G,EAAQ5G,GAAK,IAAMA,GAAK,GAAM,EAAI2G,EAAU3G,CAAC,EACnDyG,EAAMJ,IAAWI,EAAMG,GAAQ,GAAI,EAAKH,IAAQ,CAClD,CACA,OAAQA,EAAM,cAAgB,CAChC,CAMO,SAASK,GAAwBC,EAAgC,CACtE,IAAIN,EAAM,WACV,QAASzG,EAAI,EAAGA,EAAI,GAAIA,IACtByG,EAAMJ,IAAWI,EAAMM,EAAW/G,CAAC,GAAK,GAAI,EAAKyG,IAAQ,EAE3D,MAAMnC,EAAM,KAAK,IAAIyC,EAAW,WAAY,IAAI,EAChD,QAAS/G,EAAI,GAAIA,EAAIsE,EAAKtE,IACxByG,EAAMJ,IAAWI,EAAMM,EAAW/G,CAAC,GAAK,GAAI,EAAKyG,IAAQ,EAE3D,OAAQA,EAAM,cAAgB,CAChC,CCtDO,SAASO,GACdC,EACAC,EACAC,EACAC,EACAC,EACM,CACN,MAAMC,EAAIL,aAAgB,WAAaA,EAAO,IAAI,WAAWA,EAAK,OAAQA,EAAK,WAAYA,EAAK,UAAU,EACpGM,EAAIJ,aAAe,WAAaA,EAAM,IAAI,WAAWA,EAAI,OAAQA,EAAI,WAAYA,EAAI,UAAU,EACrGG,EAAE,IAAIC,EAAE,SAASH,EAAYA,EAAaC,CAAC,EAAGH,CAAW,CAC3D,CAMO,SAASM,GACdP,EACAC,EACAjH,EACAoH,EACM,EACIJ,aAAgB,WAAaA,EAAO,IAAI,WAAWA,EAAK,OAAQA,EAAK,WAAYA,EAAK,UAAU,GACxG,KAAKhH,EAAI,IAAMiH,EAAaA,EAAcG,CAAC,CAC/C,CAOO,SAASI,GACdC,EACAC,EACAC,EACAC,EACAR,EACQ,CACR,MAAMS,EAAKJ,aAAc,WAAaA,EAAK,IAAI,WAAWA,EAAG,OAAQA,EAAG,WAAYA,EAAG,UAAU,EAC3FK,EAAKH,aAAc,WAAaA,EAAK,IAAI,WAAWA,EAAG,OAAQA,EAAG,WAAYA,EAAG,UAAU,EACjG,QAAS5H,EAAI,EAAGA,EAAIqH,EAAGrH,IAAK,CAC1B,MAAMgI,EAAOF,EAAGH,EAAY3H,CAAC,EAAI+H,EAAGF,EAAY7H,CAAC,EACjD,GAAIgI,IAAS,EAAG,OAAOA,CACzB,CACA,MAAO,EACT,CAMO,SAASC,GAAOV,EAAmB,CACxC,OAAOA,EAAE,MACX,CAOO,SAASW,GAAQC,EAA6BvC,EAAwB,CAC3E,OAAOuC,aAAgB,WAAaA,EAAKvC,CAAM,EAAIuC,EAAK,SAASvC,CAAM,CACzE,CAEO,SAASwC,GACdD,EACAvC,EACAP,EACM,CACF8C,aAAgB,WAClBA,EAAKvC,CAAM,EAAIP,EAAM,IAErB8C,EAAK,SAASvC,EAAQP,EAAM,GAAI,CAEpC,CAEO,SAASgD,GAASF,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,UAAUvC,EAAQ,EAAI,CACpC,CAEO,SAAS0C,GAAUH,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,UAAUvC,EAAQP,EAAM,MAAQ,EAAI,CAC3C,CAEO,SAASkD,GAASJ,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,UAAUvC,EAAQ,EAAI,CACpC,CAEO,SAAS4C,GAAUL,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,UAAUvC,EAAQP,IAAQ,EAAG,EAAI,CACxC,CAEO,SAASoD,GAASN,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,SAASvC,EAAQ,EAAI,CACnC,CAEO,SAAS8C,GAAUP,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,SAASvC,EAAQP,EAAM,EAAG,EAAI,CACrC,CAEO,SAASsD,GAASR,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,WAAWvC,EAAQ,EAAI,CACrC,CAEO,SAASgD,GAAUT,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,WAAWvC,EAAQP,EAAK,EAAI,CACnC,CAEO,SAASwD,GAASV,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,aAAavC,EAAQ,EAAI,CACvC,CAEO,SAASkD,GAAUX,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,aAAavC,EAAQP,EAAK,EAAI,CACrC,CAEO,SAAS0D,GAASZ,EAAgBvC,EAAwB,CAC/D,OAAOuC,EAAK,YAAYvC,EAAQ,EAAI,CACtC,CAEO,SAASoD,GAAUb,EAAgBvC,EAAgBP,EAAmB,CAC3E8C,EAAK,YAAYvC,EAAQP,EAAK,EAAI,CACpC,CAMO,SAAS4D,GAAQC,EAAkBC,EAAuBC,EAA0B,CACzF,OAAIA,IAAY,OACNF,EAAKC,GAAiBC,GAAW,EAAE,EAAK,IAAMA,EAAU,GAAa,EAAI,EAE3EF,EAAKC,GAAiB,CAAC,EAAK,IAAMA,EAAgB,GAAa,EAAI,CAC7E,CAEO,SAASE,GAAQH,EAAkBC,EAAuBC,EAAwB,CACnFA,IAAY,OACdF,EAAKC,GAAiBC,GAAW,EAAE,GAAM,IAAMA,EAAU,GAEzDF,EAAKC,GAAiB,CAAC,GAAM,IAAMA,EAAgB,EAEvD,CAEO,SAASG,GAAUJ,EAAkBC,EAAuBC,EAAwB,CACrFA,IAAY,OACdF,EAAKC,GAAiBC,GAAW,EAAE,GAAK,EAAE,IAAMA,EAAU,IAE1DF,EAAKC,GAAiB,CAAC,GAAK,EAAE,IAAMA,EAAgB,GAExD,CAMO,SAASI,GAASC,EAAeC,EAA2B,CACjE,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,qBAAqBC,CAAG,EAAE,CAE9C,CClJO,MAAMC,EAAG,CA2Cd,YAAYC,EAAoB,CA1CvBpG,EAAA,YACAA,EAAA,eACAA,EAAA,cACAA,EAAA,aAEDA,EAAA,6BAAwB,KACxBA,EAAA,2BAAsB,KACtBA,EAAA,mBAMG,MA8BT,GAAI,CAACoG,EAAQ,IACX,MAAM,IAAI,MAAM,0CAA0C,EAG5D,GAAI,CAACA,EAAQ,OACX,MAAM,IAAI,MACR,yDAAA,EAIJ,KAAK,IAAMA,EAAQ,IAEnB,KAAK,OACHA,EAAQ,kBAAkB,YAAY,OAClCA,EAAQ,OAAO,OACfA,EAAQ,OAEd,KAAK,MAAQ,IAAI,WAAW,KAAK,MAAM,EACvC,KAAK,KAAO,IAAI,SAAS,KAAK,MAAM,CACtC,CA/CA,0BAA0BC,EAAwB,CAChD,KAAK,YAAcA,CACrB,CAEA,iBAA2B,CACzB,OAAO,KAAK,YAAc,KAAK,YAAY,kBAAoB,EACjE,CAKA,kBAAkBC,EAAiBnI,EAAsB,CACvD,MAAMoI,EAAcD,EAAU,KACxBE,EAAa,KAAK,MAAM,SAC5BD,EACAA,EAAc,IAAA,EAGhB,GAAIpI,IAAW,EAAG,CAChB,MAAMsI,EAAMnD,GAAqBkD,CAAU,EAC3CvB,GAAU,KAAK,KAAMsB,EAAc/S,GAA6BiT,CAAG,CACrE,KAAO,CACL,MAAMA,EAAMtD,GAAoBqD,CAAU,EAC1CvB,GAAU,KAAK,KAAMsB,EAAcjU,GAA6BmU,CAAG,CACrE,CACF,CA4BA,MAAM,SAASH,EAAiBnI,EAA+B,CAC7D,GAAIA,GAAU,EACZ,MAAM,IAAI,MACR,oBAAoBA,CAAM,uCAAA,EAI9B,GAAI,KAAK,aAAe,KAAK,YAAY,eAAeA,CAAM,EAAG,CAC/D,MAAMoI,EAAcD,EAAU,KACxBI,EAAU,KAAK,YAAY,eAAevI,CAAM,EACtD,KAAK,MAAM,IAAIuI,EAASH,CAAW,EACnC,MACF,CAGA,MAAMI,EAAkB,KAAK,kBAAkB,IAAIxI,CAAM,EAErDwI,GACF,MAAMA,EAIR,MAAMC,EAAiB,KAAK,gBAAgB,IAAIzI,CAAM,EAEtD,GAAIyI,EAAgB,CAClB,MAAMA,EACN,MACF,CAEA,MAAMC,GAAgB,SAAY,CAChC,MAAMC,EAAY,MAAM,KAAK,IAAI,SAAS3I,CAAM,EAC1CoI,EAAcD,EAAU,KAE9B,GAAIQ,EAAW,CACb,GAAIA,EAAU,aAAe,KAC3B,MAAM,IAAI5I,GACRC,EACA,gCAAgC2I,EAAU,UAAU,iBAAuB,EAK/E,MAAMC,EACJ5I,IAAW,EACP3K,GACAlB,GAEA0U,EAAkBhC,GACtB,IAAI,SAAS8B,EAAU,OAAQA,EAAU,UAAU,EACnDC,CAAA,EAGF,GAAIC,IAAoB,EAAG,CACzB,MAAMC,EACJ9I,IAAW,EACPmF,GAAqBwD,CAAS,EAC9B3D,GAAoB2D,CAAS,EAEnC,GAAIG,IAAaD,EACf,MAAM,IAAI9I,GAAiBC,EAAQ6I,EAAiBC,CAAQ,CAEhE,CAEA,KAAK,MAAM,IAAIH,EAAWP,CAAW,CACvC,MACE,KAAK,MAAM,KAAK,EAAGA,EAAaA,EAAc,IAAS,CAE3D,GAAA,EAEA,KAAK,gBAAgB,IAAIpI,EAAQ0I,CAAY,EAE7C,GAAI,CACF,MAAMA,CACR,QAAA,CACE,KAAK,gBAAgB,OAAO1I,CAAM,CACpC,CACF,CAMA,MAAM,UAAUmI,EAAiBnI,EAA+B,CAC9D,GAAIA,GAAU,EACZ,MAAM,IAAI,MACR,oBAAoBA,CAAM,uCAAA,EAI9B,MAAM+I,EAAiB,KAAK,kBAAkB,IAAI/I,CAAM,EACxD,GAAI+I,EAAgB,CAClB,MAAMA,EACN,MACF,CAEA,MAAMX,EAAcD,EAAU,KACxBE,EAAa,KAAK,MAAM,SAC5BD,EACAA,EAAc,IAAA,EAGhB,KAAK,kBAAkBD,EAASnI,CAAM,EAEtC,MAAMgJ,EAAiBX,EAAW,MAAA,EAC9B,KAAK,aACP,KAAK,YAAY,kBAAkBrI,EAAQgJ,CAAc,EAE3D,MAAMC,EAAgB,KAAK,IAAI,UAAUjJ,EAAQgJ,CAAc,EAC/D,KAAK,kBAAkB,IAAIhJ,EAAQiJ,CAAa,EAChD,GAAI,CACF,MAAMA,CACR,QAAA,CACE,KAAK,kBAAkB,OAAOjJ,CAAM,CACtC,CACF,CAKA,MAAM,iBAAiBmI,EAAiBnI,EAA+B,CACjE,KAAK,aAAe,KAAK,YAAY,kBACvC,MAAM,KAAK,YAAY,qBAAqBmI,EAASnI,CAAM,EAE3D,MAAM,KAAK,UAAUmI,EAASnI,CAAM,CAExC,CAOA,MAAM,iBACJkJ,EACAC,EACAC,EACe,CASf,GARIA,EAAc,IACZ,KAAK,aAAe,KAAK,YAAY,kBACvC,MAAM,KAAK,YAAY,qBAAqBF,EAAYE,CAAW,EAEnE,MAAM,KAAK,UAAUF,EAAYE,CAAW,GAI5C,KAAK,aAAe,KAAK,YAAY,eAAeD,CAAW,EAAG,CACpE,MAAMf,EAAcc,EAAa,KAC3BX,EAAU,KAAK,YAAY,eAAeY,CAAW,EAC3D,KAAK,MAAM,IAAIZ,EAASH,CAAW,CACrC,MACE,MAAM,KAAK,SAASc,EAAYC,CAAW,CAE/C,CAKA,MAAM,OAAuB,CAC3B,MAAM,KAAK,IAAI,MAAA,CACjB,CACF,CCpOO,MAAME,GAAkB,IAAI,WAAW,CAAC,GAAM,GAAM,GAAM,GAAM,GAAM,EAAI,CAAC,EA8B3E,SAASC,GAAoB/G,EAAiC,GAAgB,CACnF,MAAMgH,EAAQ,IAAI,WAAW7N,EAAoB,EAC3C+K,EAAO,IAAI,SAAS8C,EAAM,OAAQA,EAAM,WAAYA,EAAM,UAAU,EAG1EA,EAAM,IAAIF,GAAiB1N,EAAuB,EAGlDiL,GAAUH,EAAM7K,GAA+B2G,EAAO,YAAcnH,EAAmB,EAGvF0L,GAAUL,EAAM5K,GAA6B0G,EAAO,UAAYrH,EAAa,EAG7E4L,GAAUL,EAAM3K,GAAkCyG,EAAO,eAAiB,CAAC,EAG3E,MAAMiH,EAAQjH,EAAO,OAAU,KAAK,MAAM,KAAK,OAAA,EAAW,UAAU,IAAM,EAC1EuE,GAAUL,EAAM1K,GAAyByN,CAAK,EAG9C,MAAMC,EAAQlH,EAAO,OAAU,KAAK,MAAM,KAAK,OAAA,EAAW,UAAU,IAAM,EAC1EuE,GAAUL,EAAMzK,GAAyByN,CAAK,EAG9C,MAAMC,EAAWnH,EAAO,UAAYqC,GAAM2E,EAAO,EAAG,EAAE,EACtD,OAAAzC,GAAUL,EAAMxK,GAA4ByN,CAAQ,EAGpD5C,GAAUL,EAAMvK,GAA4B,CAAC,EAEtCqN,CACT,CAKO,SAASI,GAAoBJ,EAAmBK,EAA0B,GAAqB,CACpG,GAAIL,EAAM,WAAa7N,GACrB,MAAM,IAAIgG,GACR,gDAAgDhG,EAAoB,oBAAoB6N,EAAM,UAAU,EAAA,EAK5G,QAASjL,EAAI,EAAGA,EAAI,EAAGA,IACrB,GAAIiL,EAAM5N,GAA0B2C,CAAC,IAAM+K,GAAgB/K,CAAC,EAC1D,MAAM,IAAIoD,GACR,8DAAA,EAKN,MAAM+E,EAAO,IAAI,SAAS8C,EAAM,OAAQA,EAAM,WAAYA,EAAM,UAAU,EACpEM,EAAalD,GAASF,EAAM7K,EAA6B,EACzDkO,EAAWjD,GAASJ,EAAM5K,EAA2B,EACrDkO,EAAgBlD,GAASJ,EAAM3K,EAAgC,EAC/D0N,EAAQ3C,GAASJ,EAAM1K,EAAuB,EAC9C0N,EAAQ5C,GAASJ,EAAMzK,EAAuB,EAC9C0N,EAAW7C,GAASJ,EAAMxK,EAA0B,EAE1D,GAAI2N,EAAgB,CAClB,MAAMd,EAAWlE,GAAM2E,EAAO,EAAG,EAAE,EACnC,GAAIG,IAAaZ,EACf,MAAM,IAAIpH,GACR,mDAAmDgI,CAAQ,cAAcZ,CAAQ,EAAA,CAGvF,CAEA,MAAO,CACL,WAAAe,EACA,SAAAC,EACA,cAAAC,EACA,MAAAP,EACA,MAAAC,EACA,SAAAC,CAAA,CAEJ,CAKO,SAASM,GACdzH,EACA0H,EACY,CACZ,MAAM5E,EAAa,IAAI,WAAWlK,EAAc,EAC1CsL,EAAO,IAAI,SAASpB,EAAW,OAAQA,EAAW,WAAYA,EAAW,UAAU,EAGzFyB,GAAUL,EAAMpK,GAAwBkG,EAAO,OAASlH,EAAe,EAGvEuL,GAAUH,EAAMnK,GAA6BiG,EAAO,SAAS,EAG7DqE,GAAUH,EAAMlK,GAAwBgG,EAAO,OAAS,CAAC,EAGzDuE,GAAUL,EAAMjK,GAAwB+F,EAAO,IAAI,EAGnDuE,GAAUL,EAAMhK,GAA0B8F,EAAO,MAAM,EAGvDuE,GAAUL,EAAM/J,GAAgC6F,EAAO,aAAe,CAAC,EAGvEuE,GAAUL,EAAM9J,GAA4B4F,EAAO,QAAQ,EAG3DuE,GAAUL,EAAM5J,GAA2B,CAAC,EAGxCoN,GACF5E,EAAW,IAAI4E,EAAS,SAAS,EAAG/O,EAAa,EAAGkB,EAAqB,EAI3E,MAAMsN,EAAWnH,EAAO,UAAY6C,GAAwBC,CAAU,EACtE,OAAAyB,GAAUL,EAAM7J,GAA2B8M,CAAQ,EAE5CrE,CACT,CAKO,SAAS6E,GAAqB7E,EAAwC,CAC3E,GAAIA,EAAW,WAAajJ,GAC1B,MAAM,IAAIuF,GACR,iDAAiDvF,EAAqB,oBAAoBiJ,EAAW,UAAU,EAAA,EAInH,MAAMoB,EAAO,IAAI,SAASpB,EAAW,OAAQA,EAAW,WAAYA,EAAW,UAAU,EACzF,MAAO,CACL,MAAOwB,GAASJ,EAAMpK,EAAsB,EAC5C,UAAWsK,GAASF,EAAMnK,EAA2B,EACrD,MAAOqK,GAASF,EAAMlK,EAAsB,EAC5C,KAAMsK,GAASJ,EAAMjK,EAAsB,EAC3C,OAAQqK,GAASJ,EAAMhK,EAAwB,EAC/C,YAAaoK,GAASJ,EAAM/J,EAA8B,EAC1D,SAAUmK,GAASJ,EAAM9J,EAA0B,EACnD,SAAUkK,GAASJ,EAAM7J,EAAyB,CAAA,CAEtD,CAMO,SAASuN,GAAiB9E,EAI/B,CACA,GAAIA,EAAW,WAAalK,GAC1B,MAAO,CAAE,MAAO,GAAO,OAAQ,WAAA,EAGjC,MAAMoH,EAAS2H,GAAqB7E,CAAU,EAC9C,GAAI9C,EAAO,QAAUlH,GACnB,MAAO,CAAE,MAAO,GAAO,OAAQ,iBAAkB,OAAAkH,CAAA,EAGnD,MAAMrC,EAAmBkF,GAAwBC,CAAU,EAC3D,OAAI9C,EAAO,WAAarC,EACf,CAAE,MAAO,GAAO,OAAQ,oBAAqB,OAAAqC,CAAA,EAG/C,CAAE,MAAO,GAAM,OAAAA,CAAA,CACxB,CAKO,SAAS6H,GAAe/E,EAAwBuE,EAA0B,GAAgB,CAC/F,GAAIvE,EAAW,WAAalK,GAC1B,MAAM,IAAIwG,GACR,iCAAiCxG,EAAc,oBAAoBkK,EAAW,UAAU,EAAA,EAI5F,MAAM9C,EAAS2H,GAAqB7E,CAAU,EAC9C,GAAI9C,EAAO,QAAUlH,GACnB,MAAM,IAAIsG,GACR,uCAAuCtG,GAAgB,SAAS,EAAE,CAAC,WAAWkH,EAAO,MAAM,SAAS,EAAE,CAAC,EAAA,EAI3G,GAAIqH,EAAgB,CAClB,MAAMd,EAAW1D,GAAwBC,CAAU,EACnD,GAAI9C,EAAO,WAAauG,EACtB,MAAM,IAAInH,GACR,6CAA6CY,EAAO,QAAQ,cAAcuG,CAAQ,EAAA,CAGxF,CAEA,MAAMmB,EAAW5E,EAAW,SAASjJ,GAAuBjB,EAAc,EAC1E,MAAO,CAAE,OAAAoH,EAAQ,SAAA0H,CAAA,CACnB,CC/PA,MAAMI,GAAe,IAAI,YAEZC,GAAY,mBACZC,GAAqB,mCAKlC,SAASC,GAAQjM,EAAa,CAC5B,OAAIA,GAAK,IAAMA,GAAK,GAAWA,EAAI,GAC/BA,GAAK,IAAMA,GAAK,IAAYA,EAAI,GAAK,GACrCA,GAAK,IAAMA,GAAK,GAAWA,EAAI,GAAK,GACjC,EACT,CAKA,SAASkM,GAAiBlM,EAAa,CACrC,GAAIA,GAAK,IAAMA,GAAK,UAAWA,EAAI,GAGnC,OAFIA,GAAK,IAAMA,GAAK,QAASA,EAAI,IAEzBA,EAAA,CACN,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IAAI,MAAO,IAChB,IAAK,IACL,IAAK,IAAI,MAAO,GAChB,IAAK,IAAI,MAAO,GAChB,QAAS,MAAO,EAAA,CAEpB,CASO,SAASmM,GACdC,EACAC,EACA1G,EACK,CACL,IAAI2G,EAAY,EACZC,EAAK,GAET,QAASxM,EAAI,EAAGA,EAAIiI,GAAOoE,CAAQ,EAAGrM,IAAK,CACzC,MAAMC,EAAIoM,EAAS,WAAWrM,CAAC,EAC/B,GAAIC,IAAM,GAAI,CACZ,GAAIsM,GAAa,GAAI,MAAO,GAC5B,MAAMlH,EAAM6G,GAAQjM,CAAC,EACrB,GAAIoF,EAAM,EAAG,MAAO,GAChBkH,EAAY,IAAM,EACpBC,EAAKnH,EAELiH,EAAO1G,GAAU2G,GAAa,EAAE,EAAKC,GAAM,EAAKnH,EAElDkH,GACF,CACF,CAEA,OAAIA,IAAc,GAAW,GACtB,CACT,CAKO,SAASE,GACdC,EACA9G,EACA+G,EACM,CACN,IAAIC,EAAU,EACd,QAAS,EAAI,EAAG,EAAI,GAAI,IAAK,EACvB,IAAM,GAAK,IAAM,GAAK,IAAM,GAAK,IAAM,MACzCD,EAAQC,GAAS,EAAI,IAEvB,MAAMC,EAAIH,EAAO9G,EAAS,CAAC,EAC3B+G,EAAQC,GAAS,EAAIZ,GAAU,WAAYa,GAAK,EAAK,EAAI,EACzDF,EAAQC,GAAS,EAAIZ,GAAU,WAAWa,EAAI,EAAI,CACpD,CACAF,EAAQC,CAAO,EAAI,CACrB,CAEO,MAAME,EAAU,CAErB,OAAO,OACLT,EACAC,EACA1G,EAAiB,EACX,CAEN,GADYwG,GAAYC,EAAUC,EAAQ1G,CAAM,IACpC,EACV,MAAM,IAAI,MACR,yBAAyByG,CAAQ,wCAAA,CAGvC,CAGA,OAAO,OAAOK,EAAoB9G,EAAiB,EAAW,CAC5D,MAAMmH,EAAM,IAAI,WAAW,EAAE,EAC7B,OAAAN,GAAYC,EAAQ9G,EAAQmH,CAAG,EACxBhB,GAAa,OAAOgB,EAAI,SAAS,EAAG,EAAE,CAAC,CAChD,CACF,CASO,SAASC,GACdC,EACAX,EACA1G,EACK,CACL,GAAIqC,GAAOgF,CAAQ,IAAM,GAAI,MAAO,GAEpC,IAAIC,EAAY,GAChB,QAASlN,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,MAAMgE,EAAImI,GAAiBc,EAAS,WAAWjN,CAAC,CAAC,EACjD,GAAIgE,EAAI,EAAG,MAAO,GAClBkJ,EAAQA,GAAQ,GAAM,OAAOlJ,CAAC,CAChC,CAEAsI,EAAO1G,EAAS,CAAC,EAAI,OAAQsH,GAAQ,IAAO,KAAK,EACjDZ,EAAO1G,EAAS,CAAC,EAAI,OAAQsH,GAAQ,IAAO,KAAK,EACjDZ,EAAO1G,EAAS,CAAC,EAAI,OAAQsH,GAAQ,IAAO,KAAK,EACjDZ,EAAO1G,EAAS,CAAC,EAAI,OAAQsH,GAAQ,IAAO,KAAK,EACjDZ,EAAO1G,EAAS,CAAC,EAAI,OAAQsH,GAAQ,GAAM,KAAK,EAChDZ,EAAO1G,EAAS,CAAC,EAAI,OAAOsH,EAAO,KAAK,EAExC,IAAIC,EAAe,GACnB,QAASnN,EAAI,GAAIA,EAAI,GAAIA,IAAK,CAC5B,MAAMgE,EAAImI,GAAiBc,EAAS,WAAWjN,CAAC,CAAC,EACjD,GAAIgE,EAAI,EAAG,MAAO,GAClBmJ,EAAWA,GAAW,GAAM,OAAOnJ,CAAC,CACtC,CAEA,IAAIoJ,EAAe,GACnB,QAASpN,EAAI,GAAIA,EAAI,GAAIA,IAAK,CAC5B,MAAMgE,EAAImI,GAAiBc,EAAS,WAAWjN,CAAC,CAAC,EACjD,GAAIgE,EAAI,EAAG,MAAO,GAClBoJ,EAAWA,GAAW,GAAM,OAAOpJ,CAAC,CACtC,CAEA,QAAShE,EAAI,EAAGA,EAAI,EAAGA,IACrBsM,EAAO1G,EAAS,EAAI5F,CAAC,EAAI,OAAQmN,GAAW,QAAQ,EAAInN,GAAK,CAAC,EAAK,KAAK,EACxEsM,EAAO1G,EAAS,GAAK5F,CAAC,EAAI,OAAQoN,GAAW,QAAQ,EAAIpN,GAAK,CAAC,EAAK,KAAK,EAG3E,MAAO,EACT,CAKO,SAASqN,GACdX,EACA9G,EACA+G,EACM,CACN,IAAIO,EAAY,GAChB,QAASlN,EAAI,EAAGA,EAAI,EAAGA,IACrBkN,EAAQA,GAAQ,GAAM,OAAOR,EAAO9G,EAAS5F,CAAC,CAAC,EAGjD,QAASA,EAAI,EAAGA,GAAK,EAAGA,IACtB2M,EAAQ3M,CAAC,EAAIiM,GAAmB,WAAW,OAAOiB,EAAO,GAAG,CAAC,EAC7DA,GAAQ,IAGV,IAAIC,EAAe,GACnB,QAASnN,EAAI,EAAGA,EAAI,EAAGA,IACrBmN,EAAWA,GAAW,GAAM,OAAOT,EAAO9G,EAAS,EAAI5F,CAAC,CAAC,EAG3D,IAAIoN,EAAe,GACnB,QAASpN,EAAI,EAAGA,EAAI,EAAGA,IACrBoN,EAAWA,GAAW,GAAM,OAAOV,EAAO9G,EAAS,GAAK5F,CAAC,CAAC,EAG5D,QAASA,EAAI,GAAIA,GAAK,GAAIA,IACxB2M,EAAQ3M,CAAC,EAAIiM,GAAmB,WAAW,OAAOmB,EAAU,GAAG,CAAC,EAChEA,IAAY,GAGd,QAASpN,EAAI,GAAIA,GAAK,GAAIA,IACxB2M,EAAQ3M,CAAC,EAAIiM,GAAmB,WAAW,OAAOkB,EAAU,GAAG,CAAC,EAChEA,IAAY,GAGdR,EAAQ,EAAE,EAAI,CAChB,CAEO,MAAMW,EAAU,CAErB,OAAO,OACLL,EACAX,EACA1G,EAAiB,EACX,CAEN,GADYoH,GAAYC,EAAUX,EAAQ1G,CAAM,IACpC,EACV,MAAM,IAAI,MACR,yBAAyBqH,CAAQ,4CAAA,CAGvC,CAGA,OAAO,OAAOP,EAAoB9G,EAAiB,EAAW,CAC5D,MAAMmH,EAAM,IAAI,WAAW,EAAE,EAC7B,OAAAM,GAAYX,EAAQ9G,EAAQmH,CAAG,EACxBhB,GAAa,OAAOgB,EAAI,SAAS,EAAG,EAAE,CAAC,CAChD,CACF,CC5NA,MAAMQ,GAAe,IAAI,YACnBxB,GAAe,IAAI,YAuBlB,SAASyB,GACdrF,EACAsF,EACAC,EAAgB3O,GAChB4O,EAAoB,EACd,CACNxF,EAAK,SAASsF,EAAc,EAAGC,CAAS,EACxCvF,EAAK,SAASsF,EAAc,EAAG,CAAC,EAChCtF,EAAK,UAAUsF,EAAc,EAAG,EAAG,EAAI,EACvCtF,EAAK,UAAUsF,EAAc,EAAG,KAAW,EAAI,EAC/CtF,EAAK,UAAUsF,EAAc,EAAGE,EAAc,EAAI,EAClDxF,EAAK,UAAUsF,EAAc,GAAI,EAAG,EAAI,EACxCtF,EAAK,UAAUsF,EAAc5X,GAA6B,EAAG,EAAI,CACnE,CAMO,SAAS+X,GACdzF,EACAsF,EACAI,EAAyB,EACnB,CACN1F,EAAK,SAASsF,EAAc,EAAG/O,EAAc,EAC7CyJ,EAAK,SAASsF,EAAc,EAAG,CAAC,EAChCtF,EAAK,UAAUsF,EAAc,EAAG,EAAG,EAAI,EACvCtF,EAAK,UAAUsF,EAAc,EAAG,EAAG,EAAI,EACvCtF,EAAK,UAAUsF,EAAc,EAAGI,EAAmB,EAAI,EACvD1F,EAAK,UAAUsF,EAAc,GAAI,EAAG,EAAI,EACxCtF,EAAK,UAAUsF,EAAc5X,GAA6B,EAAG,EAAI,CACnE,CAMO,SAASiY,GAAc3F,EAAgBsF,EAAsB,CAClE,OAAOtF,EAAK,SAASsF,EAAc,CAAC,CACtC,CAMO,SAASM,GACd5F,EACAsF,EACAO,EACM,CACN7F,EAAK,SAASsF,EAAc,EAAGO,CAAI,CACrC,CAMO,SAASC,GACd9F,EACAsF,EACK,CACL,OAAOtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,CAC7C,CAMO,SAASS,GACd/F,EACAsF,EACA1K,EACM,CACNoF,EAAK,UAAUsF,EAAc,EAAG1K,EAAO,EAAI,CAC7C,CAMO,SAASoL,GACdhG,EACAsF,EACK,CACL,OAAOtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,CAC7C,CAMO,SAASW,GACdjG,EACAsF,EACA7H,EACM,CACNuC,EAAK,UAAUsF,EAAc,EAAG7H,EAAQ,EAAI,CAC9C,CAMO,SAASyI,GACdlG,EACAsF,EACK,CACL,OAAOtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,CAC7C,CAMO,SAASa,GACdnG,EACAsF,EACAE,EACM,CACNxF,EAAK,UAAUsF,EAAc,EAAGE,EAAc,EAAI,CACpD,CAMO,SAASY,GACdpG,EACAsF,EACK,CACL,OAAOtF,EAAK,UAAUsF,EAAc,GAAI,EAAI,CAC9C,CAMO,SAASe,GACdrG,EACAsF,EACAgB,EACM,CACNtG,EAAK,UAAUsF,EAAc,GAAIgB,EAAY,EAAI,CACnD,CAMO,SAASC,GAAkBvG,EAAgBsF,EAAuB,CACvE,OAAOtF,EAAK,UAAUsF,EAAc5X,GAA6B,EAAI,CACvE,CAMO,SAAS8Y,GACdxG,EACAsF,EACArC,EACM,CACNjD,EAAK,UAAUsF,EAAc5X,GAA6BuV,EAAU,EAAI,CAC1E,CAMO,SAASwD,GACdzG,EACAsF,EACAoB,EACK,CACL,MAAMC,EAAkBrB,EAAcnY,GAAmBuZ,EAAW,EACpE,OAAO1G,EAAK,UAAU2G,EAAiB,EAAI,CAC7C,CAMO,SAASC,GACd5G,EACAsF,EACAoB,EACAG,EACM,CACN,MAAMF,EAAkBrB,EAAcnY,GAAmBuZ,EAAW,EACpE1G,EAAK,UAAU2G,EAAiBE,EAAa,EAAI,CACnD,CAMO,SAASC,GACd9G,EACAsF,EACK,CACL,MAAMyB,EAAajB,GAAoB9F,EAAMsF,CAAW,EAClD0B,EAAsBhB,GAA6BhG,EAAMsF,CAAW,EACpE2B,EAAe9Z,GAAmB4Z,EAAa,EACrD,OAAQC,EAAsBC,CAChC,CAMO,SAASC,GACdlH,EACAsF,EACK,CACL,OACEwB,GAA+B9G,EAAMsF,CAAW,EAChDc,GAAoBpG,EAAMsF,CAAW,CAEzC,CAYO,SAAS6B,GACdnH,EACAsF,EACA8B,EAAyB,EACzBC,EACM,CACN,MAAMN,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIyB,IAAe,EAAG,CACpBd,GAA6BjG,EAAMsF,EAAa,IAAS,EACzDe,GAAoBrG,EAAMsF,EAAa,CAAC,EACxC,MACF,CAGA,IAAIgC,EAAyBtH,EACzBuH,EAAeH,EAEnB,GAAIA,IAAsB,GAAKA,IAAsB9B,GAAe8B,EAAoB,KAAYpH,EAAK,WAAY,CACnH,MAAMwH,EAAY,IAAI,WAAW,IAAS,EAC1CF,EAAe,IAAI,SAASE,EAAU,MAAM,EAC5CD,EAAU,CACZ,CAGA1I,GAAOyI,EAAcC,EAASvH,EAAMsF,EAAanY,EAAgB,EAGjE,IAAIsa,EAAsB,KAE1B,QAAS5P,EAAI,EAAGA,EAAIkP,EAAYlP,IAAK,CACnC,IAAI6P,EAAW,EACXC,EAAkC3H,EAClC4H,EAAiB,EAErB,GAAIP,GAAexP,IAAMwP,EAAY,SACnCK,EAAML,EAAY,UAAU,WAC5BM,EAAWN,EAAY,UACvBO,EAAY,MACP,CACL,MAAMC,EAAapB,GAAqBzG,EAAMsF,EAAazN,CAAQ,EACpD8N,GAAc3F,EAAMsF,CAAW,IAC/B5O,GAEbgR,EAAO,EADO1H,EAAK,UAAUsF,EAAcuC,EAAY,EAAI,EACxC,EAEnBH,EAAMI,GAAoB9H,EAAMsF,EAAcuC,CAAU,EAE1DF,EAAW3H,EACX4H,EAAYtC,EAAcuC,CAC5B,CAEAJ,EAAkBA,EAAiBC,EACnC7I,GAAOyI,EAAcC,EAAUE,EAAgBE,EAAUC,EAAWF,CAAG,EAGvEd,GAAqBU,EAAcC,EAAS1P,EAAU4P,CAAc,CACtE,CAGAxB,GAA6BqB,EAAcC,EAASE,CAAc,EAClEpB,GAAoBiB,EAAcC,EAAS,CAAC,EAG5C1I,GAAOmB,EAAMsF,EAAagC,EAAcC,EAAS,IAAS,CAC5D,CAMO,SAASO,GACd9H,EACA+H,EACK,CACL,OAAO/H,EAAK,UAAU+H,EAAiB,EAAG,EAAI,CAChD,CAUO,SAASC,GACdhI,EACAsF,EACA2C,EACAb,EACQ,CACR,MAAML,EAAajB,GAAoB9F,EAAMsF,CAAW,EAClD0B,EAAsBhB,GAA6BhG,EAAMsF,CAAW,EACpE4C,EAAeD,EAAU,WAAa,EAEtChB,EAAe9Z,GAAmB4Z,EAAa,EAC/CoB,EAAkBnB,EAAsBC,EACxCmB,EAAaD,EAAkB/B,GAAoBpG,EAAMsF,CAAW,EAE1E,GAAI4C,EAAeE,EACjB,MAAO,GAGLF,EAAeC,GAEjBhB,GAAanH,EAAMsF,EAAa8B,CAAiB,EAGnD,MAAMiB,EAAyBrC,GAC7BhG,EACAsF,CAAA,EAEIgD,EAAqBxC,GAAoB9F,EAAMsF,CAAW,EAG1DiD,EAAqBF,EAAyBJ,EAAU,WACxDO,EAAaxI,EAAK,WAAasF,EAAciD,EAInD,OADc,IAAI,WAAWvI,EAAK,MAAM,EAClC,IAAIiI,EAAWO,CAAU,EAG/B5B,GACE5G,EACAsF,EACAgD,EACAC,CAAA,EAIFxC,GAAoB/F,EAAMsF,EAAagD,EAAqB,CAAC,EAC7DrC,GAA6BjG,EAAMsF,EAAaiD,CAAkB,EAE3DD,CACT,CAOO,SAASG,GACdzI,EACAsF,EACAoD,EACM,CACN,MAAM3B,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIoD,GAAY3B,EACd,OAGF,MAAMtJ,EAASgJ,GAAqBzG,EAAMsF,EAAaoD,CAAQ,EACzDC,EAAUb,GAAoB9H,EAAMsF,EAAc7H,CAAM,EAGxDmL,EAAiBtD,EAAcnY,GAC/B6R,EAAM4J,GAAkBF,EAAW,GAAK,EACxCG,EAAMD,EAAiBF,EAAW,EAClCI,GAAgB/B,EAAa,EAAI2B,GAAY,EAE/CI,EAAe,GACjBjK,GAAOmB,EAAM6I,EAAK7I,EAAMhB,EAAK8J,CAAY,EAI3C/C,GAAoB/F,EAAMsF,EAAayB,EAAa,CAAC,EACrDV,GACErG,EACAsF,EACAc,GAAoBpG,EAAMsF,CAAW,EAAIqD,CAAA,CAE7C,CAMO,SAASI,GACd/I,EACAsF,EACAoD,EACAM,EACA5B,EACS,CACT,MAAML,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIoD,EAAW,GAAKA,GAAY3B,EAC9B,MAAM,IAAI,MAAM,sBAAsB2B,CAAQ,aAAa,EAG7D,MAAMb,EAAapB,GAAqBzG,EAAMsF,EAAaoD,CAAQ,EAC7DO,EAAUnB,GAAoB9H,EAAMsF,EAAcuC,CAAU,EAC5DqB,EAAUF,EAAc,WACxBG,EAAQ,IAAI,WAAWnJ,EAAK,MAAM,EAGxC,GAAIkJ,GAAWD,EACb,OAAAE,EAAM,IAAIH,EAAehJ,EAAK,WAAasF,EAAcuC,CAAU,EAC/DqB,EAAUD,GACZ5C,GACErG,EACAsF,EACAc,GAAoBpG,EAAMsF,CAAW,GAAK2D,EAAUC,EAAA,EAGjD,GAIT,MAAMd,EAAalB,GAA0BlH,EAAMsF,CAAW,EACxD8D,EAAeF,EAAUD,EAE/B,GAAIb,GAAcgB,EAAc,CAE9B,GADwBtC,GAA+B9G,EAAMsF,CAAW,EAClD4D,EACpB,OAAA/B,GAAanH,EAAMsF,EAAa8B,EAAmB,CACjD,SAAAsB,EACA,UAAWM,CAAA,CACZ,EACM,GAIT3C,GACErG,EACAsF,EACAc,GAAoBpG,EAAMsF,CAAW,EAAI2D,CAAA,EAI3C,MAAMV,EADiBvC,GAA6BhG,EAAMsF,CAAW,EACzB4D,EAC5C,OAAAC,EAAM,IACJH,EACAhJ,EAAK,WAAasF,EAAciD,CAAA,EAIlC3B,GAAqB5G,EAAMsF,EAAaoD,EAAUH,CAAkB,EACpEtC,GAA6BjG,EAAMsF,EAAaiD,CAAkB,EAC3D,EACT,CAGA,MAAO,EACT,CASO,SAASc,GACdC,EACA,CACA,MAAMC,EAAU,MAAM,QAAQD,CAAgB,EAC1CA,EACCA,EAA+B,QAC9BE,EAAoB,KAAK,KAAKD,EAAQ,OAAS,CAAC,EACtD,IAAIE,EAAmB,EACnBC,EAAgB,EACpB,QAAS7R,EAAI,EAAGA,EAAI0R,EAAQ,OAAQ1R,IAAK,CACvC,MAAMC,EAAIyR,EAAQ1R,CAAC,EACfC,EAAE,OAASC,EAAS,MAAO0R,GAAoB,EAC1C3R,EAAE,OAASC,EAAS,OAASD,EAAE,OAASC,EAAS,QACxD0R,GAAoB,EACb3R,EAAE,OAASC,EAAS,MAAQD,EAAE,OAASC,EAAS,KACvD0R,GAAoB,IACb3R,EAAE,OAASC,EAAS,MAAQD,EAAE,OAASC,EAAS,OACvD2R,GACJ,CACA,MAAO,CAAE,kBAAAF,EAAmB,iBAAAC,EAAkB,cAAAC,CAAA,CAChD,CAcO,SAASC,GACdL,EACAM,EACY,CACZ,MAAML,EAAU,MAAM,QAAQD,CAAgB,EAC1CA,EACCA,EAA+B,QAC9BO,EAAYN,EAAQ,OAC1B,GAAIM,EAAYla,GACd,MAAM,IAAI+J,GAAoBmQ,EAAWla,EAAqB,EAGhE,MAAM6Z,EAAoB,KAAK,KAAKK,EAAY,CAAC,EAC3CC,EAAc,IAAI,WAAWN,CAAiB,EAGpD,QAAS3R,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EACfqF,EAAM0M,EAAOG,EAAI,IAAI,EAG3B,GAFgB7M,GAAQ,KAEX,CACX,GAAK6M,EAAI,MAAQ/R,EAAW,SAC1B,MAAM,IAAIO,GAAuBwR,EAAI,IAAI,EAE3C,MAAMC,EAAWnS,GAAK,EAChBoS,EAAW,IAAMpS,EAAI,GAC3BiS,EAAYE,CAAQ,GAAKC,CAC3B,CACF,CAGA,IAAIR,EAAmB,EACvB,QAAS5R,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EAErB,GAAI,GADaiS,EAAYjS,GAAK,CAAC,EAAK,IAAMA,EAAI,MAAS,GAEzD,OAAQkS,EAAI,KAAA,CACV,KAAKhS,EAAS,MACZ0R,GAAoB,EACpB,MACF,KAAK1R,EAAS,MACd,KAAKA,EAAS,QACZ0R,GAAoB,EACpB,MACF,KAAK1R,EAAS,KACd,KAAKA,EAAS,KACZ0R,GAAoB,GACpB,KAAA,CAGR,CAGA,MAAMS,EAID,CAAA,EACL,QAASrS,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EACrB,GAAIkS,EAAI,OAAShS,EAAS,MAAQgS,EAAI,OAAShS,EAAS,KAEtD,IADiB+R,EAAYjS,GAAK,CAAC,EAAK,IAAMA,EAAI,MAAS,EAEzDqS,EAAY,KAAK,CAAE,QAASrS,EAAG,IAAAkS,EAAK,QAAS,KAAM,MAC9C,CACL,MAAM7M,EAAM0M,EAAOG,EAAI,IAAI,EAC3B,IAAIjH,EACAiH,EAAI,OAAShS,EAAS,KACxB+K,EAAQsC,GAAa,OAAO,OAAOlI,GAAO,EAAE,CAAC,EAE7C4F,EAAQ5F,aAAe,WAAaA,EAAM,IAAI,WAAWA,CAAU,EAErEgN,EAAY,KAAK,CAAE,QAASrS,EAAG,IAAAkS,EAAK,QAASjH,EAAO,CACtD,CAEJ,CAEA,MAAMqH,EAAwBD,EAAY,OAAS,EAC7CE,EACJ,EAAIZ,EAAoBC,EAAmBU,EAE7C,IAAIE,EAAyB,EAC7B,QAASxS,EAAI,EAAGA,EAAIqS,EAAY,OAAQrS,IAAK,CAC3C,MAAMyS,EAAOJ,EAAYrS,CAAC,EACtByS,EAAK,UACPD,GAA0BC,EAAK,QAAQ,WAE3C,CAEA,MAAMC,EAAiBH,EAAyBC,EAChD,GAAIE,EAAiB,KACnB,MAAM,IAAInS,GAA0BmS,EAAgB,IAAY,EAGlE,MAAMC,EAAa,IAAI,WAAWD,CAAc,EAC1CE,EAAW,IAAI,SAASD,EAAW,MAAM,EAG/CC,EAAS,SAAS,EAAG,CAAI,EAEzBA,EAAS,UAAU,EAAGF,EAAgB,EAAI,EAE1CC,EAAW,IAAIV,EAAa,CAAC,EAE7B,IAAIY,EAAuB,EAAIlB,EAC/B,QAAS3R,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EAErB,GAAI,GADaiS,EAAYjS,GAAK,CAAC,EAAK,IAAMA,EAAI,MAAS,GAC7C,CACZ,MAAMqF,EAAM0M,EAAOG,EAAI,IAAI,EAC3B,OAAQA,EAAI,KAAA,CACV,KAAKhS,EAAS,MACZ0S,EAAS,SAASC,EAAsB,OAAOxN,CAAG,EAAG,EAAI,EACzDwN,GAAwB,EACxB,MACF,KAAK3S,EAAS,MACZ0S,EAAS,YAAYC,EAAsB,OAAOxN,CAAU,EAAG,EAAI,EACnEwN,GAAwB,EACxB,MACF,KAAK3S,EAAS,QACZ0S,EAAS,WAAWC,EAAsB,OAAOxN,CAAG,EAAG,EAAI,EAC3DwN,GAAwB,EACxB,MACF,KAAK3S,EAAS,KACZ4M,GAAU,OAAO,OAAOzH,CAAG,EAAGsN,EAAYE,CAAoB,EAC9DA,GAAwB,GACxB,MACF,KAAK3S,EAAS,KACZoN,GAAU,OAAO,OAAOjI,CAAG,EAAGsN,EAAYE,CAAoB,EAC9DA,GAAwB,GACxB,KAAA,CAEN,CACF,CAGA,IAAIC,EAA2BD,EAC3BE,EAAyBR,EAE7B,QAASvS,EAAI,EAAGA,EAAIqS,EAAY,OAAQrS,IAAK,CAC3C,MAAMyS,EAAOJ,EAAYrS,CAAC,EACtByS,EAAK,UAAY,MAEnBG,EAAS,UAAUE,EAA0B,EAAG,EAAI,EACpDF,EAAS,UAAUE,EAA2B,EAAG,EAAG,EAAI,IAExDF,EAAS,UACPE,EACAC,EACA,EAAA,EAEFH,EAAS,UACPE,EAA2B,EAC3BL,EAAK,QAAQ,WACb,EAAA,EAEFE,EAAW,IAAIF,EAAK,QAASM,CAAsB,EACnDA,GAA0BN,EAAK,QAAQ,YAEzCK,GAA4B,CAC9B,CAEA,OAAOH,CACT,CAKO,SAASK,GACdC,EACAC,EACAC,EACO,CACP,IAAIzB,EACAvJ,EACAiL,EAEJ,GAAIH,aAAgB,SAAU,CAC5B9K,EAAO8K,EACPG,EAAgBF,EAChB,MAAMG,EAAgBF,EACtBzB,EAAU,MAAM,QAAQ2B,CAAa,EACjCA,EACCA,EAA4B,OACnC,MACE3B,EAAU,MAAM,QAAQuB,CAAI,EAAIA,EAAQA,EAAmB,QAC3D9K,EAAO+K,EACPE,EAAgBD,EAGlB,MAAMG,EAAa,CAAA,EACbtB,EAAYN,EAAQ,OACpBC,EAAoB,KAAK,KAAKK,EAAY,CAAC,EAE3CC,EAAc,IAAI,WACtB9J,EAAK,OACLA,EAAK,WAAaiL,EAAgB,EAClCzB,CAAA,EAGF,IAAIkB,EAAuBO,EAAgB,EAAIzB,EAG3C4B,EAAc,EAGlB,MAAMC,EAAcX,EACpB,QAAS7S,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EAErB,GAAI,GADaiS,EAAYjS,GAAK,CAAC,EAAK,IAAMA,EAAI,MAAS,GAEzD,OAAQkS,EAAI,KAAA,CACV,KAAKhS,EAAS,MACZ2S,GAAwB,EACxB,MACF,KAAK3S,EAAS,MACd,KAAKA,EAAS,QACZ2S,GAAwB,EACxB,MACF,KAAK3S,EAAS,KACd,KAAKA,EAAS,KACZ2S,GAAwB,GACxB,KAAA,CAGR,CAEA,MAAMY,EAAyBZ,EAC/BA,EAAuBW,EAEvB,QAASxT,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQ1R,CAAC,EAGrB,IAFiBiS,EAAYjS,GAAK,CAAC,EAAK,IAAMA,EAAI,MAAS,EAE9C,CACXsT,EAAIpB,EAAI,IAAI,EAAI,MACZA,EAAI,OAAShS,EAAS,MAAQgS,EAAI,OAAShS,EAAS,OACtDqT,IAEF,QACF,CAEA,OAAQrB,EAAI,KAAA,CACV,KAAKhS,EAAS,MACZoT,EAAIpB,EAAI,IAAI,EAAI/J,EAAK,SAAS0K,EAAsB,EAAI,EACxDA,GAAwB,EACxB,MACF,KAAK3S,EAAS,MACZoT,EAAIpB,EAAI,IAAI,EAAI/J,EAAK,YAAY0K,EAAsB,EAAI,EAC3DA,GAAwB,EACxB,MACF,KAAK3S,EAAS,QACZoT,EAAIpB,EAAI,IAAI,EAAI/J,EAAK,WAAW0K,EAAsB,EAAI,EAC1DA,GAAwB,EACxB,MACF,KAAK3S,EAAS,KAAM,CAClB,MAAMgG,EAAQ,IAAI,WAChBiC,EAAK,OACLA,EAAK,WAAa0K,EAClB,EAAA,EAEFS,EAAIpB,EAAI,IAAI,EAAIpF,GAAU,OAAO5G,EAAO,CAAC,EACzC2M,GAAwB,GACxB,KACF,CACA,KAAK3S,EAAS,KAAM,CAClB,MAAMgG,EAAQ,IAAI,WAChBiC,EAAK,OACLA,EAAK,WAAa0K,EAClB,EAAA,EAEFS,EAAIpB,EAAI,IAAI,EAAI5E,GAAU,OAAOpH,EAAO,CAAC,EACzC2M,GAAwB,GACxB,KACF,CACA,KAAK3S,EAAS,KAAM,CAClB,MAAMwT,EAAqBD,EAAyBF,EAAc,EAC5DI,EAAaxL,EAAK,UAAUuL,EAAoB,EAAI,EACpD7D,EAAM1H,EAAK,UAAUuL,EAAqB,EAAG,EAAI,EACjDE,EAAiBzL,EAAK,WAAaiL,EAAgBO,EACnDE,EAAa,IAAI,WAAW1L,EAAK,OAAQyL,EAAgB/D,CAAG,EAClEyD,EAAIpB,EAAI,IAAI,EAAInG,GAAa,OAAO8H,CAAU,EAC9CN,IACA,KACF,CACA,KAAKrT,EAAS,KAAM,CAClB,MAAMwT,EAAqBD,EAAyBF,EAAc,EAC5DI,EAAaxL,EAAK,UAAUuL,EAAoB,EAAI,EACpD7D,EAAM1H,EAAK,UAAUuL,EAAqB,EAAG,EAAI,EACjDE,EAAiBzL,EAAK,WAAaiL,EAAgBO,EACnDG,EAAa,IAAI,WAAWjE,CAAG,EACrCiE,EAAW,IAAI,IAAI,WAAW3L,EAAK,OAAQyL,EAAgB/D,CAAG,CAAC,EAC/DyD,EAAIpB,EAAI,IAAI,EAAI4B,EAChBP,IACA,KACF,CAAA,CAEJ,CAEA,OAAOD,CACT,CAUO,SAASS,GACd5L,EACAsF,EACAuG,EAA2B,EACrB,CACNxG,GAAUrF,EAAMsF,EAAa7O,GAA0BoV,CAAmB,CAC5E,CAMO,SAASC,GACd9L,EACAsF,EACK,CACL,OAAOtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,CAC7C,CAMO,SAASyG,GACd/L,EACAsF,EACAuG,EACM,CACN7L,EAAK,UAAUsF,EAAc,EAAGuG,EAAqB,EAAI,CAC3D,CAOO,SAASG,GACdhM,EACAsF,EACA2G,EACAC,EACK,CACL,MAAMnF,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIyB,GAAchZ,GAChB,MAAO,GAIT,MAAMwa,EADiBvC,GAA6BhG,EAAMsF,CAAW,EACzB1X,GAGtCue,EAAgB7G,EAAciD,EACpC,OAAAvI,EAAK,UAAUmM,EAAeF,EAAe,EAAI,EACjDjM,EAAK,YAAYmM,EAAgB,EAAGD,EAAO,EAAI,EAG/CtF,GAAqB5G,EAAMsF,EAAayB,EAAYwB,CAAkB,EAEtExC,GAAoB/F,EAAMsF,EAAayB,EAAa,CAAC,EACrDd,GAA6BjG,EAAMsF,EAAaiD,CAAkB,EAE3DxB,EAAa,CACtB,CAOO,SAASqF,GACdpM,EACAsF,EACA+G,EACK,CACL,MAAMtF,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIyB,IAAe,EACjB,OAAO+E,GAA6B9L,EAAMsF,CAAW,EAGvD,IAAIgH,EAAK,EACLjI,EAAK0C,EAAa,EAClBwF,EAAkB,GAEtB,KAAOD,GAAMjI,GAAI,CACf,MAAMmI,EAAOF,EAAKjI,GAAO,EACnBwC,EAAcJ,GAAqBzG,EAAMsF,EAAakH,CAAG,EACzDC,EAAazM,EAAK,YAAYsF,EAAcuB,EAAc,EAAG,EAAI,EAEnEwF,GAAiBI,GACnBF,EAAkBvM,EAAK,UAAUsF,EAAcuB,EAAa,EAAI,EAChExC,EAAKmI,EAAM,GAEXF,EAAKE,EAAM,CAEf,CAEA,OAAID,IAAoB,GACfA,EAIFT,GAA6B9L,EAAMsF,CAAW,CACvD,CAKO,SAASoH,GACd1M,EACAsF,EACAqH,EAKA,CACA,MAAM5F,EAAajB,GAAoB9F,EAAMsF,CAAW,EAClDsH,EAAa5e,GAEnB,GAAI+Y,GAAc6F,EAChB,MAAM,IAAI,MAAM,wCAAwC7F,CAAU,QAAQ,EAI5E,MAAM8F,EAAqBpG,GACzBzG,EACAsF,EACAsH,CAAA,EAEIE,EAAyB9M,EAAK,UAClCsF,EAAcuH,EACd,EAAA,EAEIE,EAAe/M,EAAK,YACxBsF,EAAcuH,EAAqB,EACnC,EAAA,EAIIG,EAAkBlB,GAA6B9L,EAAMsF,CAAW,EACtEsG,GAAmB5L,EAAM2M,EAAiBK,CAAe,EAGzD,QAASnV,EAAI+U,EAAa,EAAG/U,EAAIkP,EAAYlP,IAAK,CAChD,MAAM4F,EAASgJ,GAAqBzG,EAAMsF,EAAazN,CAAC,EAClDoV,EAAWjN,EAAK,UAAUsF,EAAc7H,EAAQ,EAAI,EACpDyP,EAAOlN,EAAK,YAAYsF,EAAc7H,EAAS,EAAG,EAAI,EAC5DuO,GAA0BhM,EAAM2M,EAAiBM,EAAUC,CAAI,CACjE,CAGA,OAAAnB,GAA6B/L,EAAMsF,EAAawH,CAAsB,EACtE/G,GAAoB/F,EAAMsF,EAAasH,CAAU,EAE1C,CACL,aAAAG,EACA,uBAAAD,EACA,oBAAqBE,CAAA,CAEzB,CAUO,SAASG,GACdnN,EACAsF,EACAE,EAAoB,EACd,CACNH,GAAUrF,EAAMsF,EAAa5O,GAAsB8O,CAAY,CACjE,CAMO,SAAS4H,GACdC,EACAC,EACAC,EACAC,EACAC,EACAC,EACQ,CACR,GAAIL,IAAWG,EAEb,OAAOH,EAASG,EAGlB,GAAIH,IAAWtV,EAAS,KACtB,OAAOwV,EAAUG,EAAU,GAAKH,EAAUG,EAAU,EAAI,EAG1D,IAAI7N,EAAO,EACX,GACEwN,IAAWtV,EAAS,OACpBsV,IAAWtV,EAAS,OACpBsV,IAAWtV,EAAS,QACpB,CACA,MAAM4V,EAAQ,OAAOL,GAAU,SAAW,OAAOA,CAAK,EAAIA,EACpDM,EAAQ,OAAOH,GAAU,SAAW,OAAOA,CAAK,EAAIA,EAC1D5N,EAAO8N,EAAQC,EAAQ,GAAKD,EAAQC,EAAQ,EAAI,CAClD,SACEP,IAAWtV,EAAS,MACpBsV,IAAWtV,EAAS,MACpBsV,IAAWtV,EAAS,KACpB,CACA,MAAM8V,EAAQ,OAAOP,CAAK,EACpBQ,EAAQ,OAAOL,CAAK,EAC1B5N,EAAOgO,EAAQC,EAAQ,GAAKD,EAAQC,EAAQ,EAAI,CAClD,SAAWT,IAAWtV,EAAS,KAAM,CACnC,MAAMgW,EAAMT,EACNU,EAAMP,EACNQ,EAAU,KAAK,IAAIF,EAAI,OAAQC,EAAI,MAAM,EAC/C,QAASnW,EAAI,EAAGA,EAAIoW,EAASpW,IAC3B,GAAIkW,EAAIlW,CAAC,IAAMmW,EAAInW,CAAC,EAAG,CACrBgI,EAAOkO,EAAIlW,CAAC,EAAImW,EAAInW,CAAC,EAAI,GAAK,EAC9B,KACF,CAEEgI,IAAS,IACXA,EAAOkO,EAAI,OAASC,EAAI,OAE5B,CAEA,OAAInO,IAAS,EAAUA,EAChB0N,EAAUG,EAAU,GAAKH,EAAUG,EAAU,EAAI,CAC1D,CAEA,SAASQ,GACPlO,EACAmO,EACAC,EACAC,EACsC,CACtC,MAAMC,EAAS,IAAI,WACjBtO,EAAK,OACLA,EAAK,WAAamO,EAClBC,CAAA,EAEF,OAAIA,IAAU,EACL,CAAE,SAAUrW,EAAS,KAAM,QAAS,IAAA,EAEzCsW,IAAiBtW,EAAS,KAE1BqW,IAAU,IACRE,EAAO,CAAC,IAAM,GAAKA,EAAO,CAAC,IAAM,GAChCA,EAAO,CAAC,IAAM,KAAQA,EAAO,CAAC,IAAM,KAEhC,CACL,SAAUvW,EAAS,MACnB,QAAS,IAAI,SAASuW,EAAO,OAAQA,EAAO,UAAU,EAAE,SACtD,EACA,EAAA,CACF,EAGAF,IAAU,GAAKE,EAAO,CAAC,EAAI,IAAMA,EAAO,CAAC,EAAI,GACxC,CAAE,SAAUvW,EAAS,KAAM,QAASuW,CAAA,EAEtC,CAAE,SAAUvW,EAAS,KAAM,QAAS6L,GAAa,OAAO0K,CAAM,CAAA,EAEnEF,IAAU,EACL,CAAE,SAAUrW,EAAS,KAAM,QAASuW,CAAA,EAEzCF,IAAU,EACL,CACL,SAAUrW,EAAS,MACnB,QAAS,IAAI,SAASuW,EAAO,OAAQA,EAAO,UAAU,EAAE,SAAS,EAAG,EAAI,CAAA,EAGxED,IAAiBtW,EAAS,MAAQqW,IAAU,GACvC,CAAE,SAAUrW,EAAS,KAAM,QAAS4M,GAAU,OAAO2J,EAAQ,CAAC,CAAA,EAEnED,IAAiBtW,EAAS,MAAQqW,IAAU,GACvC,CAAE,SAAUrW,EAAS,KAAM,QAASoN,GAAU,OAAOmJ,EAAQ,CAAC,CAAA,EAEnED,IAAiBtW,EAAS,SAAWqW,IAAU,EAC1C,CACL,SAAUrW,EAAS,QACnB,QAAS,IAAI,SAASuW,EAAO,OAAQA,EAAO,UAAU,EAAE,WACtD,EACA,EAAA,CACF,EAGAD,IAAiBtW,EAAS,OAASqW,IAAU,EACxC,CACL,SAAUrW,EAAS,MACnB,QAAS,IAAI,SAASuW,EAAO,OAAQA,EAAO,UAAU,EAAE,YACtD,EACA,EAAA,CACF,EAGAD,IAAiBtW,EAAS,KACxBqW,IAAU,GAAKA,IAAU,EACpB,CAAE,SAAUrW,EAAS,KAAM,QAAS6L,GAAa,OAAO0K,CAAM,CAAA,EAEhE,CAAE,SAAUvW,EAAS,KAAM,QAASuW,CAAA,EAEtC,CAAE,SAAUvW,EAAS,KAAM,QAAS6L,GAAa,OAAO0K,CAAM,CAAA,CACvE,CAKO,SAASC,GACdvO,EACAsF,EACAkJ,EACAC,EACAvC,EACA9E,EACQ,CACR,IAAIsH,EAEFF,IAAazW,EAAS,MACtB0W,IAAc,MACdA,IAAc,OAEdC,EAAY,IAAI,WAAW,CAAC,EACnBF,IAAazW,EAAS,OAC/B2W,EAAY,IAAI,WAAW,CAAC,EAC5B,IAAI,SAASA,EAAU,MAAM,EAAE,SAAS,EAAG,OAAOD,CAAS,EAAG,EAAI,GACzDD,IAAazW,EAAS,OAC/B2W,EAAY,IAAI,WAAW,CAAC,EAC5B,IAAI,SAASA,EAAU,MAAM,EAAE,YAAY,EAAG,OAAOD,CAAS,EAAG,EAAI,GAC5DD,IAAazW,EAAS,SAC/B2W,EAAY,IAAI,WAAW,CAAC,EAC5B,IAAI,SAASA,EAAU,MAAM,EAAE,WAAW,EAAG,OAAOD,CAAS,EAAG,EAAI,GAC3DD,IAAazW,EAAS,MAC/B2W,EAAY,IAAI,WAAW,EAAE,EAC7B/J,GAAU,OAAO,OAAO8J,CAAS,EAAGC,EAAW,CAAC,GACvCF,IAAazW,EAAS,MAC/B2W,EAAY,IAAI,WAAW,EAAE,EAC7BvJ,GAAU,OAAO,OAAOsJ,CAAS,EAAGC,EAAW,CAAC,GACvCF,IAAazW,EAAS,KAC/B2W,EAAYtJ,GAAa,OAAO,OAAOqJ,CAAS,CAAC,EAEjDC,EACED,aAAqB,WAAaA,EAAY,IAAI,WAAWA,CAAS,EAI1E,MAAME,EAAc,EAAID,EAAU,WAAa,EACzCxG,EAAeyG,EAAc,EAE7B5H,EAAajB,GAAoB9F,EAAMsF,CAAW,EAClD6C,EAAkBrB,GAA+B9G,EAAMsF,CAAW,EAClE8C,EAAaD,EAAkB/B,GAAoBpG,EAAMsF,CAAW,EAE1E,GAAI4C,EAAeE,EACjB,MAAO,GAGLF,EAAeC,GACjBhB,GAAanH,EAAMsF,EAAa8B,CAAiB,EAInD,MAAMmB,EADiBvC,GAA6BhG,EAAMsF,CAAW,EACzBqJ,EACtCxC,EAAgB7G,EAAciD,EAG9BC,EAAaxI,EAAK,WAAamM,EACrCnM,EAAK,UAAUmM,EAAeuC,EAAU,WAAY,EAAI,EACxD,IAAI,WAAW1O,EAAK,MAAM,EAAE,IAAI0O,EAAWlG,EAAa,CAAC,EACzDxI,EAAK,YAAYmM,EAAgB,EAAIuC,EAAU,WAAYxC,EAAO,EAAI,EAGtE,IAAII,EAAK,EACLjI,EAAK0C,EAAa,EAClB6H,EAAc7H,EAElB,KAAOuF,GAAMjI,GAAI,CACf,MAAMmI,EAAOF,EAAKjI,GAAO,EACnB5G,EAASgJ,GAAqBzG,EAAMsF,EAAakH,CAAG,EACpDqC,EAAiB7O,EAAK,UAAUsF,EAAc7H,EAAQ,EAAI,EAC1DyP,EAAOlN,EAAK,YAChBsF,EAAc7H,EAAS,EAAIoR,EAC3B,EAAA,EAEI,CAAE,SAAUC,EAAU,QAASC,GAAYb,GAC/ClO,EACAsF,EAAc7H,EAAS,EACvBoR,EACAL,CAAA,EAGUpB,GACVoB,EACAC,EACAvC,EACA4C,EACAC,EACA7B,CAAA,EAEQ,GACR0B,EAAcpC,EACdnI,EAAKmI,EAAM,GAEXF,EAAKE,EAAM,CAEf,CAGA,MAAMrD,EAAQ,IAAI,WAAWnJ,EAAK,MAAM,EAElC4I,EADiB5I,EAAK,WAAasF,EACDnY,GAClC6R,EAAM4J,EAAiBgG,EAAc,EACrC/F,EAAMD,GAAkBgG,EAAc,GAAK,EAC3CI,GAAajI,EAAa6H,GAAe,EAE/C,OAAII,EAAY,GACd7F,EAAM,WAAWN,EAAK7J,EAAKA,EAAMgQ,CAAS,EAI5CpI,GAAqB5G,EAAMsF,EAAasJ,EAAarG,CAAkB,EAEvExC,GAAoB/F,EAAMsF,EAAayB,EAAa,CAAC,EACrDd,GAA6BjG,EAAMsF,EAAaiD,CAAkB,EAE3DqG,CACT,CAKO,SAASK,GACdjP,EACAsF,EACAoB,EACM,CACN,MAAMK,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,GAAIoB,EAAW,GAAKA,GAAYK,EAAY,OAE5C,MAAMF,EAAcJ,GAAqBzG,EAAMsF,EAAaoB,CAAQ,EAE9DiI,EAAc,EADN3O,EAAK,UAAUsF,EAAcuB,EAAa,EAAI,EAC5B,EAE1B+B,EAAiBtD,EAAcnY,GAC/B6R,EAAM4J,GAAkBlC,EAAW,GAAK,EACxCmC,EAAMD,EAAiBlC,EAAW,EAClCsI,GAAajI,EAAa,EAAIL,GAAY,EAE5CsI,EAAY,GACdnQ,GAAOmB,EAAM6I,EAAK7I,EAAMhB,EAAKgQ,CAAS,EAGxCjJ,GAAoB/F,EAAMsF,EAAayB,EAAa,CAAC,EACrDV,GACErG,EACAsF,EACAc,GAAoBpG,EAAMsF,CAAW,EAAIqJ,CAAA,CAE7C,CAKO,SAASO,GACdlP,EACAsF,EACA6J,EACAC,EACA/C,EACsC,CACtC,MAAMtF,EAAajB,GAAoB9F,EAAMsF,CAAW,EACxD,IAAIgH,EAAK,EACLjI,EAAK0C,EAAa,EAEtB,KAAOuF,GAAMjI,GAAI,CACf,MAAMmI,EAAOF,EAAKjI,GAAO,EACnB5G,EAASgJ,GAAqBzG,EAAMsF,EAAakH,CAAG,EACpD4B,EAAQpO,EAAK,UAAUsF,EAAc7H,EAAQ,EAAI,EACjDyP,EAAOlN,EAAK,YAAYsF,EAAc7H,EAAS,EAAI2Q,EAAO,EAAI,EAC9D,CAAE,SAAUU,EAAU,QAASC,GAAYb,GAC/ClO,EACAsF,EAAc7H,EAAS,EACvB2Q,EACAe,CAAA,EAIIE,EAAMjC,GACV+B,EACAC,EAHuB/C,IAAkB,OAAYA,EAAgBa,EAKrE4B,EACAC,EACA7B,CAAA,EAGF,GAAImC,IAAQ,EAAG,CACb,GAAIhD,IAAkB,OAAW,CAC/B,IAAIiD,EAAa9C,EACjB,KAAO8C,EAAa,GAAG,CACrB,MAAMC,EAAYD,EAAa,EACzBE,EAAc/I,GAAqBzG,EAAMsF,EAAaiK,CAAS,EAC/DE,EAAazP,EAAK,UAAUsF,EAAckK,EAAa,EAAI,EAC3D,CAAE,SAAUE,EAAW,QAASC,GAAazB,GACjDlO,EACAsF,EAAckK,EAAc,EAC5BC,EACAN,CAAA,EAEF,GACE/B,GACE+B,EACAC,EACA,GACAM,EACAC,EACA,EAAA,IACI,EAENL,EAAaC,MAEb,MAEJ,CACA,MAAO,CAAE,MAAO,GAAM,SAAUD,CAAA,CAClC,CACA,MAAO,CAAE,MAAO,GAAM,SAAU9C,CAAA,CAClC,MAAW6C,EAAM,EACfhL,EAAKmI,EAAM,EAEXF,EAAKE,EAAM,CAEf,CAEA,MAAO,CAAE,MAAO,GAAO,SAAUF,CAAA,CACnC,CAKO,SAASsD,GAAqB/J,EAAgB3I,EAAsB,CACzE,GAAIA,GAAQ,KACV,OAAO,IAAI,WAAW,CAAC,EAEzB,GAAI2I,IAAS9N,EAAS,MAAO,CAC3B,MAAM2M,EAAI,IAAI,WAAW,CAAC,EAC1B,WAAI,SAASA,EAAE,MAAM,EAAE,SAAS,EAAG,OAAOxH,CAAG,EAAG,EAAI,EAC7CwH,CACT,CACA,GAAImB,IAAS9N,EAAS,MAAO,CAC3B,MAAM2M,EAAI,IAAI,WAAW,CAAC,EAC1B,WAAI,SAASA,EAAE,MAAM,EAAE,YAAY,EAAG,OAAOxH,CAAG,EAAG,EAAI,EAChDwH,CACT,CACA,GAAImB,IAAS9N,EAAS,QAAS,CAC7B,MAAM2M,EAAI,IAAI,WAAW,CAAC,EAC1B,WAAI,SAASA,EAAE,MAAM,EAAE,WAAW,EAAG,OAAOxH,CAAG,EAAG,EAAI,EAC/CwH,CACT,CACA,GAAImB,IAAS9N,EAAS,KAAM,CAC1B,MAAM2M,EAAI,IAAI,WAAW,EAAE,EAC3B,OAAAC,GAAU,OAAO,OAAOzH,CAAG,EAAGwH,EAAG,CAAC,EAC3BA,CACT,CACA,GAAImB,IAAS9N,EAAS,KAAM,CAC1B,MAAM2M,EAAI,IAAI,WAAW,EAAE,EAC3B,OAAAS,GAAU,OAAO,OAAOjI,CAAG,EAAGwH,EAAG,CAAC,EAC3BA,CACT,CACA,OAAImB,IAAS9N,EAAS,KACbqN,GAAa,OAAO,OAAOlI,CAAG,CAAC,EAEjCA,aAAe,WAAaA,EAAM,IAAI,WAAWA,CAAG,CAC7D,CAKO,SAAS2S,GACdtG,EACAuG,EACAjG,EACAsB,EACY,CACZ,MAAM4E,EAAsB,CAAA,EAC5B,IAAIC,EAAY,EAChB,QAASnY,EAAI,EAAGA,EAAIgS,EAAWhS,IAAK,CAClC,MAAMkS,EAAMR,EAAQuG,EAAYjY,CAAC,CAAC,EAC5BqF,EAAMiO,EAAIpB,EAAI,IAAI,EAClBkG,EAAUL,GAAqB7F,EAAI,KAAM7M,CAAG,EAC5CgT,EAAO,IAAI,WAAW,EAAQD,EAAQ,UAAU,EACtDC,EAAK,CAAC,EAAInG,EAAI,KACdmG,EAAK,CAAC,EAAID,EAAQ,WAAa,IAC/BC,EAAK,CAAC,EAAKD,EAAQ,YAAc,EAAK,IACtCC,EAAK,IAAID,EAAS,CAAC,EACnBF,EAAM,KAAKG,CAAI,EACfF,GAAaE,EAAK,UACpB,CACA,MAAMrT,EAAS,IAAI,WAAWmT,CAAS,EACvC,IAAIvS,EAAS,EACb,QAAS5F,EAAI,EAAGA,EAAIkY,EAAM,OAAQlY,IAAK,CACrC,MAAMsY,EAAIJ,EAAMlY,CAAC,EACjBgF,EAAO,IAAIsT,EAAG1S,CAAM,EACpBA,GAAU0S,EAAE,UACd,CACA,OAAOtT,CACT,CC98CA,MAAMuT,GAAwB,WAUvB,SAASC,GAAgBC,EAAiBvP,EAAsB,CACrE,MAAMwP,EAAI,KAAK,KAAKD,EAASF,EAAqB,EAClD,OAASG,EAAKA,IAAM,MAAS,EAAKxP,CACpC,CAgBO,SAASyP,GACdxQ,EACAyQ,EACAC,EACAJ,EACQ,CACR,MAAMvP,EAAO2P,EAAe,EAC5B,IAAIzS,EAAMoS,GAAgBC,EAASvP,CAAI,EAEvC,QAAS4P,EAAQ,EAAGA,EAAQD,EAAcC,IAAS,CACjD,MAAMlT,EAASgT,EAAcxS,EAAM3L,GAC7Bse,EAAgB5Q,EAAK,UAAUvC,EAAQ,EAAI,EACjD,GAAImT,IAAkB,EACpB,MAAO,GAET,GAAIA,IAAkBN,EACpB,OAAOtQ,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAExCQ,EAAOA,EAAM,EAAK8C,CACpB,CACA,MAAO,EACT,CAYO,SAAS8P,GACd7Q,EACAyQ,EACAC,EACAJ,EACA5J,EACM,CACN,MAAM3F,EAAO2P,EAAe,EAC5B,IAAIzS,EAAMoS,GAAgBC,EAASvP,CAAI,EAEvC,QAAS4P,EAAQ,EAAGA,EAAQD,EAAcC,IAAS,CACjD,MAAMlT,EAASgT,EAAcxS,EAAM3L,GAC7Bse,EAAgB5Q,EAAK,UAAUvC,EAAQ,EAAI,EACjD,GAAImT,IAAkB,GAAKA,IAAkBN,EAAS,CACpDtQ,EAAK,UAAUvC,EAAQ6S,EAAS,EAAI,EACpCtQ,EAAK,UAAUvC,EAAS,EAAGiJ,EAAU,EAAI,EACzC,MACF,CACAzI,EAAOA,EAAM,EAAK8C,CACpB,CACA,MAAM,IAAI,MAAM,kDAAkDuP,CAAO,EAAE,CAC7E,CAaO,SAASQ,GACd9Q,EACAyQ,EACAC,EACAJ,EACS,CACT,MAAMvP,EAAO2P,EAAe,EAC5B,IAAI7Y,EAAIwY,GAAgBC,EAASvP,CAAI,EAGjCgQ,EAAQ,GACZ,QAASJ,EAAQ,EAAGA,EAAQD,EAAcC,IAAS,CACjD,MAAMlT,EAASgT,EAAc5Y,EAAIvF,GAC3Bse,EAAgB5Q,EAAK,UAAUvC,EAAQ,EAAI,EACjD,GAAImT,IAAkB,EACpB,MAAO,GAET,GAAIA,IAAkBN,EAAS,CAC7BS,EAAQ,GACR,KACF,CACAlZ,EAAKA,EAAI,EAAKkJ,CAChB,CAEA,GAAI,CAACgQ,EACH,MAAO,GAIT,IAAIC,EAAInZ,EACR,OAAa,CACXmZ,EAAKA,EAAI,EAAKjQ,EACd,MAAMkQ,EAAWR,EAAcO,EAAI1e,GAC7B4e,EAAYlR,EAAK,UAAUiR,EAAU,EAAI,EAC/C,GAAIC,IAAc,EAChB,MAEF,MAAMtV,EAAIyU,GAAgBa,EAAWnQ,CAAI,EAEzC,IAAMlJ,EAAI+D,EAAKmF,IAAUiQ,EAAIpV,EAAKmF,GAAO,CACvC,MAAMoQ,EAAanR,EAAK,UAAUiR,EAAW,EAAG,EAAI,EAC9CG,EAAWX,EAAc5Y,EAAIvF,GACnC0N,EAAK,UAAUoR,EAAUF,EAAW,EAAI,EACxClR,EAAK,UAAUoR,EAAW,EAAGD,EAAY,EAAI,EAC7CtZ,EAAImZ,CACN,CACF,CAGA,MAAMK,EAAeZ,EAAc5Y,EAAIvF,GACvC,OAAA0N,EAAK,UAAUqR,EAAc,EAAG,EAAI,EACpCrR,EAAK,UAAUqR,EAAe,EAAG,EAAG,EAAI,EACjC,EACT,CC9GO,SAASC,GAAyB5K,EAAoB,CAC3D,OAAOA,EAAW,IACpB,CAMO,SAAS6K,GACdvR,EACAwR,EACA9K,EACK,CACL,OAAOtG,GAASJ,EAAMwR,EAAsB9K,EAAW,CAAC,CAC1D,CAMO,SAAS+K,GACdzR,EACAwR,EACA9K,EACA4J,EACM,CACNjQ,GAAUL,EAAMwR,EAAsB9K,EAAW,EAAG4J,CAAO,CAC7D,CAOO,SAASoB,GACd1R,EACA2R,EACAC,EACAtB,EACK,CACL,OAAOE,GACLxQ,EACA2R,EACAC,EACAtB,CAAA,CAEJ,CAMO,SAASuB,GACd7R,EACAwR,EACAG,EACAC,EACAlL,EACA4J,EACK,CACLlP,GAASkP,EAAU,EAAG,qBAAqB,EAC3C,MAAMwB,EAAWP,GACfvR,EACAwR,EACA9K,CAAA,EAEF,OAAIoL,EAAW,GAAKA,IAAaxB,GAC/BQ,GACE9Q,EACA2R,EACAC,EACAE,CAAA,EAGJL,GAA4BzR,EAAMwR,EAAqB9K,EAAU4J,CAAO,EACxEO,GACE7Q,EACA2R,EACAC,EACAtB,EACA5J,CAAA,EAEK,CACT,CAMO,SAASqL,GACd/R,EACAwR,EACAG,EACAC,EACAlL,EACK,CACL,MAAMoL,EAAWP,GACfvR,EACAwR,EACA9K,CAAA,EAEF,OAAIoL,EAAW,GACbhB,GACE9Q,EACA2R,EACAC,EACAE,CAAA,EAEFL,GAA4BzR,EAAMwR,EAAqB9K,EAAU,CAAC,EAC3D,GAEF,CACT,CAMO,SAASsL,GACdC,EACAC,EACAxL,EACM,CACNxF,GAAQ+Q,EAAYC,EAAmBxL,CAAQ,CACjD,CAMO,SAASyL,GACdF,EACAC,EACAxL,EACM,CACNvF,GAAU8Q,EAAYC,EAAmBxL,CAAQ,CACnD,CAMO,SAAS0L,GACdH,EACAC,EACAxL,EACS,CACT,OAAO5F,GAAQmR,EAAYC,EAAmBxL,CAAQ,IAAM,CAC9D,CAKO,SAAS2L,GACdC,EACA5L,EACM,CACN,GAAI4L,EAAW5L,CAAQ,GAAK,WAC1B,MAAM,IAAI,MAAM,8BAA8BA,CAAQ,EAAE,EAE1D4L,EAAW5L,CAAQ,GACrB,CAKO,SAAS6L,GACdD,EACA5L,EACM,CACFA,IAAa,GACb4L,EAAW5L,CAAQ,EAAI,GACzB4L,EAAW5L,CAAQ,GAEvB,CAKO,SAAS8L,GACdF,EACA5L,EACS,CACT,OAAOA,IAAa,GAAK4L,EAAW5L,CAAQ,EAAI,CAClD,CAKO,SAAS+L,GACd/U,EACAgV,EACAJ,EACAd,EACAmB,EACAC,EACqD,CACrD,MAAM5S,EAAO,IAAI,SAAStC,CAAM,EAGhC,QAAS7F,EAAI,EAAGA,EAAI8a,EAAY9a,IAC9B,GACEuI,GAASJ,EAAMwR,EAAsB3Z,EAAI,CAAC,IAAM,GAChD,CAAC2a,GAAmBF,EAAYza,CAAC,EAEjC,MAAO,CAAE,eAAgBA,EAAG,gBAAiB+a,CAAA,EAKjD,IAAIC,EAAOD,EACX,QAASE,EAAO,EAAGA,EAAOH,EAAa,EAAGG,IAAQ,CAIhD,GAHAD,GAAQA,EAAO,GAAKF,EAChBE,IAAS,GAETL,GAAmBF,EAAYO,CAAI,EACrC,SAIF,MAAME,EAAY,IAAI,SAASrV,EAAQmV,EAAO,KAAW,IAAS,EAClE,GAAIlN,GAAcoN,EAAW,CAAC,IAAMpc,GAIpC,GAAI+b,EAASG,CAAI,IAAM,EACrBH,EAASG,CAAI,EAAI,MAEjB,OAAO,CAAE,eAAgBA,EAAM,gBAAiBA,CAAA,CAEpD,CAEA,MAAM,IAAI,MAAM,sCAAsC,CACxD,CAMO,SAASG,GACdtV,EACAgV,EACAJ,EACAd,EACAU,EACAS,EACAC,EACAtC,EAC4E,CAC5E,MAAMtQ,EAAO,IAAI,SAAStC,CAAM,EAEhC,IAAIuV,EAAiB,GACjBC,EAAkBN,EAEtB,GACEtC,EAAU,GACVA,GAAWqC,GACXpB,GAA2BvR,EAAMwR,EAAqBlB,EAAU,CAAC,IAAM,GACvE,CAACkC,GAAmBF,EAAYhC,EAAU,CAAC,EAE3C2C,EAAiB3C,EAAU,MACtB,CACL,MAAM6C,EAASV,GACb/U,EACAgV,EACAJ,EACAd,EACAmB,EACAC,CAAA,EAEFK,EAAiBE,EAAO,eACxBD,EAAkBC,EAAO,eAC3B,CAEA,MAAMC,EAAc7B,GAClBvR,EACAwR,EACAyB,CAAA,EAEII,EAAWjB,GACf,IAAI,WAAW1U,CAAM,EACrBwU,EACAe,CAAA,EAEIF,EAAY,IAAI,SAASrV,EAAQuV,EAAiB,KAAW,IAAS,EACtEK,EACJF,EAAc,GAAKzN,GAAcoN,EAAW,CAAC,IAAMxc,GAC/Cgd,EACJF,GAAY,CAACC,GAAgBF,EAAc,EAAIA,EAAc,EAE/D,MAAO,CAAE,eAAAH,EAAgB,cAAAM,EAAe,gBAAAL,CAAA,CAC1C,CClTO,SAASM,GAAW9b,EAAgB+b,EAA8B,CACvE,OAAI/b,EAAI,SAAWA,EAAI,QAAQ+b,CAAU,EAChC/b,EAAI,QAAQ+b,CAAU,EAExB/b,EAAI,MACb,CAOO,SAASgc,GAAoB1T,EAAgBsQ,EAAyB,CAC3E,GAAIA,GAAW,EAAG,MAAO,GACzB,GAAItQ,EAAK,YAAchN,GAAsBT,GAAmB,CAC9D,MAAMohB,EAAOjC,GACX1R,EACAhN,GACAX,GACAie,CAAA,EAEF,GAAIqD,GAAQ,EACV,OAAOA,EAAO,IAElB,CACA,OAAQrD,EAAU,GAAK,IACzB,CAMO,SAASsD,GACdtG,EACAG,EACyC,CACzC,GACEH,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV,MAAO,CAAE,OAAQ,EAAG,WAAY,EAAA,EAGlC,GAAI,OAAOH,GAAU,WAAa,OAAOG,GAAU,UAAW,CAC5D,MAAME,EAAQL,EAAQ,EAAI,EACpBM,EAAQH,EAAQ,EAAI,EAC1B,OAAIE,IAAUC,EAAc,CAAE,OAAQ,EAAG,WAAY,EAAA,EAC9C,CAAE,OAAQD,EAAQC,EAAQ,EAAI,GAAI,WAAY,EAAA,CACvD,CAEA,GAAI,OAAON,GAAU,UAAY,OAAOG,GAAU,SAChD,OAAIH,IAAUG,EAAc,CAAE,OAAQ,EAAG,WAAY,EAAA,EAC9C,CAAE,OAAQH,EAAQG,EAAQ,EAAI,GAAI,WAAY,EAAA,EAGvD,GAAI,OAAOH,GAAU,UAAY,OAAOG,GAAU,SAAU,CAC1D,MAAMoG,EAAI,OAAOvG,CAAK,EAChB5I,EAAI,OAAO+I,CAAK,EACtB,OAAIoG,IAAMnP,EAAU,CAAE,OAAQ,EAAG,WAAY,EAAA,EACtC,CAAE,OAAQmP,EAAInP,EAAI,EAAI,GAAI,WAAY,EAAA,CAC/C,CAEA,GAAI,OAAO4I,GAAU,UAAY,OAAOG,GAAU,SAChD,OAAIH,IAAUG,EAAc,CAAE,OAAQ,EAAG,WAAY,EAAA,EAC9C,CAAE,OAAQH,EAAQG,EAAQ,EAAI,GAAI,WAAY,EAAA,EAGvD,GAAIH,aAAiB,YAAcG,aAAiB,WAAY,CAC9D,MAAMQ,EAAU,KAAK,IAAIX,EAAM,WAAYG,EAAM,UAAU,EAC3D,QAAS5V,EAAI,EAAGA,EAAIoW,EAASpW,IAC3B,GAAIyV,EAAMzV,CAAC,IAAM4V,EAAM5V,CAAC,EACtB,MAAO,CAAE,OAAQyV,EAAMzV,CAAC,EAAI4V,EAAM5V,CAAC,EAAI,EAAI,GAAI,WAAY,EAAA,EAG/D,OAAIyV,EAAM,aAAeG,EAAM,WACtB,CAAE,OAAQ,EAAG,WAAY,EAAA,EAE3B,CACL,OAAQH,EAAM,WAAaG,EAAM,WAAa,EAAI,GAClD,WAAY,EAAA,CAEhB,CAEA,OAAIH,IAAUG,EAAc,CAAE,OAAQ,EAAG,WAAY,EAAA,EAC9C,CAAE,OAAQH,EAAQG,EAAQ,EAAI,GAAI,WAAY,EAAA,CACvD,CAKA,SAASqG,GAAchc,EAAa,CAClC,OAAIA,GAAK,IAAMA,GAAK,GAAWA,EAAI,GAC5BA,CACT,CAiBO,SAASic,GACdC,EACAC,EACAC,EACAC,EACK,CACL,IAAI/U,EAAS,EACT+Q,EAAS,EACTiE,EAAc,GACdC,EAAc,GAElB,KAAOjV,EAAI6U,GAAS,CAClB,MAAMK,EAAMnE,EAAIgE,EAAUD,EAAQ,WAAW/D,CAAC,EAAI,EAC5CoE,EAAMP,EAAI,WAAW5U,CAAC,EAC5B,GAAI+Q,EAAIgE,IAAYG,IAAQ,IAAMR,GAAcQ,CAAG,IAAMR,GAAcS,CAAG,GACxEnV,IACA+Q,YACSA,EAAIgE,GAAWG,IAAQ,GAChCF,EAASjE,IACTkE,EAASjV,UACAgV,IAAW,GACpBjE,EAAIiE,EAAS,EACbhV,EAAI,EAAEiV,MAEN,OAAO,EAEX,CAEA,KAAOlE,EAAIgE,GAAWD,EAAQ,WAAW/D,CAAC,IAAM,IAC9CA,IAGF,OAAOA,IAAMgE,EAAU,EAAI,CAC7B,CAgEO,SAASK,GAAeR,EAAaE,EAA0B,CACpE,OAAOH,GAAmBC,EAAKA,EAAI,OAAQE,EAASA,EAAQ,MAAM,IAAM,CAC1E,CAOO,SAASO,GACdC,EACAC,EACAC,EACQ,CACR,MAAMC,EAAWD,EAAS,QAC1B,QAAShZ,EAAI,EAAGA,EAAIiZ,EAAUjZ,IAAK,CACjC,MAAMiY,EAAIa,EAAO9Y,CAAC,EACZ8I,EAAIiQ,EAAO/Y,CAAC,EACZkZ,EAAYF,EAAS,WAAWhZ,CAAC,GAAK,EACtCmZ,EAAaH,EAAS,WAAWhZ,CAAC,IAAMkZ,IAAc,EAAI,EAAI,GAE9DE,EAAYnB,GAAM,KAClBoB,EAAYvQ,GAAM,KAExB,GAAIsQ,GAAaC,EACf,SAGF,GAAID,GAAaC,EAEf,OADYF,IAAe,EAAKC,EAAY,GAAK,EAAKA,EAAY,EAAI,GAKxE,IAAI3F,EAAM,EACV,GAAI,OAAOwE,GAAM,UAAY,OAAOnP,GAAM,SACxC2K,EAAMwE,EAAInP,EAAI,GAAKmP,EAAInP,EAAI,EAAI,UACtB,OAAOmP,GAAM,UAAY,OAAOnP,GAAM,SAAU,CACzD,MAAMwQ,EAAK,OAAOrB,CAAC,EACbsB,EAAK,OAAOzQ,CAAC,EACnB2K,EAAM6F,EAAKC,EAAK,GAAKD,EAAKC,EAAK,EAAI,CACrC,SAAW,OAAOtB,GAAM,UAAY,OAAOnP,GAAM,SAC/C2K,EAAMwE,EAAInP,EAAI,GAAKmP,EAAInP,EAAI,EAAI,UACtBmP,aAAa,YAAcnP,aAAa,WAAY,CAC7D,MAAMuJ,EAAU,KAAK,IAAI4F,EAAE,WAAYnP,EAAE,UAAU,EACnD,QAAS7M,EAAI,EAAGA,EAAIoW,EAASpW,IAC3B,GAAIgc,EAAEhc,CAAC,IAAM6M,EAAE7M,CAAC,EAAG,CACjBwX,EAAMwE,EAAEhc,CAAC,EAAI6M,EAAE7M,CAAC,EAAI,GAAK,EACzB,KACF,CAEEwX,IAAQ,IACVA,EACEwE,EAAE,WAAanP,EAAE,WACb,GACAmP,EAAE,WAAanP,EAAE,WACf,EACA,EAEZ,MACE2K,EAAOwE,EAAanP,EAAY,GAAMmP,EAAanP,EAAY,EAAI,EAGrE,GAAI2K,IAAQ,EACV,OAAOyF,IAAc,EAAI,CAACzF,EAAMA,CAEpC,CACA,MAAO,EACT,CAMO,SAAS+F,GACdC,EACAC,EACAX,EACAC,EACQ,CACR,MAAMC,EAAWD,EAAS,QAC1B,QAAShZ,EAAI,EAAGA,EAAIiZ,EAAUjZ,IAAK,CACjC,MAAMiY,EAAIwB,EAAUC,EAAY1Z,CAAC,EAC3B8I,EAAIiQ,EAAO/Y,CAAC,EACZkZ,EAAYF,EAAS,WAAWhZ,CAAC,GAAK,EACtCmZ,EAAaH,EAAS,WAAWhZ,CAAC,IAAMkZ,IAAc,EAAI,EAAI,GAE9DE,EAAYnB,GAAM,KAClBoB,EAAYvQ,GAAM,KAExB,GAAIsQ,GAAaC,EAAW,SAC5B,GAAID,GAAaC,EACf,OAAOF,IAAe,EAAKC,EAAY,GAAK,EAAKA,EAAY,EAAI,GAGnE,IAAI3F,EAAM,EACV,GAAI,OAAOwE,GAAM,UAAY,OAAOnP,GAAM,SACxC2K,EAAMwE,EAAInP,EAAI,GAAKmP,EAAInP,EAAI,EAAI,UACtB,OAAOmP,GAAM,UAAY,OAAOnP,GAAM,SAC/C2K,EAAMwE,EAAInP,EAAI,GAAKmP,EAAInP,EAAI,EAAI,UACtB,OAAOmP,GAAM,UAAY,OAAOnP,GAAM,SAAU,CACzD,MAAMwQ,EAAK,OAAOrB,CAAC,EACbsB,EAAK,OAAOzQ,CAAC,EACnB2K,EAAM6F,EAAKC,EAAK,GAAKD,EAAKC,EAAK,EAAI,CACrC,SAAWtB,aAAa,YAAcnP,aAAa,WAAY,CAC7D,MAAMuJ,EAAU,KAAK,IAAI4F,EAAE,WAAYnP,EAAE,UAAU,EACnD,QAAS7M,EAAI,EAAGA,EAAIoW,EAASpW,IAC3B,GAAIgc,EAAEhc,CAAC,IAAM6M,EAAE7M,CAAC,EAAG,CACjBwX,EAAMwE,EAAEhc,CAAC,EAAI6M,EAAE7M,CAAC,EAAI,GAAK,EACzB,KACF,CAEEwX,IAAQ,IACVA,EAAMwE,EAAE,WAAanP,EAAE,WAAa,GAAKmP,EAAE,WAAanP,EAAE,WAAa,EAAI,EAE/E,MACE2K,EAAOwE,EAAanP,EAAY,GAAMmP,EAAanP,EAAY,EAAI,EAGrE,GAAI2K,IAAQ,EACV,OAAOyF,IAAc,EAAI,CAACzF,EAAMA,CAEpC,CACA,MAAO,EACT,CAMO,SAASkG,GAAS3L,EAAuB,CAC9C,IAAI4L,EAAO,WACX,QAAS5Z,EAAI,EAAGA,EAAIgO,EAAO,OAAQhO,IAAK,CACtC,MAAMC,EAAI+N,EAAOhO,CAAC,EAClB,GAAIC,GAAM,KACR2Z,GAAQ,IACRA,EAAO,KAAK,KAAKA,EAAM,QAAU,UACxB,OAAO3Z,GAAM,SAAU,CAChC,MAAM+I,EAAM,IAAI,YAAY,CAAC,EAC7B,IAAI,SAASA,CAAG,EAAE,WAAW,EAAG/I,EAAG,EAAI,EACvC,MAAM4Z,EAAK,IAAI,WAAW7Q,CAAG,EAC7B,QAAS/M,EAAI,EAAGA,EAAI,EAAGA,IACrB2d,GAAQC,EAAG5d,CAAC,EACZ2d,EAAO,KAAK,KAAKA,EAAM,QAAU,CAErC,SAAW,OAAO3Z,GAAM,SACtB,QAAS,EAAI,EAAG,EAAIA,EAAE,OAAQ,IAC5B2Z,GAAQ3Z,EAAE,WAAW,CAAC,EAAI,IAC1B2Z,EAAO,KAAK,KAAKA,EAAM,QAAU,UAE1B,OAAO3Z,GAAM,SAAU,CAChC,MAAMqD,EAAI,OAAOrD,CAAC,EAClB2Z,GAAQtW,EAAI,IACZsW,EAAO,KAAK,KAAKA,EAAM,QAAU,CACnC,SAAW3Z,aAAa,WACtB,QAAS,EAAI,EAAG,EAAIA,EAAE,WAAY,IAChC2Z,GAAQ3Z,EAAE,CAAC,EACX2Z,EAAO,KAAK,KAAKA,EAAM,QAAU,CAGvC,CACA,OAAAA,EAAOA,IAAS,EACTA,IAAS,EAAI,EAAIA,CAC1B,CAMO,SAASE,GAAiBhB,EAAeC,EAAwB,CACtE,GAAID,EAAO,SAAWC,EAAO,OAC3B,MAAO,GAGT,QAAS9c,EAAI,EAAGA,EAAI6c,EAAO,OAAQ7c,IAAK,CACtC,MAAMgc,EAAIa,EAAO7c,CAAC,EACZ6M,EAAIiQ,EAAO9c,CAAC,EAElB,GAAIgc,GAAM,MACR,GAAInP,GAAM,KAAyB,MAAO,OAC5C,IAAWA,GAAM,KACf,MAAO,GACT,GAAWmP,IAAMnP,EACf,GAAImP,aAAa,YAAcnP,aAAa,WAAY,CACtD,GAAImP,EAAE,aAAenP,EAAE,WAAY,MAAO,GAC1C,QAASsM,EAAI,EAAGA,EAAI6C,EAAE,WAAY7C,IAChC,GAAI6C,EAAE7C,CAAC,IAAMtM,EAAEsM,CAAC,EAAG,MAAO,EAE9B,KACE,OAAO,GAGb,CACA,MAAO,EACT,CAKO,SAAS2E,GAAmBC,EAAiC,CAClE,MAAMC,EAAyB,IAAI,MAAMD,CAAQ,EACjD,QAAS/d,EAAI,EAAGA,EAAI+d,EAAU/d,IAC5Bge,EAAQhe,CAAC,EAAI,CACX,KAAM,EACN,KAAM,CAAA,EACN,MAAO,EACP,IAAK,EACL,QAAS,IACT,QAAS,KACT,QAAS,EAAA,EAGb,OAAOge,CACT,CAMO,SAASC,GACdC,EACAC,EACA3X,EACAuW,EACM,CACN,IAAIqB,EAAOD,EACX,OAAa,CACX,IAAIE,EAAUD,EACd,MAAME,EAAO,EAAIF,EAAO,EAClBG,EAAQ,EAAIH,EAAO,EAezB,GAZEE,EAAO9X,GACPoW,GAAoBsB,EAAQI,CAAI,EAAE,KAAMJ,EAAQG,CAAO,EAAE,KAAMtB,CAAQ,EAAI,IAE3EsB,EAAUC,GAGVC,EAAQ/X,GACRoW,GAAoBsB,EAAQK,CAAK,EAAE,KAAML,EAAQG,CAAO,EAAE,KAAMtB,CAAQ,EAAI,IAE5EsB,EAAUE,GAGRF,IAAYD,EAAM,CACpB,MAAMI,EAAON,EAAQE,CAAI,EACzBF,EAAQE,CAAI,EAAIF,EAAQG,CAAO,EAC/BH,EAAQG,CAAO,EAAIG,EACnBJ,EAAOC,CACT,KACE,MAEJ,CACF,CAKO,SAASI,GAAoBC,EAAwB,CAC1D,MAAM3B,EAAW2B,EAAO,QACxBA,EAAO,QAAQ,KAAK,CAAC1C,EAAkBnP,IACrC+P,GAAoBZ,EAAE,KAAMnP,EAAE,KAAMkQ,CAAQ,CAAA,EAE9C2B,EAAO,QAAU3B,EAAS,QAAU,CACtC,CAKO,SAAS4B,GACdxW,EACAvC,EACAY,EACY,CACZ,MAAMW,EAAM,IAAI,WAAWgB,EAAK,OAAQA,EAAK,WAAavC,EAAQY,CAAM,EAClES,EAAO,IAAI,WAAWT,CAAM,EAClC,OAAAS,EAAK,IAAIE,CAAG,EACLF,CACT,CAMO,SAAS2X,GACd/e,EACA6e,EACAG,EACAC,EACAhO,EACA3I,EACA4W,EACU,CAEV,GAAIA,EAAQ,GAAKL,EAAO,QAAQ,QAAUK,EAAO,CAM/C,GALYnC,GACViC,EACAH,EAAO,QAAQ,CAAC,EAAE,KAClBA,EAAO,OAAA,GAEE,EAET,OAAO/e,EAAS,QAIlB,MAAMqf,EAAYN,EAAO,QAAQ,CAAC,EAC5B1W,EAAO8I,EAAUkO,EAAU,OACjC,GAAIhX,EAAO,GAAKnI,EAAI,YAAcmI,EAAOnI,EAAI,eAC3C,OAAAA,EAAI,OAASF,EAAS,gBACfA,EAAS,gBAElBE,EAAI,aAAemI,EAEnB,MAAMiX,EAAWN,GAAexW,EAAM2W,EAAmBhO,CAAO,EAChE,OAAAkO,EAAU,KAAOH,EACjBG,EAAU,UAAYF,EACtBE,EAAU,OAASlO,EACnBkO,EAAU,QAAUC,EACpBhB,GAAeS,EAAO,QAAS,EAAGK,EAAOL,EAAO,OAAO,EAChD/e,EAAS,OAClB,CAGA,MAAMuf,EAAa,GAAK,GAAKL,EAAK,OAAS/N,EAC3C,GAAIjR,EAAI,YAAcqf,EAAarf,EAAI,eACrC,OAAAA,EAAI,OAASF,EAAS,gBACfA,EAAS,gBAElBE,EAAI,aAAeqf,EAEnB,MAAMD,EAAWN,GAAexW,EAAM2W,EAAmBhO,CAAO,EAShE,GARA4N,EAAO,QAAQ,KAAK,CAClB,KAAAG,EACA,UAAWC,EACX,OAAQhO,EACR,QAASmO,CAAA,CACV,EAGGF,EAAQ,GAAKL,EAAO,QAAQ,SAAWK,EACzC,QAASrG,EAAI,KAAK,MAAMqG,EAAQ,CAAC,EAAI,EAAGrG,GAAK,EAAGA,IAC9CuF,GAAeS,EAAO,QAAShG,EAAGqG,EAAOL,EAAO,OAAO,EAI3D,OAAO/e,EAAS,OAClB,CAiBO,SAASwf,GACdtf,EACA4d,EACA2B,EACY,SACZ,IAAIC,EACJ,MAAMC,EAA8B,CAAA,EAIpC,GAAIzf,EAAI,eAAiBuf,IAAavf,EAAI,cAAc,OAAQ,CAC9Dwf,EAAOxf,EAAI,cACX,QAASI,EAAI,EAAGA,EAAImf,EAAUnf,IAC5Bqf,EAAOD,EAAKpf,CAAC,EAAE,IAAI,EAAIJ,EAAI,UAAU4d,EAAYxd,CAAC,CAEtD,SAGSJ,EAAI,OAASuf,IAAavf,EAAI,MAAM,QAAQ,OAAQ,CAC3Dwf,EAAOxf,EAAI,MAAM,QACjB,QAASI,EAAI,EAAGA,EAAImf,EAAUnf,IAC5Bqf,EAAOD,EAAKpf,CAAC,EAAE,IAAI,EAAIJ,EAAI,UAAU4d,EAAYxd,CAAC,CAEtD,KAGK,CACHof,EAAO,CAAA,EACP,QAASpf,EAAI,EAAGA,EAAImf,EAAUnf,IAAK,CACjC,MAAMoF,EAAMxF,EAAI,UAAU4d,EAAYxd,CAAC,EACjCsf,IAAWC,GAAA7Z,EAAA9F,EAAI,QAAJ,YAAA8F,EAAW,QAAQ1F,KAAnB,YAAAuf,EAAuB,OAAQ,OAAOvf,CAAC,GACxD,IAAIwf,EAAWvf,EAAS,KACpB,OAAOmF,GAAQ,SACjBoa,EAAW,OAAO,UAAUpa,CAAG,EAAInF,EAAS,MAAQA,EAAS,QACpD,OAAOmF,GAAQ,SACxBoa,EAAWvf,EAAS,MACXmF,aAAe,aACxBoa,EAAWvf,EAAS,MAEtBmf,EAAK,KAAK,CACR,KAAME,EACN,KAAME,EACN,MAAOtf,EAAW,KAClB,UAAW,CAAA,CACZ,EACDmf,EAAOC,CAAQ,EAAIla,CACrB,CACF,CAEA,OAAOyM,GAAmBuN,EAAMC,CAAM,CACxC,CAMO,SAASI,GACd7f,EACAsI,EACAiI,EACAuP,EACU,CACV,MAAMC,EAAS,EAAIxP,EAAU,WAC7B,GAAIvQ,EAAI,aAAe+f,EAAShlB,GAC9B,OAAAiF,EAAI,OAASF,EAAS,YACtBE,EAAI,GAAK8f,EACFhgB,EAAS,YAGlB,MAAMkgB,EAAavkB,GAAuBuE,EAAI,aAC9C,OAAAsI,EAAK,UAAU0X,EAAYzP,EAAU,WAAY,EAAI,EACxC,IAAI,WACfjI,EAAK,OACLA,EAAK,WAAa0X,EAAa,EAC/BzP,EAAU,UAAA,EAEP,IAAIA,CAAS,EAElBvQ,EAAI,cAAgB+f,EACpB/f,EAAI,cACGF,EAAS,OAClB,CAKO,SAASmgB,GACd3X,EACA4X,EACAC,EACS,CACT,OACG7X,EAAK,SAAS4X,GAAsBC,GAAW,EAAE,EAC/C,IAAMA,EAAU,MACnB,CAEJ,CAMO,SAASC,GACd9X,EACA4X,EACApO,EACAD,EACAwO,EACQ,CACR,IAAIC,EAAaJ,EAAqBpO,EACtC,QAAS3R,EAAI,EAAGA,EAAIkgB,EAAgBlgB,IAClC,GAAI,CAAC8f,GAAY3X,EAAM4X,EAAoB/f,CAAC,EAE1C,OADiB0R,EAAQ1R,CAAC,EACT,KAAA,CACf,KAAKE,EAAS,MACZigB,GAAc,EACd,MACF,KAAKjgB,EAAS,MACd,KAAKA,EAAS,QACZigB,GAAc,EACd,MACF,KAAKjgB,EAAS,KACd,KAAKA,EAAS,KACZigB,GAAc,GACd,KAAA,CAIR,OAAOA,CACT,CCnqBA,MAAMpU,GAAe,IAAI,YAMlB,SAASqU,GACdvgB,EACAsI,EACAkY,EACU,SACV,MAAMC,EAAY,IAAI,SACpBD,EAAS,OACTA,EAAS,WACTA,EAAS,UAAA,EAELE,EAAWF,EAAS,WAEpBG,EAAa,IACnB,IAAIC,EAAS,EAEb,MAAMC,EACJvY,EAAK,YAAcjN,GAAsB,GACzCiN,EAAK,UAAUjN,GAAqB,EAAI,EAAI,EAE9C,KAAO2E,EAAI,GAAK0gB,GAAU,CACxB,GAAI,EAAEE,EAASD,EACb,OAAA3gB,EAAI,OAASF,EAAS,QACfA,EAAS,QAGlB,MAAMggB,EAAW9f,EAAI,GACf8gB,EAAKN,EAASxgB,EAAI,EAAE,EAG1B,OAFAA,EAAI,IAAM,EAEF8gB,EAAA,CAMN,KAAKrgB,EAAO,QACV,OAAAT,EAAI,YAAc,EAClBA,EAAI,OAASF,EAAS,KACfA,EAAS,KASlB,KAAKW,EAAO,eAAgB,CAC1B,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5B+gB,EAAeN,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EACzDA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EAKzC,GAJAxW,EAAO,OAASwb,EAChBxb,EAAO,QAAU,EACjBA,EAAO,UAAY,EAEfsb,GAAmBE,EAAe,EAAG,CACvC,MAAM9E,EAAOjC,GACX1R,EACAhN,GACAX,GACAomB,CAAA,EAEF,GAAI9E,EAAO,EACT,OAAAjc,EAAI,cAAgB+gB,EACpB/gB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElByF,EAAO,QAAU0W,CACnB,CACA,KACF,CAQA,KAAKxb,EAAO,UAAW,CACrB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMyF,EAASuW,GAAW9b,EAAK+b,CAAU,EAEzC,GAAI8E,GAAmBtb,EAAO,OAAS,EAAG,CACxC,MAAM0W,EAAOjC,GACX1R,EACAhN,GACAX,GACA4K,EAAO,MAAA,EAET,GAAI0W,EAAO,EACT,OAAAjc,EAAI,cAAgBuF,EAAO,OAC3BvF,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElByF,EAAO,QAAU0W,CACnB,CAEA,MAAMrO,EAAcoO,GAAoB1T,EAAM/C,EAAO,MAAM,EAG3D,GAFmB6I,GAAoB9F,EAAMsF,CAAW,IAErC,EACjB5N,EAAI,GAAKghB,MACJ,CACLzb,EAAO,QAAU,EACjB,MAAM0b,EAAkBlS,GAAqBzG,EAAMsF,EAAa,CAAC,EACjErI,EAAO,UAAYqI,EAAcqT,CACnC,CACA,KACF,CASA,KAAKxgB,EAAO,YAAa,CACvB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMyF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnCnO,EAAcoO,GAAoB1T,EAAM/C,EAAO,MAAM,EACrD8J,EAAajB,GAAoB9F,EAAMsF,CAAW,EAElDsT,EAAgB3b,EAAO,QAAU,EACvC,GAAI2b,EAAgB7R,EAAY,CAC9B9J,EAAO,QAAU2b,EACjB,MAAMD,EAAkBlS,GACtBzG,EACAsF,EACArI,EAAO,OAAA,EAETA,EAAO,UAAYqI,EAAcqT,CACnC,KAAO,CAEL,MAAMnT,EAAeU,GAAsBlG,EAAMsF,CAAW,EAC5D,GAAIE,IAAiB,EAAG,CACtB,GAAI+S,EAAiB,CACnB,MAAM5E,EAAOjC,GACX1R,EACAhN,GACAX,GACAmT,CAAA,EAEF,GAAImO,EAAO,EAET,OAAAjc,EAAI,cAAgB8N,EACpB9N,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElByF,EAAO,QAAU0W,CACnB,CAEA1W,EAAO,OAASuI,EAChBvI,EAAO,QAAU,EACjB,MAAM4b,EAAcnF,GAAoB1T,EAAMwF,CAAY,EAE1D,GADmBM,GAAoB9F,EAAM6Y,CAAW,EACvC,EAAG,CAClB,MAAMF,EAAkBlS,GACtBzG,EACA6Y,EACA,CAAA,EAEF5b,EAAO,UAAY4b,EAAcF,CACnC,MACEjhB,EAAI,GAAKghB,CAEb,MAEEhhB,EAAI,GAAKghB,CAEb,CACA,KACF,CAOA,KAAKvgB,EAAO,QAAS,CACnB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMyF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnCnO,EAAcoO,GAAoB1T,EAAM/C,EAAO,MAAM,EACrD8J,EAAajB,GAAoB9F,EAAMsF,CAAW,EAExD,GAAIyB,IAAe,EACjBrP,EAAI,GAAKghB,MACJ,CACLzb,EAAO,QAAU8J,EAAa,EAC9B,MAAM4R,EAAkBlS,GACtBzG,EACAsF,EACArI,EAAO,OAAA,EAETA,EAAO,UAAYqI,EAAcqT,CACnC,CACA,KACF,CAOA,KAAKxgB,EAAO,YAAa,CACvB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMyF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnCnO,EAAcoO,GAAoB1T,EAAM/C,EAAO,MAAM,EAE3D,GAAIA,EAAO,QAAU,EAAG,CACtBA,EAAO,UACP,MAAM0b,EAAkBlS,GACtBzG,EACAsF,EACArI,EAAO,OAAA,EAETA,EAAO,UAAYqI,EAAcqT,CACnC,MACEjhB,EAAI,GAAKghB,EAEX,KACF,CAOA,KAAKvgB,EAAO,cAAe,CACzB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BohB,EAAUZ,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnC9b,GAASD,EAAI,QAAUA,EAAI,OAAO+b,CAAU,IAAM/b,EAAI,MACtDqS,EAAMpS,EAAM,QAAQkgB,CAAO,EAC3BrO,EAAoB,KAAK,KAAK7R,EAAM,QAAQ,OAAS,CAAC,EACtDigB,EAAqB3a,EAAO,UAAY,EAE9C,GAAI0a,GAAY3X,EAAM4X,EAAoBC,CAAO,EAAG,CAClDngB,EAAI,UAAUohB,CAAO,EAAI,KACzB,KACF,CAEA,MAAMd,EAAaF,GACjB9X,EACA4X,EACApO,EACA7R,EAAM,QACNkgB,CAAA,EAGE9N,EAAI,OAAShS,EAAS,MACxBL,EAAI,UAAUohB,CAAO,EAAI9Y,EAAK,SAASgY,EAAY,EAAI,EAC9CjO,EAAI,OAAShS,EAAS,QAC/BL,EAAI,UAAUohB,CAAO,EAAI,OAAO9Y,EAAK,YAAYgY,EAAY,EAAI,CAAC,GAEpE,KACF,CAOA,KAAK7f,EAAO,gBAAiB,CAC3B,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BohB,EAAUZ,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnC9b,GAASD,EAAI,QAAUA,EAAI,OAAO+b,CAAU,IAAM/b,EAAI,MACtD8R,EAAoB,KAAK,KAAK7R,EAAM,QAAQ,OAAS,CAAC,EACtDigB,EAAqB3a,EAAO,UAAY,EAE9C,GAAI0a,GAAY3X,EAAM4X,EAAoBC,CAAO,EAAG,CAClDngB,EAAI,UAAUohB,CAAO,EAAI,KACzB,KACF,CAEA,MAAMd,EAAaF,GACjB9X,EACA4X,EACApO,EACA7R,EAAM,QACNkgB,CAAA,EAGFngB,EAAI,UAAUohB,CAAO,EAAI9Y,EAAK,WAAWgY,EAAY,EAAI,EACzD,KACF,CAQA,KAAK7f,EAAO,eACZ,KAAKA,EAAO,eACZ,KAAKA,EAAO,eAAgB,CAC1B,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BohB,EAAUZ,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnC9b,GAASD,EAAI,QAAUA,EAAI,OAAO+b,CAAU,IAAM/b,EAAI,MACtD8R,EAAoB,KAAK,KAAK7R,EAAM,QAAQ,OAAS,CAAC,EACtDigB,EAAqB3a,EAAO,UAAY,EAE9C,GAAI0a,GAAY3X,EAAM4X,EAAoBC,CAAO,EAAG,CAClDngB,EAAI,UAAUohB,CAAO,EAAI,KACzB,KACF,CAEA,GACEnhB,EAAM,QAAQkgB,CAAO,EAAE,OAAS9f,EAAS,MACzCJ,EAAM,QAAQkgB,CAAO,EAAE,OAAS9f,EAAS,KACzC,CACA,MAAMigB,EAAaF,GACjB9X,EACA4X,EACApO,EACA7R,EAAM,QACNkgB,CAAA,EAGI9Z,EAAQ,IAAI,WAChBiC,EAAK,OACLA,EAAK,WAAagY,EAClB,EAAA,EAGFtgB,EAAI,UAAUohB,CAAO,EACnBnhB,EAAM,QAAQkgB,CAAO,EAAE,OAAS9f,EAAS,KACrC4M,GAAU,OAAO5G,EAAO,CAAC,EACzBoH,GAAU,OAAOpH,EAAO,CAAC,EAC/B,KACF,CAGA,MAAMgb,EAAmBjB,GACvB9X,EACA4X,EACApO,EACA7R,EAAM,QACNA,EAAM,QAAQ,MAAA,EAGhB,IAAIqhB,EAAU,EACd,QAASnhB,EAAI,EAAGA,EAAIggB,EAAShgB,IAAK,CAChC,MAAMC,EAAIH,EAAM,QAAQE,CAAC,GACrBC,EAAE,OAASC,EAAS,MAAQD,EAAE,OAASC,EAAS,OAClDihB,GAEJ,CAEA,MAAMC,EAAeF,EAAmBC,EAAU,EAC5CxN,EAAaxL,EAAK,UAAUiZ,EAAc,EAAI,EAC9CvR,EAAM1H,EAAK,UAAUiZ,EAAe,EAAG,EAAI,EAEjD,GAAIvR,IAAQ,EACVhQ,EAAI,UAAUohB,CAAO,EAAI,OACpB,CACL,MAAMpN,EAAa,IAAI,WACrB1L,EAAK,OACL/C,EAAO,UAAYuO,EACnB9D,CAAA,EAEFhQ,EAAI,UAAUohB,CAAO,EAAIlV,GAAa,OAAO8H,CAAU,CACzD,CACA,KACF,CAOA,KAAKvT,EAAO,eAAgB,CAC1B,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BohB,EAAUZ,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnC9b,GAASD,EAAI,QAAUA,EAAI,OAAO+b,CAAU,IAAM/b,EAAI,MACtD8R,EAAoB,KAAK,KAAK7R,EAAM,QAAQ,OAAS,CAAC,EACtDigB,EAAqB3a,EAAO,UAAY,EAE9C,GAAI0a,GAAY3X,EAAM4X,EAAoBC,CAAO,EAAG,CAClDngB,EAAI,UAAUohB,CAAO,EAAI,KACzB,KACF,CAEA,MAAMC,EAAmBjB,GACvB9X,EACA4X,EACApO,EACA7R,EAAM,QACNA,EAAM,QAAQ,MAAA,EAGhB,IAAIqhB,EAAU,EACd,QAASnhB,EAAI,EAAGA,EAAIggB,EAAShgB,IAAK,CAChC,MAAMC,EAAIH,EAAM,QAAQE,CAAC,GACrBC,EAAE,OAASC,EAAS,MAAQD,EAAE,OAASC,EAAS,OAClDihB,GAEJ,CAEA,MAAMC,EAAeF,EAAmBC,EAAU,EAC5CxN,EAAaxL,EAAK,UAAUiZ,EAAc,EAAI,EAC9CvR,EAAM1H,EAAK,UAAUiZ,EAAe,EAAG,EAAI,EAE3CC,EAAY,IAAI,WAAWxR,CAAG,EACpCwR,EAAU,IACR,IAAI,WAAWlZ,EAAK,OAAQ/C,EAAO,UAAYuO,EAAY9D,CAAG,CAAA,EAEhEhQ,EAAI,UAAUohB,CAAO,EAAII,EACzB,KACF,CAOA,KAAK/gB,EAAO,cAAe,CACzB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5B+gB,EAAeN,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EACzDA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EAMzC,GALAxW,EAAO,OAASwb,EAChBxb,EAAO,WAAawb,EACpBxb,EAAO,QAAU,EACjBA,EAAO,UAAY,EAEfsb,GAAmBE,EAAe,EAAG,CACvC,MAAM9E,EAAOjC,GACX1R,EACAhN,GACAX,GACAomB,CAAA,EAEF,GAAI9E,EAAO,EACT,OAAAjc,EAAI,cAAgB+gB,EACpB/gB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElByF,EAAO,QAAU0W,CACnB,CACA,KACF,CASA,KAAKxb,EAAO,iBAAkB,CAC5B,MAAMghB,EAAmBjB,EAASxgB,EAAI,EAAE,EAClC0hB,EAAkBlB,EAASxgB,EAAI,GAAK,CAAC,EACrC2hB,EAAUnB,EAASxgB,EAAI,GAAK,CAAC,EAC7B8W,EAAW0J,EAASxgB,EAAI,GAAK,CAAC,EAC9B4hB,EAAiBnB,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAG3D,GAFAA,EAAI,IAAM,EAEN4hB,EAAiBlB,EACnB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM+hB,EAAU7hB,EAAI,UAAU2hB,CAAO,EACrC,GAAIE,GAAY,KAA+B,CAC7C7hB,EAAI,GAAK4hB,EACT,KACF,CAEA,MAAME,EAAahG,GAAW9b,EAAKyhB,CAAgB,EAEnD,IAAIM,EAAeD,EAAW,YAAcA,EAAW,OACnDzI,EAAQ,GACR2I,EAAgB,GAEpB,KAAOD,IAAiB,GAAG,CACzB,GAAIlB,GAAmBkB,EAAe,EAAG,CACvC,MAAM9F,EAAOjC,GACX1R,EACAhN,GACAX,GACAonB,CAAA,EAEF,GAAI9F,EAAO,EACT,OAAAjc,EAAI,cAAgB+hB,EACpB/hB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElBgiB,EAAW,QAAU7F,CACvB,CAEA,MAAMrO,EAAcoO,GAAoB1T,EAAMyZ,CAAY,EACpDE,EAASzK,GACblP,EACAsF,EACAkJ,EACA+K,CAAA,EAGF,GAAII,EAAO,MAAO,CAChB5I,EAAQ,GACRyI,EAAW,OAASC,EACpBD,EAAW,QAAUG,EAAO,SAC5B,MAAM9S,EAAcJ,GAClBzG,EACAsF,EACAqU,EAAO,QAAA,EAEHvL,EAAQpO,EAAK,UAAUsF,EAAcuB,EAAa,EAAI,EAC5D6S,EAAgB1Z,EAAK,YACnBsF,EAAcuB,EAAc,EAAIuH,EAChC,EAAA,EAEF,KACF,CAEAqL,EAAevT,GAAsBlG,EAAMsF,CAAW,CACxD,CAEA,GAAI,CAACyL,EACHrZ,EAAI,GAAK4hB,MACJ,CACL,MAAMM,EAAe,OAAOF,GAAiB,GAAG,EAC1CG,EAAgB,OAAOH,EAAgB,OAAO,EAEpD,GAAInB,GAAmBqB,EAAe,GACvBlI,GACX1R,EACAhN,GACAX,GACAunB,CAAA,EAES,EACT,OAAAliB,EAAI,cAAgBkiB,EACpBliB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAIpB,MAAMsiB,EAActG,GAAW9b,EAAK0hB,CAAe,EACnDU,EAAY,OAASF,EACrBE,EAAY,QAAUD,EACtB,MAAME,EAAmBrG,GAAoB1T,EAAM4Z,CAAY,EACzDjB,EAAkBlS,GACtBzG,EACA+Z,EACAF,CAAA,EAEFC,EAAY,UAAYC,EAAmBpB,CAC7C,CACA,KACF,CASA,KAAKxgB,EAAO,iBAAkB,CAC5B,MAAMghB,EAAmBjB,EAASxgB,EAAI,EAAE,EAClC0hB,EAAkBlB,EAASxgB,EAAI,GAAK,CAAC,EACrC2hB,EAAUnB,EAASxgB,EAAI,GAAK,CAAC,EAC7B8W,EAAW0J,EAASxgB,EAAI,GAAK,CAAC,EAC9BsiB,EAAW7B,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGrD,GAFAA,EAAI,IAAM,EAENsiB,EAAW5B,EACb,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM+hB,EAAU7hB,EAAI,UAAU2hB,CAAO,EACrC,GAAIE,GAAY,KAA+B,CAC7C7hB,EAAI,GAAKsiB,EACT,KACF,CAEA,MAAMR,EAAahG,GAAW9b,EAAKyhB,CAAgB,EAEnD,IAAIM,EAAeD,EAAW,YAAcA,EAAW,OACnDzI,EAAQ,GACR2I,EAAgB,GAEpB,KAAOD,IAAiB,GAAG,CACzB,GAAIlB,GAAmBkB,EAAe,EAAG,CACvC,MAAM9F,EAAOjC,GACX1R,EACAhN,GACAX,GACAonB,CAAA,EAEF,GAAI9F,EAAO,EACT,OAAAjc,EAAI,cAAgB+hB,EACpB/hB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElBgiB,EAAW,QAAU7F,CACvB,CAEA,MAAMrO,EAAcoO,GAAoB1T,EAAMyZ,CAAY,EACpD1S,EAAajB,GAAoB9F,EAAMsF,CAAW,EAClDqU,EAASzK,GACblP,EACAsF,EACAkJ,EACA+K,CAAA,EAGF,GAAII,EAAO,OAASA,EAAO,SAAW5S,EAAY,CAChDgK,EAAQ,GACRyI,EAAW,OAASC,EACpBD,EAAW,QAAUG,EAAO,SAC5B,MAAM9S,EAAcJ,GAClBzG,EACAsF,EACAqU,EAAO,QAAA,EAEHvL,EAAQpO,EAAK,UAAUsF,EAAcuB,EAAa,EAAI,EAC5D6S,EAAgB1Z,EAAK,YACnBsF,EAAcuB,EAAc,EAAIuH,EAChC,EAAA,EAEF,KACF,CAEAqL,EAAevT,GAAsBlG,EAAMsF,CAAW,CACxD,CAEA,GAAI,CAACyL,EACHrZ,EAAI,GAAKsiB,MACJ,CACL,MAAMJ,EAAe,OAAOF,GAAiB,GAAG,EAC1CG,EAAgB,OAAOH,EAAgB,OAAO,EAEpD,GAAInB,GAAmBqB,EAAe,GACvBlI,GACX1R,EACAhN,GACAX,GACAunB,CAAA,EAES,EACT,OAAAliB,EAAI,cAAgBkiB,EACpBliB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAIpB,MAAMsiB,EAActG,GAAW9b,EAAK0hB,CAAe,EACnDU,EAAY,OAASF,EACrBE,EAAY,QAAUD,EACtB,MAAME,EAAmBrG,GAAoB1T,EAAM4Z,CAAY,EACzDjB,EAAkBlS,GACtBzG,EACA+Z,EACAF,CAAA,EAEFC,EAAY,UAAYC,EAAmBpB,CAC7C,CACA,KACF,CAQA,KAAKxgB,EAAO,cAAe,CACzB,MAAMghB,EAAmBjB,EAASxgB,EAAI,EAAE,EAClC0hB,EAAkBlB,EAASxgB,EAAI,GAAK,CAAC,EACrCsiB,EAAW7B,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGrD,GAFAA,EAAI,IAAM,EAENsiB,EAAW5B,EACb,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMgiB,EAAahG,GAAW9b,EAAKyhB,CAAgB,EACnD,IAAIM,EAAeD,EAAW,OAC1BlU,EAAcoO,GAAoB1T,EAAMyZ,CAAY,EACxD,MAAM1S,EAAajB,GAAoB9F,EAAMsF,CAAW,EAExD,IAAIsT,EAAgBY,EAAW,QAAU,EACzC,GAAIZ,GAAiB7R,EAAY,CAE/B,GADA0S,EAAevT,GAAsBlG,EAAMsF,CAAW,EAClDmU,IAAiB,EAAG,CACtB/hB,EAAI,GAAKsiB,EACT,KACF,CACA,GAAIzB,GAAmBkB,EAAe,EAAG,CACvC,MAAM9F,EAAOjC,GACX1R,EACAhN,GACAX,GACAonB,CAAA,EAEF,GAAI9F,EAAO,EACT,OAAAjc,EAAI,cAAgB+hB,EACpB/hB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAElBgiB,EAAW,QAAU7F,CACvB,CACArO,EAAcoO,GAAoB1T,EAAMyZ,CAAY,EACpDb,EAAgB,EAChBY,EAAW,OAASC,EACpBD,EAAW,QAAU,EACvB,CAEA,MAAM3S,EAAcJ,GAClBzG,EACAsF,EACAsT,CAAA,EAEIxK,EAAQpO,EAAK,UAAUsF,EAAcuB,EAAa,EAAI,EACtD6S,EAAgB1Z,EAAK,YACzBsF,EAAcuB,EAAc,EAAIuH,EAChC,EAAA,EAGIwL,EAAe,OAAOF,GAAiB,GAAG,EAC1CG,EAAgB,OAAOH,EAAgB,OAAO,EAEpD,GAAInB,GAAmBqB,EAAe,GACvBlI,GACX1R,EACAhN,GACAX,GACAunB,CAAA,EAES,EACT,OAAAliB,EAAI,cAAgBkiB,EACpBliB,EAAI,OAASF,EAAS,WACtBE,EAAI,GAAK8f,EACFhgB,EAAS,WAIpBgiB,EAAW,OAASC,EACpBD,EAAW,QAAUZ,EAErB,MAAMkB,EAActG,GAAW9b,EAAK0hB,CAAe,EACnDU,EAAY,OAASF,EACrBE,EAAY,QAAUD,EACtB,MAAME,EAAmBrG,GAAoB1T,EAAM4Z,CAAY,EACzDjB,EAAkBlS,GACtBzG,EACA+Z,EACAF,CAAA,EAEFC,EAAY,UAAYC,EAAmBpB,EAC3C,KACF,CAOA,KAAKxgB,EAAO,WAAY,CACtB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAIlB,MAAMogB,EADSpE,GAAW9b,EAAK+b,CAAU,EACP,UAAY,EAC9BkE,GAAY3X,EAAM4X,EAAoBC,CAAO,IAG3DngB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,eAAgB,CAC1B,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAC5BmgB,EAAUK,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAIlB,MAAMogB,EADSpE,GAAW9b,EAAK+b,CAAU,EACP,UAAY,EAC9BkE,GAAY3X,EAAM4X,EAAoBC,CAAO,IAG3DngB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,SAAW,IACpC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,SAAW,IACpC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,OAAS,IAClC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,QAAU,IACnC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,OAAS,IAClC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,MAAO,CACjB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6X,EAAMuE,GAAYlc,EAAI,UAAUuiB,CAAK,EAAGviB,EAAI,UAAUwiB,CAAK,CAAC,EAC9D,CAAC7K,EAAI,YAAcA,EAAI,QAAU,IACnC3X,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,QAAS,CACnB,MAAMugB,EAAcP,EAAU,UAAUzgB,EAAI,GAAI,EAAI,EACpD,GAAIghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElBE,EAAI,GAAKghB,EACT,KACF,CAOA,KAAKvgB,EAAO,YAAa,CACvB,MAAMgiB,EAAUjC,EAASxgB,EAAI,EAAE,EACzB0iB,EAAUlC,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAExD,GADAA,EAAI,IAAM,EACNghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElB,MAAM6iB,EAAU3iB,EAAI,UAAUyiB,CAAO,EAC/BG,EAAU5iB,EAAI,UAAU0iB,CAAO,EACrC,GAAIC,IAAY,MAAQC,IAAY,KAClC,MAEE9F,GAAe,OAAO6F,CAAO,EAAG,OAAOC,CAAO,CAAC,IACjD5iB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,gBAAiB,CAC3B,MAAMgiB,EAAUjC,EAASxgB,EAAI,EAAE,EACzB0iB,EAAUlC,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAExD,GADAA,EAAI,IAAM,EACNghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElB,MAAM6iB,EAAU3iB,EAAI,UAAUyiB,CAAO,EAC/BG,EAAU5iB,EAAI,UAAU0iB,CAAO,EACrC,GAAIC,IAAY,MAAQC,IAAY,KAClC,MAEG9F,GAAe,OAAO6F,CAAO,EAAG,OAAOC,CAAO,CAAC,IAClD5iB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,gBAAiB,CAC3B,MAAMgiB,EAAUjC,EAASxgB,EAAI,EAAE,EACzB6iB,EAAUrC,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAExD,GADAA,EAAI,IAAM,EACNghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElB,MAAM6iB,EAAU3iB,EAAI,UAAUyiB,CAAO,EAC/BK,EAAU9iB,EAAI,UAAU6iB,CAAO,EACrC,GAAIF,IAAY,MAAQG,IAAY,KAClC,MAEE,OAAOH,CAAO,EAAE,SAAS,OAAOG,CAAO,CAAC,IAC1C9iB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,mBAAoB,CAC9B,MAAMgiB,EAAUjC,EAASxgB,EAAI,EAAE,EACzB+iB,EAAUvC,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAExD,GADAA,EAAI,IAAM,EACNghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElB,MAAM6iB,EAAU3iB,EAAI,UAAUyiB,CAAO,EAC/BO,EAAUhjB,EAAI,UAAU+iB,CAAO,EACrC,GAAIJ,IAAY,MAAQK,IAAY,KAClC,MAEE,OAAOL,CAAO,EAAE,WAAW,OAAOK,CAAO,CAAC,IAC5ChjB,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,iBAAkB,CAC5B,MAAMgiB,EAAUjC,EAASxgB,EAAI,EAAE,EACzBijB,EAAUzC,EAASxgB,EAAI,GAAK,CAAC,EAC7BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAExD,GADAA,EAAI,IAAM,EACNghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAElB,MAAM6iB,EAAU3iB,EAAI,UAAUyiB,CAAO,EAC/BS,EAAUljB,EAAI,UAAUijB,CAAO,EACrC,GAAIN,IAAY,MAAQO,IAAY,KAClC,MAEE,OAAOP,CAAO,EAAE,SAAS,OAAOO,CAAO,CAAC,IAC1CljB,EAAI,GAAKghB,GAEX,KACF,CASA,KAAKvgB,EAAO,MAAO,CACjB,MAAM0iB,EAAU3C,EAASxgB,EAAI,EAAE,EACzBojB,EAAU3C,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAC9CghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM0F,EAAMxF,EAAI,UAAUmjB,CAAO,EACjC,GAAI3d,GAAQ,KACV,MAGF,MAAM6d,GAAMvd,EAAA9F,EAAI,SAAJ,YAAA8F,EAAasd,GACrBC,IAEAA,EAAI,IAAI7d,CAAG,GACV,OAAOA,GAAQ,UACd,OAAO,cAAcA,CAAG,GACxB6d,EAAI,IAAI,OAAO7d,CAAG,CAAC,GACpB,OAAOA,GAAQ,UAAY6d,EAAI,IAAI,OAAO7d,CAAG,CAAC,KAE/CxF,EAAI,GAAKghB,GAGb,KACF,CAOA,KAAKvgB,EAAO,YAAa,CACvB,MAAM2gB,EAAUZ,EAASxgB,EAAI,EAAE,EACzBwF,EAAMib,EAAU,SAASzgB,EAAI,GAAK,EAAG,EAAI,EAC/CA,EAAI,IAAM,EACVA,EAAI,UAAUohB,CAAO,EAAI5b,EACzB,KACF,CAOA,KAAK/E,EAAO,cAAe,CACzB,MAAM2gB,EAAUZ,EAASxgB,EAAI,EAAE,EACzBwF,EAAMib,EAAU,WAAWzgB,EAAI,GAAK,EAAG,EAAI,EACjDA,EAAI,IAAM,EACVA,EAAI,UAAUohB,CAAO,EAAI5b,EACzB,KACF,CAOA,KAAK/E,EAAO,aAAc,CACxB,MAAM2gB,EAAUZ,EAASxgB,EAAI,EAAE,EACzBgQ,EAAMyQ,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAC1CgU,EAAa,IAAI,WACrBwM,EAAS,OACTA,EAAS,WAAaxgB,EAAI,GAAK,EAC/BgQ,CAAA,EAEFhQ,EAAI,UAAUohB,CAAO,EAAIlV,GAAa,OAAO8H,CAAU,EACvDhU,EAAI,IAAM,EAAIgQ,EACd,KACF,CAOA,KAAKvP,EAAO,aAAc,CACxB,MAAM2gB,EAAUZ,EAASxgB,EAAI,EAAE,EACzBgQ,EAAMyQ,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAC1CiU,EAAa,IAAI,WAAWjE,CAAG,EACrCiE,EAAW,IACT,IAAI,WACFuM,EAAS,OACTA,EAAS,WAAaxgB,EAAI,GAAK,EAC/BgQ,CAAA,CACF,EAEFhQ,EAAI,UAAUohB,CAAO,EAAInN,EACzBjU,EAAI,IAAM,EAAIgQ,EACd,KACF,CAOA,KAAKvP,EAAO,aAAc,CACxB,MAAM2gB,EAAUZ,EAASxgB,EAAI,EAAE,EAC/BA,EAAI,IAAM,EACVA,EAAI,UAAUohB,CAAO,EAAI,KACzB,KACF,CAUA,KAAK3gB,EAAO,YAAa,CACvB,MAAMsb,EAAayE,EAASxgB,EAAI,EAAE,EAClCA,EAAI,IAAM,EAEV,MAAMuF,EAASuW,GAAW9b,EAAK+b,CAAU,EACnCuH,EAAmBhb,EAAK,UAAU/C,EAAO,UAAY,EAAG,EAAI,EAC5DgL,EAAY,IAAI,WACpBjI,EAAK,OACLA,EAAK,WAAa/C,EAAO,UACzB+d,CAAA,EAGIC,EAAc1D,GAClB7f,EACAsI,EACAiI,EACAuP,CAAA,EAEF,GAAIyD,IAAgBzjB,EAAS,QAC3B,OAAOyjB,EAET,KACF,CAOA,KAAK9iB,EAAO,UAAW,CACrB,MAAM+iB,EAAahD,EAASxgB,EAAI,EAAE,EAC5BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM2jB,EAAa,OAAOzjB,EAAI,UAAUwjB,CAAU,GAAK,CAAC,EACpDC,EAAa,IACfzjB,EAAI,UAAUwjB,CAAU,EAAIC,EAAa,EACzCzjB,EAAI,GAAKghB,GAEX,KACF,CAQA,KAAKvgB,EAAO,SAAU,CACpB,MAAMijB,EAAYlD,EAASxgB,EAAI,EAAE,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM6jB,EAAY,OAAO3jB,EAAI,UAAU0jB,CAAS,GAAK,CAAC,EAClDC,GAAa,GACf3jB,EAAI,UAAU0jB,CAAS,EAAI,EAC3B1jB,EAAI,GAAKghB,GAEThhB,EAAI,UAAU0jB,CAAS,EAAIC,EAAY,EAEzC,KACF,CAMA,KAAKljB,EAAO,YAAa,CACvB,MAAMmjB,EAASnD,EAAU,UAAUzgB,EAAI,GAAI,EAAI,EACzC6jB,EAAgBrD,EAASxgB,EAAI,GAAK,CAAC,EACnC8jB,EAAWtD,EAASxgB,EAAI,GAAK,CAAC,EAC9B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EAEV,MAAMgkB,GAAKrE,EAAA3f,EAAI,OAAJ,YAAA2f,EAAWiE,GACtB,GAAI,CAACI,EACH,OAAAhkB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMmkB,EAAc,CAAA,EACpB,QAAS9H,EAAI,EAAGA,EAAI2H,EAAU3H,IAC5B8H,EAAK,KAAKjkB,EAAI,UAAU6jB,EAAgB1H,CAAC,CAAC,EAG5C,GAAI,CACF,MAAM+H,EAAMF,EAAG,GAAGC,CAAI,EACtBjkB,EAAI,UAAU+jB,CAAQ,EAAIG,IAAQ,OAAYA,EAAM,IACtD,MAAQ,CACN,OAAAlkB,EAAI,OAASF,EAAS,MACfA,EAAS,KAClB,CACA,KACF,CAOA,KAAKW,EAAO,aAAc,CACxB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,IAAQ,KAAO,OAAOA,CAAG,EAAE,YAAA,EAAgB,KAC7C,KACF,CAOA,KAAK/E,EAAO,aAAc,CACxB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,IAAQ,KAAO,OAAOA,CAAG,EAAE,YAAA,EAAgB,KAC7C,KACF,CAOA,KAAK/E,EAAO,cAAe,CACzB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EAAIve,IAAQ,KAAO,OAAOA,CAAG,EAAE,OAAS,KAC9D,KACF,CAOA,KAAK/E,EAAO,cAAe,CACzB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB4d,EAAY4C,EAASxgB,EAAI,GAAK,CAAC,EAC/BokB,EAAU5D,EAASxgB,EAAI,GAAK,CAAC,EAC7B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EAC3Bzd,EAAQ1G,EAAI,UAAU4d,CAAS,EAC/B5N,EAAMhQ,EAAI,UAAUokB,CAAO,EACjC,GAAI5e,IAAQ,MAAQkB,IAAU,KAAM,CAClC1G,EAAI,UAAU+jB,CAAQ,EAAI,KAC1B,KACF,CACA,MAAMzH,EAAM,OAAO9W,CAAG,EAChB6e,EAAQ,KAAK,IAAI,EAAG,OAAO3d,CAAK,EAAI,CAAC,EAC3C,GAAIsJ,IAAQ,KACVhQ,EAAI,UAAU+jB,CAAQ,EAAIzH,EAAI,MAAM+H,CAAK,MACpC,CACL,MAAMC,EAAI,KAAK,IAAI,EAAG,OAAOtU,CAAG,CAAC,EACjChQ,EAAI,UAAU+jB,CAAQ,EAAIzH,EAAI,MAAM+H,EAAOA,EAAQC,CAAC,CACtD,CACA,KACF,CAOA,KAAK7jB,EAAO,YAAa,CACvB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,GAAQ,KAA4B,OAAOA,CAAG,EAAE,KAAA,EAAS,KAC3D,KACF,CAOA,KAAK/E,EAAO,YAAa,CACvB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,GAAQ,KAA4B,KAAK,IAAI,OAAOA,CAAG,CAAC,EAAI,KAC9D,KACF,CAOA,KAAK/E,EAAO,cAAe,CACzB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,GAAQ,KAA4B,KAAK,MAAM,OAAOA,CAAG,CAAC,EAAI,KAChE,KACF,CASA,KAAK/E,EAAO,cAAe,CACzB,MAAMmd,EAAY4C,EAASxgB,EAAI,EAAE,EAC3Buf,EAAWiB,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EAEV,MAAMukB,EAAajF,GAA2Btf,EAAK4d,EAAW2B,CAAQ,EAChEgE,EAAc1D,GAClB7f,EACAsI,EACAic,EACAzE,CAAA,EAEF,GAAIyD,IAAgBzjB,EAAS,QAC3B,OAAOyjB,EAET,KACF,CAOA,KAAK9iB,EAAO,eAAgB,CAC1B,MAAM+jB,EAAYhE,EAASxgB,EAAI,EAAE,EAC3BykB,EAAejE,EAASxgB,EAAI,GAAK,CAAC,EACxCA,EAAI,IAAM,EAEV,MAAMkd,EAAWld,EAAI,SAASykB,CAAY,GAAK,CAC7C,QAAS,EACT,WAAY,CAAC,CAAC,EACd,WAAY,CAAC,CAAC,CAAA,EAGVC,EACJxH,EAAS,QAAU,QAAaA,EAAS,MAAQ,GAC5CA,EAAS,QAAU,GAAKA,EAAS,MAClC,EACAgC,EACJwF,EAAc,GAAKA,GAAejlB,GAC9BilB,EACA,EAEN1kB,EAAI,QAAQwkB,CAAS,EAAI,CACvB,QAAStH,EACT,QAAS,CAAA,EACT,QAAS,EACT,SAAU,GACV,KAAMgC,CAAA,EAER,KACF,CAQA,KAAKze,EAAO,iBAAkB,CAC5B,MAAM+jB,EAAYhE,EAASxgB,EAAI,EAAE,EAC3B4d,EAAY4C,EAASxgB,EAAI,GAAK,CAAC,EAC/Bmd,EAAWqD,EAASxgB,EAAI,GAAK,CAAC,EAC9B+b,EAAayE,EAASxgB,EAAI,GAAK,CAAC,EACtCA,EAAI,IAAM,EAEV,MAAM6e,EAAS7e,EAAI,QAAQwkB,CAAS,EACpC,GAAI,CAAC3F,EACH,OAAA7e,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMof,EAAQL,EAAO,MAAQ,EAK7B,GAAIK,EAAQ,GAAKL,EAAO,QAAQ,QAAUK,GACxC,GAAI/B,IAAa,EAAG,CAClB,MAAMwH,EAAO3kB,EAAI,UAAU4d,CAAS,EAC9BgH,EAAO/F,EAAO,QAAQ,CAAC,EAAE,KAAK,CAAC,EAC/BgG,EAAMhG,EAAO,QAAQ,WAAW,CAAC,GAAK,EAC5C,GAAI,OAAO8F,GAAS,UAAY,OAAOC,GAAS,UAC9C,GAAIC,IAAQ,EAAIF,GAAQC,EAAOD,GAAQC,EACrC,cAEO,OAAOD,GAAS,UAAY,OAAOC,GAAS,UACrD,GAAIC,IAAQ,EAAIF,GAAQC,EAAOD,GAAQC,EACrC,cAGUlH,GACV1d,EAAI,UACJ4d,EACAiB,EAAO,QAAQ,CAAC,EAAE,KAClBA,EAAO,OAAA,GAEE,EAAG,KAElB,SACcnB,GACV1d,EAAI,UACJ4d,EACAiB,EAAO,QAAQ,CAAC,EAAE,KAClBA,EAAO,OAAA,GAEE,EAAG,MAIlB,MAAMtZ,EAASuW,GAAW9b,EAAK+b,CAAU,EACnC9K,EAAU3I,EAAK,UAAU/C,EAAO,UAAY,EAAG,EAAI,EAEnDyZ,EAAc,IAAI,MAAM7B,CAAQ,EACtC,QAASjZ,EAAI,EAAGA,EAAIiZ,EAAUjZ,IAC5B8a,EAAK9a,CAAC,EAAIlE,EAAI,UAAU4d,EAAY1Z,CAAC,EAGvC,MAAM4gB,EAAgB/F,GACpB/e,EACA6e,EACAG,EACAzZ,EAAO,UACP0L,EACA3I,EACA4W,CAAA,EAEF,GAAI4F,IAAkBhlB,EAAS,QAC7B,OAAOglB,EAET,KACF,CAOA,KAAKrkB,EAAO,eAAgB,CAC1B,MAAM+jB,EAAYhE,EAASxgB,EAAI,EAAE,EACjCA,EAAI,IAAM,EAEV,MAAM6e,EAAS7e,EAAI,QAAQwkB,CAAS,EACpC,GAAI,CAAC3F,EACH,OAAA7e,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB8e,GAAoBC,CAAM,EAC1BA,EAAO,SAAW,GAClB,KACF,CAQA,KAAKpe,EAAO,eAAgB,CAC1B,MAAM+jB,EAAYhE,EAASxgB,EAAI,EAAE,EAC3BghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM+e,EAAS7e,EAAI,QAAQwkB,CAAS,EACpC,GAAI,CAAC3F,EACH,OAAA7e,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMilB,EACJlG,EAAO,QAAQ,QAAU,QACpBA,EAAO,QAAQ,QAAU,GAAKA,EAAO,QAAQ,MAC9CA,EAAO,QAAQ,OAErB,GAAIA,EAAO,SAAW,KAAK,IAAIA,EAAO,QAAQ,OAAQkG,CAAQ,EAE5D,MAGF,MAAMC,EAAQnG,EAAO,QAAQA,EAAO,OAAO,EACrCtO,EACJyU,EAAM,SACN,IAAI,WACF1c,EAAK,OACLA,EAAK,WAAa0c,EAAM,UACxBA,EAAM,MAAA,EAGJzB,EAAc1D,GAClB7f,EACAsI,EACAiI,EACAuP,CAAA,EAEF,GAAIyD,IAAgBzjB,EAAS,QAC3B,OAAOyjB,EAGT1E,EAAO,UACP7e,EAAI,GAAKghB,EACT,KACF,CAOA,KAAKvgB,EAAO,cAAe,CACzB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,GAAQ,KAA4B,KAAK,MAAM,OAAOA,CAAG,CAAC,EAAI,KAChE,KACF,CAOA,KAAK/E,EAAO,aAAc,CACxB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAMwF,EAAMxF,EAAI,UAAUmkB,CAAO,EACjCnkB,EAAI,UAAU+jB,CAAQ,EACpBve,GAAQ,KAA4B,KAAK,KAAK,OAAOA,CAAG,CAAC,EAAI,KAC/D,KACF,CAOA,KAAK/E,EAAO,OAAQ,CAClB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAM4V,EAAQ5V,EAAI,UAAUuiB,CAAK,EAC3BxM,EAAQ/V,EAAI,UAAUwiB,CAAK,EAE/B5M,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV/V,EAAI,UAAU+jB,CAAQ,EAAI,KAE1B/jB,EAAI,UAAU+jB,CAAQ,EAAI,OAAOnO,CAAK,EAAI,OAAOG,CAAK,EAExD,KACF,CAOA,KAAKtV,EAAO,OAAQ,CAClB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAM4V,EAAQ5V,EAAI,UAAUuiB,CAAK,EAC3BxM,EAAQ/V,EAAI,UAAUwiB,CAAK,EAE/B5M,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV/V,EAAI,UAAU+jB,CAAQ,EAAI,KAE1B/jB,EAAI,UAAU+jB,CAAQ,EAAI,OAAOnO,CAAK,EAAI,OAAOG,CAAK,EAExD,KACF,CAOA,KAAKtV,EAAO,OAAQ,CAClB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAM4V,EAAQ5V,EAAI,UAAUuiB,CAAK,EAC3BxM,EAAQ/V,EAAI,UAAUwiB,CAAK,EAE/B5M,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV/V,EAAI,UAAU+jB,CAAQ,EAAI,KAE1B/jB,EAAI,UAAU+jB,CAAQ,EAAI,OAAOnO,CAAK,EAAI,OAAOG,CAAK,EAExD,KACF,CAOA,KAAKtV,EAAO,OAAQ,CAClB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAM4V,EAAQ5V,EAAI,UAAUuiB,CAAK,EAC3BxM,EAAQ/V,EAAI,UAAUwiB,CAAK,EACjC,GACE5M,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV/V,EAAI,UAAU+jB,CAAQ,EAAI,SACrB,CACL,MAAMkB,EAAQ,OAAOlP,CAAK,EAC1B/V,EAAI,UAAU+jB,CAAQ,EAAIkB,IAAU,EAAI,KAAO,OAAOrP,CAAK,EAAIqP,CACjE,CACA,KACF,CAOA,KAAKxkB,EAAO,OAAQ,CAClB,MAAM8hB,EAAQ/B,EAASxgB,EAAI,EAAE,EACvBwiB,EAAQhC,EAASxgB,EAAI,GAAK,CAAC,EAC3B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,MAAM4V,EAAQ5V,EAAI,UAAUuiB,CAAK,EAC3BxM,EAAQ/V,EAAI,UAAUwiB,CAAK,EACjC,GACE5M,GAAU,MAEVG,IAAU,MACVA,IAAU,OAEV/V,EAAI,UAAU+jB,CAAQ,EAAI,SACrB,CACL,MAAMkB,EAAQ,OAAOlP,CAAK,EAC1B/V,EAAI,UAAU+jB,CAAQ,EAAIkB,IAAU,EAAI,KAAO,OAAOrP,CAAK,EAAIqP,CACjE,CACA,KACF,CAOA,KAAKxkB,EAAO,cAAe,CACzB,MAAMmd,EAAY4C,EAASxgB,EAAI,EAAE,EAC3BklB,EAAW1E,EAASxgB,EAAI,GAAK,CAAC,EAC9B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,IAAIkkB,EAAM,GACNiB,EAAU,GACd,QAAShlB,EAAI,EAAGA,EAAI+kB,EAAU/kB,IAAK,CACjC,MAAMgE,EAAInE,EAAI,UAAU4d,EAAYzd,CAAC,EACjCgE,GAAM,OACRghB,EAAU,GACVjB,GAAO,OAAO/f,CAAC,EAEnB,CACAnE,EAAI,UAAU+jB,CAAQ,EAAIoB,EAAUjB,EAAM,KAC1C,KACF,CAOA,KAAKzjB,EAAO,YAAa,CACvB,MAAMmd,EAAY4C,EAASxgB,EAAI,EAAE,EAC3BklB,EAAW1E,EAASxgB,EAAI,GAAK,CAAC,EAC9B+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACV,IAAIolB,EAAsB,KAC1B,QAASjlB,EAAI,EAAGA,EAAI+kB,EAAU/kB,IAAK,CACjC,MAAMgE,EAAInE,EAAI,UAAU4d,EAAYzd,CAAC,EACrC,GAAIgE,GAAM,KAAyB,CACjCihB,EAAiBjhB,EACjB,KACF,CACF,CACAnE,EAAI,UAAU+jB,CAAQ,EAAIqB,EAC1B,KACF,CAOA,KAAK3kB,EAAO,QAAS,CACnB,MAAM0jB,EAAU3D,EAASxgB,EAAI,EAAE,EACzB+jB,EAAWvD,EAASxgB,EAAI,GAAK,CAAC,EACpCA,EAAI,IAAM,EACVA,EAAI,UAAU+jB,CAAQ,EAAI/jB,EAAI,UAAUmkB,CAAO,EAC/C,KACF,CAOA,KAAK1jB,EAAO,YAAa,CACvB,MAAM4kB,EAAS7E,EAASxgB,EAAI,EAAE,EACxBslB,EAAgB9E,EAASxgB,EAAI,GAAK,CAAC,EACnCmd,EAAWqD,EAASxgB,EAAI,GAAK,CAAC,EAC9BulB,EAAO/E,EAASxgB,EAAI,GAAK,CAAC,EAGhC,GAFAA,EAAI,IAAM,EAENulB,IAAS,EAAG,CAGd,GAAIvlB,EAAI,YAAc,MAAaA,EAAI,eACrC,OAAAA,EAAI,OAASF,EAAS,gBACfA,EAAS,gBAElBE,EAAI,aAAe,MAEnB,MAAMme,EAAyBF,GAAmB,IAAgB,EAElE,GAAId,IAAa,EAAG,CAClB,MAAMtE,EAAIgF,GAAS,EAAE,EACf5B,EAAOpD,EAAI,KACjBsF,EAAQlC,CAAI,EAAE,KAAOpD,EACrBsF,EAAQlC,CAAI,EAAE,KAAO,CAAA,EACrBkC,EAAQlC,CAAI,EAAE,MAAQ,EACtBkC,EAAQlC,CAAI,EAAE,IAAM,EACpBkC,EAAQlC,CAAI,EAAE,QAAU,IACxBkC,EAAQlC,CAAI,EAAE,QAAU,KACxBkC,EAAQlC,CAAI,EAAE,QAAU,EAC1B,CAEAjc,EAAI,YAAYqlB,CAAM,EAAI,CACxB,KAAM,EACN,YAAaC,EACb,QAASnI,EACT,SAAU,KACV,cAAeA,IAAa,EAAI,EAAI,EACpC,QAAS,EACT,QAAAgB,CAAA,CAEJ,MACEne,EAAI,YAAYqlB,CAAM,EAAI,CACxB,KAAM,EACN,YAAaC,EACb,QAASnI,EACT,SAAU,EACV,cAAe,EACf,QAAS,EACT,QAAS,CAAA,CAAC,EAGd,KACF,CAOA,KAAK1c,EAAO,YAAa,CACvB,MAAM4kB,EAAS7E,EAASxgB,EAAI,EAAE,EACxBslB,EAAgB9E,EAASxgB,EAAI,GAAK,CAAC,EACnCmd,EAAWqD,EAASxgB,EAAI,GAAK,CAAC,EAC9BwlB,EAAUhF,EAASxgB,EAAI,GAAK,CAAC,EAC7BylB,EAAUjF,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAM0lB,EAAM1lB,EAAI,YAAYqlB,CAAM,EAClC,GAAI,CAACK,EACH,OAAA1lB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAMkf,EAAc,CAAA,EACpB,QAAS9a,EAAI,EAAGA,EAAIiZ,EAAUjZ,IAC5B8a,EAAK,KAAKhf,EAAI,UAAUslB,EAAgBphB,CAAC,CAAC,EAE5C,MAAMsB,EAAMggB,IAAY,IAAM,KAAOxlB,EAAI,UAAUwlB,CAAO,EAE1D,GAAIE,EAAI,OAAS,EAAG,CAClB,MAAM5H,EAAOD,GAASmB,CAAI,EACpB/C,EAAO6B,EAAO4H,EAAI,SACxB,IAAIC,EAAoC,KAExC,QAAS1M,EAAQ,EAAGA,EAAQyM,EAAI,SAAUzM,IAAS,CACjD,MAAM1S,GAAO0V,EAAOhD,GAASyM,EAAI,SAC3B1Y,EAAI0Y,EAAI,QAAQnf,CAAG,EACzB,GAAIyG,EAAE,OAAS,EAAG,CAChBA,EAAE,KAAO8Q,EACT9Q,EAAE,KAAOgS,EAAK,MAAA,EACdhS,EAAE,MAAQ,EACVA,EAAE,IAAM,EACRA,EAAE,QAAU,IACZA,EAAE,QAAU,KACZA,EAAE,QAAU,GACZ0Y,EAAI,gBACJC,EAAgB3Y,EAChB,KACF,SAAWA,EAAE,OAAS8Q,GAAQE,GAAiBhR,EAAE,KAAMgS,CAAI,EAAG,CAC5D2G,EAAgB3Y,EAChB,KACF,CACF,CAEA,GAAI,CAAC2Y,EACH,OAAA3lB,EAAI,OAASF,EAAS,gBACfA,EAAS,gBAIlB,GAAI2lB,IAAY,GACVD,IAAY,KAAQhgB,GAAQ,OAC9BmgB,EAAc,gBAEPF,IAAY,GAAKA,IAAY,EAClCjgB,GAAQ,OACVmgB,EAAc,KAAO,OAAOngB,CAAG,EAC/BmgB,EAAc,QAAU,YAEjBF,IAAY,GACrB,GAAIjgB,GAAQ,KAA2B,CACrC,MAAMogB,EAAM,OAAOpgB,CAAG,GAClB,CAACmgB,EAAc,SAAWC,EAAMD,EAAc,WAChDA,EAAc,QAAUC,GAE1BD,EAAc,QAAU,EAC1B,UACSF,IAAY,GACjBjgB,GAAQ,KAA2B,CACrC,MAAMogB,EAAM,OAAOpgB,CAAG,GAClB,CAACmgB,EAAc,SAAWC,EAAMD,EAAc,WAChDA,EAAc,QAAUC,GAE1BD,EAAc,QAAU,EAC1B,CAIF,GAAID,EAAI,cAAgB,GAAMA,EAAI,SAAU,CAE1C,MAAMG,EADeH,EAAI,SACW,EAC9BI,EAAWD,EAAe,GAChC,GAAI7lB,EAAI,YAAc8lB,EAAW9lB,EAAI,eACnC,OAAAA,EAAI,OAASF,EAAS,gBACfA,EAAS,gBAElBE,EAAI,aAAe8lB,EAEnB,MAAMC,EAAcL,EAAI,QAClBM,EAA6B/H,GAAmB4H,CAAY,EAElE,QAASI,EAAQ,EAAGA,EAAQF,EAAY,OAAQE,IAAS,CACvD,MAAMC,EAAQH,EAAYE,CAAK,EAC/B,GAAIC,EAAM,OAAS,EAAG,CACpB,MAAMxe,EAAIwe,EAAM,KAAOL,EACvB,QAASpN,EAAI,EAAGA,EAAIoN,EAAcpN,IAAK,CACrC,MAAM0N,GAAOze,EAAI+Q,GAAKoN,EACtB,GAAIG,EAAYG,CAAG,EAAE,OAAS,EAAG,CAC/BH,EAAYG,CAAG,EAAID,EACnB,KACF,CACF,CACF,CACF,CAEAR,EAAI,SAAWG,EACfH,EAAI,QAAUM,CAChB,CACF,CACA,KACF,CAOA,KAAKvlB,EAAO,YAAa,CACvB,MAAM4kB,EAAS7E,EAASxgB,EAAI,EAAE,EACxBomB,EAAc5F,EAASxgB,EAAI,GAAK,CAAC,EACjCqmB,EAAc7F,EAASxgB,EAAI,GAAK,CAAC,EACjCghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM4lB,EAAM1lB,EAAI,YAAYqlB,CAAM,EAClC,GAAI,CAACK,EACH,OAAA1lB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,KACE4lB,EAAI,QAAUA,EAAI,QAAQ,QAC1BA,EAAI,QAAQA,EAAI,OAAO,EAAE,OAAS,GAElCA,EAAI,UAGN,GAAIA,EAAI,SAAWA,EAAI,QAAQ,OAE7B,MAGF,MAAMY,EAASZ,EAAI,QAAQA,EAAI,SAAS,EAExC,QAASxhB,EAAI,EAAGA,EAAIoiB,EAAO,KAAK,OAAQpiB,IACtClE,EAAI,UAAUomB,EAAcliB,CAAC,EAAIoiB,EAAO,KAAKpiB,CAAC,EAGhDlE,EAAI,UAAUqmB,CAAW,EAAIC,EAAO,IACpCtmB,EAAI,UAAUqmB,EAAc,CAAC,EAAIC,EAAO,MACxCtmB,EAAI,UAAUqmB,EAAc,CAAC,EAAIC,EAAO,QAAUA,EAAO,QAAU,KACnEtmB,EAAI,UAAUqmB,EAAc,CAAC,EAAIC,EAAO,QAAUA,EAAO,QAAU,KAEnEtmB,EAAI,GAAKghB,EACT,KACF,CAOA,KAAKvgB,EAAO,aAAc,CACxB,MAAM8lB,EAAU/F,EAASxgB,EAAI,EAAE,EACzBwmB,EAAYhG,EAASxgB,EAAI,GAAK,CAAC,EAC/BymB,EAAUjG,EAASxgB,EAAI,GAAK,CAAC,EAC7BylB,EAAUjF,EAASxgB,EAAI,GAAK,CAAC,EACnCA,EAAI,IAAM,EAEV,MAAM0mB,EAAM1mB,EAAI,UAAUumB,CAAO,EAC3BrjB,EAAQ,OAAOlD,EAAI,UAAUwmB,CAAS,GAAK,CAAC,EAE9Cf,IAAY,EACdzlB,EAAI,UAAUymB,CAAO,EAAIvjB,EAChBuiB,IAAY,EACrBzlB,EAAI,UAAUymB,CAAO,EAAIvjB,EAAQ,EAAI,OAAOwjB,CAAG,EAAI,KAC1CjB,IAAY,EACrBzlB,EAAI,UAAUymB,CAAO,EAAIvjB,EAAQ,EAAI,OAAOwjB,CAAG,EAAIxjB,EAAQ,MAClDuiB,IAAY,GAAKA,IAAY,KACtCzlB,EAAI,UAAUymB,CAAO,EAAIzmB,EAAI,UAAUumB,CAAO,GAEhD,KACF,CAOA,KAAK9lB,EAAO,eAAgB,CAC1B,MAAMkmB,EAAMnG,EAASxgB,EAAI,EAAE,EACrBghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM0F,EAAMxF,EAAI,UAAU2mB,CAAG,EACzBnhB,GAAQ,OACVxF,EAAI,GAAKghB,GAEX,KACF,CAOA,KAAKvgB,EAAO,mBAAoB,CAC9B,MAAMkmB,EAAMnG,EAASxgB,EAAI,EAAE,EACrBghB,EAAcP,EAAU,UAAUzgB,EAAI,GAAK,EAAG,EAAI,EAGxD,GAFAA,EAAI,IAAM,EAENghB,EAAcN,EAChB,OAAA1gB,EAAI,OAASF,EAAS,iBACfA,EAAS,iBAGlB,MAAM0F,EAAMxF,EAAI,UAAU2mB,CAAG,EACzBnhB,GAAQ,OACVxF,EAAI,GAAKghB,GAEX,KACF,CAEA,QACE,OAAAhhB,EAAI,OAASF,EAAS,iBACfA,EAAS,gBAAA,CAEtB,CAEA,OAAAE,EAAI,OAASF,EAAS,KACfA,EAAS,IAClB,CCzrEA,MAAMoM,GAAe,IAAI,YAEZ0a,GAAc,IAAI,WAAW,CAAC,GAAM,GAAM,GAAM,GAAM,GAAM,CAAI,CAAC,EAMxEpgB,GAAY,IAAI,YAAY,GAAG,EACrC,IAAIqgB,GAAwB,EAK5B,SAASC,IAAuB,CAC9B,GAAI,CAAAD,GACJ,SAAS1mB,EAAI,EAAGA,EAAI,IAAKA,IAAK,CAC5B,IAAIC,EAAID,EACR,QAAS+D,EAAI,EAAGA,EAAI,EAAGA,IACrB9D,EAAKA,EAAI,EAAM,WAAcA,IAAM,EAAOA,IAAM,EAElDoG,GAAUrG,CAAC,EAAIC,IAAM,CACvB,CACAymB,GAAwB,EAC1B,CA+BO,SAASE,GAAuBze,EAAgB0e,EAAoB,EAAQ,CACjFF,GAAA,EACA,IAAIlgB,EAAM,WACV,QAASzG,EAAI,EAAGA,EAAI,KAAWA,IAAK,CAClC,MAAM4G,EAAQ5G,GAAK,IAAMA,GAAK,GAAM,EAAImI,EAAK,SAAS0e,EAAe7mB,CAAC,EACtEyG,EAAMJ,IAAWI,EAAMG,GAAQ,GAAI,EAAKH,IAAQ,CAClD,CACA,OAAQA,EAAM,cAAgB,CAChC,CAUO,SAASqgB,GACd3e,EACA0e,EAAoB,EACd,CAENrf,GAAOW,EAAM0e,EAAc,EAAG,IAAS,EAGvC1e,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,EAAI,EAC1D4R,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,EAAI,EAC1D4R,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,EAAI,EAC1D4R,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,EAAI,EAC1D4R,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,EAAI,EAC1D4R,EAAK,SAAS0e,EAAetwB,GAAsB,EAAG,CAAI,EAG1D4R,EAAK,UAAU0e,EAAerwB,GAAyB,KAAW,EAAI,EAGtE2R,EAAK,UACH0e,EAAepwB,GACf+H,GACA,EAAA,EAIF2J,EAAK,UACH0e,EAAenwB,GACf+H,GACA,EAAA,EAIF0J,EAAK,UAAU0e,EAAelwB,GAA2B,EAAG,EAAI,EAGhEwR,EAAK,UAAU0e,EAAejwB,GAA8B,EAAG,EAAI,EAGnEuR,EAAK,UAAU0e,EAAehwB,GAA8B,EAAG,EAAI,EAGnEsR,EAAK,UAAU0e,EAAe/vB,GAA8B,EAAG,EAAI,EAGnEqR,EAAK,UAAU0e,EAAe9vB,GAA6B,EAAG,EAAI,EAGlEoR,EAAK,UAAU0e,EAAe7vB,GAAoC,EAAG,EAAI,EACzEmR,EAAK,UAAU0e,EAAe5vB,GAA0C,EAAG,EAAI,EAG/E,MAAM+S,EAAM4c,GAAuBze,EAAM0e,CAAY,EACrD1e,EAAK,UAAU0e,EAAe9vB,GAA6BiT,EAAK,EAAI,CACtE,CAKO,SAAS+c,GACd5e,EACA6e,EAA2B,GAC3B,CAEA,QAAShnB,EAAI,EAAGA,EAAIymB,GAAY,OAAQzmB,IACtC,GAAImI,EAAK,SAAS5R,GAAsByJ,CAAC,IAAMymB,GAAYzmB,CAAC,EAC1D,MAAM,IAAIoC,GACR,6CAAA,EAKN,MAAM6kB,EAAY9e,EAAK,UAAU3R,GAAyB,EAAI,EACxD0wB,EAAsB/e,EAAK,UAC/B1R,GACA,EAAA,EAEI0wB,EAAmBhf,EAAK,UAAUzR,GAAgC,EAAI,EACtE0wB,EAAcjf,EAAK,UAAUxR,GAA2B,EAAI,EAC5D0wB,EAAiBlf,EAAK,UAAUvR,GAA8B,EAAI,EAClE0wB,EAAiBnf,EAAK,UAAUtR,GAA8B,EAAI,EAClE0wB,EAAiBpf,EAAK,UAAUrR,GAA8B,EAAI,EAClEyT,EAAkBpC,EAAK,UAAUpR,GAA6B,EAAI,EAGxE,GAAIowB,EAAmB3oB,GACrB,MAAM,IAAI2D,GACR,mDAAmDglB,CAAgB,mCAAmC3oB,EAAsB,EAAA,EAKhI,GAAIwoB,GAAmBzc,IAAoB,EAAG,CAC5C,MAAMC,EAAWoc,GAAuBze,EAAM,CAAC,EAC/C,GAAIqC,IAAaD,EACf,MAAM,IAAI9I,GAAiB,EAAG8I,EAAiBC,CAAQ,CAE3D,CAEA,MAAO,CACL,SAAUyc,EACV,kBAAmBC,EACnB,eAAgBC,EAChB,WAAYC,EACZ,aAAcC,EACd,cAAeC,EACf,cAAeC,EACf,eAAgBhd,CAAA,CAEpB,CAKO,SAASid,GACdrf,EACA0e,EAAoB,EACf,CACL,OAAO1e,EAAK,UAAU0e,EAAelwB,GAA2B,EAAI,CACtE,CAKO,SAAS8wB,GACdtf,EACA0e,EACA9jB,EACM,CACFA,IAAU,SACZA,EAAQ8jB,EACRA,EAAe,GAEjB1e,EAAK,UAAU0e,EAAelwB,GAA2BoM,EAAO,EAAI,CACtE,CAKO,SAAS2kB,GACdvf,EACA0e,EAAoB,EACf,CACL,OAAO1e,EAAK,UAAU0e,EAAejwB,GAA8B,EAAI,CACzE,CAKO,SAAS+wB,GACdxf,EACA0e,EACApO,EACM,CACFA,IAAY,SACdA,EAAUoO,EACVA,EAAe,GAEjB1e,EAAK,UAAU0e,EAAejwB,GAA8B6hB,EAAS,EAAI,CAC3E,CAKO,SAASmP,GACdzf,EACA0e,EAAoB,EACf,CACL,OAAO1e,EAAK,UAAU0e,EAAehwB,GAA8B,EAAI,CACzE,CAKO,SAASgxB,GACd1f,EACA0e,EAAoB,EACf,CACL,MAAM7iB,EAAI4jB,GAA2Bzf,EAAM0e,CAAY,EAAI,EAC3D,OAAA1e,EAAK,UAAU0e,EAAehwB,GAA8BmN,EAAG,EAAI,EAC5DA,CACT,CAKO,SAAS8jB,GACd3f,EACA0e,EAAoB,EACf,CACL,OAAO1e,EAAK,UAAU0e,EAAe/vB,GAA8B,EAAI,CACzE,CAKO,SAASixB,GACd5f,EACA0e,EAAoB,EACf,CACL,MAAM5mB,EAAI6nB,GAA2B3f,EAAM0e,CAAY,EAAI,EAC3D,OAAA1e,EAAK,UAAU0e,EAAe/vB,GAA8BmJ,EAAG,EAAI,EAC5DA,CACT,CAKO,SAAS+nB,GACd7f,EACA0e,EAAoB,EACf,CACL1e,EAAK,UAAU0e,EAAe9vB,GAA6B,EAAG,EAAI,EAClE,MAAMiT,EAAM4c,GAAuBze,EAAM0e,CAAY,EACrD,OAAA1e,EAAK,UAAU0e,EAAe9vB,GAA6BiT,EAAK,EAAI,EAC7DA,CACT,CASO,SAASie,GACd9f,EACAvC,EACAuW,EACA+L,EACM,CACN,IAAI,EAAI,EACR,KAAO,EAAIA,GAAW,EAAIjgB,GAAOkU,CAAG,EAAG,IACrChU,EAAK,SAASvC,EAAS,EAAGuW,EAAI,WAAW,CAAC,CAAC,EAE7C,KAAO,EAAI+L,EAAS,IAClB/f,EAAK,SAASvC,EAAS,EAAG,CAAC,CAE/B,CAKO,SAASuiB,GACdhgB,EACAvC,EACAsiB,EACQ,CACR,MAAMjd,EAAkB,CAAA,EACxB,QAAS,EAAI,EAAG,EAAIid,EAAS,IAAK,CAChC,MAAMrb,EAAI1E,EAAK,SAASvC,EAAS,CAAC,EAClC,GAAIiH,IAAM,EAAG,MACb5B,EAAM,KAAK4B,CAAC,CACd,CACA,OAAOd,GAAa,OAAO,IAAI,WAAWd,CAAK,CAAC,CAClD,CAKO,SAASmd,GAAwBC,EAA4B,CAClE,OAAQA,EAAS,cAAY,CAC3B,IAAK,QACH,OAAOnoB,EAAS,MAClB,IAAK,QACH,OAAOA,EAAS,MAClB,IAAK,UACH,OAAOA,EAAS,QAClB,IAAK,OACH,OAAOA,EAAS,KAClB,IAAK,OACH,OAAOA,EAAS,KAClB,IAAK,OACH,OAAOA,EAAS,KAClB,IAAK,OACH,OAAOA,EAAS,KAClB,QACE,MAAM,IAAI,MAAM,kCAAkCmoB,CAAQ,GAAG,CAAA,CAEnE,CASO,SAASC,GACdngB,EACA0G,EACwB,CACxB,MAAMjJ,EAASrO,GAAsBsX,EAAW7W,GAC1CuwB,EAAWpgB,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAChD,GAAI2iB,IAAa,EAAG,OAAO,KAE3B,MAAMC,EAAergB,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAC9Cgb,EAAezY,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAC9C6iB,EAAsBtgB,EAAK,UAAUvC,EAAS,EAAG,EAAI,EACrD8iB,EAAOP,GAA0BhgB,EAAMvC,EAAS,GAAIxP,EAAe,EACnEuyB,EAAQxgB,EAAK,UAAUvC,EAAS,GAAI,EAAI,EACxCgjB,EAAqBzgB,EAAK,UAAUvC,EAAS,GAAI,EAAI,EACrDijB,EAAgB1gB,EAAK,aAAavC,EAAS,GAAI,EAAI,EAEzD,MAAO,CACL,QAAS2iB,EACT,YAAaC,EACb,WAAY5H,EACZ,iBAAkB6H,EAClB,KAAAC,EACA,MAAAC,EACA,iBAAkBC,EAClB,YAAaC,CAAA,CAEjB,CAKO,SAASC,GACd3gB,EACA0G,EACAka,EACM,CACN,MAAMnjB,EAASrO,GAAsBsX,EAAW7W,GAChDmQ,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,QAAS,EAAI,EAC7C5gB,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,YAAa,EAAI,EACjD5gB,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,WAAY,EAAI,EAChD5gB,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,iBAAkB,EAAI,EACtDd,GAA2B9f,EAAMvC,EAAS,GAAImjB,EAAK,KAAM3yB,EAAe,EACxE+R,EAAK,UAAUvC,EAAS,GAAImjB,EAAK,MAAO,EAAI,EAC5C5gB,EAAK,UAAUvC,EAAS,GAAImjB,EAAK,iBAAkB,EAAI,EACvD5gB,EAAK,aAAavC,EAAS,GAAImjB,EAAK,YAAa,EAAI,EAEvC,IAAI,WAAW5gB,EAAK,OAAQA,EAAK,UAAU,EACnD,KAAK,EAAGvC,EAAS,GAAIA,EAAS5N,EAAqB,CAC3D,CAKO,SAASgxB,GACd7gB,EACA8gB,EACwB,CACxB,MAAMnN,EAAOoN,GAAwB/gB,EAAM8gB,CAAU,EACrD,OAAOnN,IAAS,GAAKwM,GAA8BngB,EAAM2T,CAAI,EAAI,IACnE,CAKO,SAASoN,GACd/gB,EACA8gB,EACQ,CACR,QAASjpB,EAAI,EAAGA,EAAI3I,GAAkB2I,IAAK,CACzC,MAAM+oB,EAAOT,GAA8BngB,EAAMnI,CAAC,EAClD,GACE+oB,GACCA,EAAK,MAAQ3oB,GAAU,QACxB2oB,EAAK,OAASE,EAEd,OAAOjpB,CAEX,CACA,MAAO,EACT,CAMO,SAASmpB,GACdhhB,EACA0e,EAAoB,EACf,CACL,QAAS7mB,EAAI,EAAGA,EAAI3I,GAAkB2I,IAAK,CACzC,MAAM4F,EAASihB,EAAetvB,GAAsByI,EAAIhI,GAExD,GADiBmQ,EAAK,UAAUvC,EAAQ,EAAI,IAC3B,EACf,OAAO5F,CAEX,CACA,MAAO,EACT,CAKO,SAASopB,GACdjhB,EACmB,CACnB,MAAMpI,EAA4B,CAAA,EAClC,QAASC,EAAI,EAAGA,EAAI3I,GAAkB2I,IAAK,CACzC,MAAM+oB,EAAOT,GAA8BngB,EAAMnI,CAAC,EAC9C+oB,GAASA,EAAK,MAAQ3oB,GAAU,QAClCL,EAAO,KAAKgpB,CAAI,CAEpB,CACA,OAAOhpB,CACT,CASO,SAASspB,GACdlhB,EACA0G,EACwB,CACxB,MAAMjJ,EAASpO,GAAuBqX,EAAWlW,GAC3C2wB,EAAWnhB,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAEhD,GAAI0jB,IAAa,EAAG,OAAO,KAE3B,MAAMf,EAAWpgB,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAC1Cgb,EAAezY,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAC9C4iB,EAAergB,EAAK,SAASvC,EAAS,CAAC,EACvC+iB,EAAQxgB,EAAK,SAASvC,EAAS,CAAC,EAEhC2jB,EAA2B,CAAA,EAEjC,QAASvpB,EAAI,EAAGA,EAAI,EAAGA,IACrBupB,EAAe,KAAKphB,EAAK,UAAUvC,EAAS,GAAK5F,EAAI,EAAG,EAAI,CAAC,EAG/D,MAAMwpB,EAA2B,CAAA,EAEjC,QAASxpB,EAAI,EAAGA,EAAI,EAAGA,IACrBwpB,EAAe,KAAKrhB,EAAK,SAASvC,EAAS,GAAK5F,CAAC,CAAC,EAGpD,MAAM0oB,EAAOP,GAA0BhgB,EAAMvC,EAAS,GAAIxP,EAAe,EAEzE,MAAO,CACL,QAASkzB,EACT,QAASf,EACT,WAAY3H,EACZ,YAAa4H,EACb,MAAAG,EACA,cAAeY,EACf,cAAeC,EACf,KAAAd,CAAA,CAEJ,CAKO,SAASe,GACdthB,EACA0G,EACAka,EACM,CACN,MAAMnjB,EAASpO,GAAuBqX,EAAWlW,GAEjDwP,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,QAAS,EAAI,EAC7C5gB,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,QAAS,EAAI,EAC7C5gB,EAAK,UAAUvC,EAAS,EAAGmjB,EAAK,WAAY,EAAI,EAChD5gB,EAAK,SAASvC,EAAS,EAAGmjB,EAAK,WAAW,EAC1C5gB,EAAK,SAASvC,EAAS,EAAGmjB,EAAK,KAAK,EAEpC,QAAS/oB,EAAI,EAAGA,EAAI,EAAGA,IACrBmI,EAAK,UAAUvC,EAAS,GAAK5F,EAAI,EAAG+oB,EAAK,cAAc/oB,CAAC,GAAK,EAAG,EAAI,EAGtE,QAASA,EAAI,EAAGA,EAAI,EAAGA,IACrBmI,EAAK,SAASvC,EAAS,GAAK5F,EAAG+oB,EAAK,cAAc/oB,CAAC,GAAK,CAAC,EAG3DioB,GAA2B9f,EAAMvC,EAAS,GAAImjB,EAAK,KAAM3yB,EAAe,EAE1D,IAAI,WAAW+R,EAAK,OAAQA,EAAK,UAAU,EACnD,KAAK,EAAGvC,EAAS,GAAIA,EAASjN,EAAqB,CAC3D,CAEO,MAAMrB,GAAoB,EAK1B,SAASoyB,GACdvhB,EACA0e,EAAoB,EACf,CACL,QAAS7mB,EAAI,EAAGA,EAAI1I,GAAmB0I,IAAK,CAC1C,MAAM4F,EAASihB,EAAervB,GAAuBwI,EAAIrH,GAEzD,GADiBwP,EAAK,UAAUvC,EAAS,EAAG,EAAI,IAC/B,EAAG,OAAO5F,CAC7B,CACA,MAAO,EACT,CAKO,SAAS2pB,GACdxhB,EACAugB,EACmD,CACnD,MAAMpc,EAASoc,EAAK,YAAA,EACpB,QAAS1oB,EAAI,EAAGA,EAAI1I,GAAmB0I,IAAK,CAC1C,MAAM+oB,EAAOM,GAA8BlhB,EAAMnI,CAAC,EAClD,GAAI+oB,GAAQA,EAAK,KAAK,YAAA,IAAkBzc,EACtC,MAAO,CAAE,QAAStM,EAAG,KAAA+oB,CAAA,CAEzB,CACA,OAAO,IACT,CAKO,SAASa,GACdzhB,EACAogB,EACmB,CACnB,MAAMsB,EAA6B,CAAA,EACnC,QAAS7pB,EAAI,EAAGA,EAAI1I,GAAmB0I,IAAK,CAC1C,MAAM+oB,EAAOM,GAA8BlhB,EAAMnI,CAAC,EAC9C+oB,GAAQA,EAAK,UAAYR,GAC3BsB,EAAQ,KAAKd,CAAI,CAErB,CACA,OAAOc,CACT,CAKO,SAASC,GACd3hB,EACA0e,EACAhY,EACK,CAKL,GAJIA,IAAa,SACfA,EAAWgY,EACXA,EAAe,GAEbhY,GAAYvX,GAAmB,MAAO,GAC1C,MAAMsO,EAASihB,EAAervB,GAAuBqX,EAAWlW,GAChE,OAAA6O,GAAOW,EAAMvC,EAAQ,EAAGjN,EAAqB,EACtC,CACT,CAKO,SAASoxB,GACd5hB,EACA0e,EACAhY,EACK,CAKL,GAJIA,IAAa,SACfA,EAAWgY,EACXA,EAAe,GAEbhY,GAAYxX,GAAkB,MAAO,GACzC,MAAMuO,EAASihB,EAAetvB,GAAsBsX,EAAW7W,GAC/D,OAAAwP,GAAOW,EAAMvC,EAAQ,EAAG5N,EAAqB,EACtC,CACT,CAUO,SAASgyB,GACd7hB,EACAsF,EACA8a,EACA0B,EACAC,EAAgC,EAC1B,CACN1iB,GAAOW,EAAMsF,EAAa,EAAG,IAAS,EACtCtF,EAAK,SAASsF,EAAc,EAAG3O,EAAsB,EACrDqJ,EAAK,SAASsF,EAAc,EAAG,CAAC,EAChCtF,EAAK,UAAUsF,EAAc,EAAG,EAAG,EAAI,EACvCtF,EAAK,UAAUsF,EAAc,EAAG8a,EAAU,EAAI,EAC9CpgB,EAAK,UAAUsF,EAAc,EAAGwc,EAAiB,EAAI,EACrD9hB,EAAK,UAAUsF,EAAc,EAAGyc,EAA0B,EAAI,EAC9D/hB,EAAK,UAAUsF,EAAc,GAAI,EAAG,EAAI,CAC1C,CAKO,SAAS0c,GACdhiB,EACAsF,EACmB,CACnB,MAAO,CACL,SAAUtF,EAAK,SAASsF,EAAc,CAAC,EACvC,MAAOtF,EAAK,SAASsF,EAAc,CAAC,EACpC,eAAgBtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,EACpD,QAAStF,EAAK,UAAUsF,EAAc,EAAG,EAAI,EAC7C,cAAetF,EAAK,UAAUsF,EAAc,EAAG,EAAI,EACnD,qBAAsBtF,EAAK,UAAUsF,EAAc,EAAG,EAAI,EAC1D,aAActF,EAAK,UAAUsF,EAAc,GAAI,EAAI,CAAA,CAEvD,CAKO,SAAS2c,GACdjiB,EACAsF,EACA4c,EACA9B,EACA0B,EACAC,EACM,CACN/hB,EAAK,SAASsF,EAAc,EAAG3O,EAAsB,EACrDqJ,EAAK,SAASsF,EAAc,EAAG,CAAC,EAChCtF,EAAK,UAAUsF,EAAc,EAAG4c,EAAmB,EAAI,EACvDliB,EAAK,UAAUsF,EAAc,EAAG8a,EAAU,EAAI,EAC9CpgB,EAAK,UAAUsF,EAAc,EAAGwc,EAAiB,EAAI,EACrD9hB,EAAK,UAAUsF,EAAc,EAAGyc,EAA0B,EAAI,CAChE,CAKO,SAASI,GACdniB,EACAsF,EACA8c,EACAC,EACM,CACN,GAAID,EAAe,GAAKA,GAAgB1yB,GACtC,MAAM,IAAI,MAAM,gCAAgC0yB,CAAY,EAAE,EAGhE,MAAM3kB,EACJ6H,EAAcnU,GAA2BixB,EAAexwB,GAC1DoO,EAAK,SAASvC,EAAS,EAAG4kB,EAAK,IAAI,EACnCriB,EAAK,SAASvC,EAAS,EAAG4kB,EAAK,KAAK,EACpCriB,EAAK,UAAUvC,EAAS,EAAG4kB,EAAK,UAAW,EAAI,EAC/CvC,GAA2B9f,EAAMvC,EAAS,EAAG4kB,EAAK,KAAMp0B,EAAe,EAEvE+R,EAAK,UAAUvC,EAAS,GAAI,EAAG,EAAI,CACrC,CAKO,SAAS6kB,GACdtiB,EACAsF,EACA8c,EACY,CACZ,MAAM3kB,EACJ6H,EAAcnU,GAA2BixB,EAAexwB,GACpDiU,EAAO7F,EAAK,SAASvC,EAAS,CAAC,EAC/B+iB,EAAQxgB,EAAK,SAASvC,EAAS,CAAC,EAChCua,EAAahY,EAAK,UAAUvC,EAAS,EAAG,EAAI,EAC5C8iB,EAAOP,GAA0BhgB,EAAMvC,EAAS,EAAGxP,EAAe,EAExE,MAAO,CAAE,KAAA4X,EAAM,MAAA2a,EAAO,UAAWxI,EAAY,KAAAuI,CAAA,CAC/C,CAOO,SAASgC,GAA4B1K,EAG1C,CACA,MAAO,CACL,aAAc,KAAK,MAAMA,EAAUnoB,EAA4B,EAC/D,aAAcmoB,EAAUnoB,EAAA,CAE5B,CASO,SAAS8yB,GACdC,EACAC,EACAnC,EACAoC,EACW,eACX,GAAIA,EAAW,SAAW,EACxB,MAAM,IAAI,MAAM,qCAAqC,EAGvD,GAAIA,EAAW,OAAShzB,GACtB,MAAM,IAAI+J,GAAoBipB,EAAW,OAAQhzB,EAAqB,EAIxE,GAAIoxB,GAAwB0B,EAAYlC,CAAI,IAAM,GAChD,MAAM,IAAItnB,GAAwBsnB,CAAI,EAIxC,MAAM7Z,EAAWsa,GAA6ByB,CAAU,EAExD,GAAI/b,IAAa,GACf,MAAM,IAAI9M,GAAmB1K,GAAkBA,EAAgB,EAGjE,MAAMkxB,EAAW1Z,EAAW,EACtB+R,EAAeiK,EAAM,gBAAA,EAGrBE,EAAaF,EAAM,aAAajK,CAAY,EAC5CoK,EAAY,IAAI,SAASD,EAAW,OAAQA,EAAW,UAAU,EACvEC,EAAU,SAAS,EAAG,EAAI,EAC1BA,EAAU,SAAS,EAAG,CAAC,EACvBA,EAAU,UAAU,EAAG,EAAG,EAAI,EAC9BA,EAAU,UAAU,EAAG,KAAW,EAAI,EACtCA,EAAU,UAAU,EAAG,EAAG,EAAI,EAC9BA,EAAU,UAAU,GAAI,EAAG,EAAI,EAC/BA,EAAU,UAAU,GAAI,EAAG,EAAI,EAC/BH,EAAM,cAAcjK,CAAY,EAGhC,MAAMlP,EAAwB,CAAA,EAC9B,IAAImB,EAAuB,EAE3B,QAAS7S,EAAI,EAAGA,EAAI8qB,EAAW,OAAQ9qB,IAAK,CAC1C,MAAMirB,EAAMH,EAAW9qB,CAAC,EAClBgO,EACJ,OAAOid,EAAI,MAAS,SAChB7C,GAAwB6C,EAAI,IAAI,EAC/BA,EAAI,KAEX,IAAItC,EAAQ,EACR,OAAQsC,EAAY,OAAU,SAChCtC,EAASsC,EAAY,QAEjBA,EAAI,aAActlB,EAAAslB,EAAI,QAAJ,MAAAtlB,EAAW,cAC/BgjB,GAASxoB,EAAW,cAClB8qB,EAAI,UAAWzL,EAAAyL,EAAI,QAAJ,MAAAzL,EAAW,cAAkBrf,EAAW,WACvD8qB,EAAI,UAAWC,EAAAD,EAAI,QAAJ,MAAAC,EAAW,cAAkB/qB,EAAW,UAEzD8qB,EAAI,SACJA,EAAI,gBACJE,EAAAF,EAAI,QAAJ,MAAAE,EAAW,UACXC,EAAAH,EAAI,QAAJ,MAAAG,EAAW,iBAEXzC,GAASxoB,EAAW,WAGxB,MAAMggB,EAAatN,EAEnB,OAAQ7E,EAAA,CACN,KAAK9N,EAAS,MACZ2S,GAAwB,EACxB,MACF,KAAK3S,EAAS,MACd,KAAKA,EAAS,QACZ2S,GAAwB,EACxB,MACF,KAAK3S,EAAS,KACd,KAAKA,EAAS,KACZ2S,GAAwB,GACxB,KAAA,CAGJnB,EAAQ,KAAK,CACX,KAAA1D,EACA,MAAA2a,EACA,UAAWxI,EACX,KAAM8K,EAAI,IAAA,CACX,CACH,CAGA,MAAMI,EAAa3Z,EAAQ,OACrB4Z,EAAoB,KAAK,KAC7BD,EAAaxzB,EAAA,EAET0zB,EAA6B,CAAA,EAEnC,QAASvrB,EAAI,EAAGA,EAAIsrB,EAAmBtrB,IACrCurB,EAAiB,KAAKV,EAAM,iBAAiB,EAG/C,QAASvS,EAAI,EAAGA,EAAIgT,EAAmBhT,IAAK,CAC1C,MAAMG,EAAU8S,EAAiBjT,CAAC,EAC5B3K,EACJ2K,EAAIgT,EAAoB,EAAIC,EAAiBjT,EAAI,CAAC,EAAI,EAClD2R,EAAkB3R,EAAIzgB,GACtB2zB,EAAyB,KAAK,IAClCH,EAAapB,EACbpyB,EAAA,EAGIkS,EAAa8gB,EAAM,aAAapS,CAAO,EACvCtQ,EAAO,IAAI,SAAS4B,EAAW,OAAQA,EAAW,UAAU,EAElEigB,GAAkB7hB,EAAM,EAAGogB,EAAU0B,EAAiBtc,CAAY,EAClExF,EAAK,UAAU,EAAGqjB,EAAwB,EAAI,EAE9C,QAASvrB,EAAI,EAAGA,EAAIurB,EAAwBvrB,IAAK,CAC/C,MAAMiS,EAAMR,EAAQuY,EAAkBhqB,CAAC,EACvCqqB,GAA0BniB,EAAM,EAAGlI,EAAGiS,CAAG,CAC3C,CAGA,MAAMlI,EAAMtD,GAAoBqD,CAAU,EAC1C5B,EAAK,UAAU,GAAI6B,EAAK,EAAI,EAC5B6gB,EAAM,cAAcpS,CAAO,CAC7B,CAEA,MAAMgT,EAAwBF,EAAiB,CAAC,EAG1CxC,EAAwB,CAC5B,QAASR,EACT,YAAa8C,EACb,WAAYzK,EACZ,iBAAkB6K,EAClB,KAAA/C,EACA,MAAOtoB,GAAU,OACjB,iBAAkB,EAClB,YAAa,EAAA,EAGf0oB,GAA+B8B,EAAY/b,EAAUka,CAAI,EAGzD,MAAM2C,EAAwB,CAAA,EAC9B,QAAS1rB,EAAI,EAAGA,EAAI0R,EAAQ,OAAQ1R,IAC7B0R,EAAQ1R,CAAC,EAAE,MAAQG,EAAW,aACjCurB,EAAQ,KAAKha,EAAQ1R,CAAC,CAAC,EAI3B,GAAI0rB,EAAQ,OAAS,EAAG,CACtB,MAAMC,EAAajC,GAA6BkB,CAAU,EAC1D,GAAIe,IAAe,GAAI,CACrB,MAAMC,EAAqBf,EAAM,gBAAA,EAC3BgB,EAAmBhB,EAAM,aAAae,CAAkB,EACxDE,EAAkB,IAAI,SAC1BD,EAAiB,OACjBA,EAAiB,UAAA,EAEnBvW,GAAqBwW,EAAiB,EAAG,CAAC,EAC1CjB,EAAM,cAAce,CAAkB,EAEtC,MAAM3T,EAAc,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EACrCuR,EAAiB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EAC9C,QAASzlB,EAAI,EAAGA,EAAI2nB,EAAQ,QAAU3nB,EAAI,EAAGA,IAAK,CAChD,MAAMgoB,EAAcL,EAAQ3nB,CAAC,EAAE,KAC/B,IAAIioB,EAAc,GAClB,QAAS/rB,EAAI,EAAGA,EAAIyR,EAAQ,OAAQzR,IAClC,GAAIyR,EAAQzR,CAAC,EAAE,OAAS8rB,EAAa,CACnCC,EAAc/rB,EACd,KACF,CAEFgY,EAAYlU,CAAC,EAAIioB,CACnB,CAEA,MAAMC,EAA2B,CAC/B,QAASN,EAAa,EACtB,QAASpD,EACT,WAAYqD,EACZ,YAAaF,EAAQ,OACrB,MAAOrrB,GAAU,QAAUA,GAAU,OACrC,cAAe4X,EACf,cAAeuR,EACf,KAAM,MAAMd,CAAI,EAAA,EAElBe,GAA+BmB,EAAYe,EAAYM,CAAO,CAChE,CACF,CAEApE,GAAiC+C,CAAU,EAC3C7C,GAAiC6C,CAAU,EAC3C5C,GAA8B4C,CAAU,EAExC,MAAMf,EAAUD,GAA2BgB,EAAYrC,CAAQ,EACzD2D,EAAwB,CAAA,EAC9B,QAASlsB,EAAI,EAAGA,EAAI0rB,EAAQ,OAAQ1rB,IAClCksB,EAAY,KAAKR,EAAQ1rB,CAAC,EAAE,IAAI,EAGlC,MAAO,CACL,GAAG+oB,EACH,QAAArX,EACA,WAAYwa,EAAY,OAAS,EAAIA,EAAc,OACnD,QAASrC,EAAQ,OAAS,EAAIA,EAAU,MAAA,CAE5C,CAKO,SAASsC,GACdvB,EAEAC,EACA5B,EACW,CACX,MAAMpa,EAAWqa,GAAwB0B,EAAY3B,CAAU,EAE/D,GAAIpa,IAAa,GACf,MAAM,IAAI1N,GAAmB8nB,CAAU,EAGzC,MAAMF,EAAOT,GAA8BsC,EAAY/b,CAAQ,EACzD6C,EAAwB,CAAA,EAE9B,IAAI0a,EAAsBrD,EAAK,iBAC3BsD,EAAe,EAEnB,KAAOD,IAAwB,GAAKC,EAAetD,EAAK,aAAa,CACnE,MAAMhf,EAAa8gB,EAAM,aAAauB,CAAmB,EACnDjkB,EAAO,IAAI,SAAS4B,EAAW,OAAQA,EAAW,UAAU,EAC5D9F,EAASkmB,GAAyBhiB,EAAM,CAAC,EAE/C,QAASnI,EAAI,EAAGA,EAAIiE,EAAO,eAAgBjE,IAAK,CAC9C,MAAMkS,EAAMuY,GAAyBtiB,EAAM,EAAGnI,CAAC,EAC/C0R,EAAQ,KAAKQ,CAAG,EAChBma,GACF,CAEAD,EAAsBnoB,EAAO,oBAC/B,CAEA,MAAM4lB,EAAUD,GAA2BgB,EAAY7B,EAAK,OAAO,EAC7DmD,EAAwB,CAAA,EAC9B,QAASlsB,EAAI,EAAGA,EAAI0R,EAAQ,OAAQ1R,IAC7B0R,EAAQ1R,CAAC,EAAE,MAAQG,EAAW,aACjC+rB,EAAY,KAAKxa,EAAQ1R,CAAC,EAAE,IAAI,EAIpC,MAAO,CACL,GAAG+oB,EACH,QAAArX,EACA,WAAYwa,EAAY,OAAS,EAAIA,EAAc,OACnD,QAASrC,EAAQ,OAAS,EAAIA,EAAU,MAAA,CAE5C,CAKO,SAASyC,GACd1B,EAEAC,EACa,CACb,MAAM0B,EAAcnD,GAA+BwB,CAAU,EACvD7qB,EAAsB,CAAA,EAC5B,QAAS,EAAI,EAAG,EAAIwsB,EAAY,OAAQ,IACtCxsB,EAAO,KACLosB,GAAwBvB,EAAYC,EAAO0B,EAAY,CAAC,EAAE,IAAI,CAAA,EAGlE,OAAOxsB,CACT,CC3kCO,MAAMysB,GAAyB,mhjBAEtC,IAAIC,GAAiC,KAE9B,SAASC,IAAoC,CAClD,GAAI,CAACD,GAAa,CAChB,MAAME,EAAe,WAA0F,OAC/G,GAAI,OAAOA,EAAgB,KAAe,OAAOA,EAAY,MAAS,WACpEF,GAAc,IAAI,WAAWE,EAAY,KAAKH,GAAwB,QAAQ,CAAC,MAC1E,CACL,MAAMI,EAAe,KAAKJ,EAAsB,EAC1C3c,EAAM+c,EAAa,OACzBH,GAAc,IAAI,WAAW5c,CAAG,EAChC,QAAS7P,EAAI,EAAGA,EAAI6P,EAAK7P,IACvBysB,GAAYzsB,CAAC,EAAI4sB,EAAa,WAAW5sB,CAAC,CAE9C,CACF,CACA,OAAOysB,EACT,CC4DO,SAASI,GACdC,EACAC,EACiB,CACjB,MAAM9hB,EAAQ8hB,GAAeL,GAAA,EACvBM,EAAa,IAAI,YAAY,OAAO/hB,CAAgC,EACpEgiB,EAAW,IAAI,YAAY,SAASD,EAAY,CACpD,IAAK,CAAE,OAAAF,CAAA,CAAO,CACf,EAEKI,EAAMD,EAAS,QAEfE,EAAe,CAAChlB,EAA6BvC,EAAiB,IAC3DuC,EAAK,WAAavC,EA6P3B,MA1PqC,CACnC,SAAAqnB,EACA,QAASC,EACT,OAAAJ,EAGA,UAAW,CAAC3kB,EAAMsF,EAAaC,EAAY3O,GAAqB4O,EAAe,IAAM,CACnFuf,EAAI,UAAUC,EAAahlB,EAAMsF,CAAW,EAAGC,EAAWC,CAAY,CACxE,EAEA,eAAgB,CAACxF,EAAMsF,EAAaI,EAAoB,IAAM,CAC5Dqf,EAAI,eAAeC,EAAahlB,EAAMsF,CAAW,EAAGI,CAAiB,CACvE,EAEA,cAAe,CAAC1F,EAAMsF,IACbyf,EAAI,cAAcC,EAAahlB,EAAMsF,CAAW,CAAC,EAG1D,cAAe,CAACtF,EAAMsF,EAAaO,IAAS,CAC1Ckf,EAAI,cAAcC,EAAahlB,EAAMsF,CAAW,EAAGO,CAAI,CACzD,EAEA,oBAAqB,CAAC7F,EAAMsF,IACnByf,EAAI,oBAAoBC,EAAahlB,EAAMsF,CAAW,CAAC,EAGhE,oBAAqB,CAACtF,EAAMsF,EAAa1K,IAAU,CACjDmqB,EAAI,oBAAoBC,EAAahlB,EAAMsF,CAAW,EAAG1K,CAAK,CAChE,EAEA,6BAA8B,CAACoF,EAAMsF,IAC5Byf,EAAI,6BAA6BC,EAAahlB,EAAMsF,CAAW,CAAC,EAGzE,6BAA8B,CAACtF,EAAMsF,EAAa7H,IAAW,CAC3DsnB,EAAI,6BAA6BC,EAAahlB,EAAMsF,CAAW,EAAG7H,CAAM,CAC1E,EAEA,sBAAuB,CAACuC,EAAMsF,IACrByf,EAAI,sBAAsBC,EAAahlB,EAAMsF,CAAW,CAAC,EAGlE,sBAAuB,CAACtF,EAAMsF,EAAaE,IAAiB,CAC1Duf,EAAI,sBAAsBC,EAAahlB,EAAMsF,CAAW,EAAGE,CAAY,CACzE,EAEA,oBAAqB,CAACxF,EAAMsF,IACnByf,EAAI,oBAAoBC,EAAahlB,EAAMsF,CAAW,CAAC,EAGhE,oBAAqB,CAACtF,EAAMsF,EAAagB,IAAe,CACtDye,EAAI,oBAAoBC,EAAahlB,EAAMsF,CAAW,EAAGgB,CAAU,CACrE,EAEA,kBAAmB,CAACtG,EAAMsF,IACjByf,EAAI,kBAAkBC,EAAahlB,EAAMsF,CAAW,CAAC,EAG9D,kBAAmB,CAACtF,EAAMsF,EAAarC,IAAa,CAClD8hB,EAAI,kBAAkBC,EAAahlB,EAAMsF,CAAW,EAAGrC,CAAQ,CACjE,EAEA,qBAAsB,CAACjD,EAAMsF,EAAaoB,IACjCqe,EAAI,qBAAqBC,EAAahlB,EAAMsF,CAAW,EAAGoB,CAAQ,EAG3E,qBAAsB,CAAC1G,EAAMsF,EAAaoB,EAAUG,IAAgB,CAClEke,EAAI,qBAAqBC,EAAahlB,EAAMsF,CAAW,EAAGoB,EAAUG,CAAW,CACjF,EAEA,+BAAgC,CAAC7G,EAAMsF,IAC9Byf,EAAI,+BAA+BC,EAAahlB,EAAMsF,CAAW,CAAC,EAG3E,0BAA2B,CAACtF,EAAMsF,IACzByf,EAAI,0BAA0BC,EAAahlB,EAAMsF,CAAW,CAAC,EAGtE,aAAc,CAACtF,EAAMsF,EAAa8B,EAAoB,EAAGC,IAAgB,CACnEA,EAEF4d,GAAoBjlB,EAAMsF,EAAa8B,EAAmBC,CAAW,EAErE0d,EAAI,aAAaC,EAAahlB,EAAMsF,CAAW,EAAG8B,EAAmB,GAAI,EAAG,CAAC,CAEjF,EAEA,oBAAqB,CAACpH,EAAMklB,IACnBH,EAAI,oBAAoBC,EAAahlB,EAAMklB,CAAU,CAAC,EAG/D,gBAAiB,CAACllB,EAAMsF,EAAa2C,EAAWb,EAAoB,IAE3D+d,GAAuBnlB,EAAMsF,EAAa2C,EAAWb,CAAiB,EAG/E,gBAAiB,CAACpH,EAAMsF,EAAaoD,IAAa,CAChDqc,EAAI,gBAAgBC,EAAahlB,EAAMsF,CAAW,EAAGoD,CAAQ,CAC/D,EAEA,gBAAiB,CAAC1I,EAAMsF,EAAaoD,EAAUM,EAAe5B,EAAoB,IACzEge,GAAuBplB,EAAMsF,EAAaoD,EAAUM,EAAe5B,CAAiB,EAI7F,gBAAiB,CAACkJ,EAASvP,IAClBgkB,EAAI,gBAAgBzU,EAASvP,CAAI,EAG1C,eAAgB,CAACf,EAAMyQ,EAAaC,EAAcJ,IACzCyU,EAAI,eAAeC,EAAahlB,EAAMyQ,CAAW,EAAGC,EAAcJ,CAAO,EAGlF,eAAgB,CAACtQ,EAAMyQ,EAAaC,EAAcJ,EAAS5J,IAAa,CAEtE,GADYqe,EAAI,eAAeC,EAAahlB,EAAMyQ,CAAW,EAAGC,EAAcJ,EAAS5J,CAAQ,EACrF,EACR,MAAM,IAAI,MAAM,kDAAkD4J,CAAO,EAAE,CAE/E,EAEA,kBAAmB,CAACtQ,EAAMyQ,EAAaC,EAAcJ,IAC5CyU,EAAI,kBAAkBC,EAAahlB,EAAMyQ,CAAW,EAAGC,EAAcJ,CAAO,IAAM,EAI3F,yBAA2B5J,GAClBqe,EAAI,yBAAyBre,CAAQ,EAG9C,2BAA4B,CAAC1G,EAAMwR,EAAqB9K,IAC/Cqe,EAAI,2BAA2BC,EAAahlB,EAAMwR,CAAmB,EAAG9K,CAAQ,EAGzF,4BAA6B,CAAC1G,EAAMwR,EAAqB9K,EAAU4J,IAAY,CAC7EyU,EAAI,4BAA4BC,EAAahlB,EAAMwR,CAAmB,EAAG9K,EAAU4J,CAAO,CAC5F,EAEA,2BAA4B,CAACtQ,EAAM2R,EAAqBC,EAAsBtB,IACrEyU,EAAI,2BAA2BC,EAAahlB,EAAM2R,CAAmB,EAAGC,EAAsBtB,CAAO,EAG9G,qBAAsB,CAACtQ,EAAMwR,EAAqBG,EAAqBC,EAAsBlL,EAAU4J,IAAY,CACjHyU,EAAI,qBACFC,EAAahlB,EAAMwR,CAAmB,EACtCwT,EAAahlB,EAAM2R,CAAmB,EACtCC,EACAlL,EACA4J,CAAA,CAEJ,EAEA,uBAAwB,CAACtQ,EAAMwR,EAAqBG,EAAqBC,EAAsBlL,IAAa,CAC1Gqe,EAAI,uBACFC,EAAahlB,EAAMwR,CAAmB,EACtCwT,EAAahlB,EAAM2R,CAAmB,EACtCC,EACAlL,CAAA,CAEJ,EAEA,oBAAqB,CAAC1G,EAAMkS,EAAmBxL,IAAa,CAC1Dqe,EAAI,oBAAoBC,EAAahlB,EAAakS,CAAiB,EAAGxL,CAAQ,CAChF,EAEA,qBAAsB,CAAC1G,EAAMkS,EAAmBxL,IAAa,CAC3Dqe,EAAI,qBAAqBC,EAAahlB,EAAakS,CAAiB,EAAGxL,CAAQ,CACjF,EAEA,kBAAmB,CAAC1G,EAAMkS,EAAmBxL,IACpCqe,EAAI,kBAAkBC,EAAahlB,EAAakS,CAAiB,EAAGxL,CAAQ,IAAM,EAG3F,kBAAmB,CAAC4L,EAAY5L,IAAa,CAC3C2e,GAAyB/S,EAAY5L,CAAQ,CAC/C,EAEA,oBAAqB,CAAC4L,EAAY5L,IAAa,CAC7C4e,GAA2BhT,EAAY5L,CAAQ,CACjD,EAEA,mBAAoB,CAAC4L,EAAY5L,IACxB6e,GAA0BjT,EAAY5L,CAAQ,EAGvD,qBAAsB,CAAChJ,EAAQgV,EAAUJ,EAAYd,EAAqBmB,EAAYC,IAC7E4S,GAA4B9nB,EAAQgV,EAAUJ,EAAYd,EAAqBmB,EAAYC,CAAkB,EAGtH,gCAAiC,CAAClV,EAAQgV,EAAUJ,EAAYd,EAAqBU,EAAmBS,EAAYC,EAAoBtC,IAC/HmV,GAAuC/nB,EAAQgV,EAAUJ,EAAYd,EAAqBU,EAAmBS,EAAYC,EAAoBtC,CAAO,EAI7J,mBAAqBtQ,GAAS,CAC5B+kB,EAAI,mBAAmBC,EAAahlB,CAAI,CAAC,CAC3C,EAEA,0BAA2B,CAACA,EAAM6e,IACzB6G,GAAiC1lB,EAAM6e,CAAe,EAG/D,wBAA0B7e,GACjB+kB,EAAI,wBAAwBC,EAAahlB,CAAI,CAAC,EAGvD,wBAAyB,CAACA,EAAMpF,IAAU,CACxCmqB,EAAI,wBAAwBC,EAAahlB,CAAI,EAAGpF,CAAK,CACvD,EAEA,2BAA6BoF,GACpB+kB,EAAI,2BAA2BC,EAAahlB,CAAI,CAAC,EAG1D,2BAA4B,CAACA,EAAMsQ,IAAY,CAC7CyU,EAAI,2BAA2BC,EAAahlB,CAAI,EAAGsQ,CAAO,CAC5D,EAEA,2BAA6BtQ,GACpB+kB,EAAI,2BAA2BC,EAAahlB,CAAI,CAAC,EAG1D,iCAAmCA,GAC1B+kB,EAAI,iCAAiCC,EAAahlB,CAAI,CAAC,EAGhE,2BAA6BA,GACpB+kB,EAAI,2BAA2BC,EAAahlB,CAAI,CAAC,EAG1D,iCAAmCA,GAC1B+kB,EAAI,iCAAiCC,EAAahlB,CAAI,CAAC,EAGhE,8BAAgCA,GACvB+kB,EAAI,8BAA8BC,EAAahlB,CAAI,CAAC,EAI7D,eAAgB,CAACgU,EAAKE,IACbyR,GAAsB3R,EAAKE,CAAO,EAG3C,SAAWtK,GACFgc,GAAgBhc,CAAM,EAG/B,oBAAqBic,GACrB,QAASC,EAAO,CAIpB,CC9SO,SAASC,GACdryB,EAAoBvB,GACpB6zB,EAAyBnzB,GACL,CACpB,MAAMozB,EAAUxyB,GAAyBC,EAAWsyB,CAAc,EAC5DE,EAAgBD,EAAQ,qBAAuB,IAAM,KACrDE,EAAqB,KAAK,KAAKD,EAAgB,KAAK,EACpDE,EAAiB,KAAK,MACzBH,EAAQ,qBAAuBD,GAAkB,KAAA,EAEpD,OAAO,IAAI,YAAY,OAAO,CAC5B,QAASG,EACT,QAAS,KAAK,IAAIA,EAAoBC,CAAc,CAAA,CACrD,CACH,CA2BO,MAAMC,EAAiB,CA+B5B,YAAY7kB,EAAkC,CA9BrCpG,EAAA,WACAA,EAAA,mBACAA,EAAA,eACAA,EAAA,aACAA,EAAA,cACAA,EAAA,kBACAA,EAAA,uBACAA,EAAA,gBAGAA,EAAA,uBACAA,EAAA,yBACAA,EAAA,yBACAA,EAAA,0BACAA,EAAA,wBACAA,EAAA,wBACAA,EAAA,2BACAA,EAAA,uBACAA,EAAA,6BACAA,EAAA,6BAEAA,EAAA,mBACAA,EAAA,+BACAA,EAAA,iBACDA,EAAA,kBAAqB,GACrBA,EAAA,oBAAuB,GAEvBA,EAAA,8BAAyB,KACzBA,EAAA,uBAAiC,QAAQ,QAAA,aAG/C,KAAK,UACHoG,EAAQ,aAAahE,EAAAgE,EAAQ,OAAR,YAAAhE,EAAc,YAAarL,GAElD,KAAK,eACHqP,EAAQ,kBACR6V,EAAA7V,EAAQ,OAAR,YAAA6V,EAAc,iBACdxkB,GAEF,MAAM8xB,EAASnjB,EAAQ,UAAUuhB,EAAAvhB,EAAQ,OAAR,YAAAuhB,EAAc,YAE/C,GAAI,CAAC4B,EACH,MAAM,IAAI,MACR,gFAAA,EA6BJ,GAzBA,KAAK,WAAaA,EAClB,KAAK,OAAS,KAAK,WAAW,OAC9B,KAAK,KAAO,IAAI,SAAS,KAAK,MAAM,EACpC,KAAK,MAAQ,IAAI,WAAW,KAAK,MAAM,EAEvC,KAAK,QAAUlxB,GACb+N,EAAQ,wBAA0BrP,GAAqB,KAAK,UAC5D,KAAK,cAAA,EAGP,KAAK,eAAiB,KAAK,QAAQ,eACnC,KAAK,iBAAmB,KAAK,QAAQ,iBACrC,KAAK,iBAAmB,KAAK,QAAQ,iBACrC,KAAK,kBAAoB,KAAK,QAAQ,kBACtC,KAAK,gBAAkB,KAAK,QAAQ,gBACpC,KAAK,gBAAkB,KAAK,QAAQ,gBACpC,KAAK,mBAAqB,KAAK,QAAQ,mBACvC,KAAK,eAAiB,KAAK,QAAQ,eACnC,KAAK,qBAAuB,KAAK,QAAQ,qBACzC,KAAK,qBAAuB,KAAK,QAAQ,qBAEzC,KAAK,SAAW,IAAI,WAAW,KAAK,SAAS,EAC7C,KAAK,WAAa,IAAI,YAAY,KAAK,SAAS,EAChD,KAAK,uBAAyB,IAAI,YAAY,KAAK,SAAS,EAExDqP,EAAQ,GACV,KAAK,GAAKA,EAAQ,WACTA,EAAQ,IACjB,KAAK,GAAK,IAAID,GAAG,CAAE,IAAKC,EAAQ,IAAK,OAAQ,KAAK,WAAY,MAE9D,OAAM,IAAI,MACR,gEAAA,EAKJnC,GAAO,KAAK,MAAO,KAAK,iBAAkB,EAAG,KAAK,UAAY,CAAC,EAC/DA,GACE,KAAK,MACL,KAAK,iBACL,EACA,KAAK,kBAAoB/M,EAAA,EAE3B+M,GAAO,KAAK,MAAO,KAAK,gBAAiB,EAAG,KAAK,KAAK,KAAK,UAAY,CAAC,CAAC,EAGzE,KAAK,WAAW,EAAG,CAAC,EACpB,KAAK,WAAW,CAAC,EAAI,CACvB,CAEQ,kBAAkBqH,EAAwB,CAChD,GACE,CAAC,OAAO,UAAUA,CAAQ,GAC1BA,EAAW,GACXA,GAAY,KAAK,UAEjB,MAAM,IAAI,MACR,uBAAuBA,CAAQ,sCAAsC,KAAK,UAAY,CAAC,EAAA,CAG7F,CAEQ,iBAAiB4J,EAAuB,CAC9C,GAAI,CAAC,OAAO,UAAUA,CAAO,GAAKA,GAAW,EAC3C,MAAM,IAAI,MACR,oBAAoBA,CAAO,uCAAA,CAGjC,CAEA,MAAc,qBAAwBoL,EAAkC,CACtE,MAAM4K,EAAY,KAAK,gBACvB,IAAIC,EACJ,KAAK,gBAAkB,IAAI,QAAe/pB,GAAY,CACpD+pB,EAAU/pB,CACZ,CAAC,EACD,MAAM8pB,EACN,GAAI,CACF,OAAO,MAAM5K,EAAA,CACf,QAAA,CACE6K,EAAA,CACF,CACF,CAEA,0BAA0B9kB,EAAwB,CAChD,KAAK,GAAG,0BAA0BA,CAAW,CAC/C,CAMA,cAAcC,EAAyB,CACrC,YAAK,kBAAkBA,CAAO,EACvBA,EAAU,IACnB,CAEA,mBAAmBA,EAA6B,CAC9C,YAAK,kBAAkBA,CAAO,EACvB,KAAK,MAAM,SAASA,EAAU,MAAYA,EAAU,GAAK,IAAS,CAC3E,CAEA,gBAAgBA,EAA2B,CACzC,YAAK,kBAAkBA,CAAO,EACvB,IAAI,SAAS,KAAK,OAAQA,EAAU,KAAW,IAAS,CACjE,CAEA,gBAAgBnI,EAAwB,CACtC,YAAK,iBAAiBA,CAAM,EACrBmY,GACL,KAAK,KACL,KAAK,iBACL,KAAK,kBACLnY,CAAA,CAEJ,CAEA,gBAAgBmI,EAAyB,CACvC,YAAK,kBAAkBA,CAAO,EACvB6P,GACL,KAAK,KACL,KAAK,iBACL7P,CAAA,CAEJ,CAEA,WAAWA,EAAiBnI,EAAsB,CAEhD,GADA,KAAK,kBAAkBmI,CAAO,EAC1B,CAAC,OAAO,UAAUnI,CAAM,GAAKA,GAAU,EACzC,MAAM,IAAI,MACR,oBAAoBA,CAAM,mCAAA,EAG9B,GAAImI,IAAY,GAAKnI,IAAW,EAC9B,MAAM,IAAI,MACR,qEAAqEA,CAAM,GAAA,EAI/E,MAAMitB,EAAgB,KAAK,gBAAgBjtB,CAAM,EACjD,GAAIitB,IAAkB,IAAMA,IAAkB9kB,EAC5C,MAAM,IAAI,MACR,mBAAmBnI,CAAM,YAAYmI,CAAO,8BAA8B8kB,CAAa,EAAA,EAI3F3U,GACE,KAAK,KACL,KAAK,iBACL,KAAK,iBACL,KAAK,kBACLnQ,EACAnI,CAAA,EAEF,KAAK,SAASmI,CAAO,EAAI,CAC3B,CAEA,aAAaA,EAAuB,CAElC,GADA,KAAK,kBAAkBA,CAAO,EAC1BA,IAAY,EACd,MAAM,IAAI,MACR,yDAAA,EAIJqQ,GACE,KAAK,KACL,KAAK,iBACL,KAAK,iBACL,KAAK,kBACLrQ,CAAA,EAEF,KAAK,SAASA,CAAO,EAAI,CAC3B,CAEA,UAAUA,EAAuB,CAC/B,KAAK,kBAAkBA,CAAO,EAC9BsQ,GAAoB,KAAK,MAAO,KAAK,gBAAiBtQ,CAAO,EAC7D,KAAK,uBAAuBA,CAAO,GACrC,CAEA,WAAWA,EAAuB,CAChC,KAAK,kBAAkBA,CAAO,EAC9ByQ,GAAqB,KAAK,MAAO,KAAK,gBAAiBzQ,CAAO,CAChE,CAEA,QAAQA,EAA0B,CAChC,YAAK,kBAAkBA,CAAO,EACvB0Q,GAAkB,KAAK,MAAO,KAAK,gBAAiB1Q,CAAO,CACpE,CAEA,QAAQA,EAAuB,CAC7B,KAAK,kBAAkBA,CAAO,EAC9B2Q,GAAkB,KAAK,WAAY3Q,CAAO,CAC5C,CAEA,UAAUA,EAAuB,CAC/B,KAAK,kBAAkBA,CAAO,EAC9B6Q,GAAoB,KAAK,WAAY7Q,CAAO,CAC9C,CAEA,QAAQnI,EAAsB,CAC5B,KAAK,iBAAiBA,CAAM,EAC5B,MAAMoa,EAAO,KAAK,gBAAgBpa,CAAM,EACxC,GAAIoa,IAAS,GACX,MAAM,IAAI,MACR,mBAAmBpa,CAAM,uCAAA,EAG7B,KAAK,QAAQoa,CAAI,CACnB,CAEA,UAAUpa,EAAsB,CAE9B,GADA,KAAK,iBAAiBA,CAAM,EACxBA,IAAW,EAAG,OAClB,MAAMoa,EAAO,KAAK,gBAAgBpa,CAAM,EACpCoa,IAAS,IACX,KAAK,UAAUA,CAAI,CAEvB,CAEA,eAAejS,EAAuB,CACpC,KAAK,kBAAkBA,CAAO,EAC1BA,IAAY,IAChB,KAAK,WAAWA,CAAO,EAAI,EAC7B,CAEA,eAAenI,EAAsB,CAEnC,GADA,KAAK,iBAAiBA,CAAM,EACxBA,GAAU,EAAG,OACjB,MAAMoa,EAAO,KAAK,gBAAgBpa,CAAM,EACpCoa,IAAS,IACX,KAAK,eAAeA,CAAI,CAE5B,CAEA,aAAajS,EAA0B,CACrC,YAAK,kBAAkBA,CAAO,EACvB8Q,GAAmB,KAAK,WAAY9Q,CAAO,CACpD,CAEA,YAAYA,EAAyB,CACnC,YAAK,kBAAkBA,CAAO,EACvB,KAAK,WAAWA,CAAO,CAChC,CAEA,UAAUA,EAAyB,CACjC,YAAK,kBAAkBA,CAAO,EACvB,KAAK,SAASA,CAAO,CAC9B,CAEA,UAAUA,EAAiBxE,EAAmB,CAC5C,KAAK,kBAAkBwE,CAAO,EAC9B,KAAK,SAASA,CAAO,EAAIxE,EAAM,EAAI,CACrC,CAEA,WAAW7E,EAAsB,CAC/B,MAAMouB,EAAWpuB,EAAO,EAAK,GAC7B,GAAI,KAAK,aAAeouB,EAAU,KAAK,eACrC,MAAM,IAAIvsB,GAEZ,MAAMwsB,EAAU,KAAK,qBAAuB,KAAK,aACjD,YAAK,cAAgBD,EACdC,CACT,CACA,YAAmB,CACb,KAAK,aAAe,IACtBrnB,GAAO,KAAK,MAAO,KAAK,qBAAsB,EAAG,KAAK,YAAY,EAClE,KAAK,aAAe,EAExB,CACA,gBAAyB,CACvB,OAAO,KAAK,YACd,CAMA,MAAM,YAAYiR,EAAiBqW,EAAe,GAAwB,CACxE,KAAK,iBAAiBrW,CAAO,EAG7B,MAAMkW,EAAgB,KAAK,gBAAgBlW,CAAO,EAClD,GAAIkW,IAAkB,GACpB,YAAK,UAAUA,EAAe,CAAC,EAC3BG,GACF,KAAK,QAAQH,CAAa,EAErBA,EAIT,MAAMI,EAAmB,KAAK,mBAAmB,IAAItW,CAAO,EAC5D,GAAIsW,EAAkB,CACpB,MAAMjT,EAAO,MAAMiT,EACnB,OAAID,GACF,KAAK,QAAQhT,CAAI,EAEZA,CACT,CAEA,MAAMkT,GAAmB,SAAY,CAEnC,KAAM,CAAE,eAAA5T,EAAgB,cAAAM,EAAe,gBAAAL,CAAA,EACrCF,GACE,KAAK,OACL,KAAK,SACL,KAAK,WACL,KAAK,iBACL,KAAK,gBACL,KAAK,UACL,KAAK,WACL1C,CAAA,EAEJ,KAAK,WAAa4C,EAGlB,KAAK,QAAQD,CAAc,EAE3B,GAAI,CAEF,aAAM,KAAK,GAAG,iBAAiBA,EAAgB3C,EAASiD,CAAa,EAGrE,KAAK,WAAWN,EAAgB3C,CAAO,EACvC,KAAK,UAAU2C,EAAgB,CAAC,EAChC,KAAK,WAAWA,CAAc,EAEvBA,CACT,OAAS6T,EAAK,CACZ,MAAI7T,IAAmB,IACrB,KAAK,UAAUA,CAAc,EAEzB6T,CACR,CACF,GAAA,EAEA,KAAK,mBAAmB,IAAIxW,EAASuW,CAAe,EAEpD,GAAI,CACF,MAAMlT,EAAO,MAAMkT,EACnB,OAAKF,GACH,KAAK,UAAUhT,CAAI,EAEdA,CACT,QAAA,CACE,KAAK,mBAAmB,OAAOrD,CAAO,CACxC,CACF,CAEA,kBAAkBA,EAAkC,CAClD,OAAO,KAAK,YAAYA,EAAS,EAAI,CACvC,CAEA,MAAM,UAAU5J,EAAiC,CAC/C,KAAK,kBAAkBA,CAAQ,EAC/B,MAAM4J,EAAU,KAAK,gBAAgB5J,CAAQ,EAC7C,GAAI4J,IAAY,EAAG,OAEnB,GAAI5J,IAAa,GAAK4J,IAAY,EAChC,MAAM,IAAI,MACR,mDAAmDA,CAAO,oBAAA,EAI9D,MAAMyW,EAAsB,KAAK,uBAAuBrgB,CAAQ,EAChE,MAAM,KAAK,GAAG,UAAUA,EAAU4J,CAAO,EAErC,KAAK,uBAAuB5J,CAAQ,IAAMqgB,GAC5C,KAAK,WAAWrgB,CAAQ,CAE5B,CAEA,MAAM,UAAU4J,EAAgC,CAC9C,KAAK,iBAAiBA,CAAO,EAC7B,MAAMqD,EAAO,KAAK,gBAAgBrD,CAAO,EACrCqD,IAAS,IAAM,KAAK,QAAQA,CAAI,GAClC,MAAM,KAAK,UAAUA,CAAI,CAE7B,CAEA,MAAM,eAA+B,CACnC,QAAS9b,EAAI,EAAGA,EAAI,KAAK,UAAWA,IAC9B,KAAK,QAAQA,CAAC,GAChB,MAAM,KAAK,UAAUA,CAAC,EAG1B,MAAM,KAAK,GAAG,MAAA,CAChB,CAEA,MAAM,aAAa8uB,EAAe,GAAwB,CACxD,OAAO,KAAK,qBAAqB,SAAY,CAC3C,MAAMlE,EAAa,KAAK,gBAAgB,CAAC,EACnCuE,EAAY5mB,GAASqiB,EAAYh0B,EAA4B,EAC7Dw4B,EAAgB7mB,GAASqiB,EAAYj0B,EAAyB,EAEpE,GAAIw4B,EAAY,EAAG,CACjB,GACEA,GAAa,GACZC,EAAgB,GAAKD,EAAYC,EAElC,MAAM,IAAI3tB,GACR0tB,EACA,oCAAoCA,CAAS,iBAAiBC,CAAa,GAAA,EAI/E,MAAMtT,EAAO,MAAM,KAAK,YAAYqT,EAAWL,CAAG,EAC5CO,EAAiB,KAAK,gBAAgBvT,CAAI,EAE1CpO,EAAYxF,GAAQmnB,EAAgB95B,EAAuB,EACjE,GAAImY,IAAchP,GAChB,MAAM,IAAI+C,GACR0tB,EACA,uCAAuCzhB,EAAU,SAAS,EAAE,CAAC,EAAA,EAIjE,MAAM4hB,EAAe/mB,GACnB8mB,EACA15B,EAAA,EAEF,GACE25B,IAAiBH,GAChBC,EAAgB,GAAKE,EAAeF,EAErC,MAAM,IAAI3tB,GACR0tB,EACA,uCAAuCG,CAAY,iBAAiBH,CAAS,EAAA,EAIjF,OAAA3mB,GAAUoiB,EAAYh0B,GAA8B04B,CAAY,EAChE,KAAK,UAAU,CAAC,EAEhB9hB,GAAU6hB,EAAgB,CAAC,EAC3B,KAAK,UAAUvT,CAAI,EAEZqT,CACT,CAEA,MAAMI,EAAcH,EAAgB,EACpC5mB,GAAUoiB,EAAYj0B,GAA2B44B,CAAW,EAC5D,KAAK,UAAU,CAAC,EAEhB,MAAMzT,EAAO,MAAM,KAAK,YAAYyT,EAAaT,CAAG,EAC9CU,EAAgB,KAAK,gBAAgB1T,CAAI,EAC/C,OAAAtO,GAAUgiB,EAAe,CAAC,EAC1B,KAAK,UAAU1T,CAAI,EAEZyT,CACT,CAAC,CACH,CAEA,oBAAsC,CACpC,OAAO,KAAK,aAAa,EAAI,CAC/B,CAEA,MAAM,SAAS9W,EAAiBgX,EAAiB,GAAsB,CAGrE,GAFA,KAAK,iBAAiBhX,CAAO,EAEzBA,GAAW,EACb,MAAM,IAAI,MAAM,sCAAsCA,CAAO,EAAE,EAGjE,OAAO,KAAK,qBAAqB,SAAY,CAC3C,MAAMmS,EAAa,KAAK,gBAAgB,CAAC,EACnCwE,EAAgB7mB,GAASqiB,EAAYj0B,EAAyB,EACpE,GAAIy4B,EAAgB,GAAK3W,EAAU2W,EACjC,MAAM,IAAI,MACR,oBAAoB3W,CAAO,uBAAuB2W,CAAa,EAAA,EAInE,MAAMT,EAAgB,KAAK,gBAAgBlW,CAAO,EAClD,GAAIkW,IAAkB,IACpB,GAAIc,EACF,KAAK,eAAed,CAAa,UACxB,KAAK,aAAaA,CAAa,EACxC,MAAM,IAAI,MAAM,2CAA2ClW,CAAO,EAAE,EAIxE,MAAMqD,EAAO,MAAM,KAAK,YAAYrD,EAAS,EAAI,EACjD,GAAI,CACF,MAAMtQ,EAAO,KAAK,gBAAgB2T,CAAI,EAChCpO,EAAYI,GAAc3F,EAAM,CAAC,EACvC,GAAIuF,IAAchP,GAAgB,CAEhC,GADA,KAAK,aAAaod,CAAI,EAClB2T,EACF,OAEF,MAAM,IAAI,MACR,8BAA8BhX,CAAO,yBAAA,CAEzC,CACA,GAAI,CAACgX,GAAS/hB,IAAc5O,GAC1B,MAAM,IAAI,MAAM,mCAAmC2Z,CAAO,EAAE,EAG9D,MAAMiX,EAAWnnB,GAASqiB,EAAYh0B,EAA4B,EAElEgX,GAAezF,EAAM,EAAGunB,CAAQ,EAEhCloB,GACE,KAAK,MACLsU,EAAO,KAAYxmB,GACnB,EACA,KAAYA,EAAA,EAGV,KAAK,GAAG,kBACV,MAAM,KAAK,GAAG,iBAAiBwmB,EAAMrD,CAAO,EAE5C,MAAM,KAAK,UAAUqD,CAAI,EAG3B,KAAK,aAAaA,CAAI,EACtB,KAAK,WAAWA,CAAI,EACpB,KAAK,UAAUA,EAAM,CAAC,EAEtBtT,GAAUoiB,EAAYh0B,GAA8B6hB,CAAO,EAC3D,KAAK,UAAU,CAAC,CAClB,QAAA,CACE,KAAK,UAAUqD,CAAI,CACrB,CACF,CAAC,CACH,CAKA,MAAM,OAAOjc,EAAgBwgB,EAAyC,CACpE,IAAIsP,EAASvP,GAAQvgB,EAAK,KAAK,KAAMwgB,CAAQ,EAC7C,KAAOsP,IAAWhwB,EAAS,YAAY,CACrC,MAAMkL,EAAchL,EAAI,OAAO,OAC/B,MAAM,KAAK,YAAYgL,CAAW,EAClChL,EAAI,OAASF,EAAS,QACtBgwB,EAASvP,GAAQvgB,EAAK,KAAK,KAAMwgB,CAAQ,CAC3C,CACA,OAAOsP,CACT,CACF,CCtoBA,eAAsBC,GAAeC,EAA2C,CAC9E,MAAMC,EAAa,MAAMD,EAAI,iBAAA,EAC7B,GAAIC,IAAe,EACjB,MAAO,CACL,WAAY,EACZ,iBAAkB,EAClB,eAAgB,EAChB,kBAAmB,CAAA,EAKvB,MAAMC,EAAc,MAAMF,EAAI,cAAA,EAC9B,GAAI,CAACE,EAEH,aAAMF,EAAI,YAAY,CAAC,EAChB,CACL,WAAY,EACZ,iBAAkB,EAClB,eAAgB,EAChB,kBAAmB,CAAA,EAMvB,GAAI,CACFxkB,GAAoB0kB,EAAa,EAAI,CACvC,MAAc,CACZ,aAAMF,EAAI,YAAY,CAAC,EAChB,CACL,WAAY,EACZ,iBAAkB,EAClB,eAAgB,EAChB,kBAAmB,CAAA,CAEvB,CAGA,MAAMG,EAAY,MAAMH,EAAI,cAAc,EAAGC,CAAU,EAGjDG,MAAe,IACfC,MAAqB,IAC3B,IAAIC,EAAuB,EAE3B,UAAWppB,KAAcipB,EAAW,CAClC,MAAMI,EAAavkB,GAAiB9E,CAAU,EAC9C,GAAI,CAACqpB,EAAW,OAAS,CAACA,EAAW,OAGnC,MAGF,KAAM,CAAE,OAAAnsB,GAAWmsB,EACnB,GAAInsB,EAAO,WAAaksB,EAAuB,EAE7C,MAQF,GANAA,IAEKF,EAAS,IAAIhsB,EAAO,IAAI,GAC3BgsB,EAAS,IAAIhsB,EAAO,KAAM,CAAA,CAAE,EAG1BA,EAAO,YAAchH,GACvBizB,EAAe,IAAIjsB,EAAO,IAAI,UAE9BA,EAAO,YAAcjH,IACrBiH,EAAO,YAAc/G,GACrB,CACA,MAAMyO,EAAW,IAAI,WACnB5E,EAAW,OACXA,EAAW,WAAajJ,GACxB,IAAA,EAGIuyB,EAAW,IAAI,WAAW,IAAI,EACpCA,EAAS,IAAI1kB,CAAQ,EAErBskB,EAAS,IAAIhsB,EAAO,IAAI,EAAG,KAAK,CAC9B,OAAQA,EAAO,OACf,KAAMosB,EACN,UAAWpsB,EAAO,SAAA,CACnB,CACH,CACF,CAIA,MAAMqsB,MAAkB,IACxB,IAAIC,EAAmB,EACnBC,EAAiB,EAErB,SAAW,CAACC,EAAMjsB,CAAM,IAAKyrB,EAAS,UACpC,GAAIC,EAAe,IAAIO,CAAI,EAAG,CAC5BF,IACA,UAAWpsB,KAASK,EACdL,EAAM,OAAS,GACjBmsB,EAAY,IAAInsB,EAAM,OAAQA,EAAM,IAAI,CAG9C,MACEqsB,IAKJ,GAAIF,EAAY,KAAO,EAAG,CACxB,MAAMI,EAA4D,CAAA,EAClE,SAAW,CAAChvB,EAAQ+B,CAAI,IAAK6sB,EAAY,UACvCI,EAAa,KAAK,CAAE,OAAAhvB,EAAQ,KAAA+B,CAAA,CAAM,EAGpCitB,EAAa,KAAK,CAAC1U,EAAGnP,IAAMmP,EAAE,OAASnP,EAAE,MAAM,EAC/C,MAAMgjB,EAAI,WAAWa,CAAY,CACnC,CAGA,aAAMb,EAAI,MAAA,EACV,MAAMA,EAAI,YAAY,CAAC,EAEhB,CACL,WAAYM,EACZ,iBAAAI,EACA,eAAAC,EACA,kBAAmBF,EAAY,IAAA,CAEnC,CCjIO,MAAMK,EAAoB,CAY/B,YAAYC,EAA2BC,EAAsC,CAXrEttB,EAAA,mBAAuC,MACvCA,EAAA,0BAAqB,GACrBA,EAAA,aAAoC,CAAA,GACpCA,EAAA,oBAAsE,CAAA,GACtEA,EAAA,mBAAc,GACdA,EAAA,gBAAW,GAEXA,EAAA,yBACAA,EAAA,uBACAA,EAAA,sBAAsC,MAG5C,KAAK,iBAAmBqtB,EACxB,KAAK,eAAiBC,CACxB,CAEA,aAAuB,OACrB,MACE,CAAC,CAAC,KAAK,kBACP,OAAO,UAAc,KACrB,QAAOlrB,EAAA,iCAAW,QAAX,YAAAA,EAAkB,UAAY,UAEzC,CAEA,MAAc,gBAAgC,CACxC,CAAC,KAAK,eAAiB,KAAK,gBAChC,MAAM,IAAI,QAAemrB,GAAoB,CAC3C,UAAU,MACP,QAAQ,KAAK,iBAAmB,CAAE,KAAM,WAAA,EAAe,IAC/C,IAAI,QAAeC,GAAmB,CAC3C,KAAK,eAAiBA,EACtBD,EAAA,CACF,CAAC,CACF,EACA,MAAM,IAAM,CACXA,EAAA,CACF,CAAC,CACL,CAAC,CACH,CAEQ,uBAA8B,CACpC,GAAI,KAAK,eAAgB,CACvB,MAAME,EAAM,KAAK,eACjB,KAAK,eAAiB,KACtBA,EAAA,CACF,CACF,CAEA,IAAI,UAAoB,CACtB,OAAO,KAAK,cAAgB,IAC9B,CAEA,IAAI,cAAwC,CAC1C,OAAO,KAAK,WACd,CAMA,MAAM,QAAWC,EAAwBC,EAA8B,CAErE,GAAI,KAAK,aAAeA,IAAY,KAAK,YAAY,QACnD,OAAOD,EAAA,EAMT,GACE,KAAK,aACL,KAAK,aAAa,OAAS,GAC1B,KAAK,YAAA,GAAiB,KAAK,mBAAqB,EAEjD,OAAO,IAAI,QAAW,CAACtsB,EAASC,IAAW,CACzC,KAAK,MAAM,KAAK,SAAY,CAC1B,KAAK,qBACL,GAAI,CACE,KAAK,YAAA,GAAiB,KAAK,qBAAuB,IACpD,MAAM,KAAK,eAAA,EACP,KAAK,gBACP,MAAM,KAAK,eAAA,GAGf,MAAMmf,EAAM,MAAMkN,EAAA,EAClBtsB,EAAQof,CAAG,CACb,OAASkL,EAAK,CACZrqB,EAAOqqB,CAAG,CACZ,QAAA,CACE,KAAK,qBACD,KAAK,qBAAuB,GAAK,CAAC,KAAK,aACzC,KAAK,sBAAA,EAEP,KAAK,MAAA,CACP,CACF,CAAC,CACH,CAAC,EAIH,KAAK,qBACL,GAAI,CACF,OAAI,KAAK,YAAA,GAAiB,KAAK,qBAAuB,IACpD,MAAM,KAAK,eAAA,EACP,KAAK,gBACP,MAAM,KAAK,eAAA,GAGR,MAAMgC,EAAA,CACf,QAAA,CACE,KAAK,qBACD,KAAK,qBAAuB,GAAK,CAAC,KAAK,aACzC,KAAK,sBAAA,EAEP,KAAK,MAAA,CACP,CACF,CAMA,MAAM,uBAAmD,CACvD,GAAI,CAAC,KAAK,aAAe,KAAK,qBAAuB,GAAK,KAAK,MAAM,SAAW,EAAG,CACjF,MAAME,EAA0B,CAC9B,QAAS,KAAK,cACd,KAAM,KAAK,WACX,UAAW,KAAK,IAAA,CAAI,EAEtB,YAAK,YAAcA,EACnB,MAAM,KAAK,eAAA,EACJA,CACT,CAEA,OAAO,IAAI,QAA2BxsB,GAAY,CAChD,KAAK,aAAa,KAAK,CACrB,QAAS,MAAOwsB,GAAU,CACxB,MAAM,KAAK,eAAA,EACXxsB,EAAQwsB,CAAK,CACf,CAAA,CACD,EACD,KAAK,MAAA,CACP,CAAC,CACH,CAKA,sBAAsBD,EAAuB,CACvC,CAAC,KAAK,aAAe,KAAK,YAAY,UAAYA,IAGtD,KAAK,YAAc,KACnB,KAAK,sBAAA,EACL,KAAK,MAAA,EACP,CAEQ,OAAc,CACpB,GAAI,MAAK,YAKT,IAAI,KAAK,aAAa,OAAS,EAAG,CAEhC,GAAI,KAAK,qBAAuB,EAAG,CACjC,MAAME,EAAS,KAAK,aAAa,MAAA,EAC3BD,EAA0B,CAC9B,QAAS,KAAK,cACd,KAAM,KAAK,WACX,UAAW,KAAK,IAAA,CAAI,EAEtB,KAAK,YAAcA,EACnBC,EAAO,QAAQD,CAAK,CACtB,CACA,MACF,CAGA,KACE,KAAK,MAAM,OAAS,GACpB,CAAC,KAAK,aACN,KAAK,aAAa,SAAW,IAC5B,CAAC,KAAK,eAAiB,KAAK,qBAAuB,IACpD,CACA,MAAME,EAAW,KAAK,MAAM,MAAA,EACxBA,GACFA,EAAA,CAEJ,EACF,CACF,CAUO,MAAMC,EAAuB,CA4BlC,YACEzB,EACA0B,EACAC,EACAZ,EACA,CAhCMrtB,EAAA,YACAA,EAAA,aACAA,EAAA,WACAA,EAAA,cAEAA,EAAA,mBAAuC,MACvCA,EAAA,0BAAqB,GACrBA,EAAA,2BAAsB,GACtBA,EAAA,yBAAoB,KACpBA,EAAA,yBAAwC,MACxCA,EAAA,wBAAmB,KACnBA,EAAA,6BAAwB,KACxBA,EAAA,mBAAc,GACdA,EAAA,qBAAgB,GAChBA,EAAA,qBAAgB,GAGhBA,EAAA,oBAAgB,KAAK,MAAM,KAAK,SAAW,UAAU,IAAM,GAAM,GACjEA,EAAA,6BAAwB,GACxBA,EAAA,6BAAwB,GACxBA,EAAA,6BAAwB,GACxBA,EAAA,8BAGAA,EAAA,iBAAiB,MACjBA,EAAA,gBAAW,IAQjB,KAAK,IAAMssB,EACX,KAAK,KAAO0B,EACZ,KAAK,GAAKC,EACV,KAAK,MAAQ,IAAIb,GACfC,EACA,IAAM,KAAK,kBAAA,CAAkB,CAEjC,CAEA,yBAAyBa,EAA+B,CACtD,KAAK,sBAAwBA,CAC/B,CAEA,sBAA6B,CAC3B,MAAMtpB,EAAO,KAAK,KAAK,gBAAgB,CAAC,EACxC,KAAK,sBAAwBA,EAAK,UAAUrR,GAA8B,EAAI,EAC9E,KAAK,sBAAwBqR,EAAK,UAAUtR,GAA8B,EAAI,CAChF,CAEA,MAAc,eACZ66B,EACAC,EACAC,EACe,CACf,KAAK,KAAK,mBAAmB,CAAC,EAAE,IAAIF,CAAS,EAC7C,KAAK,KAAK,WAAW,CAAC,EACtB,KAAK,sBAAwBC,EAC7B,KAAK,sBAAwBC,EAE7B,QAAS9V,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAC7C,KAAK,KAAK,aAAaA,CAAI,EAC3B,KAAK,KAAK,WAAWA,CAAI,EACzB,KAAK,KAAK,WAAWA,CAAI,EAAI,EAE/B,KAAK,KAAK,WAAW,CAAC,EAAI,EAEtB,KAAK,uBACP,MAAM,KAAK,sBAAA,CAEf,CAEA,MAAM,kBAAkB2T,EAAiB,GAAsB,CAC7D,GAAI,CAACA,GAAS,CAAC,KAAK,MAAM,cAAe,OAEzC,MAAMoC,EAAgB,MAAM,KAAK,IAAI,iBAAA,EACrC,IAAIC,EAAuB,GAE3B,GAAID,EAAgB,EAAG,CACrB,MAAM9B,EAAc,MAAM,KAAK,IAAI,cAAA,EACnC,IAAIgC,EAAa,EACjB,GAAIhC,EACF,GAAI,CACFgC,EAAa1mB,GAAoB0kB,EAAa,EAAI,EAAE,KACtD,MAAQ,CACNgC,EAAa,CACf,EAEEA,IAAe,KAAK,cAAgBF,IAAkB,KAAK,yBAC7DC,EAAuB,GACvB,MAAMlC,GAAe,KAAK,GAAG,EAC7B,KAAK,kBAAkB,MAAA,EACvB,KAAK,YAAc,EACnB,KAAK,cAAgB,EACrB,KAAK,sBAAwB,EAEjC,MAAW,KAAK,sBAAwB,IACtCkC,EAAuB,GACvB,KAAK,kBAAkB,MAAA,EACvB,KAAK,YAAc,EACnB,KAAK,cAAgB,EACrB,KAAK,sBAAwB,GAG/B,MAAMJ,EAAY,MAAM,KAAK,IAAI,SAAS,CAAC,EAC3C,GAAIA,EAAW,CACb,MAAMM,EAAW,IAAI,SAASN,EAAU,OAAQA,EAAU,WAAYA,EAAU,UAAU,EACpFC,EAAoBK,EAAS,UAAUl7B,GAA8B,EAAI,EACzE86B,EAAoBI,EAAS,UAAUn7B,GAA8B,EAAI,GAG7Ei7B,GACAH,IAAsB,KAAK,uBAC3BC,IAAsB,KAAK,wBAE3B,MAAM,KAAK,eAAeF,EAAWC,EAAmBC,CAAiB,CAE7E,CACF,CAEA,IAAI,YAAkC,CACpC,OAAO,KAAK,KACd,CAEA,iBAA2B,CACzB,OAAO,KAAK,cAAgB,IAC9B,CAEA,kBAAkC,CAChC,OAAO,KAAK,YAAc,KAAK,YAAY,QAAU,IACvD,CAEA,eAA+B,CAC7B,OAAO,KAAK,YAAc,KAAK,YAAY,KAAO,IACpD,CAEA,eAAelwB,EAAyB,CACtC,OAAO,KAAK,aAAa,IAAIA,CAAM,GAAK,KAAK,kBAAkB,IAAIA,CAAM,CAC3E,CAEA,eAAeA,EAAmC,CAChD,MAAM+B,EAAO,KAAK,aAAa,IAAI/B,CAAM,GAAK,KAAK,kBAAkB,IAAIA,CAAM,EAC/E,OAAO+B,EAAO,IAAI,WAAWA,CAAI,EAAI,IACvC,CAEA,kBAAkB/B,EAAgB+B,EAAwB,CAIxD,GAHI,KAAK,kBAAkB,IAAI/B,CAAM,GACnC,KAAK,kBAAkB,IAAIA,EAAQ,IAAI,WAAW+B,CAAI,CAAC,EAErD/B,IAAW,EAAG,CAChB,MAAMyG,EAAO,IAAI,SAAS1E,EAAK,OAAQA,EAAK,WAAYA,EAAK,UAAU,EACvE,KAAK,sBAAwB0E,EAAK,UAAUrR,GAA8B,EAAI,EAC9E,KAAK,sBAAwBqR,EAAK,UAAUtR,GAA8B,EAAI,CAChF,CACF,CAMA,MAAM,qBAAqBgT,EAAiBnI,EAA+B,CACzE,GAAI,CAAC,KAAK,YAAa,CAErB,MAAM,KAAK,GAAG,UAAUmI,EAASnI,CAAM,EACvC,MACF,CAEA,KAAK,GAAG,kBAAkBmI,EAASnI,CAAM,EAEzC,MAAMuwB,EAAY,KAAK,KAAK,mBAAmBpoB,CAAO,EAChDwmB,EAAW,IAAI,WAAWzzB,EAAa,EAC7CyzB,EAAS,IAAI4B,CAAS,EAEtB,KAAK,aAAa,IAAIvwB,EAAQ2uB,CAAQ,EAEtC,MAAM6B,EAAc,KAAK,KAAK,gBAAgB,CAAC,EAAE,UAAUv7B,GAA2B,EAAI,EAGpFwN,EAAQuH,GACZ,CACE,UAAWxO,GACX,MAAO,EACP,KAAM,KAAK,YAAY,KACvB,OAAAwE,EACA,YAAAwwB,EACA,SAAU,EAAE,KAAK,WAAA,EAEnB7B,CAAA,EAGF,MAAM,KAAK,IAAI,gBAAgB,CAAClsB,CAAK,CAAC,EACtC,KAAK,sBAAwB,MAAM,KAAK,IAAI,iBAAA,CAC9C,CAMA,MAAM,kBAMH,CACD,MAAM2rB,EAAa,MAAM,KAAK,IAAI,iBAAA,EAC5BqC,MAAoB,IAC1B,QAASrW,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAAQ,CACrD,MAAMpa,EAAS,KAAK,KAAK,gBAAgBoa,CAAI,EAC7C,GAAIpa,EAAS,EAAG,CACd,MAAM0wB,EAAQ,KAAK,KAAK,QAAQtW,CAAI,EAC9BrY,EAAO,IAAI,WAAW,KAAK,KAAK,mBAAmBqY,CAAI,CAAC,EAC9DqW,EAAc,IAAIrW,EAAM,CAAE,OAAApa,EAAQ,MAAA0wB,EAAO,KAAA3uB,EAAM,CACjD,CACF,CACA,MAAM4uB,EAAY,IAAI,YAAY,KAAK,KAAK,UAAU,EAChDC,MAAmB,IACzB,SAAW,CAACvuB,EAAGC,CAAC,IAAK,KAAK,aAAa,UACrCsuB,EAAa,IAAIvuB,EAAG,IAAI,WAAWC,CAAC,CAAC,EAEvC,MAAO,CACL,WAAA8rB,EACA,cAAAqC,EACA,UAAAE,EACA,aAAAC,EACA,YAAa,KAAK,WAAA,CAEtB,CAKA,MAAM,iBAAiBC,EAML,CAEhB,QAASzW,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAC7C,KAAK,KAAK,aAAaA,CAAI,EAC3B,KAAK,KAAK,WAAWA,CAAI,EAI3B,QAASA,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAAQ,CACrD,MAAMhY,EAAOyuB,EAAU,cAAc,IAAIzW,CAAI,EACzChY,IACF,KAAK,KAAK,WAAWgY,EAAMhY,EAAK,MAAM,EACtC,KAAK,KAAK,mBAAmBgY,CAAI,EAAE,IAAIhY,EAAK,IAAI,EAC5CA,EAAK,MACP,KAAK,KAAK,UAAUgY,CAAI,EAExB,KAAK,KAAK,WAAWA,CAAI,EAG/B,CAGA,KAAK,KAAK,WAAW,IAAIyW,EAAU,SAAS,EAG5C,KAAK,aAAa,MAAA,EAClB,SAAW,CAACxuB,EAAGC,CAAC,IAAKuuB,EAAU,aAAa,UAC1C,KAAK,aAAa,IAAIxuB,EAAG,IAAI,WAAWC,CAAC,CAAC,EAE5C,KAAK,YAAcuuB,EAAU,YAC7B,MAAM,KAAK,IAAI,YAAYA,EAAU,UAAU,EAC/C,KAAK,sBAAwBA,EAAU,UACzC,CASA,MAAM,OAAmC,CACvC,MAAMpB,EAAQ,MAAM,KAAK,MAAM,sBAAA,EAC/B,KAAK,YAAcA,EACnB,KAAK,eAAA,EAEL,GAAI,CACF,MAAM,KAAK,kBAAA,EAGX,MAAMqB,EAAgB,MAAM,KAAK,IAAI,iBAAA,EAC/BC,EAAiB,MAAM,KAAK,IAAI,cAAA,EACtC,IAAIC,EAAc,GAClB,GAAID,GAAkBD,EAAgB,EACpC,GAAI,CAEFE,EADgBrnB,GAAoBonB,EAAgB,EAAI,EAClC,QAAU,KAAK,YACvC,MAAQ,CACNC,EAAc,EAChB,CAEGA,GACH,MAAM,KAAK,IAAI,eACb1nB,GAAoB,CAClB,cAAe,KAAK,cACpB,MAAO,KAAK,YAAA,CACb,CAAA,EAIL,KAAK,aAAa,MAAA,EAClB,MAAMlH,EAAO,MAAM,KAAK,iBAAA,EACxB,YAAK,mBAAqBA,EAAK,WAC/B,KAAK,oBAAsBA,EAAK,YAChC,KAAK,cAAgBA,EAAK,cAC1B,KAAK,kBAAoBA,EAAK,UAEvBqtB,CACT,OAASlC,EAAK,CACZ,WAAK,YAAc,KACnB,KAAK,MAAM,sBAAsBkC,EAAM,OAAO,EACxClC,CACR,CACF,CASA,MAAM,OAAOiC,EAAgC,CAC3C,GAAI,CAAC,KAAK,aAAe,KAAK,YAAY,UAAYA,EACpD,OAGF,MAAMT,EAAO,KAAK,YAAY,KACxBkC,EAA+B,CAAA,EAC/BT,EAAc,KAAK,KAAK,gBAAgB,CAAC,EAAE,UAAUv7B,GAA2B,EAAI,EAG1F,SAAW,CAAC+K,EAAQ+B,CAAI,IAAK,KAAK,aAAa,UAC7C,KAAK,kBAAkB,IAAI/B,EAAQ+B,CAAI,EAIzC,QAASqY,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAC7C,GAAI,KAAK,KAAK,QAAQA,CAAI,EAAG,CAC3B,MAAMpa,EAAS,KAAK,KAAK,gBAAgBoa,CAAI,EAC7C,GAAIpa,EAAS,EAAG,CACd,KAAK,GAAG,kBAAkBoa,EAAMpa,CAAM,EAEtC,MAAMiF,EAAY,KAAK,KAAK,mBAAmBmV,CAAI,EAC7CuU,EAAW,IAAI,WAAWzzB,EAAa,EAC7CyzB,EAAS,IAAI1pB,CAAS,EAEtB,KAAK,kBAAkB,IAAIjF,EAAQ2uB,CAAQ,EAC3C,KAAK,KAAK,WAAWvU,CAAI,EAEzB6W,EAAe,KACbjnB,GACE,CACE,UAAW1O,GACX,MAAO,EACP,KAAAyzB,EACA,OAAA/uB,EACA,YAAAwwB,EACA,SAAU,EAAE,KAAK,WAAA,EAEnB7B,CAAA,CACF,CAEJ,CACF,CAIFsC,EAAe,KACbjnB,GAAe,CACb,UAAWzO,GACX,MAAO,EACP,KAAAwzB,EACA,OAAQ,EACR,YAAAyB,EACA,SAAU,EAAE,KAAK,WAAA,CAClB,CAAA,EAIH,MAAM,KAAK,IAAI,gBAAgBS,CAAc,EAC7C,MAAM,KAAK,IAAI,SAAA,EACf,MAAMH,EAAgB,MAAM,KAAK,IAAI,iBAAA,EACrC,KAAK,sBAAwBA,EAG7B,KAAK,YAAc,KACnB,KAAK,aAAa,MAAA,EAClB,KAAK,cAAc,MAAA,EACnB,KAAK,kBAAoB,KACzB,KAAK,gBAGL,KAAK,MAAM,sBAAsBtB,CAAO,EACxC,KAAK,kBAAA,GAGDsB,GAAiB,KAAO,KAAK,eAAiB,MAEhD,KAAK,MAAM,QAAQ,IAAM,KAAK,mBAAmB,CAErD,CASA,MAAM,SAAStB,EAAgC,CACzC,CAAC,KAAK,aAAe,KAAK,YAAY,UAAYA,IAItD,MAAM,KAAK,iBAAiB,CAC1B,WAAY,KAAK,mBACjB,cAAe,KAAK,cACpB,UAAW,KAAK,mBAAqB,IAAI,YAAY,KAAK,KAAK,UAAU,EACzE,iBAAkB,IAClB,YAAa,KAAK,mBAAA,CACnB,EAED,KAAK,YAAc,KACnB,KAAK,aAAa,MAAA,EAClB,KAAK,cAAc,MAAA,EACnB,KAAK,kBAAoB,KAEzB,KAAK,MAAM,sBAAsBA,CAAO,EACxC,KAAK,kBAAA,EACP,CAUA,MAAM,YAAgD,CAGpD,OAAO,KAAK,MAAM,QAAQ,IAAM,KAAK,mBAAmB,CAC1D,CAEA,MAAM,mBAAuD,CAC3D,MAAMpB,EAAa,MAAM,KAAK,IAAI,iBAAA,EAG5B8C,MAAe,IACrB,GAAI9C,EAAa,EAAG,CAClB,MAAME,EAAY,MAAM,KAAK,IAAI,cAAc,EAAGF,CAAU,EACtDG,MAAe,IACf4C,MAAmB,IAEzB,UAAW9rB,KAAcipB,EAAW,CAClC,MAAMI,EAAavkB,GAAiB9E,CAAU,EAC9C,GAAI,CAACqpB,EAAW,OAAS,CAACA,EAAW,OACnC,MAEF,KAAM,CAAE,UAAA0C,EAAW,KAAArC,EAAM,OAAA/uB,CAAA,EAAW0uB,EAAW,OAI/C,GAFKH,EAAS,IAAIQ,CAAI,GAAGR,EAAS,IAAIQ,EAAM,EAAE,EAE1CqC,IAAc71B,GAChB41B,EAAa,IAAIpC,CAAI,UAErBqC,IAAc91B,IACd81B,IAAc51B,GACd,CACA,MAAMyO,EAAW,IAAI,WACnB5E,EAAW,OACXA,EAAW,WAAajJ,GACxBlB,EAAA,EAEI8G,EAAO,IAAI,WAAW9G,EAAa,EACzC8G,EAAK,IAAIiI,CAAQ,EACjBskB,EAAS,IAAIQ,CAAI,EAAG,KAAK,CAAE,OAAA/uB,EAAQ,KAAMgC,EAAM,CACjD,CACF,CAEA,SAAW,CAAC+sB,EAAMjsB,CAAM,IAAKyrB,EAAS,UACpC,GAAI4C,EAAa,IAAIpC,CAAI,EACvB,UAAWlsB,KAAKC,EACVD,EAAE,OAAS,GACbquB,EAAS,IAAIruB,EAAE,OAAQA,EAAE,IAAI,CAKvC,CAEA,SAAW,CAAC7C,EAAQ+B,CAAI,IAAK,KAAK,kBAAkB,UAClDmvB,EAAS,IAAIlxB,EAAQ+B,CAAI,EAI3B,MAAMsvB,MAAqB,IAC3B,QAASjX,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAC7C,GAAI,KAAK,KAAK,QAAQA,CAAI,EAAG,CAC3B,MAAMpa,EAAS,KAAK,KAAK,gBAAgBoa,CAAI,EAC7C,GAAIpa,EAAS,EAAG,CACd,KAAK,GAAG,kBAAkBoa,EAAMpa,CAAM,EACtC,MAAMiK,EAAW,KAAK,KAAK,mBAAmBmQ,CAAI,EAC5CpY,EAAO,IAAI,WAAW9G,EAAa,EACzC8G,EAAK,IAAIiI,CAAQ,EACjBonB,EAAe,IAAIrxB,EAAQ,CAAE,QAASoa,EAAM,KAAMpY,EAAM,CAC1D,CACF,CAIF,MAAMsvB,MAAiB,IAAY,CACjC,GAAGJ,EAAS,KAAA,EACZ,GAAGG,EAAe,KAAA,CAAK,CACxB,EAEKrC,EAA4D,CAAA,EAClE,UAAWhvB,KAAUsxB,EACnB,GAAID,EAAe,IAAIrxB,CAAM,EAAG,CAC9B,KAAM,CAAE,QAAAmI,EAAS,KAAApG,CAAA,EAASsvB,EAAe,IAAIrxB,CAAM,EACnDgvB,EAAa,KAAK,CAAE,OAAAhvB,EAAQ,KAAA+B,CAAA,CAAM,EAClC,KAAK,KAAK,WAAWoG,CAAO,CAC9B,MACE6mB,EAAa,KAAK,CAAE,OAAAhvB,EAAQ,KAAMkxB,EAAS,IAAIlxB,CAAM,EAAI,EAI7D,OAAIgvB,EAAa,OAAS,IACxBA,EAAa,KAAK,CAAC1U,EAAGnP,IAAMmP,EAAE,OAASnP,EAAE,MAAM,EAC/C,MAAM,KAAK,IAAI,WAAW6jB,CAAY,GAIxC,MAAM,KAAK,IAAI,MAAA,EAGf,MAAM,KAAK,IAAI,YAAY,CAAC,EAC5B,KAAK,kBAAkB,MAAA,EAGvB,KAAK,gBACL,KAAK,YAAc,EACnB,KAAK,cAAgB,EACrB,KAAK,sBAAwB,EAC7B,KAAK,qBAAA,EACL,MAAM,KAAK,IAAI,eACb1lB,GAAoB,CAClB,cAAe,KAAK,cACpB,MAAO,KAAK,YAAA,CACb,CAAA,EAGI,CAAE,aAAc0lB,EAAa,MAAA,CACtC,CAEA,MAAM,qBAAqC,CACzC,KAAK,aAAa,MAAA,EAClB,KAAK,kBAAkB,MAAA,EACvB,MAAM,KAAK,IAAI,YAAY,CAAC,EAC5B,KAAK,gBACL,KAAK,YAAc,EACnB,KAAK,cAAgB,EACrB,KAAK,sBAAwB,EAC7B,KAAK,qBAAA,EACL,MAAM,KAAK,IAAI,eACb1lB,GAAoB,CAClB,cAAe,KAAK,cACpB,MAAO,KAAK,YAAA,CACb,CAAA,CAEL,CAEQ,mBAA0B,CAC5B,KAAK,WACT,KAAK,eAAA,EACL,KAAK,UAAY,WAAW,IAAM,CAChC,KAAK,aAAa,MAAM,IAAM,CAAC,CAAC,CAClC,EAAG,GAAI,EACT,CAEQ,gBAAuB,CACzB,KAAK,YACP,aAAa,KAAK,SAAS,EAC3B,KAAK,UAAY,KAErB,CAEA,MAAM,OAAuB,CAC3B,KAAK,SAAW,GAChB,KAAK,eAAA,EAEL,MAAM,KAAK,WAAA,CACb,CACF,CC1yBO,MAAMioB,OAAyB,IAAI,CAAC,QAAS,MAAO,MAAO,MAAO,KAAK,CAAC,EAElEC,OAAsB,IAAI,CACrC,QACA,QACA,SACA,SACA,OACA,MACA,QACA,QACA,OACA,SACA,UACF,CAAC,EAEM,SAASC,GAAoBzK,EAAuB,CACzD,OAAOuK,GAAmB,IAAIvK,EAAK,YAAA,CAAa,CAClD,CAEO,SAAS0K,GAAwB1K,EAAuB,CAC7D,OAAOwK,GAAgB,IAAIxK,EAAK,YAAA,CAAa,CAC/C,CAEO,SAAS2K,GAAkB3K,EAAuB,CACvD,OAAOyK,GAAoBzK,CAAI,GAAK0K,GAAwB1K,CAAI,CAClE,CAEO,SAAS4K,GACdC,EACAC,EACM,CACN,GAAIA,IAAW,QAAS,CACtB,GAAID,EAAK,OAAS,MAAQJ,GAAoBI,EAAK,IAAI,EACrD,MAAM,IAAIpwB,GAAgCowB,EAAK,IAAI,EAMrD,GAJIA,EAAK,OAAS,WAChBD,GAAeC,EAAK,KAAMC,CAAM,EAChCF,GAAeC,EAAK,MAAOC,CAAM,GAE/BD,EAAK,OAAS,KAChB,UAAWE,KAAOF,EAAK,KACrBD,GAAeG,EAAKD,CAAM,CAGhC,CACF,CAuBA,SAASE,GAASC,EAAwB,CACxC,MAAMC,EAAkB,CAAA,EACxB,IAAI5zB,EAAI,EACR,MAAM6P,EAAM8jB,EAAM,OAElB,KAAO3zB,EAAI6P,GAAK,CACd,MAAMgkB,EAAKF,EAAM3zB,CAAC,EAGlB,GAAI,KAAK,KAAK6zB,CAAE,EAAG,CACjB7zB,IACA,QACF,CAGA,GAAI,QAAQ,KAAK6zB,CAAE,GAAMA,IAAO,KAAO7zB,EAAI,EAAI6P,GAAO,QAAQ,KAAK8jB,EAAM3zB,EAAI,CAAC,CAAC,EAAI,CACjF,MAAMuG,EAAQvG,EACd,IAAI8zB,EAAS,GACb,KAAO9zB,EAAI6P,IAAQ,QAAQ,KAAK8jB,EAAM3zB,CAAC,CAAC,GAAM2zB,EAAM3zB,CAAC,IAAM,KAAO,CAAC8zB,IAC7DH,EAAM3zB,CAAC,IAAM,MAAK8zB,EAAS,IAC/B9zB,IAEF4zB,EAAO,KAAK,CAAE,KAAM,SAAU,MAAOD,EAAM,MAAMptB,EAAOvG,CAAC,EAAG,IAAKuG,CAAA,CAAO,EACxE,QACF,CAGA,GAAIstB,IAAO,KAAOA,IAAO,IAAK,CAC5B,MAAME,EAAQF,EACRttB,EAAQvG,EACdA,IACA,IAAImc,EAAM,GACV,KAAOnc,EAAI6P,GAAO8jB,EAAM3zB,CAAC,IAAM+zB,GACzBJ,EAAM3zB,CAAC,IAAM,MAAQA,EAAI,EAAI6P,GAC/B7P,IACAmc,GAAOwX,EAAM3zB,CAAC,EAIhBA,IAEEA,EAAI6P,GAAO8jB,EAAM3zB,CAAC,IAAM+zB,GAC1B/zB,IAEF4zB,EAAO,KAAK,CAAE,KAAM,SAAU,MAAOzX,EAAK,IAAK5V,EAAO,EACtD,QACF,CAGA,GAAIstB,IAAO,IAAK,CACdD,EAAO,KAAK,CAAE,KAAM,SAAU,MAAO,IAAK,IAAK5zB,IAAK,EACpD,QACF,CACA,GAAI6zB,IAAO,IAAK,CACdD,EAAO,KAAK,CAAE,KAAM,SAAU,MAAO,IAAK,IAAK5zB,IAAK,EACpD,QACF,CACA,GAAI6zB,IAAO,IAAK,CACdD,EAAO,KAAK,CAAE,KAAM,QAAS,MAAO,IAAK,IAAK5zB,IAAK,EACnD,QACF,CAGA,GAAI6zB,IAAO,IAAK,CACd,GAAI7zB,EAAI,EAAI6P,GAAO8jB,EAAM3zB,EAAI,CAAC,IAAM,IAAK,CACvC4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,KAAM,IAAK5zB,EAAG,EAC/CA,GAAK,EACL,QACF,CACA,GAAIA,EAAI,EAAI6P,GAAO8jB,EAAM3zB,EAAI,CAAC,IAAM,IAAK,CACvC4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,KAAM,IAAK5zB,EAAG,EAC/CA,GAAK,EACL,QACF,CACA4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,IAAK,IAAK5zB,IAAK,EAChD,QACF,CACA,GAAI6zB,IAAO,IAAK,CACd,GAAI7zB,EAAI,EAAI6P,GAAO8jB,EAAM3zB,EAAI,CAAC,IAAM,IAAK,CACvC4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,KAAM,IAAK5zB,EAAG,EAC/CA,GAAK,EACL,QACF,CACA4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,IAAK,IAAK5zB,IAAK,EAChD,QACF,CACA,GAAI6zB,IAAO,IAAK,CACd,GAAI7zB,EAAI,EAAI6P,GAAO8jB,EAAM3zB,EAAI,CAAC,IAAM,IAAK,CACvC4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,IAAK,IAAK5zB,EAAG,EAC9CA,GAAK,EACL,QACF,CACA4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,IAAK,IAAK5zB,IAAK,EAChD,QACF,CACA,GAAI6zB,IAAO,KAAO7zB,EAAI,EAAI6P,GAAO8jB,EAAM3zB,EAAI,CAAC,IAAM,IAAK,CACrD4zB,EAAO,KAAK,CAAE,KAAM,KAAM,MAAO,KAAM,IAAK5zB,EAAG,EAC/CA,GAAK,EACL,QACF,CACA,GAAI6zB,IAAO,KAAOA,IAAO,KAAOA,IAAO,KAAOA,IAAO,IAAK,CACxDD,EAAO,KAAK,CAAE,KAAM,KAAM,MAAOC,EAAI,IAAK7zB,IAAK,EAC/C,QACF,CACA,GAAI6zB,IAAO,IAAK,CAEdD,EAAO,KAAK,CAAE,KAAM,OAAQ,MAAO,IAAK,IAAK5zB,IAAK,EAClD,QACF,CAGA,GAAI,YAAY,KAAK6zB,CAAE,EAAG,CACxB,MAAMttB,EAAQvG,EACd,KAAOA,EAAI6P,GACT,GAAI,eAAe,KAAK8jB,EAAM3zB,CAAC,CAAC,EAC9BA,YACS2zB,EAAM3zB,CAAC,IAAM,KAAOA,EAAI,EAAI6P,GAAO,YAAY,KAAK8jB,EAAM3zB,EAAI,CAAC,CAAC,EACzEA,GAAK,MAEL,OAGJ,MAAMqF,EAAMsuB,EAAM,MAAMptB,EAAOvG,CAAC,EAChC4zB,EAAO,KAAK,CAAE,KAAM,QAAS,MAAOvuB,EAAK,IAAKkB,EAAO,EACrD,QACF,CAGAvG,GACF,CAEA,OAAA4zB,EAAO,KAAK,CAAE,KAAM,MAAO,MAAO,GAAI,IAAK/jB,EAAK,EACzC+jB,CACT,CAEA,MAAMI,EAAiB,CAIrB,YAAYJ,EAAiB,CAHrBrwB,EAAA,eACAA,EAAA,cAAS,GAGf,KAAK,OAASqwB,CAChB,CAEQ,MAAc,CACpB,OAAO,KAAK,OAAO,KAAK,MAAM,GAAK,CAAE,KAAM,MAAO,MAAO,GAAI,IAAK,CAAA,CACpE,CAEQ,SAAiB,CACvB,MAAMK,EAAI,KAAK,KAAA,EACf,YAAK,SACEA,CACT,CAEQ,MAAMjmB,EAAiBkmB,EAAyB,CACtD,MAAMD,EAAI,KAAK,KAAA,EAEf,OADIA,EAAE,OAASjmB,GACXkmB,IAAU,QAAaD,EAAE,MAAM,gBAAkBC,EAAM,YAAA,EAAsB,IACjF,KAAK,SACE,GACT,CAEQ,cAAcC,EAAsB,CAC1C,GAAIA,EAAM,OAAS,MAAQA,EAAM,OAAS,OAAQ,CAChD,GACEA,EAAM,QAAU,KAChBA,EAAM,QAAU,MAChBA,EAAM,QAAU,KAChBA,EAAM,QAAU,MAChBA,EAAM,QAAU,KAChBA,EAAM,QAAU,KAEhB,MAAO,GAET,GAAIA,EAAM,QAAU,KAAOA,EAAM,QAAU,IAAK,MAAO,IACvD,GAAIA,EAAM,QAAU,KAAOA,EAAM,QAAU,KAAOA,EAAM,QAAU,IAAK,MAAO,GAChF,CACA,MAAO,EACT,CAEA,MAAMC,EAAgB,EAAa,CACjC,IAAI9V,EAAO,KAAK,aAAA,EAEhB,OAAa,CACX,MAAM6V,EAAQ,KAAK,KAAA,EACbE,EAAO,KAAK,cAAcF,CAAK,EACrC,GAAIE,IAAS,GAAKA,GAAQD,EACxB,MAEF,KAAK,QAAA,EACL,MAAM7V,EAAQ,KAAK,MAAM8V,CAAI,EAC7B/V,EAAO,CACL,KAAM,SACN,GAAI6V,EAAM,MACV,KAAA7V,EACA,MAAAC,CAAA,CAEJ,CAEA,OAAOD,CACT,CAEQ,cAAyB,CAC/B,MAAM6V,EAAQ,KAAK,KAAA,EAGnB,GAAIA,EAAM,OAAS,MAAQA,EAAM,QAAU,IAAK,CAC9C,KAAK,QAAA,EACL,MAAMG,EAAU,KAAK,MAAM,EAAE,EAC7B,OAAIA,EAAQ,OAAS,WAAa,OAAOA,EAAQ,OAAU,SAClD,CAAE,KAAM,UAAW,MAAO,CAACA,EAAQ,KAAA,EAErC,CACL,KAAM,SACN,GAAI,IACJ,KAAM,CAAE,KAAM,UAAW,MAAO,CAAA,EAChC,MAAOA,CAAA,CAEX,CAGA,GAAI,KAAK,MAAM,QAAQ,EACrB,MAAO,CAAE,KAAM,UAAW,MAAO,OAAOH,EAAM,KAAK,CAAA,EAIrD,GAAI,KAAK,MAAM,QAAQ,EACrB,MAAO,CAAE,KAAM,UAAW,MAAOA,EAAM,KAAA,EAIzC,GAAI,KAAK,MAAM,QAAQ,EAAG,CACxB,MAAMZ,EAAO,KAAK,MAAM,CAAC,EACzB,GAAI,CAAC,KAAK,MAAM,QAAQ,EACtB,MAAM,IAAI,MAAM,oCAAoC,EAEtD,OAAOA,CACT,CAGA,GAAI,KAAK,MAAM,MAAM,EACnB,MAAO,CAAE,KAAM,MAAO,KAAM,GAAA,EAI9B,GAAIY,EAAM,OAAS,QAAS,CAC1B,KAAK,QAAA,EACL,MAAMzL,EAAOyL,EAAM,MAGbI,EAAQ7L,EAAK,YAAA,EACnB,GAAI6L,IAAU,QAAU,KAAK,KAAA,EAAO,OAAS,SAC3C,MAAO,CAAE,KAAM,UAAW,MAAO,IAAA,EAEnC,GAAIA,IAAU,QAAU,KAAK,KAAA,EAAO,OAAS,SAC3C,MAAO,CAAE,KAAM,UAAW,MAAO,EAAA,EAEnC,GAAIA,IAAU,SAAW,KAAK,KAAA,EAAO,OAAS,SAC5C,MAAO,CAAE,KAAM,UAAW,MAAO,EAAA,EAInC,GAAI,KAAK,MAAM,QAAQ,EAAG,CACxB,MAAMzQ,EAAmB,CAAA,EACzB,GAAI,CAAC,KAAK,MAAM,QAAQ,GACtB,OAEE,GADAA,EAAK,KAAK,KAAK,MAAM,CAAC,CAAC,EACnB,MAAK,MAAM,OAAO,EAGtB,IAAI,KAAK,MAAM,QAAQ,EACrB,MAEF,MAAM,IAAI,MAAM,oDAAoD4E,CAAI,EAAE,GAG9E,MAAO,CACL,KAAM,KACN,KAAM6L,EACN,KAAAzQ,CAAA,CAEJ,CAGA,MAAO,CAAE,KAAM,MAAO,KAAA4E,CAAA,CACxB,CAEA,MAAM,IAAI,MAAM,qBAAqByL,EAAM,KAAK,+BAA+BA,EAAM,GAAG,EAAE,CAC5F,CACF,CAKO,SAASK,GAAgBC,EAAuB,CACrD,MAAMC,EAAUD,EAAI,KAAA,EACpB,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,+BAA+B,EAEjD,MAAMd,EAASF,GAASgB,CAAO,EAE/B,OADe,IAAIV,GAAiBJ,CAAM,EAC5B,MAAM,CAAC,CACvB,CAMA,SAASe,GAAaC,EAA0D,CAC9E,IAAIjyB,EAAQ,EACRkyB,EAAyB,KAC7B,MAAMhlB,EAAM+kB,EAAI,OAEhB,QAAS,EAAI,EAAG,EAAI/kB,EAAK,IAAK,CAC5B,MAAMgkB,EAAKe,EAAI,CAAC,EAChB,GAAIC,EAAS,CACPhB,IAAOgB,GAAWD,EAAI,EAAI,CAAC,IAAM,OACnCC,EAAU,MAEZ,QACF,CACA,GAAIhB,IAAO,KAAOA,IAAO,IAAK,CAC5BgB,EAAUhB,EACV,QACF,CACA,GAAIA,IAAO,IAAK,CACdlxB,IACA,QACF,CACA,GAAIkxB,IAAO,IAAK,CACdlxB,IACA,QACF,CAEA,GAAIA,IAAU,IAGTkxB,IAAO,KAAOA,IAAO,MACtB,EAAI,EAAIhkB,GACR+kB,EAAI,MAAM,EAAI,EAAG,EAAI,CAAC,EAAE,YAAA,IAAkB,MAC1C,KAAK,KAAKA,EAAI,EAAI,CAAC,CAAC,EACpB,CACA,MAAME,EAAUF,EAAI,MAAM,EAAG,CAAC,EAAE,KAAA,EAC1BG,EAAgBH,EAAI,MAAM,EAAI,CAAC,EAAE,KAAA,EACvC,MAAO,CAAE,QAAAE,EAAS,cAAAC,CAAA,CACpB,CAEJ,CAEA,MAAO,CAAE,QAASH,EAAI,MAAK,CAC7B,CAKO,SAASI,GAAmBzB,EAAwB,CACzD,GAAIA,EAAK,OAAS,MAChB,OAAOA,EAAK,KAAK,SAAS,GAAG,EACzBA,EAAK,KAAK,MAAMA,EAAK,KAAK,YAAY,GAAG,EAAI,CAAC,EAC9CA,EAAK,KAEX,GAAIA,EAAK,OAAS,KAAM,CACtB,GAAIA,EAAK,KAAK,OAAS,GAAKA,EAAK,KAAK,CAAC,EAAE,OAAS,OAASA,EAAK,KAAK,CAAC,EAAE,OAAS,IAAK,CACpF,MAAM0B,EAAU1B,EAAK,KAAK,CAAC,EAAE,KAAK,SAAS,GAAG,EAC1CA,EAAK,KAAK,CAAC,EAAE,KAAK,MAAMA,EAAK,KAAK,CAAC,EAAE,KAAK,YAAY,GAAG,EAAI,CAAC,EAC9DA,EAAK,KAAK,CAAC,EAAE,KACjB,MAAO,GAAGA,EAAK,IAAI,IAAI0B,CAAO,EAChC,CACA,OAAO1B,EAAK,IACd,CACA,OAAIA,EAAK,OAAS,SACT,OAEF,KACT,CAKO,SAAS2B,GAAgBN,EAA+B,CAC7D,KAAM,CAAE,QAAAE,EAAS,cAAAC,GAAkBJ,GAAaC,CAAG,EAC7CrB,EAAOiB,GAAgBM,CAAO,EAC9BK,EAAQJ,GAAiBA,EAAc,OAAS,EAAIA,EAAgBC,GAAmBzB,CAAI,EACjG,MAAO,CAAE,KAAAA,EAAM,MAAA4B,CAAA,CACjB,CAMO,MAAMC,EAAkB,CAG7B,YAAYC,EAAgB,CAFnB9xB,EAAA,aAGP,KAAK,KAAO8xB,CACd,CAEA,IAAIC,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,GAAGA,EAA2F,CAC5F,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,GAAGA,EAA2F,CAC5F,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,KACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,GAAGA,EAA0E,CAC3E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,KACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,GAAGA,EAA0E,CAC3E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,IACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,IAAIA,EAA0E,CAC5E,OAAO,IAAIF,GAAkB,CAC3B,KAAM,SACN,GAAI,KACJ,KAAM,KAAK,KACX,MAAOG,GAAWD,CAAK,CAAA,CACxB,CACH,CAEA,GAAGH,EAAiC,CAClC,MAAO,CACL,KAAM,KAAK,KACX,MAAAA,CAAA,CAEJ,CACF,CAEA,SAASI,GAAWlwB,EAAgF,CAClG,OAAIA,IAAQ,KACH,CAAE,KAAM,UAAW,MAAO,IAAA,EAE/B,OAAOA,GAAQ,UACV,CAAE,KAAM,UAAW,MAAOA,CAAA,EAE/BA,aAAe+vB,GACV/vB,EAAI,KAET,OAAOA,GAAQ,SACV,CAAE,KAAM,UAAW,MAAOA,CAAA,EAE/B,OAAOA,GAAQ,SACV,CAAE,KAAM,UAAW,MAAOA,CAAA,EAE5BA,CACT,CAEO,SAAS6M,GAAIwW,EAAiC,CACnD,OAAO,IAAI0M,GAAkB,CAAE,KAAM,MAAO,KAAA1M,EAAM,CACpD,CAEO,SAASwE,GAAIsI,EAAmC,CACrD,OAAO,IAAIJ,GAAkBZ,GAAgBgB,CAAM,CAAC,CACtD,CAEO,MAAMf,GAAMvH,GA0BnB,SAASuI,GAAO/M,EAAc5E,EAAiE,CAC7F,OAAO,IAAIsR,GAAkB,CAC3B,KAAM,KACN,KAAM1M,EAAK,YAAA,EACX,KAAM5E,EAAK,IAAK9H,GAAO,OAAOA,GAAM,UAAY,CAACA,EAAE,WAAW,GAAG,EAAI9J,GAAI8J,CAAC,EAAE,KAAOuZ,GAAWvZ,CAAC,CAAE,CAAA,CAClG,CACH,CAEA,MAAM0Z,GAAS,CACbhN,KACG5E,IAEI2R,GAAO/M,EAAM5E,CAAI,EAGpB6R,GAAY,CAChB,MAAQpC,GAAckC,GAAO,QAAS,CAAClC,CAAI,CAAC,EAC5C,MAAQA,GAAckC,GAAO,QAAS,CAAClC,CAAI,CAAC,EAC5C,OAASA,GAAckC,GAAO,SAAU,CAAClC,CAAI,CAAC,EAC9C,OAAQ,CAACA,EAAWhtB,EAAYsJ,IAAc,CAC5C,MAAMiU,EAAO,CAACyP,EAAMhtB,CAAK,EACzB,OAAIsJ,IAAQ,QAAWiU,EAAK,KAAKjU,CAAG,EAC7B4lB,GAAO,SAAU3R,CAAI,CAC9B,EACA,KAAOyP,GAAckC,GAAO,OAAQ,CAAClC,CAAI,CAAC,EAC1C,IAAMA,GAAckC,GAAO,MAAO,CAAClC,CAAI,CAAC,EACxC,MAAQA,GAAckC,GAAO,QAAS,CAAClC,CAAI,CAAC,EAC5C,MAAQA,GAAckC,GAAO,QAAS,CAAClC,CAAI,CAAC,EAC5C,KAAOA,GAAckC,GAAO,OAAQ,CAAClC,CAAI,CAAC,EAC1C,MAAQA,GAAekC,GAAO,QAAS,CAAClC,GAAQrhB,GAAI,GAAG,EAAE,IAAI,CAAC,EAC9D,IAAMqhB,GAAckC,GAAO,MAAO,CAAClC,CAAI,CAAC,EACxC,IAAMA,GAAckC,GAAO,MAAO,CAAClC,CAAI,CAAC,EACxC,IAAMA,GAAckC,GAAO,MAAO,CAAClC,CAAI,CAAC,EACxC,IAAMA,GAAckC,GAAO,MAAO,CAAClC,CAAI,CAAC,EACxC,OAAQ,IAAIqC,IAAiBH,GAAO,SAAUG,CAAK,EACnD,SAAU,IAAIA,IAAiBH,GAAO,WAAYG,CAAK,CACzD,EAEA,SAAW,CAAC/xB,EAAKqwB,CAAK,IAAK,OAAO,QAAQyB,EAAS,EACjD,OAAO,eAAeD,GAAQ7xB,EAAK,CACjC,MAAAqwB,EACA,SAAU,GACV,WAAY,GACZ,aAAc,EAAA,CACf,EAGI,MAAMrQ,GAAkB6R,GAMxB,SAASG,GACdtC,EACAjgB,EACAwiB,EAIK,CACL,OAAQvC,EAAK,KAAA,CACX,IAAK,UACH,OAAOA,EAAK,MACd,IAAK,MACH,OAAIA,EAAK,OAAS,IAAY,KACvBjgB,EAAIigB,EAAK,IAAI,IAAM,OAAYjgB,EAAIigB,EAAK,IAAI,EAAI,KAEzD,IAAK,SAAU,CACb,MAAMjV,EAAOuX,GAAatC,EAAK,KAAMjgB,EAAKwiB,CAAI,EACxCvX,EAAQsX,GAAatC,EAAK,MAAOjgB,EAAKwiB,CAAI,EAChD,GACExX,IAAS,MACTC,IAAU,MACVD,IAAS,QACTC,IAAU,OAEV,OAAO,KAET,GACEgV,EAAK,KAAO,KACZA,EAAK,KAAO,MACZA,EAAK,KAAO,KACZA,EAAK,KAAO,MACZA,EAAK,KAAO,KACZA,EAAK,KAAO,KACZ,CACA,MAAM/b,EACJ,OAAO8G,GAAS,UAAY,OAAOC,GAAU,SACzCD,EAAOC,EACL,GACAD,EAAOC,EACL,EACA,EACJ,OAAOD,CAAI,EAAI,OAAOC,CAAK,EACzB,GACA,OAAOD,CAAI,EAAI,OAAOC,CAAK,EACzB,EACA,EACV,OAAQgV,EAAK,GAAA,CACX,IAAK,IACH,OAAO/b,IAAQ,EAAI,EAAI,EACzB,IAAK,KACH,OAAOA,IAAQ,EAAI,EAAI,EACzB,IAAK,IACH,OAAOA,EAAM,EAAI,EAAI,EACvB,IAAK,KACH,OAAOA,GAAO,EAAI,EAAI,EACxB,IAAK,IACH,OAAOA,EAAM,EAAI,EAAI,EACvB,IAAK,KACH,OAAOA,GAAO,EAAI,EAAI,CAAA,CAE5B,CACA,MAAMue,EAAO,OAAOzX,CAAI,EAClB0X,EAAO,OAAOzX,CAAK,EACzB,OAAQgV,EAAK,GAAA,CACX,IAAK,IACH,OAAOwC,EAAOC,EAChB,IAAK,IACH,OAAOD,EAAOC,EAChB,IAAK,IACH,OAAOD,EAAOC,EAChB,IAAK,IACH,OAAOA,IAAS,EAAI,KAAOD,EAAOC,EACpC,IAAK,IACH,OAAOA,IAAS,EAAI,KAAOD,EAAOC,CAAA,CAEtC,OAAO,IACT,CACA,IAAK,KAAM,CACT,MAAMtN,EAAO6K,EAAK,KAAK,YAAA,EAEvB,GAAIJ,GAAoBzK,CAAI,EAAG,CAC7B,GAAIpV,EAAIoV,CAAI,IAAM,OAAW,OAAOpV,EAAIoV,CAAI,EAC5C,MAAMuN,EAAO1C,EAAK,KAAK,CAAC,EACxB,GAAI0C,GAAQA,EAAK,OAAS,MAAO,CAC/B,MAAMC,EAAS,GAAGxN,CAAI,IAAIuN,EAAK,IAAI,GACnC,GAAI3iB,EAAI4iB,CAAM,IAAM,OAAW,OAAO5iB,EAAI4iB,CAAM,CAClD,CACA,OAAO,IACT,CACA,MAAMpS,EAAOyP,EAAK,KAAK,IAAKvX,GAAM6Z,GAAa7Z,EAAG1I,EAAKwiB,CAAI,CAAC,EAC5D,OAAQpN,EAAA,CACN,IAAK,QACH,OAAO5E,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,OAAOA,EAAK,CAAC,CAAC,EAAE,cAChB,KACN,IAAK,QACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,OAAOA,EAAK,CAAC,CAAC,EAAE,cAChB,KACN,IAAK,SACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,OAAOA,EAAK,CAAC,CAAC,EAAE,OAChB,KACN,IAAK,OACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,OAAOA,EAAK,CAAC,CAAC,EAAE,OAChB,KACN,IAAK,SAAU,CACb,GAAIA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAAW,OAAO,KACtD,MAAM3H,EAAM,OAAO2H,EAAK,CAAC,CAAC,EACpBvd,EAAQ,KAAK,IAAI,GAAI,OAAOud,EAAK,CAAC,CAAC,GAAK,GAAK,CAAC,EAC9CjU,EACJiU,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAC5B,OAAOA,EAAK,CAAC,CAAC,EACd,OACN,OAAOjU,IAAQ,OACXsM,EAAI,UAAU5V,EAAOA,EAAQsJ,CAAG,EAChCsM,EAAI,UAAU5V,CAAK,CACzB,CACA,IAAK,MACH,OAAOud,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,KAAK,IAAI,OAAOA,EAAK,CAAC,CAAC,CAAC,EACxB,KACN,IAAK,QACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,KAAK,MAAM,OAAOA,EAAK,CAAC,CAAC,CAAC,EAC1B,KACN,IAAK,QACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,KAAK,MAAM,OAAOA,EAAK,CAAC,CAAC,CAAC,EAC1B,KACN,IAAK,OACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OACnC,KAAK,KAAK,OAAOA,EAAK,CAAC,CAAC,CAAC,EACzB,KACN,IAAK,SACH,OAAIA,EAAK,KAAM9H,GAAMA,GAAM,IAAuB,EAAU,KACrD8H,EAAK,IAAI,MAAM,EAAE,KAAK,EAAE,EAEjC,IAAK,WAAY,CACf,UAAW9H,KAAK8H,EACd,GAAI9H,GAAM,KAAyB,OAAOA,EAE5C,OAAO,IACT,CACA,IAAK,cACL,IAAK,aACH,OAAO8H,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,QAAaA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAChF,OAAOA,EAAK,CAAC,CAAC,EAAE,WAAW,OAAOA,EAAK,CAAC,CAAC,CAAC,EAAI,EAAI,EAClD,KACN,IAAK,YACL,IAAK,WACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,QAAaA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAChF,OAAOA,EAAK,CAAC,CAAC,EAAE,SAAS,OAAOA,EAAK,CAAC,CAAC,CAAC,EAAI,EAAI,EAChD,KACN,IAAK,WACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,QAAaA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAChF,OAAOA,EAAK,CAAC,CAAC,EAAE,SAAS,OAAOA,EAAK,CAAC,CAAC,CAAC,EAAI,EAAI,EAChD,KACN,IAAK,OACH,OAAOA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,QAAaA,EAAK,CAAC,IAAM,MAAQA,EAAK,CAAC,IAAM,OAChFnH,GAAe,OAAOmH,EAAK,CAAC,CAAC,EAAG,OAAOA,EAAK,CAAC,CAAC,CAAC,EAAI,EAAI,EACvD,KACN,QAAS,CACP,IAAIqS,EACJ,GAAI,OAAOL,GAAS,WAClBK,EAAOL,EAAKpN,CAAI,UACPoN,aAAgB,IAAK,CAC9B,MAAMjR,EAAaiR,EAAK,IAAIpN,CAAI,EAChCyN,EAAO,OAAOtR,GAAU,WAAaA,EAAQA,GAAA,YAAAA,EAAO,IACtD,SAAWiR,GAAQ,OAAOA,GAAS,SAAU,CAC3C,MAAMjR,EAAciR,EAAapN,CAAI,EACrCyN,EAAO,OAAOtR,GAAU,WAAaA,EAAQA,GAAA,YAAAA,EAAO,IACtD,CACA,GAAIsR,EACF,OAAOA,EAAK,GAAGrS,CAAI,EAErB,MAAM,IAAI7gB,GAAqBylB,CAAI,CACrC,CAAA,CAEJ,CAAA,CAEJ,CCzzBO,MAAM0N,GAAkB,GAClBC,GAAkB,IAClBC,GAAgB,IAKtB,SAASC,GAAyBC,EAA+B,CACtE,MAAMnX,EAAiB,CAAA,EAEvB,SAASoX,EAAYlyB,EAAgB,CAOnC,GANIA,EAAE,SACJ8a,EAAK,KAAK9a,EAAE,OAAO,EAEjBA,EAAE,MACJmyB,EAAUnyB,EAAE,IAAI,EAEdA,EAAE,SACJ,UAAWoyB,KAASpyB,EAAE,SACpBkyB,EAAYE,CAAK,EAGjBpyB,EAAE,OACJkyB,EAAYlyB,EAAE,KAAK,CAEvB,CAEA,SAASmyB,EAAUnD,EAAW,CAC5B,GAAKA,IACDA,EAAK,OAAS,OAASA,EAAK,MAC9BlU,EAAK,KAAKkU,EAAK,IAAI,EAEjBA,EAAK,MAAMmD,EAAUnD,EAAK,IAAI,EAC9BA,EAAK,OAAOmD,EAAUnD,EAAK,KAAK,EAChCA,EAAK,MAAQ,MAAM,QAAQA,EAAK,IAAI,GACtC,UAAWE,KAAOF,EAAK,KACrBmD,EAAUjD,CAAG,CAGnB,CAEA,OAAAgD,EAAYD,CAAM,EACXnX,CACT,CAKO,SAASuX,GACdJ,EACAz2B,EACa,CACb,MAAM82B,EAAWN,GAAyBC,CAAM,EAC1CM,MAAiB,IACvB,UAAWpO,KAAQmO,EAAU,CAC3B,MAAME,EAAWC,GAA0BtO,EAAM3oB,CAAM,EACnDg3B,GACFD,EAAW,IAAIC,EAAS,QAAQ,CAEpC,CACA,OAAOD,CACT,CAKO,SAASG,GACdT,EACA12B,EACQ,SACR,MAAMo3B,EAAW,KAAK,IAAI,EAAGp3B,EAAM,kBAAoB,EAAE,EAEzD,GAAI02B,EAAO,OAAS,MAAO,CACzB,MAAM7V,EAAK6V,EAAO,IAAM,IACxB,GAAI7V,IAAO,IAAK,CACd,MAAMsU,GAAUtvB,EAAA6wB,EAAO,UAAP,YAAA7wB,EAAgB,cAC1BwxB,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,KAAK,gBAAkBg1B,CAAA,EAElC,GAAIkC,IAAW,IAAMr3B,EAAM,SACzB,UAAWsG,KAAOtG,EAAM,QACtB,GAAIsG,EAAI,cAAgB,GAAKA,EAAI,cAAc,CAAC,IAAM+wB,EAGpD,OADG/wB,EAAI,OAAS/F,GAAU,QAAUA,GAAU,WAAa,EAElD,EAAM62B,EAER,KAAK,IAAI,GAAK,EAAMA,CAAQ,EAIzC,MAAO,GACT,CACA,GAAIvW,IAAO,KAAOA,IAAO,MAAQA,IAAO,KAAOA,IAAO,KACpD,MAAO,KAET,GAAIA,IAAO,MAASA,IAAkB,KACpC,MAAO,IAET,GACEA,IAAO,QACPA,IAAO,YACPA,IAAO,eACPA,IAAO,YAEP,MAAO,IAEX,CAEA,GAAI6V,EAAO,OAAS,KAAM,CACxB,MAAMY,EAAc,KAAK,IAAI,IAAG5X,EAAAgX,EAAO,SAAP,YAAAhX,EAAe,SAAU,CAAC,EAE1D,OAAO,KAAK,IAAI,EAAK4X,EADL,GAC0B,CAC5C,CAEA,OAAIZ,EAAO,OAAS,OACXA,EAAO,OAAS,IAAO,IAGzB,EACT,CAKO,SAASa,GACdv3B,EACAw3B,EACAC,EACA92B,EAQA,OACA,MAAMy2B,EAAW,KAAK,IAAI,EAAGp3B,EAAM,kBAAoB,EAAE,EACzD,IAAI03B,EAAc,EAElB,UAAW,KAAKF,EACdE,GAAeP,GAA0B,EAAGn3B,CAAK,EAGnD,MAAM23B,EAAgB,KAAK,IAAI,EAAG,KAAK,MAAMP,EAAWM,CAAW,CAAC,EAC9DE,EAAaH,IAAY,QAAaA,EAAQ,OAAS,EACvDI,EACJD,GAAcD,EAAgB,EAC1BA,EAAgB,KAAK,KAAKA,CAAa,EAAInB,GAC3C,EAEA9R,EAAOoT,GAAgB93B,EAAOw3B,EAASA,EAASC,CAAO,EAE7D,GAAI/S,EAAM,CACR,MAAMqT,EAAUrT,EAAK,WAAa,QAC5BsT,EAAetT,EAAK,WAAa,cACjCuT,EAAiBvT,EAAK,mBAAqB,GAC3CwT,EACJD,GAAkBt3B,IAAU,QAAaA,EAAQ,EAC7C,KAAK,IAAIA,EAAOg3B,CAAa,EAC7BA,EAEN,IAAIQ,EAAO7B,GACX,OAAIyB,GACFI,GAAQ,EAAI3B,GACL,CACL,KAAA2B,EACA,KAAM,EACN,SAAU,YACV,UAAWzT,EAAK,MAAM,KACtB,iBAAkB,GAClB,gBAAiBkT,EAAaC,EAAmB,MAAA,GAGjDG,GAEFG,KADgBtyB,EAAA6e,EAAK,WAAL,YAAA7e,EAAe,SAAU,GACxBywB,GAAkB4B,EAAgB1B,GAC/C,CAACyB,GAAkBL,IACrBO,GAAQN,GAEH,CACL,KAAAM,EACA,KAAMD,EACN,SAAU,YACV,UAAWxT,EAAK,MAAM,KACtB,iBAAkBuT,EAClB,gBAAiBA,EAAiBJ,EAAmB,MAAA,IAIzDM,GAAQD,EAAgB3B,GAAkB2B,EAAgB1B,GACtD,CAACyB,GAAkBL,IACrBO,GAAQN,GAEH,CACL,KAAAM,EACA,KAAMD,EACN,SAAU,YACV,UAAWxT,EAAK,MAAM,KACtB,iBAAkBuT,EAClB,gBAAiBA,EAAiBJ,EAAmB,MAAA,EAEzD,CAGA,IAAIM,EAAOf,EAAWZ,GACtB,OAAIoB,IACFO,GAAQN,GAEH,CACL,KAAAM,EACA,KAAMR,EACN,SAAU,YACV,iBAAkB,EAAA,CAEtB,CAKO,SAASS,GACdp4B,EACAm1B,EACsD,CACtD,GAAI,CAACn1B,EAAM,SAAWA,EAAM,QAAQ,SAAW,EAAG,OAAO,KACzD,MAAMq3B,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,KAAK,YAAA,IAAkBg1B,EAAQ,YAAA,CAAY,EAEtD,GAAIkC,IAAW,GAAI,OAAO,KAE1B,IAAIgB,EAA6D,KAC7DC,EAAW,IAEf,UAAWhyB,KAAOtG,EAAM,QACtB,GAAIsG,EAAI,cAAgB,GAAKA,EAAI,cAAc,CAAC,IAAM+wB,EAAQ,CAC5D,MAAMkB,GAAQjyB,EAAI,MAAQ/F,GAAU,WAAa,EAC3Ci4B,GAAYlyB,EAAI,MAAQ/F,GAAU,UAAY,EAC9Ck4B,EAAOF,EAAO,EAAIC,EAAW,EAAI,EACnCC,EAAOH,IACTA,EAAWG,EACXJ,EAAO,CAAE,MAAO/xB,EAAK,SAAUiyB,GAAQC,CAAA,EAE3C,CAGF,OAAOH,CACT,CAKO,SAASK,GACdC,EACAC,EACoD,CACpD,MAAMC,EAAID,EAAe,OACnBE,EAAoB,CAAA,EACpBC,EAA8B,MAAM,KACxC,CAAE,OAAQF,CAAA,EACV,QAAU,GAAY,EAGxB,GAAI,CAACF,EAAK,aAAc,MAAO,CAAE,MAAAG,EAAO,aAAAC,CAAA,EAExC,QAAS1f,EAAI,EAAGA,EAAIsf,EAAK,aAAa,OAAQtf,IAAK,CACjD,MAAM2f,EAAKL,EAAK,aAAatf,CAAC,EACxB4f,EAAY5f,EAAI,EAChB6f,EAAUhC,GAA0B8B,EAAG,QAASJ,CAAc,EAC9DO,EAAWjC,GAA0B8B,EAAG,SAAUJ,CAAc,EAEtE,GAAIM,GAAWC,IACbL,EAAM,KAAK,CACT,OAAQI,EAAQ,SAChB,OAAQC,EAAS,SACjB,KAAMD,EAAQ,IAAI,KAClB,KAAMC,EAAS,IAAI,KACnB,GAAIH,EAAG,GACP,KAAMA,EAAG,KACT,mBAAoBC,CAAA,CACrB,EAIGD,EAAG,OAAS,QAAQ,CACtB,MAAMI,EACJF,EAAQ,WAAaD,EAAYE,EAAS,SAAWD,EAAQ,SAC/DH,EAAaE,CAAS,EAAE,IAAIG,CAAQ,CACtC,CAEJ,CAEA,MAAO,CAAE,MAAAN,EAAO,aAAAC,CAAA,CAClB,CAKO,SAASM,GACdV,EACAC,EACgC,CAChC,GAAID,EAAK,aAAeA,EAAK,YAAY,OAAS,EAChD,OAAOA,EAAK,YAGd,MAAMW,MAAgB,IAChBC,MAAe,IACrB,UAAWpF,KAAKyE,EACd,UAAWz4B,KAAKg0B,EAAE,QACZmF,EAAU,IAAIn5B,EAAE,KAAK,YAAA,CAAa,GACpCo5B,EAAS,IAAIp5B,EAAE,KAAK,YAAA,CAAa,EAEnCm5B,EAAU,IAAIn5B,EAAE,KAAK,YAAA,CAAa,EAItC,MAAMq5B,EAA2C,CAAA,EACjD,UAAWrF,KAAKyE,EACd,UAAWz4B,KAAKg0B,EAAE,QAAS,CACzB,MAAMkB,EAAQkE,EAAS,IAAIp5B,EAAE,KAAK,aAAa,EAC3C,GAAGg0B,EAAE,IAAI,IAAIh0B,EAAE,IAAI,GACnBA,EAAE,KACNq5B,EAAqB,KAAK,CACxB,KAAM,CAAE,KAAM,MAAO,KAAM,GAAGrF,EAAE,IAAI,IAAIh0B,EAAE,IAAI,EAAA,EAC9C,MAAAk1B,CAAA,CACD,CACH,CAGF,OAAOmE,CACT,CAKO,SAASC,GACdC,EACAd,EACAE,EACAa,EACY,CACZ,MAAMd,EAAIa,EAAa,OACjBE,EAA6B,CAAA,EAEnC,QAAS31B,EAAI,EAAGA,EAAI40B,EAAG50B,IAAK,CAC1B,MAAM41B,EAAgBH,EAAaz1B,CAAC,EAC9B61B,EAAalB,EAAeiB,CAAa,EACzCE,EAAeL,EAAa,MAAM,EAAGz1B,CAAC,EAEtC+1B,EAAalB,EAAM,KACtBmB,GACEA,EAAE,SAAWJ,GAAiBE,EAAa,SAASE,EAAE,MAAM,GAC5DA,EAAE,SAAWJ,GAAiBE,EAAa,SAASE,EAAE,MAAM,CAAA,EAGjE,IAAIC,EACAC,EACAtZ,EAAmB,IACnBuZ,EAAqB,QAEzB,GAAIJ,EACFnZ,EAAKmZ,EAAW,GAChBI,EAAWJ,EAAW,KAClBA,EAAW,SAAWH,GACxBM,EAAe,GAAGL,EAAW,IAAI,IAAIE,EAAW,IAAI,GAEpDE,EAAc,GADKtB,EAAeoB,EAAW,MAAM,EACvB,IAAI,IAAIA,EAAW,IAAI,KAEnDG,EAAe,GAAGL,EAAW,IAAI,IAAIE,EAAW,IAAI,GAEpDE,EAAc,GADKtB,EAAeoB,EAAW,MAAM,EACvB,IAAI,IAAIA,EAAW,IAAI,QAEhD,CACL,MAAMK,EAASV,GAAA,YAAAA,EAAqB,KACjCtgB,GAAMA,EAAE,MAAM,OAASygB,EAAW,MAErCI,EAAcG,EAASA,EAAO,QAAU,GAAGzB,EAAec,EAAa,CAAC,CAAC,EAAE,IAAI,MAC/ES,EAAeE,EAASA,EAAO,SAAW,GAAGP,EAAW,IAAI,MAC5DjZ,EAAKwZ,EAASA,EAAO,GAAK,IAC1BD,EAAWC,EAASA,EAAO,KAAO,OACpC,CAEAT,EAAe,KAAK,CAClB,KAAMQ,EACN,MAAON,EACP,OAAQ71B,EACR,QAASi2B,EACT,GAAArZ,EACA,SAAUsZ,CAAA,CACX,CACH,CAEA,OAAOP,CACT,CAMO,SAASU,GACdC,EACAC,EACAC,EACAhD,EACAiD,EACS,CACT,GAAI,CAACjD,GAAWA,EAAQ,SAAW,EAAG,MAAO,GAC7C,UAAWxzB,KAAKwzB,EAAS,CACvB,GAAIxzB,EAAE,YAAc,OAAQ,MAAO,GACnC,MAAMkxB,EAAUlxB,EAAE,QAClB,GAAI,CAACkxB,EAAS,MAAO,GACrB,IAAI8B,EAAWC,GAA0B/B,EAASsF,CAAS,EAC3D,GAAI,CAACxD,GAAYyD,EAAa,CAC5B,MAAMC,EAAKD,EAAY,KAAMjzB,GAAMA,EAAE,QAAU0tB,CAAO,EAClDwF,GAAMA,EAAG,KAAK,OAAS,QACzB1D,EAAWC,GAA0ByD,EAAG,KAAK,KAAMF,CAAS,EAEhE,CACA,GAAI,CAACxD,GAAYA,EAAS,WAAauD,EACrC,MAAO,EAEX,CACA,MAAO,EACT,CCleO,SAASI,GAAkBlE,EAAqBz2B,EAA8B,OACnF,GAAIy2B,EAAO,OAAS,OAClB,MAAO,GAGT,GAAIA,EAAO,OAAS,MAAO,CACzB,MAAM7V,EAAK6V,EAAO,IAAM,IACxB,GAAI7V,IAAO,QAAUA,IAAO,WAE1B,OADY,OAAO6V,EAAO,OAAU,SAAWA,EAAO,MAAQ,IACnD,WAAW,GAAG,EAAI,GAAK,GAGpC,IAAImE,EAAY,GAChB,GAAI56B,GAAUy2B,EAAO,QAAS,CAC5B,MAAMoE,EAAepE,EAAO,QAAQ,YAAA,EAC9BqE,EAAUD,EAAa,SAAS,GAAG,EACrCA,EAAa,MAAMA,EAAa,YAAY,GAAG,EAAI,CAAC,EACpDA,EAEJ,UAAW3G,KAAKl0B,EAAQ,CACtB,MAAME,EAAIg0B,EAAE,QAAQ,KAAM/hB,GAAQA,EAAI,KAAK,YAAA,IAAkB2oB,CAAO,EACpE,GAAI56B,EAAG,CACL06B,EAAY16B,EAAE,OAAS,GAAKA,EAAE,OAAS,GAAKA,EAAE,OAAS,EACvD,KACF,CACF,CACF,MAAW,OAAOu2B,EAAO,OAAU,WACjCmE,EAAY,IAGd,OAAIha,IAAO,KAAQA,IAAkB,KAC5Bga,EAAY,EAAI,EAElBA,EAAY,EAAI,CACzB,CAEA,OAAInE,EAAO,OAAS,QACJ7wB,EAAA6wB,EAAO,SAAP,YAAA7wB,EAAe,SAAU,IACvB,EAAI,EAAI,GAGtB6wB,EAAO,OAAS,OACX,GAGLA,EAAO,OAAS,OAASA,EAAO,OAAS,KACpC,GAGLA,EAAO,OAAS,MACX,EAGF,EACT,CAQO,SAASsE,GACdxD,EACAv3B,EAMA,CACA,GAAI,CAACu3B,GAAWA,EAAQ,SAAW,EACjC,MAAO,CACL,QAAS,CAAA,EACT,cAAe,GACf,aAAc,GACd,QAAS,CACP,cAAe,EACf,eAAgB,EAChB,cAAe,GACf,aAAc,GACd,uBAAwB,EACxB,UAAW,EAAA,CACb,EAIJ,MAAMyD,EAAgBzD,EAAQ,OAGxB0D,EAA2B,CAAA,EACjC,UAAWz2B,KAAK+yB,EACV/yB,EAAE,OAAS,OAAS,MAAM,QAAQA,EAAE,QAAQ,EAC9Cy2B,EAAU,KAAK,GAAGz2B,EAAE,QAAQ,EAE5By2B,EAAU,KAAKz2B,CAAC,EAKpB,MAAM02B,MAAe,IACfC,EAAkC,CAAA,EAExC,UAAW32B,KAAKy2B,EACd,GAAIz2B,EAAE,QAAS,CACb,MAAM2xB,EAAS3xB,EAAE,QAAQ,YAAA,EACpB02B,EAAS,IAAI/E,CAAM,GACtB+E,EAAS,IAAI/E,EAAQ,EAAE,EAEzB+E,EAAS,IAAI/E,CAAM,EAAG,KAAK3xB,CAAC,CAC9B,MACE22B,EAAiB,KAAK32B,CAAC,EAK3B,SAAW,CAAC2xB,EAAQiF,CAAU,IAAKF,EAAS,UAAW,CACrD,MAAMG,EAAgBC,GAAyBF,CAAU,EACzD,GAAIC,EACF,MAAO,CACL,QAAS,CAAA,EACT,cAAe,GACf,aAAc,GACd,QAAS,CACP,cAAAL,EACA,eAAgB,EAChB,cAAe,GACf,aAAc,GACd,oBAAqB,4BAA4B7E,CAAM,MAAMkF,CAAa,GAC1E,uBAAwBL,EACxB,UAAW,EAAA,CACb,CAGN,CAGA,MAAMO,EAAkC,CAAA,EACxC,IAAIC,EAAkB,EAEtB,SAAW,CAAA,CAAGJ,CAAU,IAAKF,EAAS,UAAW,CAC/C,MAAMO,EAASC,GAAmBN,CAAU,EAC5CI,GAAmBJ,EAAW,OAASK,EAAO,OAC9CF,EAAiB,KAAK,GAAGE,CAAM,CACjC,CAEAF,EAAiB,KAAK,GAAGJ,CAAgB,EAGzC,MAAMQ,EAAmBJ,EAAiB,IAAK/2B,GAAMo3B,GAAgBp3B,CAAC,CAAC,EAAE,KAAK,GAAG,EACjF+2B,EAAiB,KAAK,CAACtf,EAAGnP,IAAM,CAC9B,MAAM+uB,EAAQlB,GAAkB1e,EAAGjc,CAAM,EACnC87B,EAAQnB,GAAkB7tB,EAAG9M,CAAM,EACzC,OAAO67B,EAAQC,CACjB,CAAC,EACD,MAAMC,EAAcR,EAAiB,IAAK/2B,GAAMo3B,GAAgBp3B,CAAC,CAAC,EAAE,KAAK,GAAG,EACtEw3B,EAAYL,IAAqBI,EAEvC,MAAO,CACL,QAASR,EACT,cAAe,GACf,aAAcA,EAAiB,SAAW,EAC1C,QAAS,CACP,cAAAP,EACA,eAAgBO,EAAiB,OACjC,cAAe,GACf,aAAcA,EAAiB,SAAW,EAC1C,uBAAwBC,EACxB,UAAAQ,CAAA,CACF,CAEJ,CAEA,SAASV,GAAyB/D,EAAuC,CACvE,IAAI0E,EAAY,GACZC,EAAe,GACnB,MAAMC,EAAwB,CAAA,EAC9B,IAAIC,EAAsD,KACtDC,EAAsD,KACtDC,EAAyB,KAE7B,UAAW93B,KAAK+yB,EAAS,CAMvB,GALI/yB,EAAE,OAAS,SACTA,EAAE,SAAW,KAAMy3B,EAAY,IAC/Bz3B,EAAE,SAAW,KAAO03B,EAAe,KAGrC13B,EAAE,OAAS,MAAO,CACpB,MAAMoc,EAAKpc,EAAE,IAAM,IACbc,EAAMd,EAAE,MAEVoc,IAAO,KAAOtb,IAAQ,MAAQA,IAAQ,QACxC62B,EAAe,KAAK72B,CAAG,EAGrB,OAAOA,GAAQ,WACbsb,IAAO,KACL,CAACwb,GAAc92B,EAAM82B,EAAW,KAAQ92B,IAAQ82B,EAAW,KAAO,CAACA,EAAW,UAChFA,EAAa,CAAE,IAAA92B,EAAK,OAAQ,EAAA,GAErBsb,IAAO,MACZ,CAACwb,GAAc92B,EAAM82B,EAAW,OAClCA,EAAa,CAAE,IAAA92B,EAAK,OAAQ,EAAA,GAErBsb,IAAO,KACZ,CAACyb,GAAc/2B,EAAM+2B,EAAW,KAAQ/2B,IAAQ+2B,EAAW,KAAO,CAACA,EAAW,UAChFA,EAAa,CAAE,IAAA/2B,EAAK,OAAQ,EAAA,GAErBsb,IAAO,OACZ,CAACyb,GAAc/2B,EAAM+2B,EAAW,OAClCA,EAAa,CAAE,IAAA/2B,EAAK,OAAQ,EAAA,GAIpC,CAEA,GAAId,EAAE,OAAS,MAAQ,CAACA,EAAE,MAAO,CAC/B,GAAI,CAACA,EAAE,QAAUA,EAAE,OAAO,SAAW,EACnC,MAAO,mBAET,MAAM+3B,EAAa,IAAI,IAAI/3B,EAAE,MAAM,EACnC,GAAI,CAAC83B,EACHA,EAAQC,MACH,CACL,MAAMC,EAAwB,IAAI,IAAI,CAAC,GAAGF,CAAK,EAAE,OAAQG,GAAMF,EAAW,IAAIE,CAAC,CAAC,CAAC,EACjF,GAAID,EAAY,OAAS,EACvB,MAAO,oDAETF,EAAQE,CACV,CACF,CACF,CAEA,GAAIP,GAAaC,EACf,MAAO,sCAGT,GAAID,IAAcE,EAAe,OAAS,GAAKC,GAAcC,GAC3D,MAAO,6CAGT,GAAIF,EAAe,OAAS,EAAG,CAC7B,MAAMO,EAAQP,EAAe,CAAC,EAC9B,QAASl8B,EAAI,EAAGA,EAAIk8B,EAAe,OAAQl8B,IACzC,GAAIk8B,EAAel8B,CAAC,IAAMy8B,EACxB,MAAO,gCAAgCA,CAAK,QAAQP,EAAel8B,CAAC,CAAC,GAG3E,CAEA,GAAIk8B,EAAe,OAAS,IAAMC,GAAcC,GAAa,CAC3D,MAAMM,EAAQR,EAAe,CAAC,EAC9B,GAAI,OAAOQ,GAAU,SAAU,CAC7B,GAAIP,IACEA,EAAW,OAASO,GAASP,EAAW,IAAMO,EAAQP,EAAW,KACnE,MAAO,kBAAkBO,CAAK,yBAAyBP,EAAW,OAAS,IAAM,IAAI,IAAIA,EAAW,GAAG,GAG3G,GAAIC,IACEA,EAAW,OAASM,GAASN,EAAW,IAAMM,EAAQN,EAAW,KACnE,MAAO,kBAAkBM,CAAK,yBAAyBN,EAAW,OAAS,IAAM,IAAI,IAAIA,EAAW,GAAG,EAG7G,CACF,CAEA,GAAIF,EAAe,OAAS,GAAKG,EAAO,CACtC,MAAMK,EAAQR,EAAe,CAAC,EAC9B,GAAI,CAACG,EAAM,IAAIK,CAAK,EAClB,MAAO,kBAAkBA,CAAK,yBAElC,CAEA,GAAIP,GAAcC,EAAY,CAC5B,GAAID,EAAW,IAAMC,EAAW,IAC9B,MAAO,eAAeD,EAAW,GAAG,gCAAgCC,EAAW,GAAG,GAEpF,GAAID,EAAW,MAAQC,EAAW,MAAQD,EAAW,QAAUC,EAAW,QACxE,MAAO,gCAAgCD,EAAW,GAAG,EAEzD,CAEA,OAAO,IACT,CAEA,SAASV,GAAmBnE,EAAuC,CACjE,MAAMtyB,EAAwB,CAAA,EACxB23B,MAAqB,IAE3B,IAAIC,EAAuB,GACvBC,EAEJ,UAAWt4B,KAAK+yB,EACd,GAAI/yB,EAAE,OAAS,QAAUA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAAcA,EAAE,QAAU,MAAQA,EAAE,QAAU,OAAW,CACzGq4B,EAAuB,GACvBC,EAAsBt4B,EAAE,MACxB,KACF,CAGF,IAAIu4B,EAA0E,KAC1EC,EAA0E,KAE9E,UAAWx4B,KAAK+yB,EACd,GAAI/yB,EAAE,OAAS,OAAS,OAAOA,EAAE,OAAU,SAAU,CACnD,MAAMoc,EAAKpc,EAAE,IAAM,IACbc,EAAMd,EAAE,MACVoc,IAAO,KACL,CAACmc,GAAaz3B,EAAMy3B,EAAU,KAAQz3B,IAAQy3B,EAAU,KAAO,CAACA,EAAU,UAC5EA,EAAY,CAAE,IAAAz3B,EAAK,OAAQ,GAAM,OAAQd,CAAA,GAElCoc,IAAO,MACZ,CAACmc,GAAaz3B,EAAMy3B,EAAU,OAChCA,EAAY,CAAE,IAAAz3B,EAAK,OAAQ,GAAO,OAAQd,CAAA,GAEnCoc,IAAO,KACZ,CAACoc,GAAa13B,EAAM03B,EAAU,KAAQ13B,IAAQ03B,EAAU,KAAO,CAACA,EAAU,UAC5EA,EAAY,CAAE,IAAA13B,EAAK,OAAQ,GAAM,OAAQd,CAAA,GAElCoc,IAAO,OACZ,CAACoc,GAAa13B,EAAM03B,EAAU,OAChCA,EAAY,CAAE,IAAA13B,EAAK,OAAQ,GAAO,OAAQd,CAAA,EAGhD,CAGF,UAAWA,KAAK+yB,EAAS,CACvB,MAAM0F,EAAMrB,GAAgBp3B,CAAC,EAC7B,GAAI,CAAAo4B,EAAe,IAAIK,CAAG,GAItB,EAAAz4B,EAAE,OAAS,QAAUA,EAAE,SAAW,IAASq4B,IAI3C,EAAAr4B,EAAE,OAAS,MAAQ,CAACA,EAAE,OAASq4B,GAAwB,MAAM,QAAQr4B,EAAE,MAAM,GAAKA,EAAE,OAAO,SAASs4B,CAAmB,GAI3H,IAAIt4B,EAAE,OAAS,OAAS,OAAOA,EAAE,OAAU,SAAU,CACnD,MAAMoc,EAAKpc,EAAE,IAAM,IACnB,GAAIoc,IAAO,KAAOA,IAAO,MACvB,GAAImc,GAAav4B,IAAMu4B,EAAU,OAC/B,kBAEOnc,IAAO,KAAOA,IAAO,OAC1Boc,GAAax4B,IAAMw4B,EAAU,OAC/B,QAGN,CAEAJ,EAAe,IAAIK,CAAG,EACtBh4B,EAAO,KAAKT,CAAC,EACf,CAEA,OAAOS,CACT,CAEA,SAAS22B,GAAgBp3B,EAAwB,CAC/C,MAAO,GAAGA,EAAE,IAAI,IAAIA,EAAE,SAAW,EAAE,IAAIA,EAAE,QAAU,EAAE,IAAIA,EAAE,IAAM,EAAE,IAAI,OAAOA,EAAE,OAAS,EAAE,CAAC,IAAIA,EAAE,OAAS,EAAE,IAAI,KAAK,UAAUA,EAAE,QAAU,EAAE,CAAC,EACjJ,CAKO,SAAS04B,GACd3F,EACA4F,EACe,CACf,MAAMl4B,EAAS,CAAC,GAAGsyB,CAAO,EACpB6F,EAAal9B,GAAcA,EAAE,YAAA,EAC7Bm9B,EAAen9B,GAAc,CACjC,MAAMmG,EAAMnG,EAAE,YAAY,GAAG,EAC7B,OAAOmG,GAAO,EAAInG,EAAE,MAAMmG,EAAM,CAAC,EAAE,YAAA,EAAgBnG,EAAE,YAAA,CACvD,EAEMo9B,EAAqBnrB,GAAqB,CAC9C,MAAMorB,EAAUH,EAAUjrB,CAAG,EACvB2oB,EAAUuC,EAAYlrB,CAAG,EAC/B,UAAW3N,KAAK+yB,EACd,GACE/yB,EAAE,OAAS,QACVA,EAAE,KAAO,KAAQA,EAAE,KAAkB,MAAQA,EAAE,KAAO,SACvDA,EAAE,SACFA,EAAE,QAAU,MACZA,EAAE,QAAU,OACZ,CACA,MAAMg5B,EAAQJ,EAAU54B,EAAE,OAAO,EAC3Bi5B,EAAQJ,EAAY74B,EAAE,OAAO,EACnC,GAAIg5B,IAAUD,GAAWE,IAAUF,GAAWC,IAAU1C,EACtD,OAAOt2B,EAAE,KAEb,CAGJ,EAEA,UAAW4U,KAAK+jB,EAAa,CAI3B,GAHI/jB,EAAE,OAAS,SAAWA,EAAE,OAAS,QAGjCA,EAAE,KAAO,KAAQA,EAAE,KAAkB,KACvC,SAGF,MAAMskB,EAAUJ,EAAkBlkB,EAAE,OAAO,EAU3C,GATIskB,IAAY,QACdz4B,EAAO,KAAK,CACV,KAAM,MACN,QAASmU,EAAE,SACX,GAAI,IACJ,MAAOskB,CAAA,CACR,EAGCtkB,EAAE,OAAS,QAAS,CACtB,MAAMukB,EAAWL,EAAkBlkB,EAAE,QAAQ,EACzCukB,IAAa,QACf14B,EAAO,KAAK,CACV,KAAM,MACN,QAASmU,EAAE,QACX,GAAI,IACJ,MAAOukB,CAAA,CACR,CAEL,CACF,CAEA,OAAO14B,CACT,CChZO,MAAM24B,EAAyC,CAMpD,YAAYh0B,EAAmC,CALtCpG,EAAA,YAAO,QACRA,EAAA,sBACAA,EAAA,sBACAA,EAAA,oBAGN,KAAK,eAAgBoG,GAAA,YAAAA,EAAS,gBAAiBysB,GAC/C,KAAK,eAAgBzsB,GAAA,YAAAA,EAAS,gBAAiB0sB,GAC/C,KAAK,aAAc1sB,GAAA,YAAAA,EAAS,cAAe2sB,EAC7C,CAEA,SAASmC,EAAsC,SAC7C,MAAMC,EAA8B,CAClCD,EAAK,MACL,KAAI9yB,EAAA8yB,EAAK,eAAL,YAAA9yB,EAAmB,IAAKwT,GAAMA,EAAE,SAAU,CAAA,CAAC,EAE3Cwf,EAAID,EAAe,OAGnBkF,EAAW9C,GAAwBrC,EAAK,QAASC,CAAc,EACrE,GAAIkF,EAAS,cACX,MAAO,CACL,KAAM,CAAE,GAAGnF,EAAM,QAAS,CAAA,CAAC,EAC3B,cAAeC,EACf,QAAS,KACT,cAAe,GACf,aAAckF,EAAS,OAAA,EAI3B,IAAIC,EAAiBD,EAAS,QAC1BE,EAAeF,EAAS,QAG5B,GAAInF,EAAK,cAAgBA,EAAK,aAAa,OAAS,EAAG,CACrD,MAAMsF,EAAiBd,GACrBY,EACApF,EAAK,YAAA,EAEP,GAAIsF,EAAe,OAASF,EAAe,OAAQ,CACjD,MAAMG,EAAWlD,GACfiD,EACArF,CAAA,EAEF,GAAIsF,EAAS,cACX,MAAO,CACL,KAAM,CAAE,GAAGvF,EAAM,QAAS,CAAA,CAAC,EAC3B,cAAeC,EACf,QAAS,KACT,cAAe,GACf,aAAcsF,EAAS,OAAA,EAG3BH,EAAiBG,EAAS,QAC1BF,EAAeE,EAAS,OAC1B,CACF,CAGA,GAAIrF,GAAK,GAAK,CAACF,EAAK,cAAgBA,EAAK,aAAa,SAAW,EAAG,CAClE,MAAMwF,MAAoB,IAC1BA,EAAc,IAAI,EAAGJ,CAAc,EAEnC,MAAMK,EAAW7G,GACfoB,EAAK,MACLoF,EACApF,EAAK,QACLA,EAAK,KAAA,EAGP,MAAO,CACL,KAAM,CACJ,GAAGA,EACH,QAASoF,CAAA,EAEX,cAAe,CAACpF,EAAK,KAAK,EAC1B,QAAS,CACP,UAAWyF,EAAS,KACpB,cAAeA,EAAS,KACxB,UAAW,CAACzF,EAAK,MAAM,IAAI,EAC3B,mBAAoBwF,EACpB,aAAc,CAAA,EACd,eAAgB,CAACC,EAAS,QAAQ,EAClC,gBAAiB,CAACA,EAAS,SAAS,EACpC,iBAAkBA,EAAS,iBAC3B,gBAAiBA,EAAS,eAAA,EAE5B,cAAe,GACf,aAAcJ,EAAa,aAC3B,aAAAA,EACA,iBAAkBI,EAAS,iBAC3B,gBAAiBA,EAAS,eAAA,CAE9B,CAGA,MAAMC,EAAaC,GAAgBP,CAAc,EAC3CQ,EAAkBC,GAA8BH,CAAU,EAG1DI,MAAyB,IACzBC,EAA8B,CAAA,EAEpC,QAASx+B,EAAI,EAAGA,EAAI24B,EAAG34B,IACrBu+B,EAAmB,IAAIv+B,EAAG,EAAE,EAG9B,UAAWw2B,KAAU6H,EAAiB,CACpC,MAAMI,EAAO7H,GAA0BJ,EAAQkC,CAAc,EAC7D,GAAI+F,EAAK,OAAS,EAAG,CACnB,MAAMC,EAASD,EAAK,OAAA,EAAS,OAAO,MAChCC,IAAW,UACblf,EAAA+e,EAAmB,IAAIG,CAAM,IAA7B,MAAAlf,EAAgC,KAAKgX,GAEzC,MACEgI,EAAa,KAAKhI,CAAM,CAE5B,CAGA,GAAImC,GAAK,GAAK,CAACF,EAAK,cAAgBA,EAAK,aAAa,SAAW,EAAG,CAClE,MAAMkG,EAAOtH,GACXqB,EAAe,CAAC,EAChB6F,EAAmB,IAAI,CAAC,GAAK,CAAA,CAAC,EAEhC,MAAO,CACL,KAAA9F,EACA,cAAeC,EACf,QAAS,CACP,UAAWiG,EAAK,KAChB,cAAeA,EAAK,KACpB,UAAW,CAACjG,EAAe,CAAC,EAAE,IAAI,EAClC,mBAAA6F,EACA,aAAAC,EACA,eAAgB,CAACG,EAAK,QAAQ,EAC9B,gBAAiB,CAACA,EAAK,SAAS,CAAA,CAClC,CAEJ,CAEA,KAAM,CAAE,MAAA/F,EAAO,aAAAC,CAAA,EAAiBL,GAAeC,EAAMC,CAAc,EAa7DkG,MAAS,IAGf,QAAS5+B,EAAI,EAAGA,EAAI24B,EAAG34B,IACrB,GAAI64B,EAAa74B,CAAC,EAAE,OAAS,EAAG,CAC9B,MAAM6+B,EAAczE,GAClB1B,EAAe14B,CAAC,EAChBA,EACA04B,EACAD,EAAK,QACLA,EAAK,WAAA,EAEDqG,EAAoBD,EACtBpG,EAAK,QAAS,IAAK10B,GAAM,CACvB,MAAMmO,EAAMnO,EAAE,SAAW,GACnBg7B,GAAW7sB,EAAI,SAAS,GAAG,EAC7BA,EAAI,MAAMA,EAAI,YAAY,GAAG,EAAI,CAAC,EAClCA,EACJ,MAAO,CAAE,GAAGnO,EAAG,QAASg7B,EAAA,CAC1B,CAAC,EACD,OAEEJ,EAAOtH,GACXqB,EAAe14B,CAAC,EAChBu+B,EAAmB,IAAIv+B,CAAC,GAAK,CAAA,EAC7B8+B,EACAD,EAAcpG,EAAK,MAAQ,MAAA,EAEvBvvB,EAAO,GAAKlJ,EAClB4+B,EAAG,IAAI11B,EAAM,CACX,MAAO,CAAClJ,CAAC,EACT,KAAM2+B,EAAK,KACX,KAAMA,EAAK,KACX,UAAW,CAACA,EAAK,QAAQ,EACzB,WAAY,CAACA,EAAK,SAAS,EAC3B,UAAW,CAAA,EACX,iBAAkBA,EAAK,iBACvB,gBAAiBA,EAAK,eAAA,CACvB,CACH,CAIF,MAAMK,EAAe,GAAKrG,EAC1B,QAASn4B,EAAO,EAAGA,GAAQm4B,EAAGn4B,IAC5B,QAAS0I,EAAO,EAAGA,EAAO81B,EAAc91B,IACtC,GAAI+1B,GAAU/1B,CAAI,IAAM1I,EAExB,QAAS+E,EAAU,EAAGA,EAAUozB,EAAGpzB,IAAW,CAC5C,GAAK,EAAA2D,EAAQ,GAAK3D,GAAiB,SAEnC,MAAM25B,EAAWh2B,EAAQ,GAAK3D,EACxB45B,EAAYP,EAAG,IAAIM,CAAQ,EACjC,GAAI,CAACC,EAAW,SAEhB,IAAIC,EAAgB,GACpB,UAAWC,MAAOxG,EAAatzB,CAAO,EACpC,GAAK,EAAA25B,EAAY,GAAKG,IAAa,CACjCD,EAAgB,GAChB,KACF,CAEF,GAAI,CAACA,EAAe,SAEpB,MAAME,EAAU,KAAK,iBACnBH,EAAU,KACVzG,EAAenzB,CAAO,EACtBA,EACAqzB,EACAuG,EAAU,MACVZ,EAAmB,IAAIh5B,CAAO,GAAK,CAAA,CAAC,EAGhCg6B,GAAYJ,EAAU,KAAOG,EAAQ,SACrCE,GAAWZ,EAAG,IAAI11B,CAAI,EAC5B,IAAIu2B,GAAW,GAEXC,GAAqBH,GACrBI,GAAoBH,GAAWA,GAAS,KAAO,EAEnD,MAAMI,GAA0BT,EAAU,mBAAqB,GACzDU,IAAyBL,IAAA,YAAAA,GAAU,oBAAqB,GAc9D,GAXIh/B,IAASm4B,GAAKF,EAAK,SAAWA,EAAK,QAAQ,OAAS,IAClD,CAACmH,IAA2BN,EAAQ,QAAU,IAChDI,IACEJ,EAAQ,QAAU,KAAK,KAAKA,EAAQ,OAAO,EAAI,KAAK,aAEpDE,IAAY,CAACK,IAA0BL,GAAS,KAAO,IACzDG,IACEH,GAAS,KAAO,KAAK,KAAKA,GAAS,IAAI,EAAI,KAAK,cAIlD,CAACA,GACHC,GAAW,WAIPG,IAA2B,CAACC,GAC9BJ,GAAW,WACF,CAACG,IAA2BC,GACrCJ,GAAW,OACN,CACL,MAAMK,GACJX,EAAU,UAAU,OAAQlL,IAAMA,KAAM,WAAW,EAAE,QACpDqL,EAAQ,WAAa,YAAc,EAAI,GACpCS,GAAqBP,GAAS,UAAU,OAC3CvL,IAAMA,KAAM,WAAA,EACb,OAEF,GACE6L,GAAsBC,IACtBL,IAAsBC,GAAoB,IAE1CF,GAAW,WACFK,GAAsBC,GAC/BN,GAAW,WACFC,GAAqBC,GAAoB,IAClDF,GAAW,WACFE,GAAoBD,GAAqB,IAClDD,GAAW,OACN,CAEL,MAAMO,GAA0Bb,EAAU,MAAM,CAAC,IAAM,EACjDc,GAAyBT,GAAS,MAAM,CAAC,IAAM,EACrD,GAAIQ,IAA2B,CAACC,GAC9BR,GAAW,WACF,CAACO,IAA2BC,GACrCR,GAAW,OACN,CACL,MAAMS,GAAsBf,EAAU,MAAM,OACzC/4B,IAAQA,GAAMb,CAAA,EACf,OACI46B,GAAqBX,GAAS,MAAM,OACxC,CAACp5B,GAAKpG,KAAMoG,GAAMpG,EAAA,EAClB,OACEkgC,GAAsBC,KACxBV,GAAW,GAEf,CACF,CACF,CAGEA,IACFb,EAAG,IAAI11B,EAAM,CACX,MAAO,CAAC,GAAGi2B,EAAU,MAAO55B,CAAO,EACnC,KAAMg6B,GACN,KAAMD,EAAQ,QACd,UAAW,CAAC,GAAGH,EAAU,UAAWG,EAAQ,QAAQ,EACpD,WAAY,CAAC,GAAGH,EAAU,WAAYG,EAAQ,SAAS,EACvD,UAAW,CAAC,GAAGH,EAAU,UAAWG,EAAQ,WAAW,EACvD,iBAAkBH,EAAU,iBAC5B,gBAAiBA,EAAU,eAAA,CAC5B,CAEL,CAKJ,MAAMiB,GAAY,GAAKzH,GAAK,EACtB0H,EAAYzB,EAAG,IAAIwB,CAAQ,EAEjC,IAAI5G,EACA8G,EACAC,EACAC,EACAC,EAEAJ,GACF7G,EAAe6G,EAAU,MACzBC,EAAcD,EAAU,KACxBE,EAAcF,EAAU,KACxBG,EAAmBH,EAAU,UAC7BI,EAAoBJ,EAAU,aAE9B7G,EAAe,MAAM,KAAK,CAAE,OAAQb,GAAK,CAAC+H,EAAG1gC,IAAMA,CAAC,EACpDsgC,EAAc,OACdC,EAAc,IACdC,EAAmB,MAAM,KAAK,CAAE,OAAQ7H,CAAA,EAAK,IAAM,WAAW,EAC9D8H,EAAoB,MAAM,KAAK,CAAE,OAAQ9H,CAAA,EAAK,IAAA,EAAe,GAG/D,MAAMgI,EAAgBnH,EAAa,IAAKpzB,GAAQsyB,EAAetyB,CAAG,CAAC,EAC7DszB,EAAiBH,GACrBC,EACAd,EACAE,EACAH,EAAK,YAAA,EAEDa,EAAuBH,GAC3BV,EACAC,CAAA,EAGIkI,GAAsBP,GAAA,YAAAA,EAAW,oBAAqB,GACtDQ,EACJD,GAAuBnI,EAAK,SAAWA,EAAK,QAAQ,OAAS,GAAK8H,EAAc,EAC5EA,EAAc,KAAK,KAAKA,CAAW,EAAI,KAAK,YAC5C,OAEN,MAAO,CACL,KAAM,CACJ,GAAG9H,EACH,MAAOkI,EAAc,CAAC,EACtB,aAAcjH,EACd,YAAaJ,EACb,QAASuE,EACT,iBAAkB+C,CAAA,EAEpB,cAAAD,EACA,QAAS,CACP,UAAWL,EACX,cAAeC,EACf,UAAWI,EAAc,IAAK1M,GAAMA,EAAE,IAAI,EAC1C,mBAAAsK,EACA,aAAAC,EACA,eAAgBgC,EAChB,gBAAiBC,EACjB,iBAAkBG,EAClB,gBAAiBC,CAAA,EAEnB,cAAe,GACf,aAAc/C,EAAa,aAC3B,aAAAA,EACA,iBAAkB8C,EAClB,gBAAiBC,CAAA,CAErB,CAEQ,iBACNC,EACAC,EACAC,EACApI,EACAqI,EACAC,EAOA,CACA,MAAMhK,EAAW,KAAK,IAAI,EAAG6J,EAAU,kBAAoB,EAAE,EAC7D,IAAII,EAAY,EAChB,UAAW58B,KAAK28B,EACdC,GAAalK,GAA0B1yB,EAAGw8B,CAAS,EAGrD,MAAMK,EAKA,CAAA,EAEN,UAAWC,KAAQzI,EACjB,GACEyI,EAAK,SAAWL,GAChBC,EAAoB,SAASI,EAAK,MAAM,EACxC,CACA,MAAMC,EAAWpJ,GAAkB6I,EAAWM,EAAK,IAAI,EACvDD,EAAW,KAAK,CACd,KAAAC,EACA,QAASA,EAAK,KACd,SAAUA,EAAK,KACf,SAAAC,CAAA,CACD,CACH,SACED,EAAK,SAAWL,GAChBC,EAAoB,SAASI,EAAK,MAAM,EACxC,CACA,MAAMC,EAAWpJ,GAAkB6I,EAAWM,EAAK,IAAI,EACvDD,EAAW,KAAK,CACd,KAAAC,EACA,QAASA,EAAK,KACd,SAAUA,EAAK,KACf,SAAAC,CAAA,CACD,CACH,CAGF,GAAIF,EAAW,SAAW,EAAG,CAC3B,MAAMG,EAAWT,GAAa,EAAM5J,EAAW,IACzCsK,EAAU,KAAK,IAAI,EAAG,KAAK,MAAMV,EAAY5J,EAAWiK,CAAS,CAAC,EAClEM,EAAyB,CAC7B,OAAQR,EAAoB,CAAC,EAC7B,OAAQD,EACR,KAAM,GACN,KAAM,GACN,GAAI,IACJ,KAAM,QACN,mBAAoBA,CAAA,EAEtB,MAAO,CACL,SAAAO,EACA,QAAAC,EACA,SAAU,YACV,YAAaC,CAAA,CAEjB,CAEAL,EAAW,KAAK,CAACplB,EAAGnP,IAAM,CACxB,MAAM60B,EAAQ1lB,EAAE,SAAYA,EAAE,SAAS,SAAW,EAAI,EAAK,EACrD2lB,EAAQ90B,EAAE,SAAYA,EAAE,SAAS,SAAW,EAAI,EAAK,EAC3D,OAAO60B,EAAQC,CACjB,CAAC,EAED,MAAMC,EAAWR,EAAW,CAAC,EAC7B,GAAIQ,EAAS,UAAYA,EAAS,SAAS,SAAU,CACnD,MAAMC,EAAW,KAAK,cAAgB,EAAI,KAAK,YACzCN,EAAWT,EAAYe,EACvBL,EAAU,KAAK,IAAI,EAAG,KAAK,MAAMV,EAAYK,CAAS,CAAC,EAC7D,MAAO,CACL,SAAAI,EACA,QAAAC,EACA,SAAU,YACV,UAAWI,EAAS,SAAS,MAAM,KACnC,YAAaA,EAAS,IAAA,CAE1B,CAEA,GAAIA,EAAS,UAAY,CAACA,EAAS,SAAS,SAAU,CACpD,MAAME,EAAW,KAAK,IAAI,EAAG,KAAK,IAAI,GAAI,KAAK,MAAM5K,EAAW,EAAE,CAAC,CAAC,EAC9D2K,EAAW,KAAK,cAAgBC,EAAW,KAAK,cAChDP,EAAWT,EAAYe,EACvBL,EAAU,KAAK,IAAI,EAAG,KAAK,MAAMV,EAAYgB,EAAWX,CAAS,CAAC,EACxE,MAAO,CACL,SAAAI,EACA,QAAAC,EACA,SAAU,YACV,UAAWI,EAAS,SAAS,MAAM,KACnC,YAAaA,EAAS,IAAA,CAE1B,CAEA,MAAML,EAAWT,GAAa,EAAM5J,EAAW,IACzCsK,EAAU,KAAK,IACnB,EACA,KAAK,MACHV,EAAY,KAAK,IAAI,EAAG,KAAK,MAAM5J,EAAW,EAAG,CAAC,EAAIiK,CAAA,CACxD,EAEF,MAAO,CACL,SAAAI,EACA,QAAAC,EACA,SAAU,YACV,YAAaI,EAAS,IAAA,CAE1B,CACF,CAEA,SAAS3C,GAAU53B,EAAmB,CACpC,IAAItE,EAAQ,EACRsC,EAAMgC,EACV,KAAOhC,EAAM,GACXtC,GAASsC,EAAM,EACfA,IAAQ,EAEV,OAAOtC,CACT,CCphBO,MAAMg/B,EAAyC,CAA/C,cACIx+B,EAAA,YAAO,aAEhB,SAASk1B,EAAsC,WAC7C,MAAMC,EAA8B,CAClCD,EAAK,MACL,KAAI9yB,EAAA8yB,EAAK,eAAL,YAAA9yB,EAAmB,IAAKwT,GAAMA,EAAE,SAAU,CAAA,CAAC,EAE3Cwf,EAAID,EAAe,OAEnByF,EAAaC,GAAgB3F,EAAK,OAAO,EACzC4F,EAAkBC,GAA8BH,CAAU,EAE1DI,MAAyB,IACzBC,EAA8B,CAAA,EAEpC,QAASx+B,EAAI,EAAGA,EAAI24B,EAAG34B,IACrBu+B,EAAmB,IAAIv+B,EAAG,EAAE,EAG9B,UAAWw2B,KAAU6H,EAAiB,CACpC,MAAMI,EAAO7H,GAA0BJ,EAAQkC,CAAc,EAC7D,GAAI+F,EAAK,OAAS,EAAG,CACnB,MAAMC,EAASD,EAAK,OAAA,EAAS,OAAO,MAChCC,IAAW,UACblf,EAAA+e,EAAmB,IAAIG,CAAM,IAA7B,MAAAlf,EAAgC,KAAKgX,GAEzC,MACEgI,EAAa,KAAKhI,CAAM,CAE5B,CAEA,GAAImC,GAAK,GAAK,CAACF,EAAK,cAAgBA,EAAK,aAAa,SAAW,EAAG,CAClE,MAAMkG,EAAOtH,GACXqB,EAAe,CAAC,EAChB6F,EAAmB,IAAI,CAAC,GAAK,CAAA,EAC7B9F,EAAK,QACLA,EAAK,KAAA,EAEP,MAAO,CACL,KAAAA,EACA,cAAeC,EACf,QAAS,CACP,UAAWiG,EAAK,KAChB,cAAeA,EAAK,KACpB,UAAW,CAACjG,EAAe,CAAC,EAAE,IAAI,EAClC,mBAAA6F,EACA,aAAAC,EACA,eAAgB,CAACG,EAAK,QAAQ,EAC9B,gBAAiB,CAACA,EAAK,SAAS,EAChC,iBAAkBA,EAAK,iBACvB,gBAAiBA,EAAK,eAAA,EAExB,iBAAkBA,EAAK,iBACvB,gBAAiBA,EAAK,eAAA,CAE1B,CAEA,KAAM,CAAE,MAAA/F,EAAO,aAAAC,CAAA,EAAiBL,GAAeC,EAAMC,CAAc,EAG7DsJ,EAAYtJ,EAAe,IAAI,CAACzE,EAAG7tB,IAAQ,CAC/C,MAAMy4B,EAAczE,GAClBnG,EACA7tB,EACAsyB,EACAD,EAAK,QACLA,EAAK,WAAA,EAEDqG,EAAoBD,EACtBpG,EAAK,QAAS,IAAK10B,GAAM,CACvB,MAAMmO,EAAMnO,EAAE,SAAW,GACnBg7B,EAAW7sB,EAAI,SAAS,GAAG,EAC7BA,EAAI,MAAMA,EAAI,YAAY,GAAG,EAAI,CAAC,EAClCA,EACJ,MAAO,CAAE,GAAGnO,EAAG,QAASg7B,CAAA,CAC1B,CAAC,EACD,OACJ,OAAO1H,GACLpD,EACAsK,EAAmB,IAAIn4B,CAAG,GAAK,CAAA,EAC/B04B,EACAD,EAAcpG,EAAK,MAAQ,MAAA,CAE/B,CAAC,EAIKwJ,EAAmC,CAAA,EACzC,QAASjiC,EAAI,EAAGA,EAAI24B,EAAG34B,IACjB64B,EAAa74B,CAAC,EAAE,OAAS,GAC3BiiC,EAAuB,KAAKjiC,CAAC,EAKjCiiC,EAAuB,KAAK,CAACjmB,EAAGnP,IAAM,CACpC,MAAMq1B,EAASF,EAAUhmB,CAAC,EAAE,iBAAmB,EAAI,EAC7CmmB,EAASH,EAAUn1B,CAAC,EAAE,iBAAmB,EAAI,EACnD,GAAIq1B,IAAWC,EAAQ,OAAOA,EAASD,EACvC,GAAIF,EAAUhmB,CAAC,EAAE,OAASgmB,EAAUn1B,CAAC,EAAE,KACrC,OAAOm1B,EAAUhmB,CAAC,EAAE,KAAOgmB,EAAUn1B,CAAC,EAAE,KAE1C,MAAMu1B,EAAWJ,EAAUhmB,CAAC,EAAE,WAAa,YAAc,EAAI,EACvDqmB,EAAWL,EAAUn1B,CAAC,EAAE,WAAa,YAAc,EAAI,EAC7D,OAAIu1B,IAAaC,EAAiBA,EAAWD,EAEzCpmB,IAAM,EAAU,GAChBnP,IAAM,EAAU,EACbmP,EAAInP,CACb,CAAC,EAED,MAAMy1B,EAAaL,EAAuB,CAAC,GAAK,EAC1CzI,EAAyB,CAAC8I,CAAU,EACpCC,EAAiD,CAACP,EAAUM,CAAU,EAAE,QAAQ,EAChFE,EAA2C,CAACR,EAAUM,CAAU,EAAE,SAAS,EACjF,IAAI/C,EAAYyC,EAAUM,CAAU,EAAE,KAClCG,EAAcT,EAAUM,CAAU,EAAE,KAExC,MAAMI,MAAgB,IACtB,QAAS1iC,EAAI,EAAGA,EAAI24B,EAAG34B,IACjBA,IAAMsiC,GAAYI,EAAU,IAAI1iC,CAAC,EAIvC,KAAO0iC,EAAU,KAAO,GAAG,CACzB,MAAMtB,EAOA,CAAA,EAEN,UAAW77B,KAAWm9B,EAAW,CAE/B,IAAItD,EAAgB,GACpB,UAAWC,KAAOxG,EAAatzB,CAAO,EACpC,GAAI,CAACi0B,EAAa,SAAS6F,CAAG,EAAG,CAC/BD,EAAgB,GAChB,KACF,CAEF,GAAI,CAACA,EAAe,SAGpB,MAAM2B,EAAYrI,EAAenzB,CAAO,EAClC2xB,EAAW,KAAK,IAAI,EAAG6J,EAAU,kBAAoB,EAAE,EAC7D,IAAI4B,EAAiE,KAErE,UAAWtB,KAAQzI,EACjB,GAAIyI,EAAK,SAAW97B,GAAWi0B,EAAa,SAAS6H,EAAK,MAAM,EAAG,CACjE,MAAMj7B,EAAM8xB,GAAkB6I,EAAWM,EAAK,IAAI,EAC9Cj7B,IAAQ,CAACu8B,GAAiBv8B,EAAI,YAChCu8B,EAAgB,CAAE,SAAUv8B,EAAI,SAAU,UAAWA,EAAI,MAAM,IAAA,EAEnE,SAAWi7B,EAAK,SAAW97B,GAAWi0B,EAAa,SAAS6H,EAAK,MAAM,EAAG,CACxE,MAAMj7B,EAAM8xB,GAAkB6I,EAAWM,EAAK,IAAI,EAC9Cj7B,IAAQ,CAACu8B,GAAiBv8B,EAAI,YAChCu8B,EAAgB,CAAE,SAAUv8B,EAAI,SAAU,UAAWA,EAAI,MAAM,IAAA,EAEnE,CAGF,GAAIu8B,EACF,GAAIA,EAAc,SAAU,CAE1B,MAAMd,EAAWzL,GAAkB,EAAIE,GACvC8K,EAAW,KAAK,CACd,SAAU77B,EACV,KAAM,EACN,SAAUk9B,EAAcZ,EACxB,QAAS,KAAK,IAAI,EAAGY,CAAW,EAChC,SAAU,YACV,UAAWE,EAAc,SAAA,CAC1B,CACH,KAAO,CAEL,MAAMb,EAAW,KAAK,IAAI,EAAG,KAAK,IAAI,GAAI,KAAK,MAAM5K,EAAW,EAAE,CAAC,CAAC,EAC9D2K,EAAWzL,GAAkB0L,EAAWzL,GAC9C+K,EAAW,KAAK,CACd,SAAU77B,EACV,KAAM,EACN,SAAUk9B,EAAcZ,EACxB,QAAS,KAAK,IAAI,EAAGY,EAAcX,CAAQ,EAC3C,SAAU,YACV,UAAWa,EAAc,SAAA,CAC1B,CACH,MAGAvB,EAAW,KAAK,CACd,SAAU77B,EACV,KAAM,EACN,SAAUk9B,GAAe,EAAMvL,EAAW,IAC1C,QAAS,KAAK,IAAI,EAAGuL,EAAc,KAAK,IAAI,EAAG,KAAK,MAAMvL,EAAW,EAAG,CAAC,CAAC,EAC1E,SAAU,WAAA,CACX,CAEL,CAEA,GAAIkK,EAAW,SAAW,EAAG,CAE3B,MAAMwB,EAAcF,EAAU,OAAA,EAAS,OAAO,MAC9C,GAAIE,IAAgB,OAAW,MAC/BpJ,EAAa,KAAKoJ,CAAW,EAC7BL,EAAgB,KAAK,WAAW,EAChCC,EAAiB,KAAK,MAAS,EAC/BE,EAAU,OAAOE,CAAW,EAC5B,QACF,CAGAxB,EAAW,KAAK,CAACplB,EAAGnP,IACdmP,EAAE,OAASnP,EAAE,KAAamP,EAAE,KAAOnP,EAAE,KACrC,KAAK,IAAImP,EAAE,SAAWnP,EAAE,QAAQ,EAAI,IAAamP,EAAE,SAAWnP,EAAE,SAC7DmP,EAAE,SAAWnP,EAAE,QACvB,EAED,MAAMg2B,EAASzB,EAAW,CAAC,EAC3B5H,EAAa,KAAKqJ,EAAO,QAAQ,EACjCN,EAAgB,KAAKM,EAAO,QAAQ,EACpCL,EAAiB,KAAKK,EAAO,SAAS,EACtCtD,GAAasD,EAAO,SACpBJ,EAAcI,EAAO,QACrBH,EAAU,OAAOG,EAAO,QAAQ,CAClC,CAEA,MAAMlC,EAAgBnH,EAAa,IAAKpzB,GAAQsyB,EAAetyB,CAAG,CAAC,EAC7DszB,EAAiBH,GACrBC,EACAd,EACAE,EACAH,EAAK,YAAA,EAEDa,EAAuBH,GAA6BV,EAAMC,CAAc,EAExEkI,IAAsB1V,EAAA8W,EAAUM,CAAU,IAApB,YAAApX,EAAuB,oBAAqB,GAClE2V,EACJD,GAAuBnI,EAAK,SAAWA,EAAK,QAAQ,OAAS,GAAKgK,EAAc,EAC5EA,EAAc,KAAK,KAAKA,CAAW,EAAInM,GACvC,OAEN,MAAO,CACL,KAAM,CACJ,GAAGmC,EACH,MAAOkI,EAAc,CAAC,EACtB,aAAcjH,EACd,YAAaJ,EACb,iBAAkBsH,CAAA,EAEpB,cAAAD,EACA,QAAS,CACP,UAAApB,EACA,cAAekD,EACf,UAAW9B,EAAc,IAAK1M,GAAMA,EAAE,IAAI,EAC1C,mBAAAsK,EACA,aAAAC,EACA,eAAgB+D,EAChB,gBAAiBC,EACjB,iBAAkB5B,EAClB,gBAAiBC,CAAA,EAEnB,iBAAkBD,EAClB,gBAAiBC,CAAA,CAErB,CACF,CClRO,MAAMiC,EAAoC,CAA1C,cACIv/B,EAAA,YAAO,QAEhB,SAASk1B,EAAsC,SAC7C,MAAMC,EAA8B,CAClCD,EAAK,MACL,KAAI9yB,EAAA8yB,EAAK,eAAL,YAAA9yB,EAAmB,IAAKwT,GAAMA,EAAE,SAAU,CAAA,CAAC,EAE3Cwf,EAAID,EAAe,OAEnByF,EAAaC,GAAgB3F,EAAK,OAAO,EACzC4F,EAAkBC,GAA8BH,CAAU,EAE1DI,MAAyB,IACzBC,EAA8B,CAAA,EAEpC,QAASx+B,EAAI,EAAGA,EAAI24B,EAAG34B,IACrBu+B,EAAmB,IAAIv+B,EAAG,EAAE,EAG9B,UAAWw2B,KAAU6H,EAAiB,CACpC,MAAMI,EAAO7H,GAA0BJ,EAAQkC,CAAc,EAC7D,GAAI+F,EAAK,OAAS,EAAG,CACnB,MAAMC,EAASD,EAAK,OAAA,EAAS,OAAO,MAChCC,IAAW,UACblf,EAAA+e,EAAmB,IAAIG,CAAM,IAA7B,MAAAlf,EAAgC,KAAKgX,GAEzC,MACEgI,EAAa,KAAKhI,CAAM,CAE5B,CAEA,MAAMuM,EAAgB1L,GACpBqB,EAAe,CAAC,EAChB6F,EAAmB,IAAI,CAAC,GAAK,CAAA,CAAC,EAG1ByE,EAAgD,CAACD,EAAc,QAAQ,EACvEE,EAA0C,CAACF,EAAc,SAAS,EACxE,IAAIxD,EAAYwD,EAAc,KAC9B,MAAMtL,EAAgBsL,EAAc,KAEpC,GAAItK,EAAK,aACP,QAASz4B,EAAI,EAAGA,EAAI24B,EAAG34B,IAAK,CAC1B,MAAMkjC,EAAQzK,EAAK,aAAaz4B,EAAI,CAAC,EAC/BwkB,EAAO2e,GAAgBD,EAAOxK,EAAe14B,CAAC,EAAGA,EAAG04B,EAAgB14B,CAAC,EACvEwkB,GACFwe,EAAe,KAAK,WAAW,EAC/BC,EAAgB,KAAKze,EAAK,MAAM,IAAI,EACpC+a,GAAa9H,EAAgB,MAE7BuL,EAAe,KAAK,WAAW,EAC/BC,EAAgB,KAAK,MAAS,EAC9B1D,GAAa9H,GAAiB,GAAOiB,EAAe14B,CAAC,EAAE,kBAAoB,IAAM,IAErF,CAGF,MAAMs5B,EAAuBH,GAA6BV,EAAMC,CAAc,EAE9E,MAAO,CACL,KAAM,CACJ,GAAGD,EACH,YAAaa,CAAA,EAEf,cAAeZ,EACf,QAAS,CACP,UAAA6G,EACA,cAAA9H,EACA,UAAWiB,EAAe,IAAKzE,GAAMA,EAAE,IAAI,EAC3C,mBAAAsK,EACA,aAAAC,EACA,eAAAwE,EACA,gBAAAC,CAAA,CACF,CAEJ,CACF,CCxEO,MAAMG,EAA2C,CAItD,YAAYC,EAA6B,CAHhC9/B,EAAA,YAAO,gBACRA,EAAA,kBAGN,KAAK,UAAY8/B,CACnB,CAEA,SAAS5K,EAAsC,WAC7C,MAAMC,EAA8B,CAClCD,EAAK,MACL,KAAI9yB,EAAA8yB,EAAK,eAAL,YAAA9yB,EAAmB,IAAKwT,GAAMA,EAAE,SAAU,CAAA,CAAC,EAE3Cwf,EAAID,EAAe,OACnB4K,EAAS7K,EAAK,eAAiB,QAAaA,EAAK,aAAa,OAAS,EAEvE0F,EAAaC,GAAgB3F,EAAK,OAAO,EACzC4F,EAAkBC,GAA8BH,CAAU,EAE1DI,MAAyB,IACzBC,EAA8B,CAAA,EAEpC,QAASx+B,EAAI,EAAGA,EAAI24B,EAAG34B,IACrBu+B,EAAmB,IAAIv+B,EAAG,EAAE,EAG9B,UAAWw2B,KAAU6H,EAAiB,CACpC,MAAMI,EAAO7H,GAA0BJ,EAAQkC,CAAc,EAC7D,GAAI+F,EAAK,OAAS,EAAG,CACnB,MAAMC,EAASD,EAAK,OAAA,EAAS,OAAO,MAChCC,IAAW,UACblf,EAAA+e,EAAmB,IAAIG,CAAM,IAA7B,MAAAlf,EAAgC,KAAKgX,GAEzC,MACEgI,EAAa,KAAKhI,CAAM,CAE5B,CAEA,GAAI,CAAC8M,GAAU3K,GAAK,EAAG,CACrB,MAAMgG,EAAOtH,GACXqB,EAAe,CAAC,EAChB6F,EAAmB,IAAI,CAAC,GAAK,CAAA,CAAC,EAEhC,MAAO,CACL,KAAA9F,EACA,cAAeC,EACf,QAAS,CACP,UAAWiG,EAAK,KAChB,cAAeA,EAAK,KACpB,UAAW,CAACjG,EAAe,CAAC,EAAE,IAAI,EAClC,mBAAA6F,EACA,aAAAC,EACA,eAAgB,CAACG,EAAK,QAAQ,EAC9B,gBAAiB,CAACA,EAAK,SAAS,CAAA,CAClC,CAEJ,CAGA,MAAM4E,EAA0B,MAAM,KAAK,CAAE,OAAQ5K,GAAK,CAAC+H,EAAG1gC,IAAMA,CAAC,EAErE,GAAI,KAAK,WACP,GAAI,OAAO,KAAK,WAAc,WAAY,CACxC,MAAMwjC,EAAa,KAAK,UACxBD,EAAc,KAAK,CAACvnB,EAAGnP,IAAM22B,EAAW9K,EAAe1c,CAAC,EAAG0c,EAAe7rB,CAAC,CAAC,CAAC,CAC/E,SAAW,MAAM,QAAQ,KAAK,SAAS,EAAG,CACxC,MAAM42B,EAAO,KAAK,UAClBF,EAAc,KAAK,CAACvnB,EAAGnP,IAAM,CAC3B,MAAM62B,EAAQhL,EAAe1c,CAAC,EAAE,KAC1B2nB,EAAQjL,EAAe7rB,CAAC,EAAE,KAC1B+2B,EAAOH,EAAK,QAAQC,CAAK,EACzBG,EAAOJ,EAAK,QAAQE,CAAK,EACzBG,EAAYF,IAAS,GAAK,KAAOA,EACjCG,EAAYF,IAAS,GAAK,KAAOA,EACvC,OAAIC,IAAcC,EACTD,EAAYC,EAEd/nB,EAAInP,CACb,CAAC,CACH,EAGF,KAAM,CAAE,MAAA+rB,CAAA,EAAUJ,GAAeC,EAAMC,CAAc,EAC/CiI,EAAgB4C,EAAc,IAAKvjC,GAAM04B,EAAe14B,CAAC,CAAC,EAC1D05B,EAAiBH,GACrBgK,EACA7K,EACAE,EACAH,EAAK,YAAA,EAEDa,EAAuBH,GAA6BV,EAAMC,CAAc,EAExEsL,EAAyB,CAC7B,GAAGvL,EACH,MAAOkI,EAAc,CAAC,EACtB,aAAcjH,EACd,YAAaJ,CAAA,EAIT2K,MAAkC,IACxC,QAASjkC,EAAI,EAAGA,EAAI24B,EAAG34B,IACrBikC,EAA4B,IAAIjkC,EAAG,EAAE,EAEvC,UAAWw2B,KAAU6H,EAAiB,CACpC,MAAMI,EAAO7H,GAA0BJ,EAAQmK,CAAa,EAC5D,GAAIlC,EAAK,OAAS,EAAG,CACnB,MAAMC,EAASD,EAAK,OAAA,EAAS,OAAO,MAChCC,IAAW,UACbxT,EAAA+Y,EAA4B,IAAIvF,CAAM,IAAtC,MAAAxT,EAAyC,KAAKsL,GAElD,CACF,CAEA,MAAMuM,EAAgB1L,GACpBsJ,EAAc,CAAC,EACfsD,EAA4B,IAAI,CAAC,GAAK,CAAA,CAAC,EAGnCjB,EAAgD,CAACD,EAAc,QAAQ,EACvEE,EAA0C,CAACF,EAAc,SAAS,EACxE,IAAIxD,EAAYwD,EAAc,KAC9B,MAAMtL,EAAgBsL,EAAc,KAEpC,GAAIiB,EAAY,aACd,QAAShkC,EAAI,EAAGA,EAAI24B,EAAG34B,IAAK,CAC1B,MAAMkjC,EAAQc,EAAY,aAAahkC,EAAI,CAAC,EACtCwkB,EAAO2e,GAAgBD,EAAOvC,EAAc3gC,CAAC,EAAGA,EAAG2gC,EAAe3gC,CAAC,EACrEwkB,GACFwe,EAAe,KAAK,WAAW,EAC/BC,EAAgB,KAAKze,EAAK,MAAM,IAAI,EACpC+a,GAAa9H,EAAgB,MAE7BuL,EAAe,KAAK,WAAW,EAC/BC,EAAgB,KAAK,MAAS,EAC9B1D,GAAa9H,GAAiB,GAAOkJ,EAAc3gC,CAAC,EAAE,kBAAoB,IAAM,IAEpF,CAGF,MAAO,CACL,KAAMgkC,EACN,cAAArD,EACA,QAAS,CACP,UAAApB,EACA,cAAA9H,EACA,UAAWkJ,EAAc,IAAK1M,GAAMA,EAAE,IAAI,EAC1C,mBAAoBgQ,EACpB,aAAAzF,EACA,eAAAwE,EACA,gBAAAC,CAAA,CACF,CAEJ,CACF,CChKO,MAAMiB,EAAsC,CAEjD,YAAoBrgB,EAA8C,CADzDtgB,EAAA,YAAO,UACI,KAAA,GAAAsgB,CAA+C,CACnE,SAAS4U,EAAsC,CAC7C,OAAO,KAAK,GAAGA,CAAI,CACrB,CACF,CAEO,MAAM0L,GAAqBD,GACrBE,GAAsBzG,GACtB0G,GAAwB1G,GACxB2G,GAAwBvC,GACxBwC,GAAmBzB,GAE1B0B,GAAiB,IAAI7G,GAKpB,SAAS8G,GACdC,EACc,CACd,OAAOA,GAAWF,EACpB,CAKO,SAASG,GACdlM,EACAiM,EACqB,CAErB,OADsBD,GAAoBC,CAAO,EAC5B,SAASjM,CAAI,CACpC,CCZO,SAASmM,GAAajkB,EAAgC,CAC3D,GAAI,CAACA,EAAI,OAAOrgB,EAAO,MAEvB,OADa,OAAOqgB,CAAE,EAAE,OAAO,cAAc,QAAQ,OAAQ,GAAG,EACxD,CACN,IAAK,IACL,IAAK,KACH,OAAOrgB,EAAO,MAChB,IAAK,KACL,IAAK,KACH,OAAOA,EAAO,MAChB,IAAK,IACH,OAAOA,EAAO,MAChB,IAAK,KACH,OAAOA,EAAO,MAChB,IAAK,IACH,OAAOA,EAAO,MAChB,IAAK,KACH,OAAOA,EAAO,MAChB,IAAK,OACH,OAAOA,EAAO,YAChB,IAAK,WACH,OAAOA,EAAO,gBAChB,IAAK,WACH,OAAOA,EAAO,gBAChB,IAAK,cACH,OAAOA,EAAO,mBAChB,IAAK,YACH,OAAOA,EAAO,iBAChB,QACE,OAAOA,EAAO,KAAA,CAEpB,CAyEO,MAAMukC,EAAgB,CAAtB,cACGthC,EAAA,cAAmB,CAAA,GACnBA,EAAA,mBAAc,IAAI,aAE1B,UAAU8B,EAAqB,CAC7B,MAAM2gB,EAAM,KAAK,OAAO,OACxB,YAAK,OAAO,KAAK3gB,EAAM,GAAI,EACpB2gB,CACT,CAEA,WAAW3gB,EAAqB,CAC9B,MAAM2gB,EAAM,KAAK,OAAO,OACxB,YAAK,OAAO,KAAK3gB,EAAM,GAAI,EAC3B,KAAK,OAAO,KAAMA,GAAO,EAAK,GAAI,EAC3B2gB,CACT,CAEA,WAAW3gB,EAAqB,CAC9B,MAAM2gB,EAAM,KAAK,OAAO,OACxB,YAAK,OAAO,KAAK3gB,EAAM,GAAI,EAC3B,KAAK,OAAO,KAAMA,GAAO,EAAK,GAAI,EAClC,KAAK,OAAO,KAAMA,GAAO,GAAM,GAAI,EACnC,KAAK,OAAO,KAAMA,GAAO,GAAM,GAAI,EAC5B2gB,CACT,CAEA,UAAU3gB,EAAqB,CAC7B,OAAO,KAAK,WAAWA,CAAG,CAC5B,CAEA,YAAYA,EAAqB,CAC/B,MAAM2gB,EAAM,KAAK,OAAO,OAClBjZ,EAAM,IAAI,YAAY,CAAC,EAC7B,IAAI,SAASA,CAAG,EAAE,WAAW,EAAG1H,EAAK,EAAI,EACzC,MAAMuY,EAAK,IAAI,WAAW7Q,CAAG,EAC7B,QAAS/M,EAAI,EAAGA,EAAI,EAAGA,IACrB,KAAK,OAAO,KAAK4d,EAAG5d,CAAC,CAAC,EAExB,OAAOgmB,CACT,CAEA,WAAW7J,EAAqB,CAC9B,MAAMlR,EAAQ,KAAK,YAAY,OAAOkR,CAAG,EACnC6J,EAAM,KAAK,WAAW/a,EAAM,UAAU,EAC5C,QAAS,EAAI,EAAG,EAAIA,EAAM,WAAY,IACpC,KAAK,OAAO,KAAKA,EAAM,CAAC,CAAC,EAE3B,OAAO+a,CACT,CAEA,UAAU/a,EAA2B,CACnC,MAAM+a,EAAM,KAAK,WAAW/a,EAAM,UAAU,EAC5C,QAASjL,EAAI,EAAGA,EAAIiL,EAAM,WAAYjL,IACpC,KAAK,OAAO,KAAKiL,EAAMjL,CAAC,CAAC,EAE3B,OAAOgmB,CACT,CAEA,YAAYA,EAAa3gB,EAAmB,CAC1C,KAAK,OAAO2gB,CAAG,EAAI3gB,EAAM,IACzB,KAAK,OAAO2gB,EAAM,CAAC,EAAK3gB,GAAO,EAAK,GACtC,CAEA,eAAwB,CACtB,OAAO,KAAK,OAAO,MACrB,CAEA,aAA0B,CACxB,OAAO,IAAI,WAAW,KAAK,MAAM,CACnC,CACF,CAEA,SAASy/B,GACPC,EACA3/B,EACA+xB,EACA6N,EACAC,EACM,CACFA,IAAY/kC,EAAS,OAAS+kC,IAAY/kC,EAAS,OACrD6kC,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,GAChBC,IAAY/kC,EAAS,SAC9B6kC,EAAQ,UAAUzkC,EAAO,eAAe,EACxCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,GAChBC,IAAY/kC,EAAS,MAC9B6kC,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,GAChBC,IAAY/kC,EAAS,MAC9B6kC,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,GAChBC,IAAY/kC,EAAS,MAC9B6kC,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,GAChBC,IAAY/kC,EAAS,OAC9B6kC,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU3/B,CAAM,EACxB2/B,EAAQ,UAAU5N,CAAM,EACxB4N,EAAQ,UAAUC,CAAO,EAE7B,CAEO,SAASE,GAAgB1O,EAAkC,CAChE,GAAIA,EAAO,OAAS,KAAM,CACxB,GAAIA,EAAO,QAAUA,EAAO,OAAO,OAASj3B,GAC1C,MAAM,IAAI,WACR,gDAAgDA,EAAgB,WAAA,EAGpE,MAAO,CACL,KAAM,KACN,QAASi3B,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQA,EAAO,OAAS,MAAM,KAAK,IAAI,IAAIA,EAAO,MAAM,CAAC,EAAI,CAAA,EAC7D,MAAO,CAAC,CAACA,EAAO,KAAA,CAEpB,CAEA,GAAIA,EAAO,OAAS,MAAO,CACzB,MAAM2O,EAAS3O,EAAO,GAAK,OAAOA,EAAO,EAAE,EAAE,KAAA,EAAO,YAAA,EAAgB,GACpE,GAAI2O,IAAW,MAAQA,IAAW,SAAU,CAC1C,MAAMC,EAAM,MAAM,QAAQ5O,EAAO,KAAK,EAAIA,EAAO,MAAQ,CAACA,EAAO,KAAK,EACtE,GAAI4O,EAAI,OAAS7lC,GACf,MAAM,IAAI,WACR,gDAAgDA,EAAgB,WAAA,EAGpE,MAAO,CACL,KAAM,KACN,QAASi3B,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQ,MAAM,KAAK,IAAI,IAAI4O,CAAG,CAAC,EAC/B,MAAOD,IAAW,QAAA,CAEtB,CACF,CAEA,GAAI3O,EAAO,OAAS,MAClB,MAAO,CACL,KAAM,MACN,SAAUA,EAAO,SAAWA,EAAO,SAAS,IAAI0O,EAAe,EAAI,CAAA,CAAC,EAIxE,GAAI1O,EAAO,OAAS,KAClB,MAAO,CACL,KAAM,KACN,SAAUA,EAAO,SAAWA,EAAO,SAAS,IAAI0O,EAAe,EAAI,CAAA,CAAC,EAIxE,GAAI1O,EAAO,OAAS,MAAO,CACzB,MAAMG,EAAQH,EAAO,MACrB,GAAI,CAACG,EAAO,OAAOH,EAGnB,GAAIG,EAAM,OAAS,OAASA,EAAM,MAChC,OAAOuO,GAAgBvO,EAAM,KAAK,EAKpC,GAAIA,EAAM,OAAS,KACjB,MAAO,CACL,KAAM,KACN,QAASA,EAAM,QACf,KAAMA,EAAM,KACZ,OAAQA,EAAM,OACd,MAAO,CAACA,EAAM,KAAA,EAKlB,GAAIA,EAAM,OAAS,MACjB,MAAO,CACL,KAAM,KACN,SAAUA,EAAM,SACZA,EAAM,SAAS,IAAK12B,GAClBilC,GAAgB,CAAE,KAAM,MAAO,MAAOjlC,EAAG,CAAA,EAE3C,CAAA,CAAC,EAKT,GAAI02B,EAAM,OAAS,KACjB,MAAO,CACL,KAAM,MACN,SAAUA,EAAM,SACZA,EAAM,SAAS,IAAK12B,GAClBilC,GAAgB,CAAE,KAAM,MAAO,MAAOjlC,EAAG,CAAA,EAE3C,CAAA,CAAC,EAMT,GAAI02B,EAAM,OAAS,OACjB,MAAO,CACL,KAAM,OACN,QAASA,EAAM,QACf,OAAQ,CAACA,EAAM,MAAA,EAKnB,GAAIA,EAAM,OAAS,MAAO,CACxB,MAAMwO,EAASxO,EAAM,GAAK,OAAOA,EAAM,EAAE,EAAE,KAAA,EAAO,YAAA,EAAgB,GAClE,GAAIwO,IAAW,MAAQA,IAAW,SAChC,OAAOD,GAAgB,CACrB,KAAM,KACN,QAASvO,EAAM,QACf,KAAMA,EAAM,KACZ,OAAQ,MAAM,QAAQA,EAAM,KAAK,EAAIA,EAAM,MAAQ,CAACA,EAAM,KAAK,EAC/D,MAAOwO,IAAW,IAAA,CACnB,EAGH,MAAME,EAA2C,CAC/C,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,KAAM,WACN,WAAY,MAAA,EAGd,OAAI1O,EAAM,IAAM0O,EAAW1O,EAAM,EAAE,EAC1B,CACL,KAAM,MACN,QAASA,EAAM,QACf,GAAI0O,EAAW1O,EAAM,EAAE,EACvB,MAAOA,EAAM,KAAA,EAMV,CACL,KAAM,MACN,SAAU,CACR,CAAE,KAAM,OAAQ,QAASA,EAAM,QAAS,OAAQ,EAAA,EAChD,CAAE,KAAM,MAAO,MAAAA,CAAA,CAAM,CACvB,CAEJ,CACF,CAEA,OAAOH,CACT,CAEO,SAAS4H,GAAgB9G,EAA4C,CAC1E,GAAI,CAACA,GAAWA,EAAQ,SAAW,EAAG,OAAO,KAC7C,MAAMgO,EACJhO,EAAQ,SAAW,EAAIA,EAAQ,CAAC,EAAI,CAAE,KAAM,MAAO,SAAUA,CAAA,EAC/D,OAAO4N,GAAgBI,CAAO,CAChC,CAEO,SAASC,GAAmB/O,EAAoC,CACrE,MAAMgP,EAAwB,CAAA,EACxBC,MAAW,IACjB,SAASC,EAASnhC,EAAgB,CAChC,GACEA,EAAE,OAAS,QACXA,EAAE,OAAS,OACXA,EAAE,OAAS,QACXA,EAAE,OAAS,KAENkhC,EAAK,IAAIlhC,CAAC,IACbkhC,EAAK,IAAIlhC,CAAC,EACVihC,EAAO,KAAKjhC,CAAC,WAENA,EAAE,OAAS,OAASA,EAAE,OAAS,MACxC,GAAIA,EAAE,SACJ,UAAWoyB,KAASpyB,EAAE,SACpBmhC,EAAS/O,CAAK,OAGTpyB,EAAE,OAAS,OAChBA,EAAE,OACJmhC,EAASnhC,EAAE,KAAK,CAGtB,CACA,OAAAmhC,EAASlP,CAAM,EACRgP,CACT,CAEO,SAASlH,GACdH,EACe,CACf,GAAI,CAACA,EAAY,MAAO,CAAA,EACxB,MAAMwH,EAA8B,CAAA,EACpC,SAASC,EAAOrhC,EAAgB,CAC9B,GAAIA,EAAE,OAAS,OAASA,EAAE,SACxB,UAAWoyB,KAASpyB,EAAE,SACpBqhC,EAAOjP,CAAK,OAELpyB,EAAE,OAAS,OAASA,EAAE,OAAS,MAAQA,EAAE,OAAS,SAC3DohC,EAAa,KAAKphC,CAAC,CAEvB,CACA,OAAAqhC,EAAOzH,CAAU,EACVwH,CACT,CAUO,SAAS3O,GACd/B,EACAl1B,EACuB,CACvB,GAAIk1B,EAAQ,SAAS,GAAG,EAAG,CACzB,MAAM/c,EAAQ+c,EAAQ,MAAM,GAAG,EACzB4Q,EAAU3tB,EAAM,CAAC,EACjB4tB,EAAQ5tB,EAAM,CAAC,EACf6tB,EAAWhmC,EAAO,UACrBk0B,GAAMA,EAAE,KAAK,YAAA,IAAkB4R,EAAQ,YAAA,CAAY,EAEtD,GAAIE,IAAa,GAAI,OAAO,KAC5B,MAAM5O,EAASp3B,EAAOgmC,CAAQ,EAAE,QAAQ,UACrC9lC,GAAMA,EAAE,KAAK,YAAA,IAAkB6lC,EAAM,YAAA,CAAY,EAEpD,OAAI3O,IAAW,GAAW,KACnB,CACL,SAAA4O,EACA,OAAQA,EACR,OAAA5O,EACA,IAAKp3B,EAAOgmC,CAAQ,EAAE,QAAQ5O,CAAM,EACpC,MAAOp3B,EAAOgmC,CAAQ,CAAA,CAE1B,CAGA,QAAS/lC,EAAI,EAAGA,EAAID,EAAO,OAAQC,IAAK,CACtC,MAAMm3B,EAASp3B,EAAOC,CAAC,EAAE,QAAQ,UAC9BC,GAAMA,EAAE,KAAK,YAAA,IAAkBg1B,EAAQ,YAAA,CAAY,EAEtD,GAAIkC,IAAW,GACb,MAAO,CACL,SAAUn3B,EACV,OAAQA,EACR,OAAAm3B,EACA,IAAKp3B,EAAOC,CAAC,EAAE,QAAQm3B,CAAM,EAC7B,MAAOp3B,EAAOC,CAAC,CAAA,CAGrB,CAEA,OAAO,IACT,CAEA,SAASgmC,GACPxP,EACAyP,EACAnmC,EACAilC,EACAmB,EACAC,EACApmC,EACAqmC,EACM,CACN,MAAMC,EAAMtmC,GAAU,CAACD,CAAK,EAC5B,GAAI02B,EAAO,OAAS,OAAQ,CAC1B,MAAM8P,EAASL,EAAU,EACnBM,EAASN,EAAU,EAAI,EAC7B,IAAIO,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACAuB,EACAG,EACAN,EACA,OACAE,CAAA,EAEFtB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUwB,CAAM,EACxBxB,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUuB,CAAM,EACxBvB,EAAQ,UAAUwB,CAAM,EACxBL,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,EACtC,MACF,CAEA,GAAIvO,EAAO,OAAS,OAAQ,CAC1B,GAAI,CAACA,EAAO,QACV,MAAM,IAAI,MAAM,kCAAkC,EAEpD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAI,CAACtP,EACH,MAAM,IAAI,MAAM,WAAWP,EAAO,OAAO,uBAAuB,EAE9DA,EAAO,OACTuO,EAAQ,UAAUzkC,EAAO,UAAU,EAEnCykC,EAAQ,UAAUzkC,EAAO,cAAc,EAEzCykC,EAAQ,UAAUhO,EAAS,MAAM,EACjCgO,EAAQ,UAAUhO,EAAS,MAAM,EACjCmP,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,EACtC,MACF,CAEA,GAAIvO,EAAO,OAAS,KAAM,CACxB,GAAI,CAACA,EAAO,QAAUA,EAAO,OAAO,SAAW,EAAG,CAC5CA,EAAO,QACTuO,EAAQ,UAAUzkC,EAAO,OAAO,EAChC4lC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,GAExC,MACF,CAEA,MAAM4B,EAASV,EAAU,EACzB,GAAIzP,EAAO,KAAM,CACf,IAAIgQ,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACA4B,EACAF,EACAN,EACA,OACAE,CAAA,CAEJ,KAAO,CACL,GAAI,CAAC7P,EAAO,QACV,MAAM,IAAI,MAAM,qCAAqC,EAEvD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAItP,EACF+N,GACEC,EACAhO,EAAS,OACTA,EAAS,OACT4P,EACA5P,EAAS,IAAI,IAAA,MAGf,IAAI,CACF,MAAM6P,EAASpS,GAAgBgC,EAAO,OAAO,EAC7C,IAAIgQ,EAAU,GAKdE,EACEE,EACA9mC,EACAilC,EACA,EACA4B,EATe,IAAM,CACrB,GAAIH,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EAQEL,EACA,OACAE,CAAA,CAEJ,MAAQ,CACN,MAAM,IAAI,MAAM,WAAW7P,EAAO,OAAO,uBAAuB,CAClE,CAEJ,CAEA,MAAMqQ,GAAST,GAAA,YAAAA,EAAc,IAAI5P,KAAW,EAC5C,GAAI,CAACA,EAAO,MACVuO,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,WAAW8B,CAAM,EACzBX,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,MACjC,CACL,IAAI+B,EAAgB,GACpB,GAAItQ,EAAO,QAAS,CAClB,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC1DtP,IACFgO,EAAQ,UAAUzkC,EAAO,UAAU,EACnCykC,EAAQ,UAAUhO,EAAS,MAAM,EACjCgO,EAAQ,UAAUhO,EAAS,MAAM,EACjC+P,EAAgB/B,EAAQ,WAAW,CAAC,EAExC,CAEAA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,WAAW8B,CAAM,EACzB,MAAME,EAAchC,EAAQ,WAAW,CAAC,EAExCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC4lC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,EAEtC,MAAMiC,EAAejC,EAAQ,cAAA,EACzB+B,IAAkB,IACpB/B,EAAQ,YAAY+B,EAAeE,CAAY,EAEjDjC,EAAQ,YAAYgC,EAAaC,CAAY,CAC/C,CACA,MACF,CAEA,MAAML,EAASV,EAAU,EACnBgB,EAAWhB,EAAU,EAAI,EAE/B,GAAIzP,EAAO,KAAM,CACf,IAAIgQ,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACA4B,EACAF,EACAN,EACA,OACAE,CAAA,CAEJ,KAAO,CACL,GAAI,CAAC7P,EAAO,QACV,MAAM,IAAI,MAAM,kCAAkC,EAEpD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAItP,EACF+N,GACEC,EACAhO,EAAS,OACTA,EAAS,OACT4P,EACA5P,EAAS,IAAI,IAAA,MAGf,IAAI,CACF,MAAM6P,EAASpS,GAAgBgC,EAAO,OAAO,EAC7C,IAAIgQ,EAAU,GAKdE,EACEE,EACA9mC,EACAilC,EACA,EACA4B,EATe,IAAM,CACrB,GAAIH,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EAQEL,EACA,OACAE,CAAA,CAEJ,MAAQ,CACN,MAAM,IAAI,MAAM,WAAW7P,EAAO,OAAO,uBAAuB,CAClE,CAEJ,CAEA,MAAM0Q,EAAYtC,GAAapO,EAAO,EAAE,EAExCuO,EAAQ,UAAUmC,CAAS,EAC3BnC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,UAAUkC,CAAQ,EAC1Bf,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,CACxC,CAEA,SAASoC,GACP3Q,EACAyP,EACAnmC,EACAilC,EACAqC,EACAjB,EACApmC,EACAqmC,EACM,CACN,MAAMC,EAAMtmC,GAAU,CAACD,CAAK,EAC5B,GAAI02B,EAAO,OAAS,OAAQ,CAC1B,MAAM8P,EAASL,EAAU,EACnBM,EAASN,EAAU,EAAI,EAC7B,IAAIO,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACAuB,EACAG,EACAN,EACA,OACAE,CAAA,EAEFtB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUwB,CAAM,EACxBxB,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUuB,CAAM,EACxBvB,EAAQ,UAAUwB,CAAM,EACxB,MAAMc,EAAYtC,EAAQ,WAAW,CAAC,EAEtCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAEvCA,EAAQ,YAAYsC,EAAWtC,EAAQ,cAAA,CAAe,EACtD,MACF,CAEA,GAAIvO,EAAO,OAAS,OAAQ,CAC1B,GAAI,CAACA,EAAO,QACV,MAAM,IAAI,MAAM,kCAAkC,EAEpD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAI,CAACtP,EACH,MAAM,IAAI,MAAM,WAAWP,EAAO,OAAO,uBAAuB,EAE9DA,EAAO,OACTuO,EAAQ,UAAUzkC,EAAO,cAAc,EAEvCykC,EAAQ,UAAUzkC,EAAO,UAAU,EAErCykC,EAAQ,UAAUhO,EAAS,MAAM,EACjCgO,EAAQ,UAAUhO,EAAS,MAAM,EACjCqQ,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EACvC,MACF,CAEA,GAAIvO,EAAO,OAAS,KAAM,CACxB,GAAI,CAACA,EAAO,QAAUA,EAAO,OAAO,SAAW,EAAG,CAC3CA,EAAO,QACVuO,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,GAEzC,MACF,CAEA,MAAM4B,EAASV,EAAU,EACzB,GAAIzP,EAAO,KAAM,CACf,IAAIgQ,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACA4B,EACAF,EACAN,EACA,OACAE,CAAA,CAEJ,KAAO,CACL,GAAI,CAAC7P,EAAO,QACV,MAAM,IAAI,MAAM,qCAAqC,EAEvD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAItP,EACF+N,GACEC,EACAhO,EAAS,OACTA,EAAS,OACT4P,EACA5P,EAAS,IAAI,IAAA,MAGf,IAAI,CACF,MAAM6P,EAASpS,GAAgBgC,EAAO,OAAO,EAC7C,IAAIgQ,EAAU,GAKdE,EACEE,EACA9mC,EACAilC,EACA,EACA4B,EATe,IAAM,CACrB,GAAIH,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EAQEL,EACA,OACAE,CAAA,CAEJ,MAAQ,CACN,MAAM,IAAI,MAAM,WAAW7P,EAAO,OAAO,uBAAuB,CAClE,CAEJ,CAEA,MAAMqQ,GAAST,GAAA,YAAAA,EAAc,IAAI5P,KAAW,EAC5C,GAAKA,EAAO,MAqBL,CACL,GAAIA,EAAO,QAAS,CAClB,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC1DtP,IACFgO,EAAQ,UAAUzkC,EAAO,UAAU,EACnCykC,EAAQ,UAAUhO,EAAS,MAAM,EACjCgO,EAAQ,UAAUhO,EAAS,MAAM,EACjCqQ,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAE3C,CAEAA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,WAAW8B,CAAM,EACzBO,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,CACzC,KApCmB,CACjB,GAAIvO,EAAO,QAAS,CAClB,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC1DtP,IACFgO,EAAQ,UAAUzkC,EAAO,UAAU,EACnCykC,EAAQ,UAAUhO,EAAS,MAAM,EACjCgO,EAAQ,UAAUhO,EAAS,MAAM,EACjCqQ,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAE3C,CAEAA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,WAAW8B,CAAM,EACzB,MAAMS,EAAavC,EAAQ,WAAW,CAAC,EAEvCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAEvC,MAAMwC,EAAUxC,EAAQ,cAAA,EACxBA,EAAQ,YAAYuC,EAAYC,CAAO,CACzC,CAgBA,MACF,CAEA,MAAMZ,EAASV,EAAU,EACnBgB,EAAWhB,EAAU,EAAI,EAE/B,GAAIzP,EAAO,KAAM,CACf,IAAIgQ,EAAU,GACd,MAAMC,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EACAE,EACElQ,EAAO,KACP12B,EACAilC,EACA,EACA4B,EACAF,EACAN,EACA,OACAE,CAAA,CAEJ,KAAO,CACL,GAAI,CAAC7P,EAAO,QACV,MAAM,IAAI,MAAM,kCAAkC,EAEpD,MAAMO,EAAWC,GAA0BR,EAAO,QAAS6P,CAAG,EAC9D,GAAItP,EACF+N,GACEC,EACAhO,EAAS,OACTA,EAAS,OACT4P,EACA5P,EAAS,IAAI,IAAA,MAGf,IAAI,CACF,MAAM6P,EAASpS,GAAgBgC,EAAO,OAAO,EAC7C,IAAIgQ,EAAU,GAKdE,EACEE,EACA9mC,EACAilC,EACA,EACA4B,EATe,IAAM,CACrB,GAAIH,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EAQEL,EACA,OACAE,CAAA,CAEJ,MAAQ,CACN,MAAM,IAAI,MAAM,WAAW7P,EAAO,OAAO,uBAAuB,CAClE,CAEJ,CAEA,MAAM0Q,EAAYtC,GAAapO,EAAO,EAAE,EAExCuO,EAAQ,UAAUmC,CAAS,EAC3BnC,EAAQ,UAAU4B,CAAM,EACxB5B,EAAQ,UAAUkC,CAAQ,EAC1B,MAAMI,EAAYtC,EAAQ,WAAW,CAAC,EAEtCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAEvCA,EAAQ,YAAYsC,EAAWtC,EAAQ,cAAA,CAAe,CACxD,CAEA,SAASyC,GACPhR,EACAyP,EACAnmC,EACAilC,EACAmB,EACAkB,EACAK,EACAtB,EACApmC,EACAqmC,EACM,CACFqB,IAAgB,OAClBN,GACE3Q,EACAyP,EACAnmC,EACAilC,EACAqC,EACAjB,EACApmC,EACAqmC,CAAA,EAEOqB,IAAgB,QACzBzB,GACExP,EACAyP,EACAnmC,EACAilC,EACAmB,EACAC,EACApmC,EACAqmC,CAAA,GAGFJ,GACExP,EACAyP,EACAnmC,EACAilC,EACAmB,EACAC,EACApmC,EACAqmC,CAAA,EAEFrB,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAE3C,CAEA,SAAS2C,GACPrS,EACA0P,EACAjlC,EACA6nC,EACAzB,EACAkB,EACAK,EACAtB,EACApmC,EACAqmC,EACM,CACN,GACE/Q,EAAK,OAAS,OACdA,EAAK,OAAS,QACdA,EAAK,OAAS,QACdA,EAAK,OAAS,KACd,CACA,MAAM4Q,EAAU0B,EAAW,IAAItS,CAAI,GAAK,EACxCmS,GACEnS,EACA4Q,EACAnmC,EACAilC,EACAmB,EACAkB,EACAK,EACAtB,EACApmC,EACAqmC,CAAA,EAEF,MACF,CAEA,GAAI/Q,EAAK,OAAS,MAAO,CACvB,GAAI,CAACA,EAAK,MACR,OAEF,MAAMuS,EAAOvS,EAAK,MACZ4Q,EAAU0B,EAAW,IAAIC,CAAI,GAAK,EACpCH,IAAgB,OAClBzB,GACE4B,EACA3B,EACAnmC,EACAilC,EACAqC,EACAjB,EACApmC,EACAqmC,CAAA,EAEOqB,IAAgB,QACzBN,GACES,EACA3B,EACAnmC,EACAilC,EACAmB,EACAC,EACApmC,EACAqmC,CAAA,GAGFe,GACES,EACA3B,EACAnmC,EACAilC,EACAmB,EACAC,EACApmC,EACAqmC,CAAA,EAEFrB,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,GAEzC,MACF,CAEA,GAAI1P,EAAK,OAAS,MAAO,CACvB,MAAMwS,EAAWxS,EAAK,UAAY,CAAA,EAClC,GAAIwS,EAAS,SAAW,EAAG,CACrBJ,IAAgB,UAClB1C,EAAQ,UAAUzkC,EAAO,OAAO,EAChC4lC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,GAExC,MACF,CAEA,QAAS/kC,EAAI,EAAGA,EAAI6nC,EAAS,OAAQ7nC,IAAK,CACxC,MAAM22B,EAAQkR,EAAS7nC,CAAC,EAExB,GADeA,IAAM6nC,EAAS,OAAS,EAoBrCH,GACE/Q,EACAoO,EACAjlC,EACA6nC,EACAzB,EACAkB,EACAK,EACAtB,EACApmC,EACAqmC,CAAA,MA7BS,CACX,MAAM0B,EAA2B,CAAA,EACjCJ,GACE/Q,EACAoO,EACAjlC,EACA6nC,EACAG,EACAV,EACA,OACAjB,EACApmC,EACAqmC,CAAA,EAEF,MAAM2B,EAAehD,EAAQ,cAAA,EAC7B,UAAWiD,KAASF,EAClB/C,EAAQ,YAAYiD,EAAOD,CAAY,CAE3C,CAcF,CACA,MACF,CAEA,GAAI1S,EAAK,OAAS,KAAM,CACtB,MAAMwS,EAAWxS,EAAK,UAAY,CAAA,EAClC,GAAIwS,EAAS,SAAW,EAAG,CACrBJ,IAAgB,SAClB1C,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,GAEzC,MACF,CAEA,QAAS/kC,EAAI,EAAGA,EAAI6nC,EAAS,OAAQ7nC,IAAK,CACxC,MAAM22B,EAAQkR,EAAS7nC,CAAC,EAExB,GADeA,IAAM6nC,EAAS,OAAS,EAoBrCH,GACE/Q,EACAoO,EACAjlC,EACA6nC,EACAzB,EACAkB,EACAK,EACAtB,EACApmC,EACAqmC,CAAA,MA7BS,CACX,MAAM6B,EAA4B,CAAA,EAClCP,GACE/Q,EACAoO,EACAjlC,EACA6nC,EACAzB,EACA+B,EACA,QACA9B,EACApmC,EACAqmC,CAAA,EAEF,MAAM2B,EAAehD,EAAQ,cAAA,EAC7B,UAAWiD,KAASC,EAClBlD,EAAQ,YAAYiD,EAAOD,CAAY,CAE3C,CAcF,CACA,MACF,CACF,CAEA,SAASG,GACP1R,EACA12B,EACAilC,EACAoD,EACA1B,EACAW,EACAjB,EACM,CACN,GAAI3P,EAAO,OAAS,MAAO,CACzB,IAAI4R,EACJ,MAAMrR,EAAWoR,EAAW3R,EAAO,QAASA,EAAO,IAAI,EACvD,GAAIO,IAAa,OACfqR,EAASrR,UACAP,EAAO,KAChB4R,EAAS3B,EAAA,EACTC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,UAEO3R,EAAO,QAAS,CACzB4R,EAAS3B,EAAA,EACT,MAAMG,EAASpS,GAAgBgC,EAAO,OAAO,EAC7CkQ,EACEE,EACA9mC,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,CAEJ,MACEC,EAAS3B,EAAA,EACT1B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUqD,CAAM,EAG1B,MAAMnB,EAAWR,EAAA,EACXphC,EAAMmxB,EAAO,MACfnxB,GAAQ,MACV0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,GACjB,OAAO5hC,GAAQ,SACpB,OAAO,UAAUA,CAAG,GACtB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU1/B,CAAG,IAErB0/B,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,YAAY1/B,CAAG,GAEhB,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,WAAW1/B,CAAG,GACb,OAAOA,GAAQ,WACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU1/B,EAAM,EAAI,CAAC,GACpB,OAAOA,GAAQ,WACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU,OAAO1/B,CAAG,CAAC,GAG/B,MAAM6hC,EAAYtC,GAAapO,EAAO,EAAE,EAExCuO,EAAQ,UAAUmC,CAAS,EAC3BnC,EAAQ,UAAUqD,CAAM,EACxBrD,EAAQ,UAAUkC,CAAQ,EAC1B,MAAMI,EAAYtC,EAAQ,WAAW,CAAC,EAEtCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAEvCA,EAAQ,YAAYsC,EAAWtC,EAAQ,cAAA,CAAe,EACtD,MACF,CAEA,GAAIvO,EAAO,OAAS,OAAQ,CAC1B,IAAI4R,EACJ,MAAMrR,EAAWoR,EAAW3R,EAAO,QAASA,EAAO,IAAI,EACvD,GAAIO,IAAa,OACfqR,EAASrR,UACAP,EAAO,KAChB4R,EAAS3B,EAAA,EACTC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,UAEO3R,EAAO,QAAS,CACzB4R,EAAS3B,EAAA,EACT,MAAMG,EAASpS,GAAgBgC,EAAO,OAAO,EAC7CkQ,EACEE,EACA9mC,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,CAEJ,MACEC,EAAS3B,EAAA,EACT1B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUqD,CAAM,EAGtB5R,EAAO,QACTuO,EAAQ,UAAUzkC,EAAO,kBAAkB,EAC3CykC,EAAQ,UAAUqD,CAAM,EACxBhB,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,IAEvCA,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAUqD,CAAM,EACxBhB,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,GAEzC,MACF,CAEA,GAAIvO,EAAO,OAAS,QAAUA,EAAO,KAAM,CACzC,MAAM8P,EAASG,EAAA,EACfC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAuB,EACAG,EACAN,EACAgC,CAAA,EAGF,MAAM5B,EAASE,EAAA,EACf1B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUwB,CAAM,EACxBxB,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUuB,CAAM,EACxBvB,EAAQ,UAAUwB,CAAM,EACxB,MAAMc,EAAYtC,EAAQ,WAAW,CAAC,EAEtCA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAEvCA,EAAQ,YAAYsC,EAAWtC,EAAQ,cAAA,CAAe,EACtD,MACF,CACF,CAEA,SAASsD,GACP7R,EACA12B,EACAilC,EACAoD,EACA1B,EACAP,EACAC,EACM,CACN,GAAI3P,EAAO,OAAS,MAAO,CACzB,IAAI4R,EACJ,MAAMrR,EAAWoR,EAAW3R,EAAO,QAASA,EAAO,IAAI,EACvD,GAAIO,IAAa,OACfqR,EAASrR,UACAP,EAAO,KAChB4R,EAAS3B,EAAA,EACTC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,UAEO3R,EAAO,QAAS,CACzB4R,EAAS3B,EAAA,EACT,MAAMG,EAASpS,GAAgBgC,EAAO,OAAO,EAC7CkQ,EACEE,EACA9mC,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,CAEJ,MACEC,EAAS3B,EAAA,EACT1B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUqD,CAAM,EAG1B,MAAMnB,EAAWR,EAAA,EACXphC,EAAMmxB,EAAO,MACfnxB,GAAQ,MACV0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,GACjB,OAAO5hC,GAAQ,SACpB,OAAO,UAAUA,CAAG,GACtB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU1/B,CAAG,IAErB0/B,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,YAAY1/B,CAAG,GAEhB,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,WAAW1/B,CAAG,GACb,OAAOA,GAAQ,WACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU1/B,EAAM,EAAI,CAAC,GACpB,OAAOA,GAAQ,WACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU,OAAO1/B,CAAG,CAAC,GAG/B,MAAM6hC,EAAYtC,GAAapO,EAAO,EAAE,EAExCuO,EAAQ,UAAUmC,CAAS,EAC3BnC,EAAQ,UAAUqD,CAAM,EACxBrD,EAAQ,UAAUkC,CAAQ,EAC1Bf,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,EACtC,MACF,CAEA,GAAIvO,EAAO,OAAS,OAAQ,CAC1B,IAAI4R,EACJ,MAAMrR,EAAWoR,EAAW3R,EAAO,QAASA,EAAO,IAAI,EACvD,GAAIO,IAAa,OACfqR,EAASrR,UACAP,EAAO,KAChB4R,EAAS3B,EAAA,EACTC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,UAEO3R,EAAO,QAAS,CACzB4R,EAAS3B,EAAA,EACT,MAAMG,EAASpS,GAAgBgC,EAAO,OAAO,EAC7CkQ,EACEE,EACA9mC,EACAilC,EACA,GACAqD,EACA3B,EACAN,EACAgC,CAAA,CAEJ,MACEC,EAAS3B,EAAA,EACT1B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUqD,CAAM,EAGtB5R,EAAO,QACTuO,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAUqD,CAAM,EACxBlC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,IAEtCA,EAAQ,UAAUzkC,EAAO,kBAAkB,EAC3CykC,EAAQ,UAAUqD,CAAM,EACxBlC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,GAExC,MACF,CAEA,GAAIvO,EAAO,OAAS,QAAUA,EAAO,KAAM,CACzC,MAAM8P,EAASG,EAAA,EACfC,EACElQ,EAAO,KACP12B,EACAilC,EACA,GACAuB,EACAG,EACAN,EACAgC,CAAA,EAGF,MAAM5B,EAASE,EAAA,EACf1B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUwB,CAAM,EACxBxB,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUuB,CAAM,EACxBvB,EAAQ,UAAUwB,CAAM,EACxBL,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,EACtC,MACF,CACF,CAEA,SAASuD,GACP9R,EACA12B,EACAilC,EACAoD,EACA1B,EACAP,EACAkB,EACAK,EACAtB,EACM,CACFsB,IAAgB,OAClBS,GACE1R,EACA12B,EACAilC,EACAoD,EACA1B,EACAW,EACAjB,CAAA,EAEOsB,IAAgB,QACzBY,GACE7R,EACA12B,EACAilC,EACAoD,EACA1B,EACAP,EACAC,CAAA,GAGFkC,GACE7R,EACA12B,EACAilC,EACAoD,EACA1B,EACAP,EACAC,CAAA,EAEFpB,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,EAE3C,CAEA,SAASwD,GACPlT,EACA0P,EACAjlC,EACAqoC,EACA1B,EACAP,EACAkB,EACAK,EACAtB,EACM,CACN,GAAI9Q,EAAK,OAAS,OAASA,EAAK,OAAS,QAAUA,EAAK,OAAS,OAAQ,CACvEiT,GACEjT,EACAv1B,EACAilC,EACAoD,EACA1B,EACAP,EACAkB,EACAK,EACAtB,CAAA,EAEF,MACF,CAEA,GAAI9Q,EAAK,OAAS,MAAO,CACvB,GAAI,CAACA,EAAK,MAAO,OACjB,MAAMuS,EAAOvS,EAAK,MACdoS,IAAgB,OAClBc,GACEX,EACA7C,EACAjlC,EACAqoC,EACA1B,EACAW,EACAlB,EACA,QACAC,CAAA,EAEOsB,IAAgB,QACzBc,GACEX,EACA7C,EACAjlC,EACAqoC,EACA1B,EACAP,EACAkB,EACA,OACAjB,CAAA,EAGFoC,GACEX,EACA7C,EACAjlC,EACAqoC,EACA1B,EACAW,EACAlB,EACA,OACAC,CAAA,EAGJ,MACF,CAEA,GAAI9Q,EAAK,OAAS,MAAO,CACvB,MAAMwS,EAAWxS,EAAK,UAAY,CAAA,EAClC,GAAIwS,EAAS,SAAW,EAAG,CACrBJ,IAAgB,UAClB1C,EAAQ,UAAUzkC,EAAO,OAAO,EAChC4lC,EAAY,KAAKnB,EAAQ,WAAW,CAAC,CAAC,GAExC,MACF,CAEA,QAAS/kC,EAAI,EAAGA,EAAI6nC,EAAS,OAAQ7nC,IAAK,CACxC,MAAM22B,EAAQkR,EAAS7nC,CAAC,EAExB,GADeA,IAAM6nC,EAAS,OAAS,EAmBrCU,GACE5R,EACAoO,EACAjlC,EACAqoC,EACA1B,EACAP,EACAkB,EACAK,EACAtB,CAAA,MA3BS,CACX,MAAM2B,EAA2B,CAAA,EACjCS,GACE5R,EACAoO,EACAjlC,EACAqoC,EACA1B,EACAqB,EACAV,EACA,OACAjB,CAAA,EAEF,MAAM4B,EAAehD,EAAQ,cAAA,EAC7B,UAAWiD,KAASF,EAClB/C,EAAQ,YAAYiD,EAAOD,CAAY,CAE3C,CAaF,CACA,MACF,CAEA,GAAI1S,EAAK,OAAS,KAAM,CACtB,MAAMwS,EAAWxS,EAAK,UAAY,CAAA,EAClC,GAAIwS,EAAS,SAAW,EAAG,CACrBJ,IAAgB,SAClB1C,EAAQ,UAAUzkC,EAAO,OAAO,EAChC8mC,EAAa,KAAKrC,EAAQ,WAAW,CAAC,CAAC,GAEzC,MACF,CAEA,QAAS/kC,EAAI,EAAGA,EAAI6nC,EAAS,OAAQ7nC,IAAK,CACxC,MAAM22B,EAAQkR,EAAS7nC,CAAC,EAExB,GADeA,IAAM6nC,EAAS,OAAS,EAmBrCU,GACE5R,EACAoO,EACAjlC,EACAqoC,EACA1B,EACAP,EACAkB,EACAK,EACAtB,CAAA,MA3BS,CACX,MAAM8B,EAA4B,CAAA,EAClCM,GACE5R,EACAoO,EACAjlC,EACAqoC,EACA1B,EACAP,EACA+B,EACA,QACA9B,CAAA,EAEF,MAAM4B,EAAehD,EAAQ,cAAA,EAC7B,UAAWiD,KAASC,EAClBlD,EAAQ,YAAYiD,EAAOD,CAAY,CAE3C,CAaF,CACA,MACF,CACF,CAEA,SAASS,GACP/jB,EACA3kB,EACAilC,EACAoD,EACA1B,EACAgC,EACAtC,EACM,CACN,GAAI,CAAC1hB,EAAM,OACX,MAAMyhB,EAAwB,CAAA,EAC9BqC,GACE9jB,EACAsgB,EACAjlC,EACAqoC,EACA1B,EACAP,EACAuC,EACA,OACAtC,CAAA,EAEF,MAAMoB,EAAUxC,EAAQ,cAAA,EACxB,UAAWiD,KAAS9B,EAClBnB,EAAQ,YAAYiD,EAAOT,CAAO,CAEtC,CAEA,SAASmB,GACPjkB,EACA3kB,EACAilC,EACA4C,EACAgB,EACAxC,EACApmC,EACAqmC,EACM,CACN,GAAI,CAAC3hB,EAAM,OACX,MAAMyhB,EAAwB,CAAA,EAC9BwB,GACEjjB,EACAsgB,EACAjlC,EACA6nC,EACAzB,EACAyC,EACA,OACAxC,EACApmC,EACAqmC,CAAA,EAEF,MAAMwC,EAAc7D,EAAQ,cAAA,EAC5B,UAAWiD,KAAS9B,EAClBnB,EAAQ,YAAYiD,EAAOY,CAAW,CAE1C,CAEO,SAASC,GACdtV,EACAzzB,EACAgpC,EACA/oC,EACU,CACV,GAAIwzB,EAAK,OAAS,UAChB,OAAI,OAAOA,EAAK,OAAU,SACjB,OAAO,UAAUA,EAAK,KAAK,EAAIrzB,EAAS,MAAQA,EAAS,SAE9D,OAAOqzB,EAAK,OAAU,SAAiBrzB,EAAS,MAGtD,GAAIqzB,EAAK,OAAS,MAAO,CACvB,MAAM8S,EAAMtmC,GAAU,CAACD,CAAK,EACtBi3B,EAAWC,GAA0BzD,EAAK,KAAM8S,CAAG,EACzD,OAAOtP,EAAWA,EAAS,IAAI,KAAO72B,EAAS,IACjD,CACA,GAAIqzB,EAAK,OAAS,SAChB,OAAOrzB,EAAS,QAElB,GAAIqzB,EAAK,OAAS,KAAM,CACtB,MAAM1P,EAAK0P,EAAK,KAAK,YAAA,EACrB,GAAIuV,GAAWA,EAAQ,IAAIjlB,CAAE,EAAG,CAC9B,MAAMoH,EAAM6d,EAAQ,IAAIjlB,CAAE,EAC1B,GAAIoH,EAAI,aAAe,OACrB,OAAOA,EAAI,UAEf,CACA,GAAI,CAAC,QAAS,QAAS,SAAU,OAAQ,QAAQ,EAAE,SAASpH,CAAE,EAC5D,OAAO3jB,EAAS,KAClB,GACE,CACE,SACA,QACA,cACA,aACA,YACA,WACA,OACA,UAAA,EACA,SAAS2jB,CAAE,EAEb,OAAO3jB,EAAS,MAClB,GACE,CAAC,MAAO,QAAS,QAAS,OAAQ,MAAO,MAAO,MAAO,KAAK,EAAE,SAAS2jB,CAAE,EACzE,CACA,GAAI0P,EAAK,KAAK,OAAS,GAAKA,EAAK,KAAK,CAAC,EAAE,OAAS,MAAO,CACvD,MAAMwD,EAAWC,GACdzD,EAAK,KAAK,CAAC,EAAU,KACtBxzB,GAAU,CAACD,CAAK,CAAA,EAElB,GAAIi3B,GAAYA,EAAS,IAAI,OAAS72B,EAAS,OAAS2jB,IAAO,MAC7D,OAAO3jB,EAAS,KACpB,CACA,OAAOA,EAAS,OAClB,CACA,OAAOA,EAAS,IAClB,CACA,OAAOA,EAAS,IAClB,CAEO,SAASwmC,EACdnT,EACAzzB,EACAilC,EACA3/B,EACA2jC,EACAtC,EACAN,EACAgC,EACApoC,EACM,CACN,GAAIooC,EAAY,CACd,MAAMlT,EAAU1B,EAAK,OAAS,MAAQA,EAAK,KAAO,OAC5CwD,EAAWoR,EAAWlT,EAAS1B,CAAI,EACzC,GAAIwD,IAAa,OAAW,CACtBA,IAAagS,IACfhE,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,UAAUhO,CAAQ,EAC1BgO,EAAQ,UAAUgE,CAAS,GAE7B,MACF,CACF,CAEA,GAAIxV,EAAK,OAAS,UAAW,CAC3B,MAAMluB,EAAMkuB,EAAK,MACbluB,GAAQ,MACV0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUgE,CAAS,GAClB,OAAO1jC,GAAQ,SACpB,OAAO,UAAUA,CAAG,GACtB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU1/B,CAAG,IAErB0/B,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,YAAY1/B,CAAG,GAEhB,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,WAAW1/B,CAAG,GACb,OAAOA,GAAQ,YACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU1/B,EAAM,EAAI,CAAC,GAE/B,MACF,CAEA,GAAIkuB,EAAK,OAAS,MAAO,CACvB,GAAInuB,IAAW,GACb,MAAM,IAAI,MACR,WAAWmuB,EAAK,IAAI,4DAAA,EAGxB,MAAM8S,EAAMtmC,GAAU,CAACD,CAAK,EACtBi3B,EAAWC,GAA0BzD,EAAK,KAAM8S,CAAG,EACzD,GAAI,CAACtP,EAAU,CACb,GAAIxD,EAAK,OAAS,IAAK,CACrBwR,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CACA,MAAM,IAAI,MACR,WAAWxV,EAAK,IAAI,8BAA8BzzB,EAAM,IAAI,GAAA,CAEhE,CACAglC,GACEC,EACAhO,EAAS,OACTA,EAAS,OACTgS,EACAhS,EAAS,IAAI,IAAA,EAEf,MACF,CAEA,GAAIxD,EAAK,OAAS,SAAU,CAC1B,MAAMyV,EAAUvC,EAAA,EACVwC,EAAWxC,EAAA,EACjBC,EACEnT,EAAK,KACLzzB,EACAilC,EACA3/B,EACA4jC,EACAvC,EACAN,EACAgC,EACApoC,CAAA,EAEF2mC,EACEnT,EAAK,MACLzzB,EACAilC,EACA3/B,EACA6jC,EACAxC,EACAN,EACAgC,EACApoC,CAAA,EAGF,IAAImpC,EAAS5oC,EAAO,OACpB,GAAIizB,EAAK,KAAO,IAAK2V,EAAS5oC,EAAO,eAC5BizB,EAAK,KAAO,IAAK2V,EAAS5oC,EAAO,eACjCizB,EAAK,KAAO,IAAK2V,EAAS5oC,EAAO,eACjCizB,EAAK,KAAO,IAAK2V,EAAS5oC,EAAO,eACjCizB,EAAK,KAAO,IAAK2V,EAAS5oC,EAAO,eAExCizB,EAAK,KAAO,KACZA,EAAK,KAAO,MACZA,EAAK,KAAO,KACZA,EAAK,KAAO,MACZA,EAAK,KAAO,KACZA,EAAK,KAAO,KACZ,CACA,IAAI4V,EAAQ7oC,EAAO,MACfizB,EAAK,KAAO,IAAK4V,EAAQ7oC,EAAO,MAC3BizB,EAAK,KAAO,KAAM4V,EAAQ7oC,EAAO,MACjCizB,EAAK,KAAO,IAAK4V,EAAQ7oC,EAAO,MAChCizB,EAAK,KAAO,KAAM4V,EAAQ7oC,EAAO,MACjCizB,EAAK,KAAO,IAAK4V,EAAQ7oC,EAAO,MAChCizB,EAAK,KAAO,OAAM4V,EAAQ7oC,EAAO,OAE1CykC,EAAQ,UAAUoE,CAAK,EACvBpE,EAAQ,UAAUiE,CAAO,EACzBjE,EAAQ,UAAUkE,CAAQ,EAC1B,MAAMG,EAAYrE,EAAQ,WAAW,CAAC,EAGtCA,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC,MAAM+oC,EAAYtE,EAAQ,WAAW,CAAC,EAGtCA,EAAQ,YAAYqE,EAAWrE,EAAQ,cAAA,CAAe,EACtDA,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,YAAYsE,EAAWtE,EAAQ,cAAA,CAAe,EACtD,MACF,CAEAA,EAAQ,UAAUmE,CAAM,EACxBnE,EAAQ,UAAUiE,CAAO,EACzBjE,EAAQ,UAAUkE,CAAQ,EAC1BlE,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CAEA,GAAIxV,EAAK,OAAS,KAAM,CACtB,MAAM+V,EAAS/V,EAAK,KAAK,YAAA,EAEnBgW,EAAmC,CACvC,MAAOjpC,EAAO,aACd,MAAOA,EAAO,aACd,OAAQA,EAAO,cACf,KAAMA,EAAO,YACb,IAAKA,EAAO,YACZ,MAAOA,EAAO,cACd,MAAOA,EAAO,cACd,KAAMA,EAAO,YAAA,EAGf,GAAIipC,EAASD,CAAM,EAAG,CACpB,MAAME,EAAS/C,EAAA,EACThT,EAAMF,EAAK,KAAK,CAAC,GAAK,CAAE,KAAM,UAAW,MAAO,IAAA,EACtDmT,EACEjT,EACA3zB,EACAilC,EACA3/B,EACAokC,EACA/C,EACAN,EACAgC,EACApoC,CAAA,EAEFglC,EAAQ,UAAUwE,EAASD,CAAM,CAAC,EAClCvE,EAAQ,UAAUyE,CAAM,EACxBzE,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CAEA,GAAIO,IAAW,SAAU,CACvB,MAAME,EAAS/C,EAAA,EACTgD,EAAWhD,EAAA,EACXiD,EAASjD,EAAA,EACfC,EACEnT,EAAK,KAAK,CAAC,EACXzzB,EACAilC,EACA3/B,EACAokC,EACA/C,EACAN,EACAgC,EACApoC,CAAA,EAEF2mC,EACEnT,EAAK,KAAK,CAAC,GAAK,CAAE,KAAM,UAAW,MAAO,CAAA,EAC1CzzB,EACAilC,EACA3/B,EACAqkC,EACAhD,EACAN,EACAgC,EACApoC,CAAA,EAEEwzB,EAAK,KAAK,CAAC,IAAM,OACnBmT,EACEnT,EAAK,KAAK,CAAC,EACXzzB,EACAilC,EACA3/B,EACAskC,EACAjD,EACAN,EACAgC,EACApoC,CAAA,GAGFglC,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAU2E,CAAM,GAE1B3E,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUyE,CAAM,EACxBzE,EAAQ,UAAU0E,CAAQ,EAC1B1E,EAAQ,UAAU2E,CAAM,EACxB3E,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CAEA,MAAMY,EAAqC,CACzC,YAAarpC,EAAO,mBACpB,WAAYA,EAAO,mBACnB,UAAWA,EAAO,iBAClB,SAAUA,EAAO,iBACjB,KAAMA,EAAO,YACb,SAAUA,EAAO,eAAA,EAEnB,GAAIqpC,EAAWL,CAAM,EAAG,CACtB,MAAMM,EAASnD,EAAA,EACToD,EAASpD,EAAA,EACfC,EACEnT,EAAK,KAAK,CAAC,GAAK,CAAE,KAAM,UAAW,MAAO,IAAA,EAC1CzzB,EACAilC,EACA3/B,EACAwkC,EACAnD,EACAN,EACAgC,EACApoC,CAAA,EAEF2mC,EACEnT,EAAK,KAAK,CAAC,GAAK,CAAE,KAAM,UAAW,MAAO,EAAA,EAC1CzzB,EACAilC,EACA3/B,EACAykC,EACApD,EACAN,EACAgC,EACApoC,CAAA,EAGFglC,EAAQ,UAAU4E,EAAWL,CAAM,CAAC,EACpCvE,EAAQ,UAAU6E,CAAM,EACxB7E,EAAQ,UAAU8E,CAAM,EACxB,MAAMT,EAAYrE,EAAQ,WAAW,CAAC,EAGtCA,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC,MAAM+oC,EAAYtE,EAAQ,WAAW,CAAC,EAGtCA,EAAQ,YAAYqE,EAAWrE,EAAQ,cAAA,CAAe,EACtDA,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUgE,CAAS,EAC3BhE,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,YAAYsE,EAAWtE,EAAQ,cAAA,CAAe,EACtD,MACF,CAEA,GAAIuE,IAAW,UAAYA,IAAW,WAAY,CAChD,MAAMQ,EAAUvW,EAAK,KAAK,OACpBkW,EAAWhD,EAAA,EACjB,QAASzmC,EAAI,EAAGA,EAAI8pC,EAAS9pC,IAC3BymC,EAAA,EAEF,QAASzmC,EAAI,EAAGA,EAAI8pC,EAAS9pC,IAC3B0mC,EACEnT,EAAK,KAAKvzB,CAAC,EACXF,EACAilC,EACA3/B,EACAqkC,EAAWzpC,EACXymC,EACAN,EACAgC,EACApoC,CAAA,EAGJ,MAAM4gB,EACJ2oB,IAAW,SAAWhpC,EAAO,cAAgBA,EAAO,YACtDykC,EAAQ,UAAUpkB,CAAE,EACpBokB,EAAQ,UAAU0E,CAAQ,EAC1B1E,EAAQ,UAAU+E,CAAO,EACzB/E,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CAEA,GAAI5C,GAAcA,EAAW,IAAImD,CAAM,EAAG,CACxC,MAAMS,EAAQ5D,EAAW,IAAImD,CAAM,EAC7BQ,EAAUvW,EAAK,KAAK,OAC1B,IAAIkW,EAAWV,EACf,GAAIe,EAAU,EAAG,CACfL,EAAWhD,EAAA,EACX,QAASzmC,EAAI,EAAGA,EAAI8pC,EAAS9pC,IAC3BymC,EAAA,EAEF,QAASzmC,EAAI,EAAGA,EAAI8pC,EAAS9pC,IAC3B0mC,EACEnT,EAAK,KAAKvzB,CAAC,EACXF,EACAilC,EACA3/B,EACAqkC,EAAWzpC,EACXymC,EACAN,EACAgC,EACApoC,CAAA,CAGN,CACAglC,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,WAAWgF,CAAK,EACxBhF,EAAQ,UAAU0E,CAAQ,EAC1B1E,EAAQ,UAAU+E,CAAO,EACzB/E,EAAQ,UAAUgE,CAAS,EAC3B,MACF,CAEA,MAAM,IAAI9lC,GAAqBqmC,CAAM,CACvC,CACF,CAEA,SAASU,GACPjF,EACAve,EACAnhB,EACA4/B,EACM,CACF5/B,GAAQ,MACV0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUve,CAAG,GACZ,OAAOnhB,GAAQ,SACpB4/B,IAAY/kC,EAAS,SAAW,CAAC,OAAO,UAAUmF,CAAG,GACvD0/B,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUve,CAAG,EACrBue,EAAQ,YAAY1/B,CAAG,IAEvB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUve,CAAG,EACrBue,EAAQ,UAAU,KAAK,MAAM1/B,CAAG,CAAC,GAE1B,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUve,CAAG,EACrBue,EAAQ,UAAU,OAAO1/B,CAAG,CAAC,GACpB,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUve,CAAG,EACrBue,EAAQ,WAAW1/B,CAAG,GACb,OAAOA,GAAQ,YACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUve,CAAG,EACrBue,EAAQ,UAAU1/B,EAAM,EAAI,CAAC,EAEjC,CAgBO,SAAS4kC,GAAsBj8B,EAAqB,CACzD,OAAQA,EAAA,CACN,KAAK9N,EAAS,MACZ,MAAO,YACT,KAAKA,EAAS,MACZ,MAAO,CAAC,qBACV,KAAKA,EAAS,QACZ,MAAO,KACT,KAAKA,EAAS,KACd,KAAKA,EAAS,KACd,KAAKA,EAAS,KACZ,MAAO,GACT,KAAKA,EAAS,KACZ,OAAO,IAAI,WAAW,CAAC,EACzB,QACE,MAAO,EAAA,CAEb,CAMO,SAASgqC,GACd/rB,EACAre,EACAy3B,EACA4S,EACS,OACT,GAAI,CAAC5S,GAAWA,EAAQ,SAAW,EAAG,MAAO,GAE7C,UAAWxzB,KAAKwzB,EACd,GAAIxzB,EAAE,YAAc,OAAQ,MAAO,GAGrC,MAAMqmC,EAAgBjsB,EAAM,cAAc,IAAKne,GAC7CF,EAAM,QAAQE,CAAC,EAAE,KAAK,YAAA,CAAY,EAIpC,IAAIqqC,EAAS,EACb,GAAIF,GAAmBA,EAAgB,KAAO,EAC5C,KACEE,EAASD,EAAc,QACvBD,EAAgB,IAAIC,EAAcC,CAAM,CAAC,GAEzCA,IAKJ,IAAIC,EAAW,EACf,KAAOD,EAASD,EAAc,QAAUE,EAAW/S,EAAQ,QAAQ,CACjE,MAAMgT,GAAW5kC,EAAA4xB,EAAQ+S,CAAQ,EAAE,UAAlB,YAAA3kC,EAA2B,cAC5C,GAAI,CAAC4kC,GAAYA,IAAaH,EAAcC,CAAM,EAChD,MAAO,GAETA,IACAC,GACF,CAEA,OAAOA,IAAa/S,EAAQ,MAC9B,CAOO,SAASiT,GACdC,EACAC,EACAnT,EACAgD,EACAC,EACS,CACT,GAAI,CAACjD,GAAWA,EAAQ,SAAW,EAAG,MAAO,GAC7C,UAAWxzB,KAAKwzB,EAAS,CACvB,GAAIxzB,EAAE,YAAc,OAAQ,MAAO,GACnC,MAAMkxB,EAAUlxB,EAAE,QAClB,GAAI,CAACkxB,EAAS,MAAO,GAErB,GAAIsF,GAAaA,EAAU,OAAS,EAAG,CACrC,IAAIxD,EAAWC,GAA0B/B,EAASsF,CAAS,EAC3D,GAAI,CAACxD,GAAYyD,EAAa,CAC5B,MAAMC,EAAKD,EAAY,KAAMjzB,GAAMA,EAAE,QAAU0tB,CAAO,EAClDwF,GAAMA,EAAG,KAAK,OAAS,QACzB1D,EAAWC,GAA0ByD,EAAG,KAAK,KAAMF,CAAS,EAEhE,CACA,GAAI,CAACxD,GAAYA,EAAS,WAAa,EACrC,MAAO,EAEX,KAAO,CACL,MAAMgI,EAAW9J,EAAQ,SAAS,GAAG,EACjCA,EAAQ,MAAMA,EAAQ,YAAY,GAAG,EAAI,CAAC,EAC1CA,EAIJ,GAAI,CAHiBwV,EAAa,QAAQ,KACvC,GAAM,EAAE,KAAK,YAAA,IAAkB1L,EAAS,YAAA,CAAY,EAEpC,MAAO,EAC5B,CACF,CAEA,MAAO,EACT,CAEO,SAASnH,GACd93B,EACA6qC,EACAC,EACArT,EAC2B,CAC3B,GAAI,CAACz3B,EAAM,SAAWA,EAAM,QAAQ,SAAW,EAAG,OAAO,KACzD,MAAM+qC,EAAYD,GAAeD,EAE3BG,MAAmB,IACzB,UAAWvmC,KAAKomC,EAEZpmC,EAAE,OAAS,QACVA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAC1BA,EAAE,SACFA,EAAE,QAAU,QACZA,EAAE,QAAU,MAEZumC,EAAa,IAAIvmC,EAAE,QAAQ,YAAA,CAAa,EAI5C,MAAMwmC,EAAgBvmB,IAChB+S,GAAWA,EAAQ,OAAS,IAE5B/S,EAAK,WAAa,SACjBA,EAAK,MAAM,OAASnkB,GAAU,QAAUA,GAAU,SAInD6pC,GAA0B1lB,EAAK,MAAO1kB,EAAOy3B,EAASuT,CAAY,KAElEtmB,EAAK,iBAAmB,IAGrBA,GAIT,UAAWpe,KAAOtG,EAAM,QACtB,GAAKsG,EAAI,MAAQ/F,GAAU,SAAkB+F,EAAI,cAAgB,EAAG,CAClE,MAAM4kC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAc,CAAC,CAAC,EAClD,QAASpG,EAAI,EAAGA,EAAI2qC,EAAiB,OAAQ3qC,IAAK,CAChD,MAAMuE,EAAIomC,EAAiB3qC,CAAC,EAC5B,GACEuE,EAAE,OAAS,QACVA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAC1BA,EAAE,UAAYymC,EAAQ,MACtBzmC,EAAE,QAAU,QACZA,EAAE,QAAU,KAEZ,OAAOwmC,EAAa,CAClB,MAAO3kC,EACP,SAAU,QACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,IAAA,CAClB,EAEH,GACEzmC,EAAE,OAAS,MACX,CAACA,EAAE,OACHA,EAAE,UAAYymC,EAAQ,MACtB,MAAM,QAAQzmC,EAAE,MAAM,GACtBA,EAAE,OAAO,OAAS,EAClB,CACA,MAAM0mC,EAAe,MAAM,KACzB,IAAI,IAAI1mC,EAAE,OAAO,OAAQP,GAAMA,GAAM,IAAuB,CAAC,CAAA,EAE/D,OAAO+mC,EAAa,CAClB,MAAO3kC,EACP,SAAU,cACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,KACjB,SAAUC,CAAA,CACX,CACH,CACF,CACF,CAIF,UAAW7kC,KAAOtG,EAAM,QACtB,GAAKsG,EAAI,MAAQ/F,GAAU,QAAiB+F,EAAI,cAAgB,EAAG,CACjE,MAAM4kC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAc,CAAC,CAAC,EAClD,QAASpG,EAAI,EAAGA,EAAI2qC,EAAiB,OAAQ3qC,IAAK,CAChD,MAAMuE,EAAIomC,EAAiB3qC,CAAC,EAC5B,GACEuE,EAAE,OAAS,QACVA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAC1BA,EAAE,UAAYymC,EAAQ,MACtBzmC,EAAE,QAAU,QACZA,EAAE,QAAU,KAEZ,OAAOwmC,EAAa,CAClB,MAAO3kC,EACP,SAAU,QACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,IAAA,CAClB,EAEH,GACEzmC,EAAE,OAAS,MACX,CAACA,EAAE,OACHA,EAAE,UAAYymC,EAAQ,MACtB,MAAM,QAAQzmC,EAAE,MAAM,GACtBA,EAAE,OAAO,OAAS,EAClB,CACA,MAAM0mC,EAAe,MAAM,KACzB,IAAI,IAAI1mC,EAAE,OAAO,OAAQP,GAAMA,GAAM,IAAuB,CAAC,CAAA,EAE/D,OAAO+mC,EAAa,CAClB,MAAO3kC,EACP,SAAU,cACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,KACjB,SAAUC,CAAA,CACX,CACH,CACF,CACF,CAIF,UAAW7kC,KAAOtG,EAAM,QACtB,GAAIsG,EAAI,YAAc,EAAG,CACvB,MAAM8kC,EAAgC,CAAA,EACtC,IAAIC,EAAW,GAEf,QAASlrC,EAAI,EAAGA,EAAImG,EAAI,YAAanG,IAAK,CACxC,MAAM+qC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAcnG,CAAC,CAAC,EAC5C,EAAI0qC,EAAiB,KACxBS,GACCA,EAAG,OAAS,QACXA,EAAG,KAAO,KAAOA,EAAG,KAAO,SAC5BA,EAAG,UAAYJ,EAAQ,MACvBI,EAAG,QAAU,QACbA,EAAG,QAAU,IAAA,EAEjB,GAAI,EACFF,EAAe,KAAK,CAAC,MAChB,CACLC,EAAW,GACX,KACF,CACF,CAEA,GAAIA,EAAU,CACZ,MAAME,EAAgC,CAAA,EACtC,UAAW,KAAKH,EACdG,EAAS,EAAE,OAAQ,EAAI,EAAE,MAE3B,MAAMC,EAAoBtzB,GACxBlY,EAAM,QACNsG,EAAI,cACJA,EAAI,YACJilC,CAAA,EAGF,OAAON,EAAa,CAClB,MAAO3kC,EACP,SAAU,QACV,WAAY8kC,EAAe,CAAC,EAC5B,YAAaL,EAAU,QAAQK,EAAe,CAAC,CAAC,EAChD,QAAShrC,EAAS,KAClB,eAAgBorC,CAAA,CACjB,CACH,CACF,CAIF,UAAWllC,KAAOtG,EAAM,QACtB,GAAIsG,EAAI,cAAgB,EAAG,CACzB,MAAM4kC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAc,CAAC,CAAC,EAClD,QAASpG,EAAI,EAAGA,EAAI2qC,EAAiB,OAAQ3qC,IAAK,CAChD,MAAMuE,EAAIomC,EAAiB3qC,CAAC,EAC5B,GACEuE,EAAE,OAAS,QACVA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAC1BA,EAAE,UAAYymC,EAAQ,MACtBzmC,EAAE,QAAU,QACZA,EAAE,QAAU,KAEZ,OAAOwmC,EAAa,CAClB,MAAO3kC,EACP,SAAU,QACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,IAAA,CAClB,CAEL,CACF,CAIF,UAAW5kC,KAAOtG,EAAM,QACtB,GAAIsG,EAAI,cAAgB,EAAG,CACzB,MAAM4kC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAc,CAAC,CAAC,EAClD,QAASpG,EAAI,EAAGA,EAAI2qC,EAAiB,OAAQ3qC,IAAK,CAChD,MAAMuE,EAAIomC,EAAiB3qC,CAAC,EAC5B,GACEuE,EAAE,OAAS,QACVA,EAAE,KAAO,MAAQA,EAAE,KAAO,MAC3BA,EAAE,UAAYymC,EAAQ,MACtBzmC,EAAE,QAAU,QACZA,EAAE,QAAU,KAEZ,OAAOwmC,EAAa,CAClB,MAAO3kC,EACP,SAAU,QACV,WAAY7B,EACZ,YAAasmC,EAAU,QAAQtmC,CAAC,EAChC,QAASymC,EAAQ,IAAA,CAClB,CAEL,CACF,CAIF,GAAIzT,GAAWA,EAAQ,OAAS,GAC9B,UAAWnxB,KAAOtG,EAAM,QACtB,GAAIoqC,GAA0B9jC,EAAKtG,EAAOy3B,EAASuT,CAAY,EAC7D,GAAI1kC,EAAI,cAAgB,EAAG,CACzB,MAAM4kC,EAAUlrC,EAAM,QAAQsG,EAAI,cAAc,CAAC,CAAC,EAClD,MAAO,CACL,MAAOA,EACP,SAAU,QACV,WAAY,OACZ,YAAa,GACb,QAAS4kC,EAAQ,KACjB,iBAAkB,EAAA,CAEtB,KAAO,CAEL,MAAMK,EAAgC,CAAA,EACtC,QAASprC,EAAI,EAAGA,EAAImG,EAAI,YAAanG,IAAK,CACxC,MAAMiS,EAAMpS,EAAM,QAAQsG,EAAI,cAAcnG,CAAC,CAAC,EACxCsrC,EAAWZ,EAAiB,KAC/BpmC,GACCA,EAAE,OAAS,QACVA,EAAE,KAAO,KAAOA,EAAE,KAAO,SAC1BA,EAAE,UAAY2N,EAAI,MAClB3N,EAAE,QAAU,QACZA,EAAE,QAAU,IAAA,EAEZgnC,EACFF,EAASn5B,EAAI,IAAI,EAAIq5B,EAAS,MAE9BF,EAASn5B,EAAI,IAAI,EAAI+3B,GAAsB/3B,EAAI,IAAI,CAEvD,CACA,MAAMo5B,EAAoBtzB,GACxBlY,EAAM,QACNsG,EAAI,cACJA,EAAI,YACJilC,CAAA,EAEF,MAAO,CACL,MAAOjlC,EACP,SAAU,QACV,WAAY,OACZ,YAAa,GACb,QAASlG,EAAS,KAClB,eAAgBorC,EAChB,iBAAkB,EAAA,CAEtB,EAKN,OAAO,IACT,CAUO,SAASnI,GACdqI,EACA5R,EACAD,EACAY,EACAkR,EAC2B,CAC3B,GACED,EAAS,KAAO,KAChB,CAAC5R,EAAW,SACZA,EAAW,QAAQ,SAAW,EAE9B,OAAO,KAGT,MAAM8R,EAAe1U,GAA0BwU,EAAS,QAASjR,CAAS,EACpEoR,EAAgB3U,GAA0BwU,EAAS,SAAUjR,CAAS,EAC5E,GAAI,CAACmR,GAAgB,CAACC,EAAe,OAAO,KAE5C,IAAIC,EAAkC,KAClCC,EAAkC,KAgBtC,GAbEH,EAAa,WAAa/R,GAC1BgS,EAAc,SAAWhS,GAEzBiS,EAAWF,EACXG,EAAWF,GAEXA,EAAc,WAAahS,GAC3B+R,EAAa,SAAW/R,IAExBiS,EAAWD,EACXE,EAAWH,GAGT,CAACE,GAAY,CAACC,EAAU,OAAO,KAEnC,IAAIC,EAAkC,KAClC1T,EAAW,IAEf,UAAWhyB,KAAOwzB,EAAW,QAC3B,GAAIxzB,EAAI,cAAgB,GAAKA,EAAI,cAAc,CAAC,IAAMwlC,EAAS,OAAQ,CACrE,MAAMvT,GAAQjyB,EAAI,MAAQ/F,GAAU,WAAa,EAC3Ci4B,GAAYlyB,EAAI,MAAQ/F,GAAU,UAAY,EAC9Ck4B,EAAOF,EAAO,EAAIC,EAAW,EAAI,EACnCC,EAAOH,IACTA,EAAWG,EACXuT,EAAU1lC,EAEd,CAGF,GAAI,CAAC0lC,EAAS,OAAO,KAErB,MAAMxT,GACHwT,EAAQ,OAASzrC,GAAU,QAAUA,GAAU,WAAa,EAC/D,MAAO,CACL,MAAOyrC,EACP,SAAAxT,EACA,SAAAsT,EACA,SAAAC,EACA,YAAAJ,CAAA,CAEJ,CAKO,SAASM,GACdtT,EACA9uB,EAGY,gCACZ,MAAM+uB,EAA8B,CAClCD,EAAK,MACL,KAAI9yB,GAAA8yB,EAAK,eAAL,YAAA9yB,GAAmB,IAAKwT,GAAMA,EAAE,SAAU,CAAA,CAAC,EAM3C6yB,EAFevH,IAAoB96B,GAAA,YAAAA,EAAS,UAAW8uB,EAAK,OAAO,EAEhD,SAASA,CAAI,EAChC8B,EAAyByR,EAAI,eAAiBtT,EAC9CoF,EAAekO,EAAI,aACnBC,EAAcD,EAAI,QAExB,GAAIA,EAAI,cAAe,CACrB,MAAME,EAAe,IAAIrH,GACzBqH,EAAa,UAAU5rC,EAAO,OAAO,EACrC,MAAMyjB,EAAMmoB,EAAa,YAAA,EACzB,OAAIzT,EAAK,gBAAgB1U,EAAY,cAAgB0U,EAAK,eACzD1U,EAAY,UAAYwW,EACxBxW,EAAY,aAAe+Z,EACrB/Z,CACT,CAEA,MAAMooB,EAAcH,EAAI,KACpBG,IAAgB1T,GAClB,OAAO,OAAOA,EAAM0T,CAAW,EAGjC,MAAMC,EACJ3T,EAAK,eAAiB,QAAaA,EAAK,aAAa,OAAS,EAE1D0F,EAAaC,GAAgB3F,EAAK,OAAO,EACzCmS,EAAczM,EAAaoH,GAAmBpH,CAAU,EAAI,CAAA,EAC5DE,EAAkBC,GAA8BH,CAAU,EAG1DkO,EAAiC,MAAM,KAC3C,CAAE,OAAQ9R,EAAU,MAAA,EACpB,IAAM,CAAA,CAAC,EAEH+R,MAAsB,IAE5B,GAAIF,GAAeH,EACjB,QAASjsC,EAAI,EAAGA,EAAIu6B,EAAU,OAAQv6B,IAAK,CACzC,MAAMusC,EAAU7T,EAAe,QAAQ6B,EAAUv6B,CAAC,CAAC,EACnD,GAAIusC,IAAY,GAAI,CAClB,MAAMjV,EAAU2U,EAAY,mBAAmB,IAAIM,CAAO,GAAK,CAAA,EAC/D,GACEvsC,IAAM,GACLy4B,EAAK,gBAAgBjZ,GAAAiZ,EAAK,aAAaz4B,EAAI,CAAC,IAAvB,YAAAwf,GAA0B,QAAS,QACzD,CACA6sB,EAAcrsC,CAAC,EAAIs3B,EACnB,UAAW/yB,KAAK+yB,EACdgV,EAAgB,IAAI/nC,CAAC,CAEzB,CACF,CACF,CAGF,MAAMioC,EAAkC,CAAA,EACxC,UAAWjoC,KAAK85B,EACTiO,EAAgB,IAAI/nC,CAAC,GACxBioC,EAAiB,KAAKjoC,CAAC,EAG3B,MAAMkoC,EAAsBrO,GAAgBoO,CAAgB,EAGtD3N,EACJuN,GACA5B,GACEjQ,EAAU,CAAC,EACX9B,EAAK,aACLA,EAAK,QACL8B,EACA9B,EAAK,WAAA,EAGHiU,EAAqB7N,EACvBpG,EAAK,QAAS,IAAK10B,GAAM,CACvB,MAAMmO,EAAMnO,EAAE,SAAW,GACnBg7B,EAAW7sB,EAAI,SAAS,GAAG,EAC7BA,EAAI,MAAMA,EAAI,YAAY,GAAG,EAAI,CAAC,EAClCA,EACJ,MAAO,CAAE,GAAGnO,EAAG,QAASg7B,CAAA,CAC1B,CAAC,EACD,OAEE4N,EAAaP,EACfxU,GACE2C,EAAU,CAAC,EACX8R,EAAc,CAAC,EACfzB,EACA8B,CAAA,EAEF,KAEEE,EAAuB/N,GAAe,CAAC,EAAC8N,GAAA,MAAAA,EAAY,kBAE1D,IAAIE,EAAatS,EAAU,OACvBuS,EAAe,GACfH,GAAcE,EAAa,KAC7BC,EAAeD,KAGjB,MAAME,EAA6C,IAAI,MACrDxS,EAAU,MAAA,EACV,KAAK,IAAI,EACX,GAAI6R,GAAe3T,EAAK,aACtB,QAASz4B,EAAI,EAAGA,EAAIu6B,EAAU,OAAQv6B,IAAK,CACzC,MAAMkjC,EAAQzK,EAAK,aAAaz4B,EAAI,CAAC,EACrC,GAAI6sC,EAAa,GAAI,CACnB,MAAMroB,EAAO2e,GACXD,EACA3I,EAAUv6B,CAAC,EACXA,EACAu6B,EACAsS,CAAA,EAEEroB,IACFuoB,EAAY/sC,CAAC,EAAIwkB,EACjBqoB,IAEJ,CACF,CAGF,MAAMG,EAAeH,EACrB,GAAIG,EAAe,GACjB,MAAM,IAAI1qC,GAAoB0qC,EAAc,EAAE,EAIhD,UAAWzoC,KAAK85B,EACd,GAAI95B,EAAE,OAAS,MAAQ,CAACA,EAAE,QAAU,CAACA,EAAE,QAAUA,EAAE,OAAO,SAAW,GAAI,CACvE,MAAM2nC,EAAe,IAAIrH,GACzBqH,EAAa,UAAU5rC,EAAO,OAAO,EACrC,MAAMyjB,EAAMmoB,EAAa,YAAA,EACzB,OAAIzT,EAAK,gBAAgB1U,EAAY,cAAgB0U,EAAK,eACnD1U,CACT,CAGF,MAAMkpB,EAAqB,CAAA,EACrB7G,MAAmB,IACzB,UAAW7hC,KAAKqmC,EACd,GAAIrmC,EAAE,OAAS,KAAM,CACnB,MAAMsiC,EAASoG,EAAO,OACtB7G,EAAa,IAAI7hC,EAAGsiC,CAAM,EAC1B,MAAMt/B,MAAQ,IACd,GAAIhD,EAAE,OACJ,UAAWP,KAAKO,EAAE,OACZP,GAAM,OACRuD,EAAE,IAAIvD,CAAC,EACH,OAAOA,GAAM,SACfuD,EAAE,IAAI,OAAOvD,CAAC,CAAC,EACN,OAAOA,GAAM,UAAY,OAAO,cAAcA,CAAC,GACxDuD,EAAE,IAAI,OAAOvD,CAAC,CAAC,GAKvBipC,EAAO,KAAK1lC,CAAC,CACf,CAGF,MAAMogC,MAAiB,IACvB,QAAS3nC,EAAI,EAAGA,EAAI4qC,EAAY,OAAQ5qC,IACtC2nC,EAAW,IAAIiD,EAAY5qC,CAAC,EAAGA,CAAC,EAGlC,GAAI4qC,EAAY,OAAS,GAAK,GAC5B,MAAM,IAAIpoC,GAAsBooC,EAAY,OAAS,CAAC,EAGxD,GAAInS,EAAK,SAAWA,EAAK,QAAQ,OAAS,EACxC,MAAM,IAAI31B,GAA2B21B,EAAK,QAAQ,MAAM,EAG1D,GAAIA,EAAK,SAAWA,EAAK,QAAQ,OAAS,EACxC,MAAM,IAAIz1B,GAA2By1B,EAAK,QAAQ,MAAM,EAG1D,MAAMsM,EAAU,IAAIF,GAEpB,GAAIpM,EAAK,QAAU,QAAaA,EAAK,OAAS,EAC5C,OAAAsM,EAAQ,UAAUzkC,EAAO,OAAO,EACzBykC,EAAQ,YAAA,EAGjB,IAAImI,EAAUtC,EAAY,OAAS,EACnC,MAAMuC,EAAY1U,EAAK,SAAW,QAAaA,EAAK,OAAS,EACvD2U,EAAW3U,EAAK,QAAU,QAAaA,EAAK,MAAQ,EACpD4U,EAAYF,EAAYD,IAAY,GACpCI,EAAWF,EAAWF,IAAY,GAExC,GAAIA,GAAW,GACb,MAAM,IAAI1qC,GAAsB0qC,CAAO,EAGzC,MAAMptC,EAAQ24B,EAAK,MAGnB,QAASz4B,EAAI,EAAGA,EAAI4qC,EAAY,OAAQ5qC,IAAK,CAC3C,MAAMw2B,EAASoU,EAAY5qC,CAAC,EAC5B,GAAIw2B,EAAO,OAAS,MAAO,CACzB,MAAMyQ,EAAWjnC,EAAI,EAAI,EACnBqF,EAAMmxB,EAAO,MAEnB,GAAInxB,GAAQ,KACV0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,UACjB,OAAO5hC,GAAQ,SAAU,CAClC,MAAM0xB,GAAWP,EAAO,QACpBQ,GAA0BR,EAAO,QAAS+D,CAAS,EACnD,OACAxD,IAAYA,GAAS,IAAI,OAAS72B,EAAS,SAC7C6kC,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,YAAY1/B,CAAG,GACb,OAAO,UAAUA,CAAG,GAK9B0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU,KAAK,MAAM1/B,CAAG,CAAC,IANjC0/B,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,YAAY1/B,CAAG,EAM3B,MAAW,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU,OAAO1/B,CAAG,CAAC,GACpB,OAAOA,GAAQ,UACxB0/B,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,WAAW1/B,CAAG,GACb,OAAOA,GAAQ,YACxB0/B,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkC,CAAQ,EAC1BlC,EAAQ,UAAU1/B,EAAM,EAAI,CAAC,EAEjC,CACF,CAeA,GAZI8nC,IACFpI,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUsI,CAAS,EAC3BtI,EAAQ,UAAUtM,EAAK,MAAO,GAE5B2U,IACFrI,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUuI,CAAQ,EAC1BvI,EAAQ,UAAUtM,EAAK,KAAM,GAK5BA,EAAK,YAAcA,EAAK,WAAW,OAAS,GAC5CA,EAAK,SAAWA,EAAK,QAAQ,OAAS,EACvC,CACA,MAAM8U,IAAIriB,GAAAuN,EAAK,UAAL,YAAAvN,GAAc,SAAU,EAC5BsiB,EAAa/U,EAAK,YAAc,CAAA,EAChCgV,EAAID,EAAW,OAGfE,EAA8B,CAAA,EACpC,UAAWC,KAASlV,EAAK,SAAW,CAAA,EAAI,CACtC,MAAMmV,EACJ,OAAOD,GAAU,SACbA,EACCA,EAAM,UACNA,EAAM,KAAO3Y,GAAmB2Y,EAAM,IAAI,EAAI,aAE/CE,GAAiB1iB,GAAAsN,EAAK,cAAL,YAAAtN,GAAkB,KAAM5jB,IAAM,CACnD,GAAIA,GAAE,QAAUqmC,EAAU,MAAO,GACjC,GAAI,OAAOD,GAAU,UAAYA,EAAM,KACrC,OAAO,KAAK,UAAUpmC,GAAE,IAAI,IAAM,KAAK,UAAUomC,EAAM,IAAI,EAE7D,GAAI,OAAOA,GAAU,UAAYA,EAAM,SAAS,GAAG,EACjD,GAAI,CACF,MAAM/G,GAASpS,GAAgBmZ,CAAK,EACpC,OAAO,KAAK,UAAUpmC,GAAE,IAAI,IAAM,KAAK,UAAUq/B,EAAM,CACzD,MAAQ,CACN,MAAO,EACT,CAEF,MAAO,EACT,GAEMkH,GAAeD,GAAA,YAAAA,EAAgB,QAASD,EACxC17B,EAAMpS,EAAM,QAAQ,KACvBG,IAAMA,GAAE,OAAS2tC,GAAY3tC,GAAE,OAAS6tC,CAAA,EAEvC57B,EACFw7B,EAAc,KAAK,CAAE,GAAGx7B,EAAK,KAAM47B,EAAc,EAEjDJ,EAAc,KAAK,CACjB,KAAMI,EACN,KAAM5tC,EAAS,KACf,MAAOC,EAAW,KAClB,UAAW,CAAA,CACZ,CAEL,CACA,QAASgZ,EAAI,EAAGA,EAAIq0B,EAAW,OAAQr0B,IAAK,CAC1C,MAAMoM,EAAMioB,EAAWr0B,CAAC,EAClB40B,EACJxoB,EAAI,QAAUA,EAAI,QAAU,GAAGA,EAAI,IAAI,IAAIA,EAAI,OAAO,GAAKA,EAAI,MAC3DyoB,EAAUzoB,EAAI,OAAS,QAAUrlB,EAAS,MAAQA,EAAS,QACjEwtC,EAAc,KAAK,CACjB,KAAMK,EACN,KAAMC,EACN,MAAO7tC,EAAW,KAClB,UAAW,CAAA,CACZ,CACH,CAIA,MAAM8tC,EADgBf,EAEhBgB,GAAiBD,EAAmBV,EACpCY,GAAYD,GAAiB,EAC7BE,GAAiBD,GAAY,EAC7BE,GAAmBD,GAAiBb,EACpCe,GAAYD,GAAmBZ,EAErC,GAAIa,IAAa,GACf,MAAM,IAAI9rC,GAAsB8rC,EAAS,EAI3CvJ,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAU,CAAC,EAGnBA,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAGnCilC,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAU,CAAC,EACnB,MAAMwJ,GAAkBxJ,EAAQ,WAAW,CAAC,EAGtCyJ,GAAezJ,EAAQ,cAAA,EACvB4D,GAA2B,CAAA,EAcjC,GAZAD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,GACAlQ,EAAK,WACL,OACA2N,CAAA,EAIE3N,EAAK,QACP,QAAS10B,EAAI,EAAGA,EAAI00B,EAAK,QAAQ,OAAQ10B,IAAK,CAC5C,MAAM4pC,EAAQlV,EAAK,QAAQ10B,CAAC,EACtBglC,EAAYkF,EAAmBlqC,EACrC,IAAIyiC,EAAU,KAAK,IAAI8H,GAAY,EAAG,EAAE,EACxC,MAAM7H,EAAW,IAAM,CACrB,GAAID,GAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,CAAO,EAC1D,OAAOA,GACT,EAEA,GAAI,OAAOmH,GAAU,UAAYA,EAAM,KACrCjH,EACEiH,EAAM,KACN7tC,EACAilC,EACA,EACAgE,EACAtC,EACAhO,EAAK,UAAA,MAEF,CACL,MAAMxD,GAAU,OAAO0Y,GAAU,SAAWA,EAAQA,EAAM,QACpDc,IAAYC,IAAAtjB,GAAAqN,EAAK,cAAL,YAAArN,GAAkB,KACjC7jB,IAAMA,GAAE,QAAU0tB,MADH,YAAAyZ,GAEf,KACH,GAAID,GACF/H,EACE+H,GACA3uC,EACAilC,EACA,EACAgE,EACAtC,EACAhO,EAAK,UAAA,MAEF,CACL,MAAMtB,GAASr3B,EAAM,QAAQ,UAAWG,IAAMA,GAAE,OAASg1B,EAAO,EAChE,GAAIkC,KAAW,GAAI,CACjB,MAAMjlB,GAAMpS,EAAM,QAAQq3B,EAAM,EAChC2N,GAAeC,EAAS,EAAG5N,GAAQ4R,EAAW72B,GAAI,IAAI,CACxD,KACE,IAAI,CACF,MAAM00B,GAASpS,GAAgBS,EAAO,EACtCyR,EACEE,GACA9mC,EACAilC,EACA,EACAgE,EACAtC,EACAhO,EAAK,UAAA,CAET,MAAQ,CACN,MAAM,IAAI,MACR,oBAAoBxD,EAAO,yBAAyBn1B,EAAM,IAAI,GAAA,CAElE,CAEJ,CACF,CACF,CAIE2tC,IAAM,GAAKF,EAAI,IACjBxI,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAU,GAAG,EACrBA,EAAQ,UAAU,CAAC,GAIrB,MAAM4J,GAAWnB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,OAAO,EACpD4yB,GAASpB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EAChD6yB,GAASrB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EAChD8yB,GAAStB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EAChD+yB,GAASvB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EAGtD,GAAI2yB,IAAYC,IAAUC,GAAQ,CAChC,MAAMG,EAAWxB,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,OAAO,EAC1D,IAAIizB,EAAS,IACb,GAAID,GAAYA,EAAS,SAAWA,EAAS,UAAY,IAAK,CAC5D,MAAM7X,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,OAAS+uC,EAAS,OAAA,EAE7B,GAAI7X,IAAW,GAAI,CACjB,MAAMjlB,EAAMpS,EAAM,QAAQq3B,CAAM,EAChC8X,EAASf,GACTpJ,GAAeC,EAAS,EAAG5N,EAAQ8X,EAAQ/8B,EAAI,IAAI,CACrD,CACF,CACA6yB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAUkK,CAAM,EACxBlK,EAAQ,UAAU,CAAC,CACrB,CAGA,GAAI8J,IAAUD,GAAQ,CACpB,MAAMM,EAAS1B,EAAW,KACvBxxB,GAAMA,EAAE,OAAS,OAASA,EAAE,OAAS,KAAA,EAExC,IAAIizB,EAAS,IACb,GAAIC,GAAUA,EAAO,SAAWA,EAAO,UAAY,IAAK,CACtD,MAAM/X,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,OAASivC,EAAO,OAAA,EAE3B,GAAI/X,IAAW,GAAI,CACjB,MAAMjlB,EAAMpS,EAAM,QAAQq3B,CAAM,EAChC8X,EAASf,GAAiB,EAC1BpJ,GAAeC,EAAS,EAAG5N,EAAQ8X,EAAQ/8B,EAAI,IAAI,CACrD,CACF,CACA6yB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAUkK,CAAM,EACxBlK,EAAQ,UAAU,CAAC,CACrB,CAGA,GAAI+J,GAAQ,CACV,MAAMK,EAAS3B,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EACtD,IAAIizB,EAAS,IACb,GAAIE,GAAUA,EAAO,SAAWA,EAAO,UAAY,IAAK,CACtD,MAAMhY,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,OAASkvC,EAAO,OAAA,EAE3B,GAAIhY,IAAW,GAAI,CACjB,MAAMjlB,EAAMpS,EAAM,QAAQq3B,CAAM,EAChC8X,EAASf,GAAiB,EAC1BpJ,GAAeC,EAAS,EAAG5N,EAAQ8X,EAAQ/8B,EAAI,IAAI,CACrD,CACF,CACA6yB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAUkK,CAAM,EACxBlK,EAAQ,UAAU,CAAC,CACrB,CAGA,GAAIgK,GAAQ,CACV,MAAMK,EAAS5B,EAAW,KAAMxxB,GAAMA,EAAE,OAAS,KAAK,EACtD,IAAIizB,EAAS,IACb,GAAIG,GAAUA,EAAO,SAAWA,EAAO,UAAY,IAAK,CACtD,MAAMjY,EAASr3B,EAAM,QAAQ,UAC1BG,GAAMA,EAAE,OAASmvC,EAAO,OAAA,EAE3B,GAAIjY,IAAW,GAAI,CACjB,MAAMjlB,EAAMpS,EAAM,QAAQq3B,CAAM,EAChC8X,EAASf,GAAiB,EAC1BpJ,GAAeC,EAAS,EAAG5N,EAAQ8X,EAAQ/8B,EAAI,IAAI,CACrD,CACF,CACA6yB,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUkJ,CAAgB,EAClClJ,EAAQ,UAAUwI,CAAC,EACnBxI,EAAQ,UAAUkK,CAAM,EACxBlK,EAAQ,UAAU,CAAC,CACrB,CAGA,MAAMsK,GAAatK,EAAQ,cAAA,EAC3B,UAAWiD,KAASW,GAClB5D,EAAQ,YAAYiD,EAAOqH,EAAU,EAIvCtK,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnB,MAAMuK,EAAkBvK,EAAQ,WAAW,CAAC,EAG5CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAWyJ,EAAY,EAG/B,MAAMe,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYwJ,GAAiBgB,EAAM,EAC3CxK,EAAQ,YAAYuK,EAAiBC,EAAM,EAG3C,MAAMC,GAAiBzK,EAAQ,cAAA,EAC/BA,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUqJ,EAAc,EAChCrJ,EAAQ,UAAUoJ,EAAS,EAC3B,MAAMsB,GAAoB1K,EAAQ,WAAW,CAAC,EAGxC2K,GAAa3K,EAAQ,cAAA,EAC3BA,EAAQ,UAAUzkC,EAAO,OAAO,EAGhC,MAAMqvC,GAAkB5K,EAAQ,cAAA,EAChCA,EAAQ,YAAY0K,GAAmBE,EAAe,EAGtD,QAASx2B,EAAI,EAAGA,EAAIq0B,EAAW,OAAQr0B,IAAK,CAC1C,MAAMoM,EAAMioB,EAAWr0B,CAAC,EAClBy2B,EAASvB,GAAmBl1B,EAClC,IAAI02B,EAAS1B,GACT2B,EAAS,EACTvqB,EAAI,OAAS,SACfsqB,EAAS1B,GACT2B,EAAS,GACAvqB,EAAI,OAAS,OACtBsqB,EAAS1B,GACT2B,EAAS,GACAvqB,EAAI,OAAS,OACtBsqB,EAAS1B,GACT2B,EAAS,GACAvqB,EAAI,OAAS,OACtBsqB,EAAS1B,GAAY,EACrB2B,EAAS,GACAvqB,EAAI,OAAS,QACtBsqB,EAAS1B,GAAY,EACrB2B,EAAS,GAGX/K,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAU8K,CAAM,EACxB9K,EAAQ,UAAUoJ,GAAY,CAAC,EAC/BpJ,EAAQ,UAAU6K,CAAM,EACxB7K,EAAQ,UAAU+K,CAAM,CAC1B,CAGA,MAAM3H,GAAa,CAACzf,EAAe6K,IAAwC,OAEzE,QAASpa,EAAI,EAAGA,EAAIq0B,EAAW,OAAQr0B,IAAK,CAC1C,MAAMoM,EAAMioB,EAAWr0B,CAAC,EAClB42B,GAAS1B,GAAmBl1B,EAElC,GAAIuP,IACEnD,EAAI,OAASA,EAAI,QAAUmD,IACXnD,EAAI,QACpB,GAAGA,EAAI,IAAI,IAAIA,EAAI,OAAO,GAC1BA,EAAI,QACYmD,GACR,GAAGnD,EAAI,IAAI,IAAIA,EAAI,SAAW,GAAG,MACjCmD,EAAK,QAAQ,OAAQ,EAAE,GAC/BnD,EAAI,OAASmD,GAAM,OAAOqnB,GAGhC,GAAIxc,GAAQA,EAAK,OAAS,KAAM,CAC9B,MAAM+V,GAAS/V,EAAK,KAAK,YAAA,EACzB,GAAIhO,EAAI,OAAS+jB,GACf,GAAIA,KAAW,QAAS,CACtB,MAAMrT,GAAO1C,EAAK,KAAK,CAAC,EAClByc,GACJ/Z,IAAQA,GAAK,OAAS,MAAQA,GAAK,KAAO,OAC5C,GACE1Q,EAAI,UAAY,QAChBA,EAAI,UAAY,KAChBA,EAAI,UAAYyqB,GAEhB,OAAOD,EAEX,KAAO,CACL,MAAM9Z,GAAO1C,EAAK,KAAK,CAAC,EAClByc,GACJ/Z,IAAQA,GAAK,OAAS,MAAQA,GAAK,KAAO,OAC5C,GAAI1Q,EAAI,UAAYyqB,GAClB,OAAOD,EAEX,CAEJ,CACF,CAGA,GAAItX,EAAK,QACP,QAAS10B,EAAI,EAAGA,EAAI00B,EAAK,QAAQ,OAAQ10B,IAAK,CAC5C,MAAM4pC,EAAQlV,EAAK,QAAQ10B,CAAC,EACtBksC,GAAO7B,GAAiBrqC,EACxB6pC,GAAW,OAAOD,GAAU,SAAWA,EAAQA,EAAM,QACrDuC,GAAQ,OAAOvC,GAAU,SAAWA,EAAM,KAAO,OAEvD,GAAIjlB,EAAM,CAER,GADIklB,KAAallB,GACbwnB,IAASlb,GAAmBkb,EAAK,IAAMxnB,EAAM,OAAOunB,GACxD,MAAME,IAAcxqC,EAAA8yB,EAAK,cAAL,YAAA9yB,EAAkB,KAAM4B,IAAMA,GAAE,QAAUmhB,GAC9D,GAAIynB,GAAa,CAEf,GADIvC,KAAauC,GAAY,OAE3BD,IACA,KAAK,UAAUA,EAAK,IAAM,KAAK,UAAUC,GAAY,IAAI,EAEzD,OAAOF,GACT,GAAI,OAAOtC,GAAU,UAAYA,EAAM,SAAS,GAAG,EACjD,GAAI,CACF,MAAM/G,GAASpS,GAAgBmZ,CAAK,EACpC,GACE,KAAK,UAAU/G,EAAM,IAAM,KAAK,UAAUuJ,GAAY,IAAI,EAE1D,OAAOF,EACX,MAAQ,CAAC,CAEb,CACF,CAEA,GAAI1c,EAAM,CAIR,GAHI2c,IAAS,KAAK,UAAUA,EAAK,IAAM,KAAK,UAAU3c,CAAI,GAGtDA,EAAK,OAAS,OAASqa,KAAara,EAAK,KAC3C,OAAO0c,GAET,GAAI,OAAOtC,GAAU,UAAYA,EAAM,SAAS,GAAG,EACjD,GAAI,CACF,MAAM/G,GAASpS,GAAgBmZ,CAAK,EACpC,GAAI,KAAK,UAAU/G,EAAM,IAAM,KAAK,UAAUrT,CAAI,EAChD,OAAO0c,EACX,MAAQ,CAAC,CAEb,CACF,CAIJ,EAGA,GAAIxX,EAAK,QAAUA,EAAK,OAAO,OAAS,EAAG,CACzC,IAAI2X,EAAiC,KACjC3X,EAAK,OAAO,SAAW,EACzB2X,EAAa3X,EAAK,OAAO,CAAC,EAE1B2X,EAAa,CAAE,KAAM,MAAO,SAAU3X,EAAK,MAAA,EAG7C,MAAMgQ,EAAwB,CAAA,EAC9B,IAAI4H,EAAgB,KAAK,IAAI/B,GAAY,EAAG,EAAE,EAM9C9F,GACE4H,EACAtwC,EACAilC,EACAoD,GATqB,IAAM,CAC3B,GAAIkI,GAAiB,GAAI,MAAM,IAAI7tC,GAAsB6tC,CAAa,EACtE,OAAOA,GACT,EAQE5H,EACAhQ,EAAK,UAAA,EAGP,UAAWuP,KAASS,EAClB1D,EAAQ,YAAYiD,EAAOwH,EAAc,CAE7C,CAEIrC,IACFpI,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3BtI,EAAQ,WAAWyK,EAAc,GAInCzK,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUqJ,EAAc,EAChCrJ,EAAQ,UAAUwI,EAAIE,CAAC,EAEnBL,IACFrI,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BvI,EAAQ,WAAW2K,EAAU,GAI/B3K,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAWyK,EAAc,EAEjC,MAAMxqC,GAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,GAAe,cAAgB0oC,EAC/B1oC,GAAe,OAASioC,EACxBxU,EAAa,cAAgBiV,EACvB1oC,EACT,CAGA,MAAMsrC,EAAalE,EAEf,KADAxU,GAAgB93B,EAAOu+B,EAAiBuM,EAAanS,EAAK,OAAO,EAMrE,GACE,CAAC2T,GACD3T,EAAK,SACLA,EAAK,QAAQ,OAAS,GACtB,EAAC6X,GAAA,MAAAA,EAAW,kBACZ,CACA,MAAMC,EAAI9X,EAAK,QAAQ,OACjB+X,EAAkBtD,EAClBoB,EAAYkC,EAAkBD,EAEpC,GAAIjC,GAAa,GACf,MAAM,IAAI9rC,GAAsB8rC,CAAS,EAG3C,MAAMmC,EAAqB,CACzB,QAASF,EACT,WAAY9X,EAAK,QAAQ,IAAK10B,IAAOA,GAAE,YAAc,OAAS,EAAI,CAAE,EACpE,WAAY00B,EAAK,QAAQ,IAAK10B,IAC5BA,GAAE,YAAc,aACZ,EACAA,GAAE,YAAc,cACd,EACAA,GAAE,YAAc,OACd,EACA,CAAA,EAEV,MAAO00B,EAAK,MACZ,OAAQA,EAAK,MAAA,EAEfA,EAAK,SAAW,CAACgY,CAAO,EAGxB1L,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU,CAAC,EAGnBA,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAGnCilC,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAU,CAAC,EACnB,MAAMwJ,GAAkBxJ,EAAQ,WAAW,CAAC,EAGtCyJ,EAAezJ,EAAQ,cAAA,EACvB4D,GAA2B,CAAA,EAEjCD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,GACAlQ,EAAK,WACL,OACA2N,CAAA,EAIF,QAASriC,GAAI,EAAGA,GAAIwsC,EAAGxsC,KAAK,CAC1B,MAAM2sC,GAAUjY,EAAK,QAAQ10B,EAAC,EACxBglC,GAAYyH,EAAkBzsC,GACpC,IAAIyiC,GAAU,GACd,MAAMC,GAAW,IAAM,CACrB,GAAID,IAAW,GAAI,MAAM,IAAIhkC,GAAsBgkC,EAAO,EAC1D,OAAOA,IACT,EAEA,GAAIkK,GAAQ,KACVhK,EACEgK,GAAQ,KACR5wC,EACAilC,EACA,EACAgE,GACAtC,GACAhO,EAAK,UAAA,UAEEiY,GAAQ,QAAS,CAC1B,MAAMzb,GAAUyb,GAAQ,QAElBjC,IAAYkC,IAAAC,GAAAnY,EAAK,cAAL,YAAAmY,GAAkB,KACjCrpC,IAAMA,GAAE,QAAU0tB,MADH,YAAA0b,GAEf,KACH,GAAIlC,GACF/H,EACE+H,GACA3uC,EACAilC,EACA,EACAgE,GACAtC,GACAhO,EAAK,UAAA,MAEF,CAEL,MAAMtB,GAASr3B,EAAM,QAAQ,UAAWG,GAAMA,EAAE,OAASg1B,EAAO,EAChE,GAAIkC,KAAW,GAAI,CACjB,MAAMjlB,EAAMpS,EAAM,QAAQq3B,EAAM,EAChC2N,GAAeC,EAAS,EAAG5N,GAAQ4R,GAAW72B,EAAI,IAAI,CACxD,KAEE,IAAI,CACF,MAAM00B,EAASpS,GAAgBS,EAAO,EACtCyR,EACEE,EACA9mC,EACAilC,EACA,EACAgE,GACAtC,GACAhO,EAAK,UAAA,CAET,MAAQ,CACN,MAAM,IAAI,MACR,oBAAoBxD,EAAO,yBAAyBn1B,EAAM,IAAI,GAAA,CAElE,CAEJ,CACF,CACF,CAGAilC,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUyL,CAAe,EACjCzL,EAAQ,UAAUwL,CAAC,EACnBxL,EAAQ,UAAU,CAAC,EAGnB,MAAMsK,GAAatK,EAAQ,cAAA,EAC3B,UAAWiD,MAASW,GAClB5D,EAAQ,YAAYiD,GAAOqH,EAAU,EAIvCtK,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnB,MAAMuK,GAAkBvK,EAAQ,WAAW,CAAC,EAG5CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAWyJ,CAAY,EAG/B,MAAMe,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYwJ,GAAiBgB,EAAM,EAC3CxK,EAAQ,YAAYuK,GAAiBC,EAAM,EAG3CxK,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EAGnB,MAAM8L,GAAc9L,EAAQ,cAAA,EAC5BA,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAW8L,EAAW,EAG9B9L,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,GAAe,SAAWyzB,EAAK,SAC/BzzB,GAAe,OAASioC,EACrBhB,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEnCjnC,EACT,CAGA,MAAM8rC,GACJrY,EAAK,cAAgB,QACrBA,EAAK,YAAY,OAAS,GAC1B,EACEA,EAAK,YAAY,SAAW,GAC5BA,EAAK,YAAY,CAAC,EAAE,KAAK,OAAS,OAClCA,EAAK,YAAY,CAAC,EAAE,KAAK,OAAS,KAGtC,IAAIsY,GAAqC,CAAA,EACzC,GAAID,GACFC,GAAiBtY,EAAK,oBACb2T,EAAa,CACtB,MAAMhT,MAAgB,IAChBC,MAAe,IACrB,UAAWpF,KAAKsG,EACd,UAAWt6B,KAAKg0B,EAAE,QACZmF,EAAU,IAAIn5B,EAAE,KAAK,YAAA,CAAa,GACpCo5B,EAAS,IAAIp5B,EAAE,KAAK,YAAA,CAAa,EAEnCm5B,EAAU,IAAIn5B,EAAE,KAAK,YAAA,CAAa,EAGtC,UAAWg0B,KAAKsG,EACd,UAAWt6B,KAAKg0B,EAAE,QAAS,CACzB,MAAMkB,GAAQkE,EAAS,IAAIp5B,EAAE,KAAK,aAAa,EAC3C,GAAGg0B,EAAE,IAAI,IAAIh0B,EAAE,IAAI,GACnBA,EAAE,KACN8wC,GAAe,KAAK,CAClB,KAAM,CAAE,KAAM,MAAO,KAAM,GAAG9c,EAAE,IAAI,IAAIh0B,EAAE,IAAI,EAAA,EAC9C,MAAAk1B,EAAA,CACD,CACH,CAEJ,CAEA,IAAI6b,GAAc,GAClB,GAAIF,IAAkB1E,EAAa,CACjC,MAAM/sB,EAAqB0xB,GAAe,IAAKtW,IAAQ,CACrD,KAAMA,EAAG,MACT,KAAMoO,GAAcpO,EAAG,KAAM36B,EAAO24B,EAAK,QAAS8B,CAAS,EAC3D,MAAOp6B,EAAW,KAClB,UAAW,CAAA,EACX,EAIF,GAHAs4B,EAAK,cAAgBpZ,EACrB2xB,GAAc9D,EACdA,GAAW6D,GAAe,OACtB7D,GAAW,GACb,MAAM,IAAI1qC,GAAsB0qC,CAAO,CAE3C,CAEA,GAAId,EAAa,CACf,MAAMzT,EAAI4B,EAAU,OACd0W,EAAuB,IAAI,MAAMtY,CAAC,EACxC,QAAS34B,EAAI,EAAGA,EAAI24B,EAAG34B,IACJy4B,EAAK,aAAcz4B,EAAI,CAAC,EAC5B,OAAS,SACpBixC,EAAWjxC,CAAC,EAAIktC,KAGpB,MAAMgE,EAAchE,IACdiE,EAAejE,IACfkE,GAAUlE,IAEhB,IAAImE,EAAU,GACd,GAAI1E,GAAcG,IAAiB,GACjC,GAAIH,EAAW,eAAgB,CAE7B,GADA0E,EAAUnE,IACNA,GAAW,GAAI,MAAM,IAAI1qC,GAAsB0qC,CAAO,EAC1DnI,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUsM,CAAO,EACzBtM,EAAQ,WAAW4H,EAAW,eAAe,MAAM,EACnD5H,EAAQ,UAAU4H,EAAW,cAAc,CAC7C,SAAWA,EAAW,WAAa,eAEjC,GADA0E,EAAUnE,IACNA,GAAW,GAAI,MAAM,IAAI1qC,GAAsB0qC,CAAO,UACjDP,EAAW,aAAe,EACnC0E,EAAU1E,EAAW,YAAc,EAAI,MAClC,CAGL,GADA0E,EAAUnE,IACNA,GAAW,GAAI,MAAM,IAAI1qC,GAAsB0qC,CAAO,EAC1D,MAAMoE,EAASrH,GAAsB0C,EAAW,OAAO,EACvD3C,GAAiBjF,EAASsM,EAASC,EAAQ3E,EAAW,OAAO,CAC/D,CAGF,GAAIO,GAAW,GACb,MAAM,IAAI1qC,GAAsB0qC,CAAO,EAIzC,QAASltC,EAAI,EAAGA,EAAI24B,EAAG34B,IACrB+kC,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU/kC,CAAC,EACnB+kC,EAAQ,WAAWxK,EAAUv6B,CAAC,EAAE,UAAU,EAIxC2sC,GAAcG,IAAiB,KACjC/H,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU+H,CAAY,EAC9B/H,EAAQ,WAAW4H,EAAW,MAAM,UAAU,GAIhD,QAAS3sC,EAAI,EAAGA,EAAI24B,EAAG34B,IAAK,CAC1B,MAAMuxC,GAAOxE,EAAY/sC,CAAC,EACtBuxC,KACFxM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUwM,GAAK,WAAW,EAClCxM,EAAQ,WAAWwM,GAAK,MAAM,UAAU,EAE5C,CAEA,MAAMC,GAA8B,IAAI,MAAM7Y,CAAC,EACzC8Y,GAA+B,IAAI,MAAM9Y,CAAC,EAC1C+Y,GAAqC,MAAM,KAC/C,CAAE,OAAQ/Y,CAAA,EACV,IAAM,CAAA,CAAC,EAEHgZ,GAA8B,IAAI,MAAMhZ,CAAC,EACzCiZ,GAA6B,CAAA,EA4BnC,GAzBIjF,GAAcG,IAAiB,GAC7BH,EAAW,WAAa,SAC1B5H,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU+H,CAAY,EAC9B/H,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUsM,CAAO,EACzBtM,EAAQ,UAAU4H,EAAW,OAAO,EACpC6E,GAAkB,CAAC,EAAIzM,EAAQ,WAAW,CAAC,IAE3CA,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU+H,CAAY,EAC9B/H,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAUsM,CAAO,EACzBtM,EAAQ,UAAU4H,EAAW,OAAO,EACpC6E,GAAkB,CAAC,EAAIzM,EAAQ,WAAW,CAAC,IAG7CA,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAU,CAAC,EACnByM,GAAkB,CAAC,EAAIzM,EAAQ,WAAW,CAAC,GAG7C0M,GAAmB,CAAC,EAAI1M,EAAQ,cAAA,EAG5BsH,EAAc,CAAC,GAAKA,EAAc,CAAC,EAAE,OAAS,EAAG,CACnD,MAAMwF,EAAQzT,GAAgBiO,EAAc,CAAC,CAAC,EAC9C3D,GACEmJ,EACAtX,EAAU,CAAC,EACXwK,EACA4C,EACA+J,GAAuB,CAAC,EACxBjZ,EAAK,WACL8B,EACA6L,CAAA,CAEJ,CAGA,QAASpmC,EAAI,EAAGA,EAAI24B,EAAG34B,IAAK,CAC1B,MAAMwrC,GAAW/S,EAAK,aAAcz4B,EAAI,CAAC,EACnCuxC,GAAOxE,EAAY/sC,CAAC,EAQ1B,GANIwrC,GAAS,OAAS,SACpBzG,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkM,EAAWjxC,CAAC,CAAC,EAC/B+kC,EAAQ,UAAU,CAAC,GAGjBwM,IAAQA,GAAK,SAAU,CAmBzB,GAjBAzM,GACEC,EACAwM,GAAK,SAAS,OACdA,GAAK,SAAS,OACdL,EACAK,GAAK,SAAS,IAAI,IAAA,EAGpBxM,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAUwM,GAAK,WAAW,EAClCxM,EAAQ,UAAU/kC,CAAC,EACnB+kC,EAAQ,UAAUmM,CAAW,EAC7BnM,EAAQ,UAAUwM,GAAK,SAAS,IAAI,IAAI,EACxCC,GAAkBxxC,CAAC,EAAI+kC,EAAQ,WAAW,CAAC,EAE3C0M,GAAmBzxC,CAAC,EAAI+kC,EAAQ,cAAA,EAG9ByG,GAAS,OAAS,SAClBa,EAAcrsC,CAAC,GACfqsC,EAAcrsC,CAAC,EAAE,OAAS,EAC1B,CACA,MAAM8xC,GAAQ1T,GAAgBiO,EAAcrsC,CAAC,CAAC,EAC9C0oC,GACEoJ,GACAvX,EAAUv6B,CAAC,EACX+kC,EACA4C,EACA+J,GAAuB1xC,CAAC,EACxBy4B,EAAK,WACL8B,EACA6L,CAAA,CAEJ,CAEIoF,GAAS,OAAS,SACpBzG,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkM,EAAWjxC,CAAC,CAAC,EAC/B+kC,EAAQ,UAAU,CAAC,EAEvB,SAAWwM,IAAQ,CAACA,GAAK,SAAU,CAEjCzM,GACEC,EACAwM,GAAK,SAAS,OACdA,GAAK,SAAS,OACdL,EACAK,GAAK,SAAS,IAAI,IAAA,EAGpBxM,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAUwM,GAAK,WAAW,EAClCxM,EAAQ,UAAU/kC,CAAC,EACnB+kC,EAAQ,UAAUmM,CAAW,EAC7BnM,EAAQ,UAAUwM,GAAK,SAAS,IAAI,IAAI,EACxCC,GAAkBxxC,CAAC,EAAI+kC,EAAQ,WAAW,CAAC,EAE3C0M,GAAmBzxC,CAAC,EAAI+kC,EAAQ,cAAA,EAEhCD,GACEC,EACA/kC,EACAuxC,GAAK,SAAS,OACdJ,EACAI,GAAK,SAAS,IAAI,IAAA,EAGpBxM,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUmM,CAAW,EAC7BnM,EAAQ,UAAUoM,CAAY,EAC9B,MAAMY,GAAiBhN,EAAQ,WAAW,CAAC,EAS3C,GANAA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCoxC,GAAuB1xC,CAAC,EAAE,KAAK+kC,EAAQ,WAAW,CAAC,CAAC,EAGpDA,EAAQ,YAAYgN,GAAgBhN,EAAQ,cAAA,CAAe,EAGzDyG,GAAS,OAAS,SAClBa,EAAcrsC,CAAC,GACfqsC,EAAcrsC,CAAC,EAAE,OAAS,EAC1B,CACA,MAAM8xC,GAAQ1T,GAAgBiO,EAAcrsC,CAAC,CAAC,EAC9C0oC,GACEoJ,GACAvX,EAAUv6B,CAAC,EACX+kC,EACA4C,EACA+J,GAAuB1xC,CAAC,EACxBy4B,EAAK,WACL8B,EACA6L,CAAA,CAEJ,CAEIoF,GAAS,OAAS,SACpBzG,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkM,EAAWjxC,CAAC,CAAC,EAC/B+kC,EAAQ,UAAU,CAAC,EAEvB,KAAO,CAELA,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAU/kC,CAAC,EACnBwxC,GAAkBxxC,CAAC,EAAI+kC,EAAQ,WAAW,CAAC,EAE3C0M,GAAmBzxC,CAAC,EAAI+kC,EAAQ,cAAA,EAEhC,MAAM2G,GAAe1U,GACnBwU,GAAS,QACTjR,CAAA,EAEF,GAAI,CAACmR,GACH,MAAM,IAAI,MACR,gBAAgBF,GAAS,OAAO,uBAAA,EAGpC,MAAMG,GAAgB3U,GACpBwU,GAAS,SACTjR,CAAA,EAEF,GAAI,CAACoR,GACH,MAAM,IAAI,MACR,gBAAgBH,GAAS,QAAQ,uBAAA,EAIrC1G,GACEC,EACA2G,GAAa,OACbA,GAAa,OACbwF,EACAxF,GAAa,IAAI,IAAA,EAEnB5G,GACEC,EACA4G,GAAc,OACdA,GAAc,OACdwF,EACAxF,GAAc,IAAI,IAAA,EAGpB,IAAIxC,GACJ,OAAQqC,GAAS,GAAA,CACf,IAAK,IACHrC,GAAQ7oC,EAAO,MACf,MACF,IAAK,KACH6oC,GAAQ7oC,EAAO,MACf,MACF,IAAK,IACH6oC,GAAQ7oC,EAAO,MACf,MACF,IAAK,KACH6oC,GAAQ7oC,EAAO,MACf,MACF,IAAK,IACH6oC,GAAQ7oC,EAAO,MACf,MACF,IAAK,KACH6oC,GAAQ7oC,EAAO,MACf,MACF,QACE6oC,GAAQ7oC,EAAO,KAAA,CAGnBykC,EAAQ,UAAUoE,EAAK,EACvBpE,EAAQ,UAAUmM,CAAW,EAC7BnM,EAAQ,UAAUoM,CAAY,EAC9B,MAAMY,GAAiBhN,EAAQ,WAAW,CAAC,EAS3C,GANAA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCoxC,GAAuB1xC,CAAC,EAAE,KAAK+kC,EAAQ,WAAW,CAAC,CAAC,EAGpDA,EAAQ,YAAYgN,GAAgBhN,EAAQ,cAAA,CAAe,EAGzDyG,GAAS,OAAS,SAClBa,EAAcrsC,CAAC,GACfqsC,EAAcrsC,CAAC,EAAE,OAAS,EAC1B,CACA,MAAM8xC,GAAQ1T,GAAgBiO,EAAcrsC,CAAC,CAAC,EAC9C0oC,GACEoJ,GACAvX,EAAUv6B,CAAC,EACX+kC,EACA4C,EACA+J,GAAuB1xC,CAAC,EACxBy4B,EAAK,WACL8B,EACA6L,CAAA,CAEJ,CAEIoF,GAAS,OAAS,SACpBzG,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUkM,EAAWjxC,CAAC,CAAC,EAC/B+kC,EAAQ,UAAU,CAAC,EAEvB,CACF,CAGA2D,GACE+D,EACA3sC,EACAilC,EACA4C,EACA+J,GAAuB/Y,EAAI,CAAC,EAC5BF,EAAK,WACL8B,EACA6L,CAAA,EAIF,MAAM4L,GAAyB,EADZvZ,EAAK,UAAY,QAAaA,EAAK,QAAQ,OAAS,IACzBmU,EAE9C,IAAIqF,GAAkB,GAClB9E,GAAa6E,KACfjN,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3B4E,GAAkBlN,EAAQ,WAAW,CAAC,GAGxC,IAAImN,GAAchF,EAClB,MAAMiF,GAAe,IAAM,CACzB,GAAID,IAAe,GAAI,MAAM,IAAI1vC,GAAsB0vC,EAAW,EAClE,OAAOA,IACT,EAEA,QAASnuC,EAAI,EAAGA,EAAIgtC,GAAe,OAAQhtC,IACzC2iC,EACEqK,GAAehtC,CAAC,EAAE,KAClBjE,EACAilC,EACA,EACAiM,GAAcjtC,EACdouC,GACA1Z,EAAK,WACL,OACA8B,CAAA,EAIJwK,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUgM,GAAe,MAAM,EAEnC3D,GAAY4E,KACdjN,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BsE,GAAiB,KAAK7M,EAAQ,WAAW,CAAC,CAAC,GAI7C,QAAS/kC,EAAI24B,EAAI,EAAG34B,GAAK,EAAGA,IAAK,CAC/B,MAAMqvC,GAAatK,EAAQ,cAAA,EACvB/kC,IAAM24B,EAAI,GAAKsZ,KAAoB,IACrClN,EAAQ,YAAYkN,GAAiB5C,EAAU,EAEjD,UAAWrH,MAAS0J,GAAuB1xC,CAAC,EAC1C+kC,EAAQ,YAAYiD,GAAOqH,EAAU,EAGvC,MAAMkC,GAAOxE,EAAY/sC,CAAC,EAC1B,GAAIuxC,IAAQA,GAAK,SAAU,CAEzB,MAAMhC,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYyM,GAAkBxxC,CAAC,EAAGuvC,EAAM,CAClD,SAAWgC,IAAQ,CAACA,GAAK,SAAU,CAEjCxM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUwM,GAAK,WAAW,EAClCxM,EAAQ,UAAU/kC,CAAC,EACnB2xC,GAAkB3xC,CAAC,EAAI+kC,EAAQ,WAAW,CAAC,EAE3CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAW0M,GAAmBzxC,CAAC,CAAC,EAExC,MAAMuvC,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYyM,GAAkBxxC,CAAC,EAAGuvC,EAAM,EAChDxK,EAAQ,YAAY4M,GAAkB3xC,CAAC,EAAGuvC,EAAM,CAClD,KAAO,CAELxK,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU/kC,CAAC,EACnB2xC,GAAkB3xC,CAAC,EAAI+kC,EAAQ,WAAW,CAAC,EAE3CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAW0M,GAAmBzxC,CAAC,CAAC,EAExC,MAAMuvC,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYyM,GAAkBxxC,CAAC,EAAGuvC,EAAM,EAChDxK,EAAQ,YAAY4M,GAAkB3xC,CAAC,EAAGuvC,EAAM,CAClD,CAGA,GADiB9W,EAAK,aAAcz4B,EAAI,CAAC,EAC5B,OAAS,OAAQ,CAC5B+kC,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAUqM,EAAO,EACzBrM,EAAQ,UAAU,CAAC,EAEnBA,EAAQ,UAAUzkC,EAAO,KAAK,EAC9BykC,EAAQ,UAAUkM,EAAWjxC,CAAC,CAAC,EAC/B+kC,EAAQ,UAAUqM,EAAO,EACzB,MAAMgB,GAAqBrN,EAAQ,WAAW,CAAC,EAE/CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC,MAAM+xC,GAAmBtN,EAAQ,WAAW,CAAC,EAE7CA,EAAQ,YAAYqN,GAAoBrN,EAAQ,cAAA,CAAe,EAE/D,QAAShhC,EAAI,EAAGA,EAAIgtC,GAAe,OAAQhtC,IAAK,CAC9C,MAAM02B,EAAKsW,GAAehtC,CAAC,EAC3B,IAAIuuC,EAAc,GAClB,GAAI7X,EAAG,KAAK,OAAS,MAAO,CAC1B,MAAM1D,EAAWC,GAA0ByD,EAAG,KAAK,KAAMF,CAAS,EAC9DxD,IACFub,EAAcvb,EAAS,SAE3B,CACIub,GAAetyC,GACjB+kC,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAUiM,GAAcjtC,CAAC,GAEjC2iC,EACEjM,EAAG,KACH36B,EACAilC,EACA,EACAiM,GAAcjtC,EACdouC,GACA1Z,EAAK,WACL,OACA8B,CAAA,CAGN,CAEA,MAAMgY,GAAgC,CAAA,EAClCpF,GAAa6E,KACfjN,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3BkF,GAAoB,KAAKxN,EAAQ,WAAW,CAAC,CAAC,GAGhDA,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUgM,GAAe,MAAM,EAEnC3D,GAAY4E,KACdjN,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BsE,GAAiB,KAAK7M,EAAQ,WAAW,CAAC,CAAC,GAG7C,MAAMyN,GAAkBzN,EAAQ,cAAA,EAChCA,EAAQ,YAAYsN,GAAkBG,EAAe,EACrD,UAAWl6B,KAAKi6B,GACdxN,EAAQ,YAAYzsB,EAAGk6B,EAAe,CAE1C,CACF,CAEA,MAAMC,GAAc1N,EAAQ,cAAA,EAC5B,UAAWiD,KAAS0J,GAAuB,CAAC,EAC1C3M,EAAQ,YAAYiD,EAAOyK,EAAW,EAGpC9F,GAAcG,IAAiB,GAC7BH,EAAW,WAAa,SAC1B5H,EAAQ,UAAUzkC,EAAO,OAAO,EAChCqxC,GAAkB,CAAC,EAAI5M,EAAQ,WAAW,CAAC,IAE3CA,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU+H,CAAY,EAC9B/H,EAAQ,UAAU,CAAC,EACnB4M,GAAkB,CAAC,EAAI5M,EAAQ,WAAW,CAAC,EAE3CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAW0M,GAAmB,CAAC,CAAC,IAG1C1M,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnB4M,GAAkB,CAAC,EAAI5M,EAAQ,WAAW,CAAC,EAE3CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAW0M,GAAmB,CAAC,CAAC,GAG1C,MAAMiB,GAAU3N,EAAQ,cAAA,EACxBA,EAAQ,YAAYyM,GAAkB,CAAC,EAAGkB,EAAO,EACjD3N,EAAQ,YAAY4M,GAAkB,CAAC,EAAGe,EAAO,EACjD,UAAW1K,KAAS4J,GAClB7M,EAAQ,YAAYiD,EAAO0K,EAAO,EAGpC3N,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACnBtM,EAAK,gBACNzzB,GAAe,cAAgByzB,EAAK,eAEvC,MAAMka,IAAmBC,GAAAna,EAAK,eAAL,YAAAma,GAAmB,IAAI,CAACz5B,EAAG/S,KAAQ,CAC1D,MAAM2/B,GAAW3/B,GAAM,EACjBoe,GAAOuoB,EAAYhH,EAAQ,EACjC,MAAO,CACL,WAAYA,GACZ,UAAW5sB,EAAE,MAAM,KACnB,SAAUqL,GAAQ,YAAyB,YAC3C,UAAWA,GAAOA,GAAK,MAAM,KAAO,MAAA,CAExC,GACCxf,OAAAA,GAAe,iBAAmB2tC,GAClC3tC,GAAe,UAAYu1B,EAC3Bv1B,GAAe,OAASioC,EACxBjoC,GAAe,WAAa2nC,EAC5B3nC,GAAe,iBAAmB4nC,EAC/BA,IACFnU,EAAK,iBAAmB,IAEtBwT,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEtCnO,IACD94B,GAAe,aAAe84B,GAE1B94B,EACT,CAEA,GAAIsrC,EAAW,CACb,IAAIuC,EACJ,GAAIvC,EAAU,eAAgB,CAE5B,GADAuC,EAAS3F,IACL2F,GAAU,GAAI,MAAM,IAAIrwC,GAAsBqwC,CAAM,EACxD9N,EAAQ,UAAUzkC,EAAO,YAAY,EACrCykC,EAAQ,UAAU8N,CAAM,EACxB9N,EAAQ,UAAUuL,EAAU,cAAc,CAC5C,SAAWA,EAAU,WAAa,eAEhC,GADAuC,EAAS3F,IACL2F,GAAU,GAAI,MAAM,IAAIrwC,GAAsBqwC,CAAM,UAC/CvC,EAAU,aAAe,EAClCuC,EAASvC,EAAU,YAAc,EAAI,MAChC,CAGL,GADAuC,EAAS3F,IACL2F,GAAU,GAAI,MAAM,IAAIrwC,GAAsBqwC,CAAM,EACxD,MAAMvB,EAASrH,GAAsBqG,EAAU,OAAO,EACtDtG,GAAiBjF,EAAS8N,EAAQvB,EAAQhB,EAAU,OAAO,CAC7D,CAEA,GAAIA,EAAU,WAAa,QAAS,CAElCvL,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAGnCilC,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWuL,EAAU,MAAM,UAAU,EAG7CvL,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU8N,CAAM,EACxB9N,EAAQ,UAAUuL,EAAU,OAAO,EACnC,MAAMwC,EAAoB/N,EAAQ,WAAW,CAAC,EAGxC4D,EAA2B,CAAA,EACjCD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,EACAlQ,EAAK,WACL,OACA2N,CAAA,EAGF,IAAI6L,EAAkB,GAQtB,GAPI9E,IACFpI,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3B4E,EAAkBlN,EAAQ,WAAW,CAAC,GAIpC+L,GAAgB,CAClB,IAAIoB,GAAchF,EAClB,MAAMiF,GAAe,IAAM,CACzB,GAAID,IAAe,GAAI,MAAM,IAAI1vC,GAAsB0vC,EAAW,EAClE,OAAOA,IACT,EACA,QAASlyC,GAAI,EAAGA,GAAIy4B,EAAK,YAAa,OAAQz4B,KAC5C0mC,EACEjO,EAAK,YAAaz4B,EAAC,EAAE,KACrBF,EACAilC,EACA,EACAiM,GAAchxC,GACdmyC,GACA1Z,EAAK,UAAA,EAGTsM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUtM,EAAK,YAAa,MAAM,CAC5C,MACEsM,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EAIrBA,EAAQ,UAAUzkC,EAAO,OAAO,EAChC,MAAMyyC,GAAehO,EAAQ,WAAW,CAAC,EAGnCwK,EAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAY+N,EAAmBvD,CAAM,EAC7CxK,EAAQ,YAAYgO,GAAcxD,CAAM,EACpC0C,IAAoB,IACtBlN,EAAQ,YAAYkN,EAAiB1C,CAAM,EAE7C,UAAWvH,MAASW,EAClB5D,EAAQ,YAAYiD,GAAOuH,CAAM,EAGnCxK,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,GAAe,UAAYsrC,EAC3BtrC,GAAe,OAASioC,EACrBxU,EAAK,gBACNzzB,GAAe,cAAgByzB,EAAK,eAEnC6X,GAAA,MAAAA,EAAW,mBACZtrC,GAAe,iBAAmB,GACnCyzB,EAAK,iBAAmB,IAEtBwT,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEnCjnC,EACT,SAAWsrC,EAAU,WAAa,cAAe,CAC/C,MAAM0C,EAAY1C,EAAU,SAAWA,EAAU,SAAS,OAAS,EACnE,GAAI0C,IAAc,EAAG,CACnBjO,EAAQ,UAAUzkC,EAAO,OAAO,EAChC,MAAM0E,EAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,EAAe,UAAYsrC,EAC3BtrC,EAAe,OAASioC,EACrBxU,EAAK,gBACNzzB,EAAe,cAAgByzB,EAAK,eAEhCzzB,CACT,CAGA+/B,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAGnCilC,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWuL,EAAU,MAAM,UAAU,EAE7C,MAAMsB,EAA6B,CAAA,EAEnC,QAASqB,EAAO,EAAGA,EAAOD,EAAWC,IAAQ,CAC3C,MAAM5tC,GAAMirC,EAAU,SAAU2C,CAAI,EACpCjJ,GAAiBjF,EAAS8N,EAAQxtC,GAAKirC,EAAU,OAAO,EAGxDvL,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU8N,CAAM,EACxB9N,EAAQ,UAAUuL,EAAU,OAAO,EACnC,MAAMwC,GAAoB/N,EAAQ,WAAW,CAAC,EAGxC4D,GAA2B,CAAA,EACjCD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,GACAlQ,EAAK,WACL,OACA2N,CAAA,EAGF,IAAI6L,GAAkB,GAQtB,GAPI9E,IACFpI,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3B4E,GAAkBlN,EAAQ,WAAW,CAAC,GAIpC+L,GAAgB,CAClB,IAAIoB,GAAchF,EAClB,MAAMiF,GAAe,IAAM,CACzB,GAAID,IAAe,GAAI,MAAM,IAAI1vC,GAAsB0vC,EAAW,EAClE,OAAOA,IACT,EACA,QAASlyC,GAAI,EAAGA,GAAIy4B,EAAK,YAAa,OAAQz4B,KAC5C0mC,EACEjO,EAAK,YAAaz4B,EAAC,EAAE,KACrBF,EACAilC,EACA,EACAiM,GAAchxC,GACdmyC,GACA1Z,EAAK,UAAA,EAGTsM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUtM,EAAK,YAAa,MAAM,CAC5C,MACEsM,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EAGjBqI,IACFrI,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BsE,EAAiB,KAAK7M,EAAQ,WAAW,CAAC,CAAC,GAG7C,MAAMmO,GAAYD,IAASD,EAAY,EACvC,IAAIG,GAAmB,GAClBD,KACHnO,EAAQ,UAAUzkC,EAAO,OAAO,EAChC6yC,GAAmBpO,EAAQ,WAAW,CAAC,GAGzC,MAAMqO,GAAarO,EAAQ,cAAA,EAC3BA,EAAQ,YAAY+N,GAAmBM,EAAU,EACjD,UAAWpL,MAASW,GAClB5D,EAAQ,YAAYiD,GAAOoL,EAAU,EAEnCnB,KAAoB,IACtBlN,EAAQ,YAAYkN,GAAiBmB,EAAU,EAE7CD,KAAqB,IACvBpO,EAAQ,YAAYoO,GAAkBC,EAAU,CAEpD,CAGA,MAAM7D,EAASxK,EAAQ,cAAA,EACvB,UAAWiD,KAAS4J,EAClB7M,EAAQ,YAAYiD,EAAOuH,CAAM,EAEnCxK,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,GAAe,UAAYsrC,EAC3BtrC,GAAe,OAASioC,EACrBxU,EAAK,gBACNzzB,GAAe,cAAgByzB,EAAK,eAEnC6X,GAAA,MAAAA,EAAW,mBACZtrC,GAAe,iBAAmB,GACnCyzB,EAAK,iBAAmB,IAEtBwT,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEnCjnC,EACT,KAAO,CAEL+/B,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAEnCilC,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWuL,EAAU,MAAM,UAAU,EAE7CvL,EAAQ,UAAUzkC,EAAO,gBAAgB,EACzCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU8N,CAAM,EACxB9N,EAAQ,UAAUuL,EAAU,OAAO,EACnC,MAAM+C,EAAetO,EAAQ,WAAW,CAAC,EAEnCyJ,EAAezJ,EAAQ,cAAA,EACvB4D,EAA2B,CAAA,EAEjCD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,EACAlQ,EAAK,WACL,OACA2N,CAAA,EAGF,IAAI6L,GAAkB,GAOtB,GANI9E,IACFpI,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3B4E,GAAkBlN,EAAQ,WAAW,CAAC,GAGpC+L,GAAgB,CAClB,IAAIoB,GAAchF,EAClB,MAAMiF,GAAe,IAAM,CACzB,GAAID,IAAe,GAAI,MAAM,IAAI1vC,GAAsB0vC,EAAW,EAClE,OAAOA,IACT,EACA,QAASlyC,GAAI,EAAGA,GAAIy4B,EAAK,YAAa,OAAQz4B,KAC5C0mC,EACEjO,EAAK,YAAaz4B,EAAC,EAAE,KACrBF,EACAilC,EACA,EACAiM,GAAchxC,GACdmyC,GACA1Z,EAAK,UAAA,EAGTsM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUtM,EAAK,YAAa,MAAM,CAC5C,MACEsM,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EAGrB,IAAIuO,EAAiB,GACjBlG,IACFrI,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BgG,EAAiBvO,EAAQ,WAAW,CAAC,GAGvC,MAAMsK,GAAatK,EAAQ,cAAA,EACvBkN,KAAoB,IACtBlN,EAAQ,YAAYkN,GAAiB5C,EAAU,EAEjD,UAAWrH,MAASW,EAClB5D,EAAQ,YAAYiD,GAAOqH,EAAU,EAGvCtK,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,UAAU,CAAC,EACnB,MAAMuK,GAAkBvK,EAAQ,WAAW,CAAC,EAE5CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAWyJ,CAAY,EAE/B,MAAMe,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYsO,EAAc9D,EAAM,EACxCxK,EAAQ,YAAYuK,GAAiBC,EAAM,EACvC+D,IAAmB,IACrBvO,EAAQ,YAAYuO,EAAgB/D,EAAM,EAG5CxK,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACtB//B,OAAAA,GAAe,UAAYsrC,EAC3BtrC,GAAe,OAASioC,EACrBxU,EAAK,gBACNzzB,GAAe,cAAgByzB,EAAK,eAEnC6X,GAAA,MAAAA,EAAW,mBACZtrC,GAAe,iBAAmB,GACnCyzB,EAAK,iBAAmB,IAEtBwT,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEnCjnC,EACT,CACF,CAGA+/B,EAAQ,UAAUzkC,EAAO,cAAc,EACvCykC,EAAQ,UAAU,CAAC,EACnBA,EAAQ,WAAWjlC,EAAM,UAAU,EAGnCilC,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAU,CAAC,EACnB,MAAMwJ,GAAkBxJ,EAAQ,WAAW,CAAC,EAGtCyJ,GAAezJ,EAAQ,cAAA,EACvB4D,GAA2B,CAAA,EAEjCD,GACEvK,EACAr+B,EACAilC,EACA4C,EACAgB,GACAlQ,EAAK,WACL,OACA2N,CAAA,EAGF,IAAI6L,GAAkB,GAQtB,GAPI9E,IACFpI,EAAQ,UAAUzkC,EAAO,SAAS,EAClCykC,EAAQ,UAAUsI,CAAS,EAC3B4E,GAAkBlN,EAAQ,WAAW,CAAC,GAIpC+L,GAAgB,CAClB,IAAIoB,EAAchF,EAClB,MAAMiF,EAAe,IAAM,CACzB,GAAID,GAAe,GAAI,MAAM,IAAI1vC,GAAsB0vC,CAAW,EAClE,OAAOA,GACT,EACA,QAASlyC,EAAI,EAAGA,EAAIy4B,EAAK,YAAa,OAAQz4B,IAC5C0mC,EACEjO,EAAK,YAAaz4B,CAAC,EAAE,KACrBF,EACAilC,EACA,EACAiM,GAAchxC,EACdmyC,EACA1Z,EAAK,UAAA,EAGTsM,EAAQ,UAAUzkC,EAAO,aAAa,EACtCykC,EAAQ,UAAUiM,EAAW,EAC7BjM,EAAQ,UAAUtM,EAAK,YAAa,MAAM,CAC5C,MACEsM,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EAGrB,IAAIuO,GAAiB,GACjBlG,IACFrI,EAAQ,UAAUzkC,EAAO,QAAQ,EACjCykC,EAAQ,UAAUuI,CAAQ,EAC1BgG,GAAiBvO,EAAQ,WAAW,CAAC,GAIvC,MAAMsK,GAAatK,EAAQ,cAAA,EACvBkN,KAAoB,IACtBlN,EAAQ,YAAYkN,GAAiB5C,EAAU,EAEjD,UAAWrH,KAASW,GAClB5D,EAAQ,YAAYiD,EAAOqH,EAAU,EAIvCtK,EAAQ,UAAUzkC,EAAO,WAAW,EACpCykC,EAAQ,UAAU,CAAC,EACnB,MAAMuK,GAAkBvK,EAAQ,WAAW,CAAC,EAG5CA,EAAQ,UAAUzkC,EAAO,OAAO,EAChCykC,EAAQ,WAAWyJ,EAAY,EAG/B,MAAMe,GAASxK,EAAQ,cAAA,EACvBA,EAAQ,YAAYwJ,GAAiBgB,EAAM,EAC3CxK,EAAQ,YAAYuK,GAAiBC,EAAM,EACvC+D,KAAmB,IACrBvO,EAAQ,YAAYuO,GAAgB/D,EAAM,EAG5CxK,EAAQ,UAAUzkC,EAAO,OAAO,EAEhC,MAAM0E,GAAS+/B,EAAQ,YAAA,EACtB,OAAA//B,GAAe,OAASioC,EACrBxU,EAAK,gBACNzzB,GAAe,cAAgByzB,EAAK,eAEnCqF,IACD94B,GAAe,aAAe84B,GAE7BmO,IACDjnC,GAAe,YAAcinC,EAC7BjnC,GAAe,cAAgBinC,EAAY,UAC3CjnC,GAAe,cAAgBinC,EAAY,cAC3CjnC,GAAe,UAAYinC,EAAY,WAEnCjnC,EACT,CAWA,MAAMuuC,GAAc,IAAI,YAKjB,SAASC,GACdnzB,EACAvgB,EAC2B,CAC3B,MAAM2zC,EAA0C,CAAA,EAC1CtrC,EAAO,IAAI,SACfkY,EAAS,OACTA,EAAS,WACTA,EAAS,UAAA,EAEX,IAAIqzB,EAAK,EAET,MAAMC,EAAcvtC,GAAgB,OAClC,OAAOT,EAAA7F,GAAA,YAAAA,EAAO,QAAQsG,KAAf,MAAAT,EAAqB,KACxB,IAAI7F,EAAM,QAAQsG,CAAG,EAAE,IAAI,IAC3B,OAAOA,CAAG,EAChB,EAEMwtC,EAAWvsC,GAAc,KAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,GAEnE,KAAOqsC,EAAKrzB,EAAS,YAAY,CAC/B,MAAMwzB,EAAOH,EACP/yB,EAAKN,EAASqzB,GAAI,EAExB,OAAQ/yB,EAAA,CACN,KAAKrgB,EAAO,QACVmzC,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,UACR,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,QAAS,iCAAA,CACV,EACD,MAEF,KAAKvzC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBI,EAAW3rC,EAAK,UAAUurC,EAAI,EAAI,EACxCA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,QAAQ0uC,CAAQ,GACpB,GAAI,GACJ,QAAS,eAAe1uC,CAAM,iBAAiB0uC,CAAQ,GAAGh0C,EAAQ,MAAMA,EAAM,IAAI,KAAO,EAAE,EAAA,CAC5F,EACD,KACF,CAEA,KAAKQ,EAAO,cAAe,CACzB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBI,EAAW3rC,EAAK,UAAUurC,EAAI,EAAI,EACxCA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,QAAQ0uC,CAAQ,GACpB,GAAI,GACJ,QAAS,qBAAqB1uC,CAAM,iBAAiB0uC,CAAQ,EAAA,CAC9D,EACD,KACF,CAEA,KAAKxzC,EAAO,iBAAkB,CAC5B,MAAMyzC,EAAY1zB,EAASqzB,GAAI,EACzBM,EAAa3zB,EAASqzB,GAAI,EAC1Bb,EAASxyB,EAASqzB,GAAI,EACtBO,EAAU5zB,EAASqzB,GAAI,EACvBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,mBACR,GAAI,SAASE,CAAS,aAAaC,CAAU,IAC7C,GAAI,SAASnB,CAAM,WAAWoB,CAAO,GACrC,GAAIL,EAAQM,CAAU,EACtB,QAAS,4DAA4DN,EAAQM,CAAU,CAAC,eAAA,CACzF,EACD,KACF,CAEA,KAAK5zC,EAAO,iBAAkB,CAC5B,MAAMyzC,EAAY1zB,EAASqzB,GAAI,EACzBM,EAAa3zB,EAASqzB,GAAI,EAC1Bb,EAASxyB,EAASqzB,GAAI,EACtBO,EAAU5zB,EAASqzB,GAAI,EACvBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,mBACR,GAAI,SAASE,CAAS,aAAaC,CAAU,IAC7C,GAAI,SAASnB,CAAM,WAAWoB,CAAO,GACrC,GAAIL,EAAQM,CAAU,EACtB,QAAS,qEAAqEN,EAAQM,CAAU,CAAC,SAAA,CAClG,EACD,KACF,CAEA,KAAK5zC,EAAO,cAAe,CACzB,MAAMyzC,EAAY1zB,EAASqzB,GAAI,EACzBM,EAAa3zB,EAASqzB,GAAI,EAC1BQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,SAASE,CAAS,aAAaC,CAAU,IAC7C,GAAIJ,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,+CAA+CN,EAAQM,CAAU,CAAC,SAAA,CAC5E,EACD,KACF,CAEA,KAAK5zC,EAAO,UAAW,CACrB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,YACR,GAAI,KAAKzuC,CAAM,IACf,GAAIwuC,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,uCAAuCN,EAAQM,CAAU,CAAC,WAAA,CACpE,EACD,KACF,CAEA,KAAK5zC,EAAO,YAAa,CACvB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,KAAKzuC,CAAM,IACf,GAAIwuC,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,uCAAuCN,EAAQM,CAAU,CAAC,SAAA,CACpE,EACD,KACF,CAEA,KAAK5zC,EAAO,QAAS,CACnB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,UACR,GAAI,KAAKzuC,CAAM,IACf,GAAIwuC,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,wCAAwCN,EAAQM,CAAU,CAAC,WAAA,CACrE,EACD,KACF,CAEA,KAAK5zC,EAAO,YAAa,CACvB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,KAAKzuC,CAAM,IACf,GAAIwuC,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,2CAA2CN,EAAQM,CAAU,CAAC,SAAA,CACxE,EACD,KACF,CAEA,KAAK5zC,EAAO,cAAe,CACzB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,kBAAkBgd,CAAM,GAAA,CAC5D,EACD,KACF,CAEA,KAAK7zC,EAAO,gBAAiB,CAC3B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,kBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,oBAAoBgd,CAAM,GAAA,CAC9D,EACD,KACF,CAEA,KAAK7zC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,mBAAmBgd,CAAM,GAAA,CAC7D,EACD,KACF,CAEA,KAAK7zC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,mBAAmBgd,CAAM,GAAA,CAC7D,EACD,KACF,CAEA,KAAK7zC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,mBAAmBgd,CAAM,GAAA,CAC7D,EACD,KACF,CAEA,KAAK7zC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBS,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAI,KAAKgd,CAAM,IACf,QAAS,QAAQR,EAAWxc,CAAM,CAAC,mBAAmBgd,CAAM,GAAA,CAC7D,EACD,KACF,CAEA,KAAK7zC,EAAO,WAAY,CACtB,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,aACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAIyc,EAAQM,CAAU,EACtB,QAAS,MAAMP,EAAWxc,CAAM,CAAC,uBAAuByc,EAAQM,CAAU,CAAC,EAAA,CAC5E,EACD,KACF,CAEA,KAAK5zC,EAAO,eAAgB,CAC1B,MAAM8E,EAASib,EAASqzB,GAAI,EACtBvc,EAAS9W,EAASqzB,GAAI,EACtBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GAAG+xB,CAAM,KAAKwc,EAAWxc,CAAM,CAAC,IACpC,GAAIyc,EAAQM,CAAU,EACtB,QAAS,MAAMP,EAAWxc,CAAM,CAAC,2BAA2Byc,EAAQM,CAAU,CAAC,EAAA,CAChF,EACD,KACF,CAEA,KAAK5zC,EAAO,MACZ,KAAKA,EAAO,MACZ,KAAKA,EAAO,MACZ,KAAKA,EAAO,MACZ,KAAKA,EAAO,MACZ,KAAKA,EAAO,MAAO,CACjB,MAAM8zC,EAAkC,CACtC,CAAC9zC,EAAO,KAAK,EAAG,QAChB,CAACA,EAAO,KAAK,EAAG,QAChB,CAACA,EAAO,KAAK,EAAG,QAChB,CAACA,EAAO,KAAK,EAAG,QAChB,CAACA,EAAO,KAAK,EAAG,QAChB,CAACA,EAAO,KAAK,EAAG,OAAA,EAEZ+zC,EAAkC,CACtC,CAAC/zC,EAAO,KAAK,EAAG,KAChB,CAACA,EAAO,KAAK,EAAG,KAChB,CAACA,EAAO,KAAK,EAAG,IAChB,CAACA,EAAO,KAAK,EAAG,KAChB,CAACA,EAAO,KAAK,EAAG,IAChB,CAACA,EAAO,KAAK,EAAG,IAAA,EAEZg0C,EAAOj0B,EAASqzB,GAAI,EACpBa,EAAOl0B,EAASqzB,GAAI,EACpBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQO,EAAQzzB,CAAE,EAClB,GAAI,KAAK2zB,CAAI,IACb,GAAI,KAAKC,CAAI,IACb,GAAIX,EAAQM,CAAU,EACtB,QAAS,QAAQI,CAAI,KAAKD,EAAQ1zB,CAAE,CAAC,MAAM4zB,CAAI,gBAAgBX,EAAQM,CAAU,CAAC,EAAA,CACnF,EACD,KACF,CAEA,KAAK5zC,EAAO,QAAS,CACnB,MAAM4zC,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,UACR,GAAID,EAAQM,CAAU,EACtB,GAAI,GACJ,GAAI,GACJ,QAAS,yBAAyBN,EAAQM,CAAU,CAAC,EAAA,CACtD,EACD,KACF,CAEA,KAAK5zC,EAAO,YACZ,KAAKA,EAAO,gBACZ,KAAKA,EAAO,gBACZ,KAAKA,EAAO,mBACZ,KAAKA,EAAO,iBAAkB,CAC5B,MAAM8zC,EAAkC,CACtC,CAAC9zC,EAAO,WAAW,EAAG,cACtB,CAACA,EAAO,eAAe,EAAG,kBAC1B,CAACA,EAAO,eAAe,EAAG,kBAC1B,CAACA,EAAO,kBAAkB,EAAG,qBAC7B,CAACA,EAAO,gBAAgB,EAAG,kBAAA,EAEvBk0C,EAAuC,CAC3C,CAACl0C,EAAO,WAAW,EAAG,OACtB,CAACA,EAAO,eAAe,EAAG,WAC1B,CAACA,EAAO,eAAe,EAAG,WAC1B,CAACA,EAAO,kBAAkB,EAAG,cAC7B,CAACA,EAAO,gBAAgB,EAAG,WAAA,EAEvBg0C,EAAOj0B,EAASqzB,GAAI,EACpBa,EAAOl0B,EAASqzB,GAAI,EACpBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQO,EAAQzzB,CAAE,EAClB,GAAI,KAAK2zB,CAAI,IACb,GAAI,KAAKC,CAAI,IACb,GAAIX,EAAQM,CAAU,EACtB,QAAS,QAAQI,CAAI,KAAKE,EAAa7zB,CAAE,CAAC,MAAM4zB,CAAI,gBAAgBX,EAAQM,CAAU,CAAC,EAAA,CACxF,EACD,KACF,CAEA,KAAK5zC,EAAO,MAAO,CACjB,MAAMm0C,EAASp0B,EAASqzB,GAAI,EACtB7M,EAAS1+B,EAAK,UAAUurC,EAAI,EAAI,EACtCA,GAAM,EACN,MAAMQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,QACR,GAAI,KAAKY,CAAM,IACf,GAAI,OAAO5N,CAAM,IACjB,GAAI+M,EAAQM,CAAU,EACtB,QAAS,QAAQO,CAAM,YAAY5N,CAAM,gBAAgB+M,EAAQM,CAAU,CAAC,EAAA,CAC7E,EACD,KACF,CAEA,KAAK5zC,EAAO,YAAa,CACvB,MAAM6zC,EAAS9zB,EAASqzB,GAAI,EACtBruC,EAAM8C,EAAK,SAASurC,EAAI,EAAI,EAClCA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,KAAKM,CAAM,IACf,GAAI,GAAG9uC,CAAG,GACV,GAAI,GACJ,QAAS,oBAAoBA,CAAG,WAAW8uC,CAAM,GAAA,CAClD,EACD,KACF,CAEA,KAAK7zC,EAAO,cAAe,CACzB,MAAM6zC,EAAS9zB,EAASqzB,GAAI,EACtBruC,EAAM8C,EAAK,WAAWurC,EAAI,EAAI,EACpCA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,KAAKM,CAAM,IACf,GAAI,GAAG9uC,CAAG,GACV,GAAI,GACJ,QAAS,sBAAsBA,CAAG,WAAW8uC,CAAM,GAAA,CACpD,EACD,KACF,CAEA,KAAK7zC,EAAO,aAAc,CACxB,MAAM6zC,EAAS9zB,EAASqzB,GAAI,EACtB7jC,EAAM1H,EAAK,UAAUurC,EAAI,EAAI,EACnCA,GAAM,EACN,MAAMgB,EAAY,IAAI,WACpBr0B,EAAS,OACTA,EAAS,WAAaqzB,EACtB7jC,CAAA,EAEIsM,EAAMo3B,GAAY,OAAOmB,CAAS,EACxChB,GAAM7jC,EACN4jC,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,eACR,GAAI,KAAKM,CAAM,IACf,GAAI,IAAIh4B,CAAG,IACX,GAAI,GACJ,QAAS,sBAAsBA,CAAG,YAAYg4B,CAAM,GAAA,CACrD,EACD,KACF,CAEA,KAAK7zC,EAAO,aAAc,CACxB,MAAM6zC,EAAS9zB,EAASqzB,GAAI,EACtB7jC,EAAM1H,EAAK,UAAUurC,EAAI,EAAI,EACnCA,GAAM,EAAI7jC,EACV4jC,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,eACR,GAAI,KAAKM,CAAM,IACf,GAAI,OAAOtkC,CAAG,GACd,GAAI,GACJ,QAAS,sBAAsBA,CAAG,kBAAkBskC,CAAM,GAAA,CAC3D,EACD,KACF,CAEA,KAAK7zC,EAAO,aAAc,CACxB,MAAM6zC,EAAS9zB,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,eACR,GAAI,KAAKM,CAAM,IACf,GAAI,OACJ,GAAI,GACJ,QAAS,SAASA,CAAM,WAAA,CACzB,EACD,KACF,CAEA,KAAK7zC,EAAO,YAAa,CACvB,MAAM8E,EAASib,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,KAAKzuC,CAAM,IACf,GAAI,GACJ,GAAI,GACJ,QAAS,wDAAA,CACV,EACD,KACF,CAEA,KAAK9E,EAAO,cAAe,CACzB,MAAMmpC,EAAWppB,EAASqzB,GAAI,EACxBiB,EAAUt0B,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,KAAKpK,CAAQ,IACjB,GAAI,QAAQkL,CAAO,GACnB,GAAI,GACJ,QAAS,yBAAyBlL,CAAQ,KAAKA,EAAWkL,EAAU,CAAC,oBAAA,CACtE,EACD,KACF,CAEA,KAAKr0C,EAAO,UAAW,CACrB,MAAMs0C,EAAYv0B,EAASqzB,GAAI,EACzBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,YACR,GAAI,KAAKe,CAAS,IAClB,GAAIhB,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,QAAQU,CAAS,sCAAsChB,EAAQM,CAAU,CAAC,EAAA,CACpF,EACD,KACF,CAEA,KAAK5zC,EAAO,SAAU,CACpB,MAAMu0C,EAAWx0B,EAASqzB,GAAI,EACxBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,WACR,GAAI,KAAKgB,CAAQ,IACjB,GAAIjB,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,QAAQW,CAAQ,qBAAqBjB,EAAQM,CAAU,CAAC,kBAAA,CAClE,EACD,KACF,CACA,KAAK5zC,EAAO,YAAa,CACvB,MAAMypC,EAAQ5hC,EAAK,UAAUurC,EAAI,EAAI,EACrCA,GAAM,EACN,MAAMoB,EAAcz0B,EAASqzB,GAAI,EAC3B5J,EAAUzpB,EAASqzB,GAAI,EACvB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,OAAO9J,CAAK,GAChB,GAAI,KAAK+K,CAAW,KAAKA,EAAchL,EAAU,CAAC,IAClD,GAAI,KAAK9E,CAAO,IAChB,QAAS,aAAa+E,CAAK,SAASD,CAAO,cAAc9E,CAAO,GAAA,CACjE,EACD,KACF,CAEA,KAAK1kC,EAAO,aACZ,KAAKA,EAAO,aACZ,KAAKA,EAAO,cACZ,KAAKA,EAAO,YACZ,KAAKA,EAAO,YACZ,KAAKA,EAAO,cACZ,KAAKA,EAAO,cACZ,KAAKA,EAAO,aAAc,CACxB,MAAM8zC,EAAkC,CACtC,CAAC9zC,EAAO,YAAY,EAAG,eACvB,CAACA,EAAO,YAAY,EAAG,eACvB,CAACA,EAAO,aAAa,EAAG,gBACxB,CAACA,EAAO,WAAW,EAAG,cACtB,CAACA,EAAO,WAAW,EAAG,cACtB,CAACA,EAAO,aAAa,EAAG,gBACxB,CAACA,EAAO,aAAa,EAAG,gBACxB,CAACA,EAAO,YAAY,EAAG,cAAA,EAEnBkpC,EAASnpB,EAASqzB,GAAI,EACtB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQO,EAAQzzB,CAAE,EAClB,GAAI,KAAK6oB,CAAM,IACf,GAAI,KAAKxE,CAAO,IAChB,GAAI,GACJ,QAAS,GAAGoP,EAAQzzB,CAAE,CAAC,OAAOqkB,CAAO,OAAOoP,EAAQzzB,CAAE,EAAE,YAAA,CAAa,MAAM6oB,CAAM,IAAA,CAClF,EACD,KACF,CAEA,KAAKlpC,EAAO,cAAe,CACzB,MAAMkpC,EAASnpB,EAASqzB,GAAI,EACtBjK,EAAWppB,EAASqzB,GAAI,EACxBhK,EAASrpB,EAASqzB,GAAI,EACtB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBACR,GAAI,KAAKrK,CAAM,IACf,GAAI,WAAWC,CAAQ,YAAYC,CAAM,IACzC,GAAI,KAAK1E,CAAO,IAChB,QAAS,4BAA4BwE,CAAM,YAAYxE,CAAO,GAAA,CAC/D,EACD,KACF,CAEA,KAAK1kC,EAAO,OACZ,KAAKA,EAAO,OACZ,KAAKA,EAAO,OACZ,KAAKA,EAAO,OACZ,KAAKA,EAAO,OAAQ,CAClB,MAAM8zC,EAAkC,CACtC,CAAC9zC,EAAO,MAAM,EAAG,SACjB,CAACA,EAAO,MAAM,EAAG,SACjB,CAACA,EAAO,MAAM,EAAG,SACjB,CAACA,EAAO,MAAM,EAAG,SACjB,CAACA,EAAO,MAAM,EAAG,QAAA,EAEbg0C,EAAOj0B,EAASqzB,GAAI,EACpBa,EAAOl0B,EAASqzB,GAAI,EACpB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQO,EAAQzzB,CAAE,EAClB,GAAI,KAAK2zB,CAAI,IACb,GAAI,KAAKC,CAAI,IACb,GAAI,KAAKvP,CAAO,IAChB,QAAS,GAAGoP,EAAQzzB,CAAE,CAAC,OAAOqkB,CAAO,SAASsP,CAAI,KAAKF,EAAQzzB,CAAE,EAAE,QAAQ,MAAO,EAAE,CAAC,MAAM4zB,CAAI,GAAA,CAChG,EACD,KACF,CAEA,KAAKj0C,EAAO,cACZ,KAAKA,EAAO,YAAa,CACvB,MAAM8zC,EAAkC,CACtC,CAAC9zC,EAAO,aAAa,EAAG,gBACxB,CAACA,EAAO,WAAW,EAAG,aAAA,EAElBmpC,EAAWppB,EAASqzB,GAAI,EACxBqB,EAAU10B,EAASqzB,GAAI,EACvB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQO,EAAQzzB,CAAE,EAClB,GAAI,KAAK8oB,CAAQ,KAAKA,EAAWsL,EAAU,CAAC,IAC5C,GAAI,SAASA,CAAO,GACpB,GAAI,KAAK/P,CAAO,IAChB,QAAS,GAAGoP,EAAQzzB,CAAE,CAAC,OAAOqkB,CAAO,GAAA,CACtC,EACD,KACF,CAEA,KAAK1kC,EAAO,QAAS,CACnB,MAAMkpC,EAASnpB,EAASqzB,GAAI,EACtB1O,EAAU3kB,EAASqzB,GAAI,EAC7BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,UACR,GAAI,KAAKrK,CAAM,IACf,GAAI,KAAKxE,CAAO,IAChB,GAAI,GACJ,QAAS,UAAUwE,CAAM,UAAUxE,CAAO,GAAA,CAC3C,EACD,KACF,CAEA,KAAK1kC,EAAO,eAAgB,CAC1B,MAAM00C,EAAW30B,EAASqzB,GAAI,EACxBuB,EAAa50B,EAASqzB,GAAI,EAChCD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKmB,CAAQ,IACjB,GAAI,WAAWC,CAAU,GACzB,GAAI,GACJ,QAAS,eAAeD,CAAQ,iBAAiBC,CAAU,EAAA,CAC5D,EACD,KACF,CAEA,KAAK30C,EAAO,iBAAkB,CAC5B,MAAM00C,EAAW30B,EAASqzB,GAAI,EACxBjK,EAAWppB,EAASqzB,GAAI,EACxBwB,EAAU70B,EAASqzB,GAAI,EACvBtuC,EAASib,EAASqzB,GAAI,EAC5BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,mBACR,GAAI,KAAKmB,CAAQ,IACjB,GAAI,KAAKvL,CAAQ,MAAMyL,CAAO,IAC9B,GAAI,KAAK9vC,CAAM,IACf,QAAS,0BAA0BA,CAAM,gBAAgB4vC,CAAQ,EAAA,CAClE,EACD,KACF,CAEA,KAAK10C,EAAO,eAAgB,CAC1B,MAAM00C,EAAW30B,EAASqzB,GAAI,EAC9BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKmB,CAAQ,IACjB,GAAI,GACJ,GAAI,GACJ,QAAS,0BAA0BA,CAAQ,EAAA,CAC5C,EACD,KACF,CAEA,KAAK10C,EAAO,eAAgB,CAC1B,MAAM00C,EAAW30B,EAASqzB,GAAI,EACxBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKmB,CAAQ,IACjB,GAAIpB,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,oCAAoCc,CAAQ,aAAapB,EAAQM,CAAU,CAAC,kBAAA,CACtF,EACD,KACF,CAEA,KAAK5zC,EAAO,YAAa,CACvB,MAAM60C,EAAQ90B,EAASqzB,GAAI,EACrB0B,EAAc/0B,EAASqzB,GAAI,EAC3BwB,EAAU70B,EAASqzB,GAAI,EACvBtuB,EAAO/E,EAASqzB,GAAI,EAC1BD,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,OAAOsB,CAAK,IAChB,GAAI,UAAUC,CAAW,MAAMF,CAAO,IACtC,GAAI,QAAQ9vB,IAAS,EAAI,OAAS,QAAQ,GAC1C,QAAS,yBAAyB+vB,CAAK,KAAK/vB,IAAS,EAAI,aAAe,QAAQ,GAAA,CACjF,EACD,KACF,CAEA,KAAK9kB,EAAO,YAAa,CACvB,MAAM60C,EAAQ90B,EAASqzB,GAAI,EACrB0B,EAAc/0B,EAASqzB,GAAI,EAC3BwB,EAAU70B,EAASqzB,GAAI,EACvBzE,EAAS5uB,EAASqzB,GAAI,EACtB5D,EAASzvB,EAASqzB,GAAI,EACtB2B,EAAY,CAAC,QAAS,MAAO,MAAO,MAAO,KAAK,EACtD5B,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,OAAOsB,CAAK,IAChB,GAAI,OAAOlG,IAAW,IAAM,IAAM,KAAKA,CAAM,GAAG,GAChD,GAAIoG,EAAUvF,CAAM,GAAK,GAAGA,CAAM,GAClC,QAAS,sBAAsBuF,EAAUvF,CAAM,GAAKA,CAAM,gBAAgBsF,CAAW,MAAMF,CAAO,GAAA,CACnG,EACD,KACF,CAEA,KAAK50C,EAAO,YAAa,CACvB,MAAM60C,EAAQ90B,EAASqzB,GAAI,EACrB4B,EAAYj1B,EAASqzB,GAAI,EACzBvF,EAAY9tB,EAASqzB,GAAI,EACzBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,cACR,GAAI,OAAOsB,CAAK,IAChB,GAAI,cAAcG,CAAS,gBAAgBnH,CAAS,IACpD,GAAIyF,EAAQM,CAAU,EACtB,QAAS,sCAAsCN,EAAQM,CAAU,CAAC,EAAA,CACnE,EACD,KACF,CAEA,KAAK5zC,EAAO,aAAc,CACxB,MAAMuvC,EAASxvB,EAASqzB,GAAI,EACtB6B,EAAWl1B,EAASqzB,GAAI,EACxB9D,EAASvvB,EAASqzB,GAAI,EACtB5D,EAASzvB,EAASqzB,GAAI,EACtB2B,EAAY,CAAC,QAAS,MAAO,MAAO,MAAO,KAAK,EACtD5B,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,eACR,GAAI,SAAShE,CAAM,YAAY0F,CAAQ,IACvC,GAAI,KAAK3F,CAAM,IACf,GAAIyF,EAAUvF,CAAM,GAAK,GAAGA,CAAM,GAClC,QAAS,YAAYuF,EAAUvF,CAAM,GAAKA,CAAM,WAAWF,CAAM,GAAA,CAClE,EACD,KACF,CAEA,KAAKtvC,EAAO,eAAgB,CAC1B,MAAMkmB,EAAMnG,EAASqzB,GAAI,EACnBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,iBACR,GAAI,KAAKrtB,CAAG,IACZ,GAAIotB,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,WAAWN,EAAQM,CAAU,CAAC,SAAS1tB,CAAG,WAAA,CACpD,EACD,KACF,CAEA,KAAKlmB,EAAO,mBAAoB,CAC9B,MAAMkmB,EAAMnG,EAASqzB,GAAI,EACnBQ,EAAa/rC,EAAK,UAAUurC,EAAI,EAAI,EAC1CA,GAAM,EACND,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,qBACR,GAAI,KAAKrtB,CAAG,IACZ,GAAIotB,EAAQM,CAAU,EACtB,GAAI,GACJ,QAAS,WAAWN,EAAQM,CAAU,CAAC,SAAS1tB,CAAG,eAAA,CACpD,EACD,KACF,CAEA,QACEitB,EAAa,KAAK,CAChB,KAAAI,EACA,OAAQ,gBAAgBlzB,EAAG,SAAS,EAAE,CAAC,IACvC,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,QAAS,gBAAA,CACV,EACD,KAAA,CAEN,CAEA,OAAO8yB,CACT,CAKO,SAAS+B,GACd/B,EACQ,CACR,MAAMgC,EAAM,CAACluC,EAAWF,IAAcE,EAAE,OAAOF,EAAG,GAAG,EAC/CusC,EAAWvsC,GAAc,KAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,GAEnE,IAAIquC,EAAM,GAAGD,EAAI,OAAQ,CAAC,CAAC,IAAIA,EAAI,SAAU,EAAE,CAAC,IAAIA,EAAI,KAAM,EAAE,CAAC,IAAIA,EAAI,KAAM,EAAE,CAAC,IAAIA,EAAI,KAAM,EAAE,CAAC;AAAA,EACnGC,GAAO,IAAI,OAAO,EAAE,EAAI;AAAA,EAExB,UAAWC,KAAOlC,EAChBiC,GAAO,GAAGD,EAAI7B,EAAQ+B,EAAI,IAAI,EAAG,CAAC,CAAC,IAAIF,EAAIE,EAAI,OAAQ,EAAE,CAAC,IAAIF,EAAIE,EAAI,GAAI,EAAE,CAAC,IAAIF,EAAIE,EAAI,GAAI,EAAE,CAAC,IAAIF,EAAIE,EAAI,GAAI,EAAE,CAAC,IAAIA,EAAI,OAAO;AAAA,EAGpI,OAAOD,CACT,CC38KO,SAASE,GACdtpC,EACuC,CACvC,GACEA,aAAkB8oB,IACjB,OAAO9oB,GAAW,UAAYA,IAAW,MAAQ,SAAUA,EAE5D,MAAO,CAAE,KAAOA,EAAe,IAAA,EAEjC,GAAI,OAAOA,GAAW,UAAYA,IAAW,MAAQ,SAAUA,EAC7D,MAAO,CAAE,KAAMA,CAAA,EAEjB,GAAI,OAAOA,GAAW,SAAU,CAC9B,MAAMooB,EAAUpoB,EAAO,KAAA,EACvB,OACEooB,EAAQ,SAAS,GAAG,GACpBA,EAAQ,SAAS,GAAG,GACpBA,EAAQ,SAAS,GAAG,GACpBA,EAAQ,SAAS,GAAG,GACpBA,EAAQ,SAAS,GAAG,GACpBA,EAAQ,SAAS,GAAG,EAEb,CAAE,KAAMF,GAAgBE,CAAO,EAAG,QAASA,CAAA,EAE7C,CAAE,QAASA,CAAA,CACpB,CACA,MAAO,CAAA,CACT,CAIO,SAASmhB,GAA0BtiB,EAA2B,CACnE,MAAMuiB,EAAkB,CAAA,EACxB,SAASC,EAAK1gB,EAAgB,CAC5B,GAAIA,EAAK,OAAS,KAAM,CACtB,MAAMiU,EAASjU,EAAK,KAAK,YAAA,EACzB,GAAIlC,GAAoBmW,CAAM,EAAG,CAC/B,MAAMrT,EAAOZ,EAAK,KAAK,CAAC,EAClBJ,EACJgB,GAAQA,EAAK,OAAS,OAASA,EAAK,OAAS,IACzCA,EAAK,KACL,OACN6f,EAAK,KAAK,CACR,KAAMxM,EACN,QAAArU,CAAA,CACD,CACH,CACA,UAAWxB,KAAO4B,EAAK,KACrB0gB,EAAKtiB,CAAG,CAEZ,MAAW4B,EAAK,OAAS,WACvB0gB,EAAK1gB,EAAK,IAAI,EACd0gB,EAAK1gB,EAAK,KAAK,EAEnB,CACA,OAAA0gB,EAAKxiB,CAAI,EACFuiB,CACT,CAEO,SAASE,GAAoBvjC,EAAoC,CACtE,GAAI,CAACA,EAAM,MAAO,CAAA,EAElB,GAAI,MAAM,QAAQA,CAAI,EAAG,CACvB,MAAMwjC,EAAkC,CAAA,EACxC,UAAWC,KAAOzjC,EAChBwjC,EAAO,KAAK,GAAGD,GAAoBE,CAAG,CAAC,EAEzC,OAAOD,CACT,CAEA,GACExjC,aAAgB2iB,IACf,OAAO3iB,GAAS,UAAYA,IAAS,MAAQ,SAAUA,EACxD,CACA,MAAM8gB,EAAiB9gB,EAAK,KAE5B,MAAO,CACL,CACE,MAHUuiB,GAAmBzB,CAAI,EAIjC,KAAAA,EACA,UACEA,EAAK,OAAS,OAASA,EAAK,OAAS,IAAMA,EAAK,KAAO,OACzD,GAAIA,EAAK,OAAS,KAAOA,EAAK,KAAO,MAAA,CACvC,CAEJ,CAEA,GAAI,OAAO9gB,GAAS,SAAU,CAC5B,MAAMiiB,EAAUjiB,EAAK,KAAA,EACrB,GAAI,CAACiiB,EAAS,MAAO,CAAA,EAErB,MAAMkS,EAAS1R,GAAgBR,CAAO,EACtC,MAAO,CACL,CACE,MAAOkS,EAAO,MACd,KAAMA,EAAO,KACb,UACEA,EAAO,KAAK,OAAS,OAASA,EAAO,KAAK,OAAS,IAC/CA,EAAO,KAAK,KACZ,OACN,GAAIA,EAAO,KAAK,OAAS,KAAOA,EAAO,KAAK,KAAO,MAAA,CACrD,CAEJ,CAEA,GAAI,OAAOn0B,GAAS,UAAYA,IAAS,KAAM,CAC7C,GAAI,SAAUA,GAAQ,UAAWA,EAAM,CACrC,MAAM8gB,EAAiB9gB,EAAK,KAC5B,MAAO,CACL,CACE,MAAOA,EAAK,MACZ,KAAA8gB,EACA,UACEA,EAAK,OAAS,OAASA,EAAK,OAAS,IAAMA,EAAK,KAAO,OACzD,GAAIA,EAAK,OAAS,KAAOA,EAAK,KAAO,MAAA,CACvC,CAEJ,CAGA,GACE,QAAS9gB,GACT,OAAQA,GACR,OAAOA,EAAK,KAAQ,UACpB,OAAOA,EAAK,IAAO,SACnB,CACA,MAAMm0B,EAAS1R,GAAgB,GAAGziB,EAAK,GAAG,OAAOA,EAAK,EAAE,EAAE,EAC1D,MAAO,CACL,CACE,UAAWA,EAAK,MAAQ,IAAM,OAAYA,EAAK,IAC/C,MAAOA,EAAK,GACZ,KAAMm0B,EAAO,KACb,GAAIA,EAAO,KAAK,OAAS,KAAOA,EAAO,KAAK,KAAO,MAAA,CACrD,CAEJ,CAGA,MAAMqP,EAAkC,CAAA,EACxC,SAAW,CAAC/jC,EAAK7M,CAAG,IAAK,OAAO,QAAQoN,CAAI,EAC1C,GAAI,OAAOpN,GAAQ,SAAU,CAC3B,MAAMuhC,EAAS1R,GAAgB,GAAGhjB,CAAG,OAAO7M,CAAG,EAAE,EACjD4wC,EAAO,KAAK,CACV,UAAW/jC,IAAQ,IAAM,OAAYA,EACrC,MAAO7M,EACP,KAAMuhC,EAAO,KACb,GAAIA,EAAO,KAAK,OAAS,KAAOA,EAAO,KAAK,KAAO,MAAA,CACpD,CACH,CAEF,OAAOqP,CACT,CAEA,MAAO,CAAA,CACT,CAwFA,SAASE,GAA0BC,EAAsB,CACvD,GAAI,OAAOA,GAAc,SAAU,CACjC,MAAM1hB,EAAU0hB,EAAU,KAAA,EAC1B,GAAIjjB,GAAoBuB,CAAO,EAC7B,MAAM,IAAIvxB,GAAgCuxB,CAAO,EAEnD,GAAIA,EAAQ,SAAS,GAAG,EACtB,GAAI,CACF,MAAMnB,EAAOiB,GAAgBE,CAAO,EACpCpB,GAAeC,EAAM,OAAO,CAC9B,OAASwG,EAAG,CACV,GAAIA,aAAa52B,GACf,MAAM42B,CAEV,CAEJ,MACEqc,aAAqBhhB,IACpB,OAAOghB,GAAc,UAAYA,IAAc,MAAQ,SAAUA,EAElE9iB,GAAe8iB,EAAU,KAAM,OAAO,EAEtC,OAAOA,GAAc,UACrBA,IAAc,MACd,SAAUA,GAEV9iB,GAAe8iB,EAAuB,OAAO,CAEjD,CAEO,MAAMC,EAAa,CAsBxB,YAAYtxC,EAA4BnE,EAAmB,CArBnD2C,EAAA,WACAA,EAAA,kBACAA,EAAA,eAAyB,CAAA,GACzBA,EAAA,oBAAwC,CAAA,GACxCA,EAAA,kBAA4B,MAC5BA,EAAA,mBAA6B,MAC7BA,EAAA,eAAyB,MACzBA,EAAA,eAA0B,OAC1BA,EAAA,iBAAuB,CAAA,GACvBA,EAAA,iBAAsB,CAAA,GACtBA,EAAA,iBAAwB,CAAA,GACxBA,EAAA,gBAAsB,CAAA,GACtBA,EAAA,qBAA+B,CAAA,GAC/BA,EAAA,aAAsB,CAAA,GACtBA,EAAA,gBAQN,KAAK,GAAKwB,EACV,KAAK,UAAYnE,CACnB,CARA,YAAY8jC,EAA6B,CACvC,YAAK,QAAUA,EACR,IACT,CAkBA,KACE5kC,EACAw2C,EACAC,EACAC,EACM,CACN,MAAM71B,EAAM61B,IAAa,OAAYD,EAAe,IAC9CE,EAAOD,IAAa,OAAYA,EAAWD,EACjD,YAAK,MAAM,KAAK,CACd,KAAM,QACN,MAAAz2C,EACA,QAAAw2C,EACA,GAAA31B,EACA,SAAU81B,CAAA,CACX,EACM,IACT,CAaA,UACE32C,EACAw2C,EACAC,EACAC,EACM,CACN,OAAO,KAAK,KAAK12C,EAAOw2C,EAASC,EAAqBC,CAAe,CACvE,CAaA,SACE12C,EACAw2C,EACAC,EACAC,EACM,CACN,MAAM71B,EAAM61B,IAAa,OAAYD,EAAe,IAC9CE,EAAOD,IAAa,OAAYA,EAAWD,EACjD,YAAK,MAAM,KAAK,CACd,KAAM,OACN,MAAAz2C,EACA,QAAAw2C,EACA,GAAA31B,EACA,SAAU81B,CAAA,CACX,EACM,IACT,CAEA,UAAyB,CACvB,OAAO,KAAK,KACd,CAUA,MACEC,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,cAAA,EAClBS,GACF,KAAK,QAAQ,KAAKA,CAAS,CAE/B,SAAWh2B,IAAO,QAAauT,IAAU,OACvC,GAAI,OAAOwiB,GAAkB,SAAU,CACrCP,GAA0BO,CAAa,EACvC,MAAMnjB,EAAOiB,GAAgBkiB,CAAa,EAC1C,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,KAAAnjB,EAAM,CAC1C,MACEmjB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,GAEZP,GAA0BO,CAAa,EACvC,KAAK,QAAQ,KAAK,CAChB,KAAM,OACN,KAAOA,EAAsB,IAAA,CAC9B,GAED,OAAOA,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,IAEVP,GAA0BO,CAAa,EACvC,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,KAAMA,EAA2B,OAEhE,CAGL,GAFAP,GAA0BO,CAAa,EACvCP,GAA0BjiB,CAAK,EAC3B,OAAOvT,GAAO,UAAYA,EAAG,OAAO,YAAA,IAAkB,KACxD,OAAO,KAAK,QAAQ+1B,EAAyBxiB,CAAK,EAEpD,GAAI,OAAOvT,GAAO,UAAYA,EAAG,OAAO,YAAA,IAAkB,SACxD,OAAO,KAAK,WAAW+1B,EAAyBxiB,CAAK,EAEvD,MAAM5nB,EAASspC,GAAkBc,CAAa,EAC9C,KAAK,QAAQ,KAAK,CAChB,KAAM,MACN,QAASpqC,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACD,CACH,CACA,OAAO,IACT,CAUA,QACEwiB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,cAAA,EAClBS,GACF,KAAK,YAAYA,CAAS,CAE9B,SAAWh2B,IAAO,QAAauT,IAAU,OACvC,GAAI,OAAOwiB,GAAkB,SAAU,CACrCP,GAA0BO,CAAa,EACvC,MAAMnjB,EAAOiB,GAAgBkiB,CAAa,EAC1C,KAAK,YAAY,CAAE,KAAM,OAAQ,KAAAnjB,EAAM,CACzC,MACEmjB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,GAEZP,GAA0BO,CAAa,EACvC,KAAK,YAAY,CACf,KAAM,OACN,KAAOA,EAAsB,IAAA,CAC9B,GAED,OAAOA,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,IAEVP,GAA0BO,CAAa,EACvC,KAAK,YAAY,CAAE,KAAM,OAAQ,KAAMA,EAA2B,OAE/D,CAGL,GAFAP,GAA0BO,CAAa,EACvCP,GAA0BjiB,CAAK,EAC3B,OAAOvT,GAAO,UAAYA,EAAG,OAAO,YAAA,IAAkB,KACxD,OAAO,KAAK,UAAU+1B,EAAyBxiB,CAAK,EAEtD,GAAI,OAAOvT,GAAO,UAAYA,EAAG,OAAO,YAAA,IAAkB,SACxD,OAAO,KAAK,aAAa+1B,EAAyBxiB,CAAK,EAEzD,MAAM5nB,EAASspC,GAAkBc,CAAa,EAC9C,KAAK,YAAY,CACf,KAAM,MACN,QAASpqC,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACD,CACH,CACA,OAAO,IACT,CAUA,SACEwiB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,cAAA,EAClBS,GACF,KAAK,QAAQ,KAAK,CAAE,KAAM,MAAO,MAAOA,EAAW,CAEvD,SAAWh2B,IAAO,QAAauT,IAAU,OACvC,GAAI,OAAOwiB,GAAkB,SAAU,CACrCP,GAA0BO,CAAa,EACvC,MAAMnjB,EAAOiB,GAAgBkiB,CAAa,EAC1C,KAAK,QAAQ,KAAK,CAAE,KAAM,MAAO,MAAO,CAAE,KAAM,OAAQ,KAAAnjB,CAAA,CAAK,CAAG,CAClE,MACEmjB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,GAEZP,GAA0BO,CAAa,EACvC,KAAK,QAAQ,KAAK,CAChB,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAOA,EAAsB,IAAA,CAAK,CAC1D,GAED,OAAOA,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,IAEVP,GAA0BO,CAAa,EACvC,KAAK,QAAQ,KAAK,CAChB,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAMA,CAAA,CAA0B,CACxD,OAEE,CACLP,GAA0BO,CAAa,EACvCP,GAA0BjiB,CAAK,EAC/B,MAAM5nB,EAASspC,GAAkBc,CAAa,EAC9C,KAAK,QAAQ,KAAK,CAChB,KAAM,MACN,MAAO,CACL,KAAM,MACN,QAASpqC,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACF,CACD,CACH,CACA,OAAO,IACT,CAUA,WACEwiB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,cAAA,EAClBS,GACF,KAAK,YAAY,CAAE,KAAM,MAAO,MAAOA,EAAW,CAEtD,SAAWh2B,IAAO,QAAauT,IAAU,OACvC,GAAI,OAAOwiB,GAAkB,SAAU,CACrCP,GAA0BO,CAAa,EACvC,MAAMnjB,EAAOiB,GAAgBkiB,CAAa,EAC1C,KAAK,YAAY,CAAE,KAAM,MAAO,MAAO,CAAE,KAAM,OAAQ,KAAAnjB,CAAA,EAAQ,CACjE,MACEmjB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,GAEZP,GAA0BO,CAAa,EACvC,KAAK,YAAY,CACf,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAOA,EAAsB,IAAA,CAAK,CAC1D,GAED,OAAOA,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,IAEVP,GAA0BO,CAAa,EACvC,KAAK,YAAY,CACf,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAMA,CAAA,CAA0B,CACxD,OAEE,CACLP,GAA0BO,CAAa,EACvCP,GAA0BjiB,CAAK,EAC/B,MAAM5nB,EAASspC,GAAkBc,CAAa,EAC9C,KAAK,YAAY,CACf,KAAM,MACN,MAAO,CACL,KAAM,MACN,QAASpqC,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACF,CACD,CACH,CACA,OAAO,IACT,CAEA,SAASsB,EAAsB,CAC7B,OAAO,KAAK,MAAMA,CAAM,CAC1B,CAEA,WAAWA,EAAsB,CAC/B,OAAO,KAAK,QAAQA,CAAM,CAC5B,CAEA,UAAUP,EAAuB,CAC/B,OAAAkhB,GAA0BlhB,CAAO,EACjC,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,QAAAA,EAAS,OAAQ,GAAM,EAClD,IACT,CAEA,aAAaA,EAAuB,CAClC,OAAAkhB,GAA0BlhB,CAAO,EACjC,KAAK,QAAQ,KAAK,CAAE,KAAM,OAAQ,QAAAA,EAAS,OAAQ,GAAO,EACnD,IACT,CAEA,YAAYA,EAAuB,CACjC,OAAAkhB,GAA0BlhB,CAAO,EACjC,KAAK,YAAY,CAAE,KAAM,OAAQ,QAAAA,EAAS,OAAQ,GAAM,EACjD,IACT,CAEA,eAAeA,EAAuB,CACpC,OAAAkhB,GAA0BlhB,CAAO,EACjC,KAAK,YAAY,CAAE,KAAM,OAAQ,QAAAA,EAAS,OAAQ,GAAO,EAClD,IACT,CAEA,UAAUA,EAAiB5Y,EAAuB,CAChD,OAAO,KAAK,MAAM4Y,EAAS,OAAQ5Y,CAAO,CAC5C,CAEA,aAAa4Y,EAAiB5Y,EAAuB,CACnD,OAAO,KAAK,MAAM4Y,EAAS,WAAY5Y,CAAO,CAChD,CAEA,gBAAgB4Y,EAAiB2hB,EAAsB,CACrD,OAAO,KAAK,MAAM3hB,EAAS,cAAe2hB,CAAM,CAClD,CAEA,cAAc3hB,EAAiB4hB,EAAsB,CACnD,OAAO,KAAK,MAAM5hB,EAAS,YAAa4hB,CAAM,CAChD,CAEA,cAAc5hB,EAAiB6hB,EAAyB,CACtD,OAAO,KAAK,MAAM7hB,EAAS,WAAY6hB,CAAS,CAClD,CAEA,YAAY7hB,EAAiB5Y,EAAuB,CAClD,OAAO,KAAK,QAAQ4Y,EAAS,OAAQ5Y,CAAO,CAC9C,CAEA,eAAe4Y,EAAiB5Y,EAAuB,CACrD,OAAO,KAAK,QAAQ4Y,EAAS,WAAY5Y,CAAO,CAClD,CAEA,kBAAkB4Y,EAAiB2hB,EAAsB,CACvD,OAAO,KAAK,QAAQ3hB,EAAS,cAAe2hB,CAAM,CACpD,CAEA,gBAAgB3hB,EAAiB4hB,EAAsB,CACrD,OAAO,KAAK,QAAQ5hB,EAAS,YAAa4hB,CAAM,CAClD,CAEA,gBAAgB5hB,EAAiB6hB,EAAyB,CACxD,OAAO,KAAK,QAAQ7hB,EAAS,WAAY6hB,CAAS,CACpD,CAEA,QAAQ7hB,EAAiBljB,EAAqB,CAE5C,GADAokC,GAA0BlhB,CAAO,EAC7B,CAAC,MAAM,QAAQljB,CAAM,EACvB,MAAM,IAAI,UAAU,4CAA4C,EAElE,GAAIA,EAAO,OAASxS,GAClB,MAAM,IAAI,WACR,gDAAgDA,EAAgB,WAAA,EAGpE,MAAM+M,EAASspC,GAAkB3gB,CAAO,EACxC,YAAK,QAAQ,KAAK,CAChB,KAAM,KACN,QAAS3oB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAAyF,EACA,MAAO,EAAA,CACR,EACM,IACT,CAEA,WAAWkjB,EAAiBljB,EAAqB,CAE/C,GADAokC,GAA0BlhB,CAAO,EAC7B,CAAC,MAAM,QAAQljB,CAAM,EACvB,MAAM,IAAI,UAAU,+CAA+C,EAErE,GAAIA,EAAO,OAASxS,GAClB,MAAM,IAAI,WACR,mDAAmDA,EAAgB,WAAA,EAGvE,MAAM+M,EAASspC,GAAkB3gB,CAAO,EACxC,YAAK,QAAQ,KAAK,CAChB,KAAM,KACN,QAAS3oB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAAyF,EACA,MAAO,EAAA,CACR,EACM,IACT,CAEA,UAAUkjB,EAAiBljB,EAAqB,CAE9C,GADAokC,GAA0BlhB,CAAO,EAC7B,CAAC,MAAM,QAAQljB,CAAM,EACvB,MAAM,IAAI,UAAU,8CAA8C,EAEpE,GAAIA,EAAO,OAASxS,GAClB,MAAM,IAAI,WACR,kDAAkDA,EAAgB,WAAA,EAGtE,MAAM+M,EAASspC,GAAkB3gB,CAAO,EACxC,YAAK,YAAY,CACf,KAAM,KACN,QAAS3oB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAAyF,EACA,MAAO,EAAA,CACR,EACM,IACT,CAEA,aAAakjB,EAAiBljB,EAAqB,CAEjD,GADAokC,GAA0BlhB,CAAO,EAC7B,CAAC,MAAM,QAAQljB,CAAM,EACvB,MAAM,IAAI,UAAU,iDAAiD,EAEvE,GAAIA,EAAO,OAASxS,GAClB,MAAM,IAAI,WACR,qDAAqDA,EAAgB,WAAA,EAGzE,MAAM+M,EAASspC,GAAkB3gB,CAAO,EACxC,YAAK,YAAY,CACf,KAAM,KACN,QAAS3oB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAAyF,EACA,MAAO,EAAA,CACR,EACM,IACT,CAEA,YAA4B,CAC1B,OAAO,KAAK,OACd,CAEA,eAAoC,CAClC,OAAI,KAAK,QAAQ,SAAW,EAAU,KAClC,KAAK,QAAQ,SAAW,EAAU,KAAK,QAAQ,CAAC,EAC7C,CAAE,KAAM,MAAO,SAAU,CAAC,GAAG,KAAK,OAAO,CAAA,CAClD,CAEQ,YAAYykB,EAA2B,CAC7C,GAAI,KAAK,QAAQ,SAAW,EAAG,CAC7B,KAAK,QAAQ,KAAKA,CAAM,EACxB,MACF,CACA,GACE,KAAK,QAAQ,SAAW,GACxB,KAAK,QAAQ,CAAC,EAAE,OAAS,MACzB,KAAK,QAAQ,CAAC,EAAE,SAChB,CACA,KAAK,QAAQ,CAAC,EAAE,SAAS,KAAKA,CAAM,EACpC,MACF,CACA,IAAIugB,EACA,KAAK,QAAQ,SAAW,EAC1BA,EAAO,KAAK,QAAQ,CAAC,EAErBA,EAAO,CAAE,KAAM,MAAO,SAAU,CAAC,GAAG,KAAK,OAAO,CAAA,EAElD,KAAK,QAAU,CAAC,CAAE,KAAM,KAAM,SAAU,CAACA,EAAMvgB,CAAM,EAAG,CAC1D,CAEA,MAAMzzB,EAAqB,CACzB,YAAK,WAAaA,EACX,IACT,CAEA,OAAOA,EAAqB,CAC1B,YAAK,YAAcA,EACZ,IACT,CAEA,QACEi0C,EACA/5B,EAA4B,MAC5Bg6B,EACM,CACN,GAAI,OAAOD,GAAc,SAAU,CACjC,KAAK,QAAUA,EACf,KAAK,QAAU/5B,EACf,MAAM3Q,EAASspC,GAAkBoB,CAAS,EAC1C,KAAK,UAAU,KAAK,CAClB,QAAS1qC,EAAO,SAAW0qC,EAC3B,KAAM1qC,EAAO,KACb,UAAA2Q,EACA,UAAAg6B,CAAA,CACD,CACH,SACED,aAAqB5hB,IACpB,OAAO4hB,GAAc,UAAYA,IAAc,MAAQ,SAAUA,EAElE,KAAK,UAAU,KAAK,CAClB,KAAOA,EAAkB,KACzB,UAAA/5B,EACA,UAAAg6B,CAAA,CACD,UAED,OAAOD,GAAc,UACrBA,IAAc,MACd,SAAUA,EAEV,KAAK,UAAU,KAAK,CAClB,KAAMA,EACN,UAAA/5B,EACA,UAAAg6B,CAAA,CACD,UACQ,MAAM,QAAQD,CAAS,EAChC,UAAWvkC,KAAQukC,EACjB,GAAI,OAAOvkC,GAAS,SAAU,CAC5B,MAAMnG,EAASspC,GAAkBnjC,CAAI,EACrC,KAAK,UAAU,KAAK,CAClB,QAASnG,EAAO,SAAWmG,EAC3B,KAAMnG,EAAO,KACb,UAAW,KAAA,CACZ,CACH,MACE,KAAK,UAAU,KAAKmG,CAAI,OAI5B,KAAK,UAAU,KAAKukC,CAAS,EAE/B,OAAO,IACT,CAEA,WAAWtlC,EAAgD,CACzD,UAAWe,KAAQf,EACjB,GAAI,MAAM,QAAQe,CAAI,EACpB,UAAWyjC,KAAOzjC,EAChB,KAAK,eAAeyjC,CAAG,OAGzB,KAAK,eAAezjC,CAAI,EAG5B,OAAO,IACT,CAEQ,eAAeA,EAAyB,CAC9C,GACEA,aAAgB2iB,IACf,OAAO3iB,GAAS,UAAYA,IAAS,MAAQ,SAAUA,EAExD,KAAK,UAAU,KAAK,CAAE,KAAOA,EAAa,KAAM,EAChD,KAAK,UAAU,KAAKuiB,GAAoBviB,EAAa,IAAI,CAAC,UAE1D,OAAOA,GAAS,UAChBA,IAAS,MACT,SAAUA,EAEV,KAAK,UAAU,KAAK,CAAE,KAAMA,EAAkB,EAC9C,KAAK,UAAU,KAAKuiB,GAAmBviB,CAAgB,CAAC,UAC/C,OAAOA,GAAS,SAAU,CACnC,MAAMnG,EAASspC,GAAkBnjC,CAAI,EACrC,KAAK,UAAU,KAAK,CAClB,QAASnG,EAAO,SAAWmG,EAC3B,KAAMnG,EAAO,IAAA,CACd,EACD,KAAK,UAAU,KAAKmG,CAAI,CAC1B,CACF,CAEQ,6BAA6B+jB,EAA2B,CAC9D,MAAM0gB,EAAc,CAACjiB,EAAkB1B,IAAoB,CACzD,GAAIA,EAAM,CACR,MAAMuiB,EAAOD,GAA0BtiB,CAAI,EAC3C,UAAWhO,KAAOuwB,EACA,KAAK,SAAS,KAC3B95B,GACCA,EAAE,OAASuJ,EAAI,OACdvJ,EAAE,UAAYuJ,EAAI,SAChBvJ,EAAE,UAAY,QAAauJ,EAAI,UAAY,OAAA,GAGhD,KAAK,SAAS,KAAKA,CAAG,CAG5B,SAAW0P,GAAWA,EAAQ,SAAS,GAAG,EACxC,GAAI,CACF,MAAM2R,EAASpS,GAAgBS,CAAO,EAChC6gB,EAAOD,GAA0BjP,CAAM,EAC7C,UAAWrhB,KAAOuwB,EACA,KAAK,SAAS,KAC3B95B,GACCA,EAAE,OAASuJ,EAAI,OACdvJ,EAAE,UAAYuJ,EAAI,SAChBvJ,EAAE,UAAY,QAAauJ,EAAI,UAAY,OAAA,GAGhD,KAAK,SAAS,KAAKA,CAAG,CAG5B,MAAQ,CAER,CAEJ,EAEA,GAAIiR,EAAO,OAAS,MAClB0gB,EAAY1gB,EAAO,QAASA,EAAO,IAAI,UAC9BA,EAAO,OAAS,QAAUA,EAAO,KAC1C0gB,EAAY,OAAW1gB,EAAO,IAAI,UACzBA,EAAO,OAAS,OACzB0gB,EAAY1gB,EAAO,QAASA,EAAO,IAAI,UAC9BA,EAAO,OAAS,OAASA,EAAO,MACzC,KAAK,6BAA6BA,EAAO,KAAK,WAE7CA,EAAO,OAAS,OAASA,EAAO,OAAS,OAC1CA,EAAO,SAEP,UAAWG,KAASH,EAAO,SACzB,KAAK,6BAA6BG,CAAK,CAG7C,CAUA,OACE+f,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,oBAAA,EAClBS,IACF,KAAK,cAAc,KAAKA,CAAS,EACjC,KAAK,6BAA6BA,CAAS,EAE/C,SAAWh2B,IAAO,QAAauT,IAAU,QACvC,GAAI,OAAOwiB,GAAkB,SAAU,CAErC,MAAMlgB,EAAsB,CAAE,KAAM,OAAQ,KAD/BhC,GAAgBkiB,CAAa,CACE,EAC5C,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,SACEkgB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,EACZ,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,OACN,KAAOkgB,EAAsB,IAAA,EAE/B,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,SACE,OAAOkgB,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,EACV,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,OACN,KAAMkgB,CAAA,EAER,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,MACK,CACL,MAAMlqB,EAASspC,GAAkBc,CAAa,EACxClgB,EAAsB,CAC1B,KAAM,MACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,EAEF,KAAK,cAAc,KAAKsC,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,CACA,OAAO,IACT,CAUA,SACEkgB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,oBAAA,EAClBS,IACF,KAAK,kBAAkBA,CAAS,EAChC,KAAK,6BAA6BA,CAAS,EAE/C,SAAWh2B,IAAO,QAAauT,IAAU,QACvC,GAAI,OAAOwiB,GAAkB,SAAU,CAErC,MAAMlgB,EAAsB,CAAE,KAAM,OAAQ,KAD/BhC,GAAgBkiB,CAAa,CACE,EAC5C,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,SACEkgB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,EACZ,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,OACN,KAAOkgB,EAAsB,IAAA,EAE/B,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,SACE,OAAOkgB,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,EACV,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,OACN,KAAMkgB,CAAA,EAER,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,MACK,CACL,MAAMlqB,EAASspC,GAAkBc,CAAa,EACxClgB,EAAsB,CAC1B,KAAM,MACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,EAEF,KAAK,kBAAkBsC,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,CACA,OAAO,IACT,CAUA,UACEkgB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,oBAAA,EACtB,GAAIS,EAAW,CACb,MAAMngB,EAAsB,CAAE,KAAM,MAAO,MAAOmgB,CAAA,EAClD,KAAK,cAAc,KAAKngB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,CACF,SAAW7V,IAAO,QAAauT,IAAU,QACvC,GAAI,OAAOwiB,GAAkB,SAAU,CAErC,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAHZhC,GAAgBkiB,CAAa,CAGjB,CAAK,EAE9B,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,SACEkgB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,EACZ,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAOkgB,EAAsB,IAAA,CAAK,EAE3D,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,SACE,OAAOkgB,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,EACV,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAMkgB,CAAA,CAA0B,EAEzD,KAAK,cAAc,KAAKlgB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,MACK,CACL,MAAMlqB,EAASspC,GAAkBc,CAAa,EACxClgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CACL,KAAM,MACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACF,EAEF,KAAK,cAAc,KAAKsC,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,CAC1C,CACA,OAAO,IACT,CAUA,YACEkgB,EAKA/1B,EACAuT,EACM,CACN,GAAI,OAAOwiB,GAAkB,WAAY,CACvC,MAAMR,EAAM,IAAIG,GAAa,KAAK,GAAI,KAAK,SAAS,EACpDK,EAAcR,CAAG,EACjB,MAAMS,EAAYT,EAAI,oBAAA,EACtB,GAAIS,EAAW,CACb,MAAMngB,EAAsB,CAAE,KAAM,MAAO,MAAOmgB,CAAA,EAClD,KAAK,kBAAkBngB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,CACF,SAAW7V,IAAO,QAAauT,IAAU,QACvC,GAAI,OAAOwiB,GAAkB,SAAU,CAErC,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAHZhC,GAAgBkiB,CAAa,CAGjB,CAAK,EAE9B,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,SACEkgB,aAAyBthB,IACxB,OAAOshB,GAAkB,UACxBA,IAAkB,MAClB,SAAUA,EACZ,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAOkgB,EAAsB,IAAA,CAAK,EAE3D,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,SACE,OAAOkgB,GAAkB,UACzBA,IAAkB,MAClB,SAAUA,EACV,CACA,MAAMlgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CAAE,KAAM,OAAQ,KAAMkgB,CAAA,CAA0B,EAEzD,KAAK,kBAAkBlgB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,MACK,CACL,MAAMlqB,EAASspC,GAAkBc,CAAa,EACxClgB,EAAsB,CAC1B,KAAM,MACN,MAAO,CACL,KAAM,MACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,GAAAqU,EACA,MAAAuT,CAAA,CACF,EAEF,KAAK,kBAAkBsC,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,CAC1C,CACA,OAAO,IACT,CAEA,UAAUhB,EAAsB,CAC9B,OAAO,KAAK,OAAOA,CAAM,CAC3B,CAEA,YAAYA,EAAsB,CAChC,OAAO,KAAK,SAASA,CAAM,CAC7B,CAEA,WAAW4gB,EAAwD,CACjE,MAAM9pC,EAASspC,GAAkBQ,CAAS,EACpC5f,EAAsB,CAC1B,KAAM,OACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQ,EAAA,EAEV,YAAK,cAAc,KAAKkqB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,EACjC,IACT,CAEA,cAAc4f,EAAwD,CACpE,MAAM9pC,EAASspC,GAAkBQ,CAAS,EACpC5f,EAAsB,CAC1B,KAAM,OACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQ,EAAA,EAEV,YAAK,cAAc,KAAKkqB,CAAM,EAC9B,KAAK,6BAA6BA,CAAM,EACjC,IACT,CAEA,aAAa4f,EAAwD,CACnE,MAAM9pC,EAASspC,GAAkBQ,CAAS,EACpC5f,EAAsB,CAC1B,KAAM,OACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQ,EAAA,EAEV,YAAK,kBAAkBkqB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,EACjC,IACT,CAEA,gBAAgB4f,EAAwD,CACtE,MAAM9pC,EAASspC,GAAkBQ,CAAS,EACpC5f,EAAsB,CAC1B,KAAM,OACN,QAASlqB,EAAO,QAChB,KAAMA,EAAO,KACb,OAAQ,EAAA,EAEV,YAAK,kBAAkBkqB,CAAM,EAC7B,KAAK,6BAA6BA,CAAM,EACjC,IACT,CAEA,kBAAkC,CAChC,OAAO,KAAK,aACd,CAEA,qBAA0C,CACxC,OAAI,KAAK,cAAc,SAAW,EAAU,KACxC,KAAK,cAAc,SAAW,EAAU,KAAK,cAAc,CAAC,EACzD,CAAE,KAAM,MAAO,SAAU,CAAC,GAAG,KAAK,aAAa,CAAA,CACxD,CAEQ,kBAAkBA,EAA2B,CACnD,GAAI,KAAK,cAAc,SAAW,EAAG,CACnC,KAAK,cAAc,KAAKA,CAAM,EAC9B,MACF,CACA,GACE,KAAK,cAAc,SAAW,GAC9B,KAAK,cAAc,CAAC,EAAE,OAAS,MAC/B,KAAK,cAAc,CAAC,EAAE,SACtB,CACA,KAAK,cAAc,CAAC,EAAE,SAAS,KAAKA,CAAM,EAC1C,MACF,CACA,IAAIugB,EACA,KAAK,cAAc,SAAW,EAChCA,EAAO,KAAK,cAAc,CAAC,EAE3BA,EAAO,CAAE,KAAM,MAAO,SAAU,CAAC,GAAG,KAAK,aAAa,CAAA,EAExD,KAAK,cAAgB,CAAC,CAAE,KAAM,KAAM,SAAU,CAACA,EAAMvgB,CAAM,EAAG,CAChE,CAEA,UAAUgX,EAA6B,CACrC,YAAK,SAAS,KAAK,GAAGA,CAAU,EACzB,IACT,CAEA,MAAMvY,EAAkBE,EAAsB,CAC5C,YAAK,SAAS,KAAK,CAAE,KAAM,QAAS,QAAAF,EAAS,MAAAE,EAAO,EAC7C,IACT,CAEA,IAAIF,EAAiBE,EAAsB,CACzC,YAAK,SAAS,KAAK,CAAE,KAAM,MAAO,QAAAF,EAAS,MAAAE,EAAO,EAC3C,IACT,CAEA,IAAIF,EAAiBE,EAAsB,CACzC,YAAK,SAAS,KAAK,CAAE,KAAM,MAAO,QAAAF,EAAS,MAAAE,EAAO,EAC3C,IACT,CAEA,IAAIF,EAAiBE,EAAsB,CACzC,YAAK,SAAS,KAAK,CAAE,KAAM,MAAO,QAAAF,EAAS,MAAAE,EAAO,EAC3C,IACT,CAEA,IAAIF,EAAiBE,EAAsB,CACzC,YAAK,SAAS,KAAK,CAAE,KAAM,MAAO,QAAAF,EAAS,MAAAE,EAAO,EAC3C,IACT,CAKA,OACEsH,KACG0a,EACG,CACN,GAAI1a,IAAU,OAAW,OAAO,KAEhC,MAAMwZ,EAAkC,CAAA,EACxCA,EAAO,KAAK,GAAGD,GAAoBvZ,CAAK,CAAC,EACzC,UAAW2a,KAAKD,EACdlB,EAAO,KAAK,GAAGD,GAAoBoB,CAAC,CAAC,EAEvC,KAAK,aAAa,KAAK,GAAGnB,CAAM,EAGhC,UAAW1xC,KAAK0xC,EACd,GAAI1xC,EAAE,MAAQA,EAAE,KAAK,OAAS,KAAM,CAClC,MAAM+kC,EAAS/kC,EAAE,KAAK,KAAK,YAAA,EAC3B,GAAI4uB,GAAoBmW,CAAM,GAExB,CADY,KAAK,SAAS,KAAM,GAAM,EAAE,QAAU/kC,EAAE,KAAK,EAC/C,CACZ,MAAM0xB,EAAO1xB,EAAE,KAAK,KAAK,CAAC,EACpB0wB,EACJgB,GAAQA,EAAK,OAAS,OAASA,EAAK,OAAS,IACzCA,EAAK,KACL,OACN,KAAK,SAAS,KAAK,CACjB,KAAMqT,EACN,QAAArU,EACA,MAAO1wB,EAAE,KAAA,CACV,CACH,CAEJ,SAAW,OAAOA,EAAE,IAAO,SAAU,CACnC,MAAM+kC,EAAS/kC,EAAE,GAAG,YAAA,EAChB4uB,GAAoBmW,CAAM,IACZ,KAAK,SAAS,KAAM,GAAM,EAAE,QAAU/kC,EAAE,KAAK,GAE3D,KAAK,SAAS,KAAK,CACjB,KAAM+kC,EACN,QAAS/kC,EAAE,YAAc,IAAM,OAAYA,EAAE,UAC7C,MAAOA,EAAE,KAAA,CACV,EAGP,CAGF,OAAO,IACT,CAEA,iBAA2C,CACzC,OAAO,KAAK,YACd,CAcQ,WAAW+O,EAAmB,CAGpC,MAAMuL,EAAO,OAAO,KAAKvL,CAAG,EAC5B,GACE,KAAK,aAAa,OAAS,GAC3BuL,EAAK,SAAW,KAAK,aAAa,QAClC,KAAK,aAAa,MAAOta,GAAMA,EAAE,SAAS+O,CAAG,EAE7C,OAAOA,EAGT,MAAM+jC,EAAmB,CAAA,EACzB,UAAWC,KAAS,KAAK,aAAc,CACrC,MAAMC,EAAcD,EAAM,MAC1B,GAAIhkC,EAAIikC,CAAW,IAAM,OACvBF,EAAUE,CAAW,EAAIjkC,EAAIikC,CAAW,UAExCD,EAAM,MACNhkC,EAAI0hB,GAAmBsiB,EAAM,IAAI,CAAC,IAAM,OAExCD,EAAUE,CAAW,EAAIjkC,EAAI0hB,GAAmBsiB,EAAM,IAAI,CAAC,UAE3DA,EAAM,YAAc,QACpBhkC,EAAIgkC,EAAM,SAAS,IAAM,OAEzBD,EAAUE,CAAW,EAAIjkC,EAAIgkC,EAAM,SAAS,UACnCA,EAAM,KAAM,CACrB,IAAIxhB,EACA,OAAQ,KAAK,GAAW,QAAW,aACrCA,EAAQpN,GAAA,SAAkB,OAAAlJ,GAAA7Z,EAAA,KAAK,GAAW,OAAO+iB,CAAI,IAA3B,YAAA/iB,EAA8B,MAA9B,YAAA6Z,EAAmC,OAE/D63B,EAAUE,CAAW,EAAI1hB,GAAayhB,EAAM,KAAMhkC,EAAKwiB,CAAI,CAC7D,MACEuhB,EAAUE,CAAW,EAAI,IAE7B,CACA,OAAOF,CACT,CAEA,MAAM,SAAkC,CACtC,MAAM7c,EAAkC,KAAK,aAAa,IAAKj2B,IAAO,CACpE,KAAMA,EAAE,MAAQ,CAAE,KAAM,MAAO,KAAMA,EAAE,WAAaA,EAAE,KAAA,EACtD,MAAOA,EAAE,KAAA,EACT,EAEF,OAAO,KAAK,GAAG,aAAa,KAAK,UAAW,KAAK,QAAS,CACxD,MAAO,KAAK,MAAM,OAAS,EAAI,KAAK,MAAQ,OAC5C,QAAS,KAAK,UAAU,OAAS,EAAI,KAAK,UAAY,OACtD,QACE,KAAK,UAAU,OAAS,EACpB,KAAK,UACL,KAAK,UAAU,OAAS,EACtB,KAAK,UACL,OACR,WAAY,KAAK,SAAS,OAAS,EAAI,KAAK,SAAW,OACvD,OAAQ,KAAK,cAAc,OAAS,EAAI,KAAK,cAAgB,OAC7D,OAAQ,KAAK,aAAa,OAAS,EAAI,KAAK,aAAe,OAC3D,YAAai2B,EAAY,OAAS,EAAIA,EAAc,OACpD,MAAO,KAAK,aAAe,KAAO,KAAK,WAAa,OACpD,OAAQ,KAAK,cAAgB,KAAO,KAAK,YAAc,OACvD,QAAS,KAAK,OAAA,CACf,CACH,CAEQ,iBAAiBlnB,EAAYvP,EAAiB,CACpD,MAAMyzC,EACJzzC,EAAE,UAAYA,EAAE,KAAOixB,GAAmBjxB,EAAE,IAAI,EAAI,QACtD,GAAI,CAACyzC,EAAQ,OAEb,GAAIlkC,EAAIkkC,CAAM,IAAM,OAAW,OAAOlkC,EAAIkkC,CAAM,EAEhD,MAAMzY,EAAWyY,EAAO,SAAS,GAAG,EAChCA,EAAO,MAAMA,EAAO,YAAY,GAAG,EAAI,CAAC,EACxCA,EACJ,GAAIlkC,EAAIyrB,CAAQ,IAAM,OAAW,OAAOzrB,EAAIyrB,CAAQ,EAEpD,GAAI,KAAK,aAAa,OAAS,GAC7B,UAAWx6B,KAAK,KAAK,aACnB,IACEA,EAAE,YAAcizC,GAChBjzC,EAAE,YAAcw6B,GAChBx6B,EAAE,QAAUizC,GACZjzC,EAAE,QAAUw6B,IAERzrB,EAAI/O,EAAE,KAAK,IAAM,OAAW,OAAO+O,EAAI/O,EAAE,KAAK,EAKxD,GAAI+O,EAAI,UAAUkkC,CAAM,EAAE,IAAM,OAAW,OAAOlkC,EAAI,UAAUkkC,CAAM,EAAE,EACxE,GAAIlkC,EAAI,UAAUyrB,CAAQ,EAAE,IAAM,OAAW,OAAOzrB,EAAI,UAAUyrB,CAAQ,EAAE,CAG9E,CAEQ,mBAAmB0Y,EAAwB,CACjD,MAAO,CAAC,GAAGA,CAAI,EAAE,KAAK,CAACz7B,EAAGnP,IAAM,CAC9B,UAAW9I,KAAK,KAAK,UAAW,CAC9B,MAAM2zC,EAAO,KAAK,iBAAiB17B,EAAGjY,CAAC,EACjC4zC,EAAO,KAAK,iBAAiB9qC,EAAG9I,CAAC,EACvC,GAAI2zC,IAASC,EAAM,SACnB,GAAID,GAAS,KACX,OAAO3zC,EAAE,YAAc,cAAgB,GAAK,EAE9C,GAAI4zC,GAAS,KACX,OAAO5zC,EAAE,YAAc,cAAgB,EAAI,GAE7C,MAAM2gB,EAAM3gB,EAAE,YAAc,OAAS,GAAK,EAC1C,OAAI,OAAO2zC,GAAS,UAAY,OAAOC,GAAS,UACtCD,EAAOC,GAAQjzB,EAElB,OAAOgzB,CAAI,EAAE,cAAc,OAAOC,CAAI,CAAC,EAAIjzB,CACpD,CACA,MAAO,EACT,CAAC,CACH,CAEA,MAAM,SAA4B,CAChC,MAAM8V,EAAkC,KAAK,aAAa,IAAKj2B,IAAO,CACpE,KAAMA,EAAE,MAAQ,CAAE,KAAM,MAAO,KAAMA,EAAE,WAAaA,EAAE,KAAA,EACtD,MAAOA,EAAE,KAAA,EACT,EAEIqzC,EAAW,KAAK,MAAM,OAAS,EAC/BlgB,EAAa,KAAK,UAAU,OAAS,EACrCmgB,EACJ,KAAK,SAAS,OAAS,GACvB,KAAK,UAAU,OAAS,GACxB,KAAK,UAAU,OAAS,EAE1B,GAAID,GAAYlgB,GAAc8C,EAAY,OAAS,EACjD,UAAWz2B,KAAK,KAAK,UAAW,CAC9B,MAAMmO,EAAMnO,EAAE,QACd,GAAImO,EAAK,CACP,MAAM4lC,EAAQ5lC,EAAI,SAAS,GAAG,EAC1BA,EAAI,MAAMA,EAAI,YAAY,GAAG,EAAI,CAAC,EAClCA,EACU,KAAK,aAAa,KAC7B,GACC,EAAE,QAAUA,GACZ,EAAE,QAAU4lC,GACZ,EAAE,YAAc5lC,GAChB,EAAE,YAAc4lC,CAAA,GAGlBtd,EAAY,KAAK,CACf,KAAM,CAAE,KAAM,MAAO,KAAMtoB,CAAA,EAC3B,MAAO,UAAUA,CAAG,EAAA,CACrB,CAEL,CACF,CAGF,MAAM6lC,EAAU,MAAM,KAAK,GAAG,aAAa,KAAK,UAAW,KAAK,QAAS,CACvE,MACEH,GAAYlgB,GAAcmgB,EAAoB,KAAO,KAAK,WAC5D,OACED,GAAYlgB,GAAcmgB,EAAoB,KAAO,KAAK,YAC5D,QAASD,EAAW,KAAO,KAAK,QAChC,QAAS,KAAK,QACd,QACEA,GAAYC,EACR,OACAngB,EACE,KAAK,UACL,OACR,MAAOkgB,EAAW,KAAK,MAAQ,OAC/B,QACE,KAAK,UAAU,OAAS,EACpB,KAAK,UACL,KAAK,UAAU,OAAS,EACtB,KAAK,UACL,OACR,WAAY,KAAK,SAAS,OAAS,EAAI,KAAK,SAAW,OACvD,OAAQ,KAAK,cAAc,OAAS,EAAI,KAAK,cAAgB,OAC7D,OAAQ,KAAK,aAAa,OAAS,EAAI,KAAK,aAAe,OAC3D,YAAapd,EAAY,OAAS,EAAIA,EAAc,OACpD,QAAS,KAAK,OAAA,CACf,EAED,IAAIid,EAAOM,EACX,MAAMC,EAAoBD,EAAgB,mBAAqB,GAC/D,OAAKF,GAAqBD,IAAalgB,GAAc,CAACsgB,IACpDP,EAAO,KAAK,mBAAmBA,CAAI,EAC/BG,IACE,KAAK,cAAgB,MAAQ,KAAK,YAAc,IAClDH,EAAOA,EAAK,MAAM,KAAK,WAAW,GAEhC,KAAK,aAAe,MAAQ,KAAK,YAAc,IACjDA,EAAOA,EAAK,MAAM,EAAG,KAAK,UAAU,KAKtC,KAAK,aAAa,OAAS,IAC7BA,EAAOA,EAAK,IAAKL,GAAM,KAAK,WAAWA,CAAC,CAAC,GAGpCK,CACT,CAEA,MAAM,OAA+B,CACnC,MAAMA,EAAO,MAAM,KAAK,MAAM,CAAC,EAAE,QAAA,EACjC,OAAOA,EAAK,OAAS,EAAIA,EAAK,CAAC,EAAI,IACrC,CAEA,MAAM,OACJzP,EACAr+B,EACiB,CACjB,GAAI,CAAC,KAAK,GAAG,cACX,MAAM,IAAI,MAAM,kDAAkD,EAEpE,OAAO,KAAK,GAAG,cAAc,KAAK,UAAW,KAAK,QAASq+B,EAAOr+B,CAAO,CAC3E,CAEA,MAAM,OAAOA,EAA+C,CAC1D,GAAI,CAAC,KAAK,GAAG,cACX,MAAM,IAAI,MAAM,kDAAkD,EAEpE,OAAO,KAAK,GAAG,cAAc,KAAK,UAAW,KAAK,QAASA,CAAO,CACpE,CACF,CCrkDO,MAAMsuC,EAAwC,CAyC3C,YACNpoB,EACA2B,EACA0mB,EACAtuC,EACAuuC,EAA0B,KAC1BC,EACA1T,EACAhgC,EACA,CAjDOnB,EAAA,YACAA,EAAA,WACAA,EAAA,eACAA,EAAA,iBACAA,EAAA,iBACDA,EAAA,gBASCA,EAAA,oBACTA,EAAA,sBAAgC,MACxBA,EAAA,cACAA,EAAA,gBAA4D,KAC5DA,EAAA,iBAAY,GACZA,EAAA,0BAA6C,KAC7CA,EAAA,0BAA0C,KAC1CA,EAAA,0BAA0C,KAG1CA,EAAA,6BAA+C,KAC/CA,EAAA,uBAAmC,KACnCA,EAAA,yBAGC,KACDA,EAAA,uBAAoC,CAAA,GACpCA,EAAA,sBAAyB,SACzBA,EAAA,qBACAA,EAAA,kBAAqB,GACrBA,EAAA,oBAAuB,KACvBA,EAAA,6BAAiC,IACjCA,EAAA,wBAA4C,MACnCA,EAAA,kBACf,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC,EAAI,KAAK,IAAA,EAAM,SAAS,EAAE,GAwC5D,GA5BA,KAAK,IAAMssB,EACX,KAAK,GAAK2B,EACV,KAAK,OAAS0mB,EACd,KAAK,YAActuC,EACnB,KAAK,SAAWuuC,EAChB,KAAK,SAAWC,EAChB,KAAK,QAAU1T,EACf,KAAK,MAAQjlC,GAAA,EAEb,KAAK,YAAY,yBAAyB,SAAY,CACpD,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EAEpB,MAAM44C,EAAmBjvB,GACvB,KAAK,OAAO,gBAAgB,CAAC,CAAA,EAE/B,UAAWL,KAAQsvB,EAAkB,CACnC,IAAIC,EAAYvvB,EAAK,iBACrB,KAAOuvB,IAAc,GAAG,CACtB,MAAMx8B,EAAO,MAAM,KAAK,OAAO,kBAAkBw8B,CAAS,EACpDnwC,EAAO,KAAK,OAAO,gBAAgB2T,CAAI,EAE7Cw8B,EADenuB,GAAyBhiB,EAAM,CAAC,EAC5B,oBACrB,CACF,CACF,CAAC,EAEG,OAAO,iBAAqB,KAAezD,EAAQ,CACrD,MAAM6zC,EAAc,cAAc1oB,EAAI,IAAI,IAAInrB,CAAM,GACpD,KAAK,iBAAmB,IAAI,iBAAiB6zC,CAAW,EACxD,KAAK,iBAAiB,UAAaC,GAAqB,CACtD,MAAM/0C,EAAO+0C,EAAG,KAChB,GAAI,CAAC/0C,GAAQA,EAAK,WAAa,KAAK,WAAY,OAChD,KAAM,CAAE,OAAA1D,EAAQ,OAAA04C,EAAQ,KAAAjuB,EAAM,cAAAkuB,EAAe,cAAAC,GAAkBl1C,EAC/D,KAAK,YAAY,WACd,QAAQ,SAAY,CACnB,MAAM,KAAK,YAAY,kBAAkB,EAAI,EAC7C,KAAK,oBAAoB,CACvB,OAAQ,MAAM,QAAQ1D,CAAM,EAAIA,EAAS,CAAA,EACzC,OAAQ04C,GAAU,SAClB,KAAAjuB,EACA,cACE,OAAOkuB,GAAkB,SACrBA,EACA,KAAK,eAAe,cAC1B,cACE,OAAOC,GAAkB,SACrBA,EACA,KAAK,eAAe,cAC1B,SAAU,EAAA,CACX,CACH,CAAC,EACA,MAAM,IAAM,CAAC,CAAC,CACnB,CACF,CACF,CAhGA,IAAI,MAAyB,CAC3B,OAAO,KAAK,MACd,CAgGA,aAAa,KAAKhvC,EAAuC,CACvD,MAAMivC,EAAcjvC,EAAQ,SAAW,SACvC,IAAIkmB,EACAlmB,EAAQ,IACVkmB,EAAMlmB,EAAQ,IACLivC,IAAgB,MACzB/oB,EAAM,IAAIprB,GAAoBkF,EAAQ,IAAI,EACjCivC,IAAgB,OACzB/oB,EAAM,IAAInqB,GAAeiE,EAAQ,IAAI,EAErCkmB,EAAM,IAAIvsB,GAGZ,MAAMzH,EAAY8N,EAAQ,WAAarP,GACjC6zB,EAAiBxkB,EAAQ,gBAAkB3O,GAC3C8xB,EAASoB,GACb,KAAK,IAAIryB,EAAWvB,EAAkB,EACtC6zB,CAAA,EAEIqD,EAAK,IAAI9nB,GAAG,CAAE,IAAAmmB,EAAK,OAAA/C,EAAQ,EAC3BorB,EAAS,IAAI1pB,GAAiB,CAClC,GAAAgD,EACA,OAAA1E,EACA,UAAAjxB,EACA,eAAAsyB,EACA,wBAAyB,EAAA,CAC1B,EAEKyC,EACJjnB,EAAQ,MAAQkmB,EAAI,OAAS,SACzB,cAAcA,EAAI,IAAI,IAAIlmB,EAAQ,IAAI,GACtC,OAEAC,EAAc,IAAI0nB,GACtBzB,EACAqoB,EACA1mB,EACAZ,CAAA,EAGFsnB,EAAO,0BAA0BtuC,CAAW,EAE5C,MAAMA,EAAY,WAAW,QAAQ,SAAY,CAE/C,MAAMgmB,GAAeC,CAAG,EAGxB,MAAMgpB,EAAY,MAAMhpB,EAAI,SAAS,CAAC,EACtC,GAAI,CAACgpB,EAEH/xB,GAAmBoxB,EAAO,gBAAgB,CAAC,CAAC,EAC5CA,EAAO,UAAU,CAAC,EAClB,MAAMA,EAAO,UAAU,CAAC,MACnB,CAELA,EAAO,mBAAmB,CAAC,EAAE,IAAIW,CAAS,EAC1CX,EAAO,WAAW,CAAC,EAEnBnxB,GAA0BmxB,EAAO,gBAAgB,CAAC,EAAG,EAAI,EAGzD,MAAMG,EAAmBjvB,GACvB8uB,EAAO,gBAAgB,CAAC,CAAA,EAE1B,UAAWnvB,KAAQsvB,EAAkB,CACnC,IAAIC,EAAYvvB,EAAK,iBACrB,KAAOuvB,IAAc,GAAG,CACtB,MAAMx8B,EAAO,MAAMo8B,EAAO,kBAAkBI,CAAS,EAC/CnwC,EAAO+vC,EAAO,gBAAgBp8B,CAAI,EAExCw8B,EADenuB,GAAyBhiB,EAAM,CAAC,EAC5B,oBACrB,CACF,CACF,CACAyB,EAAY,qBAAA,CACd,CAAC,EAED,MAAMuuC,EAAWxuC,EAAQ,MAAQ,KACjC,IAAIyuC,EACAD,IAAa,SACfC,EAAWvrB,GACTC,EACAnjB,EAAQ,WAAa,IAAI,WAAWA,EAAQ,UAAU,EAAI,MAAA,GAI9D,MAAMmvC,EAAa,IAAIb,GACrBpoB,EACA2B,EACA0mB,EACAtuC,EACAuuC,EACAC,EACAzuC,EAAQ,QACRA,EAAQ,IAAA,EAGV,OAAIA,EAAQ,aACV,MAAMmvC,EAAW,aAAanvC,EAAQ,WAAW,EAG5CmvC,CACT,CAEA,YAAuC,CACrC,OAAO,KAAK,OACd,CAEA,WAAWpU,EAA8B,CACvC,YAAK,QAAUA,EACR,IACT,CAEQ,mBAAmB5jC,EAAoBi4C,EAAgB,aAAoB,CACjF,GAAI,CAACj4C,GAAc,OAAOA,GAAe,UAAYA,EAAW,SAAW,EACzE,MAAM,IAAI,MAAM,GAAGi4C,CAAK,kBAAkB,EAE5C,GAAIj4C,EAAW,OAAS1K,GACtB,MAAM,IAAIyK,GAAuBC,EAAY1K,EAAe,CAEhE,CAEA,MAAM,YACJsyB,EACAhX,EACoB,CACpB,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,qBAAqBgX,EAAMhX,CAAO,EAC7C,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,qBACZgX,EACAhX,EACoB,OAEpB,GADA,KAAK,mBAAmBgX,EAAM,YAAY,EACtChX,EAAQ,SAAW,EACrB,MAAM,IAAI,MAAM,qCAAqC,EAEvD,GAAIA,EAAQ,OAAS5Z,GACnB,MAAM,IAAI+J,GAAoB6P,EAAQ,OAAQ5Z,EAAqB,EAGrE,MAAMkhD,MAAmB,IACzB,IAAIC,EAAQ,GACZ,UAAW/mC,KAAOR,EAAS,CAEzB,GADA,KAAK,mBAAmBQ,EAAI,KAAM,aAAa,EAC3C8mC,EAAa,IAAI9mC,EAAI,IAAI,EAC3B,MAAM,IAAInR,GAAyBmR,EAAI,KAAMwW,CAAI,EAEnDswB,EAAa,IAAI9mC,EAAI,IAAI,EACzB,MAAMgnC,EAAW,OAAQhnC,EAAY,OAAU,SAAYA,EAAY,MAAQ,GAE7EA,EAAI,aACJvM,EAAAuM,EAAI,QAAJ,MAAAvM,EAAW,YACVuzC,EAAW/4C,EAAW,eAEvB84C,EAAQ,GAEZ,CAEA,MAAME,EAAY,KAAK,KAAK,gBAAgB,CAAC,EAC7C,GAAIjwB,GAAwBiwB,EAAWzwB,CAAI,IAAM,GAC/C,MAAM,IAAItnB,GAAwBsnB,CAAI,EAExC,GAAIS,GAA6BgwB,CAAS,IAAM,GAC9C,MAAM,IAAIp3C,GAAmB1K,GAAkBA,EAAgB,EAGjE,MAAM+hD,EAAc,KAAK,KAAK1nC,EAAQ,OAAS7Z,EAA4B,EACrEwhD,EACJJ,GAASvvB,GAA6ByvB,CAAS,IAAM,GAAK,EAAI,EAC1DG,EAAuB,EAAIF,EAAcC,EAEzCE,EAA8B,CAAA,EACpC,QAASv5C,EAAI,EAAGA,EAAIs5C,EAAsBt5C,IACxCu5C,EAAkB,KAAK,MAAM,KAAK,OAAO,oBAAoB,EAG/D,IAAIC,EAAc,EAElB,MAAM3uB,EAAuB,CAC3B,gBAAiB,IAAM,CACrB,GAAI2uB,EAAcD,EAAkB,OAClC,OAAOA,EAAkBC,GAAa,EAGxC,MAAMC,EADeN,EAAU,UAAU,GAAI,EAAI,EAChB,EACjC,OAAAA,EAAU,UAAU,GAAIM,EAAW,EAAI,EACvC,KAAK,KAAK,UAAU,CAAC,EACdA,CACT,EACA,aAAe/3C,GAAmB,CAChC,IAAIoa,EAAO,KAAK,KAAK,gBAAgBpa,CAAM,EAC3C,OAAIoa,IAAS,KACXA,EAAOpa,GAAU,KAAK,KAAK,UAAYA,EAAS,EAAI,EACpD,KAAK,KAAK,WAAWoa,EAAMpa,CAAM,GAE5B,KAAK,KAAK,mBAAmBoa,CAAI,CAC1C,EACA,cAAgBpa,GAAmB,CACjC,MAAMoa,EAAO,KAAK,KAAK,gBAAgBpa,CAAM,EACzCoa,IAAS,IACX,KAAK,KAAK,UAAUA,CAAI,CAE5B,CAAA,EAGF,IAAIhc,EACJ,GAAI,CACFA,EAAQ6qB,GAAqBwuB,EAAWtuB,EAAOnC,EAAMhX,CAAO,CAC9D,OAASud,EAAK,CACZ,UAAWyqB,KAAOH,EAChB,KAAK,OAAO,eAAeG,CAAG,EAC9B,MAAM,KAAK,OAAO,SAASA,EAAK,EAAI,EAEtC,MAAMzqB,CACR,CAGA,KAAK,OAAO,UAAUnvB,EAAM,UAAU,EACtC,UAAWsG,KAAOtG,EAAM,SAAW,CAAA,EAC7BsG,EAAI,WAAa,GACnB,KAAK,OAAO,UAAUA,EAAI,UAAU,EAKxC,IAAIkyC,EAAYx4C,EAAM,iBACtB,KAAOw4C,IAAc,GAAG,CACtB,MAAMx8B,EAAO,MAAM,KAAK,OAAO,YAAYw8B,CAAS,EAC/C,KAAK,KAAK,aAAax8B,CAAI,GAC9B,KAAK,KAAK,QAAQA,CAAI,EAMxBw8B,EAJenuB,GACb,KAAK,KAAK,gBAAgBrO,CAAI,EAC9B,CAAA,EAEiB,oBACrB,CAGA,OAAK,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAEpB,KAAK,eAAe,OAAO4M,EAAK,YAAA,CAAa,EACtC5oB,CACT,CAEA,MAAM,SAASc,EAAuC,CACpD,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,kBAAkBA,CAAS,EACtC,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,kBAAkBA,EAAuC,CACrE,MAAMiD,EAAMjD,EAAU,YAAA,EAChB+4C,EAAS,KAAK,eAAe,IAAI91C,CAAG,EAC1C,GAAI81C,EACF,OAAOA,EAGT,MAAMR,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvC,EAAUqf,GAAwBiwB,EAAWv4C,CAAS,EAE5D,GAAIiJ,IAAY,GACd,MAAM,IAAI1I,GAAmBP,CAAS,EAIxC,IAAI03C,EADShwB,GAA8B6wB,EAAWtvC,CAAO,EACxC,iBAErB,KAAOyuC,IAAc,GAAG,CACtB,MAAM,KAAK,OAAO,YAAYA,CAAS,EACvC,MAAMx8B,EAAO,KAAK,KAAK,gBAAgBw8B,CAAS,EAKhDA,EAJenuB,GACb,KAAK,KAAK,gBAAgBrO,CAAI,EAC9B,CAAA,EAEiB,oBACrB,CASA,MAAM0O,EAAO2B,GAAwBgtB,EAPvB,CACZ,aAAez3C,GAAmB,CAChC,MAAMoa,EAAO,KAAK,KAAK,gBAAgBpa,CAAM,EAC7C,OAAIoa,IAAS,GAAW,KAAK,KAAK,mBAAmBA,CAAI,EAClD,IAAI,WAAW,IAAS,CACjC,CAAA,EAEqDlb,CAAS,EAChE,YAAK,eAAe,IAAIiD,EAAK2mB,CAAI,EAC1BA,CACT,CAEA,MAAM,YAAmC,CACvC,OAAO,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAM2uB,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvC5sB,EAAcnD,GAA+B+vB,CAAS,EACtDp5C,EAAsB,CAAA,EAE5B,UAAWgpB,KAAQwD,EACjBxsB,EAAO,KAAK,MAAM,KAAK,kBAAkBgpB,EAAK,IAAI,CAAC,EAGrD,OAAOhpB,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAc,mBAAmB65C,EAAmC,CAClE,GAAIA,GAAc,EAAG,OAErB,MAAMC,EAAmB,CAAA,EACnBC,MAAc,IACdC,EAAQ,CAACH,CAAU,EAEzB,KAAOG,EAAM,OAAS,GAAG,CACvB,MAAML,EAAMK,EAAM,MAAA,EAClB,GAAIL,GAAO,GAAKI,EAAQ,IAAIJ,CAAG,EAAG,SAClCI,EAAQ,IAAIJ,CAAG,EAEf,MAAM59B,EAAO,MAAM,KAAK,OAAO,YAAY49B,CAAG,EACxCvxC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrCk+B,EAAQlsC,GAAc3F,EAAM,CAAC,EAGnC,GAAI6xC,IAAUt7C,GAAgB,CAC5B,KAAK,OAAO,eAAeg7C,CAAG,EAC9B,QACF,CAIA,GAFAG,EAAO,KAAKH,CAAG,EAGbM,IAAUp7C,IACVo7C,IAAUr7C,GACV,CACA,MAAMs7C,EAAYhsC,GAAoB9F,EAAM,CAAC,EAC7C,QAASnI,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClC,MAAMk6C,EAAMtrC,GAAqBzG,EAAM,EAAGnI,CAAC,EAC3C,GAAIk6C,EAAM,GAAKA,EAAM,GAAK,KAAW,CACnC,MAAMC,EAAUhyC,EAAK,UAAU+xC,EAAK,EAAI,EACpCC,EAAU,GAAK,CAACL,EAAQ,IAAIK,CAAO,GACrCJ,EAAM,KAAKI,CAAO,CAEtB,CACF,CACA,MAAMC,EAAe/rC,GAAsBlG,EAAM,CAAC,EAC9CiyC,EAAe,GAAK,CAACN,EAAQ,IAAIM,CAAY,GAC/CL,EAAM,KAAKK,CAAY,CAE3B,SACEJ,IAAUj7C,IACVi7C,IAAUn7C,GACV,CACA,MAAMw7C,EAAShsC,GAAsBlG,EAAM,CAAC,EACxCkyC,EAAS,GAAK,CAACP,EAAQ,IAAIO,CAAM,GACnCN,EAAM,KAAKM,CAAM,CAErB,CACF,CAEA,UAAWX,KAAOG,EAChB,KAAK,OAAO,eAAeH,CAAG,EAC9B,MAAM,KAAK,OAAO,SAASA,EAAK,EAAI,CAExC,CAEA,MAAM,UAAU94C,EAAkC,CAChD,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,mBAAmBA,CAAS,EACvC,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,mBAAmBA,EAAkC,OACjE,KAAK,eAAe,OAAOA,EAAU,YAAA,CAAa,EAClD,KAAK,eAAe,OAAOA,CAAS,EAEpC,MAAMu4C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvC,EAAUqf,GAAwBiwB,EAAWv4C,CAAS,EAC5D,GAAIiJ,IAAY,GACd,MAAM,IAAI1I,GAAmBP,CAAS,EAGxC,MAAMmoB,EAAOT,GAA8B6wB,EAAWtvC,CAAO,EAG7D,QAASiS,EAAO,EAAGA,EAAOxkB,GAAmBwkB,IAAQ,CACnD,MAAM1V,EAAMijB,GAA8B8vB,EAAWr9B,CAAI,EAEvD1V,IACCA,EAAI,UAAY2iB,EAAK,SACpB3iB,EAAI,KACD,YAAA,EACA,WAAW,OAAOxF,EAAU,aAAa,GAAG,GAC/CwF,EAAI,KAAK,gBAAkB,MAAMxF,EAAU,YAAA,CAAa,MAEtDwF,EAAI,WAAa,IACnB,MAAM,KAAK,mBAAmBA,EAAI,UAAU,EAC5C,KAAK,eAAe,OAAOA,EAAI,UAAU,GAE3C0jB,GAAgCqvB,EAAWr9B,CAAI,EAEnD,CAGIiN,EAAK,WAAa,GACpB,MAAM,KAAK,mBAAmBA,EAAK,UAAU,EAI/C,IAAIuxB,EAAevxB,EAAK,iBACxB,KAAOuxB,EAAe,GAAG,CACvB,MAAMx+B,EAAO,MAAM,KAAK,OAAO,YAAYw+B,CAAY,EACjDnyC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAE3C,GADchO,GAAc3F,EAAM,CAAC,IACrBzJ,GAAgB,CAC5B,KAAK,OAAO,eAAe47C,CAAY,EACvC,KACF,CAEA,MAAMD,EADSlwB,GAAyBhiB,EAAM,CAAC,EACzB,qBACtB,KAAK,OAAO,eAAemyC,CAAY,EACvC,MAAM,KAAK,OAAO,SAASA,EAAc,EAAI,EAC7CA,EAAeD,CACjB,CAGAtwB,GAAgCovB,EAAWtvC,CAAO,EAClDge,GAAiCsxB,CAAS,EAC1CpxB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAChB,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,IAGhBxzC,EAAA,KAAK,MAAM,QAAX,YAAAA,EAAkB,KAAK,iBAAkB/E,EAAU,gBACrD,KAAK,MAAM,MAAQ,KAEvB,CAEA,MAAM,YAAY25C,EAAiBC,EAAqC,CACtE,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,qBAAqBD,EAASC,CAAO,EAChD,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,qBACZD,EACAC,EACoB,OACpB,KAAK,mBAAmBA,EAAS,YAAY,EAC7C,MAAMrB,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvC,EAAUqf,GAAwBiwB,EAAWoB,CAAO,EAC1D,GAAI1wC,IAAY,GACd,MAAM,IAAI1I,GAAmBo5C,CAAO,EAGtC,GAAIA,IAAYC,EACd,OAAO,KAAK,kBAAkBA,CAAO,EAGvC,GAAItxB,GAAwBiwB,EAAWqB,CAAO,IAAM,GAClD,MAAM,IAAIp5C,GAAwBo5C,CAAO,EAG3C,MAAMzxB,EAAOT,GAA8B6wB,EAAWtvC,CAAO,EAC7Dkf,EAAK,KAAOyxB,EACZ1xB,GAA+BqwB,EAAWtvC,EAASkf,CAAI,EAGvD,MAAM0xB,EAAY,MAAMF,CAAO,GACzBG,EAAe,OAAOH,CAAO,IACnC,QAASv6C,EAAI,EAAGA,EAAI1I,GAAmB0I,IAAK,CAC1C,MAAMoG,EAAMijB,GAA8B8vB,EAAWn5C,CAAC,EACtD,GAAIoG,GAAOA,EAAI,UAAY2iB,EAAK,QAAS,CACvC,IAAI4xB,EAA6B,KAC7Bv0C,EAAI,OAASq0C,EACfE,EAAc,MAAMH,CAAO,GAClBp0C,EAAI,KAAK,WAAWs0C,CAAY,IACzCC,EAAc,OAAOH,CAAO,IAAIp0C,EAAI,KAAK,MAAMs0C,EAAa,MAAM,CAAC,IAGnEC,GACAA,EAAY,QAAUvkD,IACtB,CAACuzB,GAA2BwvB,EAAWwB,CAAW,IAElDv0C,EAAI,KAAOu0C,EACXlxB,GAA+B0vB,EAAWn5C,EAAGoG,CAAG,EAEpD,CACF,CAEAyhB,GAAiCsxB,CAAS,EAC1CpxB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAErB,KAAK,eAAe,OAAOoB,EAAQ,YAAA,CAAa,EAChD,KAAK,eAAe,OAAOC,EAAQ,YAAA,CAAa,EAChD,MAAMI,EAAW,KAAK,eAAe,IAAIL,CAAO,EAChD,OAAIK,IAAa,SACf,KAAK,eAAe,OAAOL,CAAO,EAClC,KAAK,eAAe,IAAIC,EAASI,CAAQ,KAEvCj1C,EAAA,KAAK,MAAM,QAAX,YAAAA,EAAkB,KAAK,iBAAkB40C,EAAQ,gBACnD,KAAK,MAAM,MAAQ,MAGhB,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb,KAAK,kBAAkBC,CAAO,CACvC,CAEA,MAAM,aACJ55C,EACAi6C,EACAC,EACoB,CACpB,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,sBAAsBl6C,EAAWi6C,EAAeC,CAAa,EACxE,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,sBACZl6C,EACAi6C,EACAC,EACoB,OACpB,KAAK,mBAAmBA,EAAe,aAAa,EACpD,MAAMh7C,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9Cu2B,EAASr3B,EAAM,QAAQ,UAAWG,GAAMA,EAAE,OAAS46C,CAAa,EACtE,GAAI1jB,IAAW,GACb,MAAM,IAAIj2B,GAAoB25C,EAAej6C,CAAS,EAGxD,GAAIi6C,IAAkBC,EACpB,OAAOh7C,EAGT,GAAIA,EAAM,QAAQ,KAAK,CAACG,EAAGmG,IAAQA,IAAQ+wB,GAAUl3B,EAAE,OAAS66C,CAAa,EAC3E,MAAM,IAAI/5C,GAAyB+5C,EAAel6C,CAAS,EAG7D,KAAM,CAAE,aAAAm6C,EAAc,aAAAC,GAAiBtwB,GAA4ByM,CAAM,EACzE,IAAImhB,EAAYx4C,EAAM,iBACtB,QAASwY,EAAI,EAAGA,EAAIyiC,EAAcziC,IAAK,CACrC,MAAMwD,EAAO,MAAM,KAAK,OAAO,YAAYw8B,CAAS,EAKpDA,EAJenuB,GACb,KAAK,KAAK,gBAAgBrO,CAAI,EAC9B,CAAA,EAEiB,oBACrB,CAEA,MAAMm/B,EAAU,MAAM,KAAK,OAAO,YAAY3C,CAAS,EACjD4C,EAAU,KAAK,KAAK,gBAAgBD,CAAO,EAC3CE,EAAyB,CAC7B,GAAGr7C,EAAM,QAAQq3B,CAAM,EACvB,KAAM2jB,CAAA,EAERxwB,GAA0B4wB,EAAS,EAAGF,EAAcG,CAAU,EAC9D,MAAMnxC,EAAMtD,GAAoB,KAAK,KAAK,mBAAmBu0C,CAAO,CAAC,EACrEC,EAAQ,UAAU,GAAIlxC,EAAK,EAAI,EAC/B,KAAK,KAAK,UAAUixC,CAAO,EAE3B,MAAM9B,EAAY,KAAK,KAAK,gBAAgB,CAAC,EAC7C,OAAAtxB,GAAiCsxB,CAAS,EAC1CpxB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAErB,KAAK,eAAe,OAAOv4C,EAAU,YAAA,CAAa,IAC9C+E,EAAA,KAAK,MAAM,QAAX,YAAAA,EAAkB,KAAK,iBAAkB/E,EAAU,gBACrD,KAAK,MAAM,MAAQ,MAGhB,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb,KAAK,kBAAkBA,CAAS,CACzC,CAEA,MAAM,UACJA,EACAw6C,EACAzxC,EACoB,CACpB,KAAK,mBAAmByxC,EAAO,KAAM,aAAa,EAClD,MAAMC,GACJ1xC,GAAA,YAAAA,EAAS,gBAAiB,OACtBA,EAAQ,aACPyxC,EAAe,eAAiB,OAC9BA,EAAe,aAChB,KAER,OAAO,KAAK,2BAA2Bx6C,EAAYd,GAAU,WAC3D,GAAIA,EAAM,QAAQ,KAAMG,GAAMA,EAAE,OAASm7C,EAAO,IAAI,EAClD,MAAM,IAAIr6C,GAAyBq6C,EAAO,KAAMx6C,CAAS,EAE3D,GAAId,EAAM,QAAQ,OAAS,EAAIhI,GAC7B,MAAM,IAAI+J,GACR/B,EAAM,QAAQ,OAAS,EACvBhI,EAAA,EAIJ,MAAMwjD,EACJ,OAAQF,EAAe,OAAU,SAAYA,EAAe,MAAQ,EAChE/iB,EACJ,CAAC,CAAC+iB,EAAO,YACT,CAAC,GAACz1C,EAAAy1C,EAAO,QAAP,MAAAz1C,EAAc,cACf21C,EAAWn7C,EAAW,eAAiB,EACpCo7C,EACJ,CAAC,CAACH,EAAO,SACT,CAAC,GAAC57B,EAAA47B,EAAO,QAAP,MAAA57B,EAAc,WACf87B,EAAWn7C,EAAW,YAAc,EACjCq7C,EACJ,CAAC,CAACJ,EAAO,SACT,CAAC,GAAClwB,EAAAkwB,EAAO,QAAP,MAAAlwB,EAAc,WACfowB,EAAWn7C,EAAW,WAAa,EAEtC,GACEk4B,GACAv4B,EAAM,QAAQ,KAAMG,IAAOA,EAAE,MAAQE,EAAW,eAAiB,CAAC,EAElE,MAAM,IAAI,MACR,oCAAoCi7C,EAAO,IAAI,eAAex6C,CAAS,wCAAA,EAe3E,MAAO,CACL,WAAY,CAAC,GAZ6Bd,EAAM,QAAQ,IAAKG,IAAO,CACpE,KAAMA,EAAE,KACR,KAAMA,EAAE,KACR,MAAO,CACL,YAAaA,EAAE,MAAQE,EAAW,eAAiB,EACnD,SAAUF,EAAE,MAAQE,EAAW,YAAc,EAC7C,SAAUF,EAAE,MAAQE,EAAW,WAAa,EAC5C,SAAUF,EAAE,MAAQE,EAAW,YAAc,CAAA,CAC/C,EACA,EAGiCi7C,CAAM,EACvC,aAAe9nC,GAAe,CAC5B,MAAMmoC,EAAiB,CAAE,GAAGnoC,CAAA,EAC5B,OAAI,CAACioC,GAAaF,IAAe,QAC/BI,EAAQL,EAAO,IAAI,EAAIC,GAElBI,CACT,EACA,UAAW,IAAM,GACjB,gBAAiBD,GAAa,CAACnjB,EAAO+iB,EAAO,KAAO,MAAA,CAExD,CAAC,CACH,CAEA,MAAM,WAAWx6C,EAAmBD,EAAwC,CAC1E,YAAK,mBAAmBA,EAAY,aAAa,EAE1C,KAAK,2BAA2BC,EAAYd,GAAU,CAC3D,MAAMq3B,EAASr3B,EAAM,QAAQ,UAAWG,GAAMA,EAAE,OAASU,CAAU,EACnE,GAAIw2B,IAAW,GACb,MAAM,IAAIj2B,GAAoBP,EAAYC,CAAS,EAErD,GAAId,EAAM,QAAQ,QAAU,EAC1B,MAAM,IAAIkB,GACR,uBAAuBL,CAAU,iBAAiBC,CAAS,wCAAA,EAK/D,GADkBd,EAAM,QAAQq3B,CAAM,EACvB,MAAQh3B,EAAW,YAChC,MAAM,IAAIa,GACR,mCAAmCL,CAAU,iBAAiBC,CAAS,GAAA,EAiB3E,MAAO,CACL,WAdqCd,EAAM,QAC1C,OAAQG,GAAMA,EAAE,OAASU,CAAU,EACnC,IAAKV,IAAO,CACX,KAAMA,EAAE,KACR,KAAMA,EAAE,KACR,MAAO,CACL,YAAaA,EAAE,MAAQE,EAAW,eAAiB,EACnD,SAAUF,EAAE,MAAQE,EAAW,YAAc,EAC7C,SAAUF,EAAE,MAAQE,EAAW,WAAa,EAC5C,SAAUF,EAAE,MAAQE,EAAW,YAAc,CAAA,CAC/C,EACA,EAIF,aAAemT,GAAe,CAC5B,MAAMmoC,EAAiB,CAAE,GAAGnoC,CAAA,EAC5B,cAAOmoC,EAAQ96C,CAAU,EAClB86C,CACT,EACA,UAAY5kB,GAAuB,CAACA,EAAS,SAASl2B,CAAU,CAAA,CAEpE,CAAC,CACH,CAEA,MAAM,WACJC,EACA86C,EACoB,CACpB,OAAQA,EAAU,KAAA,CAChB,IAAK,cACH,OAAO,KAAK,YAAY96C,EAAW86C,EAAU,OAAO,EACtD,IAAK,eACH,OAAO,KAAK,aAAa96C,EAAW86C,EAAU,KAAMA,EAAU,EAAE,EAClE,IAAK,YACH,OAAO,KAAK,UAAU96C,EAAW86C,EAAU,OAAQ,CACjD,aAAcA,EAAU,YAAA,CACzB,EACH,IAAK,aACH,OAAO,KAAK,WAAW96C,EAAW86C,EAAU,MAAM,EACpD,QACE,MAAM,IAAI,MACR,qCAAsCA,GAAA,YAAAA,EAAmB,IAAI,EAAA,CAC/D,CAEN,CAEA,MAAc,2BACZ96C,EACA+6C,EAMoB,CACpB,OAAK,KAAK,YAAY,kBAMf,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMppB,EAAY,MAAM,KAAK,YAAY,iBAAA,EACzC,GAAI,CACF,OAAO,MAAM,KAAK,4BAA4B3xB,EAAW+6C,CAAO,CAClE,OAAS1sB,EAAK,CACZ,WAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,MAAM,KAAK,YAAY,iBAAiBsD,CAAS,EAC3CtD,CACR,CACF,EAAG,KAAK,gBAAkB,MAAS,EAhB1B,KAAK,YAAahqB,GACvBA,EAAG,4BAA4BrE,EAAW+6C,CAAO,CAAA,CAgBvD,CAEA,MAAc,4BACZ/6C,EACA+6C,EAMoB,CACpB,MAAM77C,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9C,CAAE,WAAAg7C,EAAY,aAAAC,EAAc,UAAAC,EAAW,gBAAAC,CAAA,EAC3CJ,EAAQ77C,CAAK,EAGTk8C,EAAwB,CAAA,EAC9B,IAAIC,EAAgBn8C,EAAM,WAC1B,KAAOm8C,IAAkB,GAAG,CAC1B,IAAIC,EAAW,MAAM,KAAK,OAAO,YAAYD,CAAa,EACtDE,EAAW,KAAK,KAAK,gBAAgBD,CAAQ,EACjD,MAAMjC,EAAYhsC,GAAoBkuC,EAAU,CAAC,EAC3CC,EAAa/tC,GAAsB8tC,EAAU,CAAC,EAEpD,QAASn8C,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClCk8C,EAAW,MAAM,KAAK,OAAO,YAAYD,CAAa,EACtDE,EAAW,KAAK,KAAK,gBAAgBD,CAAQ,EAC7C,MAAMG,EAAaztC,GAAqButC,EAAU,EAAGn8C,CAAC,EAChDsT,EAAMN,GAAqBlT,EAAM,QAASq8C,EAAUE,CAAU,EAChE/oC,GACF0oC,EAAa,KAAKH,EAAavoC,CAAG,CAAC,CAEvC,CAEA2oC,EAAgBG,CAClB,CAGA,MAAME,EAAmBx8C,EAAM,YACzBq5C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCoD,EAAkB3yB,GACtBuvB,EACAr5C,EAAM,OAAA,EAEF08C,EAID,CAAA,EAEL,UAAWp2C,KAAOm2C,EAAiB,CACjC,GAAKn2C,EAAI,MAAQ/F,GAAU,QAAgB,SAC3C,MAAMw2B,EAAWzwB,EAAI,cAClB,MAAM,EAAGA,EAAI,WAAW,EACxB,IAAKq2C,GAAA,OAAS,OAAA92C,EAAA7F,EAAM,QAAQ28C,CAAI,IAAlB,YAAA92C,EAAqB,KAAI,EACvC,OAAQ0B,GAAmB,OAAOA,GAAM,QAAQ,EAC/CwvB,EAAS,SAAWzwB,EAAI,aAAe01C,EAAUjlB,CAAQ,GAC3D2lB,EAA0B,KAAK,CAC7B,KAAMp2C,EAAI,KACV,SAAAywB,EACA,QAASzwB,EAAI,MAAQ/F,GAAU,UAAY,CAAA,CAC5C,CAEL,CAGA,MAAM,KAAK,mBAAmBO,CAAS,EACvC,MAAM,KAAK,qBAAqBA,EAAWg7C,CAAU,EAGrD,UAAWc,KAAWF,EACpB,MAAM,KAAK,qBAAqB57C,EAAW87C,EAAQ,SAAU,CAC3D,KAAMA,EAAQ,KACd,OAAQA,EAAQ,MAAA,CACjB,EAIDX,GACA,CAACS,EAA0B,KACxBp2C,GACCA,EAAI,SAAS,SAAW,GAAKA,EAAI,SAAS,CAAC,IAAM21C,CAAA,GAGrD,MAAM,KAAK,qBAAqBn7C,EAAWm7C,CAAe,EAIxDC,EAAa,OAAS,GACxB,MAAM,KAAK,oBAAoBp7C,EAAWo7C,EAAc,EAAK,EAI/D,MAAMW,EAAazzB,GAAwBiwB,EAAWv4C,CAAS,EAC/D,GAAI+7C,IAAe,GAAI,CACrB,MAAMC,EAAUt0B,GAA8B6wB,EAAWwD,CAAU,EAC/DL,EAAmBM,EAAQ,cAC7BA,EAAQ,YAAcN,EACtBxzB,GAA+BqwB,EAAWwD,EAAYC,CAAO,EAC7D50B,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAEzB,CAEA,YAAK,eAAe,OAAOv4C,EAAU,YAAA,CAAa,EAC7C,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb,KAAK,kBAAkBA,CAAS,CACzC,CAEA,MAAM,YACJA,EACA8Q,EACA/H,EACe,CACf,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,qBAAqB/I,EAAW8Q,EAAS/H,CAAO,EAC3D,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,qBACZ/I,EACA8Q,EACA/H,EACe,CACf,MAAM7J,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9Ci2B,EAAW,MAAM,QAAQnlB,CAAO,EAAIA,EAAU,CAACA,CAAO,EAE5D,GAAImlB,EAAS,SAAW,EACtB,MAAM,IAAI,MACR,mEAAmEj2B,CAAS,GAAA,EAGhF,GAAIi2B,EAAS,OAAS,EACpB,MAAM,IAAI,MACR,kDAAkDA,EAAS,MAAM,GAAA,EAIrE,MAAMgmB,EAAuB,CAAA,EAC7B,UAAWn0B,KAAQmO,EAAU,CAC3B,MAAMzwB,EAAMtG,EAAM,QAAQ,UAAWG,GAAMA,EAAE,OAASyoB,CAAI,EAC1D,GAAItiB,IAAQ,GACV,MAAM,IAAIlF,GAAoBwnB,EAAM9nB,CAAS,EAE/Ci8C,EAAW,KAAKz2C,CAAG,CACrB,CAEA,MAAM9E,GAAYqI,GAAA,YAAAA,EAAS,OAAQ,OAAO/I,CAAS,IAAIi2B,EAAS,KAAK,GAAG,CAAC,GAEnEsiB,EAAY,KAAK,KAAK,gBAAgB,CAAC,EAI7C,GADiBxvB,GAA2BwvB,EAAW73C,CAAS,IAC/C,KACf,MAAM,IAAIC,GAAwBD,CAAS,EAK7C,MAAMw7C,EADelzB,GAA2BuvB,EAAWr5C,EAAM,OAAO,EACjC,KAAMsG,GAAQ,CACnD,GAAIA,EAAI,cAAgBy2C,EAAW,OAAQ,MAAO,GAClD,QAAS78C,EAAI,EAAGA,EAAIoG,EAAI,YAAapG,IACnC,GAAIoG,EAAI,cAAcpG,CAAC,IAAM68C,EAAW78C,CAAC,EAAG,MAAO,GAErD,MAAO,EACT,CAAC,EACD,GAAI88C,EACF,MAAM,IAAIv7C,GAAwBu7C,EAAkB,MAAQx7C,CAAS,EAGvE,MAAMy7C,EAAWrzB,GAA6ByvB,CAAS,EACvD,GAAI4D,IAAa,GACf,MAAM,IAAI96C,GAAoB3K,GAAmBA,EAAiB,EAIpE,MAAM0lD,EAAkB,MAAM,KAAK,OAAO,mBAAA,EACpCC,EAAY,KAAK,KAAK,gBAAgBD,CAAe,EACrDE,EAAY,KAAK,KAAK,gBAAgBD,CAAS,EACrD3nC,GAAqB4nC,EAAW,EAAG,CAAC,EACpC,KAAK,KAAK,UAAUD,CAAS,EAC7B,KAAK,KAAK,UAAUA,CAAS,EAE7B,MAAM3kB,EAAW,CAAC,EAAC3uB,GAAA,MAAAA,EAAS,QAG5B,IAAIsyC,EAAgBn8C,EAAM,WAC1B,KAAOm8C,IAAkB,GAAG,CAC1B,IAAIC,EAAW,MAAM,KAAK,OAAO,YAAYD,CAAa,EACtDE,EAAW,KAAK,KAAK,gBAAgBD,CAAQ,EACjD,MAAMjC,EAAYhsC,GAAoBkuC,EAAU,CAAC,EAC3CC,EAAa/tC,GAAsB8tC,EAAU,CAAC,EAEpD,QAASn8C,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClCk8C,EAAW,MAAM,KAAK,OAAO,YAAYD,CAAa,EACtDE,EAAW,KAAK,KAAK,gBAAgBD,CAAQ,EAC7C,MAAMG,EAAaztC,GAAqButC,EAAU,EAAGn8C,CAAC,EAChDsT,EAAMN,GAAqBlT,EAAM,QAASq8C,EAAUE,CAAU,EACpE,GAAI/oC,EAAK,CACP,MAAMe,EAAS,OAAO4nC,CAAa,GAAK,IAAO,OAAOj8C,CAAC,EACjD,CAAE,OAAAm9C,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACN,CAAE,YAAa+8C,EAAW,OAAQ,cAAeA,CAAA,EACjDvpC,CAAA,EAGF,GAA4B6pC,GAAW,KAAM,CAC3C,GAAI7kB,GACgB,MAAM,KAAK,iBAC3B0kB,EACA/I,EACAkJ,CAAA,EAGA,YAAM,KAAK,mBAAmBH,CAAe,EAC7C,KAAK,eAAe,OAAOA,CAAe,EACpC,IAAIx7C,GACR,mDAAmDF,CAAS,eAAeV,CAAS,GAAA,EAK1F,MAAM,KAAK,gBAAgBo8C,EAAiB/I,EAASkJ,EAAQ9oC,CAAK,CACpE,CACF,CACF,CAEA4nC,EAAgBG,CAClB,CAGA,MAAM7yB,EAAiB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EACxCC,EAAiB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EAC9C,QAASzlB,EAAI,EAAGA,EAAI84C,EAAW,QAAU94C,EAAI,EAAGA,IAC9CwlB,EAAexlB,CAAC,EAAI84C,EAAW94C,CAAC,EAGlC,MAAM4kB,EAAQ2P,EAAWj4B,GAAU,OAAS,EAC5CopB,GAA+B0vB,EAAW4D,EAAU,CAClD,QAASA,EAAW,EACpB,QAASj9C,EAAM,QACf,WAAYk9C,EACZ,YAAaH,EAAW,OACxB,MAAAl0B,EACA,cAAeY,EACf,cAAeC,EACf,KAAMloB,CAAA,CACP,EAEDumB,GAAiCsxB,CAAS,EAC1CpxB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EACrB,KAAK,eAAe,OAAOv4C,EAAU,YAAA,CAAa,EAClD,KAAK,eAAe,OAAOo8C,CAAe,EACrC,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,CAEtB,CAEA,MAAM,UAAU17C,EAAkC,CAChD,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,mBAAmBA,CAAS,EACvC,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,mBAAmBA,EAAkC,CACjE,MAAM63C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCjgC,EAAQyQ,GAA2BwvB,EAAW73C,CAAS,EAC7D,GAAI,CAAC4X,EACH,MAAM,IAAI7X,GAAmBC,CAAS,EAIpC4X,EAAM,KAAK,WAAa,IAC1B,MAAM,KAAK,mBAAmBA,EAAM,KAAK,UAAU,EACnD,KAAK,eAAe,OAAOA,EAAM,KAAK,UAAU,GAGlD4Q,GAAgCqvB,EAAWjgC,EAAM,OAAO,EACxD2O,GAAiCsxB,CAAS,EAC1CpxB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EACrB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACf,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,CAEtB,CAEA,MAAM,YAAYv4C,EAAgD,CAChE,OAAO,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMu4C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EAC7C,GAAIv4C,EAAW,CACb,MAAMd,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EACpD,OAAOgpB,GAA2BuvB,EAAWr5C,EAAM,OAAO,CAC5D,CACA,MAAMs9C,EAAgC,CAAA,EACtC,QAAS,EAAI,EAAG,EAAI9lD,GAAmB,IAAK,CAC1C,MAAMyxB,EAAOM,GAA8B8vB,EAAW,CAAC,EACnDpwB,GACFq0B,EAAW,KAAKr0B,CAAI,CAExB,CACA,OAAOq0B,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEQ,gBACN1rC,EACAtL,EACAkN,EACoC,CACpC,GAAIlN,EAAI,cAAgB,EAAG,CACzB,MAAM8L,EAAMR,EAAQtL,EAAI,cAAc,CAAC,CAAC,EACxC,MAAO,CAAE,OAAQkN,EAAIpB,EAAI,IAAI,EAAG,QAASA,EAAI,IAAA,CAC/C,CACA,MAAO,CACL,OAAQ8F,GACNtG,EACAtL,EAAI,cACJA,EAAI,YACJkN,CAAA,EAEF,QAASpT,EAAS,IAAA,CAEtB,CAEA,MAAc,iBACZ05C,EACA3F,EACAkJ,EACAE,EACkB,CAClB,IAAIC,EAAgB1D,EACpB,KAAO0D,IAAkB,GAAG,CAC1B,MAAMxhC,EAAO,MAAM,KAAK,OAAO,YAAYwhC,CAAa,EAClDn1C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAE3C,GADkB7N,GAAoB9F,EAAM,CAAC,EAC7B,EAAG,CACjB,MAAM2Z,EAASzK,GAA8BlP,EAAM,EAAG8rC,EAASkJ,CAAM,EACrE,GAAIr7B,EAAO,MAAO,CAChB,MAAMy7B,EAAU3uC,GAAqBzG,EAAM,EAAG2Z,EAAO,QAAQ,EACvD07B,EAAOr1C,EAAK,UAAUo1C,EAAS,EAAI,EACnCE,EAAat1C,EAAK,YAAYo1C,EAAU,EAAIC,EAAM,EAAI,EAC5D,GAAI,CAACH,GAAkB,CAACA,EAAe,IAAII,CAAU,EACnD,MAAO,EAEX,CACF,CACAH,EAAgBjvC,GAAsBlG,EAAM,CAAC,CAC/C,CACA,MAAO,EACT,CAEA,MAAc,gBACZyxC,EACA3F,EACAkJ,EACA9oC,EACkB,CAClB,IAAIipC,EAAgB1D,EACpB,KAAO0D,IAAkB,GAAG,CAC1B,MAAMxhC,EAAO,MAAM,KAAK,OAAO,YAAYwhC,CAAa,EAClDn1C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAE3C,GADkB7N,GAAoB9F,EAAM,CAAC,EAC7B,EAAG,CACjB,MAAM2Z,EAASzK,GACblP,EACA,EACA8rC,EACAkJ,EACA9oC,CAAA,EAEF,GAAIyN,EAAO,MACT,OAAA1K,GAA4BjP,EAAM,EAAG2Z,EAAO,QAAQ,EACpD,KAAK,KAAK,UAAUhG,CAAI,EACjB,EAEX,CACAwhC,EAAgBjvC,GAAsBlG,EAAM,CAAC,CAC/C,CACA,MAAO,EACT,CAEA,MAAc,gBACZyxC,EACA3F,EACAkJ,EACA9oC,EACe,CACf,IAAIqpC,EAAY,KAAK,eAAe,IAAI9D,CAAU,GAAKA,EACnD+D,EAAU,MAAM,KAAK,OAAO,YAAYD,CAAS,EACjDE,EAAU,KAAK,KAAK,gBAAgBD,CAAO,EAE/C,OAAa,CACX,MAAME,EAAgBxvC,GAAsBuvC,EAAS,CAAC,EACtD,GAAIC,IAAkB,EAAG,MACzBH,EAAYG,EACZF,EAAU,MAAM,KAAK,OAAO,YAAYD,CAAS,EACjDE,EAAU,KAAK,KAAK,gBAAgBD,CAAO,CAC7C,CACA,KAAK,eAAe,IAAI/D,EAAY8D,CAAS,EAE7C,IAAII,EAAepnC,GACjBknC,EACA,EACA3J,EACAkJ,EACA9oC,EACA,KAAK,KAAK,oBAAA,EAGZ,GAAIypC,IAAiB,GAAI,CACvB,KAAK,KAAK,QAAQH,CAAO,EACzB,GAAI,CACF,MAAMI,EAAe,MAAM,KAAK,OAAO,mBAAA,EACjCC,EAAa,KAAK,KAAK,gBAAgBD,CAAY,EACzD,GAAI,CACFzvC,GAAsBsvC,EAAS,EAAGG,CAAY,EAC9C,KAAK,KAAK,UAAUJ,CAAO,EAE3B,MAAMM,EAAa,KAAK,KAAK,gBAAgBD,CAAU,EAUvD,GATA1oC,GAAqB2oC,EAAY,EAAG,CAAC,EACrCH,EAAepnC,GACbunC,EACA,EACAhK,EACAkJ,EACA9oC,EACA,KAAK,KAAK,oBAAA,EAERypC,IAAiB,GACnB,MAAM,IAAI,MACR,0DAAA,EAGJ,KAAK,KAAK,UAAUE,CAAU,EAC9B,KAAK,eAAe,IAAIpE,EAAYmE,CAAY,CAClD,QAAA,CACE,KAAK,KAAK,UAAUC,CAAU,CAChC,CACF,QAAA,CACE,KAAK,KAAK,UAAUL,CAAO,CAC7B,CACF,MACE,KAAK,KAAK,UAAUA,CAAO,CAE/B,CAEQ,SAASrqC,EAAmB,CAClC,MAAMoiC,EAAa,CAAA,EACnB,SAAW,CAAC3xC,EAAGC,CAAC,IAAK,OAAO,QAAQsP,CAAG,EACrCoiC,EAAI3xC,CAAC,EAAIC,aAAa,WAAaA,EAAE,QAAUA,EAEjD,OAAO0xC,CACT,CAEQ,YAAY15B,EAAQnP,EAAiB,CAE3C,GADImP,IAAMnP,GACLmP,GAAM,MAA6BnP,GAAM,KAC5C,MAAO,GAET,GAAImP,aAAa,YAAcnP,aAAa,WAAY,CACtD,GAAImP,EAAE,aAAenP,EAAE,WAAY,MAAO,GAC1C,QAAS7M,EAAI,EAAGA,EAAIgc,EAAE,WAAYhc,IAChC,GAAIgc,EAAEhc,CAAC,IAAM6M,EAAE7M,CAAC,EAAG,MAAO,GAE5B,MAAO,EACT,CACA,OACG,OAAOgc,GAAM,UAAY,OAAOnP,GAAM,UACtC,OAAOmP,GAAM,UAAY,OAAOnP,GAAM,SAEhC,OAAOmP,CAAC,IAAM,OAAOnP,CAAC,EAG5B,OAAOmP,GAAM,WAAa,OAAOnP,GAAM,UACvC,OAAOmP,GAAM,UAAY,OAAOnP,GAAM,UAEhC,OAAOmP,CAAC,IAAM,OAAOnP,CAAC,EAExB,EACT,CAEQ,kBACN/M,EACAwT,EACqB,CACrB,MAAM4qC,EAASp+C,EAAM,QAAQ,OAC1BG,IAAOA,EAAE,MAAQE,EAAW,eAAiB,CAAA,EAEhD,OAAI+9C,EAAO,SAAW,EACZ5qC,EAAI4qC,EAAO,CAAC,EAAE,IAAI,GAAK,KAE7BA,EAAO,OAAS,EACXA,EAAO,IAAKj+C,GAAOqT,EAAIrT,EAAE,IAAI,GAAK,IAAgB,EAEvDH,EAAM,QAAQ,SAAW,EACnBwT,EAAIxT,EAAM,QAAQ,CAAC,EAAE,IAAI,GAAK,KAEjCA,EAAM,QAAQ,IAAKG,GAAOqT,EAAIrT,EAAE,IAAI,GAAK,IAAgB,CAClE,CAEQ,eACNk+C,EACQ,CACR,MAAMC,EAAap6C,GACbA,GAAM,KAAgC,OACtCA,aAAa,WAAmB,KAAK,MAAM,KAAKA,CAAC,EAAE,KAAK,GAAG,CAAC,GACzD,GAAG,OAAOA,CAAC,IAAI,OAAOA,CAAC,CAAC,GAEjC,OAAI,MAAM,QAAQm6C,CAAE,EACX,IAAIA,EAAG,IAAIC,CAAS,EAAE,KAAK,GAAG,CAAC,IAEpCD,IAAO,MAAQ,OAAOA,GAAO,UAAY,EAAEA,aAAc,YAEpD,IADM,OAAO,KAAKA,CAAE,EAAE,KAAA,EACb,IAAKp6C,GAAM,GAAGA,CAAC,IAAIq6C,EAAUD,EAAGp6C,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,IAE3Dq6C,EAAUD,CAAa,CAChC,CAEQ,eACN1tB,EACAgoB,EACAjuB,EACA6zB,EACW,CACX,KAAM,CAAE,cAAA3F,EAAe,cAAAC,GAAkB,KAAK,aAAA,EACxC54C,EAAS,MAAM,KAAK,IAAI,IAAIs+C,EAAQ,IAAKp+C,GAAMA,EAAE,KAAK,CAAC,CAAC,EAE9D,MAAO,CACL,KAAAwwB,EACA,OAAAgoB,EACA,KAAAjuB,EACA,cAAAkuB,EACA,cAAAC,EACA,OAAA54C,EACA,QAAAs+C,EACA,UAAW,IAAwB,CACjC,MAAMC,MAAU,IAChB,UAAWC,KAAOF,EAAS,CACzB,MAAMx6C,EAAM,GAAG06C,EAAI,MAAM,YAAA,CAAa,KAAK,KAAK,eAAeA,EAAI,EAAE,CAAC,GAChExH,EAAOuH,EAAI,IAAIz6C,CAAG,EACxB,GAAI,CAACkzC,EAAM,CACTuH,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAIA,EAAI,GACR,GAAI,MAAM,QAAQA,EAAI,EAAE,EAAI,CAAC,GAAGA,EAAI,EAAE,EAAIA,EAAI,GAC9C,OAAQA,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAI,OACjD,OAAQA,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAI,OACjD,eAAgBA,EAAI,eAChB,CAAC,GAAGA,EAAI,cAAc,EACtB,MAAA,CACL,EACD,QACF,CAEA,GAAIxH,EAAK,KAAO,UAAYwH,EAAI,KAAO,SACrCD,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAI,SACJ,GAAI,MAAM,QAAQA,EAAI,EAAE,EAAI,CAAC,GAAGA,EAAI,EAAE,EAAIA,EAAI,GAC9C,OAAQA,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAIxH,EAAK,MAAA,CACvD,UACQA,EAAK,KAAO,UAAYwH,EAAI,KAAO,SAC5CD,EAAI,OAAOz6C,CAAG,UACLkzC,EAAK,KAAO,UAAYwH,EAAI,KAAO,SAAU,CACtD,MAAMC,EAASzH,EAAK,OACd0H,EAASF,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAIxH,EAAK,OACvD2H,EAAiB,OAAO,KAAKD,CAAM,EAAE,OACxCvsC,GAAQ,CAAC,KAAK,YAAYssC,EAAOtsC,CAAG,EAAGusC,EAAOvsC,CAAG,CAAC,CAAA,EAErDosC,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAI,SACJ,GAAI,MAAM,QAAQA,EAAI,EAAE,EAAI,CAAC,GAAGA,EAAI,EAAE,EAAIA,EAAI,GAC9C,OAAAC,EACA,OAAAC,EACA,eAAAC,CAAA,CACD,CACH,SAAW3H,EAAK,KAAO,UAAYwH,EAAI,KAAO,SAC5CD,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAI,SACJ,GAAI,MAAM,QAAQxH,EAAK,EAAE,EAAI,CAAC,GAAGA,EAAK,EAAE,EAAIA,EAAK,GACjD,OAAQA,EAAK,MAAA,CACd,UACQA,EAAK,KAAO,UAAYwH,EAAI,KAAO,SAAU,CACtD,MAAMC,EAASzH,EAAK,OACd0H,EAASF,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAI,CAAA,EAClDG,EAAiB,OAAO,KAAKD,CAAM,EAAE,OACxCvsC,GAAQ,CAAC,KAAK,YAAYssC,EAAOtsC,CAAG,EAAGusC,EAAOvsC,CAAG,CAAC,CAAA,EAErDosC,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAI,SACJ,GAAI,MAAM,QAAQA,EAAI,EAAE,EAAI,CAAC,GAAGA,EAAI,EAAE,EAAIA,EAAI,GAC9C,OAAAC,EACA,OAAAC,EACA,eAAAC,CAAA,CACD,CACH,MACEJ,EAAI,IAAIz6C,EAAK,CACX,MAAO06C,EAAI,MACX,GAAIA,EAAI,GACR,GAAI,MAAM,QAAQA,EAAI,EAAE,EAAI,CAAC,GAAGA,EAAI,EAAE,EAAIA,EAAI,GAC9C,OAAQA,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAI,OACjD,OAAQA,EAAI,OAAS,KAAK,SAASA,EAAI,MAAM,EAAI,OACjD,eAAgBA,EAAI,eAChB,CAAC,GAAGA,EAAI,cAAc,EACtB,MAAA,CACL,CAEL,CACA,OAAO,MAAM,KAAKD,EAAI,OAAA,CAAQ,CAChC,CAAA,CAEJ,CAEQ,oBAAoBK,EAA+B,CACzD,GAAIA,EAAM,OAAO,SAAW,GAAK,KAAK,cAAc,OAAS,EAAG,OAChE,MAAMC,EAAe,IAAI,IAAID,EAAM,OAAO,IAAK1qB,GAAMA,EAAE,YAAA,CAAa,CAAC,EACrE,UAAWiiB,KAAO,KAAK,cACrB,GAAIA,EAAI,SAAW,IACjBA,EAAI,SAASyI,CAAK,MAElB,WAAW1qB,KAAK2qB,EACd,GAAI1I,EAAI,OAAO,IAAIjiB,CAAC,EAAG,CACrBiiB,EAAI,SAASyI,CAAK,EAClB,KACF,CAIR,CAEQ,2BAA2BE,EAA4B,CAC7D,GAAIA,EAAU,QAAQ,SAAW,EAAG,OAEpC,UAAWC,KAAQ,KAAK,YACtBA,EAAKD,CAAS,EAGhB,MAAM9+C,EAAS8+C,EAAU,OACnB,CAAE,cAAAnG,EAAe,cAAAC,CAAA,EAAkBkG,EAYzC,GAVA,KAAK,oBAAoB,CACvB,OAAA9+C,EACA,OAAQ8+C,EAAU,OAClB,KAAMA,EAAU,KAChB,cAAAnG,EACA,cAAAC,EACA,SAAU,GACV,UAAAkG,CAAA,CACD,EAEG,KAAK,iBACP,GAAI,CACF,KAAK,iBAAiB,YAAY,CAChC,SAAU,KAAK,WACf,OAAA9+C,EACA,OAAQ8+C,EAAU,OAClB,KAAMA,EAAU,KAChB,cAAAnG,EACA,cAAAC,CAAA,CACD,CACH,MAAQ,CAER,CAEJ,CAEA,eAAemG,EAAoC,CACjD,YAAK,kBAAkB,IAAIA,CAAI,EACxB,IAAM,CACX,KAAK,kBAAkB,OAAOA,CAAI,CACpC,CACF,CAEA,SAASA,EAA8B,CACrC,YAAK,YAAY,IAAIA,CAAI,EAClB,IAAM,CACX,KAAK,YAAY,OAAOA,CAAI,CAC9B,CACF,CAEA,UACE/+C,EACAg/C,EACY,CACZ,MAAMl6B,EAAQ,CACZ,OACE9kB,IAAW,IACN,IACD,IAAI,KACD,MAAM,QAAQA,CAAM,EAAIA,EAAS,CAACA,CAAM,GAAG,IAAKk0B,GAC/CA,EAAE,YAAA,CAAY,CAChB,EAER,SAAA8qB,CAAA,EAEF,YAAK,cAAc,IAAIl6B,CAAK,EACrB,IAAM,CACX,KAAK,cAAc,OAAOA,CAAK,CACjC,CACF,CAEA,cAA0B,CACxB,MAAMs0B,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCl1C,EAAS8iB,GAA0BoyB,EAAW,EAAK,EACzD,MAAO,CACL,cAAel1C,EAAO,cACtB,cAAeA,EAAO,aAAA,CAE1B,CAEQ,sBAAsBnE,EAAkBw3B,EAA8B,CAC5E,MAAM0nB,EAAY,IAAI,IAAIl/C,EAAM,QAAQ,IAAKG,GAAMA,EAAE,IAAI,CAAC,EACpDg/C,EAAa1rB,GAAc,CAC/B,GAAKA,GACL,GAAIA,EAAK,OAAS,OAASA,EAAK,OAAS,KACvC,GAAI,CAACyrB,EAAU,IAAIzrB,EAAK,IAAI,EAC1B,MAAM,IAAIryB,GAAoBqyB,EAAK,KAAMzzB,EAAM,IAAI,UAE5CyzB,EAAK,OAAS,SACvB0rB,EAAU1rB,EAAK,IAAI,EACnB0rB,EAAU1rB,EAAK,KAAK,UACXA,EAAK,OAAS,MAAQ,MAAM,QAAQA,EAAK,IAAI,EACtD,UAAW,KAAKA,EAAK,KAAM0rB,EAAU,CAAC,EAE1C,EACMC,EAAe36C,GAAmB,CACtC,GAAIA,EAAE,SAAW,CAACy6C,EAAU,IAAIz6C,EAAE,OAAO,EACvC,MAAM,IAAIrD,GAAoBqD,EAAE,QAASzE,EAAM,IAAI,EAIrD,GAFIyE,EAAE,MAAM06C,EAAU16C,EAAE,IAAI,EACxBA,EAAE,OAAO26C,EAAY36C,EAAE,KAAK,EAC5BA,EAAE,SACJ,UAAWtE,KAAKsE,EAAE,SAAU26C,EAAYj/C,CAAC,CAE7C,EACA,UAAWsE,KAAK+yB,EAAS4nB,EAAY36C,CAAC,CACxC,CAEQ,cACNzE,EACAwT,EACA/O,EACS,CACT,OAAQA,EAAE,KAAA,CACR,IAAK,MACH,OAAQA,EAAE,UAAY,CAAA,GAAI,MAAOtE,GAC/B,KAAK,cAAcH,EAAOwT,EAAKrT,CAAC,CAAA,EAEpC,IAAK,KACH,OAAQsE,EAAE,UAAY,CAAA,GAAI,KAAMtE,GAC9B,KAAK,cAAcH,EAAOwT,EAAKrT,CAAC,CAAA,EAEpC,IAAK,MACH,OAAOsE,EAAE,MAAQ,CAAC,KAAK,cAAczE,EAAOwT,EAAK/O,EAAE,KAAK,EAAI,GAC9D,IAAK,OAAQ,CACX,MAAMc,EAAMd,EAAE,KACVsxB,GAAatxB,EAAE,KAAM+O,EAAMoV,GAAA,OAAS,OAAA/iB,EAAA,KAAK,OAAO+iB,CAAI,IAAhB,YAAA/iB,EAAmB,IAAI,KAAI,EAC/D2N,EAAI/O,EAAE,OAAQ,EACZ46C,EAAS95C,GAAQ,KACvB,OAAOd,EAAE,OAAS46C,EAAS,CAACA,CAC9B,CACA,IAAK,KAAM,CACT,MAAM95C,EAAMd,EAAE,KACVsxB,GAAatxB,EAAE,KAAM+O,EAAMoV,GAAA,OAAS,OAAA/iB,EAAA,KAAK,OAAO+iB,CAAI,IAAhB,YAAA/iB,EAAmB,IAAI,KAAI,EAC/D2N,EAAI/O,EAAE,OAAQ,EAClB,GAAIc,GAAQ,KAA2B,MAAO,GAE9C,MAAM6T,GADO3U,EAAE,QAAU,CAAA,GACN,KAAMkO,GAAS,KAAK,YAAYpN,EAAKoN,CAAI,CAAC,EAC7D,OAAOlO,EAAE,MAAQ,CAAC2U,EAAQA,CAC5B,CACA,IAAK,OAAQ,CACX,GAAI,CAAC3U,EAAE,KAAM,MAAO,GACpB,MAAMc,EAAMwwB,GACVtxB,EAAE,KACF+O,EACCoV,GAAA,OAAS,OAAA/iB,EAAA,KAAK,OAAO+iB,CAAI,IAAhB,YAAA/iB,EAAmB,IAAI,KAAA,EAEnC,MAAO,EAAQN,GAAQA,IAAQ,CACjC,CACA,IAAK,MAAO,CACV,MAAMiZ,EAAO/Z,EAAE,KACXsxB,GAAatxB,EAAE,KAAM+O,EAAMoV,GAAA,OAAS,OAAA/iB,EAAA,KAAK,OAAO+iB,CAAI,IAAhB,YAAA/iB,EAAmB,IAAI,KAAI,EAC/D2N,EAAI/O,EAAE,OAAQ,EACZga,EAAQha,EAAE,MAChB,GACE+Z,GAAS,MAETC,IAAU,MACVA,IAAU,OAEV,MAAO,GAMT,OAJW,OAAOha,EAAE,IAAM,GAAG,EAC1B,KAAA,EACA,YAAA,EACA,QAAQ,OAAQ,GAAG,EACd,CACN,IAAK,IACL,IAAK,KACH,OAAO,KAAK,YAAY+Z,EAAMC,CAAK,EACrC,IAAK,KACL,IAAK,KACH,MAAO,CAAC,KAAK,YAAYD,EAAMC,CAAK,EACtC,IAAK,IACH,OAAO,OAAOD,GAAS,UAAY,OAAOC,GAAU,SAChDD,EAAOC,EACP,OAAOD,CAAI,EAAI,OAAOC,CAAK,EACjC,IAAK,KACH,OAAO,OAAOD,GAAS,UAAY,OAAOC,GAAU,SAChDD,GAAQC,EACR,OAAOD,CAAI,GAAK,OAAOC,CAAK,EAClC,IAAK,IACH,OAAO,OAAOD,GAAS,UAAY,OAAOC,GAAU,SAChDD,EAAOC,EACP,OAAOD,CAAI,EAAI,OAAOC,CAAK,EACjC,IAAK,KACH,OAAO,OAAOD,GAAS,UAAY,OAAOC,GAAU,SAChDD,GAAQC,EACR,OAAOD,CAAI,GAAK,OAAOC,CAAK,EAClC,IAAK,OACH,OAAO5B,GAAe,OAAO2B,CAAI,EAAG,OAAOC,CAAK,CAAC,EACnD,IAAK,WACH,MAAO,CAAC5B,GAAe,OAAO2B,CAAI,EAAG,OAAOC,CAAK,CAAC,EACpD,IAAK,WACH,OAAO,OAAOD,CAAI,EAAE,SAAS,OAAOC,CAAK,CAAC,EAC5C,IAAK,cACH,OAAO,OAAOD,CAAI,EAAE,WAAW,OAAOC,CAAK,CAAC,EAC9C,IAAK,YACH,OAAO,OAAOD,CAAI,EAAE,SAAS,OAAOC,CAAK,CAAC,EAC5C,QACE,OAAO,KAAK,YAAYD,EAAMC,CAAK,CAAA,CAEzC,CACA,QACE,MAAO,EAAA,CAEb,CAEQ,eACNze,EACAwT,EACAgkB,EACS,CACT,UAAW/yB,KAAK+yB,EACd,GAAI,CAAC,KAAK,cAAcx3B,EAAOwT,EAAK/O,CAAC,EAAG,MAAO,GAEjD,MAAO,EACT,CAOA,MAAc,qCACZzE,EACA+pB,EACAnoB,EACA09C,EACAC,EACe,CACf,GAAID,EAAsB,SAAW,EAAG,OACxC,MAAME,EAAa,IAAI,IAAIF,CAAqB,EAEhD,GAAIv1B,EAAQ,OAAS,EAAG,CAEtB,UAAW01B,KAAUH,EAAuB,CAC1C,MAAMv6B,EAAQw6B,EAAeE,CAAM,EACnC,GAAI,CAAC16B,EAAO,SACZ,MAAM26B,EAAY,OAAO99C,CAAM,GAAK,IAAO,OAAO69C,CAAM,EACxD,UAAWn5C,KAAOyjB,EAAS,CACzB,KAAM,CAAE,OAAAszB,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAye,EAAM,GAAA,EAEoBs4B,GAAW,MACrC,MAAM,KAAK,gBACT/2C,EAAI,WACJ6tC,EACAkJ,EACAqC,CAAA,CAGN,CACF,CAGA,IAAIC,EAAa,EACjB,QAASlT,EAAU,EAAGA,EAAU8S,EAAe,OAAQ9S,IACrD,GAAI,CAAA+S,EAAW,IAAI/S,CAAO,EAC1B,IAAIkT,IAAelT,EAAS,CAC1B,MAAMmT,EAAeL,EAAe9S,CAAO,EAAE,IACvCoT,EAAa,OAAOj+C,CAAM,GAAK,IAAO,OAAO6qC,CAAO,EACpDqT,EAAgB,OAAOl+C,CAAM,GAAK,IAAO,OAAO+9C,CAAU,EAChE,UAAWr5C,KAAOyjB,EAAS,CACzB,KAAM,CAAE,OAAAszB,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAs5C,CAAA,EAE0BvC,GAAW,OACrC,MAAM,KAAK,gBACT/2C,EAAI,WACJ6tC,EACAkJ,EACAwC,CAAA,EAEF,MAAM,KAAK,gBACTv5C,EAAI,WACJ6tC,EACAkJ,EACAyC,CAAA,EAGN,CACF,CACAH,IAEJ,CAGA,MAAM3jC,EAAO,MAAM,KAAK,OAAO,YAAYpa,CAAM,EAC3CyG,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAC3C,QAAS/X,EAAIq7C,EAAsB,OAAS,EAAGr7C,GAAK,EAAGA,IACrD6M,GAAgBzI,EAAM,EAAGi3C,EAAsBr7C,CAAC,CAAC,EAEnD,KAAK,KAAK,UAAU+X,CAAI,CAC1B,CAEQ,0BACNhc,EACA+/C,EACe,CACf,GACEA,IAAc,MACd,OAAOA,GAAc,UACrB,EAAEA,aAAqB,YACvB,CACA,MAAMvoB,EAAyB,CAAA,EAC/B,SAAW,CAACrC,EAAS5vB,CAAG,IAAK,OAAO,QAAQw6C,CAAS,EAC/Cx6C,IAAQ,SACRA,IAAQ,KACViyB,EAAQ,KAAK,CAAE,KAAM,OAAQ,QAAArC,EAAS,OAAQ,GAAM,EAEpDqC,EAAQ,KAAK,CAAE,KAAM,MAAO,QAAArC,EAAS,GAAI,IAAK,MAAO5vB,EAAK,GAG9D,OAAOiyB,CACT,CAEA,MAAMwoB,EAAQhgD,EAAM,QAAQ,KACzBG,IAAOA,EAAE,MAAQE,EAAW,eAAiB,CAAA,EAEhD,GAAI,CAAC2/C,EACH,MAAM,IAAI,MACR,UAAUhgD,EAAM,IAAI,wDAAA,EAGxB,MAAO,CAAC,CAAE,KAAM,MAAO,QAASggD,EAAM,KAAM,GAAI,IAAK,MAAOD,CAAA,CAAW,CACzE,CAEA,MAAM,OACJj/C,EACA0S,EACA3J,EACe,CACf,MAAM,KAAK,WAAW/I,EAAW,CAAC0S,CAAG,EAAG3J,CAAO,CACjD,CAEA,MAAM,WACJ/I,EACA62C,EACA9tC,EACe,CACf,GAAI,GAAC8tC,GAAQA,EAAK,SAAW,GAC7B,IACE,CAAC,KAAK,YAAY,gBAAA,GAClB,KAAK,kBAAkB,KAAO,EAC9B,CACA,MAAM,KAAK,YAAY,MAAOxyC,GAAO,CACnC,MAAMA,EAAG,oBAAoBrE,EAAW62C,EAAM,EAAI,CACpD,EAAG9tC,CAAO,EACV,MACF,CAEA,OAAO,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMo2C,EAAO,KAAK,YAAY,gBAAA,EACxBC,EAAW,MAAM,KAAK,oBAAoBp/C,EAAW62C,EAAM,EAAI,EACrE,GAAI,CAACsI,GAAQC,EAAS,OAAS,EAAG,CAChC,MAAMnB,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACTq2C,CAAA,EAEF,KAAK,2BAA2BnB,CAAS,CAC3C,CACF,EAAG,KAAK,gBAAkB,MAAS,EACrC,CAEA,MAAc,oBACZj+C,EACA62C,EACAwI,EAAwB,GACG,CAC3B,GAAI,CAACxI,GAAQA,EAAK,SAAW,QAAU,CAAA,EACvC,MAAM33C,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9Cu4C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvB,EAAUD,GAA2BuvB,EAAWr5C,EAAM,OAAO,EAC7DogD,EAAgBr2B,EAAQ,OAC3BzjB,IAASA,EAAI,OAAS/F,GAAU,OAASA,GAAU,YAAc,CAAA,EAG9D8/C,EAAargD,EAAM,QAAQ,KAC9BG,IAAOA,EAAE,MAAQE,EAAW,YAAc,CAAA,EAKvCigD,MAA6C,IACnD,UAAWh6C,KAAO85C,EAChBE,EAAgB,IAAIh6C,EAAI,KAAM,IAAI,GAAK,EAGzC,IAAIi6C,EAAmBvgD,EAAM,YAC7B,MAAMwgD,EAKD,CAAA,EAEL,QAASC,EAAO,EAAGA,EAAO9I,EAAK,OAAQ8I,IAAQ,CAC7C,MAAMC,EAAU/I,EAAK8I,CAAI,EAGzB,UAAWtgD,KAAKH,EAAM,QACpB,GAAKG,EAAE,MAAQE,EAAW,aACnB,EAAAF,EAAE,MAAQE,EAAW,YACpBqgD,EAAQvgD,EAAE,IAAI,IAAM,QAAaugD,EAAQvgD,EAAE,IAAI,IAAM,MACvD,MAAM,IAAIS,GAAuBT,EAAE,KAAMW,CAAS,EAO1D,IAAI6/C,EACAC,EAAsB,CAAA,EAC1B,UAAWzgD,KAAKH,EAAM,QAChB0gD,EAAQvgD,EAAE,IAAI,IAAM,OACtBygD,EAAazgD,EAAE,IAAI,EAAIugD,EAAQvgD,EAAE,IAAI,EAErCygD,EAAazgD,EAAE,IAAI,EAAI,KAIzBkgD,IACCK,EAAQL,EAAW,IAAI,IAAM,QAC5BK,EAAQL,EAAW,IAAI,IAAM,QAE/BM,EAAkB,OAAOJ,CAAgB,EACzCA,GAAoB,GACpBK,EAAaP,EAAW,IAAI,EAAIM,GAIlC,UAAWr6C,KAAO85C,EAAe,CAC/B,KAAM,CAAE,OAAA/C,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAs6C,CAAA,EAEF,GAA4BvD,GAAW,KAAM,CAC3C,MAAMwD,EACJxD,aAAkB,WACd,MAAM,KAAKA,CAAM,EAAE,KAAK,GAAG,EAC3BA,EACAj6B,EAAMk9B,EAAgB,IAAIh6C,EAAI,IAAI,EACxC,GAAI8c,EAAI,IAAIy9B,CAAM,EAChB,MAAM,IAAIn/C,GACR,mDAAmD4E,EAAI,IAAI,eAAexF,CAAS,GAAA,EAUvF,GAPAsiB,EAAI,IAAIy9B,CAAM,EAEI,MAAM,KAAK,iBAC3Bv6C,EAAI,WACJ6tC,EACAkJ,CAAA,EAGA,MAAM,IAAI37C,GACR,mDAAmD4E,EAAI,IAAI,eAAexF,CAAS,GAAA,CAGzF,CACF,CAGA,MAAMggD,EAAW9uC,GAAmBhS,EAAM,QAAS4gD,CAAY,EAC/DJ,EAAa,KAAK,CAChB,IAAKE,EACL,aAAAE,EACA,SAAAE,EACA,gBAAAH,CAAA,CACD,CACH,CAGA3gD,EAAM,YAAcugD,EAGpB,IAAIpE,EAAgB,KAAK,eAAe,IAAIr7C,CAAS,GAAKd,EAAM,WAC5Dgc,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAEzC,OAAa,CACX,MAAMsgC,EAAa/tC,GAAsBlG,EAAM,CAAC,EAChD,GAAIi0C,IAAe,EAAG,MACtBH,EAAgBG,EAChBtgC,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,CACvC,CACA,KAAK,eAAe,IAAIlb,EAAWq7C,CAAa,EAEhD,MAAM4E,EAAoC,CAAA,EAG1C,QAASN,EAAO,EAAGA,EAAOD,EAAa,OAAQC,IAAQ,CACrD,KAAM,CAAE,IAAAjtC,EAAK,aAAAotC,EAAc,SAAAE,EAAU,gBAAAH,CAAA,EACnCH,EAAaC,CAAI,EACfJ,GAAcM,IAAoB,SACpCntC,EAAI6sC,EAAW,IAAI,EAAIM,GAIzB3kC,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrC,IAAIglC,EAAe7E,EACf8E,EAAa5wC,GACfhI,EACA,EACAy4C,EACA,KAAK,KAAK,oBAAA,EAGZ,GAAIG,IAAe,GAAI,CACrB,MAAMC,EAAWllC,EACjB,KAAK,KAAK,QAAQklC,CAAQ,EAC1B,GAAI,CACF,MAAMvH,EAAY,MAAM,KAAK,OAAO,mBAAA,EAC9BwH,EAAU,KAAK,KAAK,gBAAgBxH,CAAS,EACnD,GAAI,CACFnrC,GAAsBnG,EAAM,EAAGsxC,CAAS,EACxC,KAAK,KAAK,UAAUuH,CAAQ,EAE5B,MAAME,EAAU,KAAK,KAAK,gBAAgBD,CAAO,EAOjD,GANAF,EAAa5wC,GACX+wC,EACA,EACAN,EACA,KAAK,KAAK,oBAAA,EAERG,IAAe,GACjB,MAAM,IAAI,MACR,kDAAA,EAGJ,KAAK,KAAK,UAAUE,CAAO,EAC3BhF,EAAgBxC,EAChBqH,EAAerH,EACf39B,EAAOmlC,EACP94C,EAAO+4C,EACP,KAAK,eAAe,IAAItgD,EAAW64C,CAAS,CAC9C,QAAA,CACE,KAAK,KAAK,UAAUwH,CAAO,CAC7B,CACF,QAAA,CACE,KAAK,KAAK,UAAUD,CAAQ,CAC9B,CACF,MACE,KAAK,KAAK,UAAUllC,CAAI,EAI1B,MAAMzH,EAAS,OAAOysC,CAAY,GAAK,IAAO,OAAOC,CAAU,EAC/D,UAAW36C,KAAOyjB,EAAS,CACzB,KAAM,CAAE,OAAAszB,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAs6C,CAAA,EAE0BvD,GAAW,MACrC,MAAM,KAAK,gBAAgB/2C,EAAI,WAAY6tC,EAASkJ,EAAQ9oC,CAAK,CAErE,CAEA,GAAI4rC,EAAc,CAChB,MAAM1B,EAAsB,CAC1B,MAAOz+C,EAAM,KACb,GAAI,SACJ,GAAI,KAAK,kBAAkBA,EAAO4gD,CAAY,EAC9C,OAAQ,KAAK,SAASA,CAAY,CAAA,EAEpCG,EAAgB,KAAKtC,CAAG,EACpB,KAAK,YAAY,mBACnB,KAAK,gBAAgB,KAAKA,CAAG,CAEjC,CACF,CAGA,MAAM10C,EAAUqf,GAAwBiwB,EAAWv4C,CAAS,EAC5D,GAAIiJ,IAAY,GAAI,CAClB,MAAMkf,EAAOT,GAA8B6wB,EAAWtvC,CAAO,EAC7Dkf,EAAK,kBAAoB0uB,EAAK,OAC1B0I,IACFp3B,EAAK,YAAcjpB,EAAM,aAE3BgpB,GAA+BqwB,EAAWtvC,EAASkf,CAAI,EACvDhB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,CACvB,CAGA,OAAK,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb0H,CACT,CAEA,MAAM,OACJjgD,EACAi/C,EACA7X,EACAr+B,EACiB,CACjB,MACE,CAAC,KAAK,YAAY,gBAAA,GAClB,KAAK,kBAAkB,KAAO,EAEvB,KAAK,YACT1E,GAAOA,EAAG,OAAOrE,EAAWi/C,EAAW7X,EAAOr+B,CAAO,EACtDA,CAAA,EAIG,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAM7J,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9C02B,EAAU,KAAK,0BAA0Bx3B,EAAO+/C,CAAS,EACzDE,EAAO,KAAK,YAAY,gBAAA,EACxB,CAAE,MAAAh9C,EAAO,QAAAs7C,GAAY,MAAM,KAAK,uBACpCz9C,EACA02B,EACA0Q,CAAA,EAEF,GAAI,CAAC+X,GAAQ1B,EAAQ,OAAS,EAAG,CAC/B,MAAMQ,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACT00C,CAAA,EAEF,KAAK,2BAA2BQ,CAAS,CAC3C,CACA,OAAO97C,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAM,cACJnC,EACA02B,EACA0Q,EACAr+B,EACiB,CACjB,MACE,CAAC,KAAK,YAAY,gBAAA,GAClB,KAAK,kBAAkB,KAAO,EAEvB,KAAK,YACT1E,GAAOA,EAAG,cAAcrE,EAAW02B,EAAS0Q,EAAOr+B,CAAO,EAC3DA,CAAA,EAIG,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMo2C,EAAO,KAAK,YAAY,gBAAA,EACxB,CAAE,MAAAh9C,EAAO,QAAAs7C,GAAY,MAAM,KAAK,uBACpCz9C,EACA02B,EACA0Q,CAAA,EAEF,GAAI,CAAC+X,GAAQ1B,EAAQ,OAAS,EAAG,CAC/B,MAAMQ,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACT00C,CAAA,EAEF,KAAK,2BAA2BQ,CAAS,CAC3C,CACA,OAAO97C,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAc,uBACZnC,EACA02B,EACA0Q,EACuD,CACvD,MAAMloC,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EACpD,KAAK,sBAAsBd,EAAOw3B,CAAO,EAEzC,MAAM6pB,EAAc,IAAI,IAAIrhD,EAAM,QAAQ,IAAKG,GAAM,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACjE,UAAW8D,KAAK,OAAO,KAAKikC,CAAK,EAC/B,GAAI,CAACmZ,EAAY,IAAIp9C,CAAC,EACpB,MAAM,IAAI7C,GAAoB6C,EAAGnD,CAAS,EAI9C,MAAMu4C,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvB,EAAUD,GAA2BuvB,EAAWr5C,EAAM,OAAO,EAC7DogD,EAAgBr2B,EAAQ,OAC3BzjB,IAASA,EAAI,OAAS/F,GAAU,OAASA,GAAU,YAAc,CAAA,EAe9D+gD,EAAqC,CAAA,EACrCC,MAAqB,IAC3B,IAAIC,EAAe,EAGfC,EAAazhD,EAAM,WACvB,KAAOyhD,IAAe,GAAG,CACvB,MAAMzlC,EAAO,MAAM,KAAK,OAAO,YAAYylC,CAAU,EAC/Cp5C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrCm+B,EAAYhsC,GAAoB9F,EAAM,CAAC,EACvCi0C,EAAa/tC,GAAsBlG,EAAM,CAAC,EAE1Cq5C,EAAmD,CAAA,EACnDC,EAAwC,CAAA,EAE9C,QAASzhD,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClC,MAAMk6C,EAAMtrC,GAAqBzG,EAAM,EAAGnI,CAAC,EACrCsT,EAAMN,GAAqBlT,EAAM,QAASqI,EAAM+xC,CAAG,EAGzD,GAFAsH,EAAS,KAAK,CAAE,QAASxhD,EAAG,IAAAsT,EAAK,EAE7B,KAAK,eAAexT,EAAOwT,EAAKgkB,CAAO,EAAG,CAC5C,MAAMmnB,EAAgB,CAAE,GAAGnrC,CAAA,EAC3B,SAAW,CAACvP,EAAGC,CAAC,IAAK,OAAO,QAAQgkC,CAAK,EACnChkC,IAAM,SACRy6C,EAAO16C,CAAC,EAAIC,GAKhB,UAAW/D,KAAKH,EAAM,QACpB,GAAKG,EAAE,MAAQE,EAAW,cACpBs+C,EAAOx+C,EAAE,IAAI,IAAM,MAAQw+C,EAAOx+C,EAAE,IAAI,IAAM,QAChD,MAAM,IAAIS,GAAuBT,EAAE,KAAMW,CAAS,EAKxD,MAAM89C,EAAiB5+C,EAAM,QAC1B,IAAKG,GAAMA,EAAE,IAAI,EACjB,OAAQiS,GAAQ,CAAC,KAAK,YAAYoB,EAAIpB,CAAG,EAAGusC,EAAOvsC,CAAG,CAAC,CAAC,EACrDwvC,EAAc5vC,GAAmBhS,EAAM,QAAS2+C,CAAM,EAE5DgD,EAAQ,KAAK,CACX,QAASzhD,EACT,OAAQsT,EACR,OAAAmrC,EACA,eAAAC,EACA,YAAAgD,CAAA,CACD,EACDL,EAAe,IAAK,OAAOE,CAAU,GAAK,IAAO,OAAOvhD,CAAC,CAAC,EAC1DshD,GACF,CACF,CAEIG,EAAQ,OAAS,GACnBL,EAAc,KAAK,CAAE,OAAQG,EAAY,SAAAC,EAAU,QAAAC,EAAS,EAE9DF,EAAanF,CACf,CAEA,GAAIkF,IAAiB,EACnB,MAAO,CAAE,MAAO,EAAG,QAAS,CAAA,CAAC,EAI/B,UAAWl7C,KAAO85C,EAAe,CAC/B,MAAMyB,MAAoB,IAC1B,UAAWC,KAAMR,EACf,UAAWS,KAAKD,EAAG,QAAS,CAC1B,KAAM,CAAE,OAAAzE,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAy7C,EAAE,MAAA,EAEJ,GAA4B1E,GAAW,KAAM,CAC3C,MAAMwD,EACJxD,aAAkB,WACd,MAAM,KAAKA,CAAM,EAAE,KAAK,GAAG,EAC3BA,EACN,GAAIwE,EAAc,IAAIhB,CAAM,EAC1B,MAAM,IAAIn/C,GACR,mDAAmD4E,EAAI,IAAI,eAAexF,CAAS,GAAA,EAWvF,GARA+gD,EAAc,IAAIhB,CAAM,EAEP,MAAM,KAAK,iBAC1Bv6C,EAAI,WACJ6tC,EACAkJ,EACAkE,CAAA,EAGA,MAAM,IAAI7/C,GACR,mDAAmD4E,EAAI,IAAI,eAAexF,CAAS,GAAA,CAGzF,CACF,CAEJ,CAGA,MAAMigD,EAAoC,CAAA,EACpCiB,EAKD,CAAA,EAEL,UAAWF,KAAMR,EAAe,CAC9B,MAAMW,EAAkC,CAAA,EAExC,UAAWF,KAAKD,EAAG,QAAS,CAC1B,MAAM9lC,EAAO,MAAM,KAAK,OAAO,YAAY8lC,EAAG,MAAM,EAC9Cz5C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAS3C,GARY5K,GACV/I,EACA,EACA05C,EAAE,QACFA,EAAE,YACF,KAAK,KAAK,oBAAA,EAGH,CACP,KAAK,KAAK,UAAU/lC,CAAI,EACxB8lC,EAAG,SAASC,EAAE,OAAO,EAAE,IAAMA,EAAE,OAE/B,MAAMxtC,EAAS,OAAOutC,EAAG,MAAM,GAAK,IAAO,OAAOC,EAAE,OAAO,EAC3D,UAAWz7C,KAAOyjB,EAAS,CACzB,MAAMm4B,EAAS,KAAK,gBAAgBliD,EAAM,QAASsG,EAAKy7C,EAAE,MAAM,EAC1DI,EAAS,KAAK,gBAAgBniD,EAAM,QAASsG,EAAKy7C,EAAE,MAAM,EAC3D,KAAK,YAAYG,EAAO,OAAQC,EAAO,MAAM,IAC5CD,EAAO,SAAW,QAAaA,EAAO,SAAW,MACnD,MAAM,KAAK,gBACT57C,EAAI,WACJ47C,EAAO,QACPA,EAAO,OACP3tC,CAAA,EAGA4tC,EAAO,SAAW,QAAaA,EAAO,SAAW,MACnD,MAAM,KAAK,gBACT77C,EAAI,WACJ67C,EAAO,QACPA,EAAO,OACP5tC,CAAA,EAIR,CAEA,MAAMkqC,EAAsB,CAC1B,MAAOz+C,EAAM,KACb,GAAI,SACJ,GAAI,KAAK,kBAAkBA,EAAO+hD,EAAE,MAAM,EAC1C,OAAQ,KAAK,SAASA,EAAE,MAAM,EAC9B,OAAQ,KAAK,SAASA,EAAE,MAAM,EAC9B,eAAgBA,EAAE,cAAA,EAEpBhB,EAAgB,KAAKtC,CAAG,EACpB,KAAK,YAAY,mBACnB,KAAK,gBAAgB,KAAKA,CAAG,CAEjC,MACEwD,EAAsB,KAAKF,EAAE,OAAO,EACpCC,EAAgB,KAAKD,CAAC,CAE1B,CAEIE,EAAsB,OAAS,GACjC,MAAM,KAAK,qCACTjiD,EACA+pB,EACA+3B,EAAG,OACHG,EACAH,EAAG,QAAA,CAGT,CAGA,GAAIE,EAAgB,OAAS,EAAG,CAC9B,IAAI7F,EACF,KAAK,eAAe,IAAIr7C,CAAS,GAAKd,EAAM,WAC1Cgc,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACzC,OAAa,CACX,MAAMsgC,EAAa/tC,GAAsBlG,EAAM,CAAC,EAChD,GAAIi0C,IAAe,EAAG,MACtBH,EAAgBG,EAChBtgC,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,CACvC,CACA,KAAK,eAAe,IAAIlb,EAAWq7C,CAAa,EAEhD,UAAW4F,KAAKC,EAAiB,CAC/BhmC,EAAO,MAAM,KAAK,OAAO,YAAYmgC,CAAa,EAClD9zC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrC,IAAIglC,EAAe7E,EACf8E,EAAa5wC,GACfhI,EACA,EACA05C,EAAE,YACF,KAAK,KAAK,oBAAA,EAGZ,GAAId,IAAe,GAAI,CACrB,MAAMC,EAAWllC,EACjB,KAAK,KAAK,QAAQklC,CAAQ,EAC1B,GAAI,CACF,MAAMvH,EAAY,MAAM,KAAK,OAAO,mBAAA,EAC9BwH,EAAU,KAAK,KAAK,gBAAgBxH,CAAS,EACnD,GAAI,CACFnrC,GAAsBnG,EAAM,EAAGsxC,CAAS,EACxC,KAAK,KAAK,UAAUuH,CAAQ,EAE5B,MAAME,EAAU,KAAK,KAAK,gBAAgBD,CAAO,EACjDF,EAAa5wC,GACX+wC,EACA,EACAW,EAAE,YACF,KAAK,KAAK,oBAAA,EAEZ,KAAK,KAAK,UAAUZ,CAAO,EAC3BhF,EAAgBxC,EAChBqH,EAAerH,EACf,KAAK,eAAe,IAAI74C,EAAW64C,CAAS,CAC9C,QAAA,CACE,KAAK,KAAK,UAAUwH,CAAO,CAC7B,CACF,QAAA,CACE,KAAK,KAAK,UAAUD,CAAQ,CAC9B,CACF,MACE,KAAK,KAAK,UAAUllC,CAAI,EAG1B,MAAMomC,EAAY,OAAOpB,CAAY,GAAK,IAAO,OAAOC,CAAU,EAClE,UAAW36C,KAAOyjB,EAAS,CACzB,KAAM,CAAE,OAAAszB,EAAQ,QAAAlJ,CAAA,EAAY,KAAK,gBAC/Bn0C,EAAM,QACNsG,EACAy7C,EAAE,MAAA,EAEwB1E,GAAW,MACrC,MAAM,KAAK,gBACT/2C,EAAI,WACJ6tC,EACAkJ,EACA+E,CAAA,CAGN,CAEA,MAAM3D,EAAsB,CAC1B,MAAOz+C,EAAM,KACb,GAAI,SACJ,GAAI,KAAK,kBAAkBA,EAAO+hD,EAAE,MAAM,EAC1C,OAAQ,KAAK,SAASA,EAAE,MAAM,EAC9B,OAAQ,KAAK,SAASA,EAAE,MAAM,EAC9B,eAAgBA,EAAE,cAAA,EAEpBhB,EAAgB,KAAKtC,CAAG,EACpB,KAAK,YAAY,mBACnB,KAAK,gBAAgB,KAAKA,CAAG,CAEjC,CACF,CAGA,OAAAx2B,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAEhB,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb,CAAE,MAAOmI,EAAc,QAAST,CAAA,CACzC,CAEA,MAAM,OACJjgD,EACAi/C,EACAl2C,EACiB,CACjB,MACE,CAAC,KAAK,YAAY,gBAAA,GAClB,KAAK,kBAAkB,KAAO,EAEvB,KAAK,YACT1E,GAAOA,EAAG,OAAOrE,EAAWi/C,EAAWl2C,CAAO,EAC/CA,CAAA,EAIG,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAM7J,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9C02B,EAAU,KAAK,0BAA0Bx3B,EAAO+/C,CAAS,EACzDE,EAAO,KAAK,YAAY,gBAAA,EACxB,CAAE,MAAAh9C,EAAO,QAAAs7C,GAAY,MAAM,KAAK,uBACpCz9C,EACA02B,CAAA,EAEF,GAAI,CAACyoB,GAAQ1B,EAAQ,OAAS,EAAG,CAC/B,MAAMQ,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACT00C,CAAA,EAEF,KAAK,2BAA2BQ,CAAS,CAC3C,CACA,OAAO97C,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAM,cACJnC,EACA02B,EACA3tB,EACiB,CACjB,MACE,CAAC,KAAK,YAAY,gBAAA,GAClB,KAAK,kBAAkB,KAAO,EAEvB,KAAK,YACT1E,GAAOA,EAAG,cAAcrE,EAAW02B,EAAS3tB,CAAO,EACpDA,CAAA,EAIG,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMo2C,EAAO,KAAK,YAAY,gBAAA,EACxB,CAAE,MAAAh9C,EAAO,QAAAs7C,GAAY,MAAM,KAAK,uBACpCz9C,EACA02B,CAAA,EAEF,GAAI,CAACyoB,GAAQ1B,EAAQ,OAAS,EAAG,CAC/B,MAAMQ,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACT00C,CAAA,EAEF,KAAK,2BAA2BQ,CAAS,CAC3C,CACA,OAAO97C,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAc,uBACZnC,EACA02B,EACuD,CACvD,MAAMx3B,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EACpD,KAAK,sBAAsBd,EAAOw3B,CAAO,EAEzC,MAAM6hB,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvCtvB,EAAUD,GAA2BuvB,EAAWr5C,EAAM,OAAO,EAE7D+gD,EAAoC,CAAA,EAC1C,IAAIsB,EAAe,EAEfZ,EAAazhD,EAAM,WACvB,KAAOyhD,IAAe,GAAG,CACvB,MAAMzlC,EAAO,MAAM,KAAK,OAAO,YAAYylC,CAAU,EAC/Cp5C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrCm+B,EAAYhsC,GAAoB9F,EAAM,CAAC,EACvCi0C,EAAa/tC,GAAsBlG,EAAM,CAAC,EAEhD,GAAI8xC,EAAY,EAAG,CACjB,MAAMuH,EAAmD,CAAA,EACnDY,EAA2B,CAAA,EAEjC,QAASpiD,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClC,MAAMk6C,EAAMtrC,GAAqBzG,EAAM,EAAGnI,CAAC,EACrCsT,EAAMN,GAAqBlT,EAAM,QAASqI,EAAM+xC,CAAG,EAGzD,GAFAsH,EAAS,KAAK,CAAE,QAASxhD,EAAG,IAAAsT,EAAK,EAE7B,KAAK,eAAexT,EAAOwT,EAAKgkB,CAAO,EAAG,CAC5C8qB,EAAe,KAAKpiD,CAAC,EACrB,MAAMu+C,EAAsB,CAC1B,MAAOz+C,EAAM,KACb,GAAI,SACJ,GAAI,KAAK,kBAAkBA,EAAOwT,CAAG,EACrC,OAAQ,KAAK,SAASA,CAAG,CAAA,EAE3ButC,EAAgB,KAAKtC,CAAG,EACpB,KAAK,YAAY,mBACnB,KAAK,gBAAgB,KAAKA,CAAG,CAEjC,CACF,CAEI6D,EAAe,OAAS,IAC1BD,GAAgBC,EAAe,OAC/B,MAAM,KAAK,qCACTtiD,EACA+pB,EACA03B,EACAa,EACAZ,CAAA,EAGN,CAEAD,EAAanF,CACf,CAEA,GAAI+F,IAAiB,EACnB,MAAO,CAAE,MAAO,EAAG,QAAS,CAAA,CAAC,EAG/B,MAAMt4C,EAAUqf,GAAwBiwB,EAAWv4C,CAAS,EAC5D,GAAIiJ,IAAY,GAAI,CAClB,MAAMkf,EAAOT,GAA8B6wB,EAAWtvC,CAAO,EAC7Dkf,EAAK,iBAAmB,KAAK,IAAI,EAAGA,EAAK,iBAAmBo5B,CAAY,EACxEr5B,GAA+BqwB,EAAWtvC,EAASkf,CAAI,CACzD,CACA,OAAAhB,GAAiCoxB,CAAS,EAC1CnxB,GAA8BmxB,CAAS,EACvC,KAAK,KAAK,UAAU,CAAC,EAEhB,KAAK,YAAY,mBACpB,MAAM,KAAK,OAAO,cAAA,EAGb,CAAE,MAAOgJ,EAAc,QAAStB,CAAA,CACzC,CAEA,MAAM,OACJjgD,EACA0S,EACA3J,EAC6C,CAC7C,MAAMoa,EAAM,MAAM,KAAK,WAAWnjB,EAAW,CAAC0S,CAAG,EAAG3J,CAAO,EAC3D,OAAIoa,EAAI,SAAW,EAAU,WACzBA,EAAI,QAAU,EAAU,UACrB,SACT,CAEA,MAAM,WACJnjB,EACA62C,EACA9tC,EACiE,CACjE,MAAI,CAAC8tC,GAAQA,EAAK,SAAW,EACpB,CAAE,SAAU,EAAG,QAAS,EAAG,QAAS,CAAA,EAI3C,CAAC,KAAK,YAAY,gBAAA,IACjB,KAAK,kBAAkB,KAAO,GAAKA,EAAK,OAAS,GAE3C,KAAK,YACTxyC,GAAOA,EAAG,mBAAmBrE,EAAW62C,EAAM9tC,CAAO,EACtDA,CAAA,EAIG,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMo2C,EAAO,KAAK,YAAY,gBAAA,EACxBsC,EAAiC,CAAA,EACjCt+B,EAAM,MAAM,KAAK,mBACrBnjB,EACA62C,EACA9tC,EACAo2C,EAAO,OAAYsC,CAAA,EAErB,GAAI,CAACtC,GAAQsC,EAAa,OAAS,EAAG,CACpC,MAAMxD,EAAY,KAAK,eACrB,KAAK,gBACLl1C,GAAA,YAAAA,EAAS,SAAU,QACnBA,GAAA,YAAAA,EAAS,KACT04C,CAAA,EAEF,KAAK,2BAA2BxD,CAAS,CAC3C,CACA,OAAO96B,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAEA,MAAc,mBACZnjB,EACA62C,EACA9tC,EACA24C,EACiE,CACjE,MAAMxiD,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAC9Co+C,EAAY,IAAI,IAAIl/C,EAAM,QAAQ,IAAKG,GAAMA,EAAE,IAAI,CAAC,EAE1D,IAAIsiD,EACJ,GAAI54C,GAAA,MAAAA,EAAS,eAAgB,CAC3B44C,EAAe,MAAM,QAAQ54C,EAAQ,cAAc,EAC/CA,EAAQ,eACR,CAACA,EAAQ,cAAc,EAC3B,UAAWuI,KAAOqwC,EAChB,GAAI,CAACvD,EAAU,IAAI9sC,CAAG,EACpB,MAAM,IAAIhR,GAAoBgR,EAAKtR,CAAS,CAGlD,SACE2hD,EAAeziD,EAAM,QAClB,OAAQG,IAAOA,EAAE,MAAQE,EAAW,eAAiB,CAAC,EACtD,IAAKF,GAAMA,EAAE,IAAI,EAChBsiD,EAAa,SAAW,EAC1B,MAAM,IAAI,MACR,2BAA2B3hD,CAAS,oDAAA,EAK1C,MAAMwkB,GAAOzb,GAAA,YAAAA,EAAS,OAAQ,QAC9B,IAAI64C,EAAW,EACXC,EAAU,EACVC,EAAU,EAEd,UAAWpvC,KAAOmkC,EAAM,CACtB,UAAW1zC,KAAK,OAAO,KAAKuP,CAAG,EAC7B,GAAI,CAAC0rC,EAAU,IAAIj7C,CAAC,EAClB,MAAM,IAAI7C,GAAoB6C,EAAGnD,CAAS,EAI9C,MAAM+hD,EAAqBJ,EAAa,MACrCtiD,GAAMqT,EAAIrT,CAAC,IAAM,QAAaqT,EAAIrT,CAAC,IAAM,IAAA,EAG5C,IAAI2iD,EAA4B,KAC5BC,EAAiC,CAAA,EAYrC,GAVIF,IACFE,EAAkBN,EAAa,IAAKttB,IAAa,CAC/C,KAAM,MACN,QAAAA,EACA,GAAI,IACJ,MAAO3hB,EAAI2hB,CAAO,CAAA,EAClB,EACF2tB,EAAc,MAAM,KAAK,qBAAqB9iD,EAAO+iD,CAAe,GAGjED,EAUE,CACL,GAAIx9B,IAAS,SAAU,CACrBs9B,IACA,QACF,CACA,GAAI/4C,GAAA,MAAAA,EAAS,OAKP,CAJiBA,EAAQ,MAC3B,KAAK,SAASi5C,CAAW,EACzB,KAAK,SAAStvC,CAAG,CAAA,EAEA,CACjBovC,IACA,QACF,CAGF,MAAM1a,EAAwB,CAAA,EAC9B,GAAI5iB,IAAS,UACX,UAAWnlB,KAAKH,EAAM,QAChBwT,EAAIrT,EAAE,IAAI,IAAM,OAClB+nC,EAAM/nC,EAAE,IAAI,EAAIqT,EAAIrT,EAAE,IAAI,EAChBA,EAAE,MAAQE,EAAW,YAC/B6nC,EAAM/nC,EAAE,IAAI,EAAI2iD,EAAY3iD,EAAE,IAAI,EAElC+nC,EAAM/nC,EAAE,IAAI,EAAI,SAIpB,UAAW,CAAC8D,EAAGC,CAAC,IAAK,OAAO,QAAQsP,CAAG,EACjCtP,IAAM,SACRgkC,EAAMjkC,CAAC,EAAIC,GAKjB,KAAM,CAAE,QAAS8+C,GAAe,MAAM,KAAK,uBACzCliD,EACAiiD,EACA7a,CAAA,EAEEsa,GACFA,EAAoB,KAAK,GAAGQ,CAAU,EAExCL,GACF,KAtDkB,CAChB,MAAMM,EAAa,MAAM,KAAK,oBAC5BniD,EACA,CAAC0S,CAAG,EACJ,EAAA,EAEEgvC,GACFA,EAAoB,KAAK,GAAGS,CAAU,EAExCP,GACF,CA6CF,CAEA,MAAO,CAAE,SAAAA,EAAU,QAAAC,EAAS,QAAAC,CAAA,CAC9B,CAEA,MAAc,qBACZ5iD,EACAw3B,EACuB,CACvB,IAAIiqB,EAAazhD,EAAM,WACvB,KAAOyhD,IAAe,GAAG,CACvB,MAAMzlC,EAAO,MAAM,KAAK,OAAO,YAAYylC,CAAU,EAC/Cp5C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EACrCm+B,EAAYhsC,GAAoB9F,EAAM,CAAC,EACvCi0C,EAAa/tC,GAAsBlG,EAAM,CAAC,EAEhD,QAASnI,EAAI,EAAGA,EAAIi6C,EAAWj6C,IAAK,CAClC,MAAMk6C,EAAMtrC,GAAqBzG,EAAM,EAAGnI,CAAC,EACrCsT,EAAMN,GAAqBlT,EAAM,QAASqI,EAAM+xC,CAAG,EACzD,GAAI,KAAK,eAAep6C,EAAOwT,EAAKgkB,CAAO,EACzC,OAAOhkB,CAEX,CACAiuC,EAAanF,CACf,CACA,OAAO,IACT,CAEA,MAAM,YACJ2C,EACAp1C,EACY,CACZ,MAAMwnB,EAAQ,MAAM,KAAK,YAAY,MAAA,EAC/BD,EAAUC,EAAM,QACtB,KAAK,gBAAkB,CAAA,EACvB,KAAK,gBAAiBxnB,GAAA,YAAAA,EAAS,SAAU,QACzC,KAAK,aAAeA,GAAA,YAAAA,EAAS,KAC7B,KAAK,WAAawnB,EAAM,KAExB,MAAM6xB,EAAiB,IAAI,MAAM,KAAM,CACrC,IAAK,CAAC12C,EAAQ22C,EAAMC,IAAa,CAC/B,GAAID,IAAS,iBACX,OAAO/xB,EAET,GAAI+xB,IAAS,cACX,MAAO,OACLxxB,EACA0xB,IACe,CACf,MAAM5wB,EAAY,MAAM,KAAK,YAAY,iBAAA,EACnC6wB,EAAkB,KAAK,gBAAgB,OAC7C,GAAI,CACF,OAAO,MAAM3xB,EAAGuxB,CAAO,CACzB,OAAS/zB,EAAK,CACZ,WAAK,gBAAgB,OAASm0B,EAC9B,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,MAAM,KAAK,YAAY,iBAAiB7wB,CAAS,EAC3CtD,CACR,CACF,EAEF,GAAIg0B,IAAS,aACX,MAAO,IAAM,KAAK,WAAA,EAEpB,GAAIA,IAAS,OACX,OAAQriD,GAAsB,CAC5B,MAAMyiD,EAAK,IAAIhN,GAAa2M,EAASpiD,CAAS,EAC9C,OAAI0L,EAAO,SACT+2C,EAAG,YAAY/2C,EAAO,OAAO,EAExB+2C,CACT,EAEF,MAAMh+C,EAAM,QAAQ,IAAIiH,EAAQ22C,EAAMC,CAAQ,EAC9C,OAAI,OAAO79C,GAAQ,WACVA,EAAI,KAAK29C,CAAO,EAElB39C,CACT,CAAA,CACD,EAED,GAAI,CACF,MAAM0e,EAAM,MAAMg7B,EAASiE,CAAO,EAElC,GACE,KAAK,gBAAgB,OAAS,GAC9B,KAAK,kBAAkB,KAAO,GAC9B,CAAC,KAAK,sBACN,CACA,MAAMM,EAAqB,KAAK,eAC9B,KAAK,WACL,KAAK,eACL,KAAK,aACL,CAAC,GAAG,KAAK,eAAe,CAAA,EAE1B,KAAK,sBAAwB,GAC7B,GAAI,CACF,UAAWxE,KAAQ,KAAK,kBACtB,MAAMA,EAAKwE,EAAoBN,CAAO,CAE1C,QAAA,CACE,KAAK,sBAAwB,EAC/B,CACF,CAEA,MAAMO,EAAe,CAAC,GAAG,KAAK,eAAe,EACvCC,EAAc,KAAK,eACnBC,EAAY,KAAK,aACjBC,EAAY,KAAK,WAQvB,GANA,KAAK,gBAAkB,CAAA,EACvB,KAAK,eAAiB,QACtB,KAAK,aAAe,OAEpB,MAAM,KAAK,YAAY,OAAOxyB,CAAO,EAEjCqyB,EAAa,OAAS,EAAG,CAC3B,MAAMI,EAAqB,KAAK,eAC9BD,EACAF,EACAC,EACAF,CAAA,EAEF,KAAK,2BAA2BI,CAAkB,CACpD,CAEA,OAAO5/B,CACT,OAASkL,EAAK,CACZ,WAAK,gBAAkB,CAAA,EACvB,KAAK,eAAiB,QACtB,KAAK,aAAe,OACpB,KAAK,sBAAwB,GAE7B,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,MAAM,KAAK,YAAY,SAASiC,CAAO,EACjCjC,CACR,CACF,CAEA,iBACEvG,EACAuC,EACM,CACN,MAAM24B,EAAWl7B,EAAK,YAAA,EAChBm7B,EACJ,OAAO54B,GAAQ,WAAa,CAAE,KAAMA,CAAA,EAAQ,CAAE,GAAGA,CAAA,EAEnD,GAAI,CAAC44B,EAAM,WACT,GAAI,CACF,MAAMC,EAASD,EAAM,KAAK,EAAG,EAAG,EAAG,EAAG,CAAC,EACnC,OAAOC,GAAW,SACpBD,EAAM,WAAa,OAAO,UAAUC,CAAM,EACtC5jD,EAAS,MACTA,EAAS,QACJ,OAAO4jD,GAAW,WAC3BD,EAAM,WAAa3jD,EAAS,KAEhC,MAAQ,CACN,GAAI,CACF,MAAM4jD,EAASD,EAAM,KAAK,GAAI,GAAI,GAAI,GAAI,EAAE,EACxC,OAAOC,GAAW,SACpBD,EAAM,WAAa,OAAO,UAAUC,CAAM,EACtC5jD,EAAS,MACTA,EAAS,QACJ,OAAO4jD,GAAW,WAC3BD,EAAM,WAAa3jD,EAAS,KAEhC,MAAQ,CAER,CACF,CAGF,IAAI2kB,EAAQ,KAAK,KAAK,IAAI++B,CAAQ,EAClC,OAAK/+B,EAIHA,EAAM,IAAMg/B,GAHZh/B,EAAQ,CAAE,GAAI,KAAK,YAAa,IAAKg/B,CAAA,EACrC,KAAK,KAAK,IAAID,EAAU/+B,CAAK,GAIxB,IACT,CAEA,OAAO6D,EAA8D,CACnE,OAAO,KAAK,KAAK,IAAIA,EAAK,aAAa,CACzC,CAEA,WAAiC,CAC/B,MAAM41B,MAAU,IAChB,SAAW,CAAC51B,EAAM7D,CAAK,IAAK,KAAK,KAAK,UACpCy5B,EAAI,IAAI51B,EAAM7D,EAAM,EAAE,EAExB,OAAOy5B,CACT,CAEA,YAAyC,CACvC,MAAMA,MAAU,IAChB,SAAW,CAAC51B,EAAM7D,CAAK,IAAK,KAAK,KAAK,UACpCy5B,EAAI,IAAI51B,EAAM7D,EAAM,GAAG,EAEzB,OAAOy5B,CACT,CAEA,KAAK19C,EAAiC,CACpC,OAAO,IAAIy1C,GAAa,KAAMz1C,CAAS,CACzC,CAEA,MAAM,aACJA,EACA02B,EACA3tB,EAYwB,CACxB,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,sBAAsB/I,EAAW02B,EAAS3tB,CAAO,EAC5D,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,sBACZ/I,EACA02B,EACA3tB,EAYwB,WACxB,MAAM7J,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAE9CmjD,EAAwB,CAAA,EAC9B,GAAIp6C,GAAA,MAAAA,EAAS,OAASA,EAAQ,MAAM,OAAS,EAAG,CAC9C,GAAI,EAAIA,EAAQ,MAAM,OAAS,GAC7B,MAAM,IAAIrH,GAAoB,EAAIqH,EAAQ,MAAM,OAAQ,EAAE,EAE5D,QAAS3J,EAAI,EAAGA,EAAI2J,EAAQ,MAAM,OAAQ3J,IAAK,CAC7C,MAAMmZ,EAAIxP,EAAQ,MAAM3J,CAAC,EACnBgkD,EAAc,MAAM,KAAK,kBAAkB7qC,EAAE,KAAK,EACxD4qC,EAAU,KAAK,CACb,KAAM5qC,EAAE,KACR,MAAO6qC,EACP,OAAQhkD,EAAI,EACZ,QAASmZ,EAAE,QACX,GAAIA,EAAE,GACN,SAAUA,EAAE,QAAA,CACb,CACH,CACF,CAEA,MAAMkH,EAAW0rB,GAAa,CAC5B,MAAAjsC,EACA,aAAcikD,EAAU,OAAS,EAAIA,EAAY,OACjD,QAAAzsB,EACA,QAAS3tB,GAAA,YAAAA,EAAS,QAClB,QAASA,GAAA,YAAAA,EAAS,QAClB,WAAYA,GAAA,YAAAA,EAAS,WACrB,OAAQA,GAAA,YAAAA,EAAS,OACjB,YAAaA,GAAA,YAAAA,EAAS,YACtB,WAAY,KAAK,UAAA,EACjB,QAAS,KAAK,WAAA,EACd,MAAOA,GAAA,YAAAA,EAAS,MAChB,OAAQA,GAAA,YAAAA,EAAS,OACjB,SAASA,GAAA,YAAAA,EAAS,UAAW,KAAK,OAAA,CACnC,EAMK8gC,GAJHpqB,EAAiB,YACjB0jC,EAAU,OAAS,EAChB,CAACjkD,EAAO,GAAGikD,EAAU,IAAK5qC,GAAMA,EAAE,KAAK,CAAC,EACxC,CAACrZ,CAAK,IACyB,CAAC,EAChC2zC,EAAeD,GAAoBnzB,EAAUoqB,CAAY,EACzDwZ,EAAWzO,GAAkB/B,CAAY,EACzCnD,EACHjwB,EAAiB,WAAcA,EAAiB,WAC7C6jC,EAAW5T,EAAY,YAAc,YACrChvC,EAAYgvC,EAAYA,EAAU,MAAM,KAAO,OAC/CqC,EAAoBtyB,EAAiB,iBASrC8jC,GAAiBx+C,EAAAgE,GAAA,YAAAA,EAAS,QAAT,YAAAhE,EAAgB,IAAKwT,GAAM,CAChD,MAAMirC,EAAWzR,GAAA,YAAAA,EAAkB,KAChCprC,GAAMA,EAAE,UAAU,gBAAkB4R,EAAE,MAAM,YAAA,GAE/C,OAAIirC,GAAYA,EAAS,WAAa,YAC7B,CACL,GAAGjrC,EACH,SAAUirC,EAAS,SACnB,UAAWA,EAAS,SAAA,EAGjBjrC,CACT,GAEA,MAAO,CACL,KAAM,CACJ,MAAOsxB,EAAa,KACpB,WAAYA,EAAa,WACzB,SAAAyZ,EACA,UAAA5iD,EACA,QAAAg2B,EACA,QAAS3tB,GAAA,YAAAA,EAAS,QAClB,QAASA,GAAA,YAAAA,EAAS,QAClB,WAAYA,GAAA,YAAAA,EAAS,WACrB,OAAQA,GAAA,YAAAA,EAAS,OACjB,OAAQA,GAAA,YAAAA,EAAS,OACjB,MAAOw6C,EACP,MAAOx6C,GAAA,YAAAA,EAAS,MAChB,OAAQA,GAAA,YAAAA,EAAS,OACjB,cAAgB0W,EAAiB,cACjC,cAAgBA,EAAiB,cACjC,UAAYA,EAAiB,UAC7B,iBACGA,EAAiB,oBACjBb,EAAAa,EAAiB,cAAjB,YAAAb,EAA8B,mBAC/B,GACF,kBACG0L,EAAA7K,EAAiB,cAAjB,YAAA6K,EAA8B,kBAAmB,MAAA,EAEtD,aAAc7K,EAAS,WACvB,aAAAozB,EACA,SAAAwQ,CAAA,CAEJ,CAEA,MAAM,aACJrjD,EACA02B,EACA3tB,EACkB,CAClB,OAAO,KAAK,YAAY,WAAW,QACjC,IAAM,KAAK,sBAAsB/I,EAAW02B,EAAS3tB,CAAO,EAC5D,KAAK,gBAAkB,MAAA,CAE3B,CAEA,MAAc,sBACZ/I,EACA02B,EACA3tB,EACkB,OAClB,MAAM7J,EAAQ,MAAM,KAAK,kBAAkBc,CAAS,EAE9CyjD,EAAgC,CAAA,EAChCN,EAAwB,CAAA,EAC9B,GAAIp6C,EAAQ,OAASA,EAAQ,MAAM,OAAS,EAAG,CAC7C,GAAI,EAAIA,EAAQ,MAAM,OAAS,GAC7B,MAAM,IAAIrH,GAAoB,EAAIqH,EAAQ,MAAM,OAAQ,EAAE,EAE5D,QAAS3J,EAAI,EAAGA,EAAI2J,EAAQ,MAAM,OAAQ3J,IAAK,CAC7C,MAAMmZ,EAAIxP,EAAQ,MAAM3J,CAAC,EACnBgkD,EAAc,MAAM,KAAK,kBAAkB7qC,EAAE,KAAK,EACxDkrC,EAAiB,KAAKL,CAAW,EACjCD,EAAU,KAAK,CACb,KAAM5qC,EAAE,KACR,MAAO6qC,EACP,OAAQhkD,EAAI,EACZ,QAASmZ,EAAE,QACX,GAAIA,EAAE,GACN,SAAUA,EAAE,QAAA,CACb,CACH,CACF,CAGA,UAAW8a,IAAK,CAACn0B,EAAO,GAAGukD,CAAgB,EAAG,CAC5C,IAAI9C,EAAattB,EAAE,WACnB,KAAOstB,IAAe,GAAG,CACvB,MAAMzlC,EAAO,MAAM,KAAK,OAAO,YAAYylC,CAAU,EAC/Cp5C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAC3CylC,EAAalzC,GAAsBlG,EAAM,CAAC,CAC5C,CACA,UAAW/B,KAAO6tB,EAAE,SAAW,CAAA,EAAI,CACjC,IAAIypB,EAAYt3C,EAAI,WACpB,KAAOs3C,IAAc,GAAG,CACtB,MAAM5hC,EAAO,MAAM,KAAK,OAAO,YAAY4hC,CAAS,EAC9Cv1C,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAC3C4hC,EAAYrvC,GAAsBlG,EAAM,CAAC,CAC3C,CACF,CACF,CAEA,IAAIovB,EAAU5tB,EAAQ,QAClB,CAAC4tB,GAAW5tB,EAAQ,UACtB4tB,EAAU,CAAC,CAAE,QAAS5tB,EAAQ,QAAS,UAAWA,EAAQ,QAAS,GAGrE,MAAM8uB,EAAkB,CACtB,MAAA34B,EACA,aAAcikD,EAAU,OAAS,EAAIA,EAAY,OACjD,QAAAzsB,EACA,QAAAC,EACA,QAAS5tB,EAAQ,QACjB,WAAYA,EAAQ,WACpB,OAAQA,EAAQ,OAChB,YAAaA,EAAQ,YACrB,WAAY,KAAK,UAAA,EACjB,QAAS,KAAK,WAAA,EACd,MAAOA,EAAQ,QAAU,KAAOA,EAAQ,MAAQ,OAChD,OAAQA,EAAQ,SAAW,KAAOA,EAAQ,OAAS,OACnD,QAASA,EAAQ,SAAW,KAAK,OAAA,EAG7B0W,EAAW0rB,GAAatT,CAAI,EAE5B6rB,EAAgCjkC,EAAiB,WAAa,CAClEvgB,EACA,GAAGukD,CAAA,EAGLzkD,GAAe,KAAK,MAAO0kD,EAAgB,CAAC,EAAGA,CAAe,EACzDjkC,EAAiB,SACpB,KAAK,MAAM,OAAUA,EAAiB,QAExC,MAAMkkC,EAAYlkC,EAAiB,UAAYoY,EAAK,SAChD8rB,IACF,KAAK,MAAM,SAAWA,GAGxB,MAAMC,EAAsD,CAAA,EAC5D,UAAW3/B,KAAS,KAAK,KAAK,OAAA,EAC5B2/B,EAAW3/B,EAAM,EAAE,EAAIA,EAAM,IAAI,KAEnC,KAAK,MAAM,KAAO2/B,EAGlB,IAAI9W,EACDrtB,EAAiB,eAAiBoY,EAAK,eAAiB34B,EAAM,QACjE,GACG24B,EAAK,YAAcA,EAAK,WAAW,OAAS,GAC5CA,EAAK,SAAWA,EAAK,QAAQ,OAAS,EAEvC,GAAKpY,EAAiB,cACpBqtB,EAAiBrtB,EAAiB,kBAC7B,CACLqtB,EAAgB,CAAA,EAChB,MAAM+W,EAAchsB,EAAK,SAAW,CAAA,EACpC,UAAWkV,KAAS8W,EAAa,CAC/B,MAAM7W,EACJ,OAAOD,GAAU,SACbA,EACCA,EAAM,UACNA,EAAM,KAAO3Y,GAAmB2Y,EAAM,IAAI,EAAI,aAC/Cz7B,EAAMpS,EAAM,QAAQ,KAAMG,GAAMA,EAAE,OAAS2tC,CAAQ,EACrD17B,EACFw7B,EAAc,KAAKx7B,CAAG,EAEtBw7B,EAAc,KAAK,CACjB,KAAME,EACN,KAAM1tC,EAAS,KACf,MAAOC,EAAW,KAClB,UAAW,CAAA,CACZ,CAEL,CACA,QAASgZ,EAAI,EAAGA,KAAKxT,EAAA8yB,EAAK,aAAL,YAAA9yB,EAAiB,SAAU,GAAIwT,IAAK,CACvD,MAAMoM,EAAMkT,EAAK,WAAYtf,CAAC,EACxB40B,EACJxoB,EAAI,QACHA,EAAI,QAAU,GAAGA,EAAI,IAAI,IAAIA,EAAI,OAAO,GAAKA,EAAI,MAC9CyoB,EACJzoB,EAAI,OAAS,QAAUrlB,EAAS,MAAQA,EAAS,QACnDwtC,EAAc,KAAK,CACjB,KAAMK,EACN,KAAMC,EACN,MAAO7tC,EAAW,KAClB,UAAW,CAAA,CACZ,CACH,CACF,CAGF,KAAK,MAAM,cAAgButC,EAE3B,MAAM+J,EAAgB,CAAA,EACtB,OAAa,CACX,MAAM9nB,EAASvP,GAAQ,KAAK,MAAO,KAAK,KAAK,KAAMC,CAAQ,EAG3D,IAAIqkC,EAAgB,EACpB,QAAS1kD,EAAI,EAAGA,EAAI,KAAK,MAAM,YAAaA,IAAK,CAC/C,MAAM2kD,EAAS,KAAK,KAAK,KAAK,UAC5BrpD,GAAuBopD,EACvB,EAAA,EAEIE,EAAkBtpD,GAAuBopD,EAAgB,EAEzDplC,EAAStM,GACb06B,EACA,KAAK,KAAK,KACVkX,CAAA,EAEFnN,EAAK,KAAKn4B,CAAM,EAEhBolC,GAAiB,EAAIC,CACvB,CAEA,GAAIh1B,IAAWhwB,EAAS,KACtB,MACF,GAAWgwB,IAAWhwB,EAAS,YAC7B,KAAK,MAAM,aAAe,EAC1B,KAAK,MAAM,YAAc,EACzB,KAAK,MAAM,OAASA,EAAS,gBACpBgwB,IAAWhwB,EAAS,WAAY,CACzC,KAAK,MAAM,aAAe,EAC1B,KAAK,MAAM,YAAc,EAGzB,MAAMklD,EAA8B,CAAA,EAC9BnlD,EAAU,KAAK,MAAM,SAAW,CAAC,KAAK,MAAM,MAAM,EACxD,UAAWO,KAAKP,EACd,GAAIO,GAAKA,EAAE,OAAS,EAAG,CACrB,MAAMsH,EAAI,KAAK,KAAK,gBAAgBtH,EAAE,MAAM,EACxCsH,EAAI,IACN,KAAK,KAAK,QAAQA,CAAC,EACnBs9C,EAAkB,KAAKt9C,CAAC,EAE5B,CAEF,GAAI,CACF,MAAM,KAAK,OAAO,YAAY,KAAK,MAAM,aAAa,CACxD,QAAA,CACE,UAAWA,KAAKs9C,EACd,KAAK,KAAK,UAAUt9C,CAAC,CAEzB,CACA,KAAK,MAAM,OAAS5H,EAAS,OAC/B,KAAA,OAAWgwB,IAAWhwB,EAAS,iBAC7B,KAAK,MAAM,YAAc,EACnB,IAAI0C,IACDstB,IAAWhwB,EAAS,QACvB,IAAIiD,GACD+sB,IAAWhwB,EAAS,iBACvB,IAAIkD,GAEJ,IAAI,MAAM,8BAA8B8sB,CAAM,EAAE,CAE1D,CAEA,cAAO,eAAe8nB,EAAM,mBAAoB,CAC9C,MAAQp3B,EAAiB,kBAAoB,GAC7C,SAAU,GACV,WAAY,GACZ,aAAc,EAAA,CACf,EAEMo3B,CACT,CAOA,MAAM,YAAgD,CACpD,OAAO,KAAK,YAAY,WAAA,CAC1B,CAMA,MAAM,cAAoC,CACxC,OAAO,KAAK,YAAY,WAAW,QAAQ,SAAY,CAChD,KAAK,YAAY,oBACpB,MAAM,KAAK,YAAY,kBAAA,EACvB,MAAM,KAAK,OAAO,cAAA,GAGpB,MAAM0B,EAAY,KAAK,KAAK,gBAAgB,CAAC,EACvC2L,EAAat9B,GAAwB2xB,CAAS,EAC9CzD,EAAM,IAAI,WAAWoP,EAAa,IAAS,EAGjDpP,EAAI,IAAI,KAAK,KAAK,mBAAmB,CAAC,EAAG,CAAC,EAC1C,MAAMqP,EAAe,IAAI,SAASrP,EAAI,OAAQA,EAAI,WAAY,IAAS,EACvE1tB,GAA8B+8B,EAAc,CAAC,EAG7C,QAASzsC,EAAI,EAAGA,GAAKwsC,EAAYxsC,IAAK,CACpC,MAAM1S,GAAU0S,EAAI,GAAK,KACnBpS,EAAQwvC,EAAI,SAAS9vC,EAAQA,EAAS,IAAS,EAC/Co/C,EAAe,KAAK,KAAK,gBAAgB1sC,CAAC,EAEhD,GAAI0sC,IAAiB,GACnB9+C,EAAM,IAAI,KAAK,KAAK,mBAAmB8+C,CAAY,CAAC,UAC3C,KAAK,YAAY,eAAe1sC,CAAC,EAC1CpS,EAAM,IAAI,KAAK,YAAY,eAAeoS,CAAC,CAAE,MACxC,CACL,MAAM2sC,EAAW,MAAM,KAAK,IAAI,SAAS3sC,CAAC,EACtC2sC,GACF/+C,EAAM,IAAI++C,CAAQ,CAEtB,CAGA,MAAMj7C,EAAMtD,GAAoBR,CAAK,EACrC,IAAI,SAASA,EAAM,OAAQA,EAAM,WAAY,IAAS,EAAE,UACtD,GACA8D,EACA,EAAA,CAEJ,CAEA,OAAO0rC,CACT,EAAG,KAAK,gBAAkB,MAAS,CACrC,CAMA,MAAM,aAAajyC,EAA+C,CAChE,GAAI,KAAK,YAAY,kBACnB,MAAM,IAAI,MACR,6DAAA,EAIJ,OAAO,KAAK,YAAY,WAAW,QAAQ,SAAY,CACrD,MAAMwH,EACJxH,aAAgB,WACZ,IAAI,WAAWA,EAAK,OAAQA,EAAK,WAAYA,EAAK,UAAU,EAC5D,IAAI,WAAWA,CAAI,EAGzB,GAAIwH,EAAM,WAAa,MAAaA,EAAM,WAAa,OAAc,EACnE,MAAM,IAAI7I,GACR,iCAAiC6I,EAAM,UAAU,oDAAoD,EAIzG,MAAMi6C,EAAWj6C,EAAM,WAAa,KAC9Bk6C,EAAal6C,EAAM,SAAS,EAAG,IAAS,EACxCkuC,EAAY,IAAI,SACpBgM,EAAW,OACXA,EAAW,WACX,IAAA,EAGIlhD,EAAS8iB,GAA0BoyB,EAAW,EAAI,EACxD,GAAIl1C,EAAO,WAAa,KACtB,MAAM,IAAI7B,GACR,8BAA8B6B,EAAO,QAAQ,kBAAuB,EAGxE,GAAIA,EAAO,aAAeihD,EACxB,MAAM,IAAI9iD,GACR,kDAAkD6B,EAAO,UAAU,qCAAqCihD,CAAQ,QAAA,EAIpH,QAAS5sC,EAAI,EAAGA,GAAK4sC,EAAU5sC,IAAK,CAClC,MAAM1S,GAAU0S,EAAI,GAAK,KACnB8sC,EAAYn6C,EAAM,SAASrF,EAAQA,EAAS,IAAS,EAMrDy/C,EALO,IAAI,SACfD,EAAU,OACVA,EAAU,WACV,IAAA,EAEqB,UAAU,GAAI,EAAI,EACzC,GAAIC,IAAc,EAAG,CACnB,MAAMC,EAAc5+C,GAAoB0+C,CAAS,EACjD,GAAIE,IAAgBD,EAClB,MAAM,IAAI5jD,GAAiB6W,EAAG+sC,EAAWC,CAAW,CAExD,CACF,CAGA,MAAM50B,EAA4D,CAAA,EAClE,QAASpY,EAAI,EAAGA,GAAK4sC,EAAU5sC,IAAK,CAClC,MAAM1S,GAAU0S,EAAI,GAAK,KACzBoY,EAAa,KAAK,CAChB,OAAQpY,EACR,KAAMrN,EAAM,SAASrF,EAAQA,EAAS,IAAS,EAAE,MAAA,CAAM,CACxD,CACH,CAEA,QAASkW,EAAO,EAAGA,EAAO,KAAK,KAAK,UAAWA,IAC7C,KAAK,KAAK,eAAeA,CAAI,EAC7B,KAAK,KAAK,aAAaA,CAAI,EAC3B,KAAK,KAAK,WAAWA,CAAI,EACzB,KAAK,KAAK,mBAAmBA,CAAI,EAAE,KAAK,CAAC,EAG3C,KAAK,KAAK,mBAAmB,CAAC,EAAE,IAAI4U,EAAa,CAAC,EAAE,IAAI,EACxD,KAAK,KAAK,WAAW,CAAC,EAEtB,MAAM,KAAK,IAAI,WAAWA,CAAY,EACtC,MAAM,KAAK,IAAI,MAAA,EACf,MAAM,KAAK,YAAY,oBAAA,EAEvB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,eAAe,MAAA,EACpB,KAAK,MAAM,MAAQ,KAEnB,MAAM2nB,EAAmBjvB,GACvB,KAAK,KAAK,gBAAgB,CAAC,CAAA,EAE7B,UAAWL,KAAQsvB,EAAkB,CACnC,IAAIC,EAAYvvB,EAAK,iBACrB,KAAOuvB,IAAc,GAAG,CACtB,MAAMx8B,EAAO,MAAM,KAAK,OAAO,kBAAkBw8B,CAAS,EACpDnwC,EAAO,KAAK,KAAK,gBAAgB2T,CAAI,EAE3Cw8B,EADkBnuB,GAAyBhiB,EAAM,CAAC,EAC5B,oBACxB,CACF,CACF,CAAC,CACH,CAEA,MAAM,OAAuB,CACvB,KAAK,mBACP,KAAK,iBAAiB,MAAA,EACtB,KAAK,iBAAmB,MAE1B,KAAK,kBAAkB,MAAA,EACvB,KAAK,YAAY,MAAA,EACjB,KAAK,cAAc,MAAA,EACnB,MAAM,KAAK,YAAY,MAAA,EACvB,MAAM,KAAK,OAAO,cAAA,EAClB,MAAM,KAAK,IAAI,MAAA,CACjB,CACF"}