{"version":3,"sources":["../src/index.ts","../src/S3FileSystem.ts"],"sourcesContent":["export { S3FileSystem } from \"./S3FileSystem\";\nexport type { S3FileSystemConfig } from \"./types\";","import type {\n  IFileSystem,\n  IReactiveFileSystem,\n  FileEntry,\n  FileStat,\n  FileMetadata,\n  FSEvent,\n  Disposable,\n  FileSystemEventPayloads,\n} from \"@firesystem/core\";\nimport {\n  normalizePath,\n  dirname,\n  basename,\n  join,\n  TypedEventEmitter,\n  FileSystemEvents,\n} from \"@firesystem/core\";\nimport {\n  S3Client,\n  PutObjectCommand,\n  GetObjectCommand,\n  DeleteObjectCommand,\n  ListObjectsV2Command,\n  HeadObjectCommand,\n  CopyObjectCommand,\n  DeleteObjectsCommand,\n  type _Object,\n} from \"@aws-sdk/client-s3\";\nimport type { S3FileSystemConfig } from \"./types\";\n\ninterface WatchListener {\n  id: string;\n  pattern: string;\n  callback: (event: FSEvent) => void;\n}\n\nexport class S3FileSystem implements IReactiveFileSystem {\n  private client: S3Client;\n  private config: S3FileSystemConfig & { prefix: string; mode: \"strict\" | \"lenient\" };\n  private watchers: WatchListener[] = [];\n  public readonly events = new TypedEventEmitter<FileSystemEventPayloads>();\n\n  constructor(config: S3FileSystemConfig) {\n    this.config = {\n      ...config,\n      prefix: config.prefix || \"/\",\n      mode: config.mode || \"strict\",\n    };\n\n    // Normalize prefix\n    if (this.config.prefix !== \"/\") {\n      this.config.prefix = normalizePath(this.config.prefix);\n      if (!this.config.prefix.endsWith(\"/\")) {\n        this.config.prefix += \"/\";\n      }\n      // Remove leading slash for S3\n      this.config.prefix = this.config.prefix.substring(1);\n    }\n\n    this.client = new S3Client({\n      region: config.region,\n      credentials: config.credentials,\n      ...config.clientOptions,\n    });\n  }\n\n  async initialize(): Promise<void> {\n    const startTime = Date.now();\n    this.events.emit(FileSystemEvents.INITIALIZING, undefined as any);\n\n    try {\n      // Only create root directory marker in strict mode\n      if (this.config.mode === \"strict\" && \n          this.config.prefix !== \"/\" && \n          this.config.prefix !== \"\") {\n        await this.ensureDirectoryMarker(this.config.prefix);\n      }\n\n      this.events.emit(FileSystemEvents.INITIALIZED, {\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"initialize\",\n        path: \"/\",\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  private toS3Key(path: string): string {\n    const normalized = normalizePath(path);\n    if (normalized === \"/\") {\n      return this.config.prefix === \"/\" ? \"\" : this.config.prefix;\n    }\n    \n    const withoutLeadingSlash = normalized.substring(1);\n    if (this.config.prefix === \"/\" || this.config.prefix === \"\") {\n      return withoutLeadingSlash;\n    }\n    \n    return this.config.prefix + withoutLeadingSlash;\n  }\n\n  private fromS3Key(key: string): string {\n    if (this.config.prefix === \"/\" || this.config.prefix === \"\") {\n      return \"/\" + key;\n    }\n    \n    if (key.startsWith(this.config.prefix)) {\n      const withoutPrefix = key.substring(this.config.prefix.length);\n      return \"/\" + withoutPrefix;\n    }\n    \n    return \"/\" + key;\n  }\n\n  private async streamToString(stream: any): Promise<string> {\n    const chunks: any[] = [];\n    for await (const chunk of stream) {\n      chunks.push(chunk);\n    }\n    return Buffer.concat(chunks).toString(\"utf-8\");\n  }\n\n  private async ensureDirectoryMarker(s3Key: string): Promise<void> {\n    const key = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n    \n    try {\n      await this.client.send(new PutObjectCommand({\n        Bucket: this.config.bucket,\n        Key: key,\n        Body: \"\",\n        ContentType: \"application/x-directory\",\n        Metadata: {\n          \"x-amz-meta-type\": \"directory\",\n          \"x-amz-meta-created\": new Date().toISOString(),\n        },\n      }));\n    } catch (error) {\n      throw new Error(`Failed to create directory marker: ${error}`);\n    }\n  }\n\n  private async ensureParentExists(path: string): Promise<void> {\n    // Only ensure parent exists in strict mode\n    if (this.config.mode !== \"strict\") return;\n    \n    const parent = dirname(path);\n    if (parent === \"/\" || parent === \".\") return;\n\n    const s3Key = this.toS3Key(parent);\n    await this.ensureDirectoryMarker(s3Key);\n  }\n\n  private parseS3Metadata(metadata?: Record<string, string>): {\n    created?: Date;\n    modified?: Date;\n    fileMetadata?: FileMetadata;\n    type?: \"file\" | \"directory\";\n  } {\n    const result: any = {};\n    \n    if (metadata) {\n      if (metadata[\"x-amz-meta-created\"]) {\n        result.created = new Date(metadata[\"x-amz-meta-created\"]);\n      }\n      if (metadata[\"x-amz-meta-modified\"]) {\n        result.modified = new Date(metadata[\"x-amz-meta-modified\"]);\n      }\n      if (metadata[\"x-amz-meta-type\"]) {\n        result.type = metadata[\"x-amz-meta-type\"] as \"file\" | \"directory\";\n      }\n      if (metadata[\"x-amz-meta-custom\"]) {\n        try {\n          result.fileMetadata = JSON.parse(metadata[\"x-amz-meta-custom\"]);\n        } catch {\n          // Ignore parse errors\n        }\n      }\n    }\n    \n    return result;\n  }\n\n  private createS3Metadata(\n    type: \"file\" | \"directory\",\n    metadata?: FileMetadata,\n    created?: Date,\n  ): Record<string, string> {\n    const now = new Date();\n    const s3Metadata: Record<string, string> = {\n      \"x-amz-meta-type\": type,\n      \"x-amz-meta-created\": (created || now).toISOString(),\n      \"x-amz-meta-modified\": now.toISOString(),\n    };\n\n    if (metadata) {\n      s3Metadata[\"x-amz-meta-custom\"] = JSON.stringify(metadata);\n    }\n\n    return s3Metadata;\n  }\n\n  async readFile(path: string): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `read-${normalized}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"readFile\",\n      path: normalized,\n      id: operationId,\n    });\n\n    try {\n      const s3Key = this.toS3Key(normalized);\n      \n      // First check if it's a directory\n      const dirKey = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n      try {\n        const dirCheck = await this.client.send(new HeadObjectCommand({\n          Bucket: this.config.bucket,\n          Key: dirKey,\n        }));\n        if (dirCheck) {\n          throw new Error(`EISDIR: illegal operation on a directory, read '${normalized}'`);\n        }\n      } catch (error: any) {\n        if (error.name !== \"NoSuchKey\" && !error.message?.includes(\"EISDIR\")) {\n          throw error;\n        }\n      }\n      \n      const response = await this.client.send(new GetObjectCommand({\n        Bucket: this.config.bucket,\n        Key: s3Key,\n      }));\n\n      if (!response.Body) {\n        throw new Error(`File not found: ${normalized}`);\n      }\n\n      const parsedMetadata = this.parseS3Metadata(response.Metadata);\n\n      // In lenient mode, infer type from key\n      let type = parsedMetadata.type;\n      if (!type && this.config.mode === \"lenient\") {\n        type = s3Key.endsWith(\"/\") ? \"directory\" : \"file\";\n      }\n\n      // Check if trying to read a directory\n      if (type === \"directory\" || s3Key.endsWith(\"/\")) {\n        throw new Error(`EISDIR: illegal operation on a directory, read '${normalized}'`);\n      }\n\n      // Read content based on metadata\n      let content: any;\n      if (parsedMetadata.fileMetadata?.isBinary) {\n        // Decode from base64 and return as ArrayBuffer\n        const base64Content = await this.streamToString(response.Body);\n        const buffer = Buffer.from(base64Content, 'base64');\n        content = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n      } else {\n        content = await this.streamToString(response.Body);\n      }\n\n      const result: FileEntry = {\n        path: normalized,\n        name: basename(normalized),\n        type: type || \"file\",\n        size: response.ContentLength || 0,\n        created: parsedMetadata.created || new Date(response.LastModified || Date.now()),\n        modified: parsedMetadata.modified || new Date(response.LastModified || Date.now()),\n        metadata: parsedMetadata.fileMetadata,\n        content: content,\n      };\n\n      this.events.emit(FileSystemEvents.FILE_READ, {\n        path: normalized,\n        size: result.size || 0,\n      });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"readFile\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return result;\n    } catch (error: any) {\n      if (error.name === \"NoSuchKey\") {\n        const notFoundError = new Error(`ENOENT: no such file or directory, open '${normalized}'`);\n        this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n          operation: \"readFile\",\n          path: normalized,\n          error: notFoundError,\n        });\n        throw notFoundError;\n      }\n      \n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"readFile\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async writeFile(\n    path: string,\n    content: any,\n    metadata?: FileMetadata,\n  ): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `write-${normalized}-${startTime}`;\n    let contentStr: string;\n    let isBinary = false;\n    let originalSize: number;\n    \n    if (content === null || content === undefined) {\n      contentStr = \"\";\n      originalSize = 0;\n    } else if (typeof content === \"string\") {\n      contentStr = content;\n      originalSize = Buffer.byteLength(contentStr);\n    } else if (content instanceof ArrayBuffer) {\n      contentStr = Buffer.from(content).toString('base64');\n      isBinary = true;\n      originalSize = content.byteLength; // Use original ArrayBuffer size\n    } else {\n      contentStr = JSON.stringify(content);\n      originalSize = Buffer.byteLength(contentStr);\n    }\n    \n    const size = originalSize;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"writeFile\",\n      path: normalized,\n      id: operationId,\n    });\n    this.events.emit(FileSystemEvents.FILE_WRITING, { path: normalized, size });\n\n    try {\n      // In strict mode, check if parent exists\n      if (this.config.mode === \"strict\") {\n        const parent = dirname(normalized);\n        if (parent !== \"/\" && parent !== \".\") {\n          const parentExists = await this.exists(parent);\n          if (!parentExists) {\n            throw new Error(`ENOENT: no such file or directory, open '${normalized}'`);\n          }\n        }\n      }\n      \n      await this.ensureParentExists(normalized);\n\n      const s3Key = this.toS3Key(normalized);\n      \n      // Check if file already exists to preserve created date\n      let existingCreated: Date | undefined;\n      try {\n        const existing = await this.client.send(new HeadObjectCommand({\n          Bucket: this.config.bucket,\n          Key: s3Key,\n        }));\n        if (existing.Metadata?.[\"x-amz-meta-created\"]) {\n          existingCreated = new Date(existing.Metadata[\"x-amz-meta-created\"]);\n        }\n      } catch {\n        // File doesn't exist, which is fine\n      }\n      \n      const finalMetadata = isBinary ? { ...metadata, isBinary: true } : metadata;\n      const s3Metadata = this.createS3Metadata(\"file\", finalMetadata, existingCreated);\n\n      await this.client.send(new PutObjectCommand({\n        Bucket: this.config.bucket,\n        Key: s3Key,\n        Body: contentStr,\n        ContentType: \"text/plain\",\n        Metadata: s3Metadata,\n      }));\n\n      const now = new Date();\n      const result: FileEntry = {\n        path: normalized,\n        name: basename(normalized),\n        type: \"file\",\n        size,\n        created: existingCreated || new Date(s3Metadata[\"x-amz-meta-created\"]),\n        modified: now,\n        metadata: finalMetadata,\n        content,\n      };\n\n      // Notify watchers\n      this.notifyWatchers({\n        type: existingCreated ? \"updated\" : \"created\",\n        path: normalized,\n        timestamp: now,\n      });\n\n      this.events.emit(FileSystemEvents.FILE_WRITTEN, {\n        path: normalized,\n        size,\n      });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"writeFile\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return result;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"writeFile\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async deleteFile(path: string): Promise<void> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `delete-${normalized}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"deleteFile\",\n      path: normalized,\n      id: operationId,\n    });\n    this.events.emit(FileSystemEvents.FILE_DELETING, { path: normalized });\n\n    try {\n      // Check if file exists first\n      const exists = await this.exists(normalized);\n      if (!exists) {\n        throw new Error(`ENOENT: no such file or directory, unlink '${normalized}'`);\n      }\n      \n      const s3Key = this.toS3Key(normalized);\n      \n      // Check if it's a directory with contents\n      if (await this.isDirectory(normalized)) {\n        const entries = await this.readDir(normalized);\n        if (entries.length > 0) {\n          throw new Error(`ENOTEMPTY: directory not empty, rmdir '${normalized}'`);\n        }\n      }\n      \n      await this.client.send(new DeleteObjectCommand({\n        Bucket: this.config.bucket,\n        Key: s3Key,\n      }));\n\n      // Notify watchers\n      this.notifyWatchers({\n        type: \"deleted\",\n        path: normalized,\n        timestamp: new Date(),\n      });\n\n      this.events.emit(FileSystemEvents.FILE_DELETED, { path: normalized });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"deleteFile\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"deleteFile\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async exists(path: string): Promise<boolean> {\n    const normalized = normalizePath(path);\n    \n    try {\n      const s3Key = this.toS3Key(normalized);\n      \n      // Check as file first\n      try {\n        await this.client.send(new HeadObjectCommand({\n          Bucket: this.config.bucket,\n          Key: s3Key,\n        }));\n        return true;\n      } catch {\n        // In lenient mode, also check if it's a prefix with contents\n        if (this.config.mode === \"lenient\") {\n          const prefix = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n          const response = await this.client.send(new ListObjectsV2Command({\n            Bucket: this.config.bucket,\n            Prefix: prefix,\n            MaxKeys: 1,\n          }));\n          return (response.Contents?.length || 0) > 0;\n        }\n        \n        // In strict mode, check for directory marker\n        const dirKey = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n        try {\n          await this.client.send(new HeadObjectCommand({\n            Bucket: this.config.bucket,\n            Key: dirKey,\n          }));\n          return true;\n        } catch {\n          return false;\n        }\n      }\n    } catch {\n      return false;\n    }\n  }\n\n  async readDir(path: string): Promise<FileEntry[]> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `readdir-${normalized}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"readDir\",\n      path: normalized,\n      id: operationId,\n    });\n\n    try {\n      // Check if directory exists first (except root)\n      if (normalized !== \"/\") {\n        const exists = await this.exists(normalized);\n        if (!exists) {\n          throw new Error(`ENOENT: no such file or directory, scandir '${normalized}'`);\n        }\n      }\n      \n      const s3Prefix = this.toS3Key(normalized);\n      const prefix = s3Prefix === \"\" ? \"\" : (s3Prefix.endsWith(\"/\") ? s3Prefix : s3Prefix + \"/\");\n      \n      const entries: FileEntry[] = [];\n      const seenPaths = new Set<string>();\n      let continuationToken: string | undefined;\n\n      do {\n        const response = await this.client.send(new ListObjectsV2Command({\n          Bucket: this.config.bucket,\n          Prefix: prefix,\n          Delimiter: \"/\",\n          ContinuationToken: continuationToken,\n        }));\n\n        // Add directories (CommonPrefixes)\n        if (response.CommonPrefixes) {\n          for (const commonPrefix of response.CommonPrefixes) {\n            if (commonPrefix.Prefix) {\n              const path = this.fromS3Key(commonPrefix.Prefix);\n              if (!seenPaths.has(path)) {\n                seenPaths.add(path);\n                entries.push({\n                  path,\n                  name: basename(path.endsWith(\"/\") ? path.slice(0, -1) : path),\n                  type: \"directory\",\n                  size: 0,\n                  created: new Date(),\n                  modified: new Date(),\n                });\n              }\n            }\n          }\n        }\n\n        // Add files (Contents)\n        if (response.Contents) {\n          for (const object of response.Contents) {\n            if (object.Key) {\n              // Skip directory markers\n              if (object.Key.endsWith(\"/\")) continue;\n              \n              // Skip objects not directly in this directory\n              const relativePath = object.Key.substring(prefix.length);\n              if (relativePath.includes(\"/\")) continue;\n\n              const path = this.fromS3Key(object.Key);\n              if (!seenPaths.has(path)) {\n                seenPaths.add(path);\n                entries.push({\n                  path,\n                  name: basename(path),\n                  type: \"file\",\n                  size: object.Size || 0,\n                  created: object.LastModified || new Date(),\n                  modified: object.LastModified || new Date(),\n                });\n              }\n            }\n          }\n        }\n\n        continuationToken = response.NextContinuationToken;\n      } while (continuationToken);\n\n      this.events.emit(FileSystemEvents.DIR_READ, {\n        path: normalized,\n        count: entries.length,\n      });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"readDir\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return entries;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"readDir\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async mkdir(path: string, recursive?: boolean): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `mkdir-${normalized}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"mkdir\",\n      path: normalized,\n      id: operationId,\n    });\n    this.events.emit(FileSystemEvents.DIR_CREATING, { path: normalized, recursive: !!recursive });\n\n    try {\n      // Check if trying to create root\n      if (normalized === \"/\") {\n        throw new Error(`EEXIST: file already exists, mkdir '${normalized}'`);\n      }\n      \n      // Check if directory already exists\n      if (await this.exists(normalized)) {\n        throw new Error(`EEXIST: file already exists, mkdir '${normalized}'`);\n      }\n      \n      // In lenient mode, directories are virtual - just return success\n      if (this.config.mode === \"lenient\") {\n        const now = new Date();\n        const result: FileEntry = {\n          path: normalized,\n          name: basename(normalized),\n          type: \"directory\",\n          size: 0,\n          created: now,\n          modified: now,\n        };\n\n        this.notifyWatchers({\n          type: \"created\",\n          path: normalized,\n          timestamp: now,\n        });\n\n        this.events.emit(FileSystemEvents.DIR_CREATED, { path: normalized });\n        this.events.emit(FileSystemEvents.OPERATION_END, {\n          operation: \"mkdir\",\n          path: normalized,\n          id: operationId,\n          duration: Date.now() - startTime,\n        });\n\n        return result;\n      }\n\n      // Strict mode - create directory markers\n      if (recursive) {\n        // Create all parent directories\n        const parts = normalized.split(\"/\").filter(Boolean);\n        let currentPath = \"\";\n        \n        for (const part of parts) {\n          currentPath += \"/\" + part;\n          const s3Key = this.toS3Key(currentPath);\n          await this.ensureDirectoryMarker(s3Key);\n        }\n      } else {\n        // Check if parent exists\n        const parent = dirname(normalized);\n        if (parent !== \"/\" && parent !== \".\") {\n          const parentExists = await this.exists(parent);\n          if (!parentExists) {\n            throw new Error(`ENOENT: no such file or directory, mkdir '${normalized}'`);\n          }\n        }\n        \n        // Ensure parent exists\n        await this.ensureParentExists(normalized);\n        \n        // Create directory marker\n        const s3Key = this.toS3Key(normalized);\n        await this.ensureDirectoryMarker(s3Key);\n      }\n\n      const now = new Date();\n      const result: FileEntry = {\n        path: normalized,\n        name: basename(normalized),\n        type: \"directory\",\n        size: 0,\n        created: now,\n        modified: now,\n      };\n\n      // Notify watchers\n      this.notifyWatchers({\n        type: \"created\",\n        path: normalized,\n        timestamp: now,\n      });\n\n      this.events.emit(FileSystemEvents.DIR_CREATED, { path: normalized });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"mkdir\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return result;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"mkdir\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async rmdir(path: string, recursive?: boolean): Promise<void> {\n    const normalized = normalizePath(path);\n    const startTime = Date.now();\n    const operationId = `rmdir-${normalized}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"rmdir\",\n      path: normalized,\n      id: operationId,\n    });\n    this.events.emit(FileSystemEvents.DIR_DELETING, { path: normalized, recursive: !!recursive });\n\n    try {\n      // Check if trying to remove root\n      if (normalized === \"/\") {\n        throw new Error(`EBUSY: resource busy or locked, rmdir '${normalized}'`);\n      }\n      \n      // Check if directory exists\n      const exists = await this.exists(normalized);\n      if (!exists) {\n        throw new Error(`ENOENT: no such file or directory, rmdir '${normalized}'`);\n      }\n      \n      // Check if it's actually a file\n      if (!await this.isDirectory(normalized)) {\n        throw new Error(`ENOTDIR: not a directory, rmdir '${normalized}'`);\n      }\n      \n      const s3Prefix = this.toS3Key(normalized);\n      const prefix = s3Prefix.endsWith(\"/\") ? s3Prefix : s3Prefix + \"/\";\n\n      if (recursive) {\n        // Delete all objects with this prefix\n        const objectsToDelete: { Key: string }[] = [];\n        let continuationToken: string | undefined;\n\n        do {\n          const response = await this.client.send(new ListObjectsV2Command({\n            Bucket: this.config.bucket,\n            Prefix: prefix,\n            ContinuationToken: continuationToken,\n          }));\n\n          if (response.Contents) {\n            for (const object of response.Contents) {\n              if (object.Key) {\n                objectsToDelete.push({ Key: object.Key });\n              }\n            }\n          }\n\n          continuationToken = response.NextContinuationToken;\n        } while (continuationToken);\n\n        // Delete in batches (S3 allows max 1000 per request)\n        const batchSize = 1000;\n        for (let i = 0; i < objectsToDelete.length; i += batchSize) {\n          const batch = objectsToDelete.slice(i, i + batchSize);\n          await this.client.send(new DeleteObjectsCommand({\n            Bucket: this.config.bucket,\n            Delete: { Objects: batch },\n          }));\n        }\n      } else {\n        // Check if directory is empty\n        const response = await this.client.send(new ListObjectsV2Command({\n          Bucket: this.config.bucket,\n          Prefix: prefix,\n          MaxKeys: 2, // We only need to know if there's more than the dir marker\n        }));\n\n        const hasContents = (response.Contents?.length || 0) > 1 ||\n          (response.Contents?.length === 1 && !response.Contents[0].Key?.endsWith(\"/\"));\n\n        if (hasContents) {\n          throw new Error(`ENOTEMPTY: directory not empty, rmdir '${normalized}'`);\n        }\n\n        // Delete directory marker\n        await this.client.send(new DeleteObjectCommand({\n          Bucket: this.config.bucket,\n          Key: prefix,\n        }));\n      }\n\n      // Notify watchers\n      this.notifyWatchers({\n        type: \"deleted\",\n        path: normalized,\n        timestamp: new Date(),\n      });\n\n      this.events.emit(FileSystemEvents.DIR_DELETED, { path: normalized });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"rmdir\",\n        path: normalized,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"rmdir\",\n        path: normalized,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async rename(oldPath: string, newPath: string): Promise<FileEntry> {\n    const normalizedOld = normalizePath(oldPath);\n    const normalizedNew = normalizePath(newPath);\n    const startTime = Date.now();\n    const operationId = `rename-${normalizedOld}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"rename\",\n      path: normalizedOld,\n      id: operationId,\n    });\n\n    try {\n      // Check if source exists\n      if (!await this.exists(normalizedOld)) {\n        throw new Error(`ENOENT: no such file or directory, rename '${normalizedOld}' -> '${normalizedNew}'`);\n      }\n      \n      // Check if target already exists\n      if (await this.exists(normalizedNew)) {\n        throw new Error(`EEXIST: file already exists, rename '${normalizedOld}' -> '${normalizedNew}'`);\n      }\n      \n      // Check if new parent exists\n      const newParent = dirname(normalizedNew);\n      if (newParent !== \"/\" && newParent !== \".\" && !await this.exists(newParent)) {\n        throw new Error(`ENOENT: no such file or directory, rename '${normalizedOld}' -> '${normalizedNew}'`);\n      }\n      \n      // Read the old file/directory\n      const oldEntry = await this.readFile(normalizedOld);\n      \n      if (oldEntry.type === \"file\") {\n        // Copy and delete for files\n        await this.writeFile(normalizedNew, oldEntry.content, oldEntry.metadata);\n        await this.deleteFile(normalizedOld);\n      } else {\n        // For directories, we need to rename all contents\n        await this.move([normalizedOld], dirname(normalizedNew));\n      }\n\n      const result = await this.readFile(normalizedNew);\n\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"rename\",\n        path: normalizedOld,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return result;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"rename\",\n        path: normalizedOld,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async move(sourcePaths: string[], targetPath: string): Promise<void> {\n    const normalizedTarget = normalizePath(targetPath);\n    const startTime = Date.now();\n    const operationId = `move-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"move\",\n      path: sourcePaths[0],\n      id: operationId,\n    });\n\n    try {\n      // Check if target exists and is a directory\n      if (!await this.exists(normalizedTarget)) {\n        throw new Error(`ENOENT: no such file or directory, open '${normalizedTarget}'`);\n      }\n      \n      if (!await this.isDirectory(normalizedTarget)) {\n        throw new Error(`ENOTDIR: not a directory, open '${normalizedTarget}'`);\n      }\n      \n      for (const sourcePath of sourcePaths) {\n        const normalizedSource = normalizePath(sourcePath);\n        const targetFilePath = join(normalizedTarget, basename(normalizedSource));\n        \n        // Read source\n        const sourceEntry = await this.readFile(normalizedSource);\n        \n        // Write to target\n        await this.writeFile(targetFilePath, sourceEntry.content, sourceEntry.metadata);\n        \n        // Delete source\n        await this.deleteFile(normalizedSource);\n      }\n\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"move\",\n        path: sourcePaths[0],\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"move\",\n        path: sourcePaths[0],\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async copy(sourcePath: string, targetPath: string): Promise<FileEntry> {\n    const normalizedSource = normalizePath(sourcePath);\n    const normalizedTarget = normalizePath(targetPath);\n    const startTime = Date.now();\n    const operationId = `copy-${normalizedSource}-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"copy\",\n      path: normalizedSource,\n      id: operationId,\n    });\n\n    try {\n      // Check if source is a directory\n      if (await this.isDirectory(normalizedSource)) {\n        throw new Error(`EISDIR: illegal operation on a directory, open '${normalizedSource}'`);\n      }\n      \n      // Read source\n      const sourceEntry = await this.readFile(normalizedSource);\n      \n      // Write to target\n      const result = await this.writeFile(\n        normalizedTarget,\n        sourceEntry.content,\n        sourceEntry.metadata,\n      );\n\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"copy\",\n        path: normalizedSource,\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return result;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"copy\",\n        path: normalizedSource,\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  watch(pattern: string, callback: (event: FSEvent) => void): Disposable {\n    const id = Math.random().toString(36).substr(2, 9);\n    const listener: WatchListener = { id, pattern, callback };\n    this.watchers.push(listener);\n\n    return {\n      dispose: () => {\n        const index = this.watchers.findIndex((w) => w.id === id);\n        if (index !== -1) {\n          this.watchers.splice(index, 1);\n        }\n      },\n    };\n  }\n\n  private notifyWatchers(event: FSEvent): void {\n    for (const watcher of this.watchers) {\n      // Simple pattern matching (could be enhanced with glob)\n      if (\n        watcher.pattern === \"*\" ||\n        event.path.includes(watcher.pattern) ||\n        this.matchGlob(event.path, watcher.pattern)\n      ) {\n        watcher.callback(event);\n      }\n    }\n  }\n\n  private matchGlob(path: string, pattern: string): boolean {\n    // Enhanced glob matching\n    if (pattern === \"*\") {\n      // Single * matches files and directories in root\n      return path.split(\"/\").length === 2;\n    }\n    \n    if (pattern === \"**\") {\n      // ** matches everything\n      return true;\n    }\n    \n    // Convert glob to regex\n    let regex = pattern\n      .replace(/\\*\\*/g, \"___DOUBLE_STAR___\")\n      .replace(/\\*/g, \"[^/]*\")\n      .replace(/___DOUBLE_STAR___/g, \".*\")\n      .replace(/\\?/g, \".\")\n      .replace(/\\//g, \"\\\\/\");\n    \n    return new RegExp(\"^\" + regex + \"$\").test(path);\n  }\n\n  private async isDirectory(path: string): Promise<boolean> {\n    const normalized = normalizePath(path);\n    const s3Key = this.toS3Key(normalized);\n    const dirKey = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n    \n    try {\n      const response = await this.client.send(new HeadObjectCommand({\n        Bucket: this.config.bucket,\n        Key: dirKey,\n      }));\n      return response.Metadata?.[\"x-amz-meta-type\"] === \"directory\";\n    } catch {\n      // Check if any objects exist with this prefix\n      const response = await this.client.send(new ListObjectsV2Command({\n        Bucket: this.config.bucket,\n        Prefix: dirKey,\n        MaxKeys: 1,\n      }));\n      return (response.Contents?.length || 0) > 0;\n    }\n  }\n\n  async stat(path: string): Promise<FileStat> {\n    const normalized = normalizePath(path);\n    \n    try {\n      // Check if it's a directory first\n      if (await this.isDirectory(normalized)) {\n        const s3Key = this.toS3Key(normalized);\n        const dirKey = s3Key.endsWith(\"/\") ? s3Key : s3Key + \"/\";\n        \n        try {\n          const response = await this.client.send(new HeadObjectCommand({\n            Bucket: this.config.bucket,\n            Key: dirKey,\n          }));\n          \n          const metadata = this.parseS3Metadata(response.Metadata);\n          return {\n            path: normalized,\n            size: 0,\n            type: \"directory\",\n            created: metadata.created || new Date(response.LastModified || Date.now()),\n            modified: metadata.modified || new Date(response.LastModified || Date.now()),\n          };\n        } catch {\n          // Directory exists but no marker\n          return {\n            path: normalized,\n            size: 0,\n            type: \"directory\",\n            created: new Date(),\n            modified: new Date(),\n          };\n        }\n      }\n      \n      // It's a file\n      const entry = await this.readFile(normalized);\n      \n      return {\n        path: entry.path,\n        size: entry.size || 0,\n        type: entry.type,\n        created: entry.created || new Date(),\n        modified: entry.modified || new Date(),\n      };\n    } catch (error: any) {\n      if (error.message?.includes(\"EISDIR\")) {\n        // Handle the case where readFile throws EISDIR\n        return {\n          path: normalized,\n          size: 0,\n          type: \"directory\",\n          created: new Date(),\n          modified: new Date(),\n        };\n      }\n      throw new Error(`Failed to stat ${normalized}: ${error}`);\n    }\n  }\n\n  async glob(pattern: string): Promise<string[]> {\n    const results: string[] = [];\n    const seenPaths = new Set<string>();\n    \n    // Convert glob pattern to prefix for S3\n    const prefix = pattern.split(\"*\")[0].replace(/^\\//, \"\");\n    const s3Prefix = this.config.prefix === \"/\" ? prefix : this.config.prefix + prefix;\n    \n    let continuationToken: string | undefined;\n    \n    do {\n      const response = await this.client.send(new ListObjectsV2Command({\n        Bucket: this.config.bucket,\n        Prefix: s3Prefix,\n        ContinuationToken: continuationToken,\n      }));\n\n      // Add files\n      if (response.Contents) {\n        for (const object of response.Contents) {\n          if (object.Key) {\n            const path = this.fromS3Key(object.Key);\n            \n            // Add the file itself if it matches (skip directory markers)\n            if (!object.Key.endsWith(\"/\") && this.matchGlob(path, pattern)) {\n              seenPaths.add(path);\n            }\n            \n            // Also check parent directories for patterns like \"*\"\n            if (pattern === \"*\" || pattern === \"**\") {\n              const parts = path.split(\"/\").filter(Boolean);\n              for (let i = 1; i <= parts.length - 1; i++) {\n                const dirPath = \"/\" + parts.slice(0, i).join(\"/\");\n                if (this.matchGlob(dirPath, pattern)) {\n                  seenPaths.add(dirPath);\n                }\n              }\n            }\n          }\n        }\n      }\n\n      continuationToken = response.NextContinuationToken;\n    } while (continuationToken);\n\n    return Array.from(seenPaths).sort();\n  }\n\n  async clear(): Promise<void> {\n    const startTime = Date.now();\n    const operationId = `clear-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"clear\",\n      path: \"/\",\n      id: operationId,\n    });\n\n    try {\n      // List and delete all objects\n      const objectsToDelete: { Key: string }[] = [];\n      let continuationToken: string | undefined;\n\n      do {\n        const response = await this.client.send(new ListObjectsV2Command({\n          Bucket: this.config.bucket,\n          Prefix: this.config.prefix === \"/\" ? \"\" : this.config.prefix,\n          ContinuationToken: continuationToken,\n        }));\n\n        if (response.Contents) {\n          for (const object of response.Contents) {\n            if (object.Key) {\n              objectsToDelete.push({ Key: object.Key });\n            }\n          }\n        }\n\n        continuationToken = response.NextContinuationToken;\n      } while (continuationToken);\n\n      // Delete in batches\n      const batchSize = 1000;\n      for (let i = 0; i < objectsToDelete.length; i += batchSize) {\n        const batch = objectsToDelete.slice(i, i + batchSize);\n        await this.client.send(new DeleteObjectsCommand({\n          Bucket: this.config.bucket,\n          Delete: { Objects: batch },\n        }));\n      }\n\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"clear\",\n        path: \"/\",\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"clear\",\n        path: \"/\",\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async size(): Promise<number> {\n    let totalSize = 0;\n    let continuationToken: string | undefined;\n\n    do {\n      const response = await this.client.send(new ListObjectsV2Command({\n        Bucket: this.config.bucket,\n        Prefix: this.config.prefix === \"/\" ? \"\" : this.config.prefix,\n        ContinuationToken: continuationToken,\n      }));\n\n      if (response.Contents) {\n        for (const object of response.Contents) {\n          totalSize += object.Size || 0;\n        }\n      }\n\n      continuationToken = response.NextContinuationToken;\n    } while (continuationToken);\n\n    return totalSize;\n  }\n\n  // Implementações temporárias para compilar - S3 será implementado no futuro\n  async canModify(path: string): Promise<boolean> {\n    // TODO: Implementar verificação real de permissões S3\n    return true;\n  }\n\n  async canCreateIn(parentPath: string): Promise<boolean> {\n    // TODO: Implementar verificação real de permissões S3\n    return true;\n  }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACUA,kBAOO;AACP,uBAUO;AASA,IAAM,eAAN,MAAkD;AAAA,EAMvD,YAAY,QAA4B;AAHxC,SAAQ,WAA4B,CAAC;AACrC,SAAgB,SAAS,IAAI,8BAA2C;AAGtE,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,QAAQ,OAAO,UAAU;AAAA,MACzB,MAAM,OAAO,QAAQ;AAAA,IACvB;AAGA,QAAI,KAAK,OAAO,WAAW,KAAK;AAC9B,WAAK,OAAO,aAAS,2BAAc,KAAK,OAAO,MAAM;AACrD,UAAI,CAAC,KAAK,OAAO,OAAO,SAAS,GAAG,GAAG;AACrC,aAAK,OAAO,UAAU;AAAA,MACxB;AAEA,WAAK,OAAO,SAAS,KAAK,OAAO,OAAO,UAAU,CAAC;AAAA,IACrD;AAEA,SAAK,SAAS,IAAI,0BAAS;AAAA,MACzB,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO;AAAA,MACpB,GAAG,OAAO;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAA4B;AAChC,UAAM,YAAY,KAAK,IAAI;AAC3B,SAAK,OAAO,KAAK,6BAAiB,cAAc,MAAgB;AAEhE,QAAI;AAEF,UAAI,KAAK,OAAO,SAAS,YACrB,KAAK,OAAO,WAAW,OACvB,KAAK,OAAO,WAAW,IAAI;AAC7B,cAAM,KAAK,sBAAsB,KAAK,OAAO,MAAM;AAAA,MACrD;AAEA,WAAK,OAAO,KAAK,6BAAiB,aAAa;AAAA,QAC7C,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,QAAQ,MAAsB;AACpC,UAAM,iBAAa,2BAAc,IAAI;AACrC,QAAI,eAAe,KAAK;AACtB,aAAO,KAAK,OAAO,WAAW,MAAM,KAAK,KAAK,OAAO;AAAA,IACvD;AAEA,UAAM,sBAAsB,WAAW,UAAU,CAAC;AAClD,QAAI,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,WAAW,IAAI;AAC3D,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEQ,UAAU,KAAqB;AACrC,QAAI,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,WAAW,IAAI;AAC3D,aAAO,MAAM;AAAA,IACf;AAEA,QAAI,IAAI,WAAW,KAAK,OAAO,MAAM,GAAG;AACtC,YAAM,gBAAgB,IAAI,UAAU,KAAK,OAAO,OAAO,MAAM;AAC7D,aAAO,MAAM;AAAA,IACf;AAEA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAc,eAAe,QAA8B;AACzD,UAAM,SAAgB,CAAC;AACvB,qBAAiB,SAAS,QAAQ;AAChC,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,WAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAAA,EAC/C;AAAA,EAEA,MAAc,sBAAsB,OAA8B;AAChE,UAAM,MAAM,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AAElD,QAAI;AACF,YAAM,KAAK,OAAO,KAAK,IAAI,kCAAiB;AAAA,QAC1C,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAK;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,QACb,UAAU;AAAA,UACR,mBAAmB;AAAA,UACnB,uBAAsB,oBAAI,KAAK,GAAE,YAAY;AAAA,QAC/C;AAAA,MACF,CAAC,CAAC;AAAA,IACJ,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,MAA6B;AAE5D,QAAI,KAAK,OAAO,SAAS,SAAU;AAEnC,UAAM,aAAS,qBAAQ,IAAI;AAC3B,QAAI,WAAW,OAAO,WAAW,IAAK;AAEtC,UAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,UAAM,KAAK,sBAAsB,KAAK;AAAA,EACxC;AAAA,EAEQ,gBAAgB,UAKtB;AACA,UAAM,SAAc,CAAC;AAErB,QAAI,UAAU;AACZ,UAAI,SAAS,oBAAoB,GAAG;AAClC,eAAO,UAAU,IAAI,KAAK,SAAS,oBAAoB,CAAC;AAAA,MAC1D;AACA,UAAI,SAAS,qBAAqB,GAAG;AACnC,eAAO,WAAW,IAAI,KAAK,SAAS,qBAAqB,CAAC;AAAA,MAC5D;AACA,UAAI,SAAS,iBAAiB,GAAG;AAC/B,eAAO,OAAO,SAAS,iBAAiB;AAAA,MAC1C;AACA,UAAI,SAAS,mBAAmB,GAAG;AACjC,YAAI;AACF,iBAAO,eAAe,KAAK,MAAM,SAAS,mBAAmB,CAAC;AAAA,QAChE,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,iBACN,MACA,UACA,SACwB;AACxB,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,aAAqC;AAAA,MACzC,mBAAmB;AAAA,MACnB,uBAAuB,WAAW,KAAK,YAAY;AAAA,MACnD,uBAAuB,IAAI,YAAY;AAAA,IACzC;AAEA,QAAI,UAAU;AACZ,iBAAW,mBAAmB,IAAI,KAAK,UAAU,QAAQ;AAAA,IAC3D;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,MAAkC;AAC/C,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,QAAQ,UAAU,IAAI,SAAS;AAEnD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AACF,YAAM,QAAQ,KAAK,QAAQ,UAAU;AAGrC,YAAM,SAAS,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AACrD,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,UAC5D,QAAQ,KAAK,OAAO;AAAA,UACpB,KAAK;AAAA,QACP,CAAC,CAAC;AACF,YAAI,UAAU;AACZ,gBAAM,IAAI,MAAM,mDAAmD,UAAU,GAAG;AAAA,QAClF;AAAA,MACF,SAAS,OAAY;AACnB,YAAI,MAAM,SAAS,eAAe,CAAC,MAAM,SAAS,SAAS,QAAQ,GAAG;AACpE,gBAAM;AAAA,QACR;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,kCAAiB;AAAA,QAC3D,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAK;AAAA,MACP,CAAC,CAAC;AAEF,UAAI,CAAC,SAAS,MAAM;AAClB,cAAM,IAAI,MAAM,mBAAmB,UAAU,EAAE;AAAA,MACjD;AAEA,YAAM,iBAAiB,KAAK,gBAAgB,SAAS,QAAQ;AAG7D,UAAI,OAAO,eAAe;AAC1B,UAAI,CAAC,QAAQ,KAAK,OAAO,SAAS,WAAW;AAC3C,eAAO,MAAM,SAAS,GAAG,IAAI,cAAc;AAAA,MAC7C;AAGA,UAAI,SAAS,eAAe,MAAM,SAAS,GAAG,GAAG;AAC/C,cAAM,IAAI,MAAM,mDAAmD,UAAU,GAAG;AAAA,MAClF;AAGA,UAAI;AACJ,UAAI,eAAe,cAAc,UAAU;AAEzC,cAAM,gBAAgB,MAAM,KAAK,eAAe,SAAS,IAAI;AAC7D,cAAM,SAAS,OAAO,KAAK,eAAe,QAAQ;AAClD,kBAAU,OAAO,OAAO,MAAM,OAAO,YAAY,OAAO,aAAa,OAAO,UAAU;AAAA,MACxF,OAAO;AACL,kBAAU,MAAM,KAAK,eAAe,SAAS,IAAI;AAAA,MACnD;AAEA,YAAM,SAAoB;AAAA,QACxB,MAAM;AAAA,QACN,UAAM,sBAAS,UAAU;AAAA,QACzB,MAAM,QAAQ;AAAA,QACd,MAAM,SAAS,iBAAiB;AAAA,QAChC,SAAS,eAAe,WAAW,IAAI,KAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC;AAAA,QAC/E,UAAU,eAAe,YAAY,IAAI,KAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC;AAAA,QACjF,UAAU,eAAe;AAAA,QACzB;AAAA,MACF;AAEA,WAAK,OAAO,KAAK,6BAAiB,WAAW;AAAA,QAC3C,MAAM;AAAA,QACN,MAAM,OAAO,QAAQ;AAAA,MACvB,CAAC;AACD,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAY;AACnB,UAAI,MAAM,SAAS,aAAa;AAC9B,cAAM,gBAAgB,IAAI,MAAM,4CAA4C,UAAU,GAAG;AACzF,aAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,UACjD,WAAW;AAAA,UACX,MAAM;AAAA,UACN,OAAO;AAAA,QACT,CAAC;AACD,cAAM;AAAA,MACR;AAEA,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,UACJ,MACA,SACA,UACoB;AACpB,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,SAAS,UAAU,IAAI,SAAS;AACpD,QAAI;AACJ,QAAI,WAAW;AACf,QAAI;AAEJ,QAAI,YAAY,QAAQ,YAAY,QAAW;AAC7C,mBAAa;AACb,qBAAe;AAAA,IACjB,WAAW,OAAO,YAAY,UAAU;AACtC,mBAAa;AACb,qBAAe,OAAO,WAAW,UAAU;AAAA,IAC7C,WAAW,mBAAmB,aAAa;AACzC,mBAAa,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ;AACnD,iBAAW;AACX,qBAAe,QAAQ;AAAA,IACzB,OAAO;AACL,mBAAa,KAAK,UAAU,OAAO;AACnC,qBAAe,OAAO,WAAW,UAAU;AAAA,IAC7C;AAEA,UAAM,OAAO;AAEb,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AACD,SAAK,OAAO,KAAK,6BAAiB,cAAc,EAAE,MAAM,YAAY,KAAK,CAAC;AAE1E,QAAI;AAEF,UAAI,KAAK,OAAO,SAAS,UAAU;AACjC,cAAM,aAAS,qBAAQ,UAAU;AACjC,YAAI,WAAW,OAAO,WAAW,KAAK;AACpC,gBAAM,eAAe,MAAM,KAAK,OAAO,MAAM;AAC7C,cAAI,CAAC,cAAc;AACjB,kBAAM,IAAI,MAAM,4CAA4C,UAAU,GAAG;AAAA,UAC3E;AAAA,QACF;AAAA,MACF;AAEA,YAAM,KAAK,mBAAmB,UAAU;AAExC,YAAM,QAAQ,KAAK,QAAQ,UAAU;AAGrC,UAAI;AACJ,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,UAC5D,QAAQ,KAAK,OAAO;AAAA,UACpB,KAAK;AAAA,QACP,CAAC,CAAC;AACF,YAAI,SAAS,WAAW,oBAAoB,GAAG;AAC7C,4BAAkB,IAAI,KAAK,SAAS,SAAS,oBAAoB,CAAC;AAAA,QACpE;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,YAAM,gBAAgB,WAAW,EAAE,GAAG,UAAU,UAAU,KAAK,IAAI;AACnE,YAAM,aAAa,KAAK,iBAAiB,QAAQ,eAAe,eAAe;AAE/E,YAAM,KAAK,OAAO,KAAK,IAAI,kCAAiB;AAAA,QAC1C,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAK;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,QACb,UAAU;AAAA,MACZ,CAAC,CAAC;AAEF,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,SAAoB;AAAA,QACxB,MAAM;AAAA,QACN,UAAM,sBAAS,UAAU;AAAA,QACzB,MAAM;AAAA,QACN;AAAA,QACA,SAAS,mBAAmB,IAAI,KAAK,WAAW,oBAAoB,CAAC;AAAA,QACrE,UAAU;AAAA,QACV,UAAU;AAAA,QACV;AAAA,MACF;AAGA,WAAK,eAAe;AAAA,QAClB,MAAM,kBAAkB,YAAY;AAAA,QACpC,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,WAAK,OAAO,KAAK,6BAAiB,cAAc;AAAA,QAC9C,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,MAA6B;AAC5C,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,UAAU,UAAU,IAAI,SAAS;AAErD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AACD,SAAK,OAAO,KAAK,6BAAiB,eAAe,EAAE,MAAM,WAAW,CAAC;AAErE,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK,OAAO,UAAU;AAC3C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,8CAA8C,UAAU,GAAG;AAAA,MAC7E;AAEA,YAAM,QAAQ,KAAK,QAAQ,UAAU;AAGrC,UAAI,MAAM,KAAK,YAAY,UAAU,GAAG;AACtC,cAAM,UAAU,MAAM,KAAK,QAAQ,UAAU;AAC7C,YAAI,QAAQ,SAAS,GAAG;AACtB,gBAAM,IAAI,MAAM,0CAA0C,UAAU,GAAG;AAAA,QACzE;AAAA,MACF;AAEA,YAAM,KAAK,OAAO,KAAK,IAAI,qCAAoB;AAAA,QAC7C,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAK;AAAA,MACP,CAAC,CAAC;AAGF,WAAK,eAAe;AAAA,QAClB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AAED,WAAK,OAAO,KAAK,6BAAiB,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAgC;AAC3C,UAAM,iBAAa,2BAAc,IAAI;AAErC,QAAI;AACF,YAAM,QAAQ,KAAK,QAAQ,UAAU;AAGrC,UAAI;AACF,cAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,UAC3C,QAAQ,KAAK,OAAO;AAAA,UACpB,KAAK;AAAA,QACP,CAAC,CAAC;AACF,eAAO;AAAA,MACT,QAAQ;AAEN,YAAI,KAAK,OAAO,SAAS,WAAW;AAClC,gBAAM,SAAS,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AACrD,gBAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,YAC/D,QAAQ,KAAK,OAAO;AAAA,YACpB,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC,CAAC;AACF,kBAAQ,SAAS,UAAU,UAAU,KAAK;AAAA,QAC5C;AAGA,cAAM,SAAS,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AACrD,YAAI;AACF,gBAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,YAC3C,QAAQ,KAAK,OAAO;AAAA,YACpB,KAAK;AAAA,UACP,CAAC,CAAC;AACF,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,MAAoC;AAChD,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,WAAW,UAAU,IAAI,SAAS;AAEtD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AAEF,UAAI,eAAe,KAAK;AACtB,cAAM,SAAS,MAAM,KAAK,OAAO,UAAU;AAC3C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,+CAA+C,UAAU,GAAG;AAAA,QAC9E;AAAA,MACF;AAEA,YAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,YAAM,SAAS,aAAa,KAAK,KAAM,SAAS,SAAS,GAAG,IAAI,WAAW,WAAW;AAEtF,YAAM,UAAuB,CAAC;AAC9B,YAAM,YAAY,oBAAI,IAAY;AAClC,UAAI;AAEJ,SAAG;AACD,cAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,UAC/D,QAAQ,KAAK,OAAO;AAAA,UACpB,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,mBAAmB;AAAA,QACrB,CAAC,CAAC;AAGF,YAAI,SAAS,gBAAgB;AAC3B,qBAAW,gBAAgB,SAAS,gBAAgB;AAClD,gBAAI,aAAa,QAAQ;AACvB,oBAAMA,QAAO,KAAK,UAAU,aAAa,MAAM;AAC/C,kBAAI,CAAC,UAAU,IAAIA,KAAI,GAAG;AACxB,0BAAU,IAAIA,KAAI;AAClB,wBAAQ,KAAK;AAAA,kBACX,MAAAA;AAAA,kBACA,UAAM,sBAASA,MAAK,SAAS,GAAG,IAAIA,MAAK,MAAM,GAAG,EAAE,IAAIA,KAAI;AAAA,kBAC5D,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS,oBAAI,KAAK;AAAA,kBAClB,UAAU,oBAAI,KAAK;AAAA,gBACrB,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,YAAI,SAAS,UAAU;AACrB,qBAAW,UAAU,SAAS,UAAU;AACtC,gBAAI,OAAO,KAAK;AAEd,kBAAI,OAAO,IAAI,SAAS,GAAG,EAAG;AAG9B,oBAAM,eAAe,OAAO,IAAI,UAAU,OAAO,MAAM;AACvD,kBAAI,aAAa,SAAS,GAAG,EAAG;AAEhC,oBAAMA,QAAO,KAAK,UAAU,OAAO,GAAG;AACtC,kBAAI,CAAC,UAAU,IAAIA,KAAI,GAAG;AACxB,0BAAU,IAAIA,KAAI;AAClB,wBAAQ,KAAK;AAAA,kBACX,MAAAA;AAAA,kBACA,UAAM,sBAASA,KAAI;AAAA,kBACnB,MAAM;AAAA,kBACN,MAAM,OAAO,QAAQ;AAAA,kBACrB,SAAS,OAAO,gBAAgB,oBAAI,KAAK;AAAA,kBACzC,UAAU,OAAO,gBAAgB,oBAAI,KAAK;AAAA,gBAC5C,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,4BAAoB,SAAS;AAAA,MAC/B,SAAS;AAET,WAAK,OAAO,KAAK,6BAAiB,UAAU;AAAA,QAC1C,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,MACjB,CAAC;AACD,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,MAAc,WAAyC;AACjE,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,SAAS,UAAU,IAAI,SAAS;AAEpD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AACD,SAAK,OAAO,KAAK,6BAAiB,cAAc,EAAE,MAAM,YAAY,WAAW,CAAC,CAAC,UAAU,CAAC;AAE5F,QAAI;AAEF,UAAI,eAAe,KAAK;AACtB,cAAM,IAAI,MAAM,uCAAuC,UAAU,GAAG;AAAA,MACtE;AAGA,UAAI,MAAM,KAAK,OAAO,UAAU,GAAG;AACjC,cAAM,IAAI,MAAM,uCAAuC,UAAU,GAAG;AAAA,MACtE;AAGA,UAAI,KAAK,OAAO,SAAS,WAAW;AAClC,cAAMC,OAAM,oBAAI,KAAK;AACrB,cAAMC,UAAoB;AAAA,UACxB,MAAM;AAAA,UACN,UAAM,sBAAS,UAAU;AAAA,UACzB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAASD;AAAA,UACT,UAAUA;AAAA,QACZ;AAEA,aAAK,eAAe;AAAA,UAClB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,WAAWA;AAAA,QACb,CAAC;AAED,aAAK,OAAO,KAAK,6BAAiB,aAAa,EAAE,MAAM,WAAW,CAAC;AACnE,aAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,UAC/C,WAAW;AAAA,UACX,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,UAAU,KAAK,IAAI,IAAI;AAAA,QACzB,CAAC;AAED,eAAOC;AAAA,MACT;AAGA,UAAI,WAAW;AAEb,cAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,YAAI,cAAc;AAElB,mBAAW,QAAQ,OAAO;AACxB,yBAAe,MAAM;AACrB,gBAAM,QAAQ,KAAK,QAAQ,WAAW;AACtC,gBAAM,KAAK,sBAAsB,KAAK;AAAA,QACxC;AAAA,MACF,OAAO;AAEL,cAAM,aAAS,qBAAQ,UAAU;AACjC,YAAI,WAAW,OAAO,WAAW,KAAK;AACpC,gBAAM,eAAe,MAAM,KAAK,OAAO,MAAM;AAC7C,cAAI,CAAC,cAAc;AACjB,kBAAM,IAAI,MAAM,6CAA6C,UAAU,GAAG;AAAA,UAC5E;AAAA,QACF;AAGA,cAAM,KAAK,mBAAmB,UAAU;AAGxC,cAAM,QAAQ,KAAK,QAAQ,UAAU;AACrC,cAAM,KAAK,sBAAsB,KAAK;AAAA,MACxC;AAEA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,SAAoB;AAAA,QACxB,MAAM;AAAA,QACN,UAAM,sBAAS,UAAU;AAAA,QACzB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAGA,WAAK,eAAe;AAAA,QAClB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC;AAED,WAAK,OAAO,KAAK,6BAAiB,aAAa,EAAE,MAAM,WAAW,CAAC;AACnE,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,MAAc,WAAoC;AAC5D,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,SAAS,UAAU,IAAI,SAAS;AAEpD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AACD,SAAK,OAAO,KAAK,6BAAiB,cAAc,EAAE,MAAM,YAAY,WAAW,CAAC,CAAC,UAAU,CAAC;AAE5F,QAAI;AAEF,UAAI,eAAe,KAAK;AACtB,cAAM,IAAI,MAAM,0CAA0C,UAAU,GAAG;AAAA,MACzE;AAGA,YAAM,SAAS,MAAM,KAAK,OAAO,UAAU;AAC3C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,6CAA6C,UAAU,GAAG;AAAA,MAC5E;AAGA,UAAI,CAAC,MAAM,KAAK,YAAY,UAAU,GAAG;AACvC,cAAM,IAAI,MAAM,oCAAoC,UAAU,GAAG;AAAA,MACnE;AAEA,YAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,YAAM,SAAS,SAAS,SAAS,GAAG,IAAI,WAAW,WAAW;AAE9D,UAAI,WAAW;AAEb,cAAM,kBAAqC,CAAC;AAC5C,YAAI;AAEJ,WAAG;AACD,gBAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,YAC/D,QAAQ,KAAK,OAAO;AAAA,YACpB,QAAQ;AAAA,YACR,mBAAmB;AAAA,UACrB,CAAC,CAAC;AAEF,cAAI,SAAS,UAAU;AACrB,uBAAW,UAAU,SAAS,UAAU;AACtC,kBAAI,OAAO,KAAK;AACd,gCAAgB,KAAK,EAAE,KAAK,OAAO,IAAI,CAAC;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAEA,8BAAoB,SAAS;AAAA,QAC/B,SAAS;AAGT,cAAM,YAAY;AAClB,iBAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK,WAAW;AAC1D,gBAAM,QAAQ,gBAAgB,MAAM,GAAG,IAAI,SAAS;AACpD,gBAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,YAC9C,QAAQ,KAAK,OAAO;AAAA,YACpB,QAAQ,EAAE,SAAS,MAAM;AAAA,UAC3B,CAAC,CAAC;AAAA,QACJ;AAAA,MACF,OAAO;AAEL,cAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,UAC/D,QAAQ,KAAK,OAAO;AAAA,UACpB,QAAQ;AAAA,UACR,SAAS;AAAA;AAAA,QACX,CAAC,CAAC;AAEF,cAAM,eAAe,SAAS,UAAU,UAAU,KAAK,KACpD,SAAS,UAAU,WAAW,KAAK,CAAC,SAAS,SAAS,CAAC,EAAE,KAAK,SAAS,GAAG;AAE7E,YAAI,aAAa;AACf,gBAAM,IAAI,MAAM,0CAA0C,UAAU,GAAG;AAAA,QACzE;AAGA,cAAM,KAAK,OAAO,KAAK,IAAI,qCAAoB;AAAA,UAC7C,QAAQ,KAAK,OAAO;AAAA,UACpB,KAAK;AAAA,QACP,CAAC,CAAC;AAAA,MACJ;AAGA,WAAK,eAAe;AAAA,QAClB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AAED,WAAK,OAAO,KAAK,6BAAiB,aAAa,EAAE,MAAM,WAAW,CAAC;AACnE,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,SAAiB,SAAqC;AACjE,UAAM,oBAAgB,2BAAc,OAAO;AAC3C,UAAM,oBAAgB,2BAAc,OAAO;AAC3C,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,UAAU,aAAa,IAAI,SAAS;AAExD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AAEF,UAAI,CAAC,MAAM,KAAK,OAAO,aAAa,GAAG;AACrC,cAAM,IAAI,MAAM,8CAA8C,aAAa,SAAS,aAAa,GAAG;AAAA,MACtG;AAGA,UAAI,MAAM,KAAK,OAAO,aAAa,GAAG;AACpC,cAAM,IAAI,MAAM,wCAAwC,aAAa,SAAS,aAAa,GAAG;AAAA,MAChG;AAGA,YAAM,gBAAY,qBAAQ,aAAa;AACvC,UAAI,cAAc,OAAO,cAAc,OAAO,CAAC,MAAM,KAAK,OAAO,SAAS,GAAG;AAC3E,cAAM,IAAI,MAAM,8CAA8C,aAAa,SAAS,aAAa,GAAG;AAAA,MACtG;AAGA,YAAM,WAAW,MAAM,KAAK,SAAS,aAAa;AAElD,UAAI,SAAS,SAAS,QAAQ;AAE5B,cAAM,KAAK,UAAU,eAAe,SAAS,SAAS,SAAS,QAAQ;AACvE,cAAM,KAAK,WAAW,aAAa;AAAA,MACrC,OAAO;AAEL,cAAM,KAAK,KAAK,CAAC,aAAa,OAAG,qBAAQ,aAAa,CAAC;AAAA,MACzD;AAEA,YAAM,SAAS,MAAM,KAAK,SAAS,aAAa;AAEhD,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,aAAuB,YAAmC;AACnE,UAAM,uBAAmB,2BAAc,UAAU;AACjD,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,QAAQ,SAAS;AAErC,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM,YAAY,CAAC;AAAA,MACnB,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AAEF,UAAI,CAAC,MAAM,KAAK,OAAO,gBAAgB,GAAG;AACxC,cAAM,IAAI,MAAM,4CAA4C,gBAAgB,GAAG;AAAA,MACjF;AAEA,UAAI,CAAC,MAAM,KAAK,YAAY,gBAAgB,GAAG;AAC7C,cAAM,IAAI,MAAM,mCAAmC,gBAAgB,GAAG;AAAA,MACxE;AAEA,iBAAW,cAAc,aAAa;AACpC,cAAM,uBAAmB,2BAAc,UAAU;AACjD,cAAM,qBAAiB,kBAAK,sBAAkB,sBAAS,gBAAgB,CAAC;AAGxE,cAAM,cAAc,MAAM,KAAK,SAAS,gBAAgB;AAGxD,cAAM,KAAK,UAAU,gBAAgB,YAAY,SAAS,YAAY,QAAQ;AAG9E,cAAM,KAAK,WAAW,gBAAgB;AAAA,MACxC;AAEA,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM,YAAY,CAAC;AAAA,QACnB,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM,YAAY,CAAC;AAAA,QACnB;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,YAAoB,YAAwC;AACrE,UAAM,uBAAmB,2BAAc,UAAU;AACjD,UAAM,uBAAmB,2BAAc,UAAU;AACjD,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,QAAQ,gBAAgB,IAAI,SAAS;AAEzD,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AAEF,UAAI,MAAM,KAAK,YAAY,gBAAgB,GAAG;AAC5C,cAAM,IAAI,MAAM,mDAAmD,gBAAgB,GAAG;AAAA,MACxF;AAGA,YAAM,cAAc,MAAM,KAAK,SAAS,gBAAgB;AAGxD,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAEA,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,SAAiB,UAAgD;AACrE,UAAM,KAAK,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC;AACjD,UAAM,WAA0B,EAAE,IAAI,SAAS,SAAS;AACxD,SAAK,SAAS,KAAK,QAAQ;AAE3B,WAAO;AAAA,MACL,SAAS,MAAM;AACb,cAAM,QAAQ,KAAK,SAAS,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACxD,YAAI,UAAU,IAAI;AAChB,eAAK,SAAS,OAAO,OAAO,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,OAAsB;AAC3C,eAAW,WAAW,KAAK,UAAU;AAEnC,UACE,QAAQ,YAAY,OACpB,MAAM,KAAK,SAAS,QAAQ,OAAO,KACnC,KAAK,UAAU,MAAM,MAAM,QAAQ,OAAO,GAC1C;AACA,gBAAQ,SAAS,KAAK;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAU,MAAc,SAA0B;AAExD,QAAI,YAAY,KAAK;AAEnB,aAAO,KAAK,MAAM,GAAG,EAAE,WAAW;AAAA,IACpC;AAEA,QAAI,YAAY,MAAM;AAEpB,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,QACT,QAAQ,SAAS,mBAAmB,EACpC,QAAQ,OAAO,OAAO,EACtB,QAAQ,sBAAsB,IAAI,EAClC,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,KAAK;AAEvB,WAAO,IAAI,OAAO,MAAM,QAAQ,GAAG,EAAE,KAAK,IAAI;AAAA,EAChD;AAAA,EAEA,MAAc,YAAY,MAAgC;AACxD,UAAM,iBAAa,2BAAc,IAAI;AACrC,UAAM,QAAQ,KAAK,QAAQ,UAAU;AACrC,UAAM,SAAS,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AAErD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,QAC5D,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAK;AAAA,MACP,CAAC,CAAC;AACF,aAAO,SAAS,WAAW,iBAAiB,MAAM;AAAA,IACpD,QAAQ;AAEN,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,QAC/D,QAAQ,KAAK,OAAO;AAAA,QACpB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC,CAAC;AACF,cAAQ,SAAS,UAAU,UAAU,KAAK;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,MAAiC;AAC1C,UAAM,iBAAa,2BAAc,IAAI;AAErC,QAAI;AAEF,UAAI,MAAM,KAAK,YAAY,UAAU,GAAG;AACtC,cAAM,QAAQ,KAAK,QAAQ,UAAU;AACrC,cAAM,SAAS,MAAM,SAAS,GAAG,IAAI,QAAQ,QAAQ;AAErD,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,mCAAkB;AAAA,YAC5D,QAAQ,KAAK,OAAO;AAAA,YACpB,KAAK;AAAA,UACP,CAAC,CAAC;AAEF,gBAAM,WAAW,KAAK,gBAAgB,SAAS,QAAQ;AACvD,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,SAAS,WAAW,IAAI,KAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC;AAAA,YACzE,UAAU,SAAS,YAAY,IAAI,KAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC;AAAA,UAC7E;AAAA,QACF,QAAQ;AAEN,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,oBAAI,KAAK;AAAA,YAClB,UAAU,oBAAI,KAAK;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAGA,YAAM,QAAQ,MAAM,KAAK,SAAS,UAAU;AAE5C,aAAO;AAAA,QACL,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM,QAAQ;AAAA,QACpB,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM,WAAW,oBAAI,KAAK;AAAA,QACnC,UAAU,MAAM,YAAY,oBAAI,KAAK;AAAA,MACvC;AAAA,IACF,SAAS,OAAY;AACnB,UAAI,MAAM,SAAS,SAAS,QAAQ,GAAG;AAErC,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,oBAAI,KAAK;AAAA,UAClB,UAAU,oBAAI,KAAK;AAAA,QACrB;AAAA,MACF;AACA,YAAM,IAAI,MAAM,kBAAkB,UAAU,KAAK,KAAK,EAAE;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,SAAoC;AAC7C,UAAM,UAAoB,CAAC;AAC3B,UAAM,YAAY,oBAAI,IAAY;AAGlC,UAAM,SAAS,QAAQ,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,OAAO,EAAE;AACtD,UAAM,WAAW,KAAK,OAAO,WAAW,MAAM,SAAS,KAAK,OAAO,SAAS;AAE5E,QAAI;AAEJ,OAAG;AACD,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,QAC/D,QAAQ,KAAK,OAAO;AAAA,QACpB,QAAQ;AAAA,QACR,mBAAmB;AAAA,MACrB,CAAC,CAAC;AAGF,UAAI,SAAS,UAAU;AACrB,mBAAW,UAAU,SAAS,UAAU;AACtC,cAAI,OAAO,KAAK;AACd,kBAAM,OAAO,KAAK,UAAU,OAAO,GAAG;AAGtC,gBAAI,CAAC,OAAO,IAAI,SAAS,GAAG,KAAK,KAAK,UAAU,MAAM,OAAO,GAAG;AAC9D,wBAAU,IAAI,IAAI;AAAA,YACpB;AAGA,gBAAI,YAAY,OAAO,YAAY,MAAM;AACvC,oBAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC5C,uBAAS,IAAI,GAAG,KAAK,MAAM,SAAS,GAAG,KAAK;AAC1C,sBAAM,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAChD,oBAAI,KAAK,UAAU,SAAS,OAAO,GAAG;AACpC,4BAAU,IAAI,OAAO;AAAA,gBACvB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,0BAAoB,SAAS;AAAA,IAC/B,SAAS;AAET,WAAO,MAAM,KAAK,SAAS,EAAE,KAAK;AAAA,EACpC;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,cAAc,SAAS,SAAS;AAEtC,SAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,MACjD,WAAW;AAAA,MACX,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AAED,QAAI;AAEF,YAAM,kBAAqC,CAAC;AAC5C,UAAI;AAEJ,SAAG;AACD,cAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,UAC/D,QAAQ,KAAK,OAAO;AAAA,UACpB,QAAQ,KAAK,OAAO,WAAW,MAAM,KAAK,KAAK,OAAO;AAAA,UACtD,mBAAmB;AAAA,QACrB,CAAC,CAAC;AAEF,YAAI,SAAS,UAAU;AACrB,qBAAW,UAAU,SAAS,UAAU;AACtC,gBAAI,OAAO,KAAK;AACd,8BAAgB,KAAK,EAAE,KAAK,OAAO,IAAI,CAAC;AAAA,YAC1C;AAAA,UACF;AAAA,QACF;AAEA,4BAAoB,SAAS;AAAA,MAC/B,SAAS;AAGT,YAAM,YAAY;AAClB,eAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK,WAAW;AAC1D,cAAM,QAAQ,gBAAgB,MAAM,GAAG,IAAI,SAAS;AACpD,cAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,UAC9C,QAAQ,KAAK,OAAO;AAAA,UACpB,QAAQ,EAAE,SAAS,MAAM;AAAA,QAC3B,CAAC,CAAC;AAAA,MACJ;AAEA,WAAK,OAAO,KAAK,6BAAiB,eAAe;AAAA,QAC/C,WAAW;AAAA,QACX,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,IAAI,IAAI;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,OAAO,KAAK,6BAAiB,iBAAiB;AAAA,QACjD,WAAW;AAAA,QACX,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,OAAwB;AAC5B,QAAI,YAAY;AAChB,QAAI;AAEJ,OAAG;AACD,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,IAAI,sCAAqB;AAAA,QAC/D,QAAQ,KAAK,OAAO;AAAA,QACpB,QAAQ,KAAK,OAAO,WAAW,MAAM,KAAK,KAAK,OAAO;AAAA,QACtD,mBAAmB;AAAA,MACrB,CAAC,CAAC;AAEF,UAAI,SAAS,UAAU;AACrB,mBAAW,UAAU,SAAS,UAAU;AACtC,uBAAa,OAAO,QAAQ;AAAA,QAC9B;AAAA,MACF;AAEA,0BAAoB,SAAS;AAAA,IAC/B,SAAS;AAET,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UAAU,MAAgC;AAE9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,YAAsC;AAEtD,WAAO;AAAA,EACT;AACF;","names":["path","now","result"]}