logquill 0.1.1 → 0.2.0
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/README.md +349 -2
- package/dist/index.cjs +1446 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +978 -2
- package/dist/index.d.ts +978 -2
- package/dist/index.mjs +1412 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +53 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAEO,IAAM,OAAA,GAAU","file":"index.mjs","sourcesContent":["// Phase 0 scaffolding placeholder — Logger, levels, formatters, transports,\n// and plugins land in later phases.\nexport const VERSION = \"0.1.0\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/levels.ts","../src/core/records.ts","../src/core/formatter.ts","../src/plugins/context-plugin.ts","../src/plugins/redact-plugin.ts","../src/plugins/sampling-plugin.ts","../src/transports/transport.ts","../src/transports/batching-transport.ts","../src/transports/sql/base-sql-transport.ts","../src/transports/sql/sqlite-transport.ts","../src/transports/sql/postgres-transport.ts","../src/transports/sql/mysql-transport.ts","../src/transports/nosql/mongodb-transport.ts","../src/transports/nosql/dynamodb-transport.ts","../src/transports/nosql/redis-transport.ts","../src/transports/queue/base-queue-transport.ts","../src/transports/queue/kafka-transport.ts","../src/transports/queue/rabbitmq-transport.ts","../src/transports/queue/sqs-transport.ts","../src/transports/queue/pubsub-transport.ts","../src/transports/cloud/cloudwatch-transport.ts","../src/transports/cloud/cloud-logging-transport.ts","../src/transports/cloud/app-insights-transport.ts","../src/transports/cloud/datadog-transport.ts","../src/transports/cloud/elasticsearch-transport.ts","../src/transports/cloud/new-relic-transport.ts","../src/transports/console-transport.ts","../src/transports/file-transport.ts","../src/transports/http-transport.ts","../src/core/logger.ts","../src/index.ts"],"names":["Level"],"mappings":";;;;;AACO,IAAK,KAAA,qBAAAA,MAAAA,KAAL;AACL,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,CAAA,CAAA,GAAR,OAAA;AACA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AACA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,UAAO,EAAA,CAAA,GAAP,MAAA;AACA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,UAAO,EAAA,CAAA,GAAP,MAAA;AACA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AACA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AANU,EAAA,OAAAA,MAAAA;AAAA,CAAA,EAAA,KAAA,IAAA,EAAA;AASZ,IAAM,aAAA,GAAiD;AAAA,EACrD,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO,EAAA;AAAA,EACP,IAAA,EAAM,EAAA;AAAA,EACN,IAAA,EAAM,EAAA;AAAA,EACN,KAAA,EAAO,EAAA;AAAA,EACP,KAAA,EAAO,EAAA;AACT,CAAA;AAMO,SAAS,UAAU,KAAA,EAAsB;AAC9C,EAAA,OAAO,MAAM,KAAK,CAAA;AACpB;AAGO,SAAS,WAAW,KAAA,EAA0B;AACnD,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAA,GAAS,aAAA,CAAc,KAAA,CAAM,WAAA,EAAa,CAAA;AAChD,IAAA,IAAI,WAAW,MAAA,EAAW;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,CAAM,KAAK,CAAA,KAAM,MAAA,EAAW;AAC9B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,KAAA;AACT;;;AC5BO,SAAS,YAAA,GAAuB;AACrC,EAAA,OAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAChC;AAEO,SAAS,aAAa,MAAA,EAKf;AACZ,EAAA,OAAO;AAAA,IACL,WAAW,YAAA,EAAa;AAAA,IACxB,KAAA,EAAO,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA;AAAA,IAC7B,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,MAAM,MAAA,CAAO;AAAA,GACf;AACF;;;ACrBO,IAAM,gBAAN,MAAyC;AAAA,EAC9C,OAAO,MAAA,EAA2B;AAChC,IAAA,OAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAAA,EAC9B;AACF;;;ACLO,IAAM,gBAAN,MAAsC;AAAA,EAClC,OAAA;AAAA,EAET,YAAY,OAAA,EAAkC;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAM,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,GAAG,MAAA,CAAO,IAAA,EAAK,EAAE;AAAA,EAChE;AACF;;;ACdO,IAAM,wBAA2C,CAAC,UAAA,EAAY,OAAA,EAAS,QAAA,EAAU,WAAW,eAAe;AAQ3G,IAAM,eAAN,MAAqC;AAAA,EACzB,IAAA;AAAA,EACR,WAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAA+B,EAAC,EAAG;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,GAAA,CAAA,CAAK,OAAA,CAAQ,IAAA,IAAQ,qBAAA,EAAuB,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAA,EAAa,CAAC,CAAA;AAC3F,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,KAAA;AAAA,EAC5C;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,MAAM,OAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,IAAI,WAAA,EAAa,CAAA,GAAI,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,IACpE;AACA,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAK;AAAA,EAC3B;AACF;;;ACnBO,IAAM,iBAAN,MAAuC;AAAA,EACnC,IAAA;AAAA,EACQ,GAAA;AAAA,EAEjB,WAAA,CAAY,IAAA,EAAc,OAAA,GAAiC,EAAC,EAAG;AAC7D,IAAA,IAAI,IAAA,GAAO,CAAA,IAAK,IAAA,GAAO,CAAA,EAAG;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,MAAA,CAAO,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACrE;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,IAAA,CAAK,MAAA;AAAA,EACjC;AAAA,EAEA,UAAU,MAAA,EAAqC;AAC7C,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA,CAAK,OAAO,MAAA,GAAS,IAAA;AAAA,EAC3C;AACF;;;AChBO,IAAe,YAAf,MAAyB;AAAA,EAC9B,SAAA;AAAA,EAEA,WAAA,CAAY,SAAA,GAAuB,IAAI,aAAA,EAAc,EAAG;AACtD,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA,EAEA,OAAO,MAAA,EAA2B;AAChC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA;AAAA,EACrC;AAAA;AAAA,EAKA,KAAA,GAAc;AAAA,EAAC;AACjB;AAGO,IAAM,mBAAA,GAAN,cAAkC,SAAA,CAAU;AAAA,EACxC,YAAsB,EAAC;AAAA,EACvB,UAAuB,EAAC;AAAA,EACjC,MAAA,GAAS,KAAA;AAAA,EAET,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,SAAS,CAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,EAC1B;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AACF;;;AChBO,IAAe,iBAAA,GAAf,cAAwD,SAAA,CAAU;AAAA,EAC9D,UAAA;AAAA,EACA,QAAA;AAAA,EACD,SAAc,EAAC;AAAA,EACf,WAAA,GAAc,CAAA;AAAA,EAEtB,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,GAAA;AACxC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,GAAA;AAAA,EACtC;AAAA;AAAA,EAGU,MAAA,CAAO,WAAmB,MAAA,EAAsB;AAExD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGU,OAAO,IAAA,EAAiB;AAChC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,CAAE,MAAA;AAAA,EAC9B;AAAA,EAEA,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,EAAW,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,MAAA,IAAU,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA,IAAe,KAAK,QAAA,EAAU;AAC9E,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC5B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,SAAS,EAAC;AACf,IAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AAEnB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACnC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,KAAmB;AAC/B,QAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,IAAA,CAAK,WAAA,CAAY,IAAI,8BAA8B,KAAK,CAAA;AAAA,MAC3E,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AAIF;;;ACjDA,SAAS,UAAA,CAAW,MAA+B,GAAA,EAA4B;AAC7E,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAG,CAAA;AACtB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,IAAA;AAC7C;AAQO,IAAe,gBAAA,GAAf,cAAwC,iBAAA,CAA6B;AAAA,EACjE,SAAA;AAAA,EACA,YAAA;AAAA,EACD,aAAA,GAAgB,KAAA;AAAA,EAExB,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,MAAA;AACtC,IAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,YAAA,IAAgB,KAAA;AAAA,EAC9C;AAAA,EAEmB,MAAA,CAAO,YAAoB,MAAA,EAA8B;AAE1E,IAAA,OAAO;AAAA,MACL,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AAAA,MAChC,KAAA,EAAO,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,OAAO,CAAA;AAAA,MACtC,MAAA,EAAQ,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,QAAQ,CAAA;AAAA,MACxC,YAAA,EAAc,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,cAAc,CAAA;AAAA,MACpD,OAAA,EAAS,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,SAAS;AAAA,KAC5C;AAAA,EACF;AAAA,EAEmB,OAAO,GAAA,EAAwB;AAChD,IAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAA,GAAS,GAAA,CAAI,KAAK,MAAA,GAAS,EAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAA,GAAyB;AACvB,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAyB,UAAU,IAAA,EAA2C;AAC5E,IAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,IAAA,CAAK,aAAA,EAAe;AAG5C,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,MAAA,MAAM,KAAK,WAAA,EAAY;AAAA,IACzB;AACA,IAAA,MAAM,IAAA,CAAK,WAAW,IAAI,CAAA;AAAA,EAC5B;AAOF;;;AC5EO,IAAM,eAAA,GAAN,cAA8B,gBAAA,CAAiB;AAAA,EACnC,cAAA;AAAA,EACA,QAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAkC,EAAC,EAAG;AAChD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,UAAA;AAAA,EACtC;AAAA;AAAA,EAGQ,cAAA,GAA+C;AACrD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA0C;AACtD,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,gBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,YAAA,GAAe,GAAA,CAAI,OAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa,IAAA,CAAK,QAAQ,CAAA;AAC5C,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,CAAA;AAAA,EACnC;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,MAAA,CAAO,OAAA;AAAA,MAClB,CAAA,YAAA,EAAe,KAAK,SAAS,CAAA,mHAAA;AAAA,KAC/B;AACA,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,WAAA,CAAY,CAAC,KAAA,KAAgC;AACrE,MAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,QAAA,IAAA,CAAK,GAAA;AAAA,UACH,GAAA,CAAI,SAAA;AAAA,UACJ,GAAA,CAAI,KAAA;AAAA,UACJ,GAAA,CAAI,MAAA;AAAA,UACJ,GAAA,CAAI,OAAA;AAAA,UACJ,GAAA,CAAI,IAAA;AAAA,UACJ,GAAA,CAAI,KAAA;AAAA,UACJ,GAAA,CAAI,MAAA;AAAA,UACJ,GAAA,CAAI,YAAA;AAAA,UACJ,GAAA,CAAI;AAAA,SACN;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB;AACF;;;ACpEO,IAAM,iBAAA,GAAN,cAAgC,gBAAA,CAAiB;AAAA,EACrC,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA2C;AACjD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAsC;AAClD,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,IAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,EAAS,IAAA,IAAQ,GAAA,CAAI,IAAA;AAC1C,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,MACxC;AACA,MAAA,QAAA,GAAW,QAAA;AAAA,IACb,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,GAChB,EAAE,gBAAA,EAAkB,KAAK,gBAAA,EAAiB,GACzC,IAAA,CAAK,gBAAA,IAAoB,EAAC;AAC/B,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGS,cAAA,GAAyB;AAChC,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,cAAA,EAAe,EAAG,EAAE,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,CAAA;AAChB,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,EAAK,QAAA,KAAa;AAC9B,MAAA,MAAM,OAAO,QAAA,GAAW,OAAA;AACxB,MAAA,YAAA,CAAa,IAAA;AAAA,QACX,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,EAAE,QAAQ,OAAA,EAAQ,EAAG,CAAC,CAAA,EAAG,GAAA,KAAQ,IAAI,MAAA,CAAO,IAAA,GAAO,MAAM,CAAC,CAAC,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,OAC1F;AACA,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,GAAA,CAAI,SAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,OAAA;AAAA,QACJ,GAAA,CAAI,IAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,YAAA;AAAA,QACJ,GAAA,CAAI;AAAA,OACN;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,GAAA,GAAM,eAAe,IAAA,CAAK,SAAS,mGAAmG,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AACnK,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,GAAA,EAAK,MAAM,CAAA;AAAA,EAChC;AACF;;;AC5FO,IAAM,cAAA,GAAN,cAA6B,gBAAA,CAAiB;AAAA,EAClC,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,gBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,EAAS,UAAA,IAAc,GAAA,CAAI,UAAA;AAChD,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC9C;AACA,MAAA,UAAA,GAAa,QAAA;AAAA,IACf,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,IAAoB,IAAA,CAAK,oBAAoB,EAAC;AAClE,IAAA,IAAA,CAAK,MAAA,GAAS,WAAW,MAAM,CAAA;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGS,cAAA,GAAyB;AAChC,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,OAAA,CAAQ,IAAA,CAAK,cAAA,EAAe,EAAG,EAAE,CAAA;AAAA,EAChD;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,CAAA;AAChB,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,YAAA,CAAa,IAAA,CAAK,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAA,EAAQ,EAAG,MAAM,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAC9E,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,GAAA,CAAI,SAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,OAAA;AAAA,QACJ,GAAA,CAAI,IAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,YAAA;AAAA,QACJ,GAAA,CAAI;AAAA,OACN;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,eAAe,IAAA,CAAK,SAAS,2FAA2F,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC3J,IAAA,MAAM,MAAA,CAAO,OAAA,CAAQ,GAAA,EAAK,MAAM,CAAA;AAAA,EAClC;AACF;;;AChFO,IAAM,gBAAA,GAAN,cAA+B,iBAAA,CAAkB;AAAA,EACrC,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACT,UAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,qBAAqB,OAAA,CAAQ,UAAA;AAClC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,UAAA;AACpC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,MAAA;AAAA,EAClD;AAAA;AAAA,EAGQ,kBAAA,GAAsD;AAC5D,IAAA,OAAO,IAAA,CAAK,sBAAsB,IAAA,CAAK,UAAA;AAAA,EACzC;AAAA,EAEA,MAAc,gBAAA,GAAiD;AAC7D,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC1B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,eAAA,GAAkB,GAAA,CAAI,WAAA;AAAA,IACxB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,IAAA,CAAK,gBAAgB,CAAA;AACxD,IAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,EAAA,CAAG,IAAA,CAAK,QAAQ,CAAA,CAAE,UAAA,CAAW,KAAK,cAAc,CAAA;AACzE,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,aAAa,IAAA,CAAK,kBAAA,EAAmB,IAAM,MAAM,KAAK,gBAAA,EAAiB;AAG7E,IAAA,MAAM,UAAA,CAAW,UAAA,CAAW,KAAA,CAAM,GAAA,CAAI,CAAC,YAAY,EAAE,GAAG,MAAA,EAAO,CAAE,CAAC,CAAA;AAAA,EACpE;AACF;;;ACnFA,IAAM,kBAAA,GAAqB,EAAA;AAsC3B,SAAS,iBAAiB,KAAA,EAAyC;AACjE,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AAAA,EACtB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,GAAG,KAAA,EAAM;AAAA,EACpB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,EAAE;AAAA,EAC5B;AACA,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,CAAA,EAAG,KAAA,CAAM,QAAA,EAAS,EAAE;AAAA,EAC/B;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,EAAE,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA,EAAE;AAAA,EAC5D;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,IAA6B,EAAC;AACpC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AAChF,MAAA,CAAA,CAAE,GAAG,CAAA,GAAI,gBAAA,CAAiB,UAAU,CAAA;AAAA,IACtC;AACA,IAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAAA,EAChB;AAEA,EAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AACtB;AAEA,SAAS,aAAa,IAAA,EAA8C;AAClE,EAAA,OAAO,gBAAA,CAAiB,EAAE,GAAG,IAAA,EAAM,CAAA,CAAE,CAAA;AACvC;AAiBO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA,EACtC,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,MAAA;AACtC,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AAAA;AAAA,EAGQ,cAAA,GAA+C;AACrD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA0C;AACtD,IAAA,IAAI,kBAAA;AACJ,IAAA,IAAI,yBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,0BAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,kBAAA,GAAqB,GAAA,CAAI,cAAA;AACzB,MAAA,yBAAA,GAA4B,GAAA,CAAI,qBAAA;AAAA,IAClC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,IAAI,kBAAA,CAAmB,IAAA,CAAK,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,EAAE,CAAA;AACnF,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,MAAM,eAAA,CAAgB,SAAA,EAAmB,KAAA,EAAmD;AAC1F,QAAA,MAAM,YAAA,GAAe;AAAA,UACnB,CAAC,SAAS,GAAG,KAAA,CAAM,IAAI,CAAC,IAAA,MAAU,EAAE,UAAA,EAAY,EAAE,IAAA,EAAM,YAAA,CAAa,IAAI,CAAA,IAAI,CAAE;AAAA,SACjF;AACA,QAAA,OAAO,SAAA,CAAU,KAAK,IAAI,yBAAA,CAA0B,EAAE,YAAA,EAAc,YAAA,EAAc,CAAC,CAAA;AAAA,MACrF;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGQ,aAAa,MAAA,EAA2B;AAC9C,IAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,CAAK,KAAA;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,SAAS,CAAA,EAAG;AACjD,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,OAAA;AAC5B,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,SAAS,CAAA,EAAG;AACrD,MAAA,OAAO,OAAA;AAAA,IACT;AACA,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,EAChB;AAAA,EAEQ,aAAa,MAAA,EAAkC;AACrD,IAAA,MAAM,MAAA,GAAS,OAAO,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,YAAA,GAAe,OAAO,IAAA,CAAK,YAAA;AACjC,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,OAAA;AAC5B,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA;AAAA,MAC/B,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,GAAI,OAAO,MAAA,KAAW,WAAW,EAAE,MAAA,KAAW,EAAC;AAAA,MAC/C,GAAI,OAAO,YAAA,KAAiB,WAAW,EAAE,YAAA,KAAiB,EAAC;AAAA,MAC3D,GAAI,OAAO,OAAA,KAAY,WAAW,EAAE,OAAA,KAAY;AAAC,KACnD;AAAA,EACF;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,CAAC,WAAW,IAAA,CAAK,YAAA,CAAa,MAAM,CAAC,CAAA;AAC7D,IAAA,MAAM,SAA4B,EAAC;AACnC,IAAA,KAAA,IAAS,SAAS,CAAA,EAAG,MAAA,GAAS,KAAA,CAAM,MAAA,EAAQ,UAAU,kBAAA,EAAoB;AACxE,MAAA,MAAA,CAAO,KAAK,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,MAAA,GAAS,kBAAkB,CAAC,CAAA;AAAA,IAC9D;AAKA,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,MAAA,CAAO,eAAA,CAAgB,IAAA,CAAK,SAAA,EAAW,KAAK,CAAC,CAAC,CAAA;AAAA,EACxF;AACF;;;ACrJO,IAAM,cAAA,GAAN,cAA6B,iBAAA,CAAkB;AAAA,EACnC,cAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,GAAA,IAAO,wBAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,eAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,OAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,YAAA,GAAe,GAAA,CAAI,YAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,YAAA,CAAa,EAAE,GAAA,EAAK,IAAA,CAAK,KAAK,CAAA;AAC7C,IAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,SAAS,MAAA,EAA2C;AAC1D,IAAA,OAAO;AAAA,MACL,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI;AAAA,KAClC;AAAA,EACF;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AAGjE,IAAA,MAAM,QAAQ,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,WAAW,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAC,CAAC,CAAA;AAAA,EAC/F;AACF;;;ACrEO,IAAe,kBAAA,GAAf,cAA0C,iBAAA,CAAkB;AAAA,EACxD,KAAA;AAAA,EAET,YAAY,OAAA,EAAoC;AAC9C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACvB;AAAA,EAEmB,UAAU,KAAA,EAA4C;AACvE,IAAA,OAAO,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,EAChC;AAIF;;;AClBA,SAAS,OAAA,CAAQ,MAA+B,GAAA,EAAiC;AAC/E,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAG,CAAA;AACtB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAC7C;AAYO,IAAM,cAAA,GAAN,cAA6B,kBAAA,CAAmB;AAAA,EACpC,cAAA;AAAA,EACA,OAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAgC;AAC1C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,CAAC,gBAAgB,CAAA;AAAA,EACrD;AAAA;AAAA,EAGQ,cAAA,GAAgD;AACtD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,YAAA,GAA2C;AACvD,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,QAAA,GAAW,IAAI,IAAI,KAAA,CAAM,EAAE,SAAS,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAC7D,MAAA,MAAM,SAAS,OAAA,IAAU;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,QAAA;AACd,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,IAAA,CAAK;AAAA,MAChB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,QACjC,GAAA,EAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,EAAM,OAAO,KAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,EAAM,SAAS,CAAA,IAAK,IAAA;AAAA,QACzE,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,MAAM;AAAA,OAC9B,CAAE;AAAA,KACH,CAAA;AAAA,EACH;AACF;;;ACxDO,IAAM,iBAAA,GAAN,cAAgC,kBAAA,CAAmB;AAAA,EACvC,cAAA;AAAA,EACA,GAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAmC;AAC7C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,GAAA,IAAO,kBAAA;AAAA,EAC5B;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,MAAM,UAAA,GAAa,MAAM,GAAA,CAAI,OAAA,CAAQ,KAAK,GAAG,CAAA;AAC7C,MAAA,OAAA,GAAU,MAAM,WAAW,aAAA,EAAc;AACzC,MAAA,MAAM,OAAA,CAAQ,WAAA,GAAc,IAAA,CAAK,KAAK,CAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA;AACd,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAA,CAAO,WAAA,CAAY,KAAK,KAAA,EAAO,MAAA,CAAO,KAAK,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAC,CAAA;AAAA,IACpE;AAAA,EACF;AACF;;;AC7EA,IAAM,eAAA,GAAkB,EAAA;AA+BjB,IAAM,YAAA,GAAN,cAA2B,kBAAA,CAAmB;AAAA,EAClC,cAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAA8B;AACxC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AAAA;AAAA,EAGQ,cAAA,GAA4C;AAClD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAuC;AACnD,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,qBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAO1B,MAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AAC3D,MAAA,MAAM,cAAc,GAAA,CAAI,uBAAA;AACxB,MAAA,MAAA,GAAS;AAAA,QACP,gBAAA,EAAkB,CAAC,QAAA,EAAU,OAAA,KAC3B,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,WAAA,CAAY;AAAA,YACd,QAAA,EAAU,QAAA;AAAA,YACV,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,MAAW,EAAE,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,WAAA,EAAa,KAAA,CAAM,IAAA,EAAK,CAAE;AAAA,WAC5E;AAAA;AACH,OACJ;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,SAAmC,EAAC;AAC1C,IAAA,KAAA,IAAS,QAAQ,CAAA,EAAG,KAAA,GAAQ,OAAA,CAAQ,MAAA,EAAQ,SAAS,eAAA,EAAiB;AACpE,MAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,GAAQ,eAAe,CAAC,CAAA;AAAA,IAC3D;AAMA,IAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,MACZ,MAAA,CAAO,GAAA;AAAA,QAAI,CAAC,UACV,MAAA,CAAO,gBAAA;AAAA,UACL,IAAA,CAAK,KAAA;AAAA,UACL,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,EAAQ,WAAW,EAAE,EAAA,EAAI,MAAA,CAAO,KAAK,GAAG,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAM,GAAE,CAAE;AAAA;AACpF;AACF,KACF;AAAA,EACF;AACF;;;AC5EO,IAAM,eAAA,GAAN,cAA8B,kBAAA,CAAmB;AAAA,EACrC,cAAA;AAAA,EACA,SAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AAAA,EAC3B;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,sBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,KAAA,GAAQ,IAAI,GAAA,CAAI,MAAA,CAAO,EAAE,SAAA,EAAW,IAAA,CAAK,SAAA,EAAW,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AAAA,IACxE,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AAKjE,IAAA,MAAM,QAAQ,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,MAAA,KAAW,OAAO,cAAA,CAAe,EAAE,MAAM,MAAA,CAAO,IAAA,CAAK,KAAK,SAAA,CAAU,MAAM,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EACjH;AACF;;;ACxBO,IAAM,mBAAA,GAAN,cAAkC,iBAAA,CAAkB;AAAA,EAChD,YAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAqC;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,gBAAgB,OAAA,CAAQ,aAAA;AAC7B,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAmD;AACzD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA8C;AAC1D,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,uBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,iCAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,UAAA,GAAa,GAAA,CAAI,oBAAA;AACjB,MAAA,uBAAA,GAA0B,GAAA,CAAI,mBAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,IAAI,UAAA,CAAW,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AACxD,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,YAAA,EAAc,CAAC,YAAA,EAAc,aAAA,EAAe,WAC1C,SAAA,CAAU,IAAA;AAAA,QACR,IAAI,uBAAA,CAAwB;AAAA,UAC1B,YAAA;AAAA,UACA,aAAA;AAAA,UACA,SAAA,EAAW;AAAA,SACZ;AAAA;AACH,KACJ;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,MAAA,GAAS,KAAA,CACZ,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MAChB,SAAA,EAAW,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,MACtC,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,MAAM;AAAA,KAC7B,CAAE,EACD,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAS,CAAA;AAC3C,IAAA,MAAM,OAAO,YAAA,CAAa,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,eAAe,MAAM,CAAA;AAAA,EACzE;AACF;;;AC1EA,SAAS,YAAY,UAAA,EAA4B;AAC/C,EAAA,MAAM,KAAA,GAAQ,WAAW,UAAU,CAAA;AACnC,EAAA,QAAQ,KAAA;AAAO,IACb,KAAA,CAAA;AAAA,IACA,KAAA,EAAA;AACE,MAAA,OAAO,OAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,MAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,SAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,OAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,UAAA;AAAA;AAEb;AAWO,IAAM,qBAAA,GAAN,cAAoC,iBAAA,CAAkB;AAAA,EAClD,OAAA;AAAA,EACA,SAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAwC,EAAC,EAAG;AACtD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AAClC,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AACzB,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAqD;AAC3D,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAgD;AAC5D,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,uBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,WAAA,GAAc,GAAA,CAAI,OAAA;AAAA,IACpB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,IAAI,WAAA,CAAY,EAAE,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AACpC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,eAAA,EAAiB,CAAC,OAAA,KAAY,GAAA,CAAI,MAAM,OAAO;AAAA,KACjD;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MACrC,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAAA,MAClC,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,aAAa,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC;AAAA,KAC7C,CAAE,CAAA;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,OAAO,CAAA;AAAA,EACtC;AACF;;;AC5EA,SAAS,oBAAoB,UAAA,EAA4B;AACvD,EAAA,MAAM,KAAA,GAAQ,WAAW,UAAU,CAAA;AACnC,EAAA,QAAQ,KAAA;AAAO,IACb,KAAA,CAAA;AAAA,IACA,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAEb;AAaO,IAAM,oBAAA,GAAN,cAAmC,iBAAA,CAAkB;AAAA,EACjD,gBAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAuC,EAAC,EAAG;AACrD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAoD;AAC1D,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA+C;AAC3D,IAAA,IAAI,mBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,qBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,mBAAA,GAAsB,GAAA,CAAI,eAAA;AAAA,IAC5B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,eAAA,GAAkB,IAAI,mBAAA,CAAoB,IAAA,CAAK,gBAAgB,CAAA;AACrE,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,eAAA,EAAiB,CAAC,MAAA,KAAW;AAC3B,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,UAAA,eAAA,CAAgB,WAAW,KAAK,CAAA;AAAA,QAClC;AACA,QAAA,eAAA,CAAgB,KAAA,EAAM;AACtB,QAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,MACzB;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MACpC,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,MAC3B,QAAA,EAAU,mBAAA,CAAoB,MAAA,CAAO,KAAK;AAAA,KAC5C,CAAE,CAAA;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,MAAM,CAAA;AAAA,EACrC;AACF;;;AClHA,eAAe,kBAAA,CAAmB,GAAA,EAAa,MAAA,EAAgB,KAAA,EAAyC;AACtG,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,cAAc,MAAA,EAAO;AAAA,IACpE,IAAA,EAAM,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAAA,GAC1B,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,gCAAgC,GAAG,CAAA,oBAAA,EAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,yCAAA;AAAA,KACnF;AAAA,EACF;AACF;AAoBO,IAAM,gBAAA,GAAN,cAA+B,iBAAA,CAAkB;AAAA,EAC7C,GAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACQ,MAAA;AAAA,EAEjB,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,QAAQ,IAAA,IAAQ,eAAA;AAC5B,IAAA,IAAA,CAAK,GAAA,GAAM,CAAA,yBAAA,EAA4B,IAAA,CAAK,IAAI,CAAA,YAAA,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,kBAAA;AAAA,EAClC;AAAA,EAEmB,UAAU,KAAA,EAAmD;AAC9E,IAAA,MAAM,SAAA,GAAY,MAAM,GAAA,CAAI,CAAC,WAAW,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAC3D,IAAA,OAAO,KAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,EACrD;AACF;;;AC7CA,eAAe,wBAAA,CACb,GAAA,EACA,OAAA,EACA,IAAA,EACe;AACf,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,GAAG,OAAA,EAAS,gBAAgB,sBAAA,EAAuB;AAAA,IAC9D;AAAA,GACD,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,MAAM,CAAA,mCAAA,EAAsC,GAAG,uBAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,EAC3G;AACF;AAkBO,IAAM,sBAAA,GAAN,cAAqC,iBAAA,CAAkB;AAAA,EACnD,GAAA;AAAA,EACA,KAAA;AAAA,EACQ,MAAA;AAAA,EACA,MAAA;AAAA,EAEjB,YAAY,OAAA,EAAwC;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,KAAA,IAAS,MAAA;AAC9B,IAAA,IAAA,CAAK,MAAM,CAAA,EAAG,OAAA,CAAQ,KAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,MAAA,CAAA;AAC9C,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,wBAAA;AAAA,EAClC;AAAA,EAEmB,UAAU,KAAA,EAAmD;AAC9E,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,UAAU,KAAA,EAAO;AAC1B,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,IAAA,CAAK,KAAA,EAAM,EAAG,CAAC,CAAA;AAC5D,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,CAAA;AAChC,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,SAAS,IAAI,CAAA;AAAA,EAC5C;AACF;AC/CA,eAAe,mBAAA,CACb,GAAA,EACA,OAAA,EACA,IAAA,EAC+B;AAC/B,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA;AACnE,EAAA,OAAO;AAAA,IACL,IAAI,QAAA,CAAS,EAAA;AAAA,IACb,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,UAAA,EAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa;AAAA,GAChD;AACF;AAGA,SAAS,iBAAiB,MAAA,EAA8B;AACtD,EAAA,MAAM,IAAA,GAAO,EAAE,GAAG,MAAA,CAAO,IAAA,EAAK;AAC9B,EAAA,OAAO,IAAA,CAAK,SAAA;AACZ,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAK;AAC3B;AAGA,SAAS,eAAA,CAAgB,YAA2B,GAAA,EAAqB;AACvE,EAAA,IAAI,eAAe,IAAA,EAAM;AAGvB,IAAA,OAAO,GAAA,GAAM,GAAA;AAAA,EACf;AACA,EAAA,MAAM,OAAA,GAAU,OAAO,UAAU,CAAA;AACjC,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,EAAG;AAC5B,IAAA,OAAO,MAAM,OAAA,GAAU,GAAA;AAAA,EACzB;AACA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AACpC,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,GAAI,MAAM,GAAA,GAAS,MAAA;AAC/C;AA4BO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA,EAC9C,GAAA;AAAA,EACA,MAAA;AAAA,EACQ,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACT,WAAA,GAA6B,IAAA;AAAA,EAErC,YAAY,OAAA,EAAmC;AAC7C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AAChC,IAAA,IAAA,CAAK,GAAA,GACH,IAAA,CAAK,MAAA,KAAW,IAAA,GAAO,wCAAA,GAA2C,qCAAA;AACpE,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,mBAAA;AAChC,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,GAAA;AAAA,EACrC;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,EAAM;AACvB,IAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,IAAA,IAAQ,GAAA,GAAM,KAAK,WAAA,EAAa;AACvD,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN,yCAAyC,IAAI,IAAA,CAAK,KAAK,WAAW,CAAA,CAAE,aAAa,CAAA,+FAAA;AAAA,OACnF;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAEnB,IAAA,MAAM,UAAU,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,KAAW,gBAAA,CAAiB,MAAM,CAAC,CAAA;AAC9D,IAAA,MAAM,IAAA,GAAO,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,SAAA,CAAU,OAAO,CAAC,CAAC,CAAA;AAC1D,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB,kBAAA;AAAA,MAChB,kBAAA,EAAoB,MAAA;AAAA,MACpB,WAAW,IAAA,CAAK;AAAA,KAClB;AAEA,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,IAAA,CAAK,GAAA,EAAK,SAAS,IAAI,CAAA;AAExD,IAAA,IAAI,MAAA,CAAO,WAAW,GAAA,EAAK;AACzB,MAAA,IAAA,CAAK,WAAA,GAAc,eAAA,CAAgB,MAAA,CAAO,UAAA,EAAY,GAAG,CAAA;AACzD,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN,6EAAwE,IAAI,IAAA,CAAK,KAAK,WAAW,CAAA,CAAE,aAAa,CAAA,sEAAA;AAAA,OAClH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,iCAAiC,IAAA,CAAK,GAAG,uBAAuB,MAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA,wCAAA;AAAA,OACvF;AAAA,IACF;AAAA,EACF;AACF;;;AClIA,IAAM,MAAA,GAA0C;AAAA,EAC9C,iBAAe,UAAA;AAAA;AAAA,EACf,kBAAe,UAAA;AAAA;AAAA,EACf,iBAAc,UAAA;AAAA;AAAA,EACd,iBAAc,UAAA;AAAA;AAAA,EACd,kBAAe,UAAA;AAAA;AAAA,EACf,kBAAe;AAAA;AACjB,CAAA;AACA,IAAM,KAAA,GAAQ,SAAA;AAcd,SAAS,eAAA,GAA2B;AAElC,EAAA,MAAM,GAAA,GAAqC,OAAO,OAAA,KAAY,WAAA,GAAc,SAAY,OAAA,CAAQ,GAAA;AAChG,EAAA,OAAO,KAAK,QAAA,KAAa,MAAA;AAC3B;AAOO,IAAM,gBAAA,GAAN,cAA+B,SAAA,CAAU;AAAA,EAC9C,QAAA;AAAA,EACiB,GAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,eAAA,EAAgB;AACpD,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,OAAA,IAAW,OAAA;AAAA,EAChC;AAAA,EAEA,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AACrC,IAAA,MAAM,OAAO,IAAA,CAAK,QAAA,GAAW,KAAK,UAAA,CAAW,SAAA,EAAW,KAAK,CAAA,GAAI,SAAA;AACjE,IAAA,IAAI,KAAA,IAAA,EAAA,cAAsB;AACxB,MAAA,IAAA,CAAK,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,UAAA,CAAW,WAAmB,KAAA,EAAsB;AAC1D,IAAA,OAAO,GAAG,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,SAAS,GAAG,KAAK,CAAA,CAAA;AAAA,EAC7C;AACF;ACjDO,IAAM,aAAA,GAAN,cAA4B,SAAA,CAAU;AAAA,EAClC,IAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACD,EAAA;AAAA,EAER,WAAA,CAAY,IAAA,EAAc,OAAA,GAAgC,EAAC,EAAG;AAC5D,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,EAAA,GAAK,IAAA,GAAO,IAAA;AAChD,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,CAAA;AAC1C,IAAA,SAAA,CAAU,QAAQ,IAAI,CAAA,EAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5C,IAAA,IAAA,CAAK,EAAA,GAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA;AAAA,EACnC;AAAA,EAEA,MAAM,SAAA,EAAyB;AAC7B,IAAA,SAAA,CAAU,IAAA,CAAK,EAAA,EAAI,SAAA,GAAY,IAAI,CAAA;AACnC,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,IAAK,SAAA,CAAU,KAAK,EAAE,CAAA,CAAE,IAAA,IAAQ,IAAA,CAAK,QAAA,EAAU;AACjE,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,MAAA,GAAe;AACrB,IAAA,SAAA,CAAU,KAAK,EAAE,CAAA;AAEjB,IAAA,IAAI,IAAA,CAAK,cAAc,CAAA,EAAG;AACxB,MAAA,KAAA,IAAS,QAAQ,IAAA,CAAK,WAAA,GAAc,CAAA,EAAG,KAAA,GAAQ,GAAG,KAAA,EAAA,EAAS;AACzD,QAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AACzC,QAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,IAAI,IAAI,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA;AAC7C,QAAA,IAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACnB,UAAA,IAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACnB,YAAA,UAAA,CAAW,GAAG,CAAA;AAAA,UAChB;AACA,UAAA,UAAA,CAAW,KAAK,GAAG,CAAA;AAAA,QACrB;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAA;AAC3B,MAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AACtB,QAAA,UAAA,CAAW,MAAM,CAAA;AAAA,MACnB;AACA,MAAA,UAAA,CAAW,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,IAC9B,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IACtB;AAEA,IAAA,IAAA,CAAK,EAAA,GAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA;AAAA,EACnC;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,SAAA,CAAU,KAAK,EAAE,CAAA;AAAA,EACnB;AACF;;;ACzDA,eAAe,WAAA,CAAY,KAAa,KAAA,EAAyC;AAC/E,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,sBAAA,EAAuB;AAAA,IAClD,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI;AAAA,GACtB,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,MAAM,CAAA,0BAAA,EAA6B,GAAG,uBAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,EAClG;AACF;AAYO,IAAM,aAAA,GAAN,cAA4B,SAAA,CAAU;AAAA,EAClC,GAAA;AAAA,EACA,SAAA;AAAA,EACQ,MAAA;AAAA,EACT,QAAkB,EAAC;AAAA,EAE3B,WAAA,CAAY,GAAA,EAAa,OAAA,GAAgC,EAAC,EAAG;AAC3D,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,EAAA;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,WAAA;AAAA,EAClC;AAAA,EAEA,MAAM,SAAA,EAAyB;AAC7B,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AACzB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,SAAA,EAAW;AACvC,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,EAAC;AAEd,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAK,KAAK,CAAA;AAC1C,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,KAAmB;AAG/B,QAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAAA,MAChE,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AACF;;;ACxDO,IAAM,MAAA,GAAN,MAAM,OAAA,CAAO;AAAA,EACT,IAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACD,YAAA;AAAA,EACS,QAAA;AAAA,EAEjB,WAAA,CAAY,IAAA,EAAc,OAAA,GAAyB,EAAC,EAAG;AACrD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,UAAA,CAAW,OAAA,CAAQ,KAAA,IAAA,EAAA,YAAmB;AAC1D,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,GAAa,CAAC,GAAG,OAAA,CAAQ,UAAU,IAAI,EAAC;AAClE,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,GAAU,CAAC,GAAG,OAAA,CAAQ,OAAO,IAAI,EAAC;AACzD,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,IAAA,GAAO,EAAE,GAAG,OAAA,CAAQ,IAAA,KAAS,EAAC;AAAA,EACxD;AAAA,EAEA,IAAI,KAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA,EAEA,SAAS,KAAA,EAAyB;AAChC,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,KAAK,CAAA;AAAA,EACtC;AAAA;AAAA,EAGA,IAAI,MAAA,EAAsB;AACxB,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAM,CAAA;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,KAAA,MAAW,SAAA,IAAa,KAAK,UAAA,EAAY;AACvC,MAAA,SAAA,CAAU,KAAA,EAAM;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,CAAM,IAAA,EAAc,IAAA,GAAgC,EAAC,EAAW;AAC9D,IAAA,OAAO,IAAI,OAAA,CAAO,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI;AAAA,MACxC,OAAO,IAAA,CAAK,YAAA;AAAA,MACZ,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,IAAA;AAAK,KACnC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,CAAY,MAAA,EAAgB,KAAA,EAAgB,MAAA,EAAyB;AAE3E,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,OAAA,GAAU,OAAO,MAAM,CAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,QAAA,CAAS,KAAA,EAAc,OAAA,EAAiB,IAAA,EAAiD;AAC/F,IAAA,IAAI,KAAA,GAAQ,KAAK,YAAA,EAAc;AAC7B,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,SAAS,YAAA,CAAa;AAAA,MACxB,KAAA;AAAA,MACA,QAAQ,IAAA,CAAK,IAAA;AAAA,MACb,OAAA;AAAA,MACA,MAAM,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,IAAA;AAAK,KACnC,CAAA;AAED,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAA,CAAO,SAAA,GAAY,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,GAAI,MAAA;AAAA,MACzD,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,MAAM,CAAA;AACtC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,WAAW,IAAA,EAAM;AACnB,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAA,GAAS,MAAA;AAAA,IACX;AAEA,IAAA,KAAA,MAAW,SAAA,IAAa,KAAK,UAAA,EAAY;AACvC,MAAA,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,MAAM,GAAG,MAAM,CAAA;AAAA,IAClD;AAEA,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,WAAW,MAAM,CAAA;AAAA,MAC1B,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,MAAM,CAAA;AAAA,MACxC;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,CAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA,EAEA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA,EAEA,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC1E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,aAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,EAChD;AAAA,EAEA,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC1E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,aAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,EAChD;AAAA,EAEA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA,EAEA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AACF;;;ACTO,IAAM,OAAA,GAAU","file":"index.mjs","sourcesContent":["/** Log levels, shared by name and numeric weight with the logquill-python contract. */\nexport enum Level {\n TRACE = 5,\n DEBUG = 10,\n INFO = 20,\n WARN = 30,\n ERROR = 40,\n FATAL = 50,\n}\n\nconst NAME_TO_LEVEL: Readonly<Record<string, Level>> = {\n TRACE: Level.TRACE,\n DEBUG: Level.DEBUG,\n INFO: Level.INFO,\n WARN: Level.WARN,\n ERROR: Level.ERROR,\n FATAL: Level.FATAL,\n};\n\n/** A level given as a `Level`, a level name (any case), or its numeric weight. */\nexport type LevelInput = Level | number | string;\n\n/** The level's name, e.g. `levelName(Level.INFO) === \"INFO\"`. */\nexport function levelName(level: Level): string {\n return Level[level];\n}\n\n/** Normalize a level given as a `Level`, level name, or numeric weight. Throws if unknown. */\nexport function parseLevel(level: LevelInput): Level {\n if (typeof level === \"string\") {\n const parsed = NAME_TO_LEVEL[level.toUpperCase()];\n if (parsed === undefined) {\n throw new Error(`Unknown log level: ${level}`);\n }\n return parsed;\n }\n if (Level[level] === undefined) {\n throw new Error(`Unknown log level: ${String(level)}`);\n }\n return level;\n}\n","import { levelName, type Level } from \"./levels.js\";\n\n/** The cross-language record shape shared with logquill-python. */\nexport interface LogRecord {\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n}\n\n/** ISO8601 UTC timestamp with millisecond precision, matching Python's `utc_timestamp()`. */\nexport function utcTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function createRecord(params: {\n level: Level;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n}): LogRecord {\n return {\n timestamp: utcTimestamp(),\n level: levelName(params.level),\n logger: params.logger,\n message: params.message,\n meta: params.meta,\n };\n}\n","import type { LogRecord } from \"./records.js\";\n\n/** `format(record) -> string`, per the transport contract shared with logquill-python. */\nexport interface Formatter {\n format(record: LogRecord): string;\n}\n\n/** Serializes a record to the canonical JSON line shape. */\nexport class JSONFormatter implements Formatter {\n format(record: LogRecord): string {\n return JSON.stringify(record);\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Injects fixed key/value pairs into every record's `meta`.\n * A value already present in a record's own `meta` wins over the fixed context.\n */\nexport class ContextPlugin implements Plugin {\n readonly context: Record<string, unknown>;\n\n constructor(context: Record<string, unknown>) {\n this.context = context;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n return { ...record, meta: { ...this.context, ...record.meta } };\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nexport const DEFAULT_REDACTED_KEYS: readonly string[] = [\"password\", \"token\", \"secret\", \"api_key\", \"authorization\"];\n\nexport interface RedactPluginOptions {\n keys?: readonly string[];\n replacement?: string;\n}\n\n/** Replaces sensitive `meta` values, matched by key (case-insensitive), with a placeholder. */\nexport class RedactPlugin implements Plugin {\n private readonly keys: ReadonlySet<string>;\n readonly replacement: string;\n\n constructor(options: RedactPluginOptions = {}) {\n this.keys = new Set((options.keys ?? DEFAULT_REDACTED_KEYS).map((key) => key.toLowerCase()));\n this.replacement = options.replacement ?? \"***\";\n }\n\n beforeLog(record: LogRecord): LogRecord {\n const meta: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(record.meta)) {\n meta[key] = this.keys.has(key.toLowerCase()) ? this.replacement : value;\n }\n return { ...record, meta };\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nexport interface SamplingPluginOptions {\n rng?: () => number;\n}\n\n/** Keeps roughly `rate` of records (0.0-1.0), dropping the rest. */\nexport class SamplingPlugin implements Plugin {\n readonly rate: number;\n private readonly rng: () => number;\n\n constructor(rate: number, options: SamplingPluginOptions = {}) {\n if (rate < 0 || rate > 1) {\n throw new Error(`rate must be between 0 and 1, got ${String(rate)}`);\n }\n this.rate = rate;\n this.rng = options.rng ?? Math.random;\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n return this.rng() < this.rate ? record : null;\n }\n}\n","import { JSONFormatter, type Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Sink for log records, per the cross-language transport contract:\n * `format(record) -> string`, `write(formatted, record)`, `close()` on shutdown.\n */\nexport abstract class Transport {\n formatter: Formatter;\n\n constructor(formatter: Formatter = new JSONFormatter()) {\n this.formatter = formatter;\n }\n\n format(record: LogRecord): string {\n return this.formatter.format(record);\n }\n\n abstract write(formatted: string, record: LogRecord): void;\n\n /** Flush/release resources on shutdown. No-op unless a transport overrides it. */\n close(): void {}\n}\n\n/** In-memory transport for tests: collects every (formatted, record) pair written to it. */\nexport class CollectingTransport extends Transport {\n readonly formatted: string[] = [];\n readonly records: LogRecord[] = [];\n closed = false;\n\n write(formatted: string, record: LogRecord): void {\n this.formatted.push(formatted);\n this.records.push(record);\n }\n\n override close(): void {\n this.closed = true;\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\nexport interface BatchingTransportOptions {\n formatter?: Formatter;\n /** Flush once the buffer holds this many items. Default 100. */\n maxRecords?: number;\n /** Flush once the buffer's estimated byte size reaches this many bytes. Default 1_000_000 (1MB). */\n maxBytes?: number;\n}\n\n/**\n * Shared base for every batching sink transport (SQL, NoSQL, message queues,\n * batching cloud-native transports). Buffers items and flushes once either\n * `maxRecords` or `maxBytes` is reached, so no batching transport can grow\n * its buffer unboundedly under a sustained burst.\n *\n * `write()`/`close()` stay non-blocking from the caller's perspective: a\n * failed `sendBatch()` is reported via `console.error` rather than thrown,\n * matching `HTTPTransport`'s contract.\n */\nexport abstract class BatchingTransport<T = LogRecord> extends Transport {\n readonly maxRecords: number;\n readonly maxBytes: number;\n private buffer: T[] = [];\n private bufferBytes = 0;\n\n constructor(options: BatchingTransportOptions = {}) {\n super(options.formatter);\n this.maxRecords = options.maxRecords ?? 100;\n this.maxBytes = options.maxBytes ?? 1_000_000;\n }\n\n /** Converts a written record into the buffered item type. Defaults to the record itself. */\n protected toItem(formatted: string, record: LogRecord): T {\n void formatted;\n return record as unknown as T;\n }\n\n /** Estimated byte size of one buffered item, used for the `maxBytes` bound. */\n protected sizeOf(item: T): number {\n return JSON.stringify(item).length;\n }\n\n write(formatted: string, record: LogRecord): void {\n const item = this.toItem(formatted, record);\n this.buffer.push(item);\n this.bufferBytes += this.sizeOf(item);\n if (this.buffer.length >= this.maxRecords || this.bufferBytes >= this.maxBytes) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached a bound. */\n flush(): void {\n if (this.buffer.length === 0) {\n return;\n }\n const batch = this.buffer;\n this.buffer = [];\n this.bufferBytes = 0;\n\n const result = this.sendBatch(batch);\n if (result) {\n result.catch((error: unknown) => {\n console.error(`${this.constructor.name}: failed to send log batch`, error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n\n /** Deliver one batch to the backend. Always called with a non-empty batch. */\n protected abstract sendBatch(batch: readonly T[]): Promise<void> | void;\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One row of the fixed `logs` table schema shared across every SQL transport. */\nexport interface SQLLogRow {\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n /** `record.meta`, JSON-serialized — every SQL dialect can store this as TEXT/JSON/JSONB. */\n meta: string;\n runId: string | null;\n spanId: string | null;\n parentSpanId: string | null;\n traceId: string | null;\n}\n\nexport interface BaseSQLTransportOptions extends BatchingTransportOptions {\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /**\n * Dev/test convenience only: run `createTableSQL()` before the first insert.\n * Production schema/migrations are the caller's responsibility — never\n * auto-create schema unless this is explicitly set. Default `false`.\n */\n ensureSchema?: boolean;\n}\n\nfunction metaString(meta: Record<string, unknown>, key: string): string | null {\n const value = meta[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/**\n * Abstract base for every SQL transport (`SQLiteTransport`, `PostgresTransport`,\n * `MySQLTransport`, ...). Owns the fixed schema and the record → row mapping;\n * each driver-specific subclass only implements `ensureTable()`/`insertRows()`.\n * Inserts are always batched — never one query per log call.\n */\nexport abstract class BaseSQLTransport extends BatchingTransport<SQLLogRow> {\n readonly tableName: string;\n readonly ensureSchema: boolean;\n private schemaEnsured = false;\n\n constructor(options: BaseSQLTransportOptions = {}) {\n super(options);\n this.tableName = options.tableName ?? \"logs\";\n this.ensureSchema = options.ensureSchema ?? false;\n }\n\n protected override toItem(_formatted: string, record: LogRecord): SQLLogRow {\n void _formatted;\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n runId: metaString(record.meta, \"runId\"),\n spanId: metaString(record.meta, \"spanId\"),\n parentSpanId: metaString(record.meta, \"parentSpanId\"),\n traceId: metaString(record.meta, \"traceId\"),\n };\n }\n\n protected override sizeOf(row: SQLLogRow): number {\n return row.message.length + row.meta.length + 96;\n }\n\n /**\n * Minimal, dialect-generic `CREATE TABLE IF NOT EXISTS` for dev/test use via\n * `ensureSchema: true`. Production deployments should manage this table with\n * a real migration instead — override in a subclass for dialect-correct\n * column types (e.g. `JSONB` on Postgres).\n */\n createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta TEXT NOT NULL,\n runId TEXT,\n spanId TEXT,\n parentSpanId TEXT,\n traceId TEXT\n)`;\n }\n\n protected override async sendBatch(rows: readonly SQLLogRow[]): Promise<void> {\n if (this.ensureSchema && !this.schemaEnsured) {\n // Set before awaiting: a synchronous second flush (e.g. maxRecords: 1)\n // must not re-trigger ensureTable() while the first call is in flight.\n this.schemaEnsured = true;\n await this.ensureTable();\n }\n await this.insertRows(rows);\n }\n\n /** Only invoked when `ensureSchema: true` was explicitly passed. */\n protected abstract ensureTable(): Promise<void>;\n\n /** Always-batched insert of every row in `rows` — never one query per row. */\n protected abstract insertRows(rows: readonly SQLLogRow[]): Promise<void>;\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `better-sqlite3` prepared statement that `SQLiteTransport` needs. */\nexport interface SQLiteStatementLike {\n run(...params: unknown[]): unknown;\n}\n\n/** The subset of a `better-sqlite3` `Database` that `SQLiteTransport` needs. Inject a fake in tests. */\nexport interface SQLiteClientLike {\n exec(sql: string): unknown;\n prepare(sql: string): SQLiteStatementLike;\n transaction<Args extends unknown[]>(fn: (...args: Args) => void): (...args: Args) => void;\n}\n\nexport interface SQLiteTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client, e.g. for tests. Skips the `better-sqlite3` auto-import entirely. */\n client?: SQLiteClientLike;\n /** Passed to `better-sqlite3` when no `client` is injected. Default `\":memory:\"`. */\n filename?: string;\n}\n\n/**\n * Zero-setup SQL sink — no server process, just a local (or in-memory) file\n * via `better-sqlite3`. Useful for local dev and pairs with the CLI trace\n * viewer (v2.0), which can read this file directly.\n *\n * `better-sqlite3` is an optional peer dependency: install it yourself, or\n * inject a `client` (e.g. a fake, or an already-open `Database` instance).\n */\nexport class SQLiteTransport extends BaseSQLTransport {\n private readonly injectedClient: SQLiteClientLike | undefined;\n private readonly filename: string;\n private client: SQLiteClientLike | undefined;\n\n constructor(options: SQLiteTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.filename = options.filename ?? \":memory:\";\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQLiteClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQLiteClientLike> {\n let DatabaseCtor: new (filename: string) => SQLiteClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"better-sqlite3\";\n const mod = (await import(moduleName)) as unknown as {\n default: new (filename: string) => SQLiteClientLike;\n };\n DatabaseCtor = mod.default;\n } catch {\n throw new Error(\n \"SQLiteTransport: install `better-sqlite3` to use this transport without providing a client — `npm install better-sqlite3`\",\n );\n }\n\n this.client = new DatabaseCtor(this.filename);\n return this.client;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n client.exec(this.createTableSQL());\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const stmt = client.prepare(\n `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n const insertMany = client.transaction((batch: readonly SQLLogRow[]) => {\n for (const row of batch) {\n stmt.run(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n });\n insertMany(rows);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `pg` `Pool`/`Client` that `PostgresTransport` needs. Inject a fake in tests. */\nexport interface PgClientLike {\n query(text: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface PostgresTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `pg.Pool`/`pg.Client`. Skips the `pg` auto-import entirely. */\n client?: PgClientLike;\n /** Passed to `pg.Pool` when no `client` is injected, e.g. `\"postgres://user:pass@host:5432/db\"`. */\n connectionString?: string;\n /** Passed to `pg.Pool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by Postgres via `pg`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `pg` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Pool`/`Client` instance).\n */\nexport class PostgresTransport extends BaseSQLTransport {\n private readonly injectedClient: PgClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: PgClientLike | undefined;\n\n constructor(options: PostgresTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PgClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PgClientLike> {\n let PoolCtor: new (config?: Record<string, unknown>) => PgClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"pg\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { Pool?: new (config?: Record<string, unknown>) => PgClientLike };\n Pool?: new (config?: Record<string, unknown>) => PgClientLike;\n };\n const resolved = mod.default?.Pool ?? mod.Pool;\n if (!resolved) {\n throw new Error(\"no Pool export found\");\n }\n PoolCtor = resolved;\n } catch {\n throw new Error(\n \"PostgresTransport: install `pg` to use this transport without providing a client — `npm install pg`\",\n );\n }\n\n const config = this.connectionString\n ? { connectionString: this.connectionString }\n : (this.connectionConfig ?? {});\n this.client = new PoolCtor(config);\n return this.client;\n }\n\n /** Postgres-correct `CREATE TABLE IF NOT EXISTS`: `SERIAL` primary key, `JSONB` for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id SERIAL PRIMARY KEY,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta JSONB NOT NULL,\n \"runId\" TEXT,\n \"spanId\" TEXT,\n \"parentSpanId\" TEXT,\n \"traceId\" TEXT\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.query(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n rows.forEach((row, rowIndex) => {\n const base = rowIndex * columns;\n placeholders.push(\n `(${Array.from({ length: columns }, (_, col) => `$${String(base + col + 1)}`).join(\", \")})`,\n );\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n });\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, \"runId\", \"spanId\", \"parentSpanId\", \"traceId\") VALUES ${placeholders.join(\", \")}`;\n await client.query(sql, values);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `mysql2/promise` connection/pool that `MySQLTransport` needs. Inject a fake in tests. */\nexport interface MySQLClientLike {\n execute(sql: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface MySQLTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `mysql2/promise` `Pool`/`Connection`. Skips the `mysql2` auto-import entirely. */\n client?: MySQLClientLike;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected, e.g. `\"mysql://user:pass@host:3306/db\"`. */\n connectionString?: string;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by MySQL via `mysql2`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `mysql2` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open pool/connection from\n * `mysql2/promise`).\n */\nexport class MySQLTransport extends BaseSQLTransport {\n private readonly injectedClient: MySQLClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: MySQLClientLike | undefined;\n\n constructor(options: MySQLTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): MySQLClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<MySQLClientLike> {\n let createPool: (target: string | Record<string, unknown>) => MySQLClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mysql2/promise\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { createPool?: (target: string | Record<string, unknown>) => MySQLClientLike };\n createPool?: (target: string | Record<string, unknown>) => MySQLClientLike;\n };\n const resolved = mod.default?.createPool ?? mod.createPool;\n if (!resolved) {\n throw new Error(\"no createPool export found\");\n }\n createPool = resolved;\n } catch {\n throw new Error(\n \"MySQLTransport: install `mysql2` to use this transport without providing a client — `npm install mysql2`\",\n );\n }\n\n const target = this.connectionString ?? this.connectionConfig ?? {};\n this.client = createPool(target);\n return this.client;\n }\n\n /** MySQL-correct `CREATE TABLE IF NOT EXISTS`: `AUTO_INCREMENT` primary key, `JSON` column type for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INT AUTO_INCREMENT PRIMARY KEY,\n timestamp VARCHAR(64) NOT NULL,\n level VARCHAR(16) NOT NULL,\n logger VARCHAR(255) NOT NULL,\n message TEXT NOT NULL,\n meta JSON NOT NULL,\n runId VARCHAR(255),\n spanId VARCHAR(255),\n parentSpanId VARCHAR(255),\n traceId VARCHAR(255)\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.execute(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n for (const row of rows) {\n placeholders.push(`(${Array.from({ length: columns }, () => \"?\").join(\", \")})`);\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES ${placeholders.join(\", \")}`;\n await client.execute(sql, values);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `mongodb` `Collection` that `MongoDBTransport` needs. Inject a fake in tests. */\nexport interface MongoCollectionLike {\n insertMany(docs: readonly unknown[]): Promise<unknown>;\n}\n\n/** The subset of a `mongodb` `MongoClient` that `MongoDBTransport` needs to lazily connect. */\nexport interface MongoClientLike {\n connect(): Promise<unknown>;\n db(name: string): { collection(name: string): MongoCollectionLike };\n}\n\nexport interface MongoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built collection, e.g. for tests, or an already-connected app. Skips the `mongodb` auto-import entirely. */\n collection?: MongoCollectionLike;\n /** `mongodb` connection string, used when no `collection` is injected. Required in that case. */\n connectionString?: string;\n /** Database to write into when connecting via `connectionString`. Default `\"logquill\"`. */\n database?: string;\n /** Collection to write into when connecting via `connectionString`. Default `\"logs\"`. */\n collectionName?: string;\n}\n\n/**\n * Sink for MongoDB. Records map 1:1 to documents — no JSON-in-a-column\n * workaround needed, unlike the SQL transports.\n *\n * `mongodb` is an optional peer dependency: install it yourself, or inject a\n * `collection` (e.g. a fake, or a `Collection` from a client your app already\n * manages).\n */\nexport class MongoDBTransport extends BatchingTransport {\n private readonly injectedCollection: MongoCollectionLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly database: string;\n private readonly collectionName: string;\n private collection: MongoCollectionLike | undefined;\n\n constructor(options: MongoDBTransportOptions = {}) {\n super(options);\n this.injectedCollection = options.collection;\n this.connectionString = options.connectionString;\n this.database = options.database ?? \"logquill\";\n this.collectionName = options.collectionName ?? \"logs\";\n }\n\n /** Synchronously available collection, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedCollection(): MongoCollectionLike | undefined {\n return this.injectedCollection ?? this.collection;\n }\n\n private async importCollection(): Promise<MongoCollectionLike> {\n if (!this.connectionString) {\n throw new Error(\n \"MongoDBTransport: provide either a `collection` or a `connectionString` to connect with — neither was given\",\n );\n }\n\n let MongoClientCtor: new (connectionString: string) => MongoClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mongodb\";\n const mod = (await import(moduleName)) as unknown as {\n MongoClient: new (connectionString: string) => MongoClientLike;\n };\n MongoClientCtor = mod.MongoClient;\n } catch {\n throw new Error(\n \"MongoDBTransport: install `mongodb` to use this transport without providing a client — `npm install mongodb`\",\n );\n }\n\n const client = new MongoClientCtor(this.connectionString);\n await client.connect();\n this.collection = client.db(this.database).collection(this.collectionName);\n return this.collection;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const collection = this.resolvedCollection() ?? (await this.importCollection());\n // Records already match the cross-language JSON record shape, so each one\n // becomes a document as-is — spread to give Mongo a fresh plain object per doc.\n await collection.insertMany(batch.map((record) => ({ ...record })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** DynamoDB's hard cap on items per `BatchWriteItem` call — respected by chunking within `sendBatch()`. */\nconst DYNAMO_BATCH_LIMIT = 25;\n\n/** One item written to DynamoDB: `runId` is the partition key, `timestamp` is the sort key. */\nexport interface DynamoLogItem {\n runId: string;\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n spanId?: string;\n parentSpanId?: string;\n traceId?: string;\n}\n\n/**\n * The subset of DynamoDB write access `DynamoDBTransport` needs, deliberately\n * narrower than the AWS SDK v3 command pattern (`send(command)`): one\n * `BatchWriteItem`-equivalent call per sub-batch, already capped at\n * `DYNAMO_BATCH_LIMIT` items by the caller. This keeps fake-based tests\n * trivial — a fake just needs to record `(tableName, items)` calls, not\n * emulate a `DynamoDBClient`. Inject a fake in tests, or rely on the built-in\n * `@aws-sdk/client-dynamodb` wrapper by not injecting a `client`.\n */\nexport interface DynamoClientLike {\n batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown>;\n}\n\nexport interface DynamoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built client, e.g. for tests, or a custom wrapper. Skips the `@aws-sdk/client-dynamodb` auto-import entirely. */\n client?: DynamoClientLike;\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /** AWS region, used when no `client` is injected. Falls back to the SDK's own credential-chain resolution when omitted. */\n region?: string;\n}\n\n/** Minimal JS -> DynamoDB `AttributeValue` marshaller for the real-SDK code path, so this transport doesn't need `@aws-sdk/util-dynamodb` as a second peer dependency just to build one request shape. */\nfunction toAttributeValue(value: unknown): Record<string, unknown> {\n if (value === null || value === undefined) {\n return { NULL: true };\n }\n if (typeof value === \"string\") {\n return { S: value };\n }\n if (typeof value === \"number\") {\n return { N: String(value) };\n }\n if (typeof value === \"boolean\") {\n return { BOOL: value };\n }\n if (typeof value === \"bigint\") {\n return { N: value.toString() };\n }\n if (Array.isArray(value)) {\n return { L: value.map((entry) => toAttributeValue(entry)) };\n }\n if (typeof value === \"object\") {\n const m: Record<string, unknown> = {};\n for (const [key, entryValue] of Object.entries(value as Record<string, unknown>)) {\n m[key] = toAttributeValue(entryValue);\n }\n return { M: m };\n }\n // Functions/symbols aren't serializable log data — drop rather than stringify unpredictably.\n return { NULL: true };\n}\n\nfunction marshallItem(item: DynamoLogItem): Record<string, unknown> {\n return toAttributeValue({ ...item }).M as Record<string, unknown>;\n}\n\n/**\n * Sink for Amazon DynamoDB. Partition key is `runId`/`traceId` (whichever is\n * present on `record.meta`, `runId` taking priority), falling back to the\n * logger name when neither is set, so every record always lands under some\n * partition even before `RunPlugin`/`TraceContextPlugin` are wired up. Sort\n * key is `timestamp`.\n *\n * DynamoDB's actual `BatchWriteItem` API caps a call at 25 items, so\n * `sendBatch()` chunks a larger batch into sub-batches of 25 — matching how\n * `SQSTransport` respects `SendMessageBatch`'s 10-item cap.\n *\n * `@aws-sdk/client-dynamodb` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a custom wrapper around a\n * `DynamoDBClient` your app already manages).\n */\nexport class DynamoDBTransport extends BatchingTransport {\n private readonly injectedClient: DynamoClientLike | undefined;\n private readonly tableName: string;\n private readonly region: string | undefined;\n private client: DynamoClientLike | undefined;\n\n constructor(options: DynamoDBTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.tableName = options.tableName ?? \"logs\";\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): DynamoClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<DynamoClientLike> {\n let DynamoDBClientCtor: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n let BatchWriteItemCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-dynamodb\";\n const mod = (await import(moduleName)) as unknown as {\n DynamoDBClient: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n BatchWriteItemCommand: new (input: unknown) => unknown;\n };\n DynamoDBClientCtor = mod.DynamoDBClient;\n BatchWriteItemCommandCtor = mod.BatchWriteItemCommand;\n } catch {\n throw new Error(\n \"DynamoDBTransport: install `@aws-sdk/client-dynamodb` to use this transport without providing a client — `npm install @aws-sdk/client-dynamodb`\",\n );\n }\n\n const sdkClient = new DynamoDBClientCtor(this.region ? { region: this.region } : {});\n this.client = {\n async batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown> {\n const requestItems = {\n [tableName]: items.map((item) => ({ PutRequest: { Item: marshallItem(item) } })),\n };\n return sdkClient.send(new BatchWriteItemCommandCtor({ RequestItems: requestItems }));\n },\n };\n return this.client;\n }\n\n /** `meta.runId`, else `meta.traceId`, else the logger name — see the class doc for why. */\n private partitionKey(record: LogRecord): string {\n const runId = record.meta.runId;\n if (typeof runId === \"string\" && runId.length > 0) {\n return runId;\n }\n const traceId = record.meta.traceId;\n if (typeof traceId === \"string\" && traceId.length > 0) {\n return traceId;\n }\n return record.logger;\n }\n\n private toDynamoItem(record: LogRecord): DynamoLogItem {\n const spanId = record.meta.spanId;\n const parentSpanId = record.meta.parentSpanId;\n const traceId = record.meta.traceId;\n return {\n runId: this.partitionKey(record),\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: record.meta,\n ...(typeof spanId === \"string\" ? { spanId } : {}),\n ...(typeof parentSpanId === \"string\" ? { parentSpanId } : {}),\n ...(typeof traceId === \"string\" ? { traceId } : {}),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const items = batch.map((record) => this.toDynamoItem(record));\n const chunks: DynamoLogItem[][] = [];\n for (let offset = 0; offset < items.length; offset += DYNAMO_BATCH_LIMIT) {\n chunks.push(items.slice(offset, offset + DYNAMO_BATCH_LIMIT));\n }\n // Dispatched concurrently rather than one-at-a-time: each sub-batch is an\n // independent BatchWriteItem call, and issuing them together (instead of\n // serially awaiting each) is both higher-throughput and keeps every call\n // in a sub-batch-sized flush starting in the same tick `sendBatch` runs.\n await Promise.all(chunks.map((chunk) => client.batchWriteItems(this.tableName, chunk)));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `redis` (node-redis v4) client that `RedisTransport` needs. Inject a fake in tests. */\nexport interface RedisClientLike {\n xAdd(stream: string, id: string, fields: Record<string, string>): Promise<unknown>;\n}\n\nexport interface RedisTransportOptions extends BatchingTransportOptions {\n /** Pre-built, already-connected client, e.g. for tests. Skips the `redis` auto-import entirely. */\n client?: RedisClientLike;\n /** `redis` connection URL, used when no `client` is injected. Default `\"redis://localhost:6379\"`. */\n url?: string;\n /** Stream key to `XADD` into. Default `\"logquill:logs\"`. */\n stream?: string;\n}\n\n/**\n * Sink for Redis, via Redis Streams (`XADD`) — as CLAUDE.md's spec puts it,\n * \"a fast local buffer, a different use case from durable storage, not a\n * replacement for the others.\" Reach for this when you want a low-latency\n * local tail (e.g. feeding a `redis-cli XREAD`-based live viewer) rather than\n * a system of record.\n *\n * Streams has no true multi-entry `XADD`, so unlike the other batching\n * transports this issues one `XADD` per record within the batch rather than\n * one network call per batch — batching here still bounds memory and reduces\n * GC/buffer churn, but it is honestly not a network-call batch the way\n * `MongoDBTransport.insertMany()` or `DynamoDBTransport`'s `BatchWriteItem`\n * chunks are.\n *\n * `redis` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-connected client your app manages).\n */\nexport class RedisTransport extends BatchingTransport {\n private readonly injectedClient: RedisClientLike | undefined;\n private readonly url: string;\n private readonly stream: string;\n private client: RedisClientLike | undefined;\n\n constructor(options: RedisTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"redis://localhost:6379\";\n this.stream = options.stream ?? \"logquill:logs\";\n }\n\n /** Synchronously available client, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): RedisClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<RedisClientLike> {\n let createClient: (options: { url: string }) => RedisClientLike & { connect(): Promise<unknown> };\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"redis\";\n const mod = (await import(moduleName)) as unknown as {\n createClient: (options: { url: string }) => RedisClientLike & { connect(): Promise<unknown> };\n };\n createClient = mod.createClient;\n } catch {\n throw new Error(\n \"RedisTransport: install `redis` to use this transport without providing a client — `npm install redis`\",\n );\n }\n\n const client = createClient({ url: this.url });\n await client.connect();\n this.client = client;\n return client;\n }\n\n private toFields(record: LogRecord): Record<string, string> {\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // One XADD per record, all issued together rather than serially awaited —\n // see the class doc for why Streams can't take a single multi-entry append.\n await Promise.all(batch.map((record) => client.xAdd(this.stream, \"*\", this.toFields(record))));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\nexport interface BaseQueueTransportOptions extends BatchingTransportOptions {\n /**\n * Destination name on the backend — a Kafka topic, a RabbitMQ queue name,\n * an SQS queue URL, or a GCP Pub/Sub topic. One generic option name so the\n * base class's orchestration stays backend-agnostic; each subclass's own\n * docs use its backend's own vocabulary for what this means.\n */\n topic: string;\n}\n\n/**\n * Abstract base for every message-queue transport (`KafkaTransport`,\n * `RabbitMQTransport`, `SQSTransport`, `PubSubTransport`). Owns the \"always\n * batch, never publish one message per log call\" contract shared across\n * every queue backend — buffering itself is inherited from\n * `BatchingTransport`; each concrete subclass only implements\n * `publishBatch()` against its own driver's publish API.\n */\nexport abstract class BaseQueueTransport extends BatchingTransport {\n readonly topic: string;\n\n constructor(options: BaseQueueTransportOptions) {\n super(options);\n this.topic = options.topic;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> {\n return this.publishBatch(batch);\n }\n\n /** Deliver one batch of records to the queue backend. Always called with a non-empty batch. */\n protected abstract publishBatch(records: readonly LogRecord[]): Promise<void>;\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `kafkajs` `Producer` that `KafkaTransport` needs. Inject a fake in tests. */\nexport interface KafkaProducerLike {\n /** Optional: some injected producers (or fakes) are already connected. */\n connect?(): Promise<void>;\n send(record: { topic: string; messages: { key: string | null; value: string }[] }): Promise<unknown>;\n}\n\nexport interface KafkaTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built producer, e.g. for tests, or an already-configured kafkajs `Producer`. Skips the `kafkajs` auto-import entirely. */\n client?: KafkaProducerLike;\n /** Broker addresses passed to `kafkajs`'s `Kafka({ brokers })` when no `client` is injected. Default `[\"localhost:9092\"]`. */\n brokers?: string[];\n}\n\nfunction metaKey(meta: Record<string, unknown>, key: string): string | undefined {\n const value = meta[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Publishes batches to a Kafka topic via `kafkajs`. Each message's `key` is\n * set to `meta.runId` (falling back to `meta.traceId`, then `null`), so\n * kafkajs's default partitioner keeps every message from the same agent\n * run/trace on one partition — preserving per-trace ordering, per the\n * message-queue contract in the project spec.\n *\n * `kafkajs` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-configured `Producer`).\n */\nexport class KafkaTransport extends BaseQueueTransport {\n private readonly injectedClient: KafkaProducerLike | undefined;\n private readonly brokers: string[];\n private client: KafkaProducerLike | undefined;\n\n constructor(options: KafkaTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.brokers = options.brokers ?? [\"localhost:9092\"];\n }\n\n /** Synchronously available producer, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): KafkaProducerLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Builds the real `kafkajs` producer and connects it. Connection happens\n * here, once, as part of acquiring the driver — not on every\n * `publishBatch()` call — so an injected `client` (tests, or a caller's\n * own already-connected producer) is trusted to already be ready and is\n * never re-connected.\n */\n private async importClient(): Promise<KafkaProducerLike> {\n let producer: KafkaProducerLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"kafkajs\";\n const mod = (await import(moduleName)) as unknown as {\n Kafka: new (config: { brokers: string[] }) => { producer(): KafkaProducerLike };\n };\n producer = new mod.Kafka({ brokers: this.brokers }).producer();\n await producer.connect?.();\n } catch {\n throw new Error(\n \"KafkaTransport: install `kafkajs` to use this transport without providing a client — `npm install kafkajs`\",\n );\n }\n\n this.client = producer;\n return producer;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.send({\n topic: this.topic,\n messages: records.map((record) => ({\n key: metaKey(record.meta, \"runId\") ?? metaKey(record.meta, \"traceId\") ?? null,\n value: JSON.stringify(record),\n })),\n });\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of an `amqplib` `Channel` that `RabbitMQTransport` needs. Inject a fake in tests. */\nexport interface AmqpChannelLike {\n /** Optional: only called once, and only when provided, to ensure the queue exists. */\n assertQueue?(queue: string, options?: unknown): Promise<unknown>;\n sendToQueue(queue: string, content: Buffer, options?: unknown): boolean;\n}\n\nexport interface RabbitMQTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built channel, e.g. for tests, or an already-open amqplib `Channel`. Skips the `amqplib` auto-import entirely. */\n client?: AmqpChannelLike;\n /** Connection URL passed to `amqplib.connect()` when no `client` is injected. Default `\"amqp://localhost\"`. */\n url?: string;\n}\n\n/**\n * Publishes batches to a RabbitMQ queue via `amqplib`. RabbitMQ's core API\n * has no native multi-message batch primitive — there is no\n * `sendToQueue`-equivalent that takes an array — so `publishBatch()` loops\n * one `sendToQueue()` call per record. The \"batch\" LogQuill promises is at\n * the buffering level: `maxRecords`/`maxBytes` still governs how often that\n * loop runs, so this transport never makes one network round trip per log\n * call; it just can't make one round trip per *batch* either, honestly,\n * since RabbitMQ itself doesn't offer that primitive.\n *\n * `amqplib` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Channel`).\n */\nexport class RabbitMQTransport extends BaseQueueTransport {\n private readonly injectedClient: AmqpChannelLike | undefined;\n private readonly url: string;\n private client: AmqpChannelLike | undefined;\n\n constructor(options: RabbitMQTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"amqp://localhost\";\n }\n\n /** Synchronously available channel, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AmqpChannelLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Opens the real `amqplib` connection/channel and asserts the queue\n * exists. Both happen here, once, as part of acquiring the driver — not on\n * every `publishBatch()` call — so an injected `client` (tests, or a\n * caller's own already-open channel) is trusted to already have its queue\n * set up and is never re-asserted.\n */\n private async importClient(): Promise<AmqpChannelLike> {\n let channel: AmqpChannelLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"amqplib\";\n const mod = (await import(moduleName)) as unknown as {\n connect(url: string): Promise<{ createChannel(): Promise<AmqpChannelLike> }>;\n };\n const connection = await mod.connect(this.url);\n channel = await connection.createChannel();\n await channel.assertQueue?.(this.topic);\n } catch {\n throw new Error(\n \"RabbitMQTransport: install `amqplib` to use this transport without providing a client — `npm install amqplib`\",\n );\n }\n\n this.client = channel;\n return channel;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n for (const record of records) {\n client.sendToQueue(this.topic, Buffer.from(JSON.stringify(record)));\n }\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** AWS's own cap on a single `SendMessageBatch` request. Never exceed it. */\nconst SQS_BATCH_LIMIT = 10;\n\n/**\n * The subset of AWS SDK v3's SQS client that `SQSTransport` needs, narrowed\n * to a plain `sendMessageBatch(queueUrl, entries)` method rather than\n * modeling the full `@aws-sdk/client-sqs` command/client pattern — simpler\n * to fake in tests, and the only shape this transport actually calls. Inject\n * a fake in tests, or wrap a real `SQSClient` to match this shape.\n */\nexport interface SQSClientLike {\n sendMessageBatch(queueUrl: string, entries: { id: string; body: string }[]): Promise<unknown>;\n}\n\nexport interface SQSTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built client, e.g. for tests, or a thin wrapper around `@aws-sdk/client-sqs`'s `SQSClient`. Skips the `@aws-sdk/client-sqs` auto-import entirely. */\n client?: SQSClientLike;\n /** AWS region passed to `@aws-sdk/client-sqs` when no `client` is injected. */\n region?: string;\n}\n\n/**\n * Publishes batches to an SQS queue via `@aws-sdk/client-sqs`'s\n * `SendMessageBatch`. That API caps a single request at 10 messages, so\n * `publishBatch()` chunks any larger batch into sub-batches of 10 —\n * LogQuill's own `maxRecords`/`maxBytes` buffering can flush more than 10\n * records at once; this transport is responsible for respecting SQS's own\n * limit underneath, per the message-queue contract in the project spec.\n *\n * `@aws-sdk/client-sqs` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a wrapped `SQSClient`).\n */\nexport class SQSTransport extends BaseQueueTransport {\n private readonly injectedClient: SQSClientLike | undefined;\n private readonly region: string | undefined;\n private client: SQSClientLike | undefined;\n\n constructor(options: SQSTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQSClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQSClientLike> {\n let client: SQSClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-sqs\";\n const mod = (await import(moduleName)) as unknown as {\n SQSClient: new (config: { region?: string | undefined }) => { send(command: unknown): Promise<unknown> };\n SendMessageBatchCommand: new (input: {\n QueueUrl: string;\n Entries: { Id: string; MessageBody: string }[];\n }) => unknown;\n };\n const sdkClient = new mod.SQSClient({ region: this.region });\n const CommandCtor = mod.SendMessageBatchCommand;\n client = {\n sendMessageBatch: (queueUrl, entries) =>\n sdkClient.send(\n new CommandCtor({\n QueueUrl: queueUrl,\n Entries: entries.map((entry) => ({ Id: entry.id, MessageBody: entry.body })),\n }),\n ),\n };\n } catch {\n throw new Error(\n \"SQSTransport: install `@aws-sdk/client-sqs` to use this transport without providing a client — `npm install @aws-sdk/client-sqs`\",\n );\n }\n\n this.client = client;\n return client;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const chunks: (readonly LogRecord[])[] = [];\n for (let start = 0; start < records.length; start += SQS_BATCH_LIMIT) {\n chunks.push(records.slice(start, start + SQS_BATCH_LIMIT));\n }\n // Fire every sub-batch's request in the same tick (via `.map`) and await\n // them together, rather than one at a time — an `await` per iteration of\n // a sequential loop would otherwise force each sub-batch onto its own\n // microtask turn for no benefit, since the requests don't depend on\n // each other.\n await Promise.all(\n chunks.map((chunk) =>\n client.sendMessageBatch(\n this.topic,\n chunk.map((record, index) => ({ id: String(index), body: JSON.stringify(record) })),\n ),\n ),\n );\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/**\n * The subset of a `@google-cloud/pubsub` `Topic` that `PubSubTransport`\n * needs. Inject a fake in tests, or an already-resolved `Topic` instance.\n */\nexport interface PubSubTopicLike {\n publishMessage(message: { data: Buffer }): Promise<string>;\n}\n\nexport interface PubSubTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built topic reference, e.g. for tests, or an already-resolved `@google-cloud/pubsub` `Topic`. Skips the `@google-cloud/pubsub` auto-import entirely. */\n client?: PubSubTopicLike;\n /** GCP project ID passed to `@google-cloud/pubsub` when no `client` is injected. */\n projectId?: string;\n}\n\n/**\n * Publishes batches to a GCP Pub/Sub topic via `@google-cloud/pubsub`. The\n * real client already does its own internal batching/flow-control underneath\n * `publishMessage()` — this transport doesn't reimplement that. What it does\n * own is LogQuill's own bounded-memory contract: `publishBatch()` only runs\n * once per buffer flush (`maxRecords`/`maxBytes`), so the driver is never\n * invoked once per individual log call.\n *\n * `@google-cloud/pubsub` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a resolved `Topic`).\n */\nexport class PubSubTransport extends BaseQueueTransport {\n private readonly injectedClient: PubSubTopicLike | undefined;\n private readonly projectId: string | undefined;\n private client: PubSubTopicLike | undefined;\n\n constructor(options: PubSubTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.projectId = options.projectId;\n }\n\n /** Synchronously available topic reference, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PubSubTopicLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PubSubTopicLike> {\n let topic: PubSubTopicLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/pubsub\";\n const mod = (await import(moduleName)) as unknown as {\n PubSub: new (config: { projectId?: string | undefined }) => { topic(name: string): PubSubTopicLike };\n };\n topic = new mod.PubSub({ projectId: this.projectId }).topic(this.topic);\n } catch {\n throw new Error(\n \"PubSubTransport: install `@google-cloud/pubsub` to use this transport without providing a client — `npm install @google-cloud/pubsub`\",\n );\n }\n\n this.client = topic;\n return topic;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // Fire every `publishMessage()` call in the same tick (via `.map`) and\n // await them together, rather than one at a time — the real client\n // already does its own internal batching/flow-control, so a sequential\n // per-record `await` here would only add unnecessary microtask turns.\n await Promise.all(records.map((record) => client.publishMessage({ data: Buffer.from(JSON.stringify(record)) })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One CloudWatch Logs event: epoch-milliseconds timestamp plus a single log line. */\nexport interface CloudWatchLogEvent {\n timestamp: number;\n message: string;\n}\n\n/**\n * The subset of the AWS SDK v3 CloudWatch Logs client that `CloudWatchTransport`\n * needs. Deliberately narrower than the SDK's full command pattern (build a\n * `PutLogEventsCommand`, `.send()` it, track the deprecated sequence-token\n * dance) — modeling just this one operation keeps the injectable-fake surface\n * small for tests; `importClient()` builds the real adapter around it.\n */\nexport interface CloudWatchClientLike {\n putLogEvents(\n logGroupName: string,\n logStreamName: string,\n events: readonly CloudWatchLogEvent[],\n ): Promise<unknown>;\n}\n\nexport interface CloudWatchTransportOptions extends BatchingTransportOptions {\n /** CloudWatch Logs log group to write into. */\n logGroupName: string;\n /** CloudWatch Logs log stream, within `logGroupName`, to write into. */\n logStreamName: string;\n /** AWS region, e.g. `\"us-east-1\"`. Passed to the real SDK client; ignored when `client` is injected. */\n region?: string;\n /** Pre-built client, e.g. for tests. Skips the `@aws-sdk/client-cloudwatch-logs` auto-import entirely. */\n client?: CloudWatchClientLike;\n}\n\ninterface AWSCloudWatchLogsClientLike {\n send(command: unknown): Promise<unknown>;\n}\n\n/**\n * Ships batched records to AWS CloudWatch Logs via the AWS SDK v3\n * (`@aws-sdk/client-cloudwatch-logs`). Each buffered record becomes one log\n * event; CloudWatch requires events within a single `PutLogEvents` call to be\n * sorted by timestamp ascending, which `sendBatch()` does before sending.\n *\n * `@aws-sdk/client-cloudwatch-logs` is an optional peer dependency: install\n * it yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `CloudWatchLogsClient` wrapped to match `CloudWatchClientLike`).\n */\nexport class CloudWatchTransport extends BatchingTransport {\n readonly logGroupName: string;\n readonly logStreamName: string;\n readonly region: string | undefined;\n private readonly injectedClient: CloudWatchClientLike | undefined;\n private client: CloudWatchClientLike | undefined;\n\n constructor(options: CloudWatchTransportOptions) {\n super(options);\n this.logGroupName = options.logGroupName;\n this.logStreamName = options.logStreamName;\n this.region = options.region;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudWatchClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudWatchClientLike> {\n let ClientCtor: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n let PutLogEventsCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-cloudwatch-logs\";\n const mod = (await import(moduleName)) as unknown as {\n CloudWatchLogsClient: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n PutLogEventsCommand: new (input: unknown) => unknown;\n };\n ClientCtor = mod.CloudWatchLogsClient;\n PutLogEventsCommandCtor = mod.PutLogEventsCommand;\n } catch {\n throw new Error(\n \"CloudWatchTransport: install `@aws-sdk/client-cloudwatch-logs` to use this transport without providing a client — `npm install @aws-sdk/client-cloudwatch-logs`\",\n );\n }\n\n const sdkClient = new ClientCtor({ region: this.region });\n this.client = {\n putLogEvents: (logGroupName, logStreamName, events) =>\n sdkClient.send(\n new PutLogEventsCommandCtor({\n logGroupName,\n logStreamName,\n logEvents: events,\n }),\n ),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const events = batch\n .map((record) => ({\n timestamp: Date.parse(record.timestamp),\n message: this.format(record),\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n await client.putLogEvents(this.logGroupName, this.logStreamName, events);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One GCP Cloud Logging entry, shaped for `Log#write`. */\nexport interface CloudLoggingEntry {\n severity: string;\n timestamp: string;\n jsonPayload: Record<string, unknown>;\n}\n\n/**\n * The subset of the `@google-cloud/logging` client that `CloudLoggingTransport`\n * needs. Deliberately narrower than the SDK's full `Log`/`Entry` object model —\n * `importClient()` builds the real adapter around `logging.log(name).write(entries)`.\n */\nexport interface CloudLoggingClientLike {\n writeLogEntries(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\nexport interface CloudLoggingTransportOptions extends BatchingTransportOptions {\n /** GCP log name (the last segment of the log resource path). Default `\"logquill\"`. */\n logName?: string;\n /** GCP project ID. Passed to the real SDK client; ignored when `client` is injected — omit to use Application Default Credentials' project. */\n projectId?: string;\n /** Pre-built client, e.g. for tests. Skips the `@google-cloud/logging` auto-import entirely. */\n client?: CloudLoggingClientLike;\n}\n\ninterface GCPLogLike {\n write(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\ninterface GCPLoggingLike {\n log(name: string): GCPLogLike;\n}\n\n/** Maps LogQuill's level names onto Cloud Logging's `LogSeverity` enum values. */\nfunction gcpSeverity(levelValue: string): string {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return \"DEBUG\";\n case Level.INFO:\n return \"INFO\";\n case Level.WARN:\n return \"WARNING\";\n case Level.ERROR:\n return \"ERROR\";\n case Level.FATAL:\n return \"CRITICAL\";\n }\n}\n\n/**\n * Ships batched records to Google Cloud Logging via `@google-cloud/logging`.\n * Each record becomes one structured entry (`jsonPayload`), with `level`\n * mapped onto Cloud Logging's `severity` enum.\n *\n * `@google-cloud/logging` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `Log` wrapped to match `CloudLoggingClientLike`).\n */\nexport class CloudLoggingTransport extends BatchingTransport {\n readonly logName: string;\n readonly projectId: string | undefined;\n private readonly injectedClient: CloudLoggingClientLike | undefined;\n private client: CloudLoggingClientLike | undefined;\n\n constructor(options: CloudLoggingTransportOptions = {}) {\n super(options);\n this.logName = options.logName ?? \"logquill\";\n this.projectId = options.projectId;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudLoggingClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudLoggingClientLike> {\n let LoggingCtor: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/logging\";\n const mod = (await import(moduleName)) as unknown as {\n Logging: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n };\n LoggingCtor = mod.Logging;\n } catch {\n throw new Error(\n \"CloudLoggingTransport: install `@google-cloud/logging` to use this transport without providing a client — `npm install @google-cloud/logging`\",\n );\n }\n\n const logging = new LoggingCtor({ projectId: this.projectId });\n const log = logging.log(this.logName);\n this.client = {\n writeLogEntries: (entries) => log.write(entries),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const entries = batch.map((record) => ({\n severity: gcpSeverity(record.level),\n timestamp: record.timestamp,\n jsonPayload: JSON.parse(this.format(record)) as Record<string, unknown>,\n }));\n await client.writeLogEntries(entries);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One Application Insights trace: a message plus its `SeverityLevel`. */\nexport interface AppInsightsTrace {\n message: string;\n severity: number;\n}\n\n/**\n * The subset of Application Insights telemetry that `AppInsightsTransport`\n * needs.\n *\n * `trackTraceBatch` is LogQuill's own batching contract, not a native\n * `applicationinsights` SDK method — the real SDK only exposes a single-record\n * `trackTrace()` plus an async `flush()`. The real-client adapter built by\n * `importClient()` loops `trackTrace()` calls inside `trackTraceBatch` and\n * flushes once at the end, so batching happens at the LogQuill buffering\n * level (bounded by `maxRecords`/`maxBytes`), not as a real network-level\n * batch call — Application Insights doesn't offer one.\n */\nexport interface AppInsightsClientLike {\n trackTraceBatch(traces: readonly AppInsightsTrace[]): Promise<unknown>;\n}\n\nexport interface AppInsightsTransportOptions extends BatchingTransportOptions {\n /** Azure Application Insights connection string. Passed to the real SDK client; ignored when `client` is injected. */\n connectionString?: string;\n /** Pre-built client, e.g. for tests. Skips the `applicationinsights` auto-import entirely. */\n client?: AppInsightsClientLike;\n}\n\ninterface AzureTelemetryClientLike {\n trackTrace(telemetry: AppInsightsTrace): void;\n flush(): void;\n}\n\n/** Maps LogQuill's level names onto Application Insights' `SeverityLevel` enum values. */\nfunction appInsightsSeverity(levelValue: string): number {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return 0; // Verbose\n case Level.INFO:\n return 1; // Information\n case Level.WARN:\n return 2; // Warning\n case Level.ERROR:\n return 3; // Error\n case Level.FATAL:\n return 4; // Critical\n }\n}\n\n/**\n * Ships batched records to Azure Application Insights via `applicationinsights`,\n * as trace telemetry with `level` mapped onto Application Insights' severity\n * scale. See `AppInsightsClientLike` for why \"batch\" means LogQuill-side\n * buffering plus a loop of single `trackTrace()` calls, not one network batch\n * request — the underlying SDK has no batch-track API.\n *\n * `applicationinsights` is an optional peer dependency: install it yourself,\n * or inject a `client` (e.g. a fake, or an already-configured `TelemetryClient`\n * wrapped to match `AppInsightsClientLike`).\n */\nexport class AppInsightsTransport extends BatchingTransport {\n readonly connectionString: string | undefined;\n private readonly injectedClient: AppInsightsClientLike | undefined;\n private client: AppInsightsClientLike | undefined;\n\n constructor(options: AppInsightsTransportOptions = {}) {\n super(options);\n this.connectionString = options.connectionString;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AppInsightsClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<AppInsightsClientLike> {\n let TelemetryClientCtor: new (connectionString?: string) => AzureTelemetryClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"applicationinsights\";\n const mod = (await import(moduleName)) as unknown as {\n TelemetryClient: new (connectionString?: string) => AzureTelemetryClientLike;\n };\n TelemetryClientCtor = mod.TelemetryClient;\n } catch {\n throw new Error(\n \"AppInsightsTransport: install `applicationinsights` to use this transport without providing a client — `npm install applicationinsights`\",\n );\n }\n\n const telemetryClient = new TelemetryClientCtor(this.connectionString);\n this.client = {\n trackTraceBatch: (traces) => {\n for (const trace of traces) {\n telemetryClient.trackTrace(trace);\n }\n telemetryClient.flush();\n return Promise.resolve();\n },\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const traces = batch.map((record) => ({\n message: this.format(record),\n severity: appInsightsSeverity(record.level),\n }));\n await client.trackTraceBatch(traces);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one batch of formatted lines to Datadog's Logs intake API at `url`. Swap in a fake for tests. */\nexport type DatadogSender = (url: string, apiKey: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchDatadogSender(url: string, apiKey: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"DD-API-KEY\": apiKey },\n body: `[${batch.join(\",\")}]`,\n });\n if (!response.ok) {\n throw new Error(\n `DatadogTransport: request to ${url} failed with status ${String(response.status)} — check the API key and site region`,\n );\n }\n}\n\nexport interface DatadogTransportOptions extends BatchingTransportOptions {\n /** Datadog API key, sent in the `DD-API-KEY` header. */\n apiKey: string;\n /**\n * Datadog site (region), e.g. `\"datadoghq.com\"` (US1, default),\n * `\"datadoghq.eu\"` (EU), `\"us3.datadoghq.com\"`, `\"us5.datadoghq.com\"`,\n * `\"ap1.datadoghq.com\"`. Never hardcode this — sending to the wrong\n * region's intake host silently fails to deliver logs to your account.\n */\n site?: string;\n sender?: DatadogSender;\n}\n\n/**\n * Batches records and POSTs them as a JSON array to Datadog's Logs intake\n * API (`https://http-intake.logs.<site>/api/v2/logs`) via `fetch`. Pass\n * `sender` to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class DatadogTransport extends BatchingTransport {\n readonly url: string;\n readonly apiKey: string;\n readonly site: string;\n private readonly sender: DatadogSender;\n\n constructor(options: DatadogTransportOptions) {\n super(options);\n this.apiKey = options.apiKey;\n this.site = options.site ?? \"datadoghq.com\";\n this.url = `https://http-intake.logs.${this.site}/api/v2/logs`;\n this.sender = options.sender ?? fetchDatadogSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const formatted = batch.map((record) => this.format(record));\n return this.sender(this.url, this.apiKey, formatted);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one pre-built NDJSON `_bulk` body to `url` with the given headers. Swap in a fake for tests. */\nexport type ElasticsearchSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n) => Promise<void> | void;\n\nasync function fetchElasticsearchSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { ...headers, \"Content-Type\": \"application/x-ndjson\" },\n body,\n });\n if (!response.ok) {\n throw new Error(`ElasticsearchTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\nexport interface ElasticsearchTransportOptions extends BatchingTransportOptions {\n /** Cluster base URL, e.g. `\"https://localhost:9200\"`. */\n node: string;\n /** Index to write into. Default `\"logs\"`. */\n index?: string;\n /** Elasticsearch API key (base64 `id:api_key`), sent as `Authorization: ApiKey <apiKey>`. Omit to send no auth header (e.g. behind a proxy that adds its own). */\n apiKey?: string;\n sender?: ElasticsearchSender;\n}\n\n/**\n * Batches records and POSTs them to Elasticsearch's `_bulk` API\n * (`<node>/_bulk`) via `fetch`, as newline-delimited action+source pairs —\n * no client dependency needed, just NDJSON body construction. Pass `sender`\n * to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class ElasticsearchTransport extends BatchingTransport {\n readonly url: string;\n readonly index: string;\n private readonly apiKey: string | undefined;\n private readonly sender: ElasticsearchSender;\n\n constructor(options: ElasticsearchTransportOptions) {\n super(options);\n this.index = options.index ?? \"logs\";\n this.url = `${options.node.replace(/\\/+$/, \"\")}/_bulk`;\n this.apiKey = options.apiKey;\n this.sender = options.sender ?? fetchElasticsearchSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const lines: string[] = [];\n for (const record of batch) {\n lines.push(JSON.stringify({ index: { _index: this.index } }));\n lines.push(this.format(record));\n }\n // The bulk API requires a trailing newline after the final action/source pair.\n const body = `${lines.join(\"\\n\")}\\n`;\n const headers: Record<string, string> = {};\n if (this.apiKey !== undefined) {\n headers.Authorization = `ApiKey ${this.apiKey}`;\n }\n return this.sender(this.url, headers, body);\n }\n}\n","import { gzipSync } from \"node:zlib\";\nimport { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Which New Relic ingest region to send to — determines the Log API host. */\nexport type NewRelicRegion = \"US\" | \"EU\";\n\n/** What `NewRelicSender` reports back about one delivery attempt, so the transport can drive its own 429 backoff logic. */\nexport interface NewRelicSenderResult {\n ok: boolean;\n status: number;\n /** The raw `Retry-After` response header value, if present — either a number of seconds or an HTTP-date, per RFC 9110. */\n retryAfter: string | null;\n}\n\n/** Sends one gzip-compressed batch to New Relic's Log API at `url`. Swap in a fake for tests. */\nexport type NewRelicSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n) => Promise<NewRelicSenderResult> | NewRelicSenderResult;\n\nasync function fetchNewRelicSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n): Promise<NewRelicSenderResult> {\n const response = await fetch(url, { method: \"POST\", headers, body });\n return {\n ok: response.ok,\n status: response.status,\n retryAfter: response.headers.get(\"retry-after\"),\n };\n}\n\n/** Returns a copy of `record` with the reserved `meta.eventType` key removed, leaving the original record untouched. */\nfunction withoutEventType(record: LogRecord): LogRecord {\n const meta = { ...record.meta };\n delete meta.eventType;\n return { ...record, meta };\n}\n\n/** Resolves a `Retry-After` header value (seconds, or an HTTP-date) to an absolute epoch-ms resume time. */\nfunction resumeTimestamp(retryAfter: string | null, now: number): number {\n if (retryAfter === null) {\n // New Relic blocks further sends for the rest of that calendar minute on\n // a rate-limit breach even when the header is missing — 60s is a safe floor.\n return now + 60_000;\n }\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n return now + seconds * 1000;\n }\n const dateMs = Date.parse(retryAfter);\n return Number.isNaN(dateMs) ? now + 60_000 : dateMs;\n}\n\nexport interface NewRelicTransportOptions extends BatchingTransportOptions {\n /** New Relic license key, sent in the `Api-Key` header. */\n licenseKey: string;\n /**\n * New Relic account region — selects the ingest host\n * (`log-api.newrelic.com` for US, `log-api.eu.newrelic.com` for EU).\n * Never hardcode this: an EU-region license key sent to the US host (or\n * vice versa) is rejected. Default `\"US\"`.\n */\n region?: NewRelicRegion;\n sender?: NewRelicSender;\n /** Injectable clock for the 429 backoff window, matching `SamplingPlugin`'s injectable `rng`. Default `Date.now`. */\n clock?: () => number;\n}\n\n/**\n * Batches records and POSTs them, gzip-compressed, to New Relic's Log API\n * (`log-api.newrelic.com` / `log-api.eu.newrelic.com`, region-configurable)\n * via `fetch`. Strips the reserved `meta.eventType` key (New Relic drops\n * records carrying it) and honors 429 responses by reading `Retry-After`\n * and pausing further sends until it elapses, rather than hammering an\n * account that's already been rate-limited for the rest of the minute.\n *\n * Pass `sender` to swap in a fake for tests, and `clock` to control time in\n * backoff tests without waiting on a real clock.\n */\nexport class NewRelicTransport extends BatchingTransport {\n readonly url: string;\n readonly region: NewRelicRegion;\n private readonly licenseKey: string;\n private readonly sender: NewRelicSender;\n private readonly clock: () => number;\n private pausedUntil: number | null = null;\n\n constructor(options: NewRelicTransportOptions) {\n super(options);\n this.licenseKey = options.licenseKey;\n this.region = options.region ?? \"US\";\n this.url =\n this.region === \"EU\" ? \"https://log-api.eu.newrelic.com/log/v1\" : \"https://log-api.newrelic.com/log/v1\";\n this.sender = options.sender ?? fetchNewRelicSender;\n this.clock = options.clock ?? Date.now;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const now = this.clock();\n if (this.pausedUntil !== null && now < this.pausedUntil) {\n console.error(\n `NewRelicTransport: sends paused until ${new Date(this.pausedUntil).toISOString()} after a 429 rate-limit response — skipping this batch rather than making a doomed request`,\n );\n return;\n }\n this.pausedUntil = null;\n\n const records = batch.map((record) => withoutEventType(record));\n const body = gzipSync(Buffer.from(JSON.stringify(records)));\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n \"Api-Key\": this.licenseKey,\n };\n\n const result = await this.sender(this.url, headers, body);\n\n if (result.status === 429) {\n this.pausedUntil = resumeTimestamp(result.retryAfter, now);\n console.error(\n `NewRelicTransport: received 429 from New Relic — pausing sends until ${new Date(this.pausedUntil).toISOString()}. Reduce log volume or increase batching to stay under the rate limit.`,\n );\n return;\n }\n\n if (!result.ok) {\n throw new Error(\n `NewRelicTransport: request to ${this.url} failed with status ${String(result.status)} — check the license key and region`,\n );\n }\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Level, parseLevel } from \"../core/levels.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\nconst COLORS: Readonly<Record<Level, string>> = {\n [Level.TRACE]: \"\\x1b[90m\", // gray\n [Level.DEBUG]: \"\\x1b[36m\", // cyan\n [Level.INFO]: \"\\x1b[32m\", // green\n [Level.WARN]: \"\\x1b[33m\", // yellow\n [Level.ERROR]: \"\\x1b[31m\", // red\n [Level.FATAL]: \"\\x1b[35m\", // magenta\n};\nconst RESET = \"\\x1b[0m\";\n\n/** The subset of `console` this transport needs — swap in a fake for tests. */\nexport interface ConsoleLike {\n log(message: string): void;\n error(message: string): void;\n}\n\nexport interface ConsoleTransportOptions {\n formatter?: Formatter;\n colorize?: boolean;\n console?: ConsoleLike;\n}\n\nfunction defaultColorize(): boolean {\n // Isomorphic guard: `process` doesn't exist in a browser bundle.\n const env: NodeJS.ProcessEnv | undefined = typeof process === \"undefined\" ? undefined : process.env;\n return env?.NO_COLOR === undefined;\n}\n\n/**\n * Writes to `console.log`, routing ERROR/FATAL to `console.error`, colorized by\n * level. Uses the global `console` rather than Node's `process.stdout`/`stderr`\n * so this transport works unmodified in a browser bundle.\n */\nexport class ConsoleTransport extends Transport {\n colorize: boolean;\n private readonly out: ConsoleLike;\n\n constructor(options: ConsoleTransportOptions = {}) {\n super(options.formatter);\n this.colorize = options.colorize ?? defaultColorize();\n this.out = options.console ?? console;\n }\n\n write(formatted: string, record: LogRecord): void {\n const level = parseLevel(record.level);\n const line = this.colorize ? this.applyColor(formatted, level) : formatted;\n if (level >= Level.ERROR) {\n this.out.error(line);\n } else {\n this.out.log(line);\n }\n }\n\n private applyColor(formatted: string, level: Level): string {\n return `${COLORS[level]}${formatted}${RESET}`;\n }\n}\n","import { closeSync, existsSync, fstatSync, mkdirSync, openSync, renameSync, unlinkSync, writeSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\nexport interface FileTransportOptions {\n formatter?: Formatter;\n maxBytes?: number;\n backupCount?: number;\n}\n\n/** Appends formatted records to a file, rotating when it exceeds `maxBytes`. */\nexport class FileTransport extends Transport {\n readonly path: string;\n readonly maxBytes: number;\n readonly backupCount: number;\n private fd: number;\n\n constructor(path: string, options: FileTransportOptions = {}) {\n super(options.formatter);\n this.path = path;\n this.maxBytes = options.maxBytes ?? 10 * 1024 * 1024;\n this.backupCount = options.backupCount ?? 5;\n mkdirSync(dirname(path), { recursive: true });\n this.fd = openSync(this.path, \"a\");\n }\n\n write(formatted: string): void {\n writeSync(this.fd, formatted + \"\\n\");\n if (this.maxBytes > 0 && fstatSync(this.fd).size >= this.maxBytes) {\n this.rotate();\n }\n }\n\n private rotate(): void {\n closeSync(this.fd);\n\n if (this.backupCount > 0) {\n for (let index = this.backupCount - 1; index > 0; index--) {\n const src = `${this.path}.${String(index)}`;\n const dst = `${this.path}.${String(index + 1)}`;\n if (existsSync(src)) {\n if (existsSync(dst)) {\n unlinkSync(dst);\n }\n renameSync(src, dst);\n }\n }\n const backup = `${this.path}.1`;\n if (existsSync(backup)) {\n unlinkSync(backup);\n }\n renameSync(this.path, backup);\n } else {\n unlinkSync(this.path);\n }\n\n this.fd = openSync(this.path, \"a\");\n }\n\n override close(): void {\n closeSync(this.fd);\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Sends one batch of formatted lines to `url`. Swap in a fake for tests. */\nexport type Sender = (url: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchSender(url: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-ndjson\" },\n body: batch.join(\"\\n\"),\n });\n if (!response.ok) {\n throw new Error(`HTTPTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\nexport interface HTTPTransportOptions {\n formatter?: Formatter;\n batchSize?: number;\n sender?: Sender;\n}\n\n/**\n * Batches formatted records and POSTs them as newline-delimited JSON via `fetch`.\n * Pass `sender` to swap in a fake for tests, or a different backend.\n */\nexport class HTTPTransport extends Transport {\n readonly url: string;\n readonly batchSize: number;\n private readonly sender: Sender;\n private batch: string[] = [];\n\n constructor(url: string, options: HTTPTransportOptions = {}) {\n super(options.formatter);\n this.url = url;\n this.batchSize = options.batchSize ?? 50;\n this.sender = options.sender ?? fetchSender;\n }\n\n write(formatted: string): void {\n this.batch.push(formatted);\n if (this.batch.length >= this.batchSize) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached `batchSize`. */\n flush(): void {\n if (this.batch.length === 0) {\n return;\n }\n const batch = this.batch;\n this.batch = [];\n\n const result = this.sender(this.url, batch);\n if (result) {\n result.catch((error: unknown) => {\n // write()/close() are non-blocking by contract, so a send failure can't\n // propagate to the caller — report it the same way a broken plugin would.\n console.error(\"HTTPTransport: failed to send log batch\", error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"./levels.js\";\nimport type { Plugin } from \"./plugin.js\";\nimport { createRecord, type LogRecord } from \"./records.js\";\nimport type { Transport } from \"../transports/transport.js\";\n\nexport interface LoggerOptions {\n level?: LevelInput;\n transports?: Transport[];\n plugins?: Plugin[];\n meta?: Record<string, unknown>;\n}\n\nexport class Logger {\n readonly name: string;\n readonly transports: Transport[];\n readonly plugins: Plugin[];\n private currentLevel: Level;\n private readonly baseMeta: Record<string, unknown>;\n\n constructor(name: string, options: LoggerOptions = {}) {\n this.name = name;\n this.currentLevel = parseLevel(options.level ?? Level.INFO);\n this.transports = options.transports ? [...options.transports] : [];\n this.plugins = options.plugins ? [...options.plugins] : [];\n this.baseMeta = options.meta ? { ...options.meta } : {};\n }\n\n get level(): Level {\n return this.currentLevel;\n }\n\n setLevel(level: LevelInput): void {\n this.currentLevel = parseLevel(level);\n }\n\n /** Register a plugin. Returns `this` so calls can be chained. */\n use(plugin: Plugin): this {\n this.plugins.push(plugin);\n return this;\n }\n\n /** Close every attached transport. Call on shutdown to flush buffered writes. */\n close(): void {\n for (const transport of this.transports) {\n transport.close();\n }\n }\n\n /** A logger scoped under this one, inheriting its level, transports, and plugins. */\n child(name: string, meta: Record<string, unknown> = {}): Logger {\n return new Logger(`${this.name}.${name}`, {\n level: this.currentLevel,\n transports: this.transports,\n plugins: this.plugins,\n meta: { ...this.baseMeta, ...meta },\n });\n }\n\n private notifyError(plugin: Plugin, error: unknown, record: LogRecord): void {\n // a broken error handler must not crash logging either\n try {\n plugin.onError?.(error, record);\n } catch {\n /* swallowed */\n }\n }\n\n private dispatch(level: Level, message: string, meta: Record<string, unknown>): LogRecord | null {\n if (level < this.currentLevel) {\n return null;\n }\n\n let record = createRecord({\n level,\n logger: this.name,\n message,\n meta: { ...this.baseMeta, ...meta },\n });\n\n for (const plugin of this.plugins) {\n let result: LogRecord | null;\n try {\n result = plugin.beforeLog ? plugin.beforeLog(record) : record;\n } catch (error) {\n this.notifyError(plugin, error, record);\n continue;\n }\n if (result === null) {\n return null;\n }\n record = result;\n }\n\n for (const transport of this.transports) {\n transport.write(transport.format(record), record);\n }\n\n for (const plugin of this.plugins) {\n try {\n plugin.afterLog?.(record);\n } catch (error) {\n this.notifyError(plugin, error, record);\n }\n }\n\n return record;\n }\n\n trace(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.TRACE, message, meta);\n }\n\n debug(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.DEBUG, message, meta);\n }\n\n info(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, meta);\n }\n\n warn(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.WARN, message, meta);\n }\n\n error(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.ERROR, message, meta);\n }\n\n fatal(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.FATAL, message, meta);\n }\n}\n","export { Level, levelName, parseLevel } from \"./core/levels.js\";\nexport type { LevelInput } from \"./core/levels.js\";\n\nexport { createRecord, utcTimestamp } from \"./core/records.js\";\nexport type { LogRecord } from \"./core/records.js\";\n\nexport { JSONFormatter } from \"./core/formatter.js\";\nexport type { Formatter } from \"./core/formatter.js\";\n\nexport type { Plugin } from \"./core/plugin.js\";\n\nexport { ContextPlugin } from \"./plugins/context-plugin.js\";\n\nexport { DEFAULT_REDACTED_KEYS, RedactPlugin } from \"./plugins/redact-plugin.js\";\nexport type { RedactPluginOptions } from \"./plugins/redact-plugin.js\";\n\nexport { SamplingPlugin } from \"./plugins/sampling-plugin.js\";\nexport type { SamplingPluginOptions } from \"./plugins/sampling-plugin.js\";\n\nexport { CollectingTransport, Transport } from \"./transports/transport.js\";\n\nexport { BatchingTransport } from \"./transports/batching-transport.js\";\nexport type { BatchingTransportOptions } from \"./transports/batching-transport.js\";\n\nexport { BaseSQLTransport } from \"./transports/sql/base-sql-transport.js\";\nexport type { BaseSQLTransportOptions, SQLLogRow } from \"./transports/sql/base-sql-transport.js\";\n\nexport { SQLiteTransport } from \"./transports/sql/sqlite-transport.js\";\nexport type {\n SQLiteClientLike,\n SQLiteStatementLike,\n SQLiteTransportOptions,\n} from \"./transports/sql/sqlite-transport.js\";\n\nexport { PostgresTransport } from \"./transports/sql/postgres-transport.js\";\nexport type { PgClientLike, PostgresTransportOptions } from \"./transports/sql/postgres-transport.js\";\n\nexport { MySQLTransport } from \"./transports/sql/mysql-transport.js\";\nexport type { MySQLClientLike, MySQLTransportOptions } from \"./transports/sql/mysql-transport.js\";\n\nexport { MongoDBTransport } from \"./transports/nosql/mongodb-transport.js\";\nexport type {\n MongoClientLike,\n MongoCollectionLike,\n MongoDBTransportOptions,\n} from \"./transports/nosql/mongodb-transport.js\";\n\nexport { DynamoDBTransport } from \"./transports/nosql/dynamodb-transport.js\";\nexport type {\n DynamoClientLike,\n DynamoLogItem,\n DynamoDBTransportOptions,\n} from \"./transports/nosql/dynamodb-transport.js\";\n\nexport { RedisTransport } from \"./transports/nosql/redis-transport.js\";\nexport type { RedisClientLike, RedisTransportOptions } from \"./transports/nosql/redis-transport.js\";\n\nexport { BaseQueueTransport } from \"./transports/queue/base-queue-transport.js\";\nexport type { BaseQueueTransportOptions } from \"./transports/queue/base-queue-transport.js\";\n\nexport { KafkaTransport } from \"./transports/queue/kafka-transport.js\";\nexport type { KafkaProducerLike, KafkaTransportOptions } from \"./transports/queue/kafka-transport.js\";\n\nexport { RabbitMQTransport } from \"./transports/queue/rabbitmq-transport.js\";\nexport type { AmqpChannelLike, RabbitMQTransportOptions } from \"./transports/queue/rabbitmq-transport.js\";\n\nexport { SQSTransport } from \"./transports/queue/sqs-transport.js\";\nexport type { SQSClientLike, SQSTransportOptions } from \"./transports/queue/sqs-transport.js\";\n\nexport { PubSubTransport } from \"./transports/queue/pubsub-transport.js\";\nexport type { PubSubTopicLike, PubSubTransportOptions } from \"./transports/queue/pubsub-transport.js\";\n\nexport { CloudWatchTransport } from \"./transports/cloud/cloudwatch-transport.js\";\nexport type {\n CloudWatchClientLike,\n CloudWatchLogEvent,\n CloudWatchTransportOptions,\n} from \"./transports/cloud/cloudwatch-transport.js\";\n\nexport { CloudLoggingTransport } from \"./transports/cloud/cloud-logging-transport.js\";\nexport type {\n CloudLoggingClientLike,\n CloudLoggingEntry,\n CloudLoggingTransportOptions,\n} from \"./transports/cloud/cloud-logging-transport.js\";\n\nexport { AppInsightsTransport } from \"./transports/cloud/app-insights-transport.js\";\nexport type {\n AppInsightsClientLike,\n AppInsightsTrace,\n AppInsightsTransportOptions,\n} from \"./transports/cloud/app-insights-transport.js\";\n\nexport { DatadogTransport } from \"./transports/cloud/datadog-transport.js\";\nexport type { DatadogSender, DatadogTransportOptions } from \"./transports/cloud/datadog-transport.js\";\n\nexport { ElasticsearchTransport } from \"./transports/cloud/elasticsearch-transport.js\";\nexport type {\n ElasticsearchSender,\n ElasticsearchTransportOptions,\n} from \"./transports/cloud/elasticsearch-transport.js\";\n\nexport { NewRelicTransport } from \"./transports/cloud/new-relic-transport.js\";\nexport type {\n NewRelicRegion,\n NewRelicSender,\n NewRelicSenderResult,\n NewRelicTransportOptions,\n} from \"./transports/cloud/new-relic-transport.js\";\n\nexport { ConsoleTransport } from \"./transports/console-transport.js\";\nexport type { ConsoleLike, ConsoleTransportOptions } from \"./transports/console-transport.js\";\n\nexport { FileTransport } from \"./transports/file-transport.js\";\nexport type { FileTransportOptions } from \"./transports/file-transport.js\";\n\nexport { HTTPTransport } from \"./transports/http-transport.js\";\nexport type { HTTPTransportOptions, Sender } from \"./transports/http-transport.js\";\n\nexport { Logger } from \"./core/logger.js\";\nexport type { LoggerOptions } from \"./core/logger.js\";\n\nexport const VERSION = \"0.2.0\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "logquill",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A logging framework with an identical mental model and JSON log shape across Node/TypeScript and Python.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,6 +21,58 @@
|
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=18"
|
|
23
23
|
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"pg": "^8.11.0",
|
|
26
|
+
"mysql2": "^3.9.0",
|
|
27
|
+
"mongodb": "^6.0.0",
|
|
28
|
+
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
29
|
+
"redis": "^4.6.0 || ^5.0.0",
|
|
30
|
+
"kafkajs": "^2.2.0",
|
|
31
|
+
"amqplib": "^0.10.0",
|
|
32
|
+
"@aws-sdk/client-sqs": "^3.600.0",
|
|
33
|
+
"@google-cloud/pubsub": "^4.0.0",
|
|
34
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.0.0",
|
|
35
|
+
"@google-cloud/logging": "^11.0.0",
|
|
36
|
+
"applicationinsights": "^3.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"pg": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"mysql2": {
|
|
43
|
+
"optional": true
|
|
44
|
+
},
|
|
45
|
+
"mongodb": {
|
|
46
|
+
"optional": true
|
|
47
|
+
},
|
|
48
|
+
"@aws-sdk/client-dynamodb": {
|
|
49
|
+
"optional": true
|
|
50
|
+
},
|
|
51
|
+
"redis": {
|
|
52
|
+
"optional": true
|
|
53
|
+
},
|
|
54
|
+
"kafkajs": {
|
|
55
|
+
"optional": true
|
|
56
|
+
},
|
|
57
|
+
"amqplib": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"@aws-sdk/client-sqs": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"@google-cloud/pubsub": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"@aws-sdk/client-cloudwatch-logs": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@google-cloud/logging": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"applicationinsights": {
|
|
73
|
+
"optional": true
|
|
74
|
+
}
|
|
75
|
+
},
|
|
24
76
|
"repository": {
|
|
25
77
|
"type": "git",
|
|
26
78
|
"url": "git+https://github.com/nikhilvdev/logquill-js.git"
|