@layoutkit/bree-core 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -542,9 +542,7 @@ const decryptString = (data, key) => {
542
542
 
543
543
  var aes = { encrypt, decrypt, decryptString };
544
544
 
545
- let db$1 = null;
546
-
547
- /** 解析 `key=value;key=value` 形式的连接串(值允许包含 `=`) */
545
+ /** 解析 key=value;key=value 形式的连接串 */
548
546
  const parseConnectionString = (str) =>
549
547
  str.split(';').reduce((acc, param) => {
550
548
  const idx = param.indexOf('=');
@@ -555,78 +553,49 @@ const parseConnectionString = (str) =>
555
553
  return acc
556
554
  }, {});
557
555
 
558
- /** 配置了 DB_AES_KEY 时尝试解密;非密文(解密失败)则原样使用 */
556
+ /** 配置了 DB_AES_KEY 时尝试解密 */
559
557
  const resolveConnectionString = (connectionString) => {
560
558
  const aesKey = process.env.DB_AES_KEY;
561
559
  if (aesKey) {
562
560
  try {
563
561
  return aes.decryptString(connectionString, aesKey)
564
562
  } catch {
565
- // 明文连接串,直接使用
563
+ // 解密失败,认为是明文
566
564
  }
567
565
  }
566
+
568
567
  return connectionString
569
568
  };
570
-
571
- class DatabaseHelper {
572
- /**
573
- * 初始化数据库连接(自动读取 DB_CONNECTION_STRING,可传参覆盖)
574
- * @param {string} [connectionString=process.env.DB_CONNECTION_STRING] 连接串(明文或 AES 密文)
575
- * @returns {Promise<object>} knex 实例
576
- * @example
577
- * const db = await database.init()
578
- * const rows = await db('users').select('*')
579
- */
580
- async init(connectionString = process.env.DB_CONNECTION_STRING) {
581
- if (!connectionString) {
582
- throw new Error(
583
- 'DB connection string required: pass it to database.init(str) or set DB_CONNECTION_STRING'
584
- )
585
- }
586
- await this.close(); // 重复初始化前先释放旧连接
587
-
588
- const params = parseConnectionString(resolveConnectionString(connectionString));
589
- db$1 = knex({
590
- client: 'mssql',
591
- connection: {
592
- user: params.user,
593
- password: params.password,
594
- server: params.server,
595
- database: params.database,
596
- options: {
597
- encrypt: false
598
- }
569
+ /**
570
+ * 创建数据库实例
571
+ */
572
+ const useDatabase = async (connectionString = process.env.DB_CONNECTION_STRING) => {
573
+ if (!connectionString)
574
+ throw new Error('DB connection string required: pass it to init(str) or set DB_CONNECTION_STRING')
575
+
576
+ // 当前实例重复初始化
577
+ const params = parseConnectionString(resolveConnectionString(connectionString));
578
+ const db = knex({
579
+ client: 'mssql',
580
+ connection: {
581
+ user: params.user,
582
+ password: params.password,
583
+ server: params.server,
584
+ database: params.database,
585
+ options: {
586
+ encrypt: false
599
587
  }
600
- });
601
-
602
- try {
603
- await db$1.raw('SELECT 1'); // 验证真实连接
604
- } catch (err) {
605
- await this.close();
606
- throw err
607
588
  }
608
- return db$1
609
- }
589
+ });
610
590
 
611
- /**
612
- * 获取 knex 实例(未初始化时给出明确提示)
613
- * @returns {object} knex 实例
614
- */
615
- get() {
616
- if (!db$1) throw new Error('Database not initialized, call await database.init() first')
617
- return db$1
618
- }
591
+ await db.raw('SELECT 1');
592
+ const close = async () => await db.destroy();
619
593
 
620
- /** 关闭数据库连接 */
621
- async close() {
622
- if (db$1) {
623
- await db$1.destroy();
624
- db$1 = null;
625
- }
594
+ return {
595
+ db,
596
+ close
626
597
  }
627
- }
628
-
629
- var database = new DatabaseHelper();
598
+ };
630
599
 
631
600
  let registerError = null;
632
601
  let registerComplete = null;
@@ -660,7 +629,6 @@ var hooks = {
660
629
  };
661
630
 
662
631
  let bree = null;
663
- let db = null;
664
632
  let jobsRoot = null;
665
633
 
666
634
  const logger = createLogger({ name: 'scheduler', split: true });
@@ -714,31 +682,71 @@ const createBree = () => {
714
682
  workerMessageHandler: async (workerMetadata) => {
715
683
  const name = workerMetadata?.name;
716
684
  const message = workerMetadata?.message;
685
+ let close = null;
717
686
  try {
718
687
  console.log(`[${name}] worker message:`, message);
719
- if (message?.type === 'complete') {
720
- const workerData = getWorkerData(name);
721
- const sendData = { ...workerData, result: JSON.stringify(message?.data) };
722
- await hooks.registerComplete(db, sendData);
688
+ if (message?.type !== 'complete') return
689
+
690
+ const workerData = getWorkerData(name);
691
+ if (!workerData) return
692
+ if (hooks.registerComplete === null || typeof hooks.registerComplete !== 'function') {
693
+ logger.error('hooks.registerComplete is not a function');
694
+ return
695
+ }
696
+
697
+ const database = await useDatabase();
698
+ const db = database.db;
699
+ if (!db) {
700
+ logger.error('Database initialization failed');
701
+ return
723
702
  }
703
+
704
+ close = database.close;
705
+ const sendData = { ...workerData, result: JSON.stringify(message?.data ?? {}) };
706
+ await hooks.registerComplete(db, sendData);
724
707
  }
725
708
  catch (error) {
726
709
  logger.error(`[${name}] ${error?.stack || error?.message || error}`);
727
710
  }
711
+ finally {
712
+ await close?.();
713
+ }
728
714
  },
729
715
  errorHandler: async (error, workerMetadata) => {
730
716
  const name = workerMetadata?.name;
717
+ let close = null;
731
718
  try {
732
719
  if (error?.message?.indexOf('exited with code') > -1) return
733
720
  logger.error(`[${name}] ${error?.stack || error?.message || error}`);
721
+
734
722
  const workerData = getWorkerData(name);
735
- const sendData = { ...workerData, error: error?.stack };
736
- if (workerData)
737
- await hooks.registerError(db, sendData);
723
+ if (!workerData) return
724
+ if (hooks.registerError === null || typeof hooks.registerError !== 'function') {
725
+ logger.error('hooks.registerError is not a function');
726
+ return
727
+ }
728
+
729
+ const database = await useDatabase();
730
+ const db = database.db;
731
+ if (!db) {
732
+ logger.error('Database initialization failed');
733
+ return
734
+ }
735
+
736
+ close = database.close;
737
+ const sendData = {
738
+ ...workerData,
739
+ error: error?.stack ||
740
+ error?.message
741
+ };
742
+ await hooks.registerError(db, sendData);
738
743
  }
739
744
  catch (error) {
740
745
  logger.error(`[${name}] ${error?.stack || error?.message || error}`);
741
746
  }
747
+ finally {
748
+ await close?.();
749
+ }
742
750
  }
743
751
  });
744
752
 
@@ -764,11 +772,10 @@ const notInit = () => (bree ? null : fail('scheduler 未初始化,请先调用
764
772
  const isExist = (name) => bree?.config?.jobs?.some(x => x.name === name);
765
773
 
766
774
  // 统一包装:未初始化检查 + 异常捕获,让每个方法只保留业务逻辑
767
- const guard = (fn, { checkInit = true } = {}) => async (...args) => {
768
- if (checkInit) {
769
- const ni = notInit();
770
- if (ni) return ni
771
- }
775
+ const guard = (fn) => async (...args) => {
776
+ const ni = notInit();
777
+ if (ni) return ni
778
+
772
779
  try {
773
780
  return await fn(...args)
774
781
  }
@@ -788,26 +795,25 @@ const create = guard(async (job) => {
788
795
  return ok(`job "${name}" 创建成功`, { name })
789
796
  });
790
797
 
791
- // 移除任务(停止并删除)
792
- const remove = guard(async (name) => {
793
- if (!isExist(name)) return fail(`job "${name}" 不存在`)
794
- await bree.stop(name);
795
- const index = bree.config.jobs.findIndex(x => x.name === name);
796
- if (index !== -1) bree.config.jobs.splice(index, 1);
797
- return ok(`job "${name}" 已移除`, { name })
798
- });
799
-
800
798
  // 重置任务(移除后按新配置重新添加,可选立即启动)
801
799
  const reset = guard(async (job, startStatus) => {
802
800
  const name = job?.name;
803
801
  if (!name) return fail('job 必须包含 name')
804
- const removed = await remove(name);
805
- if (removed.code !== 0) return removed
802
+ await remove(name);
806
803
  await bree.add(job);
807
804
  if (startStatus) await bree.start(name);
808
805
  return ok(`job "${name}" 已重置${startStatus ? '并启动' : ''}`, { name, startStatus })
809
806
  });
810
807
 
808
+ // 移除任务(停止并删除)
809
+ const remove = guard(async (name) => {
810
+ if (!isExist(name)) return fail(`job "${name}" 不存在`)
811
+ await bree.stop(name);
812
+ const index = bree.config.jobs.findIndex(x => x.name === name);
813
+ if (index !== -1) bree.config.jobs.splice(index, 1);
814
+ return ok(`job "${name}" 已移除`, { name })
815
+ });
816
+
811
817
  // 启动任务
812
818
  const start = guard(async (name) => {
813
819
  if (!isExist(name)) return fail(`job "${name}" 不存在`)
@@ -830,13 +836,31 @@ const run = guard(async (name) => {
830
836
  });
831
837
 
832
838
  // 任务初始化:初始化数据库、创建 Bree 实例并加载任务列表
833
- const register$1 = guard(async () => {
834
- db = await database.init();
835
- bree = createBree();
836
- await hooks.registerLoader(db, logger);
837
- const jobs = bree.config.jobs.map(x => ({ name: x.name, interval: x.interval }));
838
- return ok('scheduler 已注册', { jobs })
839
- }, { checkInit: false });
839
+ const register$1 = async () => {
840
+ let close = null;
841
+ try {
842
+ if (hooks.registerLoader === null || typeof hooks.registerLoader !== 'function')
843
+ throw new Error('hooks.registerLoader is not a function')
844
+
845
+ const database = await useDatabase();
846
+ const db = database.db;
847
+ if (!db) throw new Error('Database initialization failed')
848
+
849
+ close = database.close;
850
+ bree = createBree();
851
+ if (!bree) throw new Error('Breejs initialization failed')
852
+
853
+ await hooks.registerLoader(db, logger);
854
+ const jobs = bree.config.jobs.map(x => ({ name: x.name, interval: x.interval }));
855
+ return ok('scheduler 已注册', { jobs })
856
+ }
857
+ catch (error) {
858
+ logger.error(`register=>${error?.stack || error?.message || error}`);
859
+ }
860
+ finally {
861
+ await close?.();
862
+ }
863
+ };
840
864
 
841
865
  var scheduler = {
842
866
  register: register$1,
@@ -1286,7 +1310,6 @@ function useServer(options = {}) {
1286
1310
 
1287
1311
  function useHandler() {
1288
1312
  let isCancelled = false;
1289
- let db = null;
1290
1313
  const logger = createLogger({ name: 'worker' });
1291
1314
 
1292
1315
  if (parentPort)
@@ -1300,17 +1323,35 @@ function useHandler() {
1300
1323
 
1301
1324
  const getIsCancelled = () => isCancelled;
1302
1325
  const run = async (worker) => {
1303
- db = await database.init();
1304
- const result = await worker({ logger, redis, db, workerData });
1305
- if (parentPort) {
1306
- parentPort.postMessage({ type: 'complete', data: result });
1307
- parentPort.postMessage('done');
1326
+ if (typeof worker !== 'function') {
1327
+ logger.error(`run worker is not a function`);
1328
+ return
1329
+ }
1330
+
1331
+ let close = null;
1332
+ try {
1333
+ const database = await useDatabase();
1334
+ const db = database.db;
1335
+ close = database.close;
1336
+ const result = await worker({ logger, redis, db, workerData });
1337
+ if (parentPort) parentPort.postMessage({ type: 'complete', data: result });
1338
+ }
1339
+ catch (error) {
1340
+ logger.error(`worker=>${error?.stack || error?.message || error}`);
1341
+ }
1342
+ finally {
1343
+ try {
1344
+ await close?.();
1345
+ } catch (error) {
1346
+ logger.error(`database close=>${error?.stack || error?.message || error}`);
1347
+ }
1348
+ if (parentPort) parentPort.postMessage('done');
1349
+ else process.exit(0);
1308
1350
  }
1309
- else process.exit(0);
1310
1351
  };
1311
1352
 
1312
1353
  return { run, getIsCancelled }
1313
1354
  }
1314
1355
 
1315
- export { aes, auth, createLogger, database, excelUtil as excel, hooks, mailUtil as mail, redis, route, scheduler, useHandler, useServer };
1356
+ export { aes, auth, createLogger, excelUtil as excel, hooks, mailUtil as mail, redis, route, scheduler, useDatabase, useHandler, useServer };
1316
1357
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/excelUtil.js","../src/utils/mailUtil.js","../src/core/redis.js","../src/utils/redisUtil.js","../src/config/createLogger.js","../src/utils/aesUtil.js","../src/utils/databaseUtil.js","../src/core/hooks.js","../src/core/scheduler.js","../src/core/route.js","../src/core/auth.js","../src/core/useServer.js","../src/core/useHandler.js"],"sourcesContent":["import ExcelJS from 'exceljs'\r\nimport path from 'node:path'\r\nimport fs from 'node:fs/promises'\r\n\r\nlet baseFolder = null\r\n\r\n/**\r\n * 内部:构建 sheet columns:[{ header: 'ID', key: 'id', width: 10 }]\r\n */\r\nconst buildSheet = (workbook, columns, data) => {\r\n const sheet = workbook.addWorksheet('sheet1')\r\n sheet.columns = columns\r\n for (const item of data) {\r\n sheet.addRow(item)\r\n }\r\n return sheet\r\n}\r\n\r\n/**\r\n * 文件\r\n * @param {*} fileName \r\n * @param {*} folder \r\n * @returns \r\n */\r\nconst getFilePath = async (fileName) => {\r\n const baseDir = baseFolder\r\n ? path.resolve(process.cwd(), baseFolder)\r\n : process.cwd()\r\n\r\n await fs.mkdir(baseDir, { recursive: true })\r\n\r\n const name = fileName.endsWith('.xlsx')\r\n ? fileName\r\n : `${fileName}.xlsx`\r\n\r\n return path.join(baseDir, name)\r\n}\r\n\r\n/**\r\n * 设置基础目录\r\n * @param {*} folder \r\n */\r\nconst setFolder = (folder) => {\r\n baseFolder = folder\r\n}\r\n\r\n/**\r\n * 小/中数据:生成 Excel 文件(落盘)\r\n * 适合:< 5w 行\r\n */\r\nconst createExcel = async (columns, data, fileName = 'report') => {\r\n const workbook = new ExcelJS.Workbook()\r\n buildSheet(workbook, columns, data)\r\n const filePath = await getFilePath(fileName)\r\n await workbook.xlsx.writeFile(filePath)\r\n return filePath\r\n}\r\n\r\n/**\r\n * 邮件专用:生成 Buffer(不落盘)\r\n * 适合:中小数据\r\n */\r\nconst createBufferExcel = async (columns, data) => {\r\n const workbook = new ExcelJS.Workbook()\r\n buildSheet(workbook, columns, data)\r\n return await workbook.xlsx.writeBuffer()\r\n}\r\n\r\n/**\r\n * 大数据(核心优化):流式写入(不爆内存)\r\n * 适合:10w ~ 100w+\r\n */\r\nlet streamWorkbook = null\r\nlet streamSheet = null\r\nconst createStreamExcel = async (columns, data, fileName = 'report', lastWrite = false) => {\r\n const filePath = await getFilePath(fileName)\r\n if (!streamWorkbook) {\r\n streamWorkbook = new ExcelJS.stream.xlsx.WorkbookWriter({\r\n filename: filePath,\r\n useStyles: false,\r\n useSharedStrings: true\r\n })\r\n\r\n streamSheet = workbook.addWorksheet('Report')\r\n streamSheet.columns = columns\r\n }\r\n for (const item of data) {\r\n streamSheet.addRow(item).commit()\r\n }\r\n\r\n if (lastWrite) {\r\n await workbook.commit()\r\n streamWorkbook = null\r\n streamSheet = null\r\n }\r\n return filePath\r\n}\r\n\r\n/**\r\n * 🚀 统一入口(推荐用这个)\r\n */\r\nconst exportExcel = async ({\r\n mode = 'file', // file | buffer | stream\r\n columns,\r\n data,\r\n fileName = 'report'\r\n}) => {\r\n switch (mode) {\r\n case 'buffer':\r\n return await createBufferExcel(columns, data)\r\n case 'stream':\r\n return await createStreamExcel(columns, data, fileName, true)\r\n default:\r\n return await createExcel(columns, data, fileName)\r\n }\r\n}\r\n\r\nexport default {\r\n setFolder,\r\n getFilePath,\r\n exportExcel,\r\n createExcel,\r\n createBufferExcel,\r\n createStreamExcel\r\n}","import nodemailer from 'nodemailer'\r\nimport path from 'node:path'\r\n\r\nlet transporter = null\r\nlet from = ''\r\nconst init = () => {\r\n from = `\"${process.env.MAIL_USERNAME}\" <${process.env.MAIL_ACCOUNT}>`\r\n transporter = nodemailer.createTransport({\r\n host: process.env.MAIL_HOST, // 或公司邮箱 SMTP\r\n port: Number(process.env.MAIL_PORT),\r\n secure: true,\r\n auth: {\r\n user: process.env.MAIL_ACCOUNT,\r\n pass: process.env.MAIL_PASSWORD // 注意不是密码\r\n }\r\n })\r\n}\r\n\r\nconst send = async (subject, toUser = '', copyUser = '', content = '', filePath = []) => {\r\n await transporter.sendMail({\r\n from: from,\r\n to: toUser.split(',').map(i => i.trim()).filter(Boolean),\r\n cc: copyUser.split(',').map(i => i.trim()).filter(Boolean),\r\n subject: subject,\r\n text: content,\r\n attachments: filePath.map(file => {\r\n const filename = path.basename(file) // ⭐ 核心:自动截取文件名\r\n return {\r\n path: file,\r\n filename\r\n }\r\n })\r\n })\r\n}\r\n\r\nexport default {\r\n init,\r\n send\r\n}","import { createClient } from 'redis'\r\n\r\nlet client = null\r\nlet isConnected = false\r\n\r\nasync function createRedisClient() {\r\n const redis = createClient({\r\n socket: {\r\n host: process.env.REDIS_HOST,\r\n port: Number(process.env.REDIS_PORT),\r\n reconnectStrategy(retries) {\r\n console.log(`Redis 重连 ${retries}`)\r\n\r\n // 超过 2 次停止重连\r\n if (retries > 3) {\r\n return new Error('Redis 重连失败')\r\n }\r\n\r\n return Math.min(retries * 1000, 5000)\r\n }\r\n },\r\n RESP: 2, // ⭐关键\r\n username: process.env.REDIS_USERNAME || undefined,\r\n password: process.env.REDIS_PASSWORD || undefined,\r\n database: Number(process.env.REDIS_DB || 0)\r\n })\r\n\r\n redis.on('connect', () => {\r\n console.log('Redis 正在连接...')\r\n })\r\n\r\n redis.on('ready', () => {\r\n isConnected = true\r\n console.log('Redis 已连接')\r\n })\r\n\r\n redis.on('reconnecting', () => {\r\n console.log('Redis 重连中...')\r\n })\r\n\r\n redis.on('end', () => {\r\n isConnected = false\r\n console.log('Redis 已断开')\r\n })\r\n\r\n redis.on('error', (err) => {\r\n console.error('Redis异常:', err.message)\r\n })\r\n\r\n await redis.connect()\r\n\r\n return redis\r\n}\r\n\r\nexport async function getRedis() {\r\n if (!client) {\r\n client = await createRedisClient()\r\n }\r\n\r\n return client\r\n}\r\n\r\nexport function redisConnected() {\r\n return isConnected\r\n}\r\n\r\nexport async function closeRedis() {\r\n if (client) {\r\n await client.quit()\r\n client = null\r\n }\r\n}","import { getRedis, closeRedis } from '../core/redis.js'\r\n\r\nclass RedisHelper {\r\n async set(key, value, expireSeconds = null) {\r\n const redis = await getRedis()\r\n\r\n const data =\r\n typeof value === 'object'\r\n ? JSON.stringify(value)\r\n : String(value)\r\n\r\n if (expireSeconds) {\r\n return await redis.set(key, data, {\r\n EX: expireSeconds\r\n })\r\n }\r\n\r\n return await redis.set(key, data)\r\n }\r\n\r\n async get(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.get(key)\r\n\r\n if (!value) return null\r\n\r\n try {\r\n return JSON.parse(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n\r\n async del(key) {\r\n const redis = await getRedis()\r\n return await redis.del(key)\r\n }\r\n\r\n async exists(key) {\r\n const redis = await getRedis()\r\n return (await redis.exists(key)) === 1\r\n }\r\n\r\n async expire(key, seconds) {\r\n const redis = await getRedis()\r\n return await redis.expire(key, seconds)\r\n }\r\n\r\n async ttl(key) {\r\n const redis = await getRedis()\r\n return await redis.ttl(key)\r\n }\r\n\r\n async incr(key) {\r\n const redis = await getRedis()\r\n return await redis.incr(key)\r\n }\r\n\r\n async decr(key) {\r\n const redis = await getRedis()\r\n return await redis.decr(key)\r\n }\r\n\r\n async hSet(key, field, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.hSet(\r\n key,\r\n field,\r\n typeof value === 'object'\r\n ? JSON.stringify(value)\r\n : String(value)\r\n )\r\n }\r\n\r\n async hGet(key, field) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.hGet(key, field)\r\n\r\n if (!value) return null\r\n\r\n try {\r\n return JSON.parse(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n\r\n async hGetAll(key) {\r\n const redis = await getRedis()\r\n return await redis.hGetAll(key)\r\n }\r\n\r\n async lPush(key, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.lPush(\r\n key,\r\n JSON.stringify(value)\r\n )\r\n }\r\n\r\n async rPush(key, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.rPush(\r\n key,\r\n JSON.stringify(value)\r\n )\r\n }\r\n\r\n async rPop(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.rPop(key)\r\n\r\n return value\r\n ? JSON.parse(value)\r\n : null\r\n }\r\n\r\n async lPop(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.lPop(key)\r\n\r\n return value\r\n ? JSON.parse(value)\r\n : null\r\n }\r\n\r\n async close() {\r\n await closeRedis()\r\n }\r\n}\r\n\r\nexport default new RedisHelper()","import winston from 'winston'\r\nimport 'winston-daily-rotate-file'\r\nimport path from 'node:path'\r\n\r\nconst { combine, timestamp, printf } = winston.format\r\n\r\n/**\r\n * 默认日志格式:可被 format 参数覆盖\r\n */\r\nconst defaultLogFormat = printf(({ timestamp, level, message }) => {\r\n return `[${timestamp}] [${level.toUpperCase()}] ${message}`\r\n})\r\n\r\n/**\r\n * 单级别文件过滤器(用于 split 按级别拆文件)\r\n */\r\nconst levelFilter = (level) => {\r\n return winston.format((info) => {\r\n return info.level === level ? info : false\r\n })()\r\n}\r\n\r\n/**\r\n * split=true 时默认按全部级别拆分\r\n */\r\nconst defaultSplitLevels = ['debug', 'info', 'warn', 'error']\r\n\r\n/**\r\n * 统一 logger 工厂\r\n * @param {object} options\r\n * @param {string} [options.name='app'] 日志文件名前缀,如 'worker' -> worker-%DATE%.log;不传 dirname 时同时作为子目录名\r\n * @param {string} [options.dirname] 日志子目录(相对 logs 根);不传则用 name 作为子目录名,\r\n * 显式传 '' 则直接写在 logs 根下。如 'weixinapi' -> logs/weixinapi/\r\n * @param {string} [options.level='info'] 日志级别:error | warn | info | debug\r\n * @param {function} [options.format] 自定义日志格式(printf 函数),默认 [时间] [级别] 消息\r\n * @param {boolean} [options.console=true] 是否输出到控制台\r\n * @param {boolean} [options.file=true] 是否输出到文件\r\n * @param {string} [options.datePattern='YYYY-MM-DD'] 日志文件名日期格式\r\n * @param {string} [options.maxSize='20m'] 单个日志文件大小上限,超过即滚动,如 '20m' | '100k'\r\n * @param {string|number} [options.maxFiles='30d'] 日志保留时长/份数,如 '30d' | 14\r\n * @param {boolean|string[]} [options.split=false]\r\n * false:不拆分,全部写到 <name>-%DATE%.log\r\n * true:按 debug/info/warn/error 各写一个文件\r\n * 数组:按传入级别拆分,如 ['info', 'warn', 'error']\r\n * @returns {import('winston').Logger}\r\n */\r\nexport function createLogger(options = {}) {\r\n const {\r\n name = 'app',\r\n dirname,\r\n level = 'info',\r\n format = defaultLogFormat,\r\n console = true,\r\n file = true,\r\n datePattern = 'YYYY-MM-DD',\r\n maxSize = '10m',\r\n maxFiles = '10d',\r\n split = false\r\n } = options\r\n\r\n // 目录解析:设置 LOG_DIR 环境变量即自动以其为日志根目录,否则以 logs 为根目录\r\n // dirname 为其下子目录;不传 dirname 时自动用 name 作为子目录;显式传 '' 则直接写根\r\n const subDir = dirname ?? name\r\n const root = process.env.LOG_DIR ? path.join(process.env.LOG_DIR, 'logs') : 'logs'\r\n const logDir = path.join(root, subDir)\r\n\r\n /**\r\n * 内部:创建文件滚动 transport\r\n * @param {string} filename\r\n * @param {string} [fileLevel] 指定级别时配合 levelFilter 精确过滤,仅写该级别日志\r\n */\r\n const createFileTransport = (filename, fileLevel) => {\r\n const formatParts = [\r\n timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format\r\n ]\r\n if (fileLevel) formatParts.unshift(levelFilter(fileLevel))\r\n\r\n return new winston.transports.DailyRotateFile({\r\n dirname: logDir,\r\n filename,\r\n ...(fileLevel ? { level: fileLevel } : {}),\r\n datePattern,\r\n maxSize,\r\n maxFiles,\r\n format: combine(...formatParts)\r\n })\r\n }\r\n\r\n const transports = []\r\n\r\n if (console) {\r\n transports.push(new winston.transports.Console())\r\n }\r\n\r\n if (file) {\r\n const splitLevels = Array.isArray(split)\r\n ? split\r\n : (split ? defaultSplitLevels : null)\r\n\r\n if (splitLevels) {\r\n for (const splitLevel of splitLevels) {\r\n transports.push(createFileTransport(`${name}-${splitLevel}-%DATE%.log`, splitLevel))\r\n }\r\n } else {\r\n transports.push(createFileTransport(`${name}-%DATE%.log`))\r\n }\r\n }\r\n\r\n return winston.createLogger({\r\n level,\r\n format: combine(\r\n timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format\r\n ),\r\n transports\r\n })\r\n}\r\n\r\nexport default createLogger\r\n","import crypto from 'node:crypto'\r\n\r\nconst ALGORITHM_MAP = {\r\n 16: 'aes-128-ecb',\r\n 24: 'aes-192-ecb',\r\n 32: 'aes-256-ecb'\r\n}\r\n\r\nconst encrypt = (data, key) => {\r\n // key 必须 16 / 24 / 32 字节\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const cipher = crypto.createCipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n cipher.setAutoPadding(true) // PKCS7\r\n const encrypted = Buffer.concat([\r\n cipher.update(data),\r\n cipher.final()\r\n ])\r\n return encrypted\r\n}\r\n\r\nconst decrypt = (data, key) => {\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const decipher = crypto.createDecipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n decipher.setAutoPadding(true)\r\n const decrypted = Buffer.concat([\r\n decipher.update(data),\r\n decipher.final()\r\n ])\r\n return decrypted\r\n}\r\n\r\n/**\r\n * AES解密\r\n * 对应 Java:\r\n * AesUtil.decrypt(String data, String key)\r\n *\r\n * @param {string} data Base64密文\r\n * @param {string} key AES密钥(16/24/32字节)\r\n * @returns {string} 明文\r\n */\r\nconst decryptString = (data, key) => {\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const decipher = crypto.createDecipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n decipher.setAutoPadding(true)\r\n const decrypted = Buffer.concat([\r\n decipher.update(Buffer.from(data, 'base64')),\r\n decipher.final()\r\n ])\r\n return decrypted.toString('utf8')\r\n}\r\n\r\nexport default { encrypt, decrypt, decryptString }","import knex from 'knex'\r\nimport aes from './aesUtil.js'\r\n\r\nlet db = null\r\n\r\n/** 解析 `key=value;key=value` 形式的连接串(值允许包含 `=`) */\r\nconst parseConnectionString = (str) =>\r\n str.split(';').reduce((acc, param) => {\r\n const idx = param.indexOf('=')\r\n if (idx === -1) return acc\r\n const key = param.slice(0, idx).trim()\r\n const value = param.slice(idx + 1).trim()\r\n if (key) acc[key] = value\r\n return acc\r\n }, {})\r\n\r\n/** 配置了 DB_AES_KEY 时尝试解密;非密文(解密失败)则原样使用 */\r\nconst resolveConnectionString = (connectionString) => {\r\n const aesKey = process.env.DB_AES_KEY\r\n if (aesKey) {\r\n try {\r\n return aes.decryptString(connectionString, aesKey)\r\n } catch {\r\n // 明文连接串,直接使用\r\n }\r\n }\r\n return connectionString\r\n}\r\n\r\nclass DatabaseHelper {\r\n /**\r\n * 初始化数据库连接(自动读取 DB_CONNECTION_STRING,可传参覆盖)\r\n * @param {string} [connectionString=process.env.DB_CONNECTION_STRING] 连接串(明文或 AES 密文)\r\n * @returns {Promise<object>} knex 实例\r\n * @example\r\n * const db = await database.init()\r\n * const rows = await db('users').select('*')\r\n */\r\n async init(connectionString = process.env.DB_CONNECTION_STRING) {\r\n if (!connectionString) {\r\n throw new Error(\r\n 'DB connection string required: pass it to database.init(str) or set DB_CONNECTION_STRING'\r\n )\r\n }\r\n await this.close() // 重复初始化前先释放旧连接\r\n\r\n const params = parseConnectionString(resolveConnectionString(connectionString))\r\n db = knex({\r\n client: 'mssql',\r\n connection: {\r\n user: params.user,\r\n password: params.password,\r\n server: params.server,\r\n database: params.database,\r\n options: {\r\n encrypt: false\r\n }\r\n }\r\n })\r\n\r\n try {\r\n await db.raw('SELECT 1') // 验证真实连接\r\n } catch (err) {\r\n await this.close()\r\n throw err\r\n }\r\n return db\r\n }\r\n\r\n /**\r\n * 获取 knex 实例(未初始化时给出明确提示)\r\n * @returns {object} knex 实例\r\n */\r\n get() {\r\n if (!db) throw new Error('Database not initialized, call await database.init() first')\r\n return db\r\n }\r\n\r\n /** 关闭数据库连接 */\r\n async close() {\r\n if (db) {\r\n await db.destroy()\r\n db = null\r\n }\r\n }\r\n}\r\n\r\nexport default new DatabaseHelper()\r\n","\r\nlet registerError = null\r\nlet registerComplete = null\r\nlet registerLoader = null\r\n\r\n/** 每个钩子未注册时只提示一次,避免刷屏 */\r\nconst warnOnce = (() => {\r\n const warned = new Set()\r\n return (name) => {\r\n if (warned.has(name)) return\r\n warned.add(name)\r\n console.warn(\r\n `[bree-core] hooks.${name} 未注册,任务状态不会回写数据库。` +\r\n `可直接赋值 hooks.${name} = async (db, obj) => { /* 回写逻辑 */ } 注册。`\r\n )\r\n }\r\n})()\r\n\r\n// 默认空实现:不注册不崩溃,只提示一次\r\nregisterError = async () => warnOnce('registerError')\r\nregisterComplete = async () => warnOnce('registerComplete')\r\nregisterLoader = async () => {\r\n warnOnce('registerLoader')\r\n return []\r\n}\r\n\r\nexport default {\r\n registerLoader,\r\n registerError,\r\n registerComplete\r\n}\r\n","import Bree from 'bree'\r\nimport path from 'node:path'\r\nimport fs from 'node:fs'\r\nimport createLogger from '../config/createLogger.js'\r\nimport database from '../utils/databaseUtil.js'\r\nimport hooks from './hooks.js'\r\n\r\nlet bree = null\r\nlet db = null\r\nlet jobsRoot = null\r\n\r\nconst logger = createLogger({ name: 'scheduler', split: true })\r\n\r\n// 让使用者通过环境变量或配置指定 jobs 目录\r\nconst getJobsRoot = () => {\r\n if (jobsRoot) return jobsRoot\r\n\r\n // 多种方式获取 jobs 目录\r\n // 1. 环境变量\r\n if (process.env.BREE_JOBS_PATH) {\r\n jobsRoot = path.resolve(process.env.BREE_JOBS_PATH)\r\n return jobsRoot\r\n }\r\n\r\n // 2. 使用当前工作目录(项目根目录)\r\n const cwd = process.cwd()\r\n const possiblePaths = [\r\n path.join(cwd, 'src/jobs'),\r\n path.join(cwd, 'jobs'),\r\n path.join(cwd, 'dist/jobs'),\r\n ]\r\n\r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n jobsRoot = p\r\n return jobsRoot\r\n }\r\n }\r\n\r\n // 3. 默认使用当前工作目录下的 src/jobs\r\n jobsRoot = path.join(cwd, 'src/jobs')\r\n console.warn(`Jobs directory not found, using default: ${jobsRoot}`)\r\n return jobsRoot\r\n}\r\n\r\nconst createBree = () => {\r\n const jobsPath = getJobsRoot()\r\n // 确保 jobs 目录存在(创建警告但不自动创建,因为这是使用者的责任)\r\n if (!fs.existsSync(jobsPath)) {\r\n console.warn(`⚠️ Jobs directory not found: ${jobsPath}`)\r\n console.warn(` Please create it or set BREE_JOBS_PATH environment variable`)\r\n }\r\n const getWorkerData = (name) => instance.config.jobs.find(a => a.name === name)?.worker?.workerData\r\n const instance = new Bree({\r\n hasSeconds: true,\r\n root: jobsPath,\r\n doRootCheck: false, // 任务列表由 hooks.registerLoader / 数据库提供,无需 root/index.js\r\n // bree 9.x 官方消息回调(替代已移除的 'worker message' 事件):\r\n // worker 发来的所有消息都进这里;发字符串 'done' 时 bree 会自动清理 worker(terminate + worker deleted)\r\n workerMessageHandler: async (workerMetadata) => {\r\n const name = workerMetadata?.name\r\n const message = workerMetadata?.message\r\n try {\r\n console.log(`[${name}] worker message:`, message)\r\n if (message?.type === 'complete') {\r\n const workerData = getWorkerData(name)\r\n const sendData = { ...workerData, result: JSON.stringify(message?.data) }\r\n await hooks.registerComplete(db, sendData)\r\n }\r\n }\r\n catch (error) {\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n }\r\n },\r\n errorHandler: async (error, workerMetadata) => {\r\n const name = workerMetadata?.name\r\n try {\r\n if (error?.message?.indexOf('exited with code') > -1) return\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n const workerData = getWorkerData(name)\r\n const sendData = { ...workerData, error: error?.stack }\r\n if (workerData)\r\n await hooks.registerError(db, sendData)\r\n }\r\n catch (error) {\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n }\r\n }\r\n })\r\n\r\n instance.on('worker created', (name) => {\r\n console.log(`[${name}] worker created`)\r\n logger.info(`[${name}] worker created`)\r\n })\r\n\r\n instance.on('worker deleted', async (name) => {\r\n console.log(`[${name}] worker deleted`)\r\n logger.info(`[${name}] worker deleted`)\r\n })\r\n\r\n return instance\r\n}\r\n\r\n// 统一返回结构:\r\n// 成功: { code: 0, message, data }\r\n// 失败: { code: -1, message }\r\nconst ok = (message, data = undefined) => ({ code: 0, message, data })\r\nconst fail = (message) => ({ code: -1, message })\r\nconst notInit = () => (bree ? null : fail('scheduler 未初始化,请先调用 scheduler.register()'))\r\nconst isExist = (name) => bree?.config?.jobs?.some(x => x.name === name)\r\n\r\n// 统一包装:未初始化检查 + 异常捕获,让每个方法只保留业务逻辑\r\nconst guard = (fn, { checkInit = true } = {}) => async (...args) => {\r\n if (checkInit) {\r\n const ni = notInit()\r\n if (ni) return ni\r\n }\r\n try {\r\n return await fn(...args)\r\n }\r\n catch (e) {\r\n return fail(e?.message || String(e))\r\n }\r\n}\r\n\r\nconst getBree = () => bree\r\n\r\n// 创建任务(仅注册到调度器,不会自动执行)\r\nconst create = guard(async (job) => {\r\n const name = job?.name\r\n if (!name) return fail('job 必须包含 name')\r\n if (isExist(name)) return fail(`job \"${name}\" 已存在`)\r\n await bree.add(job)\r\n return ok(`job \"${name}\" 创建成功`, { name })\r\n})\r\n\r\n// 移除任务(停止并删除)\r\nconst remove = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.stop(name)\r\n const index = bree.config.jobs.findIndex(x => x.name === name)\r\n if (index !== -1) bree.config.jobs.splice(index, 1)\r\n return ok(`job \"${name}\" 已移除`, { name })\r\n})\r\n\r\n// 重置任务(移除后按新配置重新添加,可选立即启动)\r\nconst reset = guard(async (job, startStatus) => {\r\n const name = job?.name\r\n if (!name) return fail('job 必须包含 name')\r\n const removed = await remove(name)\r\n if (removed.code !== 0) return removed\r\n await bree.add(job)\r\n if (startStatus) await bree.start(name)\r\n return ok(`job \"${name}\" 已重置${startStatus ? '并启动' : ''}`, { name, startStatus })\r\n})\r\n\r\n// 启动任务\r\nconst start = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.start(name)\r\n return ok(`job \"${name}\" 已启动`, { name })\r\n})\r\n\r\n// 停止任务\r\nconst stop = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.stop(name)\r\n return ok(`job \"${name}\" 已停止`, { name })\r\n})\r\n\r\n// 执行一次任务(不按周期调度,立即跑一次)\r\nconst run = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.run(name)\r\n return ok(`job \"${name}\" 已触发执行`, { name })\r\n})\r\n\r\n// 任务初始化:初始化数据库、创建 Bree 实例并加载任务列表\r\nconst register = guard(async () => {\r\n db = await database.init()\r\n bree = createBree()\r\n await hooks.registerLoader(db, logger)\r\n const jobs = bree.config.jobs.map(x => ({ name: x.name, interval: x.interval }))\r\n return ok('scheduler 已注册', { jobs })\r\n}, { checkInit: false })\r\n\r\nexport default {\r\n register,\r\n create,\r\n reset,\r\n start,\r\n stop,\r\n run,\r\n getBree,\r\n remove\r\n}","/**\r\n * 单函数接口风格路由(近似 `@Route('/path')` 装饰器,纯 JS 用函数包装实现)\r\n *\r\n * 用法(业务模块中定义即自动注册,无需手动传给 useServer):\r\n * route.post('/test', (body) => {\r\n * const { name, age } = body\r\n * return { code: 0, message: 'success', data: null } // 完整响应体原样返回\r\n * })\r\n * route.get('/user/:id', async ({ id }) => ({ id }))\r\n *\r\n * 分组前缀(减少重复路径):\r\n * const api = route.parentRoute('/task')\r\n * api.post('/upload', upload.single('file'), async (body, req) => {\r\n * // 注册为 POST /task/upload\r\n * if (!req.file) return { code: -1, message: '文件不能为空' }\r\n * return { code: 0, message: '上传成功', data: { filename: req.file.filename } }\r\n * })\r\n * api.get('/list', async () => []) // GET /task/list\r\n * api.parentRoute('/:id').get('/info', async ({ id }) => ({})) // 支持嵌套,GET /task/:id/info\r\n *\r\n * 支持中间件(Express 风格,如 multer 文件上传):\r\n * route.post('/upload', upload.single('file'), async (body, req, res) => {\r\n * // req.file 由 multer 解析后注入(body 不含文件,文件在 req.file)\r\n * return { code: 0, message: '上传成功', data: { filename: req.file.filename } }\r\n * })\r\n * route.post('/upload', [auth, upload.array('files', 5)], async (body, req, res) => { ... })\r\n *\r\n * handler 签名:async (body, req, res) => result\r\n * - body:自动合并 { params, query, body },解构即用\r\n * - req / res:原始对象(需要时可用 req.file、req.ip、res.setHeader 等)\r\n * - 返回 { code, ... } 对象时原样 res.json 输出;返回普通数据自动包装为 res.success\r\n * - 抛错自动进入全局错误处理\r\n *\r\n * 方法类型:route.get / route.post / route.put / route.delete / route.patch\r\n * 也可 route(path, handler, method),默认 POST\r\n */\r\n\r\n/** 自动注册路由注册表(模块加载时定义即注册,useServer 启动时自动收集) */\r\nconst registeredRoutes = []\r\n\r\nconst register = (route) => {\r\n const idx = registeredRoutes.findIndex((r) => r.method === route.method && r.path === route.path)\r\n if (idx >= 0) registeredRoutes[idx] = route\r\n else registeredRoutes.push(route)\r\n return route\r\n}\r\n\r\n/** 获取所有已注册路由(内部使用,供 useServer 启动时收集) */\r\nexport const getRegisteredRoutes = () => [...registeredRoutes]\r\n\r\n/** 拼接路径:joinPath('/task', '/upload') => '/task/upload';joinPath('/task', '') => '/task' */\r\nconst joinPath = (prefix, path) => {\r\n const p = String(prefix ?? '').replace(/\\/+$/, '')\r\n const h = String(path ?? '').replace(/^\\/+/, '')\r\n return h ? `${p}/${h}` : p\r\n}\r\n\r\n/**\r\n * 解析参数:route(path, [middlewares...,] handler[, method])\r\n * 兼容:route(path, handler, method)\r\n */\r\nconst resolveArgs = (...args) => {\r\n let method = null\r\n // 末尾若为合法方法字符串,视为 method(兼容 route(path, handler, method))\r\n if (typeof args[args.length - 1] === 'string' && ['get', 'post', 'put', 'delete', 'patch'].includes(args[args.length - 1].toLowerCase())) {\r\n method = args.pop()\r\n }\r\n const handler = args.pop()\r\n // 中间件:单个函数或数组(数组展开),handler 之前的参数\r\n const middlewares = Array.isArray(args[0]) ? args[0] : args\r\n return { middlewares, handler, method }\r\n}\r\n\r\nconst createRoute = (path, middlewares, handler, method) => {\r\n const item = {\r\n method,\r\n path,\r\n handler: async (req, res, next) => {\r\n try {\r\n // 先执行引用者中间件(Express 风格 (req, res, next),如 multer 的 upload.single('file'))\r\n for (const mw of middlewares) {\r\n await new Promise((resolve, reject) => {\r\n mw(req, res, (err) => (err ? reject(err) : resolve()))\r\n })\r\n }\r\n const body = { ...req.params, ...req.query, ...req.body }\r\n const result = await handler(body, req, res)\r\n if (!res.headersSent) {\r\n if (result && typeof result === 'object' && 'code' in result) {\r\n res.json(result)\r\n } else {\r\n res.success(result === undefined ? null : result)\r\n }\r\n }\r\n } catch (err) {\r\n next(err)\r\n }\r\n }\r\n }\r\n return register(item)\r\n}\r\n\r\n/**\r\n * 定义并自动注册一个路由\r\n * @param {string} path 路由路径,如 '/test'\r\n * @param {function|function[]} handlerOrMws 处理函数 async (body, req, res) => result;\r\n * 也可先传中间件(单个或数组,如 multer 的 upload.single('file')),最后一个参数为处理函数\r\n * @param {string} [method='post'] HTTP 方法:get | post | put | delete | patch\r\n * @returns {{method:string,path:string,handler:function}} 路由配置\r\n */\r\nconst route = (path, ...args) => {\r\n const { middlewares, handler, method } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, method || 'post')\r\n}\r\n\r\n// 方法类型便捷写法(IDE 自动补全友好)\r\nroute.get = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'get')\r\n}\r\nroute.post = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'post')\r\n}\r\nroute.put = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'put')\r\n}\r\nroute.delete = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'delete')\r\n}\r\nroute.patch = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'patch')\r\n}\r\n\r\n/**\r\n * 分组前缀路由:返回带 get/post/put/delete/patch 的子路由,路径自动拼接前缀\r\n * 用法:\r\n * const api = route.parentRoute('/task')\r\n * api.post('/upload', upload.single('file'), handler) // POST /task/upload\r\n * api.get('/list', handler) // GET /task/list\r\n * api.parentRoute('/:id').get('/info', handler) // 支持嵌套,GET /task/:id/info\r\n * @param {string} [prefix=''] 路径前缀,如 '/task'\r\n * @returns {{get:function,post:function,put:function,delete:function,patch:function,parentRoute:function}}\r\n */\r\nroute.parentRoute = (prefix = '') => {\r\n const api = {}\r\n for (const method of ['get', 'post', 'put', 'delete', 'patch']) {\r\n api[method] = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(joinPath(prefix, path), middlewares, handler, method)\r\n }\r\n }\r\n // 嵌套分组:api.parentRoute('/:id').get(...)\r\n api.parentRoute = (sub = '') => route.parentRoute(joinPath(prefix, sub))\r\n return api\r\n}\r\n\r\nexport default route\r\n","import aes from \"../utils/aesUtil.js\"\r\n\r\nconst getClientIp = (req) => {\r\n return req.headers['x-forwarded-for']?.split(',')[0]?.trim()\r\n || req.headers['x-real-ip']\r\n || req.ip\r\n || req.connection.remoteAddress\r\n}\r\n\r\nexport function auth(req, res, next) {\r\n const headerName = process.env.API_SECRET_KEY_NAME.toLowerCase()\r\n const apiKey = req.headers[headerName]\r\n if (!apiKey) {\r\n return res.status(200).json({\r\n code: -1,\r\n message: 'Missing API Key'\r\n })\r\n }\r\n\r\n const decryptedApiKey = aes.decryptString(apiKey, process.env.API_SECRET_KEY)\r\n if (!decryptedApiKey || decryptedApiKey !== process.env.API_TOKEN) {\r\n return res.status(200).json({\r\n code: -1,\r\n message: 'Unauthorized'\r\n })\r\n }\r\n\r\n const ip = getClientIp(req)\r\n const allowIps = process.env.ALLOW_IPS?.split(',') || []\r\n if (!allowIps.includes(ip)) {\r\n return res.status(200)\r\n .json({\r\n code: -1,\r\n message: 'IP forbidden'\r\n })\r\n }\r\n\r\n next()\r\n}","import express from 'express'\r\nimport { readdir } from 'fs/promises'\r\nimport path from 'path'\r\nimport { pathToFileURL } from 'url'\r\nimport { createLogger } from '../config/createLogger.js'\r\nimport { auth } from './auth.js'\r\nimport { getRegisteredRoutes } from './route.js'\r\n\r\n/**\r\n * 递归扫描目录下所有 JS 文件并动态加载(触发 route() 自动注册)\r\n * 跳过以 . / _ 开头的文件(如 .DS_Store、_private.js)\r\n */\r\nconst loadRouteFiles = async (dirs, logger) => {\r\n const list = Array.isArray(dirs) ? dirs : [dirs]\r\n let total = 0\r\n\r\n for (const dir of list) {\r\n const abs = path.resolve(dir)\r\n let entries\r\n try {\r\n entries = await readdir(abs, { withFileTypes: true })\r\n } catch {\r\n // 目录不存在则跳过,但给出提示便于诊断路由未加载\r\n logger?.warn?.(`routes dir not found, skipped: ${abs}`)\r\n continue\r\n }\r\n\r\n const walk = async (items, base) => {\r\n for (const item of items) {\r\n if (item.name.startsWith('.') || item.name.startsWith('_')) continue\r\n const full = path.join(base, item.name)\r\n if (item.isDirectory()) {\r\n await walk(await readdir(full, { withFileTypes: true }), full)\r\n } else if (/\\.(mjs|cjs|js)$/i.test(item.name)) {\r\n try {\r\n await import(pathToFileURL(full).href)\r\n total += 1\r\n } catch (err) {\r\n logger?.error?.(`load routes file failed: ${full} - ${err?.message || err}`)\r\n }\r\n }\r\n }\r\n }\r\n await walk(entries, abs)\r\n }\r\n\r\n if (total > 0) logger?.info?.(`auto-loaded ${total} routes file(s)`)\r\n}\r\n\r\n/**\r\n * CORS 中间件(不引入额外依赖)\r\n */\r\nconst createCors = (options = {}) => {\r\n const opts = typeof options === 'string' ? { origin: options } : options\r\n const origin = opts.origin ?? '*'\r\n const methods = opts.methods || 'GET,POST,PUT,DELETE,PATCH,OPTIONS'\r\n const headers = opts.headers || 'Content-Type,Authorization,x-api-key'\r\n\r\n return (req, res, next) => {\r\n res.setHeader('Access-Control-Allow-Origin', origin)\r\n res.setHeader('Access-Control-Allow-Methods', methods)\r\n res.setHeader('Access-Control-Allow-Headers', headers)\r\n if (req.method === 'OPTIONS') return res.sendStatus(204)\r\n next()\r\n }\r\n}\r\n\r\n/**\r\n * Express 服务封装\r\n * @param {object} options\r\n * @param {number} [options.port=3000] 监听端口\r\n * @param {string} [options.host='0.0.0.0'] 监听地址\r\n * @param {object} [options.logger] 自定义 logger(默认 createLogger({ name: 'server', split: true }))\r\n * @param {string} [options.jsonLimit='10mb'] JSON body 大小限制\r\n * @param {string} [options.urlencodedLimit='10mb'] urlencoded body 大小限制\r\n * @param {boolean|string|object} [options.cors=true] 是否启用 CORS;可传 origin 字符串或 { origin, methods, headers }\r\n * @param {string|string[]} [options.staticDir=null] 静态资源目录(可传数组),相对 cwd 或绝对路径\r\n * @param {boolean|function|function[]} [options.auth=false] 认证中间件:\r\n * true 使用内置 auth(依赖 API_SECRET_KEY/API_TOKEN/ALLOW_IPS 环境变量);\r\n * 传函数或函数数组则使用外部自定义中间件(如 (req, res, next) => {...});false 不启用\r\n * @param {boolean} [options.health=true] 是否启用 GET /health 健康检查\r\n * @param {boolean} [options.trustProxy=true] 是否信任代理(影响 req.ip)\r\n * @param {function|Array<{method:string,path:string,handler:function|function[]}>} [options.routes=null]\r\n * 路由注册:函数 (app) => {...} 或路由配置数组;也可省略,用 route() 定义即自动注册\r\n * @param {string|string[]|false} [options.routesDir=['routes','src/routes']] 路由文件目录(相对 cwd 或绝对路径),\r\n * start() 时自动递归扫描并加载其中所有 JS 文件(触发 route() 自动注册),无需手动 import;\r\n * 默认同时扫描 'routes' 与 'src/routes' 两个候选目录(存在哪个扫哪个);\r\n * 传 false 关闭扫描;传数组可自定义多个目录\r\n * @returns {{ app, start, stop, getServer }}\r\n */\r\nexport function useServer(options = {}) {\r\n const {\r\n port = 3000,\r\n host = '0.0.0.0',\r\n logger = createLogger({ name: 'server', split: true }),\r\n jsonLimit = '10mb',\r\n urlencodedLimit = '10mb',\r\n cors = true,\r\n staticDir = null,\r\n auth: enableAuth = false,\r\n health = true,\r\n trustProxy = true,\r\n routes = null,\r\n routesDir = ['routes', 'src/routes']\r\n } = options\r\n\r\n const app = express()\r\n\r\n if (trustProxy) app.set('trust proxy', true)\r\n\r\n // body 解析\r\n app.use(express.json({ limit: jsonLimit }))\r\n app.use(express.urlencoded({ extended: true, limit: urlencodedLimit }))\r\n\r\n // 请求日志(含耗时/状态码/IP)\r\n app.use((req, res, next) => {\r\n const start = Date.now()\r\n res.on('finish', () => {\r\n const duration = Date.now() - start\r\n logger.info(`${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms ${req.ip || ''}`)\r\n })\r\n next()\r\n })\r\n\r\n // CORS\r\n if (cors) app.use(createCors(cors))\r\n\r\n // 统一响应格式 res.success / res.fail\r\n app.use((req, res, next) => {\r\n res.success = (data = null, message = 'ok') => {\r\n res.json({ code: 0, message, data })\r\n }\r\n res.fail = (message = 'error', code = -1) => {\r\n res.json({ code, message, data: null })\r\n }\r\n next()\r\n })\r\n\r\n // 静态资源\r\n if (staticDir) {\r\n const dirs = Array.isArray(staticDir) ? staticDir : [staticDir]\r\n for (const dir of dirs) {\r\n app.use(express.static(dir))\r\n }\r\n }\r\n\r\n // 认证(true 用内置 auth;函数/数组用外部自定义中间件)\r\n if (enableAuth) {\r\n if (typeof enableAuth === 'function') {\r\n app.use(enableAuth)\r\n } else if (Array.isArray(enableAuth)) {\r\n app.use(...enableAuth)\r\n } else {\r\n app.use(auth)\r\n }\r\n }\r\n\r\n // 健康检查\r\n if (health) {\r\n app.get('/health', (req, res) => {\r\n res.success({ status: 'ok', uptime: process.uptime() })\r\n })\r\n }\r\n\r\n // 路由注册 + 404 + 错误处理\r\n // 需在 routesDir 扫描加载(触发 route() 自动注册)之后执行,故封装为函数由 start() 调用\r\n const setupRoutes = () => {\r\n // 业务路由(routes 为函数时保留原逻辑:完全自控注册顺序)\r\n if (typeof routes === 'function') {\r\n routes(app)\r\n }\r\n\r\n // 路由配置:手动传入的 routes + route() 自动注册的路由\r\n // 定义即自动注册,无需在 app.js 中重复传递\r\n const allRoutes = [\r\n ...(Array.isArray(routes) ? routes : []),\r\n ...getRegisteredRoutes()\r\n ]\r\n\r\n // 静态路径优先注册,避免被动态参数路由(如 /:id)吞掉\r\n allRoutes.sort((a, b) => {\r\n const dynamic = (r) => (r.path || '').split('/').filter((s) => s.startsWith(':')).length\r\n return dynamic(a) - dynamic(b)\r\n })\r\n\r\n for (const route of allRoutes) {\r\n const { method, path: routePath, handler } = route\r\n const fn = app[method?.toLowerCase()]\r\n if (typeof fn === 'function' && routePath && handler) {\r\n fn.call(app, routePath, handler)\r\n }\r\n }\r\n\r\n // 404\r\n app.use((req, res) => {\r\n res.status(404).fail('Not Found', 404)\r\n })\r\n\r\n // 全局错误处理(express 5 自动捕获 async 异常)\r\n app.use((err, req, res, next) => {\r\n logger.error(`${req.method} ${req.originalUrl} - ${err?.stack || err?.message || err}`)\r\n if (res.headersSent) return next(err)\r\n\r\n const status = err?.status || err?.statusCode || 500\r\n res.status(status).fail(err?.message || 'Internal Server Error', status)\r\n })\r\n }\r\n\r\n // 启动/停止控制\r\n let server = null\r\n\r\n const start = async () => {\r\n // 自动扫描加载路由文件(触发 route() 自动注册)\r\n if (routesDir) await loadRouteFiles(routesDir, logger)\r\n\r\n // 路由注册 + 404 + 错误处理(在扫描之后执行)\r\n setupRoutes()\r\n\r\n return new Promise((resolve, reject) => {\r\n server = app.listen(port, host, () => {\r\n logger.info(`Server listening on http://${host}:${port}`)\r\n resolve(server)\r\n })\r\n server.on('error', (err) => {\r\n logger.error(`Server error: ${err?.message}`)\r\n reject(err)\r\n })\r\n })\r\n }\r\n\r\n const stop = () => {\r\n return new Promise((resolve) => {\r\n if (!server) return resolve()\r\n server.close(() => resolve())\r\n })\r\n }\r\n\r\n return {\r\n app,\r\n start,\r\n stop,\r\n getServer: () => server\r\n }\r\n}\r\n","import { parentPort, workerData } from 'node:worker_threads'\r\nimport createLogger from '../config/createLogger.js'\r\nimport redis from '../utils/redisUtil.js'\r\nimport database from '../utils/databaseUtil.js'\r\n\r\nexport function useHandler() {\r\n let isCancelled = false\r\n let db = null\r\n const logger = createLogger({ name: 'worker' })\r\n\r\n if (parentPort)\r\n parentPort.once('message', (message) => {\r\n if (message !== 'cancel') return\r\n\r\n isCancelled = true\r\n if (parentPort) parentPort.postMessage('cancelled')\r\n else process.exit(0)\r\n })\r\n\r\n const getIsCancelled = () => isCancelled\r\n const run = async (worker) => {\r\n db = await database.init()\r\n const result = await worker({ logger, redis, db, workerData })\r\n if (parentPort) {\r\n parentPort.postMessage({ type: 'complete', data: result })\r\n parentPort.postMessage('done')\r\n }\r\n else process.exit(0)\r\n }\r\n\r\n return { run, getIsCancelled }\r\n}\r\n"],"names":["db","fs","register","path"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/excelUtil.js","../src/utils/mailUtil.js","../src/core/redis.js","../src/utils/redisUtil.js","../src/config/createLogger.js","../src/utils/aesUtil.js","../src/utils/databaseUtil.js","../src/core/hooks.js","../src/core/scheduler.js","../src/core/route.js","../src/core/auth.js","../src/core/useServer.js","../src/core/useHandler.js"],"sourcesContent":["import ExcelJS from 'exceljs'\r\nimport path from 'node:path'\r\nimport fs from 'node:fs/promises'\r\n\r\nlet baseFolder = null\r\n\r\n/**\r\n * 内部:构建 sheet columns:[{ header: 'ID', key: 'id', width: 10 }]\r\n */\r\nconst buildSheet = (workbook, columns, data) => {\r\n const sheet = workbook.addWorksheet('sheet1')\r\n sheet.columns = columns\r\n for (const item of data) {\r\n sheet.addRow(item)\r\n }\r\n return sheet\r\n}\r\n\r\n/**\r\n * 文件\r\n * @param {*} fileName \r\n * @param {*} folder \r\n * @returns \r\n */\r\nconst getFilePath = async (fileName) => {\r\n const baseDir = baseFolder\r\n ? path.resolve(process.cwd(), baseFolder)\r\n : process.cwd()\r\n\r\n await fs.mkdir(baseDir, { recursive: true })\r\n\r\n const name = fileName.endsWith('.xlsx')\r\n ? fileName\r\n : `${fileName}.xlsx`\r\n\r\n return path.join(baseDir, name)\r\n}\r\n\r\n/**\r\n * 设置基础目录\r\n * @param {*} folder \r\n */\r\nconst setFolder = (folder) => {\r\n baseFolder = folder\r\n}\r\n\r\n/**\r\n * 小/中数据:生成 Excel 文件(落盘)\r\n * 适合:< 5w 行\r\n */\r\nconst createExcel = async (columns, data, fileName = 'report') => {\r\n const workbook = new ExcelJS.Workbook()\r\n buildSheet(workbook, columns, data)\r\n const filePath = await getFilePath(fileName)\r\n await workbook.xlsx.writeFile(filePath)\r\n return filePath\r\n}\r\n\r\n/**\r\n * 邮件专用:生成 Buffer(不落盘)\r\n * 适合:中小数据\r\n */\r\nconst createBufferExcel = async (columns, data) => {\r\n const workbook = new ExcelJS.Workbook()\r\n buildSheet(workbook, columns, data)\r\n return await workbook.xlsx.writeBuffer()\r\n}\r\n\r\n/**\r\n * 大数据(核心优化):流式写入(不爆内存)\r\n * 适合:10w ~ 100w+\r\n */\r\nlet streamWorkbook = null\r\nlet streamSheet = null\r\nconst createStreamExcel = async (columns, data, fileName = 'report', lastWrite = false) => {\r\n const filePath = await getFilePath(fileName)\r\n if (!streamWorkbook) {\r\n streamWorkbook = new ExcelJS.stream.xlsx.WorkbookWriter({\r\n filename: filePath,\r\n useStyles: false,\r\n useSharedStrings: true\r\n })\r\n\r\n streamSheet = workbook.addWorksheet('Report')\r\n streamSheet.columns = columns\r\n }\r\n for (const item of data) {\r\n streamSheet.addRow(item).commit()\r\n }\r\n\r\n if (lastWrite) {\r\n await workbook.commit()\r\n streamWorkbook = null\r\n streamSheet = null\r\n }\r\n return filePath\r\n}\r\n\r\n/**\r\n * 🚀 统一入口(推荐用这个)\r\n */\r\nconst exportExcel = async ({\r\n mode = 'file', // file | buffer | stream\r\n columns,\r\n data,\r\n fileName = 'report'\r\n}) => {\r\n switch (mode) {\r\n case 'buffer':\r\n return await createBufferExcel(columns, data)\r\n case 'stream':\r\n return await createStreamExcel(columns, data, fileName, true)\r\n default:\r\n return await createExcel(columns, data, fileName)\r\n }\r\n}\r\n\r\nexport default {\r\n setFolder,\r\n getFilePath,\r\n exportExcel,\r\n createExcel,\r\n createBufferExcel,\r\n createStreamExcel\r\n}","import nodemailer from 'nodemailer'\r\nimport path from 'node:path'\r\n\r\nlet transporter = null\r\nlet from = ''\r\nconst init = () => {\r\n from = `\"${process.env.MAIL_USERNAME}\" <${process.env.MAIL_ACCOUNT}>`\r\n transporter = nodemailer.createTransport({\r\n host: process.env.MAIL_HOST, // 或公司邮箱 SMTP\r\n port: Number(process.env.MAIL_PORT),\r\n secure: true,\r\n auth: {\r\n user: process.env.MAIL_ACCOUNT,\r\n pass: process.env.MAIL_PASSWORD // 注意不是密码\r\n }\r\n })\r\n}\r\n\r\nconst send = async (subject, toUser = '', copyUser = '', content = '', filePath = []) => {\r\n await transporter.sendMail({\r\n from: from,\r\n to: toUser.split(',').map(i => i.trim()).filter(Boolean),\r\n cc: copyUser.split(',').map(i => i.trim()).filter(Boolean),\r\n subject: subject,\r\n text: content,\r\n attachments: filePath.map(file => {\r\n const filename = path.basename(file) // ⭐ 核心:自动截取文件名\r\n return {\r\n path: file,\r\n filename\r\n }\r\n })\r\n })\r\n}\r\n\r\nexport default {\r\n init,\r\n send\r\n}","import { createClient } from 'redis'\r\n\r\nlet client = null\r\nlet isConnected = false\r\n\r\nasync function createRedisClient() {\r\n const redis = createClient({\r\n socket: {\r\n host: process.env.REDIS_HOST,\r\n port: Number(process.env.REDIS_PORT),\r\n reconnectStrategy(retries) {\r\n console.log(`Redis 重连 ${retries}`)\r\n\r\n // 超过 2 次停止重连\r\n if (retries > 3) {\r\n return new Error('Redis 重连失败')\r\n }\r\n\r\n return Math.min(retries * 1000, 5000)\r\n }\r\n },\r\n RESP: 2, // ⭐关键\r\n username: process.env.REDIS_USERNAME || undefined,\r\n password: process.env.REDIS_PASSWORD || undefined,\r\n database: Number(process.env.REDIS_DB || 0)\r\n })\r\n\r\n redis.on('connect', () => {\r\n console.log('Redis 正在连接...')\r\n })\r\n\r\n redis.on('ready', () => {\r\n isConnected = true\r\n console.log('Redis 已连接')\r\n })\r\n\r\n redis.on('reconnecting', () => {\r\n console.log('Redis 重连中...')\r\n })\r\n\r\n redis.on('end', () => {\r\n isConnected = false\r\n console.log('Redis 已断开')\r\n })\r\n\r\n redis.on('error', (err) => {\r\n console.error('Redis异常:', err.message)\r\n })\r\n\r\n await redis.connect()\r\n\r\n return redis\r\n}\r\n\r\nexport async function getRedis() {\r\n if (!client) {\r\n client = await createRedisClient()\r\n }\r\n\r\n return client\r\n}\r\n\r\nexport function redisConnected() {\r\n return isConnected\r\n}\r\n\r\nexport async function closeRedis() {\r\n if (client) {\r\n await client.quit()\r\n client = null\r\n }\r\n}","import { getRedis, closeRedis } from '../core/redis.js'\r\n\r\nclass RedisHelper {\r\n async set(key, value, expireSeconds = null) {\r\n const redis = await getRedis()\r\n\r\n const data =\r\n typeof value === 'object'\r\n ? JSON.stringify(value)\r\n : String(value)\r\n\r\n if (expireSeconds) {\r\n return await redis.set(key, data, {\r\n EX: expireSeconds\r\n })\r\n }\r\n\r\n return await redis.set(key, data)\r\n }\r\n\r\n async get(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.get(key)\r\n\r\n if (!value) return null\r\n\r\n try {\r\n return JSON.parse(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n\r\n async del(key) {\r\n const redis = await getRedis()\r\n return await redis.del(key)\r\n }\r\n\r\n async exists(key) {\r\n const redis = await getRedis()\r\n return (await redis.exists(key)) === 1\r\n }\r\n\r\n async expire(key, seconds) {\r\n const redis = await getRedis()\r\n return await redis.expire(key, seconds)\r\n }\r\n\r\n async ttl(key) {\r\n const redis = await getRedis()\r\n return await redis.ttl(key)\r\n }\r\n\r\n async incr(key) {\r\n const redis = await getRedis()\r\n return await redis.incr(key)\r\n }\r\n\r\n async decr(key) {\r\n const redis = await getRedis()\r\n return await redis.decr(key)\r\n }\r\n\r\n async hSet(key, field, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.hSet(\r\n key,\r\n field,\r\n typeof value === 'object'\r\n ? JSON.stringify(value)\r\n : String(value)\r\n )\r\n }\r\n\r\n async hGet(key, field) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.hGet(key, field)\r\n\r\n if (!value) return null\r\n\r\n try {\r\n return JSON.parse(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n\r\n async hGetAll(key) {\r\n const redis = await getRedis()\r\n return await redis.hGetAll(key)\r\n }\r\n\r\n async lPush(key, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.lPush(\r\n key,\r\n JSON.stringify(value)\r\n )\r\n }\r\n\r\n async rPush(key, value) {\r\n const redis = await getRedis()\r\n\r\n return await redis.rPush(\r\n key,\r\n JSON.stringify(value)\r\n )\r\n }\r\n\r\n async rPop(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.rPop(key)\r\n\r\n return value\r\n ? JSON.parse(value)\r\n : null\r\n }\r\n\r\n async lPop(key) {\r\n const redis = await getRedis()\r\n\r\n const value = await redis.lPop(key)\r\n\r\n return value\r\n ? JSON.parse(value)\r\n : null\r\n }\r\n\r\n async close() {\r\n await closeRedis()\r\n }\r\n}\r\n\r\nexport default new RedisHelper()","import winston from 'winston'\r\nimport 'winston-daily-rotate-file'\r\nimport path from 'node:path'\r\n\r\nconst { combine, timestamp, printf } = winston.format\r\n\r\n/**\r\n * 默认日志格式:可被 format 参数覆盖\r\n */\r\nconst defaultLogFormat = printf(({ timestamp, level, message }) => {\r\n return `[${timestamp}] [${level.toUpperCase()}] ${message}`\r\n})\r\n\r\n/**\r\n * 单级别文件过滤器(用于 split 按级别拆文件)\r\n */\r\nconst levelFilter = (level) => {\r\n return winston.format((info) => {\r\n return info.level === level ? info : false\r\n })()\r\n}\r\n\r\n/**\r\n * split=true 时默认按全部级别拆分\r\n */\r\nconst defaultSplitLevels = ['debug', 'info', 'warn', 'error']\r\n\r\n/**\r\n * 统一 logger 工厂\r\n * @param {object} options\r\n * @param {string} [options.name='app'] 日志文件名前缀,如 'worker' -> worker-%DATE%.log;不传 dirname 时同时作为子目录名\r\n * @param {string} [options.dirname] 日志子目录(相对 logs 根);不传则用 name 作为子目录名,\r\n * 显式传 '' 则直接写在 logs 根下。如 'weixinapi' -> logs/weixinapi/\r\n * @param {string} [options.level='info'] 日志级别:error | warn | info | debug\r\n * @param {function} [options.format] 自定义日志格式(printf 函数),默认 [时间] [级别] 消息\r\n * @param {boolean} [options.console=true] 是否输出到控制台\r\n * @param {boolean} [options.file=true] 是否输出到文件\r\n * @param {string} [options.datePattern='YYYY-MM-DD'] 日志文件名日期格式\r\n * @param {string} [options.maxSize='20m'] 单个日志文件大小上限,超过即滚动,如 '20m' | '100k'\r\n * @param {string|number} [options.maxFiles='30d'] 日志保留时长/份数,如 '30d' | 14\r\n * @param {boolean|string[]} [options.split=false]\r\n * false:不拆分,全部写到 <name>-%DATE%.log\r\n * true:按 debug/info/warn/error 各写一个文件\r\n * 数组:按传入级别拆分,如 ['info', 'warn', 'error']\r\n * @returns {import('winston').Logger}\r\n */\r\nexport function createLogger(options = {}) {\r\n const {\r\n name = 'app',\r\n dirname,\r\n level = 'info',\r\n format = defaultLogFormat,\r\n console = true,\r\n file = true,\r\n datePattern = 'YYYY-MM-DD',\r\n maxSize = '10m',\r\n maxFiles = '10d',\r\n split = false\r\n } = options\r\n\r\n // 目录解析:设置 LOG_DIR 环境变量即自动以其为日志根目录,否则以 logs 为根目录\r\n // dirname 为其下子目录;不传 dirname 时自动用 name 作为子目录;显式传 '' 则直接写根\r\n const subDir = dirname ?? name\r\n const root = process.env.LOG_DIR ? path.join(process.env.LOG_DIR, 'logs') : 'logs'\r\n const logDir = path.join(root, subDir)\r\n\r\n /**\r\n * 内部:创建文件滚动 transport\r\n * @param {string} filename\r\n * @param {string} [fileLevel] 指定级别时配合 levelFilter 精确过滤,仅写该级别日志\r\n */\r\n const createFileTransport = (filename, fileLevel) => {\r\n const formatParts = [\r\n timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format\r\n ]\r\n if (fileLevel) formatParts.unshift(levelFilter(fileLevel))\r\n\r\n return new winston.transports.DailyRotateFile({\r\n dirname: logDir,\r\n filename,\r\n ...(fileLevel ? { level: fileLevel } : {}),\r\n datePattern,\r\n maxSize,\r\n maxFiles,\r\n format: combine(...formatParts)\r\n })\r\n }\r\n\r\n const transports = []\r\n\r\n if (console) {\r\n transports.push(new winston.transports.Console())\r\n }\r\n\r\n if (file) {\r\n const splitLevels = Array.isArray(split)\r\n ? split\r\n : (split ? defaultSplitLevels : null)\r\n\r\n if (splitLevels) {\r\n for (const splitLevel of splitLevels) {\r\n transports.push(createFileTransport(`${name}-${splitLevel}-%DATE%.log`, splitLevel))\r\n }\r\n } else {\r\n transports.push(createFileTransport(`${name}-%DATE%.log`))\r\n }\r\n }\r\n\r\n return winston.createLogger({\r\n level,\r\n format: combine(\r\n timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format\r\n ),\r\n transports\r\n })\r\n}\r\n\r\nexport default createLogger\r\n","import crypto from 'node:crypto'\r\n\r\nconst ALGORITHM_MAP = {\r\n 16: 'aes-128-ecb',\r\n 24: 'aes-192-ecb',\r\n 32: 'aes-256-ecb'\r\n}\r\n\r\nconst encrypt = (data, key) => {\r\n // key 必须 16 / 24 / 32 字节\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const cipher = crypto.createCipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n cipher.setAutoPadding(true) // PKCS7\r\n const encrypted = Buffer.concat([\r\n cipher.update(data),\r\n cipher.final()\r\n ])\r\n return encrypted\r\n}\r\n\r\nconst decrypt = (data, key) => {\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const decipher = crypto.createDecipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n decipher.setAutoPadding(true)\r\n const decrypted = Buffer.concat([\r\n decipher.update(data),\r\n decipher.final()\r\n ])\r\n return decrypted\r\n}\r\n\r\n/**\r\n * AES解密\r\n * 对应 Java:\r\n * AesUtil.decrypt(String data, String key)\r\n *\r\n * @param {string} data Base64密文\r\n * @param {string} key AES密钥(16/24/32字节)\r\n * @returns {string} 明文\r\n */\r\nconst decryptString = (data, key) => {\r\n const keyBuf = Buffer.from(key, 'utf8')\r\n const decipher = crypto.createDecipheriv(ALGORITHM_MAP[keyBuf.length], keyBuf, null)\r\n decipher.setAutoPadding(true)\r\n const decrypted = Buffer.concat([\r\n decipher.update(Buffer.from(data, 'base64')),\r\n decipher.final()\r\n ])\r\n return decrypted.toString('utf8')\r\n}\r\n\r\nexport default { encrypt, decrypt, decryptString }","import knex from 'knex'\r\nimport aes from './aesUtil.js'\r\n\r\n/** 解析 key=value;key=value 形式的连接串 */\r\nconst parseConnectionString = (str) =>\r\n str.split(';').reduce((acc, param) => {\r\n const idx = param.indexOf('=')\r\n if (idx === -1) return acc\r\n const key = param.slice(0, idx).trim()\r\n const value = param.slice(idx + 1).trim()\r\n if (key) acc[key] = value\r\n return acc\r\n }, {})\r\n\r\n/** 配置了 DB_AES_KEY 时尝试解密 */\r\nconst resolveConnectionString = (connectionString) => {\r\n const aesKey = process.env.DB_AES_KEY\r\n if (aesKey) {\r\n try {\r\n return aes.decryptString(connectionString, aesKey)\r\n } catch {\r\n // 解密失败,认为是明文\r\n }\r\n }\r\n\r\n return connectionString\r\n}\r\n/**\r\n * 创建数据库实例\r\n */\r\nexport const useDatabase = async (connectionString = process.env.DB_CONNECTION_STRING) => {\r\n if (!connectionString)\r\n throw new Error('DB connection string required: pass it to init(str) or set DB_CONNECTION_STRING')\r\n\r\n // 当前实例重复初始化\r\n const params = parseConnectionString(resolveConnectionString(connectionString))\r\n const db = knex({\r\n client: 'mssql',\r\n connection: {\r\n user: params.user,\r\n password: params.password,\r\n server: params.server,\r\n database: params.database,\r\n options: {\r\n encrypt: false\r\n }\r\n }\r\n })\r\n\r\n await db.raw('SELECT 1')\r\n const close = async () => await db.destroy()\r\n\r\n return {\r\n db,\r\n close\r\n }\r\n}","\r\nlet registerError = null\r\nlet registerComplete = null\r\nlet registerLoader = null\r\n\r\n/** 每个钩子未注册时只提示一次,避免刷屏 */\r\nconst warnOnce = (() => {\r\n const warned = new Set()\r\n return (name) => {\r\n if (warned.has(name)) return\r\n warned.add(name)\r\n console.warn(\r\n `[bree-core] hooks.${name} 未注册,任务状态不会回写数据库。` +\r\n `可直接赋值 hooks.${name} = async (db, obj) => { /* 回写逻辑 */ } 注册。`\r\n )\r\n }\r\n})()\r\n\r\n// 默认空实现:不注册不崩溃,只提示一次\r\nregisterError = async () => warnOnce('registerError')\r\nregisterComplete = async () => warnOnce('registerComplete')\r\nregisterLoader = async () => {\r\n warnOnce('registerLoader')\r\n return []\r\n}\r\n\r\nexport default {\r\n registerLoader,\r\n registerError,\r\n registerComplete\r\n}\r\n","import Bree from 'bree'\r\nimport path from 'node:path'\r\nimport fs from 'node:fs'\r\nimport createLogger from '../config/createLogger.js'\r\nimport { useDatabase } from '../utils/databaseUtil.js'\r\nimport hooks from './hooks.js'\r\n\r\nlet bree = null\r\nlet jobsRoot = null\r\n\r\nconst logger = createLogger({ name: 'scheduler', split: true })\r\n\r\n// 让使用者通过环境变量或配置指定 jobs 目录\r\nconst getJobsRoot = () => {\r\n if (jobsRoot) return jobsRoot\r\n\r\n // 多种方式获取 jobs 目录\r\n // 1. 环境变量\r\n if (process.env.BREE_JOBS_PATH) {\r\n jobsRoot = path.resolve(process.env.BREE_JOBS_PATH)\r\n return jobsRoot\r\n }\r\n\r\n // 2. 使用当前工作目录(项目根目录)\r\n const cwd = process.cwd()\r\n const possiblePaths = [\r\n path.join(cwd, 'src/jobs'),\r\n path.join(cwd, 'jobs'),\r\n path.join(cwd, 'dist/jobs'),\r\n ]\r\n\r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n jobsRoot = p\r\n return jobsRoot\r\n }\r\n }\r\n\r\n // 3. 默认使用当前工作目录下的 src/jobs\r\n jobsRoot = path.join(cwd, 'src/jobs')\r\n console.warn(`Jobs directory not found, using default: ${jobsRoot}`)\r\n return jobsRoot\r\n}\r\n\r\nconst createBree = () => {\r\n const jobsPath = getJobsRoot()\r\n // 确保 jobs 目录存在(创建警告但不自动创建,因为这是使用者的责任)\r\n if (!fs.existsSync(jobsPath)) {\r\n console.warn(`⚠️ Jobs directory not found: ${jobsPath}`)\r\n console.warn(` Please create it or set BREE_JOBS_PATH environment variable`)\r\n }\r\n const getWorkerData = (name) => instance.config.jobs.find(a => a.name === name)?.worker?.workerData\r\n const instance = new Bree({\r\n hasSeconds: true,\r\n root: jobsPath,\r\n doRootCheck: false, // 任务列表由 hooks.registerLoader / 数据库提供,无需 root/index.js\r\n // bree 9.x 官方消息回调(替代已移除的 'worker message' 事件):\r\n // worker 发来的所有消息都进这里;发字符串 'done' 时 bree 会自动清理 worker(terminate + worker deleted)\r\n workerMessageHandler: async (workerMetadata) => {\r\n const name = workerMetadata?.name\r\n const message = workerMetadata?.message\r\n let close = null\r\n try {\r\n console.log(`[${name}] worker message:`, message)\r\n if (message?.type !== 'complete') return\r\n\r\n const workerData = getWorkerData(name)\r\n if (!workerData) return\r\n if (hooks.registerComplete === null || typeof hooks.registerComplete !== 'function') {\r\n logger.error('hooks.registerComplete is not a function')\r\n return\r\n }\r\n\r\n const database = await useDatabase()\r\n const db = database.db\r\n if (!db) {\r\n logger.error('Database initialization failed')\r\n return\r\n }\r\n\r\n close = database.close\r\n const sendData = { ...workerData, result: JSON.stringify(message?.data ?? {}) }\r\n await hooks.registerComplete(db, sendData)\r\n }\r\n catch (error) {\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n }\r\n finally {\r\n await close?.()\r\n }\r\n },\r\n errorHandler: async (error, workerMetadata) => {\r\n const name = workerMetadata?.name\r\n let close = null\r\n try {\r\n if (error?.message?.indexOf('exited with code') > -1) return\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n\r\n const workerData = getWorkerData(name)\r\n if (!workerData) return\r\n if (hooks.registerError === null || typeof hooks.registerError !== 'function') {\r\n logger.error('hooks.registerError is not a function')\r\n return\r\n }\r\n\r\n const database = await useDatabase()\r\n const db = database.db\r\n if (!db) {\r\n logger.error('Database initialization failed')\r\n return\r\n }\r\n\r\n close = database.close\r\n const sendData = {\r\n ...workerData,\r\n error: error?.stack ||\r\n error?.message\r\n }\r\n await hooks.registerError(db, sendData)\r\n }\r\n catch (error) {\r\n logger.error(`[${name}] ${error?.stack || error?.message || error}`)\r\n }\r\n finally {\r\n await close?.()\r\n }\r\n }\r\n })\r\n\r\n instance.on('worker created', (name) => {\r\n console.log(`[${name}] worker created`)\r\n logger.info(`[${name}] worker created`)\r\n })\r\n\r\n instance.on('worker deleted', async (name) => {\r\n console.log(`[${name}] worker deleted`)\r\n logger.info(`[${name}] worker deleted`)\r\n })\r\n\r\n return instance\r\n}\r\n\r\n// 统一返回结构:\r\n// 成功: { code: 0, message, data }\r\n// 失败: { code: -1, message }\r\nconst ok = (message, data = undefined) => ({ code: 0, message, data })\r\nconst fail = (message) => ({ code: -1, message })\r\nconst notInit = () => (bree ? null : fail('scheduler 未初始化,请先调用 scheduler.register()'))\r\nconst isExist = (name) => bree?.config?.jobs?.some(x => x.name === name)\r\n\r\n// 统一包装:未初始化检查 + 异常捕获,让每个方法只保留业务逻辑\r\nconst guard = (fn) => async (...args) => {\r\n const ni = notInit()\r\n if (ni) return ni\r\n\r\n try {\r\n return await fn(...args)\r\n }\r\n catch (e) {\r\n return fail(e?.message || String(e))\r\n }\r\n}\r\n\r\nconst getBree = () => bree\r\n\r\n// 创建任务(仅注册到调度器,不会自动执行)\r\nconst create = guard(async (job) => {\r\n const name = job?.name\r\n if (!name) return fail('job 必须包含 name')\r\n if (isExist(name)) return fail(`job \"${name}\" 已存在`)\r\n await bree.add(job)\r\n return ok(`job \"${name}\" 创建成功`, { name })\r\n})\r\n\r\n// 重置任务(移除后按新配置重新添加,可选立即启动)\r\nconst reset = guard(async (job, startStatus) => {\r\n const name = job?.name\r\n if (!name) return fail('job 必须包含 name')\r\n await remove(name)\r\n await bree.add(job)\r\n if (startStatus) await bree.start(name)\r\n return ok(`job \"${name}\" 已重置${startStatus ? '并启动' : ''}`, { name, startStatus })\r\n})\r\n\r\n// 移除任务(停止并删除)\r\nconst remove = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.stop(name)\r\n const index = bree.config.jobs.findIndex(x => x.name === name)\r\n if (index !== -1) bree.config.jobs.splice(index, 1)\r\n return ok(`job \"${name}\" 已移除`, { name })\r\n})\r\n\r\n// 启动任务\r\nconst start = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.start(name)\r\n return ok(`job \"${name}\" 已启动`, { name })\r\n})\r\n\r\n// 停止任务\r\nconst stop = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.stop(name)\r\n return ok(`job \"${name}\" 已停止`, { name })\r\n})\r\n\r\n// 执行一次任务(不按周期调度,立即跑一次)\r\nconst run = guard(async (name) => {\r\n if (!isExist(name)) return fail(`job \"${name}\" 不存在`)\r\n await bree.run(name)\r\n return ok(`job \"${name}\" 已触发执行`, { name })\r\n})\r\n\r\n// 任务初始化:初始化数据库、创建 Bree 实例并加载任务列表\r\nconst register = async () => {\r\n let close = null\r\n try {\r\n if (hooks.registerLoader === null || typeof hooks.registerLoader !== 'function')\r\n throw new Error('hooks.registerLoader is not a function')\r\n\r\n const database = await useDatabase()\r\n const db = database.db\r\n if (!db) throw new Error('Database initialization failed')\r\n\r\n close = database.close\r\n bree = createBree()\r\n if (!bree) throw new Error('Breejs initialization failed')\r\n\r\n await hooks.registerLoader(db, logger)\r\n const jobs = bree.config.jobs.map(x => ({ name: x.name, interval: x.interval }))\r\n return ok('scheduler 已注册', { jobs })\r\n }\r\n catch (error) {\r\n logger.error(`register=>${error?.stack || error?.message || error}`)\r\n }\r\n finally {\r\n await close?.()\r\n }\r\n}\r\n\r\nexport default {\r\n register,\r\n create,\r\n reset,\r\n start,\r\n stop,\r\n run,\r\n getBree,\r\n remove\r\n}","/**\r\n * 单函数接口风格路由(近似 `@Route('/path')` 装饰器,纯 JS 用函数包装实现)\r\n *\r\n * 用法(业务模块中定义即自动注册,无需手动传给 useServer):\r\n * route.post('/test', (body) => {\r\n * const { name, age } = body\r\n * return { code: 0, message: 'success', data: null } // 完整响应体原样返回\r\n * })\r\n * route.get('/user/:id', async ({ id }) => ({ id }))\r\n *\r\n * 分组前缀(减少重复路径):\r\n * const api = route.parentRoute('/task')\r\n * api.post('/upload', upload.single('file'), async (body, req) => {\r\n * // 注册为 POST /task/upload\r\n * if (!req.file) return { code: -1, message: '文件不能为空' }\r\n * return { code: 0, message: '上传成功', data: { filename: req.file.filename } }\r\n * })\r\n * api.get('/list', async () => []) // GET /task/list\r\n * api.parentRoute('/:id').get('/info', async ({ id }) => ({})) // 支持嵌套,GET /task/:id/info\r\n *\r\n * 支持中间件(Express 风格,如 multer 文件上传):\r\n * route.post('/upload', upload.single('file'), async (body, req, res) => {\r\n * // req.file 由 multer 解析后注入(body 不含文件,文件在 req.file)\r\n * return { code: 0, message: '上传成功', data: { filename: req.file.filename } }\r\n * })\r\n * route.post('/upload', [auth, upload.array('files', 5)], async (body, req, res) => { ... })\r\n *\r\n * handler 签名:async (body, req, res) => result\r\n * - body:自动合并 { params, query, body },解构即用\r\n * - req / res:原始对象(需要时可用 req.file、req.ip、res.setHeader 等)\r\n * - 返回 { code, ... } 对象时原样 res.json 输出;返回普通数据自动包装为 res.success\r\n * - 抛错自动进入全局错误处理\r\n *\r\n * 方法类型:route.get / route.post / route.put / route.delete / route.patch\r\n * 也可 route(path, handler, method),默认 POST\r\n */\r\n\r\n/** 自动注册路由注册表(模块加载时定义即注册,useServer 启动时自动收集) */\r\nconst registeredRoutes = []\r\n\r\nconst register = (route) => {\r\n const idx = registeredRoutes.findIndex((r) => r.method === route.method && r.path === route.path)\r\n if (idx >= 0) registeredRoutes[idx] = route\r\n else registeredRoutes.push(route)\r\n return route\r\n}\r\n\r\n/** 获取所有已注册路由(内部使用,供 useServer 启动时收集) */\r\nexport const getRegisteredRoutes = () => [...registeredRoutes]\r\n\r\n/** 拼接路径:joinPath('/task', '/upload') => '/task/upload';joinPath('/task', '') => '/task' */\r\nconst joinPath = (prefix, path) => {\r\n const p = String(prefix ?? '').replace(/\\/+$/, '')\r\n const h = String(path ?? '').replace(/^\\/+/, '')\r\n return h ? `${p}/${h}` : p\r\n}\r\n\r\n/**\r\n * 解析参数:route(path, [middlewares...,] handler[, method])\r\n * 兼容:route(path, handler, method)\r\n */\r\nconst resolveArgs = (...args) => {\r\n let method = null\r\n // 末尾若为合法方法字符串,视为 method(兼容 route(path, handler, method))\r\n if (typeof args[args.length - 1] === 'string' && ['get', 'post', 'put', 'delete', 'patch'].includes(args[args.length - 1].toLowerCase())) {\r\n method = args.pop()\r\n }\r\n const handler = args.pop()\r\n // 中间件:单个函数或数组(数组展开),handler 之前的参数\r\n const middlewares = Array.isArray(args[0]) ? args[0] : args\r\n return { middlewares, handler, method }\r\n}\r\n\r\nconst createRoute = (path, middlewares, handler, method) => {\r\n const item = {\r\n method,\r\n path,\r\n handler: async (req, res, next) => {\r\n try {\r\n // 先执行引用者中间件(Express 风格 (req, res, next),如 multer 的 upload.single('file'))\r\n for (const mw of middlewares) {\r\n await new Promise((resolve, reject) => {\r\n mw(req, res, (err) => (err ? reject(err) : resolve()))\r\n })\r\n }\r\n const body = { ...req.params, ...req.query, ...req.body }\r\n const result = await handler(body, req, res)\r\n if (!res.headersSent) {\r\n if (result && typeof result === 'object' && 'code' in result) {\r\n res.json(result)\r\n } else {\r\n res.success(result === undefined ? null : result)\r\n }\r\n }\r\n } catch (err) {\r\n next(err)\r\n }\r\n }\r\n }\r\n return register(item)\r\n}\r\n\r\n/**\r\n * 定义并自动注册一个路由\r\n * @param {string} path 路由路径,如 '/test'\r\n * @param {function|function[]} handlerOrMws 处理函数 async (body, req, res) => result;\r\n * 也可先传中间件(单个或数组,如 multer 的 upload.single('file')),最后一个参数为处理函数\r\n * @param {string} [method='post'] HTTP 方法:get | post | put | delete | patch\r\n * @returns {{method:string,path:string,handler:function}} 路由配置\r\n */\r\nconst route = (path, ...args) => {\r\n const { middlewares, handler, method } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, method || 'post')\r\n}\r\n\r\n// 方法类型便捷写法(IDE 自动补全友好)\r\nroute.get = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'get')\r\n}\r\nroute.post = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'post')\r\n}\r\nroute.put = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'put')\r\n}\r\nroute.delete = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'delete')\r\n}\r\nroute.patch = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(path, middlewares, handler, 'patch')\r\n}\r\n\r\n/**\r\n * 分组前缀路由:返回带 get/post/put/delete/patch 的子路由,路径自动拼接前缀\r\n * 用法:\r\n * const api = route.parentRoute('/task')\r\n * api.post('/upload', upload.single('file'), handler) // POST /task/upload\r\n * api.get('/list', handler) // GET /task/list\r\n * api.parentRoute('/:id').get('/info', handler) // 支持嵌套,GET /task/:id/info\r\n * @param {string} [prefix=''] 路径前缀,如 '/task'\r\n * @returns {{get:function,post:function,put:function,delete:function,patch:function,parentRoute:function}}\r\n */\r\nroute.parentRoute = (prefix = '') => {\r\n const api = {}\r\n for (const method of ['get', 'post', 'put', 'delete', 'patch']) {\r\n api[method] = (path, ...args) => {\r\n const { middlewares, handler } = resolveArgs(...args)\r\n return createRoute(joinPath(prefix, path), middlewares, handler, method)\r\n }\r\n }\r\n // 嵌套分组:api.parentRoute('/:id').get(...)\r\n api.parentRoute = (sub = '') => route.parentRoute(joinPath(prefix, sub))\r\n return api\r\n}\r\n\r\nexport default route\r\n","import aes from \"../utils/aesUtil.js\"\r\n\r\nconst getClientIp = (req) => {\r\n return req.headers['x-forwarded-for']?.split(',')[0]?.trim()\r\n || req.headers['x-real-ip']\r\n || req.ip\r\n || req.connection.remoteAddress\r\n}\r\n\r\nexport function auth(req, res, next) {\r\n const headerName = process.env.API_SECRET_KEY_NAME.toLowerCase()\r\n const apiKey = req.headers[headerName]\r\n if (!apiKey) {\r\n return res.status(200).json({\r\n code: -1,\r\n message: 'Missing API Key'\r\n })\r\n }\r\n\r\n const decryptedApiKey = aes.decryptString(apiKey, process.env.API_SECRET_KEY)\r\n if (!decryptedApiKey || decryptedApiKey !== process.env.API_TOKEN) {\r\n return res.status(200).json({\r\n code: -1,\r\n message: 'Unauthorized'\r\n })\r\n }\r\n\r\n const ip = getClientIp(req)\r\n const allowIps = process.env.ALLOW_IPS?.split(',') || []\r\n if (!allowIps.includes(ip)) {\r\n return res.status(200)\r\n .json({\r\n code: -1,\r\n message: 'IP forbidden'\r\n })\r\n }\r\n\r\n next()\r\n}","import express from 'express'\r\nimport { readdir } from 'fs/promises'\r\nimport path from 'path'\r\nimport { pathToFileURL } from 'url'\r\nimport { createLogger } from '../config/createLogger.js'\r\nimport { auth } from './auth.js'\r\nimport { getRegisteredRoutes } from './route.js'\r\n\r\n/**\r\n * 递归扫描目录下所有 JS 文件并动态加载(触发 route() 自动注册)\r\n * 跳过以 . / _ 开头的文件(如 .DS_Store、_private.js)\r\n */\r\nconst loadRouteFiles = async (dirs, logger) => {\r\n const list = Array.isArray(dirs) ? dirs : [dirs]\r\n let total = 0\r\n\r\n for (const dir of list) {\r\n const abs = path.resolve(dir)\r\n let entries\r\n try {\r\n entries = await readdir(abs, { withFileTypes: true })\r\n } catch {\r\n // 目录不存在则跳过,但给出提示便于诊断路由未加载\r\n logger?.warn?.(`routes dir not found, skipped: ${abs}`)\r\n continue\r\n }\r\n\r\n const walk = async (items, base) => {\r\n for (const item of items) {\r\n if (item.name.startsWith('.') || item.name.startsWith('_')) continue\r\n const full = path.join(base, item.name)\r\n if (item.isDirectory()) {\r\n await walk(await readdir(full, { withFileTypes: true }), full)\r\n } else if (/\\.(mjs|cjs|js)$/i.test(item.name)) {\r\n try {\r\n await import(pathToFileURL(full).href)\r\n total += 1\r\n } catch (err) {\r\n logger?.error?.(`load routes file failed: ${full} - ${err?.message || err}`)\r\n }\r\n }\r\n }\r\n }\r\n await walk(entries, abs)\r\n }\r\n\r\n if (total > 0) logger?.info?.(`auto-loaded ${total} routes file(s)`)\r\n}\r\n\r\n/**\r\n * CORS 中间件(不引入额外依赖)\r\n */\r\nconst createCors = (options = {}) => {\r\n const opts = typeof options === 'string' ? { origin: options } : options\r\n const origin = opts.origin ?? '*'\r\n const methods = opts.methods || 'GET,POST,PUT,DELETE,PATCH,OPTIONS'\r\n const headers = opts.headers || 'Content-Type,Authorization,x-api-key'\r\n\r\n return (req, res, next) => {\r\n res.setHeader('Access-Control-Allow-Origin', origin)\r\n res.setHeader('Access-Control-Allow-Methods', methods)\r\n res.setHeader('Access-Control-Allow-Headers', headers)\r\n if (req.method === 'OPTIONS') return res.sendStatus(204)\r\n next()\r\n }\r\n}\r\n\r\n/**\r\n * Express 服务封装\r\n * @param {object} options\r\n * @param {number} [options.port=3000] 监听端口\r\n * @param {string} [options.host='0.0.0.0'] 监听地址\r\n * @param {object} [options.logger] 自定义 logger(默认 createLogger({ name: 'server', split: true }))\r\n * @param {string} [options.jsonLimit='10mb'] JSON body 大小限制\r\n * @param {string} [options.urlencodedLimit='10mb'] urlencoded body 大小限制\r\n * @param {boolean|string|object} [options.cors=true] 是否启用 CORS;可传 origin 字符串或 { origin, methods, headers }\r\n * @param {string|string[]} [options.staticDir=null] 静态资源目录(可传数组),相对 cwd 或绝对路径\r\n * @param {boolean|function|function[]} [options.auth=false] 认证中间件:\r\n * true 使用内置 auth(依赖 API_SECRET_KEY/API_TOKEN/ALLOW_IPS 环境变量);\r\n * 传函数或函数数组则使用外部自定义中间件(如 (req, res, next) => {...});false 不启用\r\n * @param {boolean} [options.health=true] 是否启用 GET /health 健康检查\r\n * @param {boolean} [options.trustProxy=true] 是否信任代理(影响 req.ip)\r\n * @param {function|Array<{method:string,path:string,handler:function|function[]}>} [options.routes=null]\r\n * 路由注册:函数 (app) => {...} 或路由配置数组;也可省略,用 route() 定义即自动注册\r\n * @param {string|string[]|false} [options.routesDir=['routes','src/routes']] 路由文件目录(相对 cwd 或绝对路径),\r\n * start() 时自动递归扫描并加载其中所有 JS 文件(触发 route() 自动注册),无需手动 import;\r\n * 默认同时扫描 'routes' 与 'src/routes' 两个候选目录(存在哪个扫哪个);\r\n * 传 false 关闭扫描;传数组可自定义多个目录\r\n * @returns {{ app, start, stop, getServer }}\r\n */\r\nexport function useServer(options = {}) {\r\n const {\r\n port = 3000,\r\n host = '0.0.0.0',\r\n logger = createLogger({ name: 'server', split: true }),\r\n jsonLimit = '10mb',\r\n urlencodedLimit = '10mb',\r\n cors = true,\r\n staticDir = null,\r\n auth: enableAuth = false,\r\n health = true,\r\n trustProxy = true,\r\n routes = null,\r\n routesDir = ['routes', 'src/routes']\r\n } = options\r\n\r\n const app = express()\r\n\r\n if (trustProxy) app.set('trust proxy', true)\r\n\r\n // body 解析\r\n app.use(express.json({ limit: jsonLimit }))\r\n app.use(express.urlencoded({ extended: true, limit: urlencodedLimit }))\r\n\r\n // 请求日志(含耗时/状态码/IP)\r\n app.use((req, res, next) => {\r\n const start = Date.now()\r\n res.on('finish', () => {\r\n const duration = Date.now() - start\r\n logger.info(`${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms ${req.ip || ''}`)\r\n })\r\n next()\r\n })\r\n\r\n // CORS\r\n if (cors) app.use(createCors(cors))\r\n\r\n // 统一响应格式 res.success / res.fail\r\n app.use((req, res, next) => {\r\n res.success = (data = null, message = 'ok') => {\r\n res.json({ code: 0, message, data })\r\n }\r\n res.fail = (message = 'error', code = -1) => {\r\n res.json({ code, message, data: null })\r\n }\r\n next()\r\n })\r\n\r\n // 静态资源\r\n if (staticDir) {\r\n const dirs = Array.isArray(staticDir) ? staticDir : [staticDir]\r\n for (const dir of dirs) {\r\n app.use(express.static(dir))\r\n }\r\n }\r\n\r\n // 认证(true 用内置 auth;函数/数组用外部自定义中间件)\r\n if (enableAuth) {\r\n if (typeof enableAuth === 'function') {\r\n app.use(enableAuth)\r\n } else if (Array.isArray(enableAuth)) {\r\n app.use(...enableAuth)\r\n } else {\r\n app.use(auth)\r\n }\r\n }\r\n\r\n // 健康检查\r\n if (health) {\r\n app.get('/health', (req, res) => {\r\n res.success({ status: 'ok', uptime: process.uptime() })\r\n })\r\n }\r\n\r\n // 路由注册 + 404 + 错误处理\r\n // 需在 routesDir 扫描加载(触发 route() 自动注册)之后执行,故封装为函数由 start() 调用\r\n const setupRoutes = () => {\r\n // 业务路由(routes 为函数时保留原逻辑:完全自控注册顺序)\r\n if (typeof routes === 'function') {\r\n routes(app)\r\n }\r\n\r\n // 路由配置:手动传入的 routes + route() 自动注册的路由\r\n // 定义即自动注册,无需在 app.js 中重复传递\r\n const allRoutes = [\r\n ...(Array.isArray(routes) ? routes : []),\r\n ...getRegisteredRoutes()\r\n ]\r\n\r\n // 静态路径优先注册,避免被动态参数路由(如 /:id)吞掉\r\n allRoutes.sort((a, b) => {\r\n const dynamic = (r) => (r.path || '').split('/').filter((s) => s.startsWith(':')).length\r\n return dynamic(a) - dynamic(b)\r\n })\r\n\r\n for (const route of allRoutes) {\r\n const { method, path: routePath, handler } = route\r\n const fn = app[method?.toLowerCase()]\r\n if (typeof fn === 'function' && routePath && handler) {\r\n fn.call(app, routePath, handler)\r\n }\r\n }\r\n\r\n // 404\r\n app.use((req, res) => {\r\n res.status(404).fail('Not Found', 404)\r\n })\r\n\r\n // 全局错误处理(express 5 自动捕获 async 异常)\r\n app.use((err, req, res, next) => {\r\n logger.error(`${req.method} ${req.originalUrl} - ${err?.stack || err?.message || err}`)\r\n if (res.headersSent) return next(err)\r\n\r\n const status = err?.status || err?.statusCode || 500\r\n res.status(status).fail(err?.message || 'Internal Server Error', status)\r\n })\r\n }\r\n\r\n // 启动/停止控制\r\n let server = null\r\n\r\n const start = async () => {\r\n // 自动扫描加载路由文件(触发 route() 自动注册)\r\n if (routesDir) await loadRouteFiles(routesDir, logger)\r\n\r\n // 路由注册 + 404 + 错误处理(在扫描之后执行)\r\n setupRoutes()\r\n\r\n return new Promise((resolve, reject) => {\r\n server = app.listen(port, host, () => {\r\n logger.info(`Server listening on http://${host}:${port}`)\r\n resolve(server)\r\n })\r\n server.on('error', (err) => {\r\n logger.error(`Server error: ${err?.message}`)\r\n reject(err)\r\n })\r\n })\r\n }\r\n\r\n const stop = () => {\r\n return new Promise((resolve) => {\r\n if (!server) return resolve()\r\n server.close(() => resolve())\r\n })\r\n }\r\n\r\n return {\r\n app,\r\n start,\r\n stop,\r\n getServer: () => server\r\n }\r\n}\r\n","import { parentPort, workerData } from 'node:worker_threads'\r\nimport createLogger from '../config/createLogger.js'\r\nimport redis from '../utils/redisUtil.js'\r\nimport { useDatabase } from '../utils/databaseUtil.js'\r\n\r\nexport function useHandler() {\r\n let isCancelled = false\r\n const logger = createLogger({ name: 'worker' })\r\n\r\n if (parentPort)\r\n parentPort.once('message', (message) => {\r\n if (message !== 'cancel') return\r\n\r\n isCancelled = true\r\n if (parentPort) parentPort.postMessage('cancelled')\r\n else process.exit(0)\r\n })\r\n\r\n const getIsCancelled = () => isCancelled\r\n const run = async (worker) => {\r\n if (typeof worker !== 'function') {\r\n logger.error(`run worker is not a function`)\r\n return\r\n }\r\n\r\n let close = null\r\n try {\r\n const database = await useDatabase()\r\n const db = database.db\r\n close = database.close\r\n const result = await worker({ logger, redis, db, workerData })\r\n if (parentPort) parentPort.postMessage({ type: 'complete', data: result })\r\n }\r\n catch (error) {\r\n logger.error(`worker=>${error?.stack || error?.message || error}`)\r\n }\r\n finally {\r\n try {\r\n await close?.()\r\n } catch (error) {\r\n logger.error(`database close=>${error?.stack || error?.message || error}`)\r\n }\r\n if (parentPort) parentPort.postMessage('done')\r\n else process.exit(0)\r\n }\r\n }\r\n\r\n return { run, getIsCancelled }\r\n}\r\n"],"names":["fs","register","path"],"mappings":";;;;;;;;;;;;;;;;;AAIA,IAAI,UAAU,GAAG,KAAI;AACrB;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,KAAK;AAChD,IAAI,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAC;AACjD,IAAI,KAAK,CAAC,OAAO,GAAG,QAAO;AAC3B,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAQ,KAAK,CAAC,MAAM,CAAC,IAAI,EAAC;AAC1B,IAAI,CAAC;AACL,IAAI,OAAO,KAAK;AAChB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,OAAO,QAAQ,KAAK;AACxC,IAAI,MAAM,OAAO,GAAG,UAAU;AAC9B,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;AACjD,UAAU,OAAO,CAAC,GAAG,GAAE;AACvB;AACA,IAAI,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAC;AAChD;AACA,IAAI,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AAC3C,UAAU,QAAQ;AAClB,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAC;AAC5B;AACA,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;AACnC,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,MAAM,SAAS,GAAG,CAAC,MAAM,KAAK;AAC9B,IAAI,UAAU,GAAG,OAAM;AACvB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,OAAO,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,KAAK;AAClE,IAAI,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,GAAE;AAC3C,IAAI,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAC;AACvC,IAAI,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAC;AAChD,IAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAC;AAC3C,IAAI,OAAO,QAAQ;AACnB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,MAAM,iBAAiB,GAAG,OAAO,OAAO,EAAE,IAAI,KAAK;AACnD,IAAI,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,GAAE;AAC3C,IAAI,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAC;AACvC,IAAI,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE;AAC5C,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,IAAI,cAAc,GAAG,KAAI;AACzB,IAAI,WAAW,GAAG,KAAI;AACtB,MAAM,iBAAiB,GAAG,OAAO,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,SAAS,GAAG,KAAK,KAAK;AAC3F,IAAI,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAC;AAChD,IAAI,IAAI,CAAC,cAAc,EAAE;AACzB,QAAQ,cAAc,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;AAChE,YAAY,QAAQ,EAAE,QAAQ;AAC9B,YAAY,SAAS,EAAE,KAAK;AAC5B,YAAY,gBAAgB,EAAE,IAAI;AAClC,SAAS,EAAC;AACV;AACA,QAAQ,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAC;AACrD,QAAQ,WAAW,CAAC,OAAO,GAAG,QAAO;AACrC,IAAI,CAAC;AACL,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;AAC7B,QAAQ,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAE;AACzC,IAAI,CAAC;AACL;AACA,IAAI,IAAI,SAAS,EAAE;AACnB,QAAQ,MAAM,QAAQ,CAAC,MAAM,GAAE;AAC/B,QAAQ,cAAc,GAAG,KAAI;AAC7B,QAAQ,WAAW,GAAG,KAAI;AAC1B,IAAI,CAAC;AACL,IAAI,OAAO,QAAQ;AACnB,EAAC;AACD;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,OAAO;AAC3B,IAAI,IAAI,GAAG,MAAM;AACjB,IAAI,OAAO;AACX,IAAI,IAAI;AACR,IAAI,QAAQ,GAAG,QAAQ;AACvB,CAAC,KAAK;AACN,IAAI,QAAQ,IAAI;AAChB,QAAQ,KAAK,QAAQ;AACrB,YAAY,OAAO,MAAM,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC;AACzD,QAAQ,KAAK,QAAQ;AACrB,YAAY,OAAO,MAAM,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC;AACzE,QAAQ;AACR,YAAY,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC;AAC7D,KAAK;AACL,EAAC;AACD;AACA,gBAAe;AACf,IAAI,SAAS;AACb,IAAI,WAAW;AACf,IAAI,WAAW;AACf,IAAI,WAAW;AACf,IAAI,iBAAiB;AACrB,IAAI,iBAAiB;AACrB;;ACzHA,IAAI,WAAW,GAAG,KAAI;AACtB,IAAI,IAAI,GAAG,GAAE;AACb,MAAM,IAAI,GAAG,MAAM;AACnB,IAAI,IAAI,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAC;AACzE,IAAI,WAAW,GAAG,UAAU,CAAC,eAAe,CAAC;AAC7C,QAAQ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS;AACnC,QAAQ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;AAC3C,QAAQ,MAAM,EAAE,IAAI;AACpB,QAAQ,IAAI,EAAE;AACd,YAAY,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;AAC1C,YAAY,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;AAC3C,SAAS;AACT,KAAK,EAAC;AACN,EAAC;AACD;AACA,MAAM,IAAI,GAAG,OAAO,OAAO,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,KAAK;AACzF,IAAI,MAAM,WAAW,CAAC,QAAQ,CAAC;AAC/B,QAAQ,IAAI,EAAE,IAAI;AAClB,QAAQ,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAChE,QAAQ,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAClE,QAAQ,OAAO,EAAE,OAAO;AACxB,QAAQ,IAAI,EAAE,OAAO;AACrB,QAAQ,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI;AAC1C,YAAY,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAC;AAChD,YAAY,OAAO;AACnB,gBAAgB,IAAI,EAAE,IAAI;AAC1B,gBAAgB,QAAQ;AACxB,aAAa;AACb,QAAQ,CAAC,CAAC;AACV,KAAK,EAAC;AACN,EAAC;AACD;AACA,eAAe;AACf,IAAI,IAAI;AACR,IAAI,IAAI;AACR;;ACpCA,IAAI,MAAM,GAAG,KAAI;AAEjB;AACA,eAAe,iBAAiB,GAAG;AACnC,IAAI,MAAM,KAAK,GAAG,YAAY,CAAC;AAC/B,QAAQ,MAAM,EAAE;AAChB,YAAY,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;AACxC,YAAY,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAChD,YAAY,iBAAiB,CAAC,OAAO,EAAE;AACvC,gBAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAAC;AAClD;AACA;AACA,gBAAgB,IAAI,OAAO,GAAG,CAAC,EAAE;AACjC,oBAAoB,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC;AAClD,gBAAgB,CAAC;AACjB;AACA,gBAAgB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC;AACrD,YAAY,CAAC;AACb,SAAS;AACT,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS;AACzD,QAAQ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS;AACzD,QAAQ,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;AACnD,KAAK,EAAC;AACN;AACA,IAAI,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM;AAC9B,QAAQ,OAAO,CAAC,GAAG,CAAC,eAAe,EAAC;AACpC,IAAI,CAAC,EAAC;AACN;AACA,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM;AAE5B,QAAQ,OAAO,CAAC,GAAG,CAAC,WAAW,EAAC;AAChC,IAAI,CAAC,EAAC;AACN;AACA,IAAI,KAAK,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM;AACnC,QAAQ,OAAO,CAAC,GAAG,CAAC,cAAc,EAAC;AACnC,IAAI,CAAC,EAAC;AACN;AACA,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM;AAE1B,QAAQ,OAAO,CAAC,GAAG,CAAC,WAAW,EAAC;AAChC,IAAI,CAAC,EAAC;AACN;AACA,IAAI,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK;AAC/B,QAAQ,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,EAAC;AAC9C,IAAI,CAAC,EAAC;AACN;AACA,IAAI,MAAM,KAAK,CAAC,OAAO,GAAE;AACzB;AACA,IAAI,OAAO,KAAK;AAChB,CAAC;AACD;AACO,eAAe,QAAQ,GAAG;AACjC,IAAI,IAAI,CAAC,MAAM,EAAE;AACjB,QAAQ,MAAM,GAAG,MAAM,iBAAiB,GAAE;AAC1C,IAAI,CAAC;AACL;AACA,IAAI,OAAO,MAAM;AACjB,CAAC;AAKD;AACO,eAAe,UAAU,GAAG;AACnC,IAAI,IAAI,MAAM,EAAE;AAChB,QAAQ,MAAM,MAAM,CAAC,IAAI,GAAE;AAC3B,QAAQ,MAAM,GAAG,KAAI;AACrB,IAAI,CAAC;AACL;;ACrEA,MAAM,WAAW,CAAC;AAClB,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,EAAE;AAChD,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,MAAM,IAAI;AAClB,YAAY,OAAO,KAAK,KAAK,QAAQ;AACrC,kBAAkB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACvC,kBAAkB,MAAM,CAAC,KAAK,EAAC;AAC/B;AACA,QAAQ,IAAI,aAAa,EAAE;AAC3B,YAAY,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE;AAC9C,gBAAgB,EAAE,EAAE,aAAa;AACjC,aAAa,CAAC;AACd,QAAQ,CAAC;AACT;AACA,QAAQ,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;AACzC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACnB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAC;AAC1C;AACA,QAAQ,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI;AAC/B;AACA,QAAQ,IAAI;AACZ,YAAY,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AACpC,QAAQ,CAAC,CAAC,MAAM;AAChB,YAAY,OAAO,KAAK;AACxB,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACnB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AACnC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,MAAM,CAAC,GAAG,EAAE;AACtB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;AAC9C,IAAI,CAAC;AACL;AACA,IAAI,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE;AAC/B,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC;AAC/C,IAAI,CAAC;AACL;AACA,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACnB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AACnC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE;AACpB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;AACpC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE;AACpB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;AACpC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;AAClC,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,OAAO,MAAM,KAAK,CAAC,IAAI;AAC/B,YAAY,GAAG;AACf,YAAY,KAAK;AACjB,YAAY,OAAO,KAAK,KAAK,QAAQ;AACrC,kBAAkB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACvC,kBAAkB,MAAM,CAAC,KAAK,CAAC;AAC/B,SAAS;AACT,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE;AAC3B,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAC;AAClD;AACA,QAAQ,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI;AAC/B;AACA,QAAQ,IAAI;AACZ,YAAY,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AACpC,QAAQ,CAAC,CAAC,MAAM;AAChB,YAAY,OAAO,KAAK;AACxB,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE;AACvB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC,QAAQ,OAAO,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;AACvC,IAAI,CAAC;AACL;AACA,IAAI,MAAM,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE;AAC5B,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,OAAO,MAAM,KAAK,CAAC,KAAK;AAChC,YAAY,GAAG;AACf,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACjC,SAAS;AACT,IAAI,CAAC;AACL;AACA,IAAI,MAAM,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE;AAC5B,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,OAAO,MAAM,KAAK,CAAC,KAAK;AAChC,YAAY,GAAG;AACf,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACjC,SAAS;AACT,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE;AACpB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAC;AAC3C;AACA,QAAQ,OAAO,KAAK;AACpB,cAAc,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAC/B,cAAc,IAAI;AAClB,IAAI,CAAC;AACL;AACA,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE;AACpB,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,GAAE;AACtC;AACA,QAAQ,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAC;AAC3C;AACA,QAAQ,OAAO,KAAK;AACpB,cAAc,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAC/B,cAAc,IAAI;AAClB,IAAI,CAAC;AACL;AACA,IAAI,MAAM,KAAK,GAAG;AAClB,QAAQ,MAAM,UAAU,GAAE;AAC1B,IAAI,CAAC;AACL,CAAC;AACD;AACA,YAAe,IAAI,WAAW;;ACtI9B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAM;AACrD;AACA;AACA;AACA;AACA,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK;AACnE,IAAI,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC/D,CAAC,EAAC;AACF;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,CAAC,KAAK,KAAK;AAC/B,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK;AACpC,QAAQ,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,GAAG,IAAI,GAAG,KAAK;AAClD,IAAI,CAAC,CAAC,EAAE;AACR,EAAC;AACD;AACA;AACA;AACA;AACA,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY,CAAC,OAAO,GAAG,EAAE,EAAE;AAC3C,IAAI,MAAM;AACV,QAAQ,IAAI,GAAG,KAAK;AACpB,QAAQ,OAAO;AACf,QAAQ,KAAK,GAAG,MAAM;AACtB,QAAQ,MAAM,GAAG,gBAAgB;AACjC,QAAQ,OAAO,GAAG,IAAI;AACtB,QAAQ,IAAI,GAAG,IAAI;AACnB,QAAQ,WAAW,GAAG,YAAY;AAClC,QAAQ,OAAO,GAAG,KAAK;AACvB,QAAQ,QAAQ,GAAG,KAAK;AACxB,QAAQ,KAAK,GAAG,KAAK;AACrB,KAAK,GAAG,QAAO;AACf;AACA;AACA;AACA,IAAI,MAAM,MAAM,GAAG,OAAO,IAAI,KAAI;AAClC,IAAI,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,OAAM;AACtF,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,SAAS,KAAK;AACzD,QAAQ,MAAM,WAAW,GAAG;AAC5B,YAAY,SAAS,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;AACxD,YAAY,MAAM;AAClB,UAAS;AACT,QAAQ,IAAI,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,EAAC;AAClE;AACA,QAAQ,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC;AACtD,YAAY,OAAO,EAAE,MAAM;AAC3B,YAAY,QAAQ;AACpB,YAAY,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACtD,YAAY,WAAW;AACvB,YAAY,OAAO;AACnB,YAAY,QAAQ;AACpB,YAAY,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC;AAC3C,SAAS,CAAC;AACV,IAAI,EAAC;AACL;AACA,IAAI,MAAM,UAAU,GAAG,GAAE;AACzB;AACA,IAAI,IAAI,OAAO,EAAE;AACjB,QAAQ,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,EAAC;AACzD,IAAI,CAAC;AACL;AACA,IAAI,IAAI,IAAI,EAAE;AACd,QAAQ,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAChD,cAAc,KAAK;AACnB,eAAe,KAAK,GAAG,kBAAkB,GAAG,IAAI,EAAC;AACjD;AACA,QAAQ,IAAI,WAAW,EAAE;AACzB,YAAY,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;AAClD,gBAAgB,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,EAAC;AACpG,YAAY,CAAC;AACb,QAAQ,CAAC,MAAM;AACf,YAAY,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAC;AACtE,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA,IAAI,OAAO,OAAO,CAAC,YAAY,CAAC;AAChC,QAAQ,KAAK;AACb,QAAQ,MAAM,EAAE,OAAO;AACvB,YAAY,SAAS,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;AACxD,YAAY,MAAM;AAClB,SAAS;AACT,QAAQ,UAAU;AAClB,KAAK,CAAC;AACN;;ACnHA,MAAM,aAAa,GAAG;AACtB,IAAI,EAAE,EAAE,aAAa;AACrB,IAAI,EAAE,EAAE,aAAa;AACrB,IAAI,EAAE,EAAE,aAAa;AACrB,EAAC;AACD;AACA,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK;AAC/B;AACA,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAC;AAC3C,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAC;AACpF,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,EAAC;AAC/B,IAAI,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;AACpC,QAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;AAC3B,QAAQ,MAAM,CAAC,KAAK,EAAE;AACtB,KAAK,EAAC;AACN,IAAI,OAAO,SAAS;AACpB,EAAC;AACD;AACA,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK;AAC/B,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAC;AAC3C,IAAI,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAC;AACxF,IAAI,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAC;AACjC,IAAI,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;AACpC,QAAQ,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AAC7B,QAAQ,QAAQ,CAAC,KAAK,EAAE;AACxB,KAAK,EAAC;AACN,IAAI,OAAO,SAAS;AACpB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK;AACrC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAC;AAC3C,IAAI,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAC;AACxF,IAAI,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAC;AACjC,IAAI,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;AACpC,QAAQ,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACpD,QAAQ,QAAQ,CAAC,KAAK,EAAE;AACxB,KAAK,EAAC;AACN,IAAI,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;AACrC,EAAC;AACD;AACA,UAAe,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa;;AChDhD;AACA,MAAM,qBAAqB,GAAG,CAAC,GAAG;AAClC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK;AAC1C,QAAQ,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAC;AACtC,QAAQ,IAAI,GAAG,KAAK,EAAE,EAAE,OAAO,GAAG;AAClC,QAAQ,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,GAAE;AAC9C,QAAQ,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAE;AACjD,QAAQ,IAAI,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,MAAK;AACjC,QAAQ,OAAO,GAAG;AAClB,IAAI,CAAC,EAAE,EAAE,EAAC;AACV;AACA;AACA,MAAM,uBAAuB,GAAG,CAAC,gBAAgB,KAAK;AACtD,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAU;AACzC,IAAI,IAAI,MAAM,EAAE;AAChB,QAAQ,IAAI;AACZ,YAAY,OAAO,GAAG,CAAC,aAAa,CAAC,gBAAgB,EAAE,MAAM,CAAC;AAC9D,QAAQ,CAAC,CAAC,MAAM;AAChB;AACA,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA,IAAI,OAAO,gBAAgB;AAC3B,EAAC;AACD;AACA;AACA;AACY,MAAC,WAAW,GAAG,OAAO,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK;AAC1F,IAAI,IAAI,CAAC,gBAAgB;AACzB,QAAQ,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC;AAC1G;AACA;AACA,IAAI,MAAM,MAAM,GAAG,qBAAqB,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,EAAC;AACnF,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC;AACpB,QAAQ,MAAM,EAAE,OAAO;AACvB,QAAQ,UAAU,EAAE;AACpB,YAAY,IAAI,EAAE,MAAM,CAAC,IAAI;AAC7B,YAAY,QAAQ,EAAE,MAAM,CAAC,QAAQ;AACrC,YAAY,MAAM,EAAE,MAAM,CAAC,MAAM;AACjC,YAAY,QAAQ,EAAE,MAAM,CAAC,QAAQ;AACrC,YAAY,OAAO,EAAE;AACrB,gBAAgB,OAAO,EAAE,KAAK;AAC9B,aAAa;AACb,SAAS;AACT,KAAK,EAAC;AACN;AACA,IAAI,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,EAAC;AAC5B,IAAI,MAAM,KAAK,GAAG,YAAY,MAAM,EAAE,CAAC,OAAO,GAAE;AAChD;AACA,IAAI,OAAO;AACX,QAAQ,EAAE;AACV,QAAQ,KAAK;AACb,KAAK;AACL;;ACvDA,IAAI,aAAa,GAAG,KAAI;AACxB,IAAI,gBAAgB,GAAG,KAAI;AAC3B,IAAI,cAAc,GAAG,KAAI;AACzB;AACA;AACA,MAAM,QAAQ,GAAG,CAAC,MAAM;AACxB,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG,GAAE;AAC5B,IAAI,OAAO,CAAC,IAAI,KAAK;AACrB,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM;AACpC,QAAQ,MAAM,CAAC,GAAG,CAAC,IAAI,EAAC;AACxB,QAAQ,OAAO,CAAC,IAAI;AACpB,YAAY,CAAC,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,CAAC;AACxD,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,wCAAwC,CAAC;AACzE,UAAS;AACT,IAAI,CAAC;AACL,CAAC,IAAG;AACJ;AACA;AACA,aAAa,GAAG,YAAY,QAAQ,CAAC,eAAe,EAAC;AACrD,gBAAgB,GAAG,YAAY,QAAQ,CAAC,kBAAkB,EAAC;AAC3D,cAAc,GAAG,YAAY;AAC7B,IAAI,QAAQ,CAAC,gBAAgB,EAAC;AAC9B,IAAI,OAAO,EAAE;AACb,EAAC;AACD;AACA,YAAe;AACf,IAAI,cAAc;AAClB,IAAI,aAAa;AACjB,IAAI,gBAAgB;AACpB;;ACvBA,IAAI,IAAI,GAAG,KAAI;AACf,IAAI,QAAQ,GAAG,KAAI;AACnB;AACA,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAC;AAC/D;AACA;AACA,MAAM,WAAW,GAAG,MAAM;AAC1B,IAAI,IAAI,QAAQ,EAAE,OAAO,QAAQ;AACjC;AACA;AACA;AACA,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;AACpC,QAAQ,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAC;AAC3D,QAAQ,OAAO,QAAQ;AACvB,IAAI,CAAC;AACL;AACA;AACA,IAAI,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,GAAE;AAC7B,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC;AAClC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;AAC9B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC;AACnC,MAAK;AACL;AACA,IAAI,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE;AACnC,QAAQ,IAAIA,IAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;AAC9B,YAAY,QAAQ,GAAG,EAAC;AACxB,YAAY,OAAO,QAAQ;AAC3B,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA;AACA,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAC;AACzC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,yCAAyC,EAAE,QAAQ,CAAC,CAAC,EAAC;AACxE,IAAI,OAAO,QAAQ;AACnB,EAAC;AACD;AACA,MAAM,UAAU,GAAG,MAAM;AACzB,IAAI,MAAM,QAAQ,GAAG,WAAW,GAAE;AAClC;AACA,IAAI,IAAI,CAACA,IAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;AAClC,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC,EAAC;AACjE,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,8DAA8D,CAAC,EAAC;AACtF,IAAI,CAAC;AACL,IAAI,MAAM,aAAa,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,WAAU;AACvG,IAAI,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC;AAC9B,QAAQ,UAAU,EAAE,IAAI;AACxB,QAAQ,IAAI,EAAE,QAAQ;AACtB,QAAQ,WAAW,EAAE,KAAK;AAC1B;AACA;AACA,QAAQ,oBAAoB,EAAE,OAAO,cAAc,KAAK;AACxD,YAAY,MAAM,IAAI,GAAG,cAAc,EAAE,KAAI;AAC7C,YAAY,MAAM,OAAO,GAAG,cAAc,EAAE,QAAO;AACnD,YAAY,IAAI,KAAK,GAAG,KAAI;AAC5B,YAAY,IAAI;AAChB,gBAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAC;AACjE,gBAAgB,IAAI,OAAO,EAAE,IAAI,KAAK,UAAU,EAAE,MAAM;AACxD;AACA,gBAAgB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAC;AACtD,gBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM;AACvC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,UAAU,EAAE;AACrG,oBAAoB,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAC;AAC5E,oBAAoB,MAAM;AAC1B,gBAAgB,CAAC;AACjB;AACA,gBAAgB,MAAM,QAAQ,GAAG,MAAM,WAAW,GAAE;AACpD,gBAAgB,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAE;AACtC,gBAAgB,IAAI,CAAC,EAAE,EAAE;AACzB,oBAAoB,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAC;AAClE,oBAAoB,MAAM;AAC1B,gBAAgB,CAAC;AACjB;AACA,gBAAgB,KAAK,GAAG,QAAQ,CAAC,MAAK;AACtC,gBAAgB,MAAM,QAAQ,GAAG,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,GAAE;AAC/F,gBAAgB,MAAM,KAAK,CAAC,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAC;AAC1D,YAAY,CAAC;AACb,YAAY,OAAO,KAAK,EAAE;AAC1B,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AACpF,YAAY,CAAC;AACb,oBAAoB;AACpB,gBAAgB,MAAM,KAAK,KAAI;AAC/B,YAAY,CAAC;AACb,QAAQ,CAAC;AACT,QAAQ,YAAY,EAAE,OAAO,KAAK,EAAE,cAAc,KAAK;AACvD,YAAY,MAAM,IAAI,GAAG,cAAc,EAAE,KAAI;AAC7C,YAAY,IAAI,KAAK,GAAG,KAAI;AAC5B,YAAY,IAAI;AAChB,gBAAgB,IAAI,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM;AAC5E,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AACpF;AACA,gBAAgB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAC;AACtD,gBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM;AACvC,gBAAgB,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,UAAU,EAAE;AAC/F,oBAAoB,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAC;AACzE,oBAAoB,MAAM;AAC1B,gBAAgB,CAAC;AACjB;AACA,gBAAgB,MAAM,QAAQ,GAAG,MAAM,WAAW,GAAE;AACpD,gBAAgB,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAE;AACtC,gBAAgB,IAAI,CAAC,EAAE,EAAE;AACzB,oBAAoB,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAC;AAClE,oBAAoB,MAAM;AAC1B,gBAAgB,CAAC;AACjB;AACA,gBAAgB,KAAK,GAAG,QAAQ,CAAC,MAAK;AACtC,gBAAgB,MAAM,QAAQ,GAAG;AACjC,oBAAoB,GAAG,UAAU;AACjC,oBAAoB,KAAK,EAAE,KAAK,EAAE,KAAK;AACvC,wBAAwB,KAAK,EAAE,OAAO;AACtC,kBAAiB;AACjB,gBAAgB,MAAM,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAC;AACvD,YAAY,CAAC;AACb,YAAY,OAAO,KAAK,EAAE;AAC1B,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AACpF,YAAY,CAAC;AACb,oBAAoB;AACpB,gBAAgB,MAAM,KAAK,KAAI;AAC/B,YAAY,CAAC;AACb,QAAQ,CAAC;AACT,KAAK,EAAC;AACN;AACA,IAAI,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,IAAI,KAAK;AAC5C,QAAQ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAC;AAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAC;AAC/C,IAAI,CAAC,EAAC;AACN;AACA,IAAI,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,IAAI,KAAK;AAClD,QAAQ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAC;AAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAC;AAC/C,IAAI,CAAC,EAAC;AACN;AACA,IAAI,OAAO,QAAQ;AACnB,EAAC;AACD;AACA;AACA;AACA;AACA,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC;AACtE,MAAM,IAAI,GAAG,CAAC,OAAO,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAC;AACjD,MAAM,OAAO,GAAG,OAAO,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,0CAA0C,CAAC,EAAC;AACtF,MAAM,OAAO,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAC;AACxE;AACA;AACA,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,OAAO,GAAG,IAAI,KAAK;AACzC,IAAI,MAAM,EAAE,GAAG,OAAO,GAAE;AACxB,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE;AACrB;AACA,IAAI,IAAI;AACR,QAAQ,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;AAChC,IAAI,CAAC;AACL,IAAI,OAAO,CAAC,EAAE;AACd,QAAQ,OAAO,IAAI,CAAC,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,IAAI,CAAC;AACL,EAAC;AACD;AACA,MAAM,OAAO,GAAG,MAAM,KAAI;AAC1B;AACA;AACA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK;AACpC,IAAI,MAAM,IAAI,GAAG,GAAG,EAAE,KAAI;AAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC;AAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACvD,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAC;AACvB,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;AAC7C,CAAC,EAAC;AACF;AACA;AACA,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,EAAE,WAAW,KAAK;AAChD,IAAI,MAAM,IAAI,GAAG,GAAG,EAAE,KAAI;AAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC;AAC3C,IAAI,MAAM,MAAM,CAAC,IAAI,EAAC;AACtB,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAC;AACvB,IAAI,IAAI,WAAW,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAC;AAC3C,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AACpF,CAAC,EAAC;AACF;AACA;AACA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK;AACrC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACxD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AACzB,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAC;AAClE,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAC;AACvD,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;AAC5C,CAAC,EAAC;AACF;AACA;AACA,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK;AACpC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACxD,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAC;AAC1B,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;AAC5C,CAAC,EAAC;AACF;AACA;AACA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK;AACnC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACxD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAC;AACzB,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;AAC5C,CAAC,EAAC;AACF;AACA;AACA,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK;AAClC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACxD,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAC;AACxB,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;AAC9C,CAAC,EAAC;AACF;AACA;AACA,MAAMC,UAAQ,GAAG,YAAY;AAC7B,IAAI,IAAI,KAAK,GAAG,KAAI;AACpB,IAAI,IAAI;AACR,QAAQ,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,UAAU;AACvF,YAAY,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC;AACrE;AACA,QAAQ,MAAM,QAAQ,GAAG,MAAM,WAAW,GAAE;AAC5C,QAAQ,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAE;AAC9B,QAAQ,IAAI,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC;AAClE;AACA,QAAQ,KAAK,GAAG,QAAQ,CAAC,MAAK;AAC9B,QAAQ,IAAI,GAAG,UAAU,GAAE;AAC3B,QAAQ,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC;AAClE;AACA,QAAQ,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAC;AAC9C,QAAQ,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAC;AACxF,QAAQ,OAAO,EAAE,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,CAAC;AAC5C,IAAI,CAAC;AACL,IAAI,OAAO,KAAK,EAAE;AAClB,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AAC5E,IAAI,CAAC;AACL,YAAY;AACZ,QAAQ,MAAM,KAAK,KAAI;AACvB,IAAI,CAAC;AACL,EAAC;AACD;AACA,gBAAe;AACf,cAAIA,UAAQ;AACZ,IAAI,MAAM;AACV,IAAI,KAAK;AACT,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,MAAM;AACV;;AC1PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,gBAAgB,GAAG,GAAE;AAC3B;AACA,MAAM,QAAQ,GAAG,CAAC,KAAK,KAAK;AAC5B,IAAI,MAAM,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAC;AACrG,IAAI,IAAI,GAAG,IAAI,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAK;AAC/C,SAAS,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAC;AACrC,IAAI,OAAO,KAAK;AAChB,EAAC;AACD;AACA;AACO,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,gBAAgB,EAAC;AAC9D;AACA;AACA,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,IAAI,KAAK;AACnC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,EAAC;AACtD,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,EAAC;AACpD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9B,EAAC;AACD;AACA;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,KAAK;AACjC,IAAI,IAAI,MAAM,GAAG,KAAI;AACrB;AACA,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE;AAC9I,QAAQ,MAAM,GAAG,IAAI,CAAC,GAAG,GAAE;AAC3B,IAAI,CAAC;AACL,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,GAAE;AAC9B;AACA,IAAI,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAI;AAC/D,IAAI,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE;AAC3C,EAAC;AACD;AACA,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,KAAK;AAC5D,IAAI,MAAM,IAAI,GAAG;AACjB,QAAQ,MAAM;AACd,QAAQ,IAAI;AACZ,QAAQ,OAAO,EAAE,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AAC3C,YAAY,IAAI;AAChB;AACA,gBAAgB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE;AAC9C,oBAAoB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC3D,wBAAwB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC,EAAC;AAC9E,oBAAoB,CAAC,EAAC;AACtB,gBAAgB,CAAC;AACjB,gBAAgB,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,IAAI,GAAE;AACzE,gBAAgB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAC;AAC5D,gBAAgB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;AACtC,oBAAoB,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE;AAClF,wBAAwB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAC;AACxC,oBAAoB,CAAC,MAAM;AAC3B,wBAAwB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM,EAAC;AACzE,oBAAoB,CAAC;AACrB,gBAAgB,CAAC;AACjB,YAAY,CAAC,CAAC,OAAO,GAAG,EAAE;AAC1B,gBAAgB,IAAI,CAAC,GAAG,EAAC;AACzB,YAAY,CAAC;AACb,QAAQ,CAAC;AACT,MAAK;AACL,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK,MAAC,KAAK,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AACjC,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACjE,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC;AACpE,EAAC;AACD;AACA;AACA,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AAC/B,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC;AACzD,EAAC;AACD,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AAChC,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC;AAC1D,EAAC;AACD,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AAC/B,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC;AACzD,EAAC;AACD,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AAClC,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC;AAC5D,EAAC;AACD,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AACjC,IAAI,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACzD,IAAI,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC;AAC3D,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,KAAK;AACrC,IAAI,MAAM,GAAG,GAAG,GAAE;AAClB,IAAI,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;AACpE,QAAQ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK;AACzC,YAAY,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,EAAC;AACjE,YAAY,OAAO,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC;AACpF,QAAQ,EAAC;AACT,IAAI,CAAC;AACL;AACA,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,EAAC;AAC5E,IAAI,OAAO,GAAG;AACd;;AC5JA,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK;AAC7B,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE;AAChE,WAAW,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC;AACnC,WAAW,GAAG,CAAC,EAAE;AACjB,WAAW,GAAG,CAAC,UAAU,CAAC,aAAa;AACvC,EAAC;AACD;AACO,SAAS,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE;AACrC,IAAI,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,WAAW,GAAE;AACpE,IAAI,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,EAAC;AAC1C,IAAI,IAAI,CAAC,MAAM,EAAE;AACjB,QAAQ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AACpC,YAAY,IAAI,EAAE,EAAE;AACpB,YAAY,OAAO,EAAE,iBAAiB;AACtC,SAAS,CAAC;AACV,IAAI,CAAC;AACL;AACA,IAAI,MAAM,eAAe,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAC;AACjF,IAAI,IAAI,CAAC,eAAe,IAAI,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;AACvE,QAAQ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AACpC,YAAY,IAAI,EAAE,EAAE;AACpB,YAAY,OAAO,EAAE,cAAc;AACnC,SAAS,CAAC;AACV,IAAI,CAAC;AACL;AACA,IAAI,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAC;AAC/B,IAAI,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,GAAE;AAC5D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;AAChC,QAAQ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;AAC9B,aAAa,IAAI,CAAC;AAClB,gBAAgB,IAAI,EAAE,EAAE;AACxB,gBAAgB,OAAO,EAAE,cAAc;AACvC,aAAa,CAAC;AACd,IAAI,CAAC;AACL;AACA,IAAI,IAAI,GAAE;AACV;;AC9BA;AACA;AACA;AACA;AACA,MAAM,cAAc,GAAG,OAAO,IAAI,EAAE,MAAM,KAAK;AAC/C,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAC;AACpD,IAAI,IAAI,KAAK,GAAG,EAAC;AACjB;AACA,IAAI,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AAC5B,QAAQ,MAAM,GAAG,GAAGC,MAAI,CAAC,OAAO,CAAC,GAAG,EAAC;AACrC,QAAQ,IAAI,QAAO;AACnB,QAAQ,IAAI;AACZ,YAAY,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAC;AACjE,QAAQ,CAAC,CAAC,MAAM;AAChB;AACA,YAAY,MAAM,EAAE,IAAI,GAAG,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC,EAAC;AACnE,YAAY,QAAQ;AACpB,QAAQ,CAAC;AACT;AACA,QAAQ,MAAM,IAAI,GAAG,OAAO,KAAK,EAAE,IAAI,KAAK;AAC5C,YAAY,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACtC,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,QAAQ;AACpF,gBAAgB,MAAM,IAAI,GAAGA,MAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAC;AACvD,gBAAgB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AACxC,oBAAoB,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAC;AAClF,gBAAgB,CAAC,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAC/D,oBAAoB,IAAI;AACxB,wBAAwB,MAAM,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAC;AAC9D,wBAAwB,KAAK,IAAI,EAAC;AAClC,oBAAoB,CAAC,CAAC,OAAO,GAAG,EAAE;AAClC,wBAAwB,MAAM,EAAE,KAAK,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,EAAC;AACpG,oBAAoB,CAAC;AACrB,gBAAgB,CAAC;AACjB,YAAY,CAAC;AACb,QAAQ,EAAC;AACT,QAAQ,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,EAAC;AAChC,IAAI,CAAC;AACL;AACA,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,EAAC;AACxE,EAAC;AACD;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,CAAC,OAAO,GAAG,EAAE,KAAK;AACrC,IAAI,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAO;AAC5E,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAG;AACrC,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,oCAAmC;AACvE,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,uCAAsC;AAC1E;AACA,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AAC/B,QAAQ,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,EAAC;AAC5D,QAAQ,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,EAAC;AAC9D,QAAQ,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,OAAO,EAAC;AAC9D,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;AAChE,QAAQ,IAAI,GAAE;AACd,IAAI,CAAC;AACL,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,OAAO,GAAG,EAAE,EAAE;AACxC,IAAI,MAAM;AACV,QAAQ,IAAI,GAAG,IAAI;AACnB,QAAQ,IAAI,GAAG,SAAS;AACxB,QAAQ,MAAM,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC9D,QAAQ,SAAS,GAAG,MAAM;AAC1B,QAAQ,eAAe,GAAG,MAAM;AAChC,QAAQ,IAAI,GAAG,IAAI;AACnB,QAAQ,SAAS,GAAG,IAAI;AACxB,QAAQ,IAAI,EAAE,UAAU,GAAG,KAAK;AAChC,QAAQ,MAAM,GAAG,IAAI;AACrB,QAAQ,UAAU,GAAG,IAAI;AACzB,QAAQ,MAAM,GAAG,IAAI;AACrB,QAAQ,SAAS,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC;AAC5C,KAAK,GAAG,QAAO;AACf;AACA,IAAI,MAAM,GAAG,GAAG,OAAO,GAAE;AACzB;AACA,IAAI,IAAI,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAC;AAChD;AACA;AACA,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAC;AAC/C,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,EAAC;AAC3E;AACA;AACA,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AAChC,QAAQ,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,GAAE;AAChC,QAAQ,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM;AAC/B,YAAY,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAK;AAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAC;AAC3G,QAAQ,CAAC,EAAC;AACV,QAAQ,IAAI,GAAE;AACd,IAAI,CAAC,EAAC;AACN;AACA;AACA,IAAI,IAAI,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAC;AACvC;AACA;AACA,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AAChC,QAAQ,GAAG,CAAC,OAAO,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK;AACvD,YAAY,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAC;AAChD,QAAQ,EAAC;AACT,QAAQ,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,KAAK;AACrD,YAAY,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAC;AACnD,QAAQ,EAAC;AACT,QAAQ,IAAI,GAAE;AACd,IAAI,CAAC,EAAC;AACN;AACA;AACA,IAAI,IAAI,SAAS,EAAE;AACnB,QAAQ,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,GAAG,CAAC,SAAS,EAAC;AACvE,QAAQ,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AAChC,YAAY,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAC;AACxC,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA;AACA,IAAI,IAAI,UAAU,EAAE;AACpB,QAAQ,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE;AAC9C,YAAY,GAAG,CAAC,GAAG,CAAC,UAAU,EAAC;AAC/B,QAAQ,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;AAC9C,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,EAAC;AAClC,QAAQ,CAAC,MAAM;AACf,YAAY,GAAG,CAAC,GAAG,CAAC,IAAI,EAAC;AACzB,QAAQ,CAAC;AACT,IAAI,CAAC;AACL;AACA;AACA,IAAI,IAAI,MAAM,EAAE;AAChB,QAAQ,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;AACzC,YAAY,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,EAAC;AACnE,QAAQ,CAAC,EAAC;AACV,IAAI,CAAC;AACL;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG,MAAM;AAC9B;AACA,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;AAC1C,YAAY,MAAM,CAAC,GAAG,EAAC;AACvB,QAAQ,CAAC;AACT;AACA;AACA;AACA,QAAQ,MAAM,SAAS,GAAG;AAC1B,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;AACpD,YAAY,GAAG,mBAAmB,EAAE;AACpC,UAAS;AACT;AACA;AACA,QAAQ,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK;AACjC,YAAY,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,OAAM;AACpG,YAAY,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAC1C,QAAQ,CAAC,EAAC;AACV;AACA,QAAQ,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE;AACvC,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAK;AAC9D,YAAY,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,EAAC;AACjD,YAAY,IAAI,OAAO,EAAE,KAAK,UAAU,IAAI,SAAS,IAAI,OAAO,EAAE;AAClE,gBAAgB,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAC;AAChD,YAAY,CAAC;AACb,QAAQ,CAAC;AACT;AACA;AACA,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK;AAC9B,YAAY,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAC;AAClD,QAAQ,CAAC,EAAC;AACV;AACA;AACA,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK;AACzC,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,EAAC;AACnG,YAAY,IAAI,GAAG,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC;AACjD;AACA,YAAY,MAAM,MAAM,GAAG,GAAG,EAAE,MAAM,IAAI,GAAG,EAAE,UAAU,IAAI,IAAG;AAChE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,EAAC;AACpF,QAAQ,CAAC,EAAC;AACV,IAAI,EAAC;AACL;AACA;AACA,IAAI,IAAI,MAAM,GAAG,KAAI;AACrB;AACA,IAAI,MAAM,KAAK,GAAG,YAAY;AAC9B;AACA,QAAQ,IAAI,SAAS,EAAE,MAAM,cAAc,CAAC,SAAS,EAAE,MAAM,EAAC;AAC9D;AACA;AACA,QAAQ,WAAW,GAAE;AACrB;AACA,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAChD,YAAY,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM;AAClD,gBAAgB,MAAM,CAAC,IAAI,CAAC,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAC;AACzE,gBAAgB,OAAO,CAAC,MAAM,EAAC;AAC/B,YAAY,CAAC,EAAC;AACd,YAAY,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK;AACxC,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,EAAC;AAC7D,gBAAgB,MAAM,CAAC,GAAG,EAAC;AAC3B,YAAY,CAAC,EAAC;AACd,QAAQ,CAAC,CAAC;AACV,IAAI,EAAC;AACL;AACA,IAAI,MAAM,IAAI,GAAG,MAAM;AACvB,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK;AACxC,YAAY,IAAI,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE;AACzC,YAAY,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,EAAC;AACzC,QAAQ,CAAC,CAAC;AACV,IAAI,EAAC;AACL;AACA,IAAI,OAAO;AACX,QAAQ,GAAG;AACX,QAAQ,KAAK;AACb,QAAQ,IAAI;AACZ,QAAQ,SAAS,EAAE,MAAM,MAAM;AAC/B,KAAK;AACL;;AC9OO,SAAS,UAAU,GAAG;AAC7B,IAAI,IAAI,WAAW,GAAG,MAAK;AAC3B,IAAI,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAC;AACnD;AACA,IAAI,IAAI,UAAU;AAClB,QAAQ,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,KAAK;AAChD,YAAY,IAAI,OAAO,KAAK,QAAQ,EAAE,MAAM;AAC5C;AACA,YAAY,WAAW,GAAG,KAAI;AAC9B,YAAY,IAAI,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,WAAW,EAAC;AAC/D,iBAAiB,OAAO,CAAC,IAAI,CAAC,CAAC,EAAC;AAChC,QAAQ,CAAC,EAAC;AACV;AACA,IAAI,MAAM,cAAc,GAAG,MAAM,YAAW;AAC5C,IAAI,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK;AAClC,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;AAC1C,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,4BAA4B,CAAC,EAAC;AACxD,YAAY,MAAM;AAClB,QAAQ,CAAC;AACT;AACA,QAAQ,IAAI,KAAK,GAAG,KAAI;AACxB,QAAQ,IAAI;AACZ,YAAY,MAAM,QAAQ,GAAG,MAAM,WAAW,GAAE;AAChD,YAAY,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAE;AAClC,YAAY,KAAK,GAAG,QAAQ,CAAC,MAAK;AAClC,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAC;AAC1E,YAAY,IAAI,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAC;AACtF,QAAQ,CAAC;AACT,QAAQ,OAAO,KAAK,EAAE;AACtB,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AAC9E,QAAQ,CAAC;AACT,gBAAgB;AAChB,YAAY,IAAI;AAChB,gBAAgB,MAAM,KAAK,KAAI;AAC/B,YAAY,CAAC,CAAC,OAAO,KAAK,EAAE;AAC5B,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,EAAC;AAC1F,YAAY,CAAC;AACb,YAAY,IAAI,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM,EAAC;AAC1D,iBAAiB,OAAO,CAAC,IAAI,CAAC,CAAC,EAAC;AAChC,QAAQ,CAAC;AACT,IAAI,EAAC;AACL;AACA,IAAI,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE;AAClC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layoutkit/bree-core",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Reusable Bree scheduler core package",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",