@igniter-js/jobs 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/AGENTS.md +119 -243
  2. package/README.md +352 -158
  3. package/dist/{adapter-CXZxomI9.d.mts → adapter-DDyMVche.d.mts} +125 -20
  4. package/dist/{adapter-CXZxomI9.d.ts → adapter-DDyMVche.d.ts} +125 -20
  5. package/dist/adapters/bun.d.mts +101 -0
  6. package/dist/adapters/bun.d.ts +101 -0
  7. package/dist/adapters/bun.js +1048 -0
  8. package/dist/adapters/bun.js.map +1 -0
  9. package/dist/adapters/bun.mjs +1046 -0
  10. package/dist/adapters/bun.mjs.map +1 -0
  11. package/dist/adapters/{memory.adapter.d.ts → mock.d.mts} +7 -3
  12. package/dist/adapters/{memory.adapter.d.mts → mock.d.ts} +7 -3
  13. package/dist/adapters/{memory.adapter.js → mock.js} +122 -25
  14. package/dist/adapters/mock.js.map +1 -0
  15. package/dist/adapters/{memory.adapter.mjs → mock.mjs} +122 -25
  16. package/dist/adapters/mock.mjs.map +1 -0
  17. package/dist/adapters/{bullmq.adapter.d.mts → node.d.mts} +8 -3
  18. package/dist/adapters/{bullmq.adapter.d.ts → node.d.ts} +8 -3
  19. package/dist/adapters/{bullmq.adapter.js → node.js} +194 -40
  20. package/dist/adapters/node.js.map +1 -0
  21. package/dist/adapters/{bullmq.adapter.mjs → node.mjs} +194 -40
  22. package/dist/adapters/node.mjs.map +1 -0
  23. package/dist/index.d.mts +41 -38
  24. package/dist/index.d.ts +41 -38
  25. package/dist/index.js +145 -1856
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +146 -1854
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +29 -41
  30. package/CHANGELOG.md +0 -13
  31. package/dist/adapters/bullmq.adapter.js.map +0 -1
  32. package/dist/adapters/bullmq.adapter.mjs.map +0 -1
  33. package/dist/adapters/index.d.mts +0 -143
  34. package/dist/adapters/index.d.ts +0 -143
  35. package/dist/adapters/index.js +0 -1891
  36. package/dist/adapters/index.js.map +0 -1
  37. package/dist/adapters/index.mjs +0 -1887
  38. package/dist/adapters/index.mjs.map +0 -1
  39. package/dist/adapters/memory.adapter.js.map +0 -1
  40. package/dist/adapters/memory.adapter.mjs.map +0 -1
@@ -33,6 +33,8 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
33
33
  this.registeredJobs = /* @__PURE__ */ new Map();
34
34
  this.registeredCrons = /* @__PURE__ */ new Map();
35
35
  this.workers = /* @__PURE__ */ new Map();
36
+ this.streamRecords = /* @__PURE__ */ new Map();
37
+ this.streamSubscribers = /* @__PURE__ */ new Map();
36
38
  this.subscribers = /* @__PURE__ */ new Map();
37
39
  this.queues = {
38
40
  list: async () => this.listQueues(),
@@ -358,25 +360,6 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
358
360
  }
359
361
  return retried;
360
362
  }
361
- async pauseJobType(queue, jobName) {
362
- const jobIds = this.jobsByQueue.get(queue) ?? [];
363
- for (const id of jobIds) {
364
- const job = this.jobsById.get(id);
365
- if (!job) continue;
366
- if (job.name === jobName && job.status === "waiting")
367
- job.status = "paused";
368
- }
369
- }
370
- async resumeJobType(queue, jobName) {
371
- const jobIds = this.jobsByQueue.get(queue) ?? [];
372
- for (const id of jobIds) {
373
- const job = this.jobsById.get(id);
374
- if (!job) continue;
375
- if (job.name === jobName && job.status === "paused")
376
- job.status = "waiting";
377
- }
378
- void this.kickWorkers(queue);
379
- }
380
363
  async searchJobs(filter) {
381
364
  const queue = filter?.queue;
382
365
  const statuses = filter?.status;
@@ -440,9 +423,68 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
440
423
  if (current.size === 0) this.subscribers.delete(channel);
441
424
  };
442
425
  }
426
+ async writeJobStreamEvent(params) {
427
+ const key = this.getStreamKey(params.queue, params.jobId);
428
+ const record = this.streamRecords.get(key) ?? { events: [], nextId: 1 };
429
+ const id = String(record.nextId++);
430
+ const event = {
431
+ ...params.event,
432
+ id
433
+ };
434
+ if (params.persistence?.enabled) {
435
+ record.events.push(event);
436
+ const maxEvents = params.persistence.maxEvents;
437
+ if (typeof maxEvents === "number" && maxEvents > 0 && record.events.length > maxEvents) {
438
+ record.events.splice(0, record.events.length - maxEvents);
439
+ }
440
+ this.streamRecords.set(key, record);
441
+ } else if (!this.streamRecords.has(key)) {
442
+ this.streamRecords.set(key, record);
443
+ }
444
+ const handlers = this.streamSubscribers.get(key);
445
+ if (handlers?.size) {
446
+ await Promise.all(
447
+ Array.from(handlers).map(async (handler) => handler(event))
448
+ );
449
+ }
450
+ return id;
451
+ }
452
+ async readJobStream(params) {
453
+ const key = this.getStreamKey(params.queue, params.jobId);
454
+ const record = this.streamRecords.get(key);
455
+ if (!record) {
456
+ return { items: [], nextCursor: void 0, hasMore: false };
457
+ }
458
+ const after = params.after ? Number(params.after) : void 0;
459
+ const limit = params.limit ?? 100;
460
+ const filtered = record.events.filter(
461
+ (event) => typeof after === "number" ? Number(event.id) > after : true
462
+ );
463
+ const items = filtered.slice(0, limit);
464
+ const hasMore = filtered.length > items.length;
465
+ return {
466
+ items,
467
+ nextCursor: items.at(-1)?.id,
468
+ hasMore
469
+ };
470
+ }
471
+ async subscribeJobStream(params) {
472
+ const key = this.getStreamKey(params.queue, params.jobId);
473
+ const set = this.streamSubscribers.get(key) ?? /* @__PURE__ */ new Set();
474
+ set.add(params.handler);
475
+ this.streamSubscribers.set(key, set);
476
+ return async () => {
477
+ const current = this.streamSubscribers.get(key);
478
+ if (!current) return;
479
+ current.delete(params.handler);
480
+ if (current.size === 0) this.streamSubscribers.delete(key);
481
+ };
482
+ }
443
483
  async shutdown() {
444
484
  this.workers.clear();
445
485
  this.subscribers.clear();
486
+ this.streamSubscribers.clear();
487
+ this.streamRecords.clear();
446
488
  }
447
489
  toSearchResult(job) {
448
490
  return {
@@ -463,6 +505,9 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
463
505
  scope: job.scope
464
506
  };
465
507
  }
508
+ getStreamKey(queue, jobId) {
509
+ return `${queue}:${jobId}`;
510
+ }
466
511
  toWorkerHandle(worker) {
467
512
  return {
468
513
  id: worker.id,
@@ -561,12 +606,61 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
561
606
  name: job.name,
562
607
  queue: job.queue,
563
608
  attemptsMade: job.attemptsMade,
564
- metadata: job.metadata
609
+ metadata: job.metadata,
610
+ updateProgress: async (progress, message) => {
611
+ job.progress = progress;
612
+ if (message) {
613
+ job.logs.push({
614
+ timestamp: /* @__PURE__ */ new Date(),
615
+ level: "info",
616
+ message
617
+ });
618
+ }
619
+ await definition.onProgress?.({
620
+ input: job.input,
621
+ context: {},
622
+ job: {
623
+ id: job.id,
624
+ name: job.name,
625
+ queue: job.queue,
626
+ attemptsMade: job.attemptsMade,
627
+ metadata: job.metadata
628
+ },
629
+ scope: job.scope,
630
+ progress,
631
+ message
632
+ });
633
+ }
565
634
  },
566
635
  scope: job.scope,
567
636
  startedAt: job.startedAt
568
637
  });
569
638
  }
639
+ const updateProgress = async (progress, message) => {
640
+ job.progress = progress;
641
+ if (message) {
642
+ job.logs.push({
643
+ timestamp: /* @__PURE__ */ new Date(),
644
+ level: "info",
645
+ message
646
+ });
647
+ }
648
+ await definition.onProgress?.({
649
+ input: job.input,
650
+ context: {},
651
+ job: {
652
+ id: job.id,
653
+ name: job.name,
654
+ queue: job.queue,
655
+ attemptsMade: job.attemptsMade,
656
+ metadata: job.metadata,
657
+ updateProgress
658
+ },
659
+ scope: job.scope,
660
+ progress,
661
+ message
662
+ });
663
+ };
570
664
  const result = await definition.handler({
571
665
  input: job.input,
572
666
  context: {},
@@ -575,7 +669,8 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
575
669
  name: job.name,
576
670
  queue: job.queue,
577
671
  attemptsMade: job.attemptsMade,
578
- metadata: job.metadata
672
+ metadata: job.metadata,
673
+ updateProgress
579
674
  },
580
675
  scope: job.scope
581
676
  });
@@ -600,7 +695,8 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
600
695
  name: job.name,
601
696
  queue: job.queue,
602
697
  attemptsMade: job.attemptsMade,
603
- metadata: job.metadata
698
+ metadata: job.metadata,
699
+ updateProgress
604
700
  },
605
701
  scope: job.scope,
606
702
  result,
@@ -634,7 +730,8 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
634
730
  name: job.name,
635
731
  queue: job.queue,
636
732
  attemptsMade: job.attemptsMade,
637
- metadata: job.metadata
733
+ metadata: job.metadata,
734
+ updateProgress: async () => void 0
638
735
  },
639
736
  scope: job.scope,
640
737
  error,
@@ -655,5 +752,5 @@ var IgniterJobsMemoryAdapter = class _IgniterJobsMemoryAdapter {
655
752
  };
656
753
 
657
754
  export { IgniterJobsMemoryAdapter };
