{"version":3,"file":"index.mjs","sources":["../src/storage/node-fs.ts","../src/platform/node.ts","../src/query/schema.ts","../src/query/validate.ts","../src/platform/web.ts","../src/index.ts"],"sourcesContent":["import * as fs from 'fs/promises';\nimport { createReadStream, createWriteStream, WriteStream } from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport { Activity, SessionResource } from '../types.js';\nimport {\n  ActivityStorage,\n  SessionStorage,\n  CachedSession,\n  SessionIndexEntry,\n  SessionMetadata,\n} from './types.js';\n\n/**\n * Node.js filesystem implementation of ActivityStorage.\n * Stores activities in a JSONL file located at `.jules/cache/<sessionId>/activities.jsonl`.\n */\nexport class NodeFileStorage implements ActivityStorage {\n  private filePath: string;\n  private metadataPath: string;\n  private initialized = false;\n  private writeStream: WriteStream | null = null;\n\n  // In-memory index: ActivityID -> Byte Offset\n  private index: Map<string, number> = new Map();\n  private indexBuilt = false;\n  private indexBuildPromise: Promise<void> | null = null;\n\n  // Tracks the current file size to calculate offsets for new appends\n  private currentFileSize = 0;\n\n  constructor(sessionId: string, rootDir: string) {\n    const sessionCacheDir = path.resolve(rootDir, '.jules/cache', sessionId);\n    this.filePath = path.join(sessionCacheDir, 'activities.jsonl');\n    this.metadataPath = path.join(sessionCacheDir, 'metadata.json');\n  }\n\n  /**\n   * Initializes the storage by ensuring the cache directory exists.\n   *\n   * **Side Effects:**\n   * - Creates the `.jules/cache/<sessionId>` directory if it does not exist.\n   * - Sets the internal `initialized` flag.\n   */\n  async init(): Promise<void> {\n    if (this.initialized) return;\n    // Ensure the cache directory exists before we ever try to read/write\n    await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n\n    // Initialize currentFileSize for accurate append offsets\n    try {\n      const stats = await fs.stat(this.filePath);\n      this.currentFileSize = stats.size;\n    } catch (e: any) {\n      if (e.code === 'ENOENT') {\n        this.currentFileSize = 0;\n      } else {\n        throw e;\n      }\n    }\n\n    // Open a persistent write stream for efficient appending\n    this.writeStream = createWriteStream(this.filePath, {\n      flags: 'a',\n      encoding: 'utf8',\n    });\n\n    // Prevent process crash on stream error\n    this.writeStream.on('error', (err) => {\n      console.error(\n        `[NodeFileStorage] WriteStream error for ${this.filePath}:`,\n        err,\n      );\n      // We might want to set initialized = false or nullify stream,\n      // but for now, logging prevents the crash.\n    });\n\n    this.initialized = true;\n  }\n\n  /**\n   * Closes the storage.\n   */\n  async close(): Promise<void> {\n    if (this.writeStream) {\n      await new Promise<void>((resolve) => this.writeStream!.end(resolve));\n      this.writeStream = null;\n    }\n    this.initialized = false;\n    this.indexBuilt = false;\n    this.index.clear();\n    // We do not await indexBuildPromise as we are closing.\n    this.indexBuildPromise = null;\n  }\n\n  private async _readMetadata(): Promise<SessionMetadata> {\n    try {\n      const content = await fs.readFile(this.metadataPath, 'utf8');\n      return JSON.parse(content) as SessionMetadata;\n    } catch (e: any) {\n      if (e.code === 'ENOENT') {\n        return { activityCount: 0 }; // Default if file doesn't exist\n      }\n      throw e;\n    }\n  }\n\n  private async _writeMetadata(metadata: SessionMetadata): Promise<void> {\n    await fs.writeFile(\n      this.metadataPath,\n      JSON.stringify(metadata, null, 2),\n      'utf8',\n    );\n  }\n\n  /**\n   * Appends an activity to the file.\n   *\n   * **Side Effects:**\n   * - Appends a new line containing the JSON representation of the activity to `activities.jsonl`.\n   * - Implicitly calls `init()` if not already initialized.\n   */\n  async append(activity: Activity): Promise<void> {\n    // Safety check: ensure init() was called if the user forgot\n    if (!this.initialized) await this.init();\n\n    // 1. Atomically update metadata\n    const metadata = await this._readMetadata();\n    metadata.activityCount += 1;\n    await this._writeMetadata(metadata);\n\n    // 2. Append the activity\n    const line = JSON.stringify(activity) + '\\n';\n    const startOffset = this.currentFileSize;\n\n    // Write to stream. Handle backpressure if necessary.\n    if (this.writeStream) {\n      const canContinue = this.writeStream.write(line);\n      this.currentFileSize += Buffer.byteLength(line);\n\n      // Concurrency Handling:\n      // Update the index if it's already built or if a build is in progress.\n      // This optimistic update ensures the new activity is indexed even if the\n      // background scan (buildIndex) misses it due to race conditions.\n      if (this.indexBuilt || this.indexBuildPromise) {\n        if (!this.index.has(activity.id)) {\n          this.index.set(activity.id, startOffset);\n        }\n      }\n\n      if (!canContinue) {\n        await new Promise<void>((resolve) =>\n          this.writeStream!.once('drain', resolve),\n        );\n      }\n    } else {\n      throw new Error('NodeFileStorage: WriteStream is not initialized');\n    }\n  }\n\n  /**\n   * Builds the in-memory index by scanning the file once.\n   * Handles concurrency by coalescing multiple calls into a single promise.\n   */\n  private async buildIndex(): Promise<void> {\n    if (this.indexBuilt) return;\n    if (this.indexBuildPromise) return this.indexBuildPromise;\n\n    this.indexBuildPromise = (async () => {\n      try {\n        this.index.clear();\n\n        try {\n          await fs.access(this.filePath);\n        } catch (e) {\n          // File doesn't exist, index is empty but built\n          this.indexBuilt = true;\n          return;\n        }\n\n        const fileStream = createReadStream(this.filePath, {\n          encoding: 'utf8',\n        });\n        const rl = readline.createInterface({\n          input: fileStream,\n          crlfDelay: Infinity,\n        });\n\n        let currentOffset = 0;\n        for await (const line of rl) {\n          const byteLen = Buffer.byteLength(line);\n          // readline strips \\n or \\r\\n. We assume \\n (1 byte) as we write it.\n          const lineTotalBytes = byteLen + 1;\n\n          if (line.trim().length > 0) {\n            try {\n              const activity = JSON.parse(line) as Activity;\n              if (!this.index.has(activity.id)) {\n                this.index.set(activity.id, currentOffset);\n              }\n            } catch (e) {\n              // Ignore corrupt lines\n            }\n          }\n          currentOffset += lineTotalBytes;\n        }\n\n        this.indexBuilt = true;\n      } finally {\n        this.indexBuildPromise = null;\n      }\n    })();\n\n    return this.indexBuildPromise;\n  }\n\n  /**\n   * Retrieves an activity by ID.\n   * Uses an in-memory index (ID -> Offset) to seek directly to the line.\n   */\n  async get(activityId: string): Promise<Activity | undefined> {\n    if (!this.initialized) await this.init();\n    if (!this.indexBuilt) await this.buildIndex();\n\n    const offset = this.index.get(activityId);\n    if (offset === undefined) return undefined;\n\n    return new Promise((resolve, reject) => {\n      // Create a stream starting at the exact offset\n      const stream = createReadStream(this.filePath, {\n        start: offset,\n        encoding: 'utf8',\n      });\n      const rl = readline.createInterface({\n        input: stream,\n        crlfDelay: Infinity,\n      });\n\n      let found = false;\n      rl.on('line', (line) => {\n        if (found) return; // Prevent double firing\n        found = true;\n\n        // We only needed the first line\n        rl.close();\n        stream.destroy();\n\n        try {\n          const activity = JSON.parse(line) as Activity;\n          resolve(activity);\n        } catch (e) {\n          // If the indexed line is corrupt (shouldn't happen if buildIndex verified it)\n          resolve(undefined);\n        }\n      });\n\n      rl.on('error', (err) => {\n        reject(err);\n      });\n\n      stream.on('error', (err) => {\n        reject(err);\n      });\n\n      // Handle case where stream ends without yielding a line (e.g., EOF right at offset)\n      rl.on('close', () => {\n        if (!found) resolve(undefined);\n      });\n    });\n  }\n\n  /**\n   * Retrieves the latest activity.\n   * Efficiently reads the file backwards to find the last valid entry.\n   */\n  async latest(): Promise<Activity | undefined> {\n    if (!this.initialized) await this.init();\n\n    try {\n      await fs.access(this.filePath);\n    } catch (e) {\n      if ((e as any).code === 'ENOENT') {\n        return undefined; // File doesn't exist\n      }\n      throw e;\n    }\n\n    // Optimization: Read backward from the end of the file.\n    // This is significantly faster than scanning the entire file for large logs.\n    const stat = await fs.stat(this.filePath);\n    const fileSize = stat.size;\n\n    if (fileSize === 0) return undefined;\n\n    // We'll read in chunks from the end.\n    // 4KB is typically enough for several activity lines.\n    const bufferSize = 4096;\n    const buffer = Buffer.alloc(bufferSize);\n    let fd: fs.FileHandle | undefined;\n\n    try {\n      fd = await fs.open(this.filePath, 'r');\n      let currentPos = fileSize;\n      let trailing = ''; // To hold parts of lines from previous chunks\n\n      while (currentPos > 0) {\n        const readSize = Math.min(bufferSize, currentPos);\n        const position = currentPos - readSize;\n\n        const result = await fd.read(buffer, 0, readSize, position);\n        const chunk = result.buffer.toString('utf8', 0, readSize);\n\n        // Prepend previous trailing content\n        const content = chunk + trailing;\n\n        // Split by newline\n        const lines = content.split('\\n');\n\n        // The last part might be an incomplete line (start of a line),\n        // so it becomes the 'trailing' part for the next iteration (reading earlier).\n        // Exception: if currentPos was 0, we read the start of the file, so the first part is a valid start.\n        if (position > 0) {\n          trailing = lines.shift() || ''; // The first element is the partial line at the end of the *previous* chunk (start of this chunk's content)\n        } else {\n          // We are at the start of the file, so the first element is a complete line\n          trailing = '';\n        }\n\n        // Iterate lines from end to start\n        for (let i = lines.length - 1; i >= 0; i--) {\n          const line = lines[i].trim();\n          if (line.length === 0) continue;\n\n          try {\n            return JSON.parse(line) as Activity;\n          } catch (e) {\n            console.warn(\n              `[NodeFileStorage] Corrupt JSON line ignored during latest() check in ${this.filePath}`,\n            );\n            // Continue searching backwards\n          }\n        }\n\n        currentPos -= readSize;\n      }\n    } finally {\n      if (fd) await fd.close();\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Yields all activities in the file.\n   *\n   * **Behavior:**\n   * - Opens a read stream to `activities.jsonl`.\n   * - Reads line-by-line using `readline`.\n   * - Parses each line as JSON.\n   *\n   * **Edge Cases:**\n   * - Logs a warning and skips lines if JSON parsing fails (corrupt data).\n   * - Returns immediately (yields nothing) if the file does not exist.\n   */\n  async *scan(): AsyncIterable<Activity> {\n    if (!this.initialized) await this.init();\n\n    try {\n      await fs.access(this.filePath);\n    } catch (e) {\n      if ((e as any).code === 'ENOENT') {\n        return; // File doesn't exist, yield nothing.\n      }\n      throw e;\n    }\n\n    const fileStream = createReadStream(this.filePath, { encoding: 'utf8' });\n    const rl = readline.createInterface({\n      input: fileStream,\n      crlfDelay: Infinity,\n    });\n\n    for await (const line of rl) {\n      if (line.trim().length === 0) continue;\n      try {\n        yield JSON.parse(line) as Activity;\n      } catch (e) {\n        console.warn(\n          `[NodeFileStorage] Corrupt JSON line ignored in ${this.filePath}`,\n        );\n      }\n    }\n  }\n}\n\nexport class NodeSessionStorage implements SessionStorage {\n  private cacheDir: string;\n  private indexFilePath: string;\n  private initialized = false;\n\n  constructor(rootDir: string) {\n    this.cacheDir = path.resolve(rootDir, '.jules/cache');\n    this.indexFilePath = path.join(this.cacheDir, 'sessions.jsonl');\n  }\n\n  async init(): Promise<void> {\n    if (this.initialized) return;\n    await fs.mkdir(this.cacheDir, { recursive: true });\n    this.initialized = true;\n  }\n\n  private getSessionPath(sessionId: string): string {\n    return path.join(this.cacheDir, sessionId, 'session.json');\n  }\n\n  async upsert(session: SessionResource): Promise<void> {\n    await this.init();\n\n    // 1. Write the Atomic \"Source of Truth\"\n    const sessionDir = path.join(this.cacheDir, session.id);\n    await fs.mkdir(sessionDir, { recursive: true });\n\n    const cached: CachedSession = {\n      resource: session,\n      _lastSyncedAt: Date.now(),\n    };\n\n    // Write atomically (JSON.stringify is fast for single sessions)\n    await fs.writeFile(\n      path.join(sessionDir, 'session.json'),\n      JSON.stringify(cached, null, 2),\n      'utf8',\n    );\n\n    // 2. Update the High-Speed Index (Append-Only)\n    // We strictly append. The reader is responsible for deduplication.\n    const indexEntry: SessionIndexEntry = {\n      id: session.id,\n      title: session.title,\n      state: session.state,\n      createTime: session.createTime,\n      source: session.sourceContext?.source || 'unknown',\n      _updatedAt: Date.now(),\n    };\n\n    await fs.appendFile(\n      this.indexFilePath,\n      JSON.stringify(indexEntry) + '\\n',\n      'utf8',\n    );\n  }\n\n  async upsertMany(sessions: SessionResource[]): Promise<void> {\n    // Parallelize file writes, sequentialize index write\n    await Promise.all(sessions.map((s) => this.upsert(s)));\n  }\n\n  async get(sessionId: string): Promise<CachedSession | undefined> {\n    await this.init();\n    try {\n      const data = await fs.readFile(this.getSessionPath(sessionId), 'utf8');\n      return JSON.parse(data) as CachedSession;\n    } catch (e: any) {\n      if (e.code === 'ENOENT') return undefined;\n      throw e;\n    }\n  }\n\n  async delete(sessionId: string): Promise<void> {\n    await this.init();\n    // 1. Remove the directory (Metadata + Activities + Artifacts)\n    const sessionDir = path.join(this.cacheDir, sessionId);\n    await fs.rm(sessionDir, { recursive: true, force: true });\n\n    // 2. We do NOT rewrite the index here for performance.\n    // The \"Get\" method will return 404 (undefined) which is the ultimate check.\n    // Periodic compaction can clean the index later.\n  }\n\n  async *scanIndex(): AsyncIterable<SessionIndexEntry> {\n    await this.init();\n\n    // Read the raw stream\n    // Note: In Phase 3 (Query Planner), we will optimize this to read backward\n    // or keep an in-memory map to dedupe instantly.\n    try {\n      const fileStream = createReadStream(this.indexFilePath, {\n        encoding: 'utf8',\n      });\n      const rl = readline.createInterface({\n        input: fileStream,\n        crlfDelay: Infinity,\n      });\n\n      // Deduplication Map: ID -> Entry\n      const entries = new Map<string, SessionIndexEntry>();\n\n      for await (const line of rl) {\n        if (!line.trim()) continue;\n        try {\n          const entry = JSON.parse(line) as SessionIndexEntry;\n          entries.set(entry.id, entry);\n        } catch (e) {\n          /* ignore corrupt lines */\n        }\n      }\n\n      for (const entry of entries.values()) {\n        yield entry;\n      }\n    } catch (e: any) {\n      if (e.code === 'ENOENT') return; // No index yet\n      throw e;\n    }\n  }\n}\n","import { writeFile, readFile, rm } from 'node:fs/promises';\nimport { Buffer } from 'node:buffer';\nimport { setTimeout } from 'node:timers/promises';\nimport * as crypto from 'node:crypto';\nimport { Platform, PlatformResponse } from './types.js';\n\n/**\n * Node.js implementation of the Platform interface.\n */\nexport class NodePlatform implements Platform {\n  /**\n   * Saves a file to the local filesystem using `node:fs/promises`.\n   *\n   * **Side Effects:**\n   * - Writes a file to disk.\n   * - Overwrites the file if it already exists.\n   */\n  async saveFile(\n    filepath: string,\n    data: string,\n    encoding: 'base64',\n    activityId?: string, // unused in Node.js, standard filesystem doesn't support this metadata easily\n  ): Promise<void> {\n    const buffer = Buffer.from(data, encoding);\n    await writeFile(filepath, buffer);\n  }\n\n  async sleep(ms: number): Promise<void> {\n    await setTimeout(ms);\n  }\n\n  createDataUrl(data: string, mimeType: string): string {\n    return `data:${mimeType};base64,${data}`;\n  }\n\n  async fetch(input: string, init?: any): Promise<PlatformResponse> {\n    const res = await global.fetch(input, init);\n    return {\n      ok: res.ok,\n      status: res.status,\n      json: () => res.json(),\n      text: () => res.text(),\n    };\n  }\n\n  crypto = {\n    randomUUID: () => crypto.randomUUID(),\n\n    async sign(text: string, secret: string): Promise<string> {\n      const hmac = crypto.createHmac('sha256', secret);\n      hmac.update(text);\n      return hmac.digest('base64url');\n    },\n\n    async verify(\n      text: string,\n      signature: string,\n      secret: string,\n    ): Promise<boolean> {\n      const expected = await this.sign(text, secret);\n      // Use timingSafeEqual to prevent timing attacks\n      const a = Buffer.from(expected);\n      const b = Buffer.from(signature);\n      return a.length === b.length && crypto.timingSafeEqual(a, b);\n    },\n  };\n\n  encoding = {\n    base64Encode: (text: string): string => {\n      return Buffer.from(text).toString('base64url');\n    },\n\n    base64Decode: (text: string): string => {\n      return Buffer.from(text, 'base64url').toString('utf-8');\n    },\n  };\n\n  getEnv(key: string): string | undefined {\n    return process.env[key];\n  }\n\n  async readFile(path: string): Promise<string> {\n    return readFile(path, 'utf-8');\n  }\n\n  async writeFile(path: string, content: string): Promise<void> {\n    await writeFile(path, content, 'utf-8');\n  }\n\n  async deleteFile(path: string): Promise<void> {\n    await rm(path, { force: true });\n  }\n}\n","/**\n * Schema Introspection for Jules Query Language\n *\n * Provides TypeScript type definitions and field metadata for LLM discoverability.\n * These schemas help LLMs understand the shape of Session, Activity, and related types\n * to translate natural language queries into proper JQL.\n */\n\n/**\n * Field metadata for schema introspection\n */\nexport interface FieldMeta {\n  /** Field name */\n  name: string;\n  /** TypeScript type representation */\n  type: string;\n  /** Human-readable description */\n  description: string;\n  /** Whether field is optional */\n  optional?: boolean;\n  /** Whether field is computed (not stored, derived at query time) */\n  computed?: boolean;\n  /** Whether field can be filtered in where clause */\n  filterable?: boolean;\n  /** Whether field can be used in select projection */\n  selectable?: boolean;\n  /** Nested fields if this is an object or array type */\n  fields?: FieldMeta[];\n}\n\n/**\n * Schema definition for a domain\n */\nexport interface DomainSchema {\n  /** Domain name */\n  domain: 'sessions' | 'activities';\n  /** Human-readable description */\n  description: string;\n  /** All fields in this domain */\n  fields: FieldMeta[];\n  /** Example queries for this domain */\n  examples: QueryExample[];\n}\n\n/**\n * Example query for documentation\n */\nexport interface QueryExample {\n  /** Natural language description */\n  description: string;\n  /** JQL query */\n  query: Record<string, unknown>;\n}\n\n/**\n * Schema for SessionResource\n */\nexport const SESSION_SCHEMA: DomainSchema = {\n  domain: 'sessions',\n  description:\n    'A Jules session representing a task or conversation with the agent',\n  fields: [\n    {\n      name: 'id',\n      type: 'string',\n      description: 'Unique session identifier',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'name',\n      type: 'string',\n      description: 'Full resource name (e.g., \"sessions/314159...\")',\n      selectable: true,\n    },\n    {\n      name: 'title',\n      type: 'string',\n      description: 'Human-readable session title',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'prompt',\n      type: 'string',\n      description: 'The initial instruction or task description',\n      selectable: true,\n    },\n    {\n      name: 'state',\n      type: 'SessionState',\n      description:\n        'Current session state: \"queued\" | \"planning\" | \"awaitingPlanApproval\" | \"awaitingUserFeedback\" | \"inProgress\" | \"paused\" | \"failed\" | \"completed\"',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'createTime',\n      type: 'string',\n      description: 'RFC 3339 timestamp when session was created',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'updateTime',\n      type: 'string',\n      description: 'RFC 3339 timestamp when session was last updated',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'url',\n      type: 'string',\n      description: 'URL to view the session in the Jules web app',\n      selectable: true,\n    },\n    {\n      name: 'durationMs',\n      type: 'number',\n      description: 'Duration in milliseconds (updateTime - createTime)',\n      computed: true,\n      selectable: true,\n    },\n    {\n      name: 'sourceContext',\n      type: 'SourceContext',\n      description: 'The source code context (repository, branch)',\n      selectable: true,\n      fields: [\n        {\n          name: 'source',\n          type: 'string',\n          description: 'Source name (e.g., \"sources/github/owner/repo\")',\n          selectable: true,\n        },\n        {\n          name: 'githubRepoContext',\n          type: 'object',\n          description: 'GitHub-specific context',\n          optional: true,\n          selectable: true,\n          fields: [\n            {\n              name: 'startingBranch',\n              type: 'string',\n              description: 'The branch the session started from',\n              selectable: true,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      name: 'outputs',\n      type: 'SessionOutput[]',\n      description: 'Outputs generated by the session (e.g., pull requests)',\n      selectable: true,\n      fields: [\n        {\n          name: 'type',\n          type: '\"pullRequest\"',\n          description: 'Output type discriminator',\n          selectable: true,\n        },\n        {\n          name: 'pullRequest',\n          type: 'PullRequest',\n          description: 'Pull request details',\n          selectable: true,\n          fields: [\n            {\n              name: 'url',\n              type: 'string',\n              description: 'PR URL',\n              selectable: true,\n            },\n            {\n              name: 'title',\n              type: 'string',\n              description: 'PR title',\n              selectable: true,\n            },\n            {\n              name: 'description',\n              type: 'string',\n              description: 'PR description',\n              selectable: true,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      name: 'outcome',\n      type: 'object',\n      description: 'Final outcome if session is in terminal state',\n      optional: true,\n      selectable: true,\n      fields: [\n        {\n          name: 'status',\n          type: '\"SUCCESS\" | \"FAILURE\"',\n          description: 'Outcome status',\n          selectable: true,\n        },\n        {\n          name: 'summary',\n          type: 'string',\n          description: 'Human-readable outcome summary',\n          selectable: true,\n        },\n      ],\n    },\n  ],\n  examples: [\n    {\n      description: 'Get all completed sessions',\n      query: {\n        from: 'sessions',\n        where: { state: 'completed' },\n        select: ['id', 'title', 'createTime'],\n      },\n    },\n    {\n      description: 'Find sessions with PR output',\n      query: {\n        from: 'sessions',\n        where: { 'outputs.type': 'pullRequest' },\n        select: ['id', 'title', 'outputs.pullRequest.url'],\n      },\n    },\n    {\n      description: 'Get session with all activities',\n      query: {\n        from: 'sessions',\n        where: { id: 'SESSION_ID' },\n        include: { activities: true },\n      },\n    },\n  ],\n};\n\n/**\n * Schema for Activity types\n */\nexport const ACTIVITY_SCHEMA: DomainSchema = {\n  domain: 'activities',\n  description: 'An event or action within a session',\n  fields: [\n    {\n      name: 'id',\n      type: 'string',\n      description: 'Unique activity identifier',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'name',\n      type: 'string',\n      description: 'Full resource name',\n      selectable: true,\n    },\n    {\n      name: 'type',\n      type: 'ActivityType',\n      description:\n        'Activity type: \"agentMessaged\" | \"userMessaged\" | \"planGenerated\" | \"planApproved\" | \"progressUpdated\" | \"sessionCompleted\" | \"sessionFailed\"',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'createTime',\n      type: 'string',\n      description: 'RFC 3339 timestamp when activity was created',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'originator',\n      type: '\"user\" | \"agent\" | \"system\"',\n      description: 'Entity that originated this activity',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'sessionId',\n      type: 'string',\n      description: 'ID of the parent session',\n      filterable: true,\n      selectable: true,\n    },\n    {\n      name: 'artifactCount',\n      type: 'number',\n      description: 'Number of artifacts in this activity',\n      computed: true,\n      selectable: true,\n    },\n    {\n      name: 'summary',\n      type: 'string',\n      description: 'Human-readable summary of the activity',\n      computed: true,\n      selectable: true,\n    },\n    // Type-specific fields\n    {\n      name: 'message',\n      type: 'string',\n      description: 'Message content (for agentMessaged, userMessaged)',\n      optional: true,\n      selectable: true,\n    },\n    {\n      name: 'plan',\n      type: 'Plan',\n      description: 'Generated plan (for planGenerated)',\n      optional: true,\n      selectable: true,\n      fields: [\n        {\n          name: 'id',\n          type: 'string',\n          description: 'Plan ID',\n          selectable: true,\n        },\n        {\n          name: 'createTime',\n          type: 'string',\n          description: 'Plan creation time',\n          selectable: true,\n        },\n        {\n          name: 'steps',\n          type: 'PlanStep[]',\n          description: 'Plan steps',\n          selectable: true,\n          fields: [\n            {\n              name: 'id',\n              type: 'string',\n              description: 'Step ID',\n              selectable: true,\n            },\n            {\n              name: 'title',\n              type: 'string',\n              description: 'Step title',\n              selectable: true,\n            },\n            {\n              name: 'description',\n              type: 'string',\n              description: 'Step description',\n              optional: true,\n              selectable: true,\n            },\n            {\n              name: 'index',\n              type: 'number',\n              description: 'Step index',\n              selectable: true,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      name: 'planId',\n      type: 'string',\n      description: 'ID of approved plan (for planApproved)',\n      optional: true,\n      selectable: true,\n    },\n    {\n      name: 'title',\n      type: 'string',\n      description: 'Progress title (for progressUpdated)',\n      optional: true,\n      selectable: true,\n    },\n    {\n      name: 'description',\n      type: 'string',\n      description: 'Progress description (for progressUpdated)',\n      optional: true,\n      selectable: true,\n    },\n    {\n      name: 'reason',\n      type: 'string',\n      description: 'Failure reason (for sessionFailed)',\n      optional: true,\n      selectable: true,\n    },\n    {\n      name: 'artifacts',\n      type: 'Artifact[]',\n      description: 'Artifacts produced by this activity',\n      selectable: true,\n      fields: [\n        {\n          name: 'type',\n          type: '\"changeSet\" | \"media\" | \"bashOutput\"',\n          description: 'Artifact type discriminator',\n          filterable: true,\n          selectable: true,\n        },\n        {\n          name: 'changeSet',\n          type: 'ChangeSet',\n          description: 'Code changes (for changeSet type)',\n          optional: true,\n          selectable: true,\n          fields: [\n            {\n              name: 'source',\n              type: 'string',\n              description: 'Source name',\n              selectable: true,\n            },\n            {\n              name: 'gitPatch',\n              type: 'GitPatch',\n              description: 'Git patch data',\n              selectable: true,\n              fields: [\n                {\n                  name: 'unidiffPatch',\n                  type: 'string',\n                  description: 'Unidiff patch content',\n                  selectable: true,\n                },\n                {\n                  name: 'baseCommitId',\n                  type: 'string',\n                  description: 'Base commit SHA',\n                  selectable: true,\n                },\n                {\n                  name: 'suggestedCommitMessage',\n                  type: 'string',\n                  description: 'Suggested commit message',\n                  selectable: true,\n                },\n              ],\n            },\n          ],\n        },\n        {\n          name: 'command',\n          type: 'string',\n          description: 'Bash command executed (for bashOutput type)',\n          optional: true,\n          filterable: true,\n          selectable: true,\n        },\n        {\n          name: 'stdout',\n          type: 'string',\n          description: 'Standard output (for bashOutput type)',\n          optional: true,\n          selectable: true,\n        },\n        {\n          name: 'stderr',\n          type: 'string',\n          description: 'Standard error (for bashOutput type)',\n          optional: true,\n          selectable: true,\n        },\n        {\n          name: 'exitCode',\n          type: 'number | null',\n          description: 'Exit code (for bashOutput type)',\n          optional: true,\n          filterable: true,\n          selectable: true,\n        },\n        {\n          name: 'data',\n          type: 'string',\n          description:\n            'Base64 media data (for media type) - typically excluded',\n          optional: true,\n          selectable: true,\n        },\n        {\n          name: 'format',\n          type: 'string',\n          description: 'Media format (for media type)',\n          optional: true,\n          selectable: true,\n        },\n      ],\n    },\n  ],\n  examples: [\n    {\n      description: 'Get all plan generations from a session',\n      query: {\n        from: 'activities',\n        where: { sessionId: 'SESSION_ID', type: 'planGenerated' },\n        select: ['id', 'createTime', 'plan.steps.title'],\n      },\n    },\n    {\n      description: 'Find activities with bash commands that failed',\n      query: {\n        from: 'activities',\n        where: {\n          'artifacts.type': 'bashOutput',\n          'artifacts.exitCode': { neq: 0 },\n        },\n        select: [\n          'id',\n          'artifacts.command',\n          'artifacts.exitCode',\n          'artifacts.stderr',\n        ],\n      },\n    },\n    {\n      description: 'Get agent messages with their artifacts',\n      query: {\n        from: 'activities',\n        where: { type: 'agentMessaged' },\n        select: ['id', 'message', 'artifactCount', 'artifacts.type'],\n      },\n    },\n    {\n      description: 'Find activities with code changes',\n      query: {\n        from: 'activities',\n        where: { 'artifacts.type': 'changeSet' },\n        select: [\n          'id',\n          'createTime',\n          'artifacts.changeSet.gitPatch.suggestedCommitMessage',\n        ],\n      },\n    },\n  ],\n};\n\n/**\n * FilterOp schema for where clause operators\n */\nexport const FILTER_OP_SCHEMA = {\n  description: 'Filter operators for where clause',\n  operators: [\n    {\n      name: 'eq',\n      description: 'Equals (also supports direct value)',\n      example: '{ id: \"abc\" } or { id: { eq: \"abc\" } }',\n    },\n    {\n      name: 'neq',\n      description: 'Not equals',\n      example: '{ state: { neq: \"failed\" } }',\n    },\n    {\n      name: 'contains',\n      description: 'Case-insensitive substring match',\n      example: '{ title: { contains: \"bug\" } }',\n    },\n    {\n      name: 'gt',\n      description: 'Greater than',\n      example: '{ createTime: { gt: \"2024-01-01\" } }',\n    },\n    {\n      name: 'lt',\n      description: 'Less than',\n      example: '{ createTime: { lt: \"2024-12-31\" } }',\n    },\n    {\n      name: 'gte',\n      description: 'Greater than or equal',\n      example: '{ artifactCount: { gte: 1 } }',\n    },\n    {\n      name: 'lte',\n      description: 'Less than or equal',\n      example: '{ artifactCount: { lte: 10 } }',\n    },\n    {\n      name: 'in',\n      description: 'Value in array',\n      example: '{ state: { in: [\"completed\", \"failed\"] } }',\n    },\n    {\n      name: 'exists',\n      description: 'Field existence check',\n      example: '{ \"outputs.pullRequest\": { exists: true } }',\n    },\n  ],\n  dotNotation: {\n    description:\n      'Use dot notation for nested field paths. When filtering arrays, uses existential matching (ANY element matches).',\n    examples: [\n      '\"artifacts.type\": \"bashOutput\"',\n      '\"artifacts.exitCode\": { neq: 0 }',\n      '\"plan.steps.title\": { contains: \"test\" }',\n      '\"outputs.pullRequest.url\": { exists: true }',\n    ],\n  },\n};\n\n/**\n * Projection schema for select clause\n */\nexport const PROJECTION_SCHEMA = {\n  description: 'Select clause projection syntax',\n  syntax: [\n    {\n      name: 'Field selection',\n      description: 'Include specific fields',\n      example: '[\"id\", \"title\", \"state\"]',\n    },\n    {\n      name: 'Dot notation',\n      description: 'Select nested fields',\n      example: '[\"id\", \"artifacts.type\", \"artifacts.command\"]',\n    },\n    {\n      name: 'Wildcard',\n      description: 'Include all fields',\n      example: '[\"*\"]',\n    },\n    {\n      name: 'Exclusion',\n      description: 'Exclude specific fields (use with wildcard)',\n      example: '[\"*\", \"-artifacts.data\"]',\n    },\n  ],\n  defaults: {\n    sessions: ['id', 'state', 'title', 'createTime'],\n    activities: [\n      'id',\n      'type',\n      'createTime',\n      'originator',\n      'artifactCount',\n      'summary',\n    ],\n  },\n};\n\n/**\n * Get the full schema for a domain\n */\nexport function getSchema(domain: 'sessions' | 'activities'): DomainSchema {\n  return domain === 'sessions' ? SESSION_SCHEMA : ACTIVITY_SCHEMA;\n}\n\n/**\n * Get all schemas with filter and projection documentation\n */\nexport function getAllSchemas(): {\n  sessions: DomainSchema;\n  activities: DomainSchema;\n  filterOps: typeof FILTER_OP_SCHEMA;\n  projection: typeof PROJECTION_SCHEMA;\n} {\n  return {\n    sessions: SESSION_SCHEMA,\n    activities: ACTIVITY_SCHEMA,\n    filterOps: FILTER_OP_SCHEMA,\n    projection: PROJECTION_SCHEMA,\n  };\n}\n\n/**\n * Generate TypeScript type definition string for a domain\n */\nexport function generateTypeDefinition(\n  domain: 'sessions' | 'activities',\n): string {\n  const schema = getSchema(domain);\n  const lines: string[] = [];\n\n  lines.push(`/**`);\n  lines.push(` * ${schema.description}`);\n  lines.push(` */`);\n\n  const typeName = domain === 'sessions' ? 'SessionResource' : 'Activity';\n  lines.push(`interface ${typeName} {`);\n\n  for (const field of schema.fields) {\n    const optional = field.optional ? '?' : '';\n    const computed = field.computed ? ' // computed' : '';\n    lines.push(`  /** ${field.description} */`);\n    lines.push(`  ${field.name}${optional}: ${field.type};${computed}`);\n  }\n\n  lines.push(`}`);\n\n  return lines.join('\\n');\n}\n\n/**\n * Generate markdown documentation for LLM consumption\n */\nexport function generateMarkdownDocs(): string {\n  const lines: string[] = [];\n\n  lines.push('# Jules Query Language (JQL) Schema Reference\\n');\n\n  // Sessions\n  lines.push('## Sessions Domain\\n');\n  lines.push(SESSION_SCHEMA.description + '\\n');\n  lines.push('### Fields\\n');\n  lines.push('| Field | Type | Description | Filterable |');\n  lines.push('|-------|------|-------------|------------|');\n  for (const field of SESSION_SCHEMA.fields) {\n    const filterable = field.filterable ? 'Yes' : 'No';\n    const computed = field.computed ? ' (computed)' : '';\n    lines.push(\n      `| ${field.name} | ${field.type}${computed} | ${field.description} | ${filterable} |`,\n    );\n  }\n\n  // Activities\n  lines.push('\\n## Activities Domain\\n');\n  lines.push(ACTIVITY_SCHEMA.description + '\\n');\n  lines.push('### Fields\\n');\n  lines.push('| Field | Type | Description | Filterable |');\n  lines.push('|-------|------|-------------|------------|');\n  for (const field of ACTIVITY_SCHEMA.fields) {\n    const filterable = field.filterable ? 'Yes' : 'No';\n    const computed = field.computed ? ' (computed)' : '';\n    lines.push(\n      `| ${field.name} | ${field.type}${computed} | ${field.description} | ${filterable} |`,\n    );\n  }\n\n  // Filter Operators\n  lines.push('\\n## Filter Operators\\n');\n  for (const op of FILTER_OP_SCHEMA.operators) {\n    lines.push(`- **${op.name}**: ${op.description}`);\n    lines.push(`  - Example: \\`${op.example}\\``);\n  }\n\n  // Dot Notation\n  lines.push('\\n### Dot Notation\\n');\n  lines.push(FILTER_OP_SCHEMA.dotNotation.description + '\\n');\n  lines.push('Examples:');\n  for (const ex of FILTER_OP_SCHEMA.dotNotation.examples) {\n    lines.push(`- \\`${ex}\\``);\n  }\n\n  // Projection\n  lines.push('\\n## Projection (Select)\\n');\n  for (const syntax of PROJECTION_SCHEMA.syntax) {\n    lines.push(`- **${syntax.name}**: ${syntax.description}`);\n    lines.push(`  - Example: \\`${syntax.example}\\``);\n  }\n\n  // Examples\n  lines.push('\\n## Query Examples\\n');\n  lines.push('### Sessions');\n  for (const ex of SESSION_SCHEMA.examples) {\n    lines.push(`\\n**${ex.description}**`);\n    lines.push('```json');\n    lines.push(JSON.stringify(ex.query, null, 2));\n    lines.push('```');\n  }\n\n  lines.push('\\n### Activities');\n  for (const ex of ACTIVITY_SCHEMA.examples) {\n    lines.push(`\\n**${ex.description}**`);\n    lines.push('```json');\n    lines.push(JSON.stringify(ex.query, null, 2));\n    lines.push('```');\n  }\n\n  return lines.join('\\n');\n}\n","/**\n * Query Validator for Jules Query Language\n *\n * Validates queries before execution, providing actionable error messages\n * for LLMs to self-correct their queries.\n */\n\nimport {\n  SESSION_SCHEMA,\n  ACTIVITY_SCHEMA,\n  FILTER_OP_SCHEMA,\n  FieldMeta,\n} from './schema.js';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface ValidationError {\n  /** Error code for programmatic handling */\n  code: ValidationErrorCode;\n  /** JSON path to the error location (e.g., \"where.artifacts.type\") */\n  path: string;\n  /** Human-readable error message */\n  message: string;\n  /** Suggested fix or valid alternatives */\n  suggestion?: string;\n}\n\nexport interface ValidationWarning {\n  /** Warning code */\n  code: string;\n  /** JSON path to the warning location */\n  path: string;\n  /** Human-readable warning message */\n  message: string;\n}\n\nexport interface ValidationResult {\n  /** Whether the query is valid */\n  valid: boolean;\n  /** Validation errors (if any) */\n  errors: ValidationError[];\n  /** Validation warnings (non-blocking issues) */\n  warnings: ValidationWarning[];\n  /** Auto-corrected query (if corrections were possible) */\n  correctedQuery?: Record<string, unknown>;\n}\n\nexport type ValidationErrorCode =\n  | 'INVALID_STRUCTURE'\n  | 'MISSING_REQUIRED_FIELD'\n  | 'INVALID_DOMAIN'\n  | 'INVALID_FIELD_PATH'\n  | 'INVALID_OPERATOR'\n  | 'INVALID_OPERATOR_VALUE'\n  | 'COMPUTED_FIELD_FILTER'\n  | 'INVALID_ORDER'\n  | 'INVALID_LIMIT'\n  | 'INVALID_SELECT_EXPRESSION';\n\n// ============================================\n// Valid Operators\n// ============================================\n\nconst VALID_OPERATORS = new Set(\n  FILTER_OP_SCHEMA.operators.map((op) => op.name),\n);\n\nconst VALID_DOMAINS = new Set(['sessions', 'activities']);\n\nconst VALID_ORDERS = new Set(['asc', 'desc']);\n\n// ============================================\n// Field Path Resolution\n// ============================================\n\n/**\n * Resolve a dot-notation path to field metadata\n */\nfunction resolveFieldPath(\n  path: string,\n  domain: 'sessions' | 'activities',\n): { field: FieldMeta | null; exists: boolean; computedField: boolean } {\n  const schema = domain === 'sessions' ? SESSION_SCHEMA : ACTIVITY_SCHEMA;\n  const parts = path.split('.');\n\n  let currentFields: FieldMeta[] = schema.fields;\n  let currentField: FieldMeta | null = null;\n\n  for (const part of parts) {\n    const found = currentFields.find((f) => f.name === part);\n    if (!found) {\n      return { field: null, exists: false, computedField: false };\n    }\n    currentField = found;\n    currentFields = found.fields || [];\n  }\n\n  return {\n    field: currentField,\n    exists: true,\n    computedField: currentField?.computed || false,\n  };\n}\n\n/**\n * Get all valid field names for a domain (including nested paths)\n */\nfunction getValidFieldPaths(\n  domain: 'sessions' | 'activities',\n  prefix = '',\n): string[] {\n  const schema = domain === 'sessions' ? SESSION_SCHEMA : ACTIVITY_SCHEMA;\n  const paths: string[] = [];\n\n  function collectPaths(fields: FieldMeta[], currentPrefix: string) {\n    for (const field of fields) {\n      const fullPath = currentPrefix\n        ? `${currentPrefix}.${field.name}`\n        : field.name;\n      paths.push(fullPath);\n      if (field.fields) {\n        collectPaths(field.fields, fullPath);\n      }\n    }\n  }\n\n  collectPaths(schema.fields, prefix);\n  return paths;\n}\n\n// ============================================\n// Validation Functions\n// ============================================\n\n/**\n * Validate query structure\n */\nfunction validateStructure(\n  query: unknown,\n  errors: ValidationError[],\n): query is Record<string, unknown> {\n  if (typeof query !== 'object' || query === null || Array.isArray(query)) {\n    errors.push({\n      code: 'INVALID_STRUCTURE',\n      path: '',\n      message: 'Query must be a non-null object',\n      suggestion: 'Provide a query object like { from: \"sessions\" }',\n    });\n    return false;\n  }\n  return true;\n}\n\n/**\n * Validate the 'from' field (domain)\n */\nfunction validateDomain(\n  query: Record<string, unknown>,\n  errors: ValidationError[],\n): 'sessions' | 'activities' | null {\n  if (!('from' in query)) {\n    errors.push({\n      code: 'MISSING_REQUIRED_FIELD',\n      path: 'from',\n      message: 'Missing required field: from',\n      suggestion: 'Add from: \"sessions\" or from: \"activities\"',\n    });\n    return null;\n  }\n\n  const from = query.from;\n  if (typeof from !== 'string' || !VALID_DOMAINS.has(from)) {\n    errors.push({\n      code: 'INVALID_DOMAIN',\n      path: 'from',\n      message: `Invalid domain: \"${from}\"`,\n      suggestion: 'Valid domains are: \"sessions\", \"activities\"',\n    });\n    return null;\n  }\n\n  return from as 'sessions' | 'activities';\n}\n\n/**\n * Validate the 'select' field\n */\nfunction validateSelect(\n  select: unknown,\n  domain: 'sessions' | 'activities',\n  errors: ValidationError[],\n  warnings: ValidationWarning[],\n): void {\n  if (select === undefined) return;\n\n  if (!Array.isArray(select)) {\n    errors.push({\n      code: 'INVALID_STRUCTURE',\n      path: 'select',\n      message: 'select must be an array of strings',\n      suggestion: 'Use select: [\"id\", \"title\"] or omit for default projection',\n    });\n    return;\n  }\n\n  for (let i = 0; i < select.length; i++) {\n    const expr = select[i];\n    if (typeof expr !== 'string') {\n      errors.push({\n        code: 'INVALID_SELECT_EXPRESSION',\n        path: `select[${i}]`,\n        message: `Select expression must be a string, got ${typeof expr}`,\n      });\n      continue;\n    }\n\n    // Handle wildcard\n    if (expr === '*') continue;\n\n    // Handle exclusion prefix\n    const isExclusion = expr.startsWith('-');\n    const fieldPath = isExclusion ? expr.slice(1) : expr;\n\n    // Validate field path exists\n    const resolution = resolveFieldPath(fieldPath, domain);\n    if (!resolution.exists) {\n      const validPaths = getValidFieldPaths(domain);\n      const similar = validPaths.filter(\n        (p) =>\n          p.includes(fieldPath.split('.')[0]) ||\n          fieldPath.split('.')[0].includes(p.split('.')[0]),\n      );\n      warnings.push({\n        code: 'UNKNOWN_FIELD',\n        path: `select[${i}]`,\n        message: `Unknown field path: \"${fieldPath}\"`,\n      });\n      if (similar.length > 0) {\n        warnings[warnings.length - 1].message +=\n          `. Did you mean: ${similar.slice(0, 3).join(', ')}?`;\n      }\n    }\n  }\n}\n\n/**\n * Validate the 'where' clause\n */\nfunction validateWhere(\n  where: unknown,\n  domain: 'sessions' | 'activities',\n  errors: ValidationError[],\n  warnings: ValidationWarning[],\n): void {\n  if (where === undefined) return;\n\n  if (typeof where !== 'object' || where === null || Array.isArray(where)) {\n    errors.push({\n      code: 'INVALID_STRUCTURE',\n      path: 'where',\n      message: 'where must be an object',\n      suggestion:\n        'Use where: { field: \"value\" } or where: { field: { op: value } }',\n    });\n    return;\n  }\n\n  const whereObj = where as Record<string, unknown>;\n\n  for (const [key, value] of Object.entries(whereObj)) {\n    const fieldPath = `where.${key}`;\n\n    // Special case for 'search' - it's a virtual field\n    if (key === 'search') {\n      if (typeof value !== 'string') {\n        errors.push({\n          code: 'INVALID_OPERATOR_VALUE',\n          path: fieldPath,\n          message: 'search must be a string',\n        });\n      }\n      continue;\n    }\n\n    // Validate field exists\n    const resolution = resolveFieldPath(key, domain);\n    if (!resolution.exists) {\n      const validPaths = getValidFieldPaths(domain).filter(\n        (p) =>\n          SESSION_SCHEMA.fields.find((f) => f.name === p)?.filterable ||\n          ACTIVITY_SCHEMA.fields.find((f) => f.name === p)?.filterable,\n      );\n      warnings.push({\n        code: 'UNKNOWN_FIELD',\n        path: fieldPath,\n        message: `Unknown field: \"${key}\"`,\n      });\n    } else if (resolution.computedField) {\n      errors.push({\n        code: 'COMPUTED_FIELD_FILTER',\n        path: fieldPath,\n        message: `Cannot filter on computed field: \"${key}\"`,\n        suggestion:\n          'Computed fields (artifactCount, summary, durationMs) can only be selected, not filtered',\n      });\n    } else if (resolution.field && !resolution.field.filterable) {\n      warnings.push({\n        code: 'NON_FILTERABLE_FIELD',\n        path: fieldPath,\n        message: `Field \"${key}\" may not be efficiently filterable`,\n      });\n    }\n\n    // Validate filter value/operator\n    validateFilterValue(value, fieldPath, errors);\n  }\n}\n\n/**\n * Validate a filter value (direct value or operator object)\n */\nfunction validateFilterValue(\n  value: unknown,\n  path: string,\n  errors: ValidationError[],\n): void {\n  // Direct value (equality shorthand)\n  if (\n    value === null ||\n    typeof value === 'string' ||\n    typeof value === 'number' ||\n    typeof value === 'boolean'\n  ) {\n    return;\n  }\n\n  // Operator object\n  if (typeof value === 'object' && !Array.isArray(value)) {\n    const opObj = value as Record<string, unknown>;\n    const keys = Object.keys(opObj);\n\n    if (keys.length === 0) {\n      errors.push({\n        code: 'INVALID_OPERATOR',\n        path,\n        message: 'Empty filter object',\n        suggestion: 'Use { eq: value } or a direct value',\n      });\n      return;\n    }\n\n    for (const op of keys) {\n      if (!VALID_OPERATORS.has(op)) {\n        errors.push({\n          code: 'INVALID_OPERATOR',\n          path: `${path}.${op}`,\n          message: `Invalid operator: \"${op}\"`,\n          suggestion: `Valid operators: ${Array.from(VALID_OPERATORS).join(', ')}`,\n        });\n        continue;\n      }\n\n      // Validate operator value types\n      const opValue = opObj[op];\n      switch (op) {\n        case 'eq':\n        case 'neq':\n        case 'gt':\n        case 'lt':\n        case 'gte':\n        case 'lte':\n          if (\n            opValue !== null &&\n            typeof opValue !== 'string' &&\n            typeof opValue !== 'number' &&\n            typeof opValue !== 'boolean'\n          ) {\n            errors.push({\n              code: 'INVALID_OPERATOR_VALUE',\n              path: `${path}.${op}`,\n              message: `${op} operator requires a primitive value (string, number, boolean, or null)`,\n            });\n          }\n          break;\n        case 'contains':\n          if (typeof opValue !== 'string') {\n            errors.push({\n              code: 'INVALID_OPERATOR_VALUE',\n              path: `${path}.${op}`,\n              message: 'contains operator requires a string value',\n            });\n          }\n          break;\n        case 'in':\n          if (!Array.isArray(opValue)) {\n            errors.push({\n              code: 'INVALID_OPERATOR_VALUE',\n              path: `${path}.${op}`,\n              message: 'in operator requires an array of values',\n              suggestion: 'Use in: [\"value1\", \"value2\"]',\n            });\n          }\n          break;\n        case 'exists':\n          if (typeof opValue !== 'boolean') {\n            errors.push({\n              code: 'INVALID_OPERATOR_VALUE',\n              path: `${path}.${op}`,\n              message: 'exists operator requires a boolean value',\n              suggestion: 'Use exists: true or exists: false',\n            });\n          }\n          break;\n      }\n    }\n  } else {\n    errors.push({\n      code: 'INVALID_OPERATOR_VALUE',\n      path,\n      message: `Invalid filter value type: ${typeof value}`,\n      suggestion:\n        'Use a primitive value for equality or an operator object like { contains: \"text\" }',\n    });\n  }\n}\n\n/**\n * Validate the 'order' field\n */\nfunction validateOrder(order: unknown, errors: ValidationError[]): void {\n  if (order === undefined) return;\n\n  if (typeof order !== 'string' || !VALID_ORDERS.has(order)) {\n    errors.push({\n      code: 'INVALID_ORDER',\n      path: 'order',\n      message: `Invalid order: \"${order}\"`,\n      suggestion: 'Valid values are: \"asc\", \"desc\"',\n    });\n  }\n}\n\n/**\n * Validate the 'limit' field\n */\nfunction validateLimit(\n  limit: unknown,\n  errors: ValidationError[],\n  warnings: ValidationWarning[],\n): void {\n  if (limit === undefined) return;\n\n  if (typeof limit !== 'number' || !Number.isInteger(limit)) {\n    errors.push({\n      code: 'INVALID_LIMIT',\n      path: 'limit',\n      message: 'limit must be an integer',\n    });\n    return;\n  }\n\n  if (limit < 0) {\n    errors.push({\n      code: 'INVALID_LIMIT',\n      path: 'limit',\n      message: 'limit cannot be negative',\n    });\n  }\n\n  if (limit > 1000) {\n    warnings.push({\n      code: 'LIMIT_TOO_HIGH',\n      path: 'limit',\n      message: `limit of ${limit} exceeds maximum of 1000, will be capped`,\n    });\n  }\n}\n\n/**\n * Validate startAfter cursor\n */\nfunction validateCursor(\n  cursor: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (cursor === undefined) return;\n\n  if (typeof cursor !== 'string') {\n    errors.push({\n      code: 'INVALID_STRUCTURE',\n      path: field,\n      message: `${field} must be a string (ID)`,\n    });\n  }\n}\n\n// ============================================\n// Main Validation Function\n// ============================================\n\n/**\n * Validate a Jules Query Language query\n *\n * @param query - The query object to validate\n * @returns Validation result with errors, warnings, and optional corrections\n *\n * @example\n * ```typescript\n * const result = validateQuery({\n *   from: 'activities',\n *   where: { type: 'agentMessaged' },\n *   select: ['id', 'message']\n * });\n *\n * if (!result.valid) {\n *   console.log('Errors:', result.errors);\n * }\n * ```\n */\nexport function validateQuery(query: unknown): ValidationResult {\n  const errors: ValidationError[] = [];\n  const warnings: ValidationWarning[] = [];\n\n  // Step 1: Validate basic structure\n  if (!validateStructure(query, errors)) {\n    return { valid: false, errors, warnings };\n  }\n\n  const queryObj = query as Record<string, unknown>;\n\n  // Step 2: Validate domain\n  const domain = validateDomain(queryObj, errors);\n  if (!domain) {\n    return { valid: false, errors, warnings };\n  }\n\n  // Step 3: Validate select\n  validateSelect(queryObj.select, domain, errors, warnings);\n\n  // Step 4: Validate where\n  validateWhere(queryObj.where, domain, errors, warnings);\n\n  // Step 5: Validate order\n  validateOrder(queryObj.order, errors);\n\n  // Step 6: Validate limit\n  validateLimit(queryObj.limit, errors, warnings);\n\n  // Step 7: Validate cursors\n  validateCursor(queryObj.startAfter, 'startAfter', errors);\n  validateCursor(queryObj.startAt, 'startAt', errors);\n\n  // Step 8: Check for unknown top-level fields\n  const validTopLevelFields = new Set([\n    'from',\n    'select',\n    'where',\n    'order',\n    'limit',\n    'startAfter',\n    'startAt',\n    'include',\n    'tokenBudget',\n    'offset',\n  ]);\n\n  for (const key of Object.keys(queryObj)) {\n    if (!validTopLevelFields.has(key)) {\n      warnings.push({\n        code: 'UNKNOWN_QUERY_FIELD',\n        path: key,\n        message: `Unknown query field: \"${key}\"`,\n      });\n    }\n  }\n\n  return {\n    valid: errors.length === 0,\n    errors,\n    warnings,\n  };\n}\n\n/**\n * Format validation result as a human-readable string\n */\nexport function formatValidationResult(result: ValidationResult): string {\n  const lines: string[] = [];\n\n  if (result.valid) {\n    lines.push('Query is valid.');\n  } else {\n    lines.push('Query validation failed:');\n  }\n\n  if (result.errors.length > 0) {\n    lines.push('\\nErrors:');\n    for (const error of result.errors) {\n      lines.push(`  - [${error.code}] ${error.path}: ${error.message}`);\n      if (error.suggestion) {\n        lines.push(`    Suggestion: ${error.suggestion}`);\n      }\n    }\n  }\n\n  if (result.warnings.length > 0) {\n    lines.push('\\nWarnings:');\n    for (const warning of result.warnings) {\n      lines.push(`  - [${warning.code}] ${warning.path}: ${warning.message}`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n","import { Platform, PlatformResponse } from './types.js';\n\n/**\n * Web Platform implementation using standard Web APIs.\n * Works on Edge runtimes, Deno, Cloudflare Workers, and Node.js 18+.\n *\n * Note: This is a minimal implementation focused on server-side gateway usage.\n * It does not support file storage operations (use NodePlatform for that).\n */\nexport class WebPlatform implements Platform {\n  /**\n   * File saving is not supported in the Web Platform.\n   * Use NodePlatform or BrowserPlatform for file operations.\n   */\n  async saveFile(\n    filepath: string,\n    data: string,\n    encoding: 'base64',\n    activityId?: string,\n  ): Promise<void> {\n    throw new Error(\n      'saveFile is not supported in WebPlatform. Use NodePlatform for file operations.',\n    );\n  }\n\n  async sleep(ms: number): Promise<void> {\n    await new Promise((resolve) => setTimeout(resolve, ms));\n  }\n\n  createDataUrl(data: string, mimeType: string): string {\n    return `data:${mimeType};base64,${data}`;\n  }\n\n  async fetch(input: string, init?: any): Promise<PlatformResponse> {\n    const res = await globalThis.fetch(input, init);\n    return {\n      ok: res.ok,\n      status: res.status,\n      json: () => res.json(),\n      text: () => res.text(),\n    };\n  }\n\n  crypto = {\n    randomUUID: (): string => globalThis.crypto.randomUUID(),\n\n    async sign(text: string, secret: string): Promise<string> {\n      const enc = new TextEncoder();\n      const key = await globalThis.crypto.subtle.importKey(\n        'raw',\n        enc.encode(secret),\n        { name: 'HMAC', hash: 'SHA-256' },\n        false,\n        ['sign'],\n      );\n      const signature = await globalThis.crypto.subtle.sign(\n        'HMAC',\n        key,\n        enc.encode(text),\n      );\n      return this.arrayBufferToBase64Url(signature);\n    },\n\n    async verify(\n      text: string,\n      signature: string,\n      secret: string,\n    ): Promise<boolean> {\n      const expected = await this.sign(text, secret);\n      // Constant-time comparison would be ideal, but Web Crypto doesn't expose it\n      // For HMAC verification, timing attacks are less critical than for password comparison\n      return expected === signature;\n    },\n\n    arrayBufferToBase64Url(buffer: ArrayBuffer): string {\n      const bytes = new Uint8Array(buffer);\n      let binary = '';\n      for (let i = 0; i < bytes.byteLength; i++) {\n        binary += String.fromCharCode(bytes[i]);\n      }\n      // Use btoa which is available in all modern runtimes\n      return btoa(binary)\n        .replace(/\\+/g, '-')\n        .replace(/\\//g, '_')\n        .replace(/=+$/, '');\n    },\n  };\n\n  encoding = {\n    base64Encode: (text: string): string => {\n      const encoder = new TextEncoder();\n      const bytes = encoder.encode(text);\n      let binary = '';\n      for (let i = 0; i < bytes.length; i++) {\n        binary += String.fromCharCode(bytes[i]);\n      }\n      return btoa(binary)\n        .replace(/\\+/g, '-')\n        .replace(/\\//g, '_')\n        .replace(/=+$/, '');\n    },\n\n    base64Decode: (text: string): string => {\n      const base64 = text.replace(/-/g, '+').replace(/_/g, '/');\n      const binary = atob(base64);\n      const bytes = new Uint8Array(binary.length);\n      for (let i = 0; i < binary.length; i++) {\n        bytes[i] = binary.charCodeAt(i);\n      }\n      const decoder = new TextDecoder();\n      return decoder.decode(bytes);\n    },\n  };\n\n  getEnv(key: string): string | undefined {\n    // Check for Deno\n    if (typeof (globalThis as any).Deno !== 'undefined') {\n      return (globalThis as any).Deno.env.get(key);\n    }\n    // Check for Node.js process.env\n    if (typeof process !== 'undefined' && process.env) {\n      return process.env[key];\n    }\n    // Cloudflare Workers don't have env access this way - they use bindings\n    return undefined;\n  }\n}\n","// src/index.ts\nimport { JulesClientImpl } from './client.js';\nimport { NodeFileStorage, NodeSessionStorage } from './storage/node-fs.js';\nimport { NodePlatform } from './platform/node.js';\nimport { JulesClient, JulesOptions, StorageFactory } from './types.js';\nimport { getRootDir } from './storage/root.js';\n\n// Define defaults for the Node.js environment\nconst defaultPlatform = new NodePlatform();\nconst defaultStorageFactory: StorageFactory = {\n  activity: (sessionId: string) => new NodeFileStorage(sessionId, getRootDir()),\n  session: () => new NodeSessionStorage(getRootDir()),\n};\n\n/**\n * Connects to the Jules service using Node.js defaults (File System, Native Crypto).\n * Acts as a factory method for creating a new client instance.\n *\n * @param options Configuration options for the client.\n * @returns A new JulesClient instance.\n */\nexport function connect(options: JulesOptions = {}): JulesClient {\n  return new JulesClientImpl(options, defaultStorageFactory, defaultPlatform);\n}\n\n/**\n * The main entry point for the Jules SDK.\n * This is a pre-initialized client that can be used immediately with default settings\n * (e.g., reading API keys from environment variables).\n *\n * @example\n * import { jules } from 'modjules';\n * const session = await jules.session({ ... });\n */\nexport const jules: JulesClient = connect();\n\n// Re-export all the types for convenience\nexport * from './errors.js';\nexport type {\n  Activity,\n  ActivityAgentMessaged,\n  ActivityPlanApproved,\n  ActivityPlanGenerated,\n  ActivityProgressUpdated,\n  ActivitySummary,\n  ActivitySessionCompleted,\n  ActivitySessionFailed,\n  ActivityUserMessaged,\n  Artifact,\n  AutomatedSession,\n  ChangeSet,\n  GitHubRepo,\n  GitPatch,\n  JulesClient,\n  JulesOptions,\n  LightweightActivity,\n  LightweightArtifact,\n  MediaArtifact,\n  Outcome,\n  ParsedChangeSet,\n  ParsedFile,\n  Plan,\n  PlanStep,\n  PullRequest,\n  SessionClient,\n  SessionConfig,\n  SessionOutput,\n  SessionResource,\n  SessionState,\n  Source,\n  SourceContext,\n  SourceInput,\n  SourceManager,\n  StrippedMediaArtifact,\n  JulesQuery,\n  JulesDomain,\n  SyncDepth,\n} from './types.js';\n\n// Re-export schema and validation for MCP and other consumers\nexport {\n  SESSION_SCHEMA,\n  ACTIVITY_SCHEMA,\n  FILTER_OP_SCHEMA,\n  PROJECTION_SCHEMA,\n  getSchema,\n  getAllSchemas,\n  generateTypeDefinition,\n  generateMarkdownDocs,\n} from './query/schema.js';\nexport type { FieldMeta, DomainSchema, QueryExample } from './query/schema.js';\nexport { validateQuery, formatValidationResult } from './query/validate.js';\nexport type {\n  ValidationError,\n  ValidationWarning,\n  ValidationResult,\n  ValidationErrorCode,\n} from './query/validate.js';\n\nexport { SessionCursor } from './sessions.js';\nexport type { ListSessionsOptions, ListSessionsResponse } from './sessions.js';\n\n// Activity utilities\nexport { toSummary } from './activity/summary.js';\n\n// Internal exports for @modjules/server package\nexport { JulesClientImpl } from './client.js';\nexport { MemoryStorage, MemorySessionStorage } from './storage/memory.js';\nexport { WebPlatform } from './platform/web.js';\nexport { NodePlatform } from './platform/node.js';\nexport type { Platform } from './platform/types.js';\nexport type { StorageFactory } from './types.js';\n\n// Artifact classes with helper methods\nexport { ChangeSetArtifact, BashArtifact, parseUnidiff } from './artifacts.js';\n"],"names":["e","i","Buffer","setTimeout","a","b","path","f","p"],"mappings":";;;;;;;;;;AAiBO,MAAM,gBAA2C;AAAA,EAC9C;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,cAAkC;AAAA;AAAA,EAGlC,4BAAiC,IAAA;AAAA,EACjC,aAAa;AAAA,EACb,oBAA0C;AAAA;AAAA,EAG1C,kBAAkB;AAAA,EAE1B,YAAY,WAAmB,SAAiB;AAC9C,UAAM,kBAAkB,KAAK,QAAQ,SAAS,gBAAgB,SAAS;AACvE,SAAK,WAAW,KAAK,KAAK,iBAAiB,kBAAkB;AAC7D,SAAK,eAAe,KAAK,KAAK,iBAAiB,eAAe;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAsB;AAC1B,QAAI,KAAK,YAAa;AAEtB,UAAM,GAAG,MAAM,KAAK,QAAQ,KAAK,QAAQ,GAAG,EAAE,WAAW,MAAM;AAG/D,QAAI;AACF,YAAM,QAAQ,MAAM,GAAG,KAAK,KAAK,QAAQ;AACzC,WAAK,kBAAkB,MAAM;AAAA,IAC/B,SAASA,IAAQ;AACf,UAAIA,GAAE,SAAS,UAAU;AACvB,aAAK,kBAAkB;AAAA,MACzB,OAAO;AACL,cAAMA;AAAA,MACR;AAAA,IACF;AAGA,SAAK,cAAc,kBAAkB,KAAK,UAAU;AAAA,MAClD,OAAO;AAAA,MACP,UAAU;AAAA,IAAA,CACX;AAGD,SAAK,YAAY,GAAG,SAAS,CAAC,QAAQ;AACpC,cAAQ;AAAA,QACN,2CAA2C,KAAK,QAAQ;AAAA,QACxD;AAAA,MAAA;AAAA,IAIJ,CAAC;AAED,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,QAAI,KAAK,aAAa;AACpB,YAAM,IAAI,QAAc,CAAC,YAAY,KAAK,YAAa,IAAI,OAAO,CAAC;AACnE,WAAK,cAAc;AAAA,IACrB;AACA,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,MAAM,MAAA;AAEX,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,MAAc,gBAA0C;AACtD,QAAI;AACF,YAAM,UAAU,MAAM,GAAG,SAAS,KAAK,cAAc,MAAM;AAC3D,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,SAASA,IAAQ;AACf,UAAIA,GAAE,SAAS,UAAU;AACvB,eAAO,EAAE,eAAe,EAAA;AAAA,MAC1B;AACA,YAAMA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,UAA0C;AACrE,UAAM,GAAG;AAAA,MACP,KAAK;AAAA,MACL,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,MAChC;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,UAAmC;AAE9C,QAAI,CAAC,KAAK,YAAa,OAAM,KAAK,KAAA;AAGlC,UAAM,WAAW,MAAM,KAAK,cAAA;AAC5B,aAAS,iBAAiB;AAC1B,UAAM,KAAK,eAAe,QAAQ;AAGlC,UAAM,OAAO,KAAK,UAAU,QAAQ,IAAI;AACxC,UAAM,cAAc,KAAK;AAGzB,QAAI,KAAK,aAAa;AACpB,YAAM,cAAc,KAAK,YAAY,MAAM,IAAI;AAC/C,WAAK,mBAAmB,OAAO,WAAW,IAAI;AAM9C,UAAI,KAAK,cAAc,KAAK,mBAAmB;AAC7C,YAAI,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE,GAAG;AAChC,eAAK,MAAM,IAAI,SAAS,IAAI,WAAW;AAAA,QACzC;AAAA,MACF;AAEA,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI;AAAA,UAAc,CAAC,YACvB,KAAK,YAAa,KAAK,SAAS,OAAO;AAAA,QAAA;AAAA,MAE3C;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,aAA4B;AACxC,QAAI,KAAK,WAAY;AACrB,QAAI,KAAK,kBAAmB,QAAO,KAAK;AAExC,SAAK,qBAAqB,YAAY;AACpC,UAAI;AACF,aAAK,MAAM,MAAA;AAEX,YAAI;AACF,gBAAM,GAAG,OAAO,KAAK,QAAQ;AAAA,QAC/B,SAASA,IAAG;AAEV,eAAK,aAAa;AAClB;AAAA,QACF;AAEA,cAAM,aAAa,iBAAiB,KAAK,UAAU;AAAA,UACjD,UAAU;AAAA,QAAA,CACX;AACD,cAAM,KAAK,SAAS,gBAAgB;AAAA,UAClC,OAAO;AAAA,UACP,WAAW;AAAA,QAAA,CACZ;AAED,YAAI,gBAAgB;AACpB,yBAAiB,QAAQ,IAAI;AAC3B,gBAAM,UAAU,OAAO,WAAW,IAAI;AAEtC,gBAAM,iBAAiB,UAAU;AAEjC,cAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,gBAAI;AACF,oBAAM,WAAW,KAAK,MAAM,IAAI;AAChC,kBAAI,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE,GAAG;AAChC,qBAAK,MAAM,IAAI,SAAS,IAAI,aAAa;AAAA,cAC3C;AAAA,YACF,SAASA,IAAG;AAAA,YAEZ;AAAA,UACF;AACA,2BAAiB;AAAA,QACnB;AAEA,aAAK,aAAa;AAAA,MACpB,UAAA;AACE,aAAK,oBAAoB;AAAA,MAC3B;AAAA,IACF,GAAA;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,YAAmD;AAC3D,QAAI,CAAC,KAAK,YAAa,OAAM,KAAK,KAAA;AAClC,QAAI,CAAC,KAAK,WAAY,OAAM,KAAK,WAAA;AAEjC,UAAM,SAAS,KAAK,MAAM,IAAI,UAAU;AACxC,QAAI,WAAW,OAAW,QAAO;AAEjC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAEtC,YAAM,SAAS,iBAAiB,KAAK,UAAU;AAAA,QAC7C,OAAO;AAAA,QACP,UAAU;AAAA,MAAA,CACX;AACD,YAAM,KAAK,SAAS,gBAAgB;AAAA,QAClC,OAAO;AAAA,QACP,WAAW;AAAA,MAAA,CACZ;AAED,UAAI,QAAQ;AACZ,SAAG,GAAG,QAAQ,CAAC,SAAS;AACtB,YAAI,MAAO;AACX,gBAAQ;AAGR,WAAG,MAAA;AACH,eAAO,QAAA;AAEP,YAAI;AACF,gBAAM,WAAW,KAAK,MAAM,IAAI;AAChC,kBAAQ,QAAQ;AAAA,QAClB,SAASA,IAAG;AAEV,kBAAQ,MAAS;AAAA,QACnB;AAAA,MACF,CAAC;AAED,SAAG,GAAG,SAAS,CAAC,QAAQ;AACtB,eAAO,GAAG;AAAA,MACZ,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,QAAQ;AAC1B,eAAO,GAAG;AAAA,MACZ,CAAC;AAGD,SAAG,GAAG,SAAS,MAAM;AACnB,YAAI,CAAC,MAAO,SAAQ,MAAS;AAAA,MAC/B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAwC;AAC5C,QAAI,CAAC,KAAK,YAAa,OAAM,KAAK,KAAA;AAElC,QAAI;AACF,YAAM,GAAG,OAAO,KAAK,QAAQ;AAAA,IAC/B,SAASA,IAAG;AACV,UAAKA,GAAU,SAAS,UAAU;AAChC,eAAO;AAAA,MACT;AACA,YAAMA;AAAA,IACR;AAIA,UAAM,OAAO,MAAM,GAAG,KAAK,KAAK,QAAQ;AACxC,UAAM,WAAW,KAAK;AAEtB,QAAI,aAAa,EAAG,QAAO;AAI3B,UAAM,aAAa;AACnB,UAAM,SAAS,OAAO,MAAM,UAAU;AACtC,QAAI;AAEJ,QAAI;AACF,WAAK,MAAM,GAAG,KAAK,KAAK,UAAU,GAAG;AACrC,UAAI,aAAa;AACjB,UAAI,WAAW;AAEf,aAAO,aAAa,GAAG;AACrB,cAAM,WAAW,KAAK,IAAI,YAAY,UAAU;AAChD,cAAM,WAAW,aAAa;AAE9B,cAAM,SAAS,MAAM,GAAG,KAAK,QAAQ,GAAG,UAAU,QAAQ;AAC1D,cAAM,QAAQ,OAAO,OAAO,SAAS,QAAQ,GAAG,QAAQ;AAGxD,cAAM,UAAU,QAAQ;AAGxB,cAAM,QAAQ,QAAQ,MAAM,IAAI;AAKhC,YAAI,WAAW,GAAG;AAChB,qBAAW,MAAM,WAAW;AAAA,QAC9B,OAAO;AAEL,qBAAW;AAAA,QACb;AAGA,iBAASC,KAAI,MAAM,SAAS,GAAGA,MAAK,GAAGA,MAAK;AAC1C,gBAAM,OAAO,MAAMA,EAAC,EAAE,KAAA;AACtB,cAAI,KAAK,WAAW,EAAG;AAEvB,cAAI;AACF,mBAAO,KAAK,MAAM,IAAI;AAAA,UACxB,SAASD,IAAG;AACV,oBAAQ;AAAA,cACN,wEAAwE,KAAK,QAAQ;AAAA,YAAA;AAAA,UAGzF;AAAA,QACF;AAEA,sBAAc;AAAA,MAChB;AAAA,IACF,UAAA;AACE,UAAI,GAAI,OAAM,GAAG,MAAA;AAAA,IACnB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,OAAgC;AACrC,QAAI,CAAC,KAAK,YAAa,OAAM,KAAK,KAAA;AAElC,QAAI;AACF,YAAM,GAAG,OAAO,KAAK,QAAQ;AAAA,IAC/B,SAASA,IAAG;AACV,UAAKA,GAAU,SAAS,UAAU;AAChC;AAAA,MACF;AACA,YAAMA;AAAA,IACR;AAEA,UAAM,aAAa,iBAAiB,KAAK,UAAU,EAAE,UAAU,QAAQ;AACvE,UAAM,KAAK,SAAS,gBAAgB;AAAA,MAClC,OAAO;AAAA,MACP,WAAW;AAAA,IAAA,CACZ;AAED,qBAAiB,QAAQ,IAAI;AAC3B,UAAI,KAAK,OAAO,WAAW,EAAG;AAC9B,UAAI;AACF,cAAM,KAAK,MAAM,IAAI;AAAA,MACvB,SAASA,IAAG;AACV,gBAAQ;AAAA,UACN,kDAAkD,KAAK,QAAQ;AAAA,QAAA;AAAA,MAEnE;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,mBAA6C;AAAA,EAChD;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EAEtB,YAAY,SAAiB;AAC3B,SAAK,WAAW,KAAK,QAAQ,SAAS,cAAc;AACpD,SAAK,gBAAgB,KAAK,KAAK,KAAK,UAAU,gBAAgB;AAAA,EAChE;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,YAAa;AACtB,UAAM,GAAG,MAAM,KAAK,UAAU,EAAE,WAAW,MAAM;AACjD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,eAAe,WAA2B;AAChD,WAAO,KAAK,KAAK,KAAK,UAAU,WAAW,cAAc;AAAA,EAC3D;AAAA,EAEA,MAAM,OAAO,SAAyC;AACpD,UAAM,KAAK,KAAA;AAGX,UAAM,aAAa,KAAK,KAAK,KAAK,UAAU,QAAQ,EAAE;AACtD,UAAM,GAAG,MAAM,YAAY,EAAE,WAAW,MAAM;AAE9C,UAAM,SAAwB;AAAA,MAC5B,UAAU;AAAA,MACV,eAAe,KAAK,IAAA;AAAA,IAAI;AAI1B,UAAM,GAAG;AAAA,MACP,KAAK,KAAK,YAAY,cAAc;AAAA,MACpC,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,MAC9B;AAAA,IAAA;AAKF,UAAM,aAAgC;AAAA,MACpC,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,QAAQ,QAAQ,eAAe,UAAU;AAAA,MACzC,YAAY,KAAK,IAAA;AAAA,IAAI;AAGvB,UAAM,GAAG;AAAA,MACP,KAAK;AAAA,MACL,KAAK,UAAU,UAAU,IAAI;AAAA,MAC7B;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,WAAW,UAA4C;AAE3D,UAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,IAAI,WAAuD;AAC/D,UAAM,KAAK,KAAA;AACX,QAAI;AACF,YAAM,OAAO,MAAM,GAAG,SAAS,KAAK,eAAe,SAAS,GAAG,MAAM;AACrE,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAASA,IAAQ;AACf,UAAIA,GAAE,SAAS,SAAU,QAAO;AAChC,YAAMA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,WAAkC;AAC7C,UAAM,KAAK,KAAA;AAEX,UAAM,aAAa,KAAK,KAAK,KAAK,UAAU,SAAS;AACrD,UAAM,GAAG,GAAG,YAAY,EAAE,WAAW,MAAM,OAAO,MAAM;AAAA,EAK1D;AAAA,EAEA,OAAO,YAA8C;AACnD,UAAM,KAAK,KAAA;AAKX,QAAI;AACF,YAAM,aAAa,iBAAiB,KAAK,eAAe;AAAA,QACtD,UAAU;AAAA,MAAA,CACX;AACD,YAAM,KAAK,SAAS,gBAAgB;AAAA,QAClC,OAAO;AAAA,QACP,WAAW;AAAA,MAAA,CACZ;AAGD,YAAM,8BAAc,IAAA;AAEpB,uBAAiB,QAAQ,IAAI;AAC3B,YAAI,CAAC,KAAK,OAAQ;AAClB,YAAI;AACF,gBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,kBAAQ,IAAI,MAAM,IAAI,KAAK;AAAA,QAC7B,SAASA,IAAG;AAAA,QAEZ;AAAA,MACF;AAEA,iBAAW,SAAS,QAAQ,UAAU;AACpC,cAAM;AAAA,MACR;AAAA,IACF,SAASA,IAAQ;AACf,UAAIA,GAAE,SAAS,SAAU;AACzB,YAAMA;AAAA,IACR;AAAA,EACF;AACF;AC1fO,MAAM,aAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,MAAM,SACJ,UACA,MACA,UACA,YACe;AACf,UAAM,SAASE,SAAO,KAAK,MAAM,QAAQ;AACzC,UAAM,UAAU,UAAU,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,MAAM,IAA2B;AACrC,UAAMC,aAAW,EAAE;AAAA,EACrB;AAAA,EAEA,cAAc,MAAc,UAA0B;AACpD,WAAO,QAAQ,QAAQ,WAAW,IAAI;AAAA,EACxC;AAAA,EAEA,MAAM,MAAM,OAAe,MAAuC;AAChE,UAAM,MAAM,MAAM,OAAO,MAAM,OAAO,IAAI;AAC1C,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,QAAQ,IAAI;AAAA,MACZ,MAAM,MAAM,IAAI,KAAA;AAAA,MAChB,MAAM,MAAM,IAAI,KAAA;AAAA,IAAK;AAAA,EAEzB;AAAA,EAEA,SAAS;AAAA,IACP,YAAY,MAAM,OAAO,WAAA;AAAA,IAEzB,MAAM,KAAK,MAAc,QAAiC;AACxD,YAAM,OAAO,OAAO,WAAW,UAAU,MAAM;AAC/C,WAAK,OAAO,IAAI;AAChB,aAAO,KAAK,OAAO,WAAW;AAAA,IAChC;AAAA,IAEA,MAAM,OACJ,MACA,WACA,QACkB;AAClB,YAAM,WAAW,MAAM,KAAK,KAAK,MAAM,MAAM;AAE7C,YAAMC,KAAIF,SAAO,KAAK,QAAQ;AAC9B,YAAMG,KAAIH,SAAO,KAAK,SAAS;AAC/B,aAAOE,GAAE,WAAWC,GAAE,UAAU,OAAO,gBAAgBD,IAAGC,EAAC;AAAA,IAC7D;AAAA,EAAA;AAAA,EAGF,WAAW;AAAA,IACT,cAAc,CAAC,SAAyB;AACtC,aAAOH,SAAO,KAAK,IAAI,EAAE,SAAS,WAAW;AAAA,IAC/C;AAAA,IAEA,cAAc,CAAC,SAAyB;AACtC,aAAOA,SAAO,KAAK,MAAM,WAAW,EAAE,SAAS,OAAO;AAAA,IACxD;AAAA,EAAA;AAAA,EAGF,OAAO,KAAiC;AACtC,WAAO,QAAQ,IAAI,GAAG;AAAA,EACxB;AAAA,EAEA,MAAM,SAASI,OAA+B;AAC5C,WAAO,SAASA,OAAM,OAAO;AAAA,EAC/B;AAAA,EAEA,MAAM,UAAUA,OAAc,SAAgC;AAC5D,UAAM,UAAUA,OAAM,SAAS,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,WAAWA,OAA6B;AAC5C,UAAM,GAAGA,OAAM,EAAE,OAAO,MAAM;AAAA,EAChC;AACF;ACnCO,MAAM,iBAA+B;AAAA,EAC1C,QAAQ;AAAA,EACR,aACE;AAAA,EACF,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,MACF,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAEF,UAAU;AAAA,IACR;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,OAAO,YAAA;AAAA,QAChB,QAAQ,CAAC,MAAM,SAAS,YAAY;AAAA,MAAA;AAAA,IACtC;AAAA,IAEF;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,gBAAgB,cAAA;AAAA,QACzB,QAAQ,CAAC,MAAM,SAAS,yBAAyB;AAAA,MAAA;AAAA,IACnD;AAAA,IAEF;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,IAAI,aAAA;AAAA,QACb,SAAS,EAAE,YAAY,KAAA;AAAA,MAAK;AAAA,IAC9B;AAAA,EACF;AAEJ;AAKO,MAAM,kBAAgC;AAAA,EAC3C,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,MACF,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA;AAAA,IAGd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,UAAU;AAAA,cACV,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,IAEd;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,YACN;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,YAAA;AAAA,YAEd;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY;AAAA,cACZ,QAAQ;AAAA,gBACN;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,YAAY;AAAA,gBAAA;AAAA,gBAEd;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,YAAY;AAAA,gBAAA;AAAA,gBAEd;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,YAAY;AAAA,gBAAA;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEF;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aACE;AAAA,UACF,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,QAEd;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAEF,UAAU;AAAA,IACR;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,WAAW,cAAc,MAAM,gBAAA;AAAA,QACxC,QAAQ,CAAC,MAAM,cAAc,kBAAkB;AAAA,MAAA;AAAA,IACjD;AAAA,IAEF;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,UACL,kBAAkB;AAAA,UAClB,sBAAsB,EAAE,KAAK,EAAA;AAAA,QAAE;AAAA,QAEjC,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,IAEF;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,MAAM,gBAAA;AAAA,QACf,QAAQ,CAAC,MAAM,WAAW,iBAAiB,gBAAgB;AAAA,MAAA;AAAA,IAC7D;AAAA,IAEF;AAAA,MACE,aAAa;AAAA,MACb,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,kBAAkB,YAAA;AAAA,QAC3B,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEJ;AAKO,MAAM,mBAAmB;AAAA,EAC9B,aAAa;AAAA,EACb,WAAW;AAAA,IACT;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,aAAa;AAAA,IACX,aACE;AAAA,IACF,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAEJ;AAKO,MAAM,oBAAoB;AAAA,EAC/B,aAAa;AAAA,EACb,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,UAAU;AAAA,IACR,UAAU,CAAC,MAAM,SAAS,SAAS,YAAY;AAAA,IAC/C,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAEJ;AAKO,SAAS,UAAU,QAAiD;AACzE,SAAO,WAAW,aAAa,iBAAiB;AAClD;AAKO,SAAS,gBAKd;AACA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,YAAY;AAAA,EAAA;AAEhB;AAKO,SAAS,uBACd,QACQ;AACR,QAAM,SAAS,UAAU,MAAM;AAC/B,QAAM,QAAkB,CAAA;AAExB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,MAAM,OAAO,WAAW,EAAE;AACrC,QAAM,KAAK,KAAK;AAEhB,QAAM,WAAW,WAAW,aAAa,oBAAoB;AAC7D,QAAM,KAAK,aAAa,QAAQ,IAAI;AAEpC,aAAW,SAAS,OAAO,QAAQ;AACjC,UAAM,WAAW,MAAM,WAAW,MAAM;AACxC,UAAM,WAAW,MAAM,WAAW,iBAAiB;AACnD,UAAM,KAAK,SAAS,MAAM,WAAW,KAAK;AAC1C,UAAM,KAAK,KAAK,MAAM,IAAI,GAAG,QAAQ,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE;AAAA,EACpE;AAEA,QAAM,KAAK,GAAG;AAEd,SAAO,MAAM,KAAK,IAAI;AACxB;AAKO,SAAS,uBAA+B;AAC7C,QAAM,QAAkB,CAAA;AAExB,QAAM,KAAK,iDAAiD;AAG5D,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,eAAe,cAAc,IAAI;AAC5C,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,6CAA6C;AACxD,QAAM,KAAK,6CAA6C;AACxD,aAAW,SAAS,eAAe,QAAQ;AACzC,UAAM,aAAa,MAAM,aAAa,QAAQ;AAC9C,UAAM,WAAW,MAAM,WAAW,gBAAgB;AAClD,UAAM;AAAA,MACJ,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,QAAQ,MAAM,MAAM,WAAW,MAAM,UAAU;AAAA,IAAA;AAAA,EAErF;AAGA,QAAM,KAAK,0BAA0B;AACrC,QAAM,KAAK,gBAAgB,cAAc,IAAI;AAC7C,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,6CAA6C;AACxD,QAAM,KAAK,6CAA6C;AACxD,aAAW,SAAS,gBAAgB,QAAQ;AAC1C,UAAM,aAAa,MAAM,aAAa,QAAQ;AAC9C,UAAM,WAAW,MAAM,WAAW,gBAAgB;AAClD,UAAM;AAAA,MACJ,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,QAAQ,MAAM,MAAM,WAAW,MAAM,UAAU;AAAA,IAAA;AAAA,EAErF;AAGA,QAAM,KAAK,yBAAyB;AACpC,aAAW,MAAM,iBAAiB,WAAW;AAC3C,UAAM,KAAK,OAAO,GAAG,IAAI,OAAO,GAAG,WAAW,EAAE;AAChD,UAAM,KAAK,kBAAkB,GAAG,OAAO,IAAI;AAAA,EAC7C;AAGA,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,iBAAiB,YAAY,cAAc,IAAI;AAC1D,QAAM,KAAK,WAAW;AACtB,aAAW,MAAM,iBAAiB,YAAY,UAAU;AACtD,UAAM,KAAK,OAAO,EAAE,IAAI;AAAA,EAC1B;AAGA,QAAM,KAAK,4BAA4B;AACvC,aAAW,UAAU,kBAAkB,QAAQ;AAC7C,UAAM,KAAK,OAAO,OAAO,IAAI,OAAO,OAAO,WAAW,EAAE;AACxD,UAAM,KAAK,kBAAkB,OAAO,OAAO,IAAI;AAAA,EACjD;AAGA,QAAM,KAAK,uBAAuB;AAClC,QAAM,KAAK,cAAc;AACzB,aAAW,MAAM,eAAe,UAAU;AACxC,UAAM,KAAK;AAAA,IAAO,GAAG,WAAW,IAAI;AACpC,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,GAAG,OAAO,MAAM,CAAC,CAAC;AAC5C,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,QAAM,KAAK,kBAAkB;AAC7B,aAAW,MAAM,gBAAgB,UAAU;AACzC,UAAM,KAAK;AAAA,IAAO,GAAG,WAAW,IAAI;AACpC,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,GAAG,OAAO,MAAM,CAAC,CAAC;AAC5C,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;ACzsBA,MAAM,kBAAkB,IAAI;AAAA,EAC1B,iBAAiB,UAAU,IAAI,CAAC,OAAO,GAAG,IAAI;AAChD;AAEA,MAAM,gBAAgB,oBAAI,IAAI,CAAC,YAAY,YAAY,CAAC;AAExD,MAAM,eAAe,oBAAI,IAAI,CAAC,OAAO,MAAM,CAAC;AAS5C,SAAS,iBACPA,OACA,QACsE;AACtE,QAAM,SAAS,WAAW,aAAa,iBAAiB;AACxD,QAAM,QAAQA,MAAK,MAAM,GAAG;AAE5B,MAAI,gBAA6B,OAAO;AACxC,MAAI,eAAiC;AAErC,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,cAAc,KAAK,CAACC,OAAMA,GAAE,SAAS,IAAI;AACvD,QAAI,CAAC,OAAO;AACV,aAAO,EAAE,OAAO,MAAM,QAAQ,OAAO,eAAe,MAAA;AAAA,IACtD;AACA,mBAAe;AACf,oBAAgB,MAAM,UAAU,CAAA;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,eAAe,cAAc,YAAY;AAAA,EAAA;AAE7C;AAKA,SAAS,mBACP,QACA,SAAS,IACC;AACV,QAAM,SAAS,WAAW,aAAa,iBAAiB;AACxD,QAAM,QAAkB,CAAA;AAExB,WAAS,aAAa,QAAqB,eAAuB;AAChE,eAAW,SAAS,QAAQ;AAC1B,YAAM,WAAW,gBACb,GAAG,aAAa,IAAI,MAAM,IAAI,KAC9B,MAAM;AACV,YAAM,KAAK,QAAQ;AACnB,UAAI,MAAM,QAAQ;AAChB,qBAAa,MAAM,QAAQ,QAAQ;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,eAAa,OAAO,QAAQ,MAAM;AAClC,SAAO;AACT;AASA,SAAS,kBACP,OACA,QACkC;AAClC,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACb;AACD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,SAAS,eACP,OACA,QACkC;AAClC,MAAI,EAAE,UAAU,QAAQ;AACtB,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACb;AACD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,MAAM;AACnB,MAAI,OAAO,SAAS,YAAY,CAAC,cAAc,IAAI,IAAI,GAAG;AACxD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,oBAAoB,IAAI;AAAA,MACjC,YAAY;AAAA,IAAA,CACb;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,eACP,QACA,QACA,QACA,UACM;AACN,MAAI,WAAW,OAAW;AAE1B,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACb;AACD;AAAA,EACF;AAEA,WAASN,KAAI,GAAGA,KAAI,OAAO,QAAQA,MAAK;AACtC,UAAM,OAAO,OAAOA,EAAC;AACrB,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM,UAAUA,EAAC;AAAA,QACjB,SAAS,2CAA2C,OAAO,IAAI;AAAA,MAAA,CAChE;AACD;AAAA,IACF;AAGA,QAAI,SAAS,IAAK;AAGlB,UAAM,cAAc,KAAK,WAAW,GAAG;AACvC,UAAM,YAAY,cAAc,KAAK,MAAM,CAAC,IAAI;AAGhD,UAAM,aAAa,iBAAiB,WAAW,MAAM;AACrD,QAAI,CAAC,WAAW,QAAQ;AACtB,YAAM,aAAa,mBAAmB,MAAM;AAC5C,YAAM,UAAU,WAAW;AAAA,QACzB,CAACO,OACCA,GAAE,SAAS,UAAU,MAAM,GAAG,EAAE,CAAC,CAAC,KAClC,UAAU,MAAM,GAAG,EAAE,CAAC,EAAE,SAASA,GAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MAAA;AAEpD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,UAAUP,EAAC;AAAA,QACjB,SAAS,wBAAwB,SAAS;AAAA,MAAA,CAC3C;AACD,UAAI,QAAQ,SAAS,GAAG;AACtB,iBAAS,SAAS,SAAS,CAAC,EAAE,WAC5B,mBAAmB,QAAQ,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,cACP,OACA,QACA,QACA,UACM;AACN,MAAI,UAAU,OAAW;AAEzB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YACE;AAAA,IAAA,CACH;AACD;AAAA,EACF;AAEA,QAAM,WAAW;AAEjB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,YAAY,SAAS,GAAG;AAG9B,QAAI,QAAQ,UAAU;AACpB,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QAAA,CACV;AAAA,MACH;AACA;AAAA,IACF;AAGA,UAAM,aAAa,iBAAiB,KAAK,MAAM;AAC/C,QAAI,CAAC,WAAW,QAAQ;AACH,yBAAmB,MAAM,EAAE;AAAA,QAC5C,CAACO,OACC,eAAe,OAAO,KAAK,CAACD,OAAMA,GAAE,SAASC,EAAC,GAAG,cACjD,gBAAgB,OAAO,KAAK,CAACD,OAAMA,GAAE,SAASC,EAAC,GAAG;AAAA,MAAA;AAEtD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,mBAAmB,GAAG;AAAA,MAAA,CAChC;AAAA,IACH,WAAW,WAAW,eAAe;AACnC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,qCAAqC,GAAG;AAAA,QACjD,YACE;AAAA,MAAA,CACH;AAAA,IACH,WAAW,WAAW,SAAS,CAAC,WAAW,MAAM,YAAY;AAC3D,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,UAAU,GAAG;AAAA,MAAA,CACvB;AAAA,IACH;AAGA,wBAAoB,OAAO,WAAW,MAAM;AAAA,EAC9C;AACF;AAKA,SAAS,oBACP,OACAF,OACA,QACM;AAEN,MACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WACjB;AACA;AAAA,EACF;AAGA,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACtD,UAAM,QAAQ;AACd,UAAM,OAAO,OAAO,KAAK,KAAK;AAE9B,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAAA;AAAA,QACA,SAAS;AAAA,QACT,YAAY;AAAA,MAAA,CACb;AACD;AAAA,IACF;AAEA,eAAW,MAAM,MAAM;AACrB,UAAI,CAAC,gBAAgB,IAAI,EAAE,GAAG;AAC5B,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,GAAGA,KAAI,IAAI,EAAE;AAAA,UACnB,SAAS,sBAAsB,EAAE;AAAA,UACjC,YAAY,oBAAoB,MAAM,KAAK,eAAe,EAAE,KAAK,IAAI,CAAC;AAAA,QAAA,CACvE;AACD;AAAA,MACF;AAGA,YAAM,UAAU,MAAM,EAAE;AACxB,cAAQ,IAAA;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,cACE,YAAY,QACZ,OAAO,YAAY,YACnB,OAAO,YAAY,YACnB,OAAO,YAAY,WACnB;AACA,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,MAAM,GAAGA,KAAI,IAAI,EAAE;AAAA,cACnB,SAAS,GAAG,EAAE;AAAA,YAAA,CACf;AAAA,UACH;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,YAAY,UAAU;AAC/B,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,MAAM,GAAGA,KAAI,IAAI,EAAE;AAAA,cACnB,SAAS;AAAA,YAAA,CACV;AAAA,UACH;AACA;AAAA,QACF,KAAK;AACH,cAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,MAAM,GAAGA,KAAI,IAAI,EAAE;AAAA,cACnB,SAAS;AAAA,cACT,YAAY;AAAA,YAAA,CACb;AAAA,UACH;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,YAAY,WAAW;AAChC,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,MAAM,GAAGA,KAAI,IAAI,EAAE;AAAA,cACnB,SAAS;AAAA,cACT,YAAY;AAAA,YAAA,CACb;AAAA,UACH;AACA;AAAA,MAAA;AAAA,IAEN;AAAA,EACF,OAAO;AACL,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAAA;AAAA,MACA,SAAS,8BAA8B,OAAO,KAAK;AAAA,MACnD,YACE;AAAA,IAAA,CACH;AAAA,EACH;AACF;AAKA,SAAS,cAAc,OAAgB,QAAiC;AACtE,MAAI,UAAU,OAAW;AAEzB,MAAI,OAAO,UAAU,YAAY,CAAC,aAAa,IAAI,KAAK,GAAG;AACzD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,mBAAmB,KAAK;AAAA,MACjC,YAAY;AAAA,IAAA,CACb;AAAA,EACH;AACF;AAKA,SAAS,cACP,OACA,QACA,UACM;AACN,MAAI,UAAU,OAAW;AAEzB,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,GAAG;AACzD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IAAA,CACV;AACD;AAAA,EACF;AAEA,MAAI,QAAQ,GAAG;AACb,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAEA,MAAI,QAAQ,KAAM;AAChB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,YAAY,KAAK;AAAA,IAAA,CAC3B;AAAA,EACH;AACF;AAKA,SAAS,eACP,QACA,OACA,QACM;AACN,MAAI,WAAW,OAAW;AAE1B,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,GAAG,KAAK;AAAA,IAAA,CAClB;AAAA,EACH;AACF;AAyBO,SAAS,cAAc,OAAkC;AAC9D,QAAM,SAA4B,CAAA;AAClC,QAAM,WAAgC,CAAA;AAGtC,MAAI,CAAC,kBAAkB,OAAO,MAAM,GAAG;AACrC,WAAO,EAAE,OAAO,OAAO,QAAQ,SAAA;AAAA,EACjC;AAEA,QAAM,WAAW;AAGjB,QAAM,SAAS,eAAe,UAAU,MAAM;AAC9C,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,OAAO,OAAO,QAAQ,SAAA;AAAA,EACjC;AAGA,iBAAe,SAAS,QAAQ,QAAQ,QAAQ,QAAQ;AAGxD,gBAAc,SAAS,OAAO,QAAQ,QAAQ,QAAQ;AAGtD,gBAAc,SAAS,OAAO,MAAM;AAGpC,gBAAc,SAAS,OAAO,QAAQ,QAAQ;AAG9C,iBAAe,SAAS,YAAY,cAAc,MAAM;AACxD,iBAAe,SAAS,SAAS,WAAW,MAAM;AAGlD,QAAM,0CAA0B,IAAI;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,aAAW,OAAO,OAAO,KAAK,QAAQ,GAAG;AACvC,QAAI,CAAC,oBAAoB,IAAI,GAAG,GAAG;AACjC,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,yBAAyB,GAAG;AAAA,MAAA,CACtC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,IACA;AAAA,EAAA;AAEJ;AAKO,SAAS,uBAAuB,QAAkC;AACvE,QAAM,QAAkB,CAAA;AAExB,MAAI,OAAO,OAAO;AAChB,UAAM,KAAK,iBAAiB;AAAA,EAC9B,OAAO;AACL,UAAM,KAAK,0BAA0B;AAAA,EACvC;AAEA,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,WAAW;AACtB,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,KAAK,QAAQ,MAAM,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AAChE,UAAI,MAAM,YAAY;AACpB,cAAM,KAAK,mBAAmB,MAAM,UAAU,EAAE;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,aAAa;AACxB,eAAW,WAAW,OAAO,UAAU;AACrC,YAAM,KAAK,QAAQ,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,QAAQ,OAAO,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AC/lBO,MAAM,YAAgC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3C,MAAM,SACJ,UACA,MACA,UACA,YACe;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,MAAM,IAA2B;AACrC,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACxD;AAAA,EAEA,cAAc,MAAc,UAA0B;AACpD,WAAO,QAAQ,QAAQ,WAAW,IAAI;AAAA,EACxC;AAAA,EAEA,MAAM,MAAM,OAAe,MAAuC;AAChE,UAAM,MAAM,MAAM,WAAW,MAAM,OAAO,IAAI;AAC9C,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,QAAQ,IAAI;AAAA,MACZ,MAAM,MAAM,IAAI,KAAA;AAAA,MAChB,MAAM,MAAM,IAAI,KAAA;AAAA,IAAK;AAAA,EAEzB;AAAA,EAEA,SAAS;AAAA,IACP,YAAY,MAAc,WAAW,OAAO,WAAA;AAAA,IAE5C,MAAM,KAAK,MAAc,QAAiC;AACxD,YAAM,MAAM,IAAI,YAAA;AAChB,YAAM,MAAM,MAAM,WAAW,OAAO,OAAO;AAAA,QACzC;AAAA,QACA,IAAI,OAAO,MAAM;AAAA,QACjB,EAAE,MAAM,QAAQ,MAAM,UAAA;AAAA,QACtB;AAAA,QACA,CAAC,MAAM;AAAA,MAAA;AAET,YAAM,YAAY,MAAM,WAAW,OAAO,OAAO;AAAA,QAC/C;AAAA,QACA;AAAA,QACA,IAAI,OAAO,IAAI;AAAA,MAAA;AAEjB,aAAO,KAAK,uBAAuB,SAAS;AAAA,IAC9C;AAAA,IAEA,MAAM,OACJ,MACA,WACA,QACkB;AAClB,YAAM,WAAW,MAAM,KAAK,KAAK,MAAM,MAAM;AAG7C,aAAO,aAAa;AAAA,IACtB;AAAA,IAEA,uBAAuB,QAA6B;AAClD,YAAM,QAAQ,IAAI,WAAW,MAAM;AACnC,UAAI,SAAS;AACb,eAASL,KAAI,GAAGA,KAAI,MAAM,YAAYA,MAAK;AACzC,kBAAU,OAAO,aAAa,MAAMA,EAAC,CAAC;AAAA,MACxC;AAEA,aAAO,KAAK,MAAM,EACf,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA,IACtB;AAAA,EAAA;AAAA,EAGF,WAAW;AAAA,IACT,cAAc,CAAC,SAAyB;AACtC,YAAM,UAAU,IAAI,YAAA;AACpB,YAAM,QAAQ,QAAQ,OAAO,IAAI;AACjC,UAAI,SAAS;AACb,eAASA,KAAI,GAAGA,KAAI,MAAM,QAAQA,MAAK;AACrC,kBAAU,OAAO,aAAa,MAAMA,EAAC,CAAC;AAAA,MACxC;AACA,aAAO,KAAK,MAAM,EACf,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA,IACtB;AAAA,IAEA,cAAc,CAAC,SAAyB;AACtC,YAAM,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AACxD,YAAM,SAAS,KAAK,MAAM;AAC1B,YAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,eAASA,KAAI,GAAGA,KAAI,OAAO,QAAQA,MAAK;AACtC,cAAMA,EAAC,IAAI,OAAO,WAAWA,EAAC;AAAA,MAChC;AACA,YAAM,UAAU,IAAI,YAAA;AACpB,aAAO,QAAQ,OAAO,KAAK;AAAA,IAC7B;AAAA,EAAA;AAAA,EAGF,OAAO,KAAiC;AAEtC,QAAI,OAAQ,WAAmB,SAAS,aAAa;AACnD,aAAQ,WAAmB,KAAK,IAAI,IAAI,GAAG;AAAA,IAC7C;AAEA,QAAI,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjD,aAAO,QAAQ,IAAI,GAAG;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AACF;ACtHA,MAAM,kBAAkB,IAAI,aAAA;AAC5B,MAAM,wBAAwC;AAAA,EAC5C,UAAU,CAAC,cAAsB,IAAI,gBAAgB,WAAW,YAAY;AAAA,EAC5E,SAAS,MAAM,IAAI,mBAAmB,YAAY;AACpD;AASO,SAAS,QAAQ,UAAwB,IAAiB;AAC/D,SAAO,IAAI,gBAAgB,SAAS,uBAAuB,eAAe;AAC5E;AAWO,MAAM,QAAqB,QAAA;"}