{ "version": 3, "sources": ["../../../lib/fs.ts"], "sourcesContent": ["/**\r\n * FS\r\n * Pokemon Showdown - http://pokemonshowdown.com/\r\n *\r\n * An abstraction layer around Node's filesystem.\r\n *\r\n * Advantages:\r\n * - write() etc do nothing in unit tests\r\n * - paths are always relative to PS's base directory\r\n * - Promises (seriously wtf Node Core what are you thinking)\r\n * - PS-style API: FS(\"foo.txt\").write(\"bar\") for easier argument order\r\n * - mkdirp\r\n *\r\n * FS is used nearly everywhere, but exceptions include:\r\n * - crashlogger.js - in case the crash is in here\r\n * - repl.js - which use Unix sockets out of this file's scope\r\n * - launch script - happens before modules are loaded\r\n * - sim/ - intended to be self-contained\r\n *\r\n * @author Guangcong Luo \r\n * @license MIT\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as pathModule from 'path';\r\nimport {ReadStream, WriteStream} from './streams';\r\n\r\n// not sure why it's necessary to use path.sep, but testing with Windows showed it was\r\nconst DIST = `${pathModule.sep}dist${pathModule.sep}`;\r\n// account for pwd/dist/lib\r\nconst ROOT_PATH = pathModule.resolve(__dirname, __dirname.includes(DIST) ? '..' : '', '..');\r\n\r\ninterface PendingUpdate {\r\n\tisWriting: boolean; // true: waiting on a call to FS.write, false: waiting on a throttle\r\n\tpendingDataFetcher: (() => string | Buffer) | null;\r\n\tpendingOptions: AnyObject | null;\r\n\tthrottleTime: number; // throttling until time (0 for no throttle)\r\n\tthrottleTimer: NodeJS.Timer | null;\r\n}\r\n\r\ndeclare const __fsState: {pendingUpdates: Map};\r\n// config needs to be declared here since we access it as global.Config?.nofswriting\r\n// (so we can use it without the global)\r\ndeclare const global: {__fsState: typeof __fsState, Config: any};\r\nif (!global.__fsState) {\r\n\tglobal.__fsState = {\r\n\t\tpendingUpdates: new Map(),\r\n\t};\r\n}\r\n\r\nexport class FSPath {\r\n\tpath: string;\r\n\r\n\tconstructor(path: string) {\r\n\t\tthis.path = pathModule.resolve(ROOT_PATH, path);\r\n\t}\r\n\r\n\tparentDir() {\r\n\t\treturn new FSPath(pathModule.dirname(this.path));\r\n\t}\r\n\r\n\tread(options: AnyObject | BufferEncoding = 'utf8'): Promise {\r\n\t\tif (typeof options !== 'string' && options.encoding === undefined) {\r\n\t\t\toptions.encoding = 'utf8';\r\n\t\t}\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.readFile(this.path, options, (err, data) => {\r\n\t\t\t\terr ? reject(err) : resolve(data as string);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treadSync(options: AnyObject | string = 'utf8'): string {\r\n\t\tif (typeof options !== 'string' && options.encoding === undefined) {\r\n\t\t\toptions.encoding = 'utf8';\r\n\t\t}\r\n\t\treturn fs.readFileSync(this.path, options as {encoding: 'utf8'});\r\n\t}\r\n\r\n\treadBuffer(options: AnyObject | BufferEncoding = {}): Promise {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.readFile(this.path, options, (err, data) => {\r\n\t\t\t\terr ? reject(err) : resolve(data as Buffer);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treadBufferSync(options: AnyObject | string = {}) {\r\n\t\treturn fs.readFileSync(this.path, options as {encoding: null});\r\n\t}\r\n\r\n\texists(): Promise {\r\n\t\treturn new Promise(resolve => {\r\n\t\t\tfs.exists(this.path, exists => {\r\n\t\t\t\tresolve(exists);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\texistsSync() {\r\n\t\treturn fs.existsSync(this.path);\r\n\t}\r\n\r\n\treadIfExists(): Promise {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.readFile(this.path, 'utf8', (err, data) => {\r\n\t\t\t\tif (err && err.code === 'ENOENT') return resolve('');\r\n\t\t\t\terr ? reject(err) : resolve(data);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treadIfExistsSync() {\r\n\t\ttry {\r\n\t\t\treturn fs.readFileSync(this.path, 'utf8');\r\n\t\t} catch (err: any) {\r\n\t\t\tif (err.code !== 'ENOENT') throw err;\r\n\t\t}\r\n\t\treturn '';\r\n\t}\r\n\r\n\twrite(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.writeFile(this.path, data, options, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\twriteSync(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.writeFileSync(this.path, data, options);\r\n\t}\r\n\r\n\t/**\r\n\t * Writes to a new file before renaming to replace an old file. If\r\n\t * the process crashes while writing, the old file won't be lost.\r\n\t * Does not protect against simultaneous writing; use writeUpdate\r\n\t * for that.\r\n\t */\r\n\tasync safeWrite(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tawait FS(this.path + '.NEW').write(data, options);\r\n\t\tawait FS(this.path + '.NEW').rename(this.path);\r\n\t}\r\n\r\n\tsafeWriteSync(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tFS(this.path + '.NEW').writeSync(data, options);\r\n\t\tFS(this.path + '.NEW').renameSync(this.path);\r\n\t}\r\n\r\n\t/**\r\n\t * Safest way to update a file with in-memory state. Pass a callback\r\n\t * that fetches the data to be written. It will write an update,\r\n\t * avoiding race conditions. The callback may not necessarily be\r\n\t * called, if `writeUpdate` is called many times in a short period.\r\n\t *\r\n\t * `options.throttle`, if it exists, will make sure updates are not\r\n\t * written more than once every `options.throttle` milliseconds.\r\n\t *\r\n\t * No synchronous version because there's no risk of race conditions\r\n\t * with synchronous code; just use `safeWriteSync`.\r\n\t */\r\n\twriteUpdate(dataFetcher: () => string | Buffer, options: AnyObject = {}) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\tconst pendingUpdate: PendingUpdate | undefined = __fsState.pendingUpdates.get(this.path);\r\n\r\n\t\tconst throttleTime = options.throttle ? Date.now() + options.throttle : 0;\r\n\r\n\t\tif (pendingUpdate) {\r\n\t\t\tpendingUpdate.pendingDataFetcher = dataFetcher;\r\n\t\t\tpendingUpdate.pendingOptions = options;\r\n\t\t\tif (pendingUpdate.throttleTimer && throttleTime < pendingUpdate.throttleTime) {\r\n\t\t\t\tpendingUpdate.throttleTime = throttleTime;\r\n\t\t\t\tclearTimeout(pendingUpdate.throttleTimer);\r\n\t\t\t\tpendingUpdate.throttleTimer = setTimeout(() => this.checkNextUpdate(), throttleTime - Date.now());\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!throttleTime) {\r\n\t\t\tthis.writeUpdateNow(dataFetcher, options);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst update: PendingUpdate = {\r\n\t\t\tisWriting: false,\r\n\t\t\tpendingDataFetcher: dataFetcher,\r\n\t\t\tpendingOptions: options,\r\n\t\t\tthrottleTime,\r\n\t\t\tthrottleTimer: setTimeout(() => this.checkNextUpdate(), throttleTime - Date.now()),\r\n\t\t};\r\n\t\t__fsState.pendingUpdates.set(this.path, update);\r\n\t}\r\n\r\n\twriteUpdateNow(dataFetcher: () => string | Buffer, options: AnyObject) {\r\n\t\tconst throttleTime = options.throttle ? Date.now() + options.throttle : 0;\r\n\t\tconst update = {\r\n\t\t\tisWriting: true,\r\n\t\t\tpendingDataFetcher: null,\r\n\t\t\tpendingOptions: null,\r\n\t\t\tthrottleTime,\r\n\t\t\tthrottleTimer: null,\r\n\t\t};\r\n\t\t__fsState.pendingUpdates.set(this.path, update);\r\n\t\tvoid this.safeWrite(dataFetcher(), options).then(() => this.finishUpdate());\r\n\t}\r\n\tcheckNextUpdate() {\r\n\t\tconst pendingUpdate = __fsState.pendingUpdates.get(this.path);\r\n\t\tif (!pendingUpdate) throw new Error(`FS: Pending update not found`);\r\n\t\tif (pendingUpdate.isWriting) throw new Error(`FS: Conflicting update`);\r\n\r\n\t\tconst {pendingDataFetcher: dataFetcher, pendingOptions: options} = pendingUpdate;\r\n\t\tif (!dataFetcher || !options) {\r\n\t\t\t// no pending update\r\n\t\t\t__fsState.pendingUpdates.delete(this.path);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.writeUpdateNow(dataFetcher, options);\r\n\t}\r\n\tfinishUpdate() {\r\n\t\tconst pendingUpdate = __fsState.pendingUpdates.get(this.path);\r\n\t\tif (!pendingUpdate) throw new Error(`FS: Pending update not found`);\r\n\t\tif (!pendingUpdate.isWriting) throw new Error(`FS: Conflicting update`);\r\n\r\n\t\tpendingUpdate.isWriting = false;\r\n\t\tconst throttleTime = pendingUpdate.throttleTime;\r\n\t\tif (!throttleTime || throttleTime < Date.now()) {\r\n\t\t\tthis.checkNextUpdate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tpendingUpdate.throttleTimer = setTimeout(() => this.checkNextUpdate(), throttleTime - Date.now());\r\n\t}\r\n\r\n\tappend(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.appendFile(this.path, data, options, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tappendSync(data: string | Buffer, options: AnyObject = {}) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.appendFileSync(this.path, data, options);\r\n\t}\r\n\r\n\tsymlinkTo(target: string) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.symlink(target, this.path, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tsymlinkToSync(target: string) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.symlinkSync(target, this.path);\r\n\t}\r\n\r\n\tcopyFile(dest: string) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.copyFile(this.path, dest, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\trename(target: string) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.rename(this.path, target, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\trenameSync(target: string) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.renameSync(this.path, target);\r\n\t}\r\n\r\n\treaddir(): Promise {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.readdir(this.path, (err, data) => {\r\n\t\t\t\terr ? reject(err) : resolve(data);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\treaddirSync() {\r\n\t\treturn fs.readdirSync(this.path);\r\n\t}\r\n\r\n\tasync readdirIfExists(): Promise {\r\n\t\tif (await this.exists()) return this.readdir();\r\n\t\treturn Promise.resolve([]);\r\n\t}\r\n\r\n\treaddirIfExistsSync() {\r\n\t\tif (this.existsSync()) return this.readdirSync();\r\n\t\treturn [];\r\n\t}\r\n\r\n\tcreateReadStream() {\r\n\t\treturn new FileReadStream(this.path);\r\n\t}\r\n\r\n\tcreateWriteStream(options = {}): WriteStream {\r\n\t\tif (global.Config?.nofswriting) {\r\n\t\t\t// @ts-ignore\r\n\t\t\treturn new WriteStream({write() {}});\r\n\t\t}\r\n\t\t// @ts-ignore\r\n\t\treturn new WriteStream(fs.createWriteStream(this.path, options));\r\n\t}\r\n\r\n\tcreateAppendStream(options = {}): WriteStream {\r\n\t\tif (global.Config?.nofswriting) {\r\n\t\t\t// @ts-ignore\r\n\t\t\treturn new WriteStream({write() {}});\r\n\t\t}\r\n\t\t// @ts-ignore\r\n\t\toptions.flags = options.flags || 'a';\r\n\t\t// @ts-ignore\r\n\t\treturn new WriteStream(fs.createWriteStream(this.path, options));\r\n\t}\r\n\r\n\tunlinkIfExists() {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.unlink(this.path, err => {\r\n\t\t\t\tif (err && err.code === 'ENOENT') return resolve();\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tunlinkIfExistsSync() {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\ttry {\r\n\t\t\tfs.unlinkSync(this.path);\r\n\t\t} catch (err: any) {\r\n\t\t\tif (err.code !== 'ENOENT') throw err;\r\n\t\t}\r\n\t}\r\n\r\n\tasync rmdir(recursive?: boolean) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.rmdir(this.path, {recursive}, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\trmdirSync(recursive?: boolean) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.rmdirSync(this.path, {recursive});\r\n\t}\r\n\r\n\tmkdir(mode: string | number = 0o755) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.mkdir(this.path, mode, err => {\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tmkdirSync(mode: string | number = 0o755) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\treturn fs.mkdirSync(this.path, mode);\r\n\t}\r\n\r\n\tmkdirIfNonexistent(mode: string | number = 0o755) {\r\n\t\tif (global.Config?.nofswriting) return Promise.resolve();\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.mkdir(this.path, mode, err => {\r\n\t\t\t\tif (err && err.code === 'EEXIST') return resolve();\r\n\t\t\t\terr ? reject(err) : resolve();\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tmkdirIfNonexistentSync(mode: string | number = 0o755) {\r\n\t\tif (global.Config?.nofswriting) return;\r\n\t\ttry {\r\n\t\t\tfs.mkdirSync(this.path, mode);\r\n\t\t} catch (err: any) {\r\n\t\t\tif (err.code !== 'EEXIST') throw err;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Creates the directory (and any parent directories if necessary).\r\n\t * Does not throw if the directory already exists.\r\n\t */\r\n\tasync mkdirp(mode: string | number = 0o755) {\r\n\t\ttry {\r\n\t\t\tawait this.mkdirIfNonexistent(mode);\r\n\t\t} catch (err: any) {\r\n\t\t\tif (err.code !== 'ENOENT') throw err;\r\n\t\t\tawait this.parentDir().mkdirp(mode);\r\n\t\t\tawait this.mkdirIfNonexistent(mode);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Creates the directory (and any parent directories if necessary).\r\n\t * Does not throw if the directory already exists. Synchronous.\r\n\t */\r\n\tmkdirpSync(mode: string | number = 0o755) {\r\n\t\ttry {\r\n\t\t\tthis.mkdirIfNonexistentSync(mode);\r\n\t\t} catch (err: any) {\r\n\t\t\tif (err.code !== 'ENOENT') throw err;\r\n\t\t\tthis.parentDir().mkdirpSync(mode);\r\n\t\t\tthis.mkdirIfNonexistentSync(mode);\r\n\t\t}\r\n\t}\r\n\r\n\t/** Calls the callback if the file is modified. */\r\n\tonModify(callback: () => void) {\r\n\t\tfs.watchFile(this.path, (curr, prev) => {\r\n\t\t\tif (curr.mtime > prev.mtime) return callback();\r\n\t\t});\r\n\t}\r\n\r\n\t/** Clears callbacks added with onModify(). */\r\n\tunwatch() {\r\n\t\tfs.unwatchFile(this.path);\r\n\t}\r\n\r\n\tasync isFile() {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.stat(this.path, (err, stats) => {\r\n\t\t\t\terr ? reject(err) : resolve(stats.isFile());\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tisFileSync() {\r\n\t\treturn fs.statSync(this.path).isFile();\r\n\t}\r\n\r\n\tasync isDirectory() {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.stat(this.path, (err, stats) => {\r\n\t\t\t\terr ? reject(err) : resolve(stats.isDirectory());\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\tisDirectorySync() {\r\n\t\treturn fs.statSync(this.path).isDirectory();\r\n\t}\r\n\r\n\tasync realpath() {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tfs.realpath(this.path, (err, path) => {\r\n\t\t\t\terr ? reject(err) : resolve(path);\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\trealpathSync() {\r\n\t\treturn fs.realpathSync(this.path);\r\n\t}\r\n}\r\n\r\nclass FileReadStream extends ReadStream {\r\n\tfd: Promise;\r\n\r\n\tconstructor(file: string) {\r\n\t\tsuper();\r\n\t\tthis.fd = new Promise((resolve, reject) => {\r\n\t\t\tfs.open(file, 'r', (err, fd) => err ? reject(err) : resolve(fd));\r\n\t\t});\r\n\t\tthis.atEOF = false;\r\n\t}\r\n\r\n\t_read(size = 16384): Promise {\r\n\t\treturn new Promise((resolve, reject) => {\r\n\t\t\tif (this.atEOF) return resolve();\r\n\t\t\tthis.ensureCapacity(size);\r\n\t\t\tvoid this.fd.then(fd => {\r\n\t\t\t\tfs.read(fd, this.buf, this.bufEnd, size, null, (err, bytesRead, buf) => {\r\n\t\t\t\t\tif (err) return reject(err);\r\n\t\t\t\t\tif (!bytesRead) {\r\n\t\t\t\t\t\tthis.atEOF = true;\r\n\t\t\t\t\t\tthis.resolvePush();\r\n\t\t\t\t\t\treturn resolve();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.bufEnd += bytesRead;\r\n\t\t\t\t\t// throw new Error([...this.buf].map(x => x.toString(16)).join(' '));\r\n\t\t\t\t\tthis.resolvePush();\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\t_destroy() {\r\n\t\treturn new Promise(resolve => {\r\n\t\t\tvoid this.fd.then(fd => {\r\n\t\t\t\tfs.close(fd, () => resolve());\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n}\r\n\r\nfunction getFs(path: string) {\r\n\treturn new FSPath(path);\r\n}\r\n\r\nexport const FS = Object.assign(getFs, {\r\n\tFileReadStream, FSPath, ROOT_PATH,\r\n});\r\n"], "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBA,SAAoB;AACpB,iBAA4B;AAC5B,qBAAsC;AAzBtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BA,MAAM,OAAO,GAAG,WAAW,UAAU,WAAW;AAEhD,MAAM,YAAY,WAAW,QAAQ,WAAW,UAAU,SAAS,IAAI,IAAI,OAAO,IAAI,IAAI;AAc1F,IAAI,CAAC,OAAO,WAAW;AACtB,SAAO,YAAY;AAAA,IAClB,gBAAgB,oBAAI,IAAI;AAAA,EACzB;AACD;AAEO,MAAM,OAAO;AAAA,EAGnB,YAAY,MAAc;AACzB,SAAK,OAAO,WAAW,QAAQ,WAAW,IAAI;AAAA,EAC/C;AAAA,EAEA,YAAY;AACX,WAAO,IAAI,OAAO,WAAW,QAAQ,KAAK,IAAI,CAAC;AAAA,EAChD;AAAA,EAEA,KAAK,UAAsC,QAAyB;AACnE,QAAI,OAAO,YAAY,YAAY,QAAQ,aAAa,QAAW;AAClE,cAAQ,WAAW;AAAA,IACpB;AACA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,SAAG,SAAS,KAAK,MAAM,SAAS,CAAC,KAAK,SAAS;AAC9C,cAAM,OAAO,GAAG,IAAI,QAAQ,IAAc;AAAA,MAC3C,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,SAAS,UAA8B,QAAgB;AACtD,QAAI,OAAO,YAAY,YAAY,QAAQ,aAAa,QAAW;AAClE,cAAQ,WAAW;AAAA,IACpB;AACA,WAAO,GAAG,aAAa,KAAK,MAAM,OAA6B;AAAA,EAChE;AAAA,EAEA,WAAW,UAAsC,CAAC,GAAoB;AACrE,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,SAAG,SAAS,KAAK,MAAM,SAAS,CAAC,KAAK,SAAS;AAC9C,cAAM,OAAO,GAAG,IAAI,QAAQ,IAAc;AAAA,MAC3C,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,eAAe,UAA8B,CAAC,GAAG;AAChD,WAAO,GAAG,aAAa,KAAK,MAAM,OAA2B;AAAA,EAC9D;AAAA,EAEA,SAA2B;AAC1B,WAAO,IAAI,QAAQ,aAAW;AAC7B,SAAG,OAAO,KAAK,MAAM,YAAU;AAC9B,gBAAQ,MAAM;AAAA,MACf,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,aAAa;AACZ,WAAO,GAAG,WAAW,KAAK,IAAI;AAAA,EAC/B;AAAA,EAEA,eAAgC;AAC/B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,SAAG,SAAS,KAAK,MAAM,QAAQ,CAAC,KAAK,SAAS;AAC7C,YAAI,OAAO,IAAI,SAAS;AAAU,iBAAO,QAAQ,EAAE;AACnD,cAAM,OAAO,GAAG,IAAI,QAAQ,IAAI;AAAA,MACjC,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,mBAAmB;AAClB,QAAI;AACH,aAAO,GAAG,aAAa,KAAK,MAAM,MAAM;AAAA,IACzC,SAAS,KAAP;AACD,UAAI,IAAI,SAAS;AAAU,cAAM;AAAA,IAClC;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,MAAuB,UAAqB,CAAC,GAAG;AACrD,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,UAAU,KAAK,MAAM,MAAM,SAAS,SAAO;AAC7C,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,UAAU,MAAuB,UAAqB,CAAC,GAAG;AACzD,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,cAAc,KAAK,MAAM,MAAM,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,MAAuB,UAAqB,CAAC,GAAG;AAC/D,UAAM,GAAG,KAAK,OAAO,MAAM,EAAE,MAAM,MAAM,OAAO;AAChD,UAAM,GAAG,KAAK,OAAO,MAAM,EAAE,OAAO,KAAK,IAAI;AAAA,EAC9C;AAAA,EAEA,cAAc,MAAuB,UAAqB,CAAC,GAAG;AAC7D,OAAG,KAAK,OAAO,MAAM,EAAE,UAAU,MAAM,OAAO;AAC9C,OAAG,KAAK,OAAO,MAAM,EAAE,WAAW,KAAK,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,YAAY,aAAoC,UAAqB,CAAC,GAAG;AACxE,QAAI,OAAO,QAAQ;AAAa;AAChC,UAAM,gBAA2C,UAAU,eAAe,IAAI,KAAK,IAAI;AAEvF,UAAM,eAAe,QAAQ,WAAW,KAAK,IAAI,IAAI,QAAQ,WAAW;AAExE,QAAI,eAAe;AAClB,oBAAc,qBAAqB;AACnC,oBAAc,iBAAiB;AAC/B,UAAI,cAAc,iBAAiB,eAAe,cAAc,cAAc;AAC7E,sBAAc,eAAe;AAC7B,qBAAa,cAAc,aAAa;AACxC,sBAAc,gBAAgB,WAAW,MAAM,KAAK,gBAAgB,GAAG,eAAe,KAAK,IAAI,CAAC;AAAA,MACjG;AACA;AAAA,IACD;AAEA,QAAI,CAAC,cAAc;AAClB,WAAK,eAAe,aAAa,OAAO;AACxC;AAAA,IACD;AAEA,UAAM,SAAwB;AAAA,MAC7B,WAAW;AAAA,MACX,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAChB;AAAA,MACA,eAAe,WAAW,MAAM,KAAK,gBAAgB,GAAG,eAAe,KAAK,IAAI,CAAC;AAAA,IAClF;AACA,cAAU,eAAe,IAAI,KAAK,MAAM,MAAM;AAAA,EAC/C;AAAA,EAEA,eAAe,aAAoC,SAAoB;AACtE,UAAM,eAAe,QAAQ,WAAW,KAAK,IAAI,IAAI,QAAQ,WAAW;AACxE,UAAM,SAAS;AAAA,MACd,WAAW;AAAA,MACX,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAChB;AAAA,MACA,eAAe;AAAA,IAChB;AACA,cAAU,eAAe,IAAI,KAAK,MAAM,MAAM;AAC9C,SAAK,KAAK,UAAU,YAAY,GAAG,OAAO,EAAE,KAAK,MAAM,KAAK,aAAa,CAAC;AAAA,EAC3E;AAAA,EACA,kBAAkB;AACjB,UAAM,gBAAgB,UAAU,eAAe,IAAI,KAAK,IAAI;AAC5D,QAAI,CAAC;AAAe,YAAM,IAAI,MAAM,8BAA8B;AAClE,QAAI,cAAc;AAAW,YAAM,IAAI,MAAM,wBAAwB;AAErE,UAAM,EAAC,oBAAoB,aAAa,gBAAgB,QAAO,IAAI;AACnE,QAAI,CAAC,eAAe,CAAC,SAAS;AAE7B,gBAAU,eAAe,OAAO,KAAK,IAAI;AACzC;AAAA,IACD;AAEA,SAAK,eAAe,aAAa,OAAO;AAAA,EACzC;AAAA,EACA,eAAe;AACd,UAAM,gBAAgB,UAAU,eAAe,IAAI,KAAK,IAAI;AAC5D,QAAI,CAAC;AAAe,YAAM,IAAI,MAAM,8BAA8B;AAClE,QAAI,CAAC,cAAc;AAAW,YAAM,IAAI,MAAM,wBAAwB;AAEtE,kBAAc,YAAY;AAC1B,UAAM,eAAe,cAAc;AACnC,QAAI,CAAC,gBAAgB,eAAe,KAAK,IAAI,GAAG;AAC/C,WAAK,gBAAgB;AACrB;AAAA,IACD;AAEA,kBAAc,gBAAgB,WAAW,MAAM,KAAK,gBAAgB,GAAG,eAAe,KAAK,IAAI,CAAC;AAAA,EACjG;AAAA,EAEA,OAAO,MAAuB,UAAqB,CAAC,GAAG;AACtD,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,WAAW,KAAK,MAAM,MAAM,SAAS,SAAO;AAC9C,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,WAAW,MAAuB,UAAqB,CAAC,GAAG;AAC1D,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,eAAe,KAAK,MAAM,MAAM,OAAO;AAAA,EAClD;AAAA,EAEA,UAAU,QAAgB;AACzB,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,QAAQ,QAAQ,KAAK,MAAM,SAAO;AACpC,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,cAAc,QAAgB;AAC7B,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,YAAY,QAAQ,KAAK,IAAI;AAAA,EACxC;AAAA,EAEA,SAAS,MAAc;AACtB,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,SAAS,KAAK,MAAM,MAAM,SAAO;AACnC,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,OAAO,QAAgB;AACtB,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,OAAO,KAAK,MAAM,QAAQ,SAAO;AACnC,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,WAAW,QAAgB;AAC1B,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,WAAW,KAAK,MAAM,MAAM;AAAA,EACvC;AAAA,EAEA,UAA6B;AAC5B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,SAAG,QAAQ,KAAK,MAAM,CAAC,KAAK,SAAS;AACpC,cAAM,OAAO,GAAG,IAAI,QAAQ,IAAI;AAAA,MACjC,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,cAAc;AACb,WAAO,GAAG,YAAY,KAAK,IAAI;AAAA,EAChC;AAAA,EAEA,MAAM,kBAAqC;AAC1C,QAAI,MAAM,KAAK,OAAO;AAAG,aAAO,KAAK,QAAQ;AAC7C,WAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC1B;AAAA,EAEA,sBAAsB;AACrB,QAAI,KAAK,WAAW;AAAG,aAAO,KAAK,YAAY;AAC/C,WAAO,CAAC;AAAA,EACT;AAAA,EAEA,mBAAmB;AAClB,WAAO,IAAI,eAAe,KAAK,IAAI;AAAA,EACpC;AAAA,EAEA,kBAAkB,UAAU,CAAC,GAAgB;AAC5C,QAAI,OAAO,QAAQ,aAAa;AAE/B,aAAO,IAAI,2BAAY,EAAC,QAAQ;AAAA,MAAC,EAAC,CAAC;AAAA,IACpC;AAEA,WAAO,IAAI,2BAAY,GAAG,kBAAkB,KAAK,MAAM,OAAO,CAAC;AAAA,EAChE;AAAA,EAEA,mBAAmB,UAAU,CAAC,GAAgB;AAC7C,QAAI,OAAO,QAAQ,aAAa;AAE/B,aAAO,IAAI,2BAAY,EAAC,QAAQ;AAAA,MAAC,EAAC,CAAC;AAAA,IACpC;AAEA,YAAQ,QAAQ,QAAQ,SAAS;AAEjC,WAAO,IAAI,2BAAY,GAAG,kBAAkB,KAAK,MAAM,OAAO,CAAC;AAAA,EAChE;AAAA,EAEA,iBAAiB;AAChB,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,OAAO,KAAK,MAAM,SAAO;AAC3B,YAAI,OAAO,IAAI,SAAS;AAAU,iBAAO,QAAQ;AACjD,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,qBAAqB;AACpB,QAAI,OAAO,QAAQ;AAAa;AAChC,QAAI;AACH,SAAG,WAAW,KAAK,IAAI;AAAA,IACxB,SAAS,KAAP;AACD,UAAI,IAAI,SAAS;AAAU,cAAM;AAAA,IAClC;AAAA,EACD;AAAA,EAEA,MAAM,MAAM,WAAqB;AAChC,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,MAAM,KAAK,MAAM,EAAC,UAAS,GAAG,SAAO;AACvC,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,UAAU,WAAqB;AAC9B,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,UAAU,KAAK,MAAM,EAAC,UAAS,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAM,OAAwB,KAAO;AACpC,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,MAAM,KAAK,MAAM,MAAM,SAAO;AAChC,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,UAAU,OAAwB,KAAO;AACxC,QAAI,OAAO,QAAQ;AAAa;AAChC,WAAO,GAAG,UAAU,KAAK,MAAM,IAAI;AAAA,EACpC;AAAA,EAEA,mBAAmB,OAAwB,KAAO;AACjD,QAAI,OAAO,QAAQ;AAAa,aAAO,QAAQ,QAAQ;AACvD,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,SAAG,MAAM,KAAK,MAAM,MAAM,SAAO;AAChC,YAAI,OAAO,IAAI,SAAS;AAAU,iBAAO,QAAQ;AACjD,cAAM,OAAO,GAAG,IAAI,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,uBAAuB,OAAwB,KAAO;AACrD,QAAI,OAAO,QAAQ;AAAa;AAChC,QAAI;AACH,SAAG,UAAU,KAAK,MAAM,IAAI;AAAA,IAC7B,SAAS,KAAP;AACD,UAAI,IAAI,SAAS;AAAU,cAAM;AAAA,IAClC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,OAAwB,KAAO;AAC3C,QAAI;AACH,YAAM,KAAK,mBAAmB,IAAI;AAAA,IACnC,SAAS,KAAP;AACD,UAAI,IAAI,SAAS;AAAU,cAAM;AACjC,YAAM,KAAK,UAAU,EAAE,OAAO,IAAI;AAClC,YAAM,KAAK,mBAAmB,IAAI;AAAA,IACnC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,OAAwB,KAAO;AACzC,QAAI;AACH,WAAK,uBAAuB,IAAI;AAAA,IACjC,SAAS,KAAP;AACD,UAAI,IAAI,SAAS;AAAU,cAAM;AACjC,WAAK,UAAU,EAAE,WAAW,IAAI;AAChC,WAAK,uBAAuB,IAAI;AAAA,IACjC;AAAA,EACD;AAAA;AAAA,EAGA,SAAS,UAAsB;AAC9B,OAAG,UAAU,KAAK,MAAM,CAAC,MAAM,SAAS;AACvC,UAAI,KAAK,QAAQ,KAAK;AAAO,eAAO,SAAS;AAAA,IAC9C,CAAC;AAAA,EACF;AAAA;AAAA,EAGA,UAAU;AACT,OAAG,YAAY,KAAK,IAAI;AAAA,EACzB;AAAA,EAEA,MAAM,SAAS;AACd,WAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAChD,SAAG,KAAK,KAAK,MAAM,CAAC,KAAK,UAAU;AAClC,cAAM,OAAO,GAAG,IAAI,QAAQ,MAAM,OAAO,CAAC;AAAA,MAC3C,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,aAAa;AACZ,WAAO,GAAG,SAAS,KAAK,IAAI,EAAE,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,cAAc;AACnB,WAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAChD,SAAG,KAAK,KAAK,MAAM,CAAC,KAAK,UAAU;AAClC,cAAM,OAAO,GAAG,IAAI,QAAQ,MAAM,YAAY,CAAC;AAAA,MAChD,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,kBAAkB;AACjB,WAAO,GAAG,SAAS,KAAK,IAAI,EAAE,YAAY;AAAA,EAC3C;AAAA,EAEA,MAAM,WAAW;AAChB,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC/C,SAAG,SAAS,KAAK,MAAM,CAAC,KAAK,SAAS;AACrC,cAAM,OAAO,GAAG,IAAI,QAAQ,IAAI;AAAA,MACjC,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,eAAe;AACd,WAAO,GAAG,aAAa,KAAK,IAAI;AAAA,EACjC;AACD;AAEA,MAAM,uBAAuB,0BAAW;AAAA,EAGvC,YAAY,MAAc;AACzB,UAAM;AACN,SAAK,KAAK,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC1C,SAAG,KAAK,MAAM,KAAK,CAAC,KAAK,OAAO,MAAM,OAAO,GAAG,IAAI,QAAQ,EAAE,CAAC;AAAA,IAChE,CAAC;AACD,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,MAAM,OAAO,OAAsB;AAClC,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC7C,UAAI,KAAK;AAAO,eAAO,QAAQ;AAC/B,WAAK,eAAe,IAAI;AACxB,WAAK,KAAK,GAAG,KAAK,QAAM;AACvB,WAAG,KAAK,IAAI,KAAK,KAAK,KAAK,QAAQ,MAAM,MAAM,CAAC,KAAK,WAAW,QAAQ;AACvE,cAAI;AAAK,mBAAO,OAAO,GAAG;AAC1B,cAAI,CAAC,WAAW;AACf,iBAAK,QAAQ;AACb,iBAAK,YAAY;AACjB,mBAAO,QAAQ;AAAA,UAChB;AACA,eAAK,UAAU;AAEf,eAAK,YAAY;AACjB,kBAAQ;AAAA,QACT,CAAC;AAAA,MACF,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,WAAW;AACV,WAAO,IAAI,QAAc,aAAW;AACnC,WAAK,KAAK,GAAG,KAAK,QAAM;AACvB,WAAG,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,MAC7B,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AACD;AAEA,SAAS,MAAM,MAAc;AAC5B,SAAO,IAAI,OAAO,IAAI;AACvB;AAEO,MAAM,KAAK,OAAO,OAAO,OAAO;AAAA,EACtC;AAAA,EAAgB;AAAA,EAAQ;AACzB,CAAC;", "names": [] }