658
- //# sourceMappingURL=memory.adapter.mjs.map
659
- //# sourceMappingURL=memory.adapter.mjs.map
755
+ //# sourceMappingURL=mock.mjs.map
756
+ //# sourceMappingURL=mock.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/id-generator.ts","../../src/errors/jobs.error.ts","../../src/adapters/memory.adapter.ts"],"names":[],"mappings":";;;AAGO,IAAM,yBAAN,MAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlC,OAAc,SAAS,MAAA,EAAwB;AAC7C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,CAAE,SAAS,EAAE,CAAA;AAClC,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AACpD,IAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,IAAI,MAAM,CAAA,CAAA;AAAA,EACnC;AACF,CAAA;AC+CO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA,EACjD,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AAAA,EACf;AACF,CAAA;;;ACUO,IAAM,wBAAA,GAAN,MAAM,yBAAA,CAAuD;AAAA,EAA7D,WAAA,GAAA;AACL,IAAA,IAAA,CAAgB,MAAA,GAAS;AAAA,MACvB,IAAA,EAAM;AAAA,KACR;AAEA,IAAA,IAAA,CAAiB,QAAA,uBAAe,GAAA,EAAuB;AACvD,IAAA,IAAA,CAAiB,WAAA,uBAAkB,GAAA,EAAsB;AACzD,IAAA,IAAA,CAAiB,cAAA,uBAAqB,GAAA,EAGpC;AACF,IAAA,IAAA,CAAiB,eAAA,uBAAsB,GAAA,EAGrC;AAEF,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAA+B;AAC9D,IAAA,IAAA,CAAiB,aAAA,uBAAoB,GAAA,EAAgC;AACrE,IAAA,IAAA,CAAiB,iBAAA,uBAAwB,GAAA,EAOvC;AAEF,IAAA,IAAA,CAAiB,WAAA,uBAAkB,GAAA,EAGjC;AAEF,IAAA,IAAA,CAAgB,MAAA,GAAkC;AAAA,MAChD,IAAA,EAAM,YAAY,IAAA,CAAK,UAAA,EAAW;AAAA,MAClC,GAAA,EAAK,OAAO,IAAA,KAAS,IAAA,CAAK,aAAa,IAAI,CAAA;AAAA,MAC3C,YAAA,EAAc,OAAO,IAAA,KAAS,IAAA,CAAK,kBAAkB,IAAI,CAAA;AAAA,MACzD,OAAA,EAAS,OAAO,IAAA,EAAM,MAAA,KAAW;AAC/B,QAAA,MAAM,WAAW,MAAA,EAAQ,MAAA;AACzB,QAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,GAAA;AAC/B,QAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,CAAA;AACjC,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,CAAW;AAAA,UACpC,KAAA,EAAO,IAAA;AAAA,UACP,MAAA,EAAQ,QAAA;AAAA,UACR,KAAA;AAAA,UACA;AAAA,SACM,CAAA;AACR,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AAAA,MACA,KAAA,EAAO,OAAO,IAAA,KAAS,IAAA,CAAK,WAAW,IAAI,CAAA;AAAA,MAC3C,MAAA,EAAQ,OAAO,IAAA,KAAS,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA,MAC7C,QAAA,EAAU,OAAO,IAAA,KAAS;AAGxB,QAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AACzC,QAAA,OAAO,MAAM,QAAA,IAAY,KAAA;AAAA,MAC3B,CAAA;AAAA,MACA,KAAA,EAAO,OAAO,IAAA,KAAS,IAAA,CAAK,WAAW,IAAI,CAAA;AAAA,MAC3C,OAAO,OAAO,IAAA,EAAM,YAAY,IAAA,CAAK,UAAA,CAAW,MAAM,OAAO,CAAA;AAAA,MAC7D,YAAY,OAAO,IAAA,EAAM,YAAY,IAAA,CAAK,eAAA,CAAgB,MAAM,OAAO;AAAA,KACzE;AAEA,IAAA,IAAA,CAAiB,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAAA;AAAA,EAEhD,OAAc,MAAA,GAA6B;AACzC,IAAA,OAAO,IAAI,yBAAA,EAAyB;AAAA,EACtC;AAAA,EAEO,WAAA,CACL,SAAA,EACA,OAAA,EACA,UAAA,EACM;AACN,IAAA,MAAM,YACJ,IAAA,CAAK,cAAA,CAAe,IAAI,SAAS,CAAA,wBAC7B,GAAA,EAAiD;AACvD,IAAA,IAAI,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA,EAAG;AAC1B,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,oBAAA;AAAA,QACN,OAAA,EAAS,CAAA,KAAA,EAAQ,OAAO,CAAA,gCAAA,EAAmC,SAAS,CAAA,EAAA;AAAA,OACrE,CAAA;AAAA,IACH;AACA,IAAA,SAAA,CAAU,GAAA,CAAI,SAAS,UAAU,CAAA;AACjC,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,SAAA,EAAW,SAAS,CAAA;AAAA,EAC9C;AAAA,EAEO,YAAA,CACL,SAAA,EACA,QAAA,EACA,UAAA,EACM;AACN,IAAA,MAAM,aACJ,IAAA,CAAK,eAAA,CAAgB,IAAI,SAAS,CAAA,wBAC9B,GAAA,EAA6C;AACnD,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,mBAAA;AAAA,QACN,OAAA,EAAS,CAAA,MAAA,EAAS,QAAQ,CAAA,gCAAA,EAAmC,SAAS,CAAA,EAAA;AAAA,OACvE,CAAA;AAAA,IACH;AACA,IAAA,UAAA,CAAW,GAAA,CAAI,UAAU,UAAU,CAAA;AACnC,IAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,SAAA,EAAW,UAAU,CAAA;AAAA,EAChD;AAAA,EAEA,MAAa,SACX,MAAA,EACiB;AACjB,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,IAAS,sBAAA,CAAuB,SAAS,KAAK,CAAA;AACnE,IAAA,MAAM,WAAA,GAAc,OAAO,QAAA,IAAY,CAAA;AAEvC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,EAAC;AAErC,IAAA,MAAM,GAAA,GAAiB;AAAA,MACrB,EAAA,EAAI,KAAA;AAAA,MACJ,MAAM,MAAA,CAAO,OAAA;AAAA,MACb,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,MAAA,EAAQ,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,GACtC,QAAA,GACA,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,GAAQ,IAC7B,SAAA,GACA,SAAA;AAAA,MACN,QAAA,EAAU,CAAA;AAAA,MACV,YAAA,EAAc,CAAA;AAAA,MACd,WAAA;AAAA,MACA,QAAA,EAAU,OAAO,QAAA,IAAY,CAAA;AAAA,MAC7B,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,QAAA;AAAA,MACA,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,MAAM;AAAC,KACT;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAC5B,IAAA,MAAM,YAAY,IAAA,CAAK,WAAA,CAAY,IAAI,MAAA,CAAO,KAAK,KAAK,EAAC;AACzD,IAAA,SAAA,CAAU,KAAK,KAAK,CAAA;AACpB,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,KAAA,EAAO,SAAS,CAAA;AAE5C,IAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,GAAQ,CAAA,EAAG;AACpC,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACtC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACb,QAAA,IAAI,CAAC,KAAK,YAAA,CAAa,GAAA,CAAI,OAAO,KAAK,CAAA,SAAU,MAAA,GAAS,SAAA;AAC1D,QAAA,KAAK,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAAA,MACpC,CAAA,EAAG,OAAO,KAAK,CAAA;AACf,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,KAAK,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAClC,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAa,SACX,MAAA,EACiB;AACjB,IAAA,IAAI,OAAO,EAAA,EAAI;AACb,MAAA,MAAM,QAAQ,MAAA,CAAO,EAAA,CAAG,OAAA,EAAQ,GAAI,KAAK,GAAA,EAAI;AAC7C,MAAA,IAAI,SAAS,CAAA,EAAG;AACd,QAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,UACzB,IAAA,EAAM,uBAAA;AAAA,UACN,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AACA,MAAA,OAAO,KAAK,QAAA,CAAS,EAAE,GAAG,MAAA,EAAQ,OAAO,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,MAAA,CAAO,IAAA,IAAQ,MAAA,CAAO,KAAA,EAAO;AAG/B,MAAA,OAAO,IAAA,CAAK,SAAS,EAAE,GAAG,QAAQ,KAAA,EAAO,MAAA,CAAO,KAAA,IAAS,CAAA,EAAG,CAAA;AAAA,IAC9D;AACA,IAAA,OAAO,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAa,MAAA,CACX,KAAA,EACA,KAAA,EACwC;AACxC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO,OAAO,IAAA;AACzC,IAAA,OAAO,IAAA,CAAK,eAAe,GAAG,CAAA;AAAA,EAChC;AAAA,EAEA,MAAa,WAAA,CACX,KAAA,EACA,KAAA,EACkC;AAClC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO,OAAO,IAAA;AACzC,IAAA,OAAO,GAAA,CAAI,MAAA;AAAA,EACb;AAAA,EAEA,MAAa,UAAA,CACX,KAAA,EACA,KAAA,EAC8B;AAC9B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,SAAc,EAAC;AAC1C,IAAA,OAAO,GAAA,CAAI,IAAA;AAAA,EACb;AAAA,EAEA,MAAa,cAAA,CAAe,KAAA,EAAe,KAAA,EAAiC;AAC1E,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,KAAK,OAAO,CAAA;AACjB,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO,OAAO,CAAA;AACzC,IAAA,OAAO,GAAA,CAAI,QAAA;AAAA,EACb;AAAA,EAEA,MAAa,QAAA,CAAS,KAAA,EAAe,KAAA,EAA+B;AAClE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,QAAQ,KAAK,CAAA,YAAA;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO;AAChC,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,CAAA,KAAA,EAAQ,KAAK,CAAA,sBAAA,EAAyB,KAAK,CAAA,EAAA;AAAA,OACrD,CAAA;AAAA,IACH;AACA,IAAA,GAAA,CAAI,MAAA,GAAS,SAAA;AACb,IAAA,GAAA,CAAI,KAAA,GAAQ,MAAA;AACZ,IAAA,GAAA,CAAI,WAAA,GAAc,MAAA;AAClB,IAAA,GAAA,CAAI,QAAA,GAAW,CAAA;AACf,IAAA,KAAK,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AAAA,EACjC;AAAA,EAEA,MAAa,SAAA,CAAU,KAAA,EAAe,KAAA,EAA+B;AACnE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO;AAClC,IAAA,IAAA,CAAK,QAAA,CAAS,OAAO,KAAK,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,KAAK,CAAA;AAC3C,IAAA,IAAI,IAAA;AACF,MAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,QACf,GAAA,CAAI,KAAA;AAAA,QACJ,IAAA,CAAK,MAAA,CAAO,CAAC,EAAA,KAAO,OAAO,KAAK;AAAA,OAClC;AAAA,EACJ;AAAA,EAEA,MAAa,UAAA,CAAW,KAAA,EAAe,KAAA,EAA+B;AACpE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,QAAQ,KAAK,CAAA,YAAA;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO;AAChC,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,CAAA,KAAA,EAAQ,KAAK,CAAA,sBAAA,EAAyB,KAAK,CAAA,EAAA;AAAA,OACrD,CAAA;AAAA,IACH;AACA,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,SAAA,IAAa,GAAA,CAAI,WAAW,QAAA,EAAU;AACvD,MAAA,GAAA,CAAI,SAAS,IAAA,CAAK,YAAA,CAAa,IAAI,GAAA,CAAI,KAAK,IAAI,QAAA,GAAW,SAAA;AAC3D,MAAA,KAAK,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAa,eAAA,CACX,KAAA,EACA,MAAA,EACA,KAAA,EACe;AACf,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,QAAQ,KAAK,CAAA,YAAA;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,IAAI,KAAA,IAAS,GAAA,CAAI,KAAA,KAAU,KAAA,EAAO;AAChC,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,CAAA,KAAA,EAAQ,KAAK,CAAA,sBAAA,EAAyB,KAAK,CAAA,EAAA;AAAA,OACrD,CAAA;AAAA,IACH;AACA,IAAA,GAAA,CAAI,MAAA,GAAS,QAAA;AACb,IAAA,GAAA,CAAI,KAAA,GAAQ,MAAA;AACZ,IAAA,GAAA,CAAI,WAAA,uBAAkB,IAAA,EAAK;AAAA,EAC7B;AAAA,EAEA,MAAa,aAAA,CAAc,MAAA,EAAkB,KAAA,EAA+B;AAC1E,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,EAAA,KAAO,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,KAAK,CAAC,CAAC,CAAA;AAAA,EAChE;AAAA,EAEA,MAAa,cAAA,CAAe,MAAA,EAAkB,KAAA,EAA+B;AAC3E,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,EAAA,KAAO,IAAA,CAAK,SAAA,CAAU,EAAA,EAAI,KAAK,CAAC,CAAC,CAAA;AAAA,EACjE;AAAA,EAEA,MAAa,aACX,KAAA,EACsC;AACtC,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,iBAAA,CAAkB,KAAK,CAAA;AACjD,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,KAAA;AAAA,MACN,QAAA,EAAU,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AAAA,MACrC,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AAAA,EAEA,MAAa,kBAAkB,KAAA,EAA0C;AACvE,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,MAAM,MAAA,GAA2B;AAAA,MAC/B,OAAA,EAAS,CAAA;AAAA,MACT,MAAA,EAAQ,CAAA;AAAA,MACR,SAAA,EAAW,CAAA;AAAA,MACX,MAAA,EAAQ,CAAA;AAAA,MACR,OAAA,EAAS,CAAA;AAAA,MACT,MAAA,EAAQ;AAAA,KACV;AACA,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,GAAA,CAAI,UAAU,MAAA,EAAQ;AACxB,QAAC,MAAA,CAAe,IAAI,MAAM,CAAA,EAAA;AAAA,MAC5B;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAa,UAAA,GAA8C;AACzD,IAAA,MAAM,SAAS,KAAA,CAAM,IAAA;AAAA,0BACf,GAAA,CAAI;AAAA,QACN,GAAG,IAAA,CAAK,WAAA,CAAY,IAAA,EAAK;AAAA,QACzB,GAAG,IAAA,CAAK,cAAA,CAAe,IAAA,EAAK;AAAA,QAC5B,GAAG,IAAA,CAAK,eAAA,CAAgB,IAAA;AAAK,OAC9B;AAAA,KACH;AACA,IAAA,MAAM,SAAiC,EAAC;AACxC,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,MAAA,CAAO,IAAA,CAAM,MAAM,IAAA,CAAK,YAAA,CAAa,CAAC,CAAG,CAAA;AAAA,IAC3C;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAa,WAAW,KAAA,EAA8B;AACpD,IAAA,IAAA,CAAK,YAAA,CAAa,IAAI,KAAK,CAAA;AAC3B,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,SAAA,EAAW,GAAA,CAAI,MAAA,GAAS,QAAA;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,MAAa,YAAY,KAAA,EAA8B;AACrD,IAAA,IAAA,CAAK,YAAA,CAAa,OAAO,KAAK,CAAA;AAC9B,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,QAAA,EAAU,GAAA,CAAI,MAAA,GAAS,SAAA;AAAA,IAC5C;AACA,IAAA,KAAK,IAAA,CAAK,YAAY,KAAK,CAAA;AAAA,EAC7B;AAAA,EAEA,MAAa,WAAW,KAAA,EAAgC;AACtD,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,SAAA,IAAa,GAAA,CAAI,WAAW,QAAA,EAAU;AACvD,QAAA,IAAA,CAAK,QAAA,CAAS,OAAO,EAAE,CAAA;AACvB,QAAA,OAAA,EAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,MACf,KAAA;AAAA,MACA,MAAA,CAAO,OAAO,CAAC,EAAA,KAAO,KAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC;AAAA,KAC7C;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAa,UAAA,CACX,KAAA,EACA,OAAA,EACiB;AACjB,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,IACzC,OAAA,CAAQ,MAAA,GACR,CAAC,OAAA,CAAQ,MAAM,CAAA;AACnB,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,CAAA;AACvC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,iBAAA;AAEtC,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,OAAA,GAAU,CAAA;AAEd,IAAA,KAAA,MAAW,EAAA,IAAM,CAAC,GAAG,MAAM,CAAA,EAAG;AAC5B,MAAA,IAAI,WAAW,KAAA,EAAO;AACtB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AACpC,MAAA,MAAM,KAAA,GAAQ,GAAA,GAAM,GAAA,CAAI,SAAA,CAAU,OAAA,EAAQ;AAC1C,MAAA,IAAI,QAAQ,SAAA,EAAW;AACvB,MAAA,IAAA,CAAK,QAAA,CAAS,OAAO,EAAE,CAAA;AACvB,MAAA,OAAA,EAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,MACf,KAAA;AAAA,MACA,MAAA,CAAO,OAAO,CAAC,EAAA,KAAO,KAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC;AAAA,KAC7C;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAa,eAAA,CACX,KAAA,EACA,OAAA,EACe;AAEf,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,KAAA,MAAW,EAAA,IAAM,MAAA,EAAQ,IAAA,CAAK,QAAA,CAAS,OAAO,EAAE,CAAA;AAChD,IAAA,IAAA,CAAK,WAAA,CAAY,OAAO,KAAK,CAAA;AAC7B,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,KAAK,CAAA;AAChC,IAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,KAAK,CAAA;AACjC,IAAA,IAAA,CAAK,YAAA,CAAa,OAAO,KAAK,CAAA;AAAA,EAChC;AAAA,EAEA,MAAa,gBAAgB,KAAA,EAAgC;AAC3D,IAAA,MAAM,SAAS,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC/C,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAI,GAAA,CAAI,WAAW,QAAA,EAAU;AAC3B,QAAA,MAAM,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,KAAK,CAAA;AAC7B,QAAA,OAAA,EAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAa,WAAW,MAAA,EAAgD;AACtE,IAAA,MAAM,QAAQ,MAAA,EAAQ,KAAA;AACtB,IAAA,MAAM,WAA2C,MAAA,EAAQ,MAAA;AACzD,IAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,GAAA;AAC/B,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,CAAA;AAEjC,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,CAAA,CAC1C,MAAA,CAAO,CAAC,CAAA,KAAO,KAAA,GAAQ,CAAA,CAAE,KAAA,KAAU,KAAA,GAAQ,IAAK,CAAA,CAChD,MAAA,CAAO,CAAC,CAAA,KAAO,QAAA,GAAW,QAAA,CAAS,QAAA,CAAS,CAAA,CAAE,MAAM,CAAA,GAAI,IAAK,CAAA,CAC7D,IAAA;AAAA,MACC,CAAC,CAAA,EAAG,CAAA,KACF,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA,IACf,CAAA,CAAE,SAAA,CAAU,OAAA,EAAQ,GAAI,CAAA,CAAE,UAAU,OAAA;AAAQ,KAChD;AAEF,IAAA,OAAO,GAAA,CAAI,KAAA,CAAM,MAAA,EAAQ,MAAA,GAAS,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AAAA,EAC5E;AAAA,EAEA,MAAa,aAAa,MAAA,EAA8C;AACtE,IAAA,MAAM,OAAO,MAAA,EAAQ,IAAA;AACrB,IAAA,MAAM,WAAW,MAAA,EAAQ,QAAA;AACzB,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,UAAA,EAAW;AAClC,IAAA,OAAO,GAAA,CACJ,MAAA,CAAO,CAAC,CAAA,KAAO,IAAA,GAAO,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,IAAK,CAAA,CACnD,MAAA;AAAA,MAAO,CAAC,CAAA,KACP,OAAO,aAAa,SAAA,GAAY,CAAA,CAAE,aAAa,QAAA,GAAW;AAAA,KAC5D;AAAA,EACJ;AAAA,EAEA,MAAa,cAAc,MAAA,EAAiD;AAC1E,IAAA,MAAM,QAAQ,MAAA,EAAQ,KAAA;AACtB,IAAA,MAAM,YAAY,MAAA,EAAQ,SAAA;AAC1B,IAAA,OAAO,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,CAAA,CACpC,MAAA,CAAO,CAAC,CAAA,KAAO,QAAQ,CAAA,CAAE,MAAA,CAAO,SAAS,KAAK,CAAA,GAAI,IAAK,CAAA,CACvD,MAAA;AAAA,MAAO,CAAC,CAAA,KACP,OAAO,SAAA,KAAc,SAAA,GACjB,YACE,CAAC,CAAA,CAAE,MAAA,GACH,CAAA,CAAE,MAAA,GACJ;AAAA,MAEL,GAAA,CAAI,CAAC,MAAM,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AAAA,EACtC;AAAA,EAEA,MAAa,aACX,MAAA,EACkC;AAClC,IAAA,MAAM,QAAA,GAAW,sBAAA,CAAuB,QAAA,CAAS,QAAQ,CAAA;AACzD,IAAA,MAAM,KAAA,GAA2B;AAAA,MAC/B,EAAA,EAAI,QAAA;AAAA,MACJ,MAAA,EAAQ,MAAA,CAAO,MAAA,IAAU,EAAC;AAAA,MAC1B,WAAA,EAAa,OAAO,WAAA,IAAe,CAAA;AAAA,MACnC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAA,EAAQ,KAAA;AAAA,MACR,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,SAAS,EAAE,SAAA,EAAW,GAAG,MAAA,EAAQ,CAAA,EAAG,eAAe,CAAA,EAAE;AAAA,MACrD,UAAU,MAAA,CAAO;AAAA,KACnB;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,QAAA,EAAU,KAAK,CAAA;AAGhC,IAAA,KAAA,MAAW,KAAK,KAAA,CAAM,MAAA,EAAQ,KAAK,IAAA,CAAK,YAAY,CAAC,CAAA;AAErD,IAAA,OAAO,IAAA,CAAK,eAAe,KAAK,CAAA;AAAA,EAClC;AAAA,EAEO,UAAA,GAAmD;AACxD,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAqC;AACrD,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,CAAA,IAAK,IAAA,CAAK,OAAA;AAC7B,MAAA,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AACxC,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAa,YAAA,CAAa,OAAA,EAAiB,OAAA,EAAiC;AAC1E,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AAC7C,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,CAAE,GAAA,CAAI,OAAO,CAAA,KAAM,CAAA,CAAE,OAAc,CAAC,CAAC,CAAA;AAAA,EAC5E;AAAA,EAEA,MAAa,cAAA,CACX,OAAA,EACA,OAAA,EAC8B;AAC9B,IAAA,MAAM,MACJ,IAAA,CAAK,WAAA,CAAY,IAAI,OAAO,CAAA,wBAAS,GAAA,EAA6B;AACpE,IAAA,GAAA,CAAI,IAAI,OAAO,CAAA;AACf,IAAA,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,OAAA,EAAS,GAAG,CAAA;AAEjC,IAAA,OAAO,YAAY;AACjB,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AAC5C,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,OAAA,CAAQ,OAAO,OAAO,CAAA;AACtB,MAAA,IAAI,QAAQ,IAAA,KAAS,CAAA,EAAG,IAAA,CAAK,WAAA,CAAY,OAAO,OAAO,CAAA;AAAA,IACzD,CAAA;AAAA,EACF;AAAA,EAEA,MAAa,oBACX,MAAA,EACiB;AACjB,IAAA,MAAM,MAAM,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,KAAA,EAAO,OAAO,KAAK,CAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,MAAA,EAAQ,EAAC,EAAG,MAAA,EAAQ,CAAA,EAAE;AACtE,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,CAAA;AACjC,IAAA,MAAM,KAAA,GAAoD;AAAA,MACxD,GAAG,MAAA,CAAO,KAAA;AAAA,MACV;AAAA,KACF;AAEA,IAAA,IAAI,MAAA,CAAO,aAAa,OAAA,EAAS;AAC/B,MAAA,MAAA,CAAO,MAAA,CAAO,KAAK,KAAK,CAAA;AACxB,MAAA,MAAM,SAAA,GAAY,OAAO,WAAA,CAAY,SAAA;AACrC,MAAA,IACE,OAAO,cAAc,QAAA,IACrB,SAAA,GAAY,KACZ,MAAA,CAAO,MAAA,CAAO,SAAS,SAAA,EACvB;AACA,QAAA,MAAA,CAAO,OAAO,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,MAAA,CAAO,SAAS,SAAS,CAAA;AAAA,MAC1D;AACA,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,MAAM,CAAA;AAAA,IACpC,WAAW,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,EAAG;AACvC,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAA,EAAK,MAAM,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,GAAG,CAAA;AAC/C,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,KAAA,CAAM,KAAK,QAAQ,CAAA,CAAE,IAAI,OAAO,OAAA,KAAY,OAAA,CAAQ,KAAK,CAAC;AAAA,OAC5D;AAAA,IACF;AAEA,IAAA,OAAO,EAAA;AAAA,EACT;AAAA,EAEA,MAAa,cACX,MAAA,EAGA;AACA,IAAA,MAAM,MAAM,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,KAAA,EAAO,OAAO,KAAK,CAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA;AACzC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO,EAAE,KAAA,EAAO,IAAI,UAAA,EAAY,MAAA,EAAW,SAAS,KAAA,EAAM;AAAA,IAC5D;AAEA,IAAA,MAAM,QAAQ,MAAA,CAAO,KAAA,GAAQ,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,GAAI,MAAA;AACpD,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,IAAS,GAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,OAAO,MAAA,CAAO,MAAA;AAAA,MAAO,CAAC,UACrC,OAAO,KAAA,KAAU,WAAW,MAAA,CAAO,KAAA,CAAM,EAAE,CAAA,GAAI,KAAA,GAAQ;AAAA,KACzD;AACA,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AACrC,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,GAAS,KAAA,CAAM,MAAA;AAExC,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,UAAA,EAAY,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,EAAA;AAAA,MAC1B;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAa,mBACX,MAAA,EAC8B;AAC9B,IAAA,MAAM,MAAM,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,KAAA,EAAO,OAAO,KAAK,CAAA;AACxD,IAAA,MAAM,MAAM,IAAA,CAAK,iBAAA,CAAkB,IAAI,GAAG,CAAA,wBAAS,GAAA,EAAI;AACvD,IAAA,GAAA,CAAI,GAAA,CAAI,OAAO,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,GAAA,EAAK,GAAG,CAAA;AAEnC,IAAA,OAAO,YAAY;AACjB,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,GAAG,CAAA;AAC9C,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,OAAA,CAAQ,MAAA,CAAO,OAAO,OAAO,CAAA;AAC7B,MAAA,IAAI,QAAQ,IAAA,KAAS,CAAA,EAAG,IAAA,CAAK,iBAAA,CAAkB,OAAO,GAAG,CAAA;AAAA,IAC3D,CAAA;AAAA,EACF;AAAA,EAEA,MAAa,QAAA,GAA0B;AACrC,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAC7B,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AAAA,EAC3B;AAAA,EAEQ,eAAe,GAAA,EAAwC;AAC7D,IAAA,OAAO;AAAA,MACL,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,QAAQ,GAAA,CAAI,MAAA;AAAA,MACZ,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,QAAQ,GAAA,CAAI,MAAA;AAAA,MACZ,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,cAAc,GAAA,CAAI,YAAA;AAAA,MAClB,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,OAAO,GAAA,CAAI;AAAA,KACb;AAAA,EACF;AAAA,EAEQ,YAAA,CAAa,OAAe,KAAA,EAAuB;AACzD,IAAA,OAAO,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA;AAAA,EAC1B;AAAA,EAEQ,eAAe,MAAA,EAAoD;AACzE,IAAA,OAAO;AAAA,MACL,IAAI,MAAA,CAAO,EAAA;AAAA,MACX,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAO,YAAY;AACjB,QAAA,MAAA,CAAO,MAAA,GAAS,IAAA;AAAA,MAClB,CAAA;AAAA,MACA,QAAQ,YAAY;AAClB,QAAA,MAAA,CAAO,MAAA,GAAS,KAAA;AAChB,QAAA,KAAA,MAAW,KAAK,MAAA,CAAO,MAAA,EAAQ,KAAK,IAAA,CAAK,YAAY,CAAC,CAAA;AAAA,MACxD,CAAA;AAAA,MACA,OAAO,YAAY;AACjB,QAAA,MAAA,CAAO,MAAA,GAAS,IAAA;AAAA,MAClB,CAAA;AAAA,MACA,WAAW,MAAM,CAAC,MAAA,CAAO,MAAA,IAAU,CAAC,MAAA,CAAO,MAAA;AAAA,MAC3C,QAAA,EAAU,MAAM,MAAA,CAAO,MAAA;AAAA,MACvB,QAAA,EAAU,MAAM,MAAA,CAAO,MAAA;AAAA,MACvB,UAAA,EAAY,YAAY,IAAA,CAAK,eAAA,CAAgB,MAAM;AAAA,KACrD;AAAA,EACF;AAAA,EAEQ,gBAAgB,MAAA,EAAqD;AAC3E,IAAA,MAAM,SAAS,IAAA,CAAK,GAAA,EAAI,GAAI,MAAA,CAAO,UAAU,OAAA,EAAQ;AACrD,IAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,SAAA;AACjC,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,MAAA,EAAQ,OAAO,OAAA,CAAQ,MAAA;AAAA,MACvB,aAAa,SAAA,GAAY,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,gBAAgB,SAAA,GAAY,CAAA;AAAA,MACxE,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,KAAA,EAA8B;AACtD,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA,EAAG;AAClC,IAAA,MAAM,WAAW,KAAA,CAAM,IAAA,CAAK,KAAK,OAAA,CAAQ,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,MACjD,CAAC,CAAA,KACC,CAAC,CAAA,CAAE,UACH,CAAC,CAAA,CAAE,MAAA,KACF,CAAA,CAAE,OAAO,MAAA,KAAW,CAAA,IAAK,CAAA,CAAE,MAAA,CAAO,SAAS,KAAK,CAAA;AAAA,KACrD;AACA,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAE3B,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,KAAK,IAAA,CAAK,WAAA,CAAY,CAAA,EAAG,KAAK,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,CACZ,MAAA,EACA,KAAA,EACe;AACf,IAAA,IAAI,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,MAAA,EAAQ;AACpC,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,WAAW,CAAA;AAElD,IAAA,MAAM,UAAW,MAAA,CAAe,SAAA;AAChC,IAAA,MAAM,iBAAiB,OAAA,IAAW,CAAA;AAClC,IAAA,IAAI,kBAAkB,WAAA,EAAa;AACnC,IAAC,MAAA,CAAe,YAAY,cAAA,GAAiB,CAAA;AAE7C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AAC/B,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,IAAA,CAAK,UAAA,CAAW,MAAA,EAAQ,IAAI,CAAA;AAAA,IACpC,CAAA,SAAE;AACA,MAAC,MAAA,CAAe,SAAA,GAAc,MAAA,CAAe,SAAA,GAAuB,CAAA;AAEpE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAK,CAAA,OAAQ,IAAA,CAAK,WAAA,CAAY,QAAQ,KAAK,CAAA;AAAA,WAAA,IACnD,OAAO,QAAA,EAAU,MAAA,EAAQ,MAAM,MAAA,CAAO,SAAS,MAAA,EAAO;AAAA,IACjE;AAAA,EACF;AAAA,EAEQ,QAAQ,KAAA,EAAiC;AAC/C,IAAA,MAAM,MAAM,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,KAAK,EAAC;AAC5C,IAAA,MAAM,UAAA,GAAa,GAAA,CAChB,GAAA,CAAI,CAAC,EAAA,KAAO,KAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC,CAAA,CACjC,MAAA,CAAO,CAAC,CAAA,KAAsB,OAAA,CAAQ,CAAC,CAAC,CAAA,CACxC,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,CACpC,IAAA;AAAA,MACC,CAAC,CAAA,EAAG,CAAA,KACF,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA,IACf,CAAA,CAAE,SAAA,CAAU,OAAA,EAAQ,GAAI,CAAA,CAAE,UAAU,OAAA;AAAQ,KAChD;AACF,IAAA,OAAO,UAAA,CAAW,CAAC,CAAA,IAAK,IAAA;AAAA,EAC1B;AAAA,EAEA,MAAc,UAAA,CACZ,MAAA,EACA,GAAA,EACe;AACf,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA,EAAG;AACpC,MAAA,GAAA,CAAI,MAAA,GAAS,QAAA;AACb,MAAA;AAAA,IACF;AAEA,IAAA,GAAA,CAAI,MAAA,GAAS,QAAA;AACb,IAAA,GAAA,CAAI,SAAA,uBAAgB,IAAA,EAAK;AACzB,IAAA,GAAA,CAAI,YAAA,IAAgB,CAAA;AACpB,IAAA,GAAA,CAAI,KAAK,IAAA,CAAK;AAAA,MACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,IAAI,OAAO,QAAA,EAAU,QAAA;AACnB,MAAA,MAAM,MAAA,CAAO,SAAS,QAAA,CAAS,EAAE,KAAK,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA,EAAG,CAAA;AAElE,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AAEvB,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,KAAK,cAAA,CAAe,GAAA,CAAI,IAAI,KAAK,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA;AACnE,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,UACzB,IAAA,EAAM,qBAAA;AAAA,UACN,SAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,IAAI,CAAA,+BAAA,EAAkC,IAAI,KAAK,CAAA,EAAA;AAAA,SACrE,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,MAAM,WAAW,OAAA,CAAQ;AAAA,UACvB,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,SAAS,EAAC;AAAA,UACV,GAAA,EAAK;AAAA,YACH,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,MAAM,GAAA,CAAI,IAAA;AAAA,YACV,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,cAAc,GAAA,CAAI,YAAA;AAAA,YAClB,UAAU,GAAA,CAAI,QAAA;AAAA,YACd,cAAA,EAAgB,OAAO,QAAA,EAAkB,OAAA,KAAqB;AAC5D,cAAA,GAAA,CAAI,QAAA,GAAW,QAAA;AACf,cAAA,IAAI,OAAA,EAAS;AACX,gBAAA,GAAA,CAAI,KAAK,IAAA,CAAK;AAAA,kBACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,kBACpB,KAAA,EAAO,MAAA;AAAA,kBACP;AAAA,iBACD,CAAA;AAAA,cACH;AACA,cAAA,MAAM,WAAW,UAAA,GAAa;AAAA,gBAC5B,OAAO,GAAA,CAAI,KAAA;AAAA,gBACX,SAAS,EAAC;AAAA,gBACV,GAAA,EAAK;AAAA,kBACH,IAAI,GAAA,CAAI,EAAA;AAAA,kBACR,MAAM,GAAA,CAAI,IAAA;AAAA,kBACV,OAAO,GAAA,CAAI,KAAA;AAAA,kBACX,cAAc,GAAA,CAAI,YAAA;AAAA,kBAClB,UAAU,GAAA,CAAI;AAAA,iBAChB;AAAA,gBACA,OAAO,GAAA,CAAI,KAAA;AAAA,gBACX,QAAA;AAAA,gBACA;AAAA,eACM,CAAA;AAAA,YACV;AAAA,WACF;AAAA,UACA,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,WAAW,GAAA,CAAI;AAAA,SACT,CAAA;AAAA,MACV;AAEA,MAAA,MAAM,cAAA,GAAiB,OAAO,QAAA,EAAkB,OAAA,KAAqB;AACnE,QAAA,GAAA,CAAI,QAAA,GAAW,QAAA;AACf,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,GAAA,CAAI,KAAK,IAAA,CAAK;AAAA,YACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,YACpB,KAAA,EAAO,MAAA;AAAA,YACP;AAAA,WACD,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,WAAW,UAAA,GAAa;AAAA,UAC5B,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,SAAS,EAAC;AAAA,UACV,GAAA,EAAK;AAAA,YACH,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,MAAM,GAAA,CAAI,IAAA;AAAA,YACV,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,cAAc,GAAA,CAAI,YAAA;AAAA,YAClB,UAAU,GAAA,CAAI,QAAA;AAAA,YACd;AAAA,WACF;AAAA,UACA,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,QAAA;AAAA,UACA;AAAA,SACM,CAAA;AAAA,MACV,CAAA;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ;AAAA,QACtC,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,SAAS,EAAC;AAAA,QACV,GAAA,EAAK;AAAA,UACH,IAAI,GAAA,CAAI,EAAA;AAAA,UACR,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,cAAc,GAAA,CAAI,YAAA;AAAA,UAClB,UAAU,GAAA,CAAI,QAAA;AAAA,UACd;AAAA,SACF;AAAA,QACA,OAAO,GAAA,CAAI;AAAA,OACL,CAAA;AAER,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA;AAC9B,MAAA,GAAA,CAAI,MAAA,GAAS,WAAA;AACb,MAAA,GAAA,CAAI,WAAA,uBAAkB,IAAA,EAAK;AAC3B,MAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AACb,MAAA,GAAA,CAAI,QAAA,GAAW,GAAA;AACf,MAAA,GAAA,CAAI,KAAK,IAAA,CAAK;AAAA,QACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,QACpB,KAAA,EAAO,MAAA;AAAA,QACP,OAAA,EAAS,oBAAoB,QAAQ,CAAA,EAAA;AAAA,OACtC,CAAA;AAED,MAAA,MAAA,CAAO,QAAQ,SAAA,IAAa,CAAA;AAC5B,MAAA,MAAA,CAAO,QAAQ,aAAA,IAAiB,QAAA;AAEhC,MAAA,IAAI,WAAW,SAAA,EAAW;AACxB,QAAA,MAAM,WAAW,SAAA,CAAU;AAAA,UACzB,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,SAAS,EAAC;AAAA,UACV,GAAA,EAAK;AAAA,YACH,IAAI,GAAA,CAAI,EAAA;AAAA,YACR,MAAM,GAAA,CAAI,IAAA;AAAA,YACV,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,cAAc,GAAA,CAAI,YAAA;AAAA,YAClB,UAAU,GAAA,CAAI,QAAA;AAAA,YACd;AAAA,WACF;AAAA,UACA,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,MAAA;AAAA,UACA;AAAA,SACM,CAAA;AAAA,MACV;AAEA,MAAA,IAAI,OAAO,QAAA,EAAU,SAAA;AACnB,QAAA,MAAM,MAAA,CAAO,SAAS,SAAA,CAAU;AAAA,UAC9B,GAAA,EAAK,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AAAA,UAC5B;AAAA,SACD,CAAA;AAAA,IACL,SAAS,KAAA,EAAY;AAEnB,MAAA,GAAA,CAAI,KAAA,GAAQ,KAAA,EAAO,OAAA,IAAW,MAAA,CAAO,KAAK,CAAA;AAC1C,MAAA,GAAA,CAAI,KAAK,IAAA,CAAK;AAAA,QACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,QACpB,KAAA,EAAO,OAAA;AAAA,QACP,OAAA,EAAS,IAAI,KAAA,IAAS;AAAA,OACvB,CAAA;AAED,MAAA,MAAM,cAAA,GAAiB,GAAA,CAAI,YAAA,IAAgB,GAAA,CAAI,WAAA;AAC/C,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,GAAA,CAAI,MAAA,GAAS,QAAA;AACb,QAAA,GAAA,CAAI,WAAA,uBAAkB,IAAA,EAAK;AAC3B,QAAA,MAAA,CAAO,QAAQ,MAAA,IAAU,CAAA;AAEzB,QAAA,MAAM,UAAA,GAAa,KAAK,cAAA,CAAe,GAAA,CAAI,IAAI,KAAK,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA;AACnE,QAAA,IAAI,YAAY,SAAA,EAAW;AACzB,UAAA,MAAM,WAAW,SAAA,CAAU;AAAA,YACzB,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,SAAS,EAAC;AAAA,YACV,GAAA,EAAK;AAAA,cACH,IAAI,GAAA,CAAI,EAAA;AAAA,cACR,MAAM,GAAA,CAAI,IAAA;AAAA,cACV,OAAO,GAAA,CAAI,KAAA;AAAA,cACX,cAAc,GAAA,CAAI,YAAA;AAAA,cAClB,UAAU,GAAA,CAAI,QAAA;AAAA,cACd,gBAAgB,YAAY;AAAA,aAC9B;AAAA,YACA,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,KAAA;AAAA,YACA,cAAA,EAAgB;AAAA,WACV,CAAA;AAAA,QACV;AAEA,QAAA,IAAI,OAAO,QAAA,EAAU,SAAA;AACnB,UAAA,MAAM,MAAA,CAAO,SAAS,SAAA,CAAU;AAAA,YAC9B,GAAA,EAAK,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AAAA,YAC5B;AAAA,WACD,CAAA;AAAA,MACL,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,MAAA,GAAS,SAAA;AACb,QAAA,KAAK,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACF","file":"mock.mjs","sourcesContent":["/**\n * Generates consistent identifiers for jobs, workers, and schedules.\n */\nexport class IgniterJobsIdGenerator {\n /**\n * Generates a unique identifier with a prefix.\n *\n * @example\n * ```typescript\n * const jobId = IgniterJobsIdGenerator.generate('job')\n * ```\n */\n public static generate(prefix: string): string {\n const now = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${prefix}_${now}_${random}`\n }\n}\n","import { IgniterError } from \"@igniter-js/common\";\n\n/**\n * Canonical error codes for `@igniter-js/jobs`.\n */\nexport const IGNITER_JOBS_ERROR_CODES = {\n JOBS_ADAPTER_REQUIRED: 'JOBS_ADAPTER_REQUIRED',\n JOBS_SERVICE_REQUIRED: 'JOBS_SERVICE_REQUIRED',\n JOBS_CONTEXT_REQUIRED: 'JOBS_CONTEXT_REQUIRED',\n JOBS_CONFIGURATION_INVALID: 'JOBS_CONFIGURATION_INVALID',\n JOBS_QUEUE_NOT_FOUND: 'JOBS_QUEUE_NOT_FOUND',\n JOBS_QUEUE_DUPLICATE: 'JOBS_QUEUE_DUPLICATE',\n JOBS_QUEUE_OPERATION_FAILED: 'JOBS_QUEUE_OPERATION_FAILED',\n JOBS_INVALID_DEFINITION: 'JOBS_INVALID_DEFINITION',\n JOBS_HANDLER_REQUIRED: 'JOBS_HANDLER_REQUIRED',\n JOBS_DUPLICATE_JOB: 'JOBS_DUPLICATE_JOB',\n JOBS_NOT_FOUND: 'JOBS_NOT_FOUND',\n JOBS_NOT_REGISTERED: 'JOBS_NOT_REGISTERED',\n JOBS_EXECUTION_FAILED: 'JOBS_EXECUTION_FAILED',\n JOBS_TIMEOUT: 'JOBS_TIMEOUT',\n JOBS_CONTEXT_FACTORY_FAILED: 'JOBS_CONTEXT_FACTORY_FAILED',\n JOBS_VALIDATION_FAILED: 'JOBS_VALIDATION_FAILED',\n JOBS_INVALID_INPUT: 'JOBS_INVALID_INPUT',\n JOBS_INVALID_CRON: 'JOBS_INVALID_CRON',\n JOBS_INVALID_SCHEDULE: 'JOBS_INVALID_SCHEDULE',\n JOBS_SCOPE_ALREADY_DEFINED: 'JOBS_SCOPE_ALREADY_DEFINED',\n JOBS_WORKER_FAILED: 'JOBS_WORKER_FAILED',\n JOBS_ADAPTER_ERROR: 'JOBS_ADAPTER_ERROR',\n JOBS_ADAPTER_CONNECTION_FAILED: 'JOBS_ADAPTER_CONNECTION_FAILED',\n JOBS_SUBSCRIBE_FAILED: 'JOBS_SUBSCRIBE_FAILED',\n} as const\n\nexport type IgniterJobsErrorCode = keyof typeof IGNITER_JOBS_ERROR_CODES\n\nexport interface IgniterJobsErrorOptions {\n /** Error code scoped to Igniter Jobs. */\n code: IgniterJobsErrorCode\n /** Human-readable message. */\n message: string\n /** HTTP-like status code hint (default: 500). */\n statusCode?: number\n /** Optional structured details for debugging and clients. */\n details?: unknown\n /** Optional metadata for logs and tracing. */\n metadata?: Record<string, unknown>\n /** Optional causer tag used by some Igniter tooling. */\n causer?: string\n /** Underlying cause for debugging (optional). */\n cause?: Error\n /** Optional logger passthrough to align with other Igniter errors. */\n logger?: any\n}\n\n/**\n * Typed error class for the Jobs package.\n *\n * @example\n * ```typescript\n * throw new IgniterJobsError({\n * code: 'JOBS_INVALID_INPUT',\n * message: 'Input payload failed validation',\n * })\n * ```\n */\nexport class IgniterJobsError extends IgniterError {\n constructor(options: IgniterJobsErrorOptions) {\n super(options)\n }\n}\n","/**\n * @fileoverview In-memory adapter for @igniter-js/jobs (tests/dev only)\n * @module @igniter-js/jobs/adapters/memory\n */\n\nimport type {\n IgniterJobsAdapterJobStreamReadParams,\n IgniterJobsAdapterJobStreamSubscribeParams,\n IgniterJobsAdapterJobStreamWriteParams,\n IgniterCronDefinition,\n IgniterJobCounts,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n} from \"../types\";\nimport type {\n IgniterJobsJobStreamEvent,\n IgniterJobsJobStreamReadResult,\n} from \"../types/stream\";\nimport { IgniterJobsIdGenerator } from \"../utils/id-generator\";\nimport { IgniterJobsError } from \"../errors\";\n\ntype MemoryJob = {\n id: string;\n name: string;\n queue: string;\n input: unknown;\n status: IgniterJobStatus;\n progress: number;\n attemptsMade: number;\n maxAttempts: number;\n priority: number;\n createdAt: Date;\n startedAt?: Date;\n completedAt?: Date;\n result?: unknown;\n error?: string;\n metadata?: Record<string, unknown>;\n scope?: unknown;\n logs: IgniterJobsJobLog[];\n};\n\ntype MemoryWorkerState = {\n id: string;\n queues: string[];\n concurrency: number;\n paused: boolean;\n closed: boolean;\n startedAt: Date;\n metrics: {\n processed: number;\n failed: number;\n totalDuration: number;\n };\n handlers?: IgniterJobsWorkerBuilderConfig[\"handlers\"];\n};\n\ntype MemoryStreamRecord = {\n events: IgniterJobsJobStreamEvent<string, unknown>[];\n nextId: number;\n};\n\n/**\n * Lightweight in-memory adapter used for unit tests and local development.\n *\n * This adapter is not suitable for production use.\n */\nexport class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {\n public readonly client = {\n type: \"memory\" as const,\n };\n\n private readonly jobsById = new Map<string, MemoryJob>();\n private readonly jobsByQueue = new Map<string, string[]>();\n private readonly registeredJobs = new Map<\n string,\n Map<string, IgniterJobDefinition<any, any, any>>\n >();\n private readonly registeredCrons = new Map<\n string,\n Map<string, IgniterCronDefinition<any, any>>\n >();\n\n private readonly workers = new Map<string, MemoryWorkerState>();\n private readonly streamRecords = new Map<string, MemoryStreamRecord>();\n private readonly streamSubscribers = new Map<\n string,\n Set<\n (\n event: IgniterJobsJobStreamEvent<string, unknown>,\n ) => void | Promise<void>\n >\n >();\n\n private readonly subscribers = new Map<\n string,\n Set<IgniterJobsEventHandler>\n >();\n\n public readonly queues: IgniterJobsQueueManager = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) => {\n const statuses = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n const results = await this.searchJobs({\n queue: name,\n status: statuses,\n limit,\n offset,\n } as any);\n return results;\n },\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) => {\n // Queue-level pause is stored as a special marker job list state.\n // For memory adapter, we model it by a metadata flag in queue info.\n const info = await this.getQueueInfo(name);\n return info?.isPaused ?? false;\n },\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n };\n\n private readonly pausedQueues = new Set<string>();\n\n public static create(): IgniterJobsAdapter {\n return new IgniterJobsMemoryAdapter();\n }\n\n public registerJob(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>,\n ): void {\n const queueJobs =\n this.registeredJobs.get(queueName) ??\n new Map<string, IgniterJobDefinition<any, any, any>>();\n if (queueJobs.has(jobName)) {\n throw new IgniterJobsError({\n code: \"JOBS_DUPLICATE_JOB\",\n message: `Job \"${jobName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueJobs.set(jobName, definition);\n this.registeredJobs.set(queueName, queueJobs);\n }\n\n public registerCron(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>,\n ): void {\n const queueCrons =\n this.registeredCrons.get(queueName) ??\n new Map<string, IgniterCronDefinition<any, any>>();\n if (queueCrons.has(cronName)) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_CRON\",\n message: `Cron \"${cronName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueCrons.set(cronName, definition);\n this.registeredCrons.set(queueName, queueCrons);\n }\n\n public async dispatch(\n params: IgniterJobsAdapterDispatchParams,\n ): Promise<string> {\n const jobId = params.jobId ?? IgniterJobsIdGenerator.generate(\"job\");\n const maxAttempts = params.attempts ?? 1;\n\n const metadata = params.metadata ?? {};\n\n const job: MemoryJob = {\n id: jobId,\n name: params.jobName,\n queue: params.queue,\n input: params.input,\n status: this.pausedQueues.has(params.queue)\n ? \"paused\"\n : params.delay && params.delay > 0\n ? \"delayed\"\n : \"waiting\",\n progress: 0,\n attemptsMade: 0,\n maxAttempts,\n priority: params.priority ?? 0,\n createdAt: new Date(),\n metadata: metadata as Record<string, unknown>,\n scope: params.scope,\n logs: [],\n };\n\n this.jobsById.set(jobId, job);\n const queueList = this.jobsByQueue.get(params.queue) ?? [];\n queueList.push(jobId);\n this.jobsByQueue.set(params.queue, queueList);\n\n if (params.delay && params.delay > 0) {\n setTimeout(() => {\n const stored = this.jobsById.get(jobId);\n if (!stored) return;\n if (!this.pausedQueues.has(params.queue)) stored.status = \"waiting\";\n void this.kickWorkers(params.queue);\n }, params.delay);\n return jobId;\n }\n\n void this.kickWorkers(params.queue);\n return jobId;\n }\n\n public async schedule(\n params: IgniterJobsAdapterScheduleParams,\n ): Promise<string> {\n if (params.at) {\n const delay = params.at.getTime() - Date.now();\n if (delay <= 0) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_SCHEDULE\",\n message: \"Scheduled time must be in the future.\",\n });\n }\n return this.dispatch({ ...params, delay });\n }\n if (params.cron || params.every) {\n // Memory adapter does not implement a cron engine. It stores the job as delayed and relies on tests\n // to invoke dispatch manually if needed.\n return this.dispatch({ ...params, delay: params.delay ?? 0 });\n }\n return this.dispatch(params);\n }\n\n public async getJob(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobSearchResult | null> {\n const job = this.jobsById.get(jobId);\n if (!job) return null;\n if (queue && job.queue !== queue) return null;\n return this.toSearchResult(job);\n }\n\n public async getJobState(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobStatus | null> {\n const job = this.jobsById.get(jobId);\n if (!job) return null;\n if (queue && job.queue !== queue) return null;\n return job.status;\n }\n\n public async getJobLogs(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobsJobLog[]> {\n const job = this.jobsById.get(jobId);\n if (!job) return [];\n if (queue && job.queue !== queue) return [];\n return job.logs;\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n const job = this.jobsById.get(jobId);\n if (!job) return 0;\n if (queue && job.queue !== queue) return 0;\n return job.progress;\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n job.status = \"waiting\";\n job.error = undefined;\n job.completedAt = undefined;\n job.progress = 0;\n void this.kickWorkers(job.queue);\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) return;\n if (queue && job.queue !== queue) return;\n this.jobsById.delete(jobId);\n const list = this.jobsByQueue.get(job.queue);\n if (list)\n this.jobsByQueue.set(\n job.queue,\n list.filter((id) => id !== jobId),\n );\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n if (job.status === \"delayed\" || job.status === \"paused\") {\n job.status = this.pausedQueues.has(job.queue) ? \"paused\" : \"waiting\";\n void this.kickWorkers(job.queue);\n }\n }\n\n public async moveJobToFailed(\n jobId: string,\n reason: string,\n queue?: string,\n ): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n job.status = \"failed\";\n job.error = reason;\n job.completedAt = new Date();\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.retryJob(id, queue)));\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.removeJob(id, queue)));\n }\n\n public async getQueueInfo(\n queue: string,\n ): Promise<IgniterJobsQueueInfo | null> {\n const counts = await this.getQueueJobCounts(queue);\n return {\n name: queue,\n isPaused: this.pausedQueues.has(queue),\n jobCounts: counts,\n };\n }\n\n public async getQueueJobCounts(queue: string): Promise<IgniterJobCounts> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n const counts: IgniterJobCounts = {\n waiting: 0,\n active: 0,\n completed: 0,\n failed: 0,\n delayed: 0,\n paused: 0,\n };\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status in counts) {\n (counts as any)[job.status]++;\n }\n }\n return counts;\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n const queues = Array.from(\n new Set([\n ...this.jobsByQueue.keys(),\n ...this.registeredJobs.keys(),\n ...this.registeredCrons.keys(),\n ]),\n );\n const result: IgniterJobsQueueInfo[] = [];\n for (const q of queues) {\n result.push((await this.getQueueInfo(q))!);\n }\n return result;\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n this.pausedQueues.add(queue);\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"waiting\") job.status = \"paused\";\n }\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n this.pausedQueues.delete(queue);\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"paused\") job.status = \"waiting\";\n }\n void this.kickWorkers(queue);\n }\n\n public async drainQueue(queue: string): Promise<number> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n let removed = 0;\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"waiting\" || job.status === \"paused\") {\n this.jobsById.delete(id);\n removed++;\n }\n }\n this.jobsByQueue.set(\n queue,\n jobIds.filter((id) => this.jobsById.has(id)),\n );\n return removed;\n }\n\n public async cleanQueue(\n queue: string,\n options: IgniterJobsQueueCleanOptions,\n ): Promise<number> {\n const statuses = Array.isArray(options.status)\n ? options.status\n : [options.status];\n const olderThan = options.olderThan ?? 0;\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n const now = Date.now();\n let cleaned = 0;\n\n for (const id of [...jobIds]) {\n if (cleaned >= limit) break;\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (!statuses.includes(job.status)) continue;\n const ageMs = now - job.createdAt.getTime();\n if (ageMs < olderThan) continue;\n this.jobsById.delete(id);\n cleaned++;\n }\n\n this.jobsByQueue.set(\n queue,\n jobIds.filter((id) => this.jobsById.has(id)),\n );\n return cleaned;\n }\n\n public async obliterateQueue(\n queue: string,\n options?: { force?: boolean },\n ): Promise<void> {\n void options;\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) this.jobsById.delete(id);\n this.jobsByQueue.delete(queue);\n this.registeredJobs.delete(queue);\n this.registeredCrons.delete(queue);\n this.pausedQueues.delete(queue);\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n let retried = 0;\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"failed\") {\n await this.retryJob(id, queue);\n retried++;\n }\n }\n return retried;\n }\n\n public async searchJobs(filter: any): Promise<IgniterJobSearchResult[]> {\n const queue = filter?.queue as string | undefined;\n const statuses: IgniterJobStatus[] | undefined = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n const all = Array.from(this.jobsById.values())\n .filter((j) => (queue ? j.queue === queue : true))\n .filter((j) => (statuses ? statuses.includes(j.status) : true))\n .sort(\n (a, b) =>\n b.priority - a.priority ||\n a.createdAt.getTime() - b.createdAt.getTime(),\n );\n\n return all.slice(offset, offset + limit).map((j) => this.toSearchResult(j));\n }\n\n public async searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]> {\n const name = filter?.name as string | undefined;\n const isPaused = filter?.isPaused as boolean | undefined;\n const all = await this.listQueues();\n return all\n .filter((q) => (name ? q.name.includes(name) : true))\n .filter((q) =>\n typeof isPaused === \"boolean\" ? q.isPaused === isPaused : true,\n );\n }\n\n public async searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter?.queue as string | undefined;\n const isRunning = filter?.isRunning as boolean | undefined;\n return Array.from(this.workers.values())\n .filter((w) => (queue ? w.queues.includes(queue) : true))\n .filter((w) =>\n typeof isRunning === \"boolean\"\n ? isRunning\n ? !w.closed\n : w.closed\n : true,\n )\n .map((w) => this.toWorkerHandle(w));\n }\n\n public async createWorker(\n config: IgniterJobsWorkerBuilderConfig,\n ): Promise<IgniterJobsWorkerHandle> {\n const workerId = IgniterJobsIdGenerator.generate(\"worker\");\n const state: MemoryWorkerState = {\n id: workerId,\n queues: config.queues ?? [],\n concurrency: config.concurrency ?? 1,\n paused: false,\n closed: false,\n startedAt: new Date(),\n metrics: { processed: 0, failed: 0, totalDuration: 0 },\n handlers: config.handlers,\n };\n this.workers.set(workerId, state);\n\n // Kick initial processing.\n for (const q of state.queues) void this.kickWorkers(q);\n\n return this.toWorkerHandle(state);\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n const out = new Map<string, IgniterJobsWorkerHandle>();\n for (const [id, state] of this.workers)\n out.set(id, this.toWorkerHandle(state));\n return out;\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n const handlers = this.subscribers.get(channel);\n if (!handlers) return;\n await Promise.all(Array.from(handlers).map(async (h) => h(payload as any)));\n }\n\n public async subscribeEvent(\n channel: string,\n handler: IgniterJobsEventHandler,\n ): Promise<() => Promise<void>> {\n const set =\n this.subscribers.get(channel) ?? new Set<IgniterJobsEventHandler>();\n set.add(handler);\n this.subscribers.set(channel, set);\n\n return async () => {\n const current = this.subscribers.get(channel);\n if (!current) return;\n current.delete(handler);\n if (current.size === 0) this.subscribers.delete(channel);\n };\n }\n\n public async writeJobStreamEvent(\n params: IgniterJobsAdapterJobStreamWriteParams,\n ): Promise<string> {\n const key = this.getStreamKey(params.queue, params.jobId);\n const record = this.streamRecords.get(key) ?? { events: [], nextId: 1 };\n const id = String(record.nextId++);\n const event: IgniterJobsJobStreamEvent<string, unknown> = {\n ...params.event,\n id,\n };\n\n if (params.persistence?.enabled) {\n record.events.push(event);\n const maxEvents = params.persistence.maxEvents;\n if (\n typeof maxEvents === \"number\" &&\n maxEvents > 0 &&\n record.events.length > maxEvents\n ) {\n record.events.splice(0, record.events.length - maxEvents);\n }\n this.streamRecords.set(key, record);\n } else if (!this.streamRecords.has(key)) {\n this.streamRecords.set(key, record);\n }\n\n const handlers = this.streamSubscribers.get(key);\n if (handlers?.size) {\n await Promise.all(\n Array.from(handlers).map(async (handler) => handler(event)),\n );\n }\n\n return id;\n }\n\n public async readJobStream(\n params: IgniterJobsAdapterJobStreamReadParams,\n ): Promise<\n IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>\n > {\n const key = this.getStreamKey(params.queue, params.jobId);\n const record = this.streamRecords.get(key);\n if (!record) {\n return { items: [], nextCursor: undefined, hasMore: false };\n }\n\n const after = params.after ? Number(params.after) : undefined;\n const limit = params.limit ?? 100;\n const filtered = record.events.filter((event) =>\n typeof after === \"number\" ? Number(event.id) > after : true,\n );\n const items = filtered.slice(0, limit);\n const hasMore = filtered.length > items.length;\n\n return {\n items,\n nextCursor: items.at(-1)?.id,\n hasMore,\n };\n }\n\n public async subscribeJobStream(\n params: IgniterJobsAdapterJobStreamSubscribeParams,\n ): Promise<() => Promise<void>> {\n const key = this.getStreamKey(params.queue, params.jobId);\n const set = this.streamSubscribers.get(key) ?? new Set();\n set.add(params.handler);\n this.streamSubscribers.set(key, set);\n\n return async () => {\n const current = this.streamSubscribers.get(key);\n if (!current) return;\n current.delete(params.handler);\n if (current.size === 0) this.streamSubscribers.delete(key);\n };\n }\n\n public async shutdown(): Promise<void> {\n this.workers.clear();\n this.subscribers.clear();\n this.streamSubscribers.clear();\n this.streamRecords.clear();\n }\n\n private toSearchResult(job: MemoryJob): IgniterJobSearchResult {\n return {\n id: job.id,\n name: job.name,\n queue: job.queue,\n status: job.status,\n input: job.input,\n result: job.result,\n error: job.error,\n progress: job.progress,\n attemptsMade: job.attemptsMade,\n priority: job.priority,\n createdAt: job.createdAt,\n startedAt: job.startedAt,\n completedAt: job.completedAt,\n metadata: job.metadata,\n scope: job.scope as any,\n };\n }\n\n private getStreamKey(queue: string, jobId: string): string {\n return `${queue}:${jobId}`;\n }\n\n private toWorkerHandle(worker: MemoryWorkerState): IgniterJobsWorkerHandle {\n return {\n id: worker.id,\n queues: worker.queues,\n pause: async () => {\n worker.paused = true;\n },\n resume: async () => {\n worker.paused = false;\n for (const q of worker.queues) void this.kickWorkers(q);\n },\n close: async () => {\n worker.closed = true;\n },\n isRunning: () => !worker.closed && !worker.paused,\n isPaused: () => worker.paused,\n isClosed: () => worker.closed,\n getMetrics: async () => this.toWorkerMetrics(worker),\n };\n }\n\n private toWorkerMetrics(worker: MemoryWorkerState): IgniterJobsWorkerMetrics {\n const uptime = Date.now() - worker.startedAt.getTime();\n const processed = worker.metrics.processed;\n return {\n processed,\n failed: worker.metrics.failed,\n avgDuration: processed > 0 ? worker.metrics.totalDuration / processed : 0,\n concurrency: worker.concurrency,\n uptime,\n };\n }\n\n private async kickWorkers(queue: string): Promise<void> {\n if (this.pausedQueues.has(queue)) return;\n const relevant = Array.from(this.workers.values()).filter(\n (w) =>\n !w.closed &&\n !w.paused &&\n (w.queues.length === 0 || w.queues.includes(queue)),\n );\n if (relevant.length === 0) return;\n\n for (const w of relevant) {\n void this.processLoop(w, queue);\n }\n }\n\n private async processLoop(\n worker: MemoryWorkerState,\n queue: string,\n ): Promise<void> {\n if (worker.closed || worker.paused) return;\n const concurrency = Math.max(1, worker.concurrency);\n\n const running = (worker as any).__running as number | undefined;\n const currentRunning = running ?? 0;\n if (currentRunning >= concurrency) return;\n (worker as any).__running = currentRunning + 1;\n\n try {\n const next = this.nextJob(queue);\n if (!next) return;\n await this.processJob(worker, next);\n } finally {\n (worker as any).__running = ((worker as any).__running as number) - 1;\n // Continue draining if more work exists.\n if (this.nextJob(queue)) void this.processLoop(worker, queue);\n else if (worker.handlers?.onIdle) await worker.handlers.onIdle();\n }\n }\n\n private nextJob(queue: string): MemoryJob | null {\n const ids = this.jobsByQueue.get(queue) ?? [];\n const candidates = ids\n .map((id) => this.jobsById.get(id))\n .filter((j): j is MemoryJob => Boolean(j))\n .filter((j) => j.status === \"waiting\")\n .sort(\n (a, b) =>\n b.priority - a.priority ||\n a.createdAt.getTime() - b.createdAt.getTime(),\n );\n return candidates[0] ?? null;\n }\n\n private async processJob(\n worker: MemoryWorkerState,\n job: MemoryJob,\n ): Promise<void> {\n if (this.pausedQueues.has(job.queue)) {\n job.status = \"paused\";\n return;\n }\n\n job.status = \"active\";\n job.startedAt = new Date();\n job.attemptsMade += 1;\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message: \"Job started\",\n });\n\n if (worker.handlers?.onActive)\n await worker.handlers.onActive({ job: this.toSearchResult(job) });\n\n const start = Date.now();\n\n try {\n const definition = this.registeredJobs.get(job.queue)?.get(job.name);\n if (!definition) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_REGISTERED\",\n message: `Job \"${job.name}\" is not registered for queue \"${job.queue}\".`,\n });\n }\n\n if (definition.onStart) {\n await definition.onStart({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n updateProgress: async (progress: number, message?: string) => {\n job.progress = progress;\n if (message) {\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message,\n });\n }\n await definition.onProgress?.({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n },\n scope: job.scope as any,\n progress,\n message,\n } as any);\n },\n },\n scope: job.scope as any,\n startedAt: job.startedAt,\n } as any);\n }\n\n const updateProgress = async (progress: number, message?: string) => {\n job.progress = progress;\n if (message) {\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message,\n });\n }\n\n await definition.onProgress?.({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n updateProgress,\n },\n scope: job.scope as any,\n progress,\n message,\n } as any);\n };\n\n const result = await definition.handler({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n updateProgress,\n },\n scope: job.scope as any,\n } as any);\n\n const duration = Date.now() - start;\n job.status = \"completed\";\n job.completedAt = new Date();\n job.result = result;\n job.progress = 100;\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message: `Job completed in ${duration}ms`,\n });\n\n worker.metrics.processed += 1;\n worker.metrics.totalDuration += duration;\n\n if (definition.onSuccess) {\n await definition.onSuccess({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n updateProgress,\n },\n scope: job.scope as any,\n result,\n duration,\n } as any);\n }\n\n if (worker.handlers?.onSuccess)\n await worker.handlers.onSuccess({\n job: this.toSearchResult(job),\n result,\n });\n } catch (error: any) {\n const duration = Date.now() - start;\n job.error = error?.message ?? String(error);\n job.logs.push({\n timestamp: new Date(),\n level: \"error\",\n message: job.error ?? \"Unknown error\",\n });\n\n const isFinalAttempt = job.attemptsMade >= job.maxAttempts;\n if (isFinalAttempt) {\n job.status = \"failed\";\n job.completedAt = new Date();\n worker.metrics.failed += 1;\n\n const definition = this.registeredJobs.get(job.queue)?.get(job.name);\n if (definition?.onFailure) {\n await definition.onFailure({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n updateProgress: async () => undefined,\n },\n scope: job.scope as any,\n error,\n isFinalAttempt: true,\n } as any);\n }\n\n if (worker.handlers?.onFailure)\n await worker.handlers.onFailure({\n job: this.toSearchResult(job),\n error,\n });\n } else {\n job.status = \"waiting\";\n void this.kickWorkers(job.queue);\n }\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { I as IgniterJobsAdapter, a as IgniterJobsQueueManager, b as IgniterJobsBullMQAdapterOptions, c as IgniterJobDefinition, d as IgniterCronDefinition, e as IgniterJobsAdapterDispatchParams, f as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, h as IgniterJobStatus, i as IgniterJobsJobLog, j as IgniterJobsQueueInfo, k as IgniterJobsQueueCleanOptions, l as IgniterJobsWorkerHandle, m as IgniterJobsWorkerBuilderConfig, n as IgniterJobsEventHandler } from '../adapter-CXZxomI9.mjs';
1
+ import { a as IgniterJobsAdapter, X as IgniterJobsQueueManager, C as IgniterJobsBullMQAdapterOptions, c as IgniterJobDefinition, r as IgniterCronDefinition, x as IgniterJobsAdapterDispatchParams, B as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, Q as IgniterJobsJobLog, h as IgniterJobsQueueInfo, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler, A as IgniterJobsAdapterJobStreamWriteParams, y as IgniterJobsAdapterJobStreamReadParams, V as IgniterJobsJobStreamReadResult, S as IgniterJobsJobStreamEvent, z as IgniterJobsAdapterJobStreamSubscribeParams } from '../adapter-DDyMVche.mjs';
2
2
  import 'ioredis';
3
3
  import '@igniter-js/common';
4
4
 
@@ -52,8 +52,6 @@ declare class IgniterJobsBullMQAdapter implements IgniterJobsAdapter {
52
52
  force?: boolean;
53
53
  }): Promise<void>;
54
54
  retryAllInQueue(queue: string): Promise<number>;
55
- pauseJobType(queue: string, jobName: string): Promise<void>;
56
- resumeJobType(queue: string, jobName: string): Promise<void>;
57
55
  searchJobs(filter: any): Promise<IgniterJobSearchResult[]>;
58
56
  searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]>;
59
57
  searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]>;
@@ -61,10 +59,17 @@ declare class IgniterJobsBullMQAdapter implements IgniterJobsAdapter {
61
59
  getWorkers(): Map<string, IgniterJobsWorkerHandle>;
62
60
  publishEvent(channel: string, payload: unknown): Promise<void>;
63
61
  subscribeEvent(channel: string, handler: IgniterJobsEventHandler): Promise<() => Promise<void>>;
62
+ writeJobStreamEvent(params: IgniterJobsAdapterJobStreamWriteParams): Promise<string>;
63
+ readJobStream(params: IgniterJobsAdapterJobStreamReadParams): Promise<IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>>;
64
+ subscribeJobStream(params: IgniterJobsAdapterJobStreamSubscribeParams): Promise<() => Promise<void>>;
64
65
  shutdown(): Promise<void>;
65
66
  private core;
66
67
  private executor;
67
68
  private toCoreQueueName;
69
+ private getJobStreamChannel;
70
+ private getJobStreamListKey;
71
+ private getJobStreamSequenceKey;
72
+ private parseJobStreamRow;
68
73
  private mapQueueInfo;
69
74
  private fromCoreQueueName;
70
75
  private mapJob;
@@ -1,4 +1,4 @@
1
- import { I as IgniterJobsAdapter, a as IgniterJobsQueueManager, b as IgniterJobsBullMQAdapterOptions, c as IgniterJobDefinition, d as IgniterCronDefinition, e as IgniterJobsAdapterDispatchParams, f as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, h as IgniterJobStatus, i as IgniterJobsJobLog, j as IgniterJobsQueueInfo, k as IgniterJobsQueueCleanOptions, l as IgniterJobsWorkerHandle, m as IgniterJobsWorkerBuilderConfig, n as IgniterJobsEventHandler } from '../adapter-CXZxomI9.js';
1
+ import { a as IgniterJobsAdapter, X as IgniterJobsQueueManager, C as IgniterJobsBullMQAdapterOptions, c as IgniterJobDefinition, r as IgniterCronDefinition, x as IgniterJobsAdapterDispatchParams, B as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, Q as IgniterJobsJobLog, h as IgniterJobsQueueInfo, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler, A as IgniterJobsAdapterJobStreamWriteParams, y as IgniterJobsAdapterJobStreamReadParams, V as IgniterJobsJobStreamReadResult, S as IgniterJobsJobStreamEvent, z as IgniterJobsAdapterJobStreamSubscribeParams } from '../adapter-DDyMVche.js';
2
2
  import 'ioredis';
3
3
  import '@igniter-js/common';
4
4
 
@@ -52,8 +52,6 @@ declare class IgniterJobsBullMQAdapter implements IgniterJobsAdapter {
52
52
  force?: boolean;
53
53
  }): Promise<void>;
54
54
  retryAllInQueue(queue: string): Promise<number>;
55
- pauseJobType(queue: string, jobName: string): Promise<void>;
56
- resumeJobType(queue: string, jobName: string): Promise<void>;
57
55
  searchJobs(filter: any): Promise<IgniterJobSearchResult[]>;
58
56
  searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]>;
59
57
  searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]>;
@@ -61,10 +59,17 @@ declare class IgniterJobsBullMQAdapter implements IgniterJobsAdapter {
61
59
  getWorkers(): Map<string, IgniterJobsWorkerHandle>;
62
60
  publishEvent(channel: string, payload: unknown): Promise<void>;
63
61
  subscribeEvent(channel: string, handler: IgniterJobsEventHandler): Promise<() => Promise<void>>;
62
+ writeJobStreamEvent(params: IgniterJobsAdapterJobStreamWriteParams): Promise<string>;
63
+ readJobStream(params: IgniterJobsAdapterJobStreamReadParams): Promise<IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>>;
64
+ subscribeJobStream(params: IgniterJobsAdapterJobStreamSubscribeParams): Promise<() => Promise<void>>;
64
65
  shutdown(): Promise<void>;
65
66
  private core;
66
67
  private executor;
67
68
  private toCoreQueueName;
69
+ private getJobStreamChannel;
70
+ private getJobStreamListKey;
71
+ private getJobStreamSequenceKey;
72
+ private parseJobStreamRow;
68
73
  private mapQueueInfo;
69
74
  private fromCoreQueueName;
70
75
  private mapJob;