@kb-labs/commit-core 2.72.0 → 2.74.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/dist/applier/index.d.ts +1 -1
- package/dist/generator/index.d.ts +2 -2
- package/dist/generator/index.js +6 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/{heuristics-C9M8f0KK.d.ts → heuristics-AM06lXSo.d.ts} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-CEjOl41u.d.ts → types-CBjdZMSt.d.ts} +4 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/generator/commit-tools.ts","../../src/analyzer/git-status.ts","../../src/analyzer/file-summary.ts","../../src/analyzer/recent-commits.ts","../../src/generator/llm-prompt.ts","../../src/generator/heuristics.ts","../../src/generator/pattern-detector.ts","../../src/analyzer/secrets-detector.ts","../../src/utils/prompt.ts","../../src/generator/commit-plan.ts"],"names":["simpleGit","group"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwStB,IAAM,uBAAA,GAA0B,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmQhC,SAAS,WAAA,CACd,WACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;;AAAA,uJAAA,CAAA;AAGX;AAKO,SAAS,mBAAA,CACd,SAAA,EACA,eAAA,EACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAGJ,EAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,UAAA,GAAa,GAAA,GAC7C;;AAAA,wCAAA,EAAA,CAAyC,eAAA,CAAgB,UAAA,GAAa,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,cAAA,EAC3E,gBAAgB,WAAW;AAAA,uBAAA,EAClB,eAAA,CAAgB,iBAAiB,SAAS;;AAAA;AAAA,EAGjE,eAAA,CAAgB,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,SAAA,EAAO,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;;AAAA,qFAAA,CAAA,GAGjD,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;;AAAA,uJAAA,CAAA;AAGb;AAKO,SAAS,mBAAA,CACd,SAAA,EACA,KAAA,EACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,CAAA,CAC3C,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,IAAI,CAAA,KAAM;AAErB,IAAA,MAAM,UAAU,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,OAAA,EAAS,SAAA,GAAY,oCAAA,GAAuC,iCAAA;AAG/E,IAAA,MAAM,aAAA,GAAgB,KAAK,MAAA,GAAS,GAAA,GAChC,KAAK,KAAA,CAAM,CAAA,EAAG,GAAI,CAAA,GAAI,mBAAA,GACtB,IAAA;AACJ,IAAA,OAAO,CAAA,IAAA,EAAO,IAAI,CAAA,EAAG,UAAU;AAAA;AAAA,EAAiB,aAAa;AAAA,MAAA,CAAA;AAAA,EAC/D,CAAC,CAAA,CACA,IAAA,CAAK,MAAM,CAAA;AAEd,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;;AAAA;AAAA,EAGT,WAAW;;AAAA,sEAAA,CAAA;AAGb;AAgBA,SAAS,kBAAkB,WAAA,EAA6B;AACtD,EAAA,IAAI,OAAA,GAAU,YAAY,IAAA,EAAK;AAG/B,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA;AACjD,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AACxC,EAAA,OAAA,GAAU,QAAQ,IAAA,EAAK;AAGvB,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,WAAA,CAAY,GAAG,CAAA;AAEvC,EAAA,IAAI,SAAA,KAAc,EAAA,IAAM,OAAA,KAAY,EAAA,IAAM,YAAY,OAAA,EAAS;AAC7D,IAAA,OAAA,GAAU,OAAA,CAAQ,SAAA,CAAU,SAAA,EAAW,OAAA,GAAU,CAAC,CAAA;AAAA,EACpD;AAGA,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,cAAA,EAAgB,IAAI,CAAA;AAE9C,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,aAAA,CACd,QAAA,EACA,SAAA,EACA,eAAA,EACmB;AAEnB,EAAA,MAAM,OAAA,GAAU,kBAAkB,QAAQ,CAAA;AAG1C,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AAEd,IAAA,MAAM,OAAA,GAAU,QAAQ,SAAA,CAAU,CAAA,EAAG,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC5D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,gDAAA,EACa,OAAO,CAAA,EAAG,OAAA,CAAQ,SAAS,GAAA,GAAM,KAAA,GAAQ,EAAE,CAAA,SAAA,EAC9C,iBAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,KAClE;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,OAAO,OAAA,IAAW,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AACrD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2CAAA,EACQ,KAAK,SAAA,CAAU,MAAM,EAAE,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,KAClD;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,IAAI,OAAO,gBAAA,EAAkB;AAE3B,MAAA,OAAO;AAAA,QACL,gBAAA,EAAkB,IAAA;AAAA,QAClB,cAAA,EAAgB,MAAM,OAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,GAAI,MAAA,CAAO,iBAAiB,EAAC;AAAA,QAChF,SAAS,EAAC;AAAA,QACV,iBAAA,EAAmB;AAAA,OACrB;AAAA,IACF;AAEA,IAAA,MAAM,IAAI,MAAM,sEAAsE,CAAA;AAAA,EACxF;AAIA,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,QAAiC,KAAA,KAAkB;AAErF,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,8BAAA,CAAgC,CAAA;AAAA,IACrE;AACA,IAAA,IAAI,CAAC,OAAO,KAAA,IAAS,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,qCAAA,CAAuC,CAAA;AAAA,IAC5E;AACA,IAAA,IAAI,MAAA,CAAO,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,sBAAA,CAAwB,CAAA;AAAA,IAC7D;AACA,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,iCAAA,CAAmC,CAAA;AAAA,IACxE;AAGA,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,MAAA,CAAO,IAAc,CAAA;AAChD,IAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AAGrB,IAAA,MAAM,YAAY,MAAA,CAAO,SAAA;AACzB,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,UAAA,GAAa,GAAA;AAEjB,IAAA,IAAI,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAE9C,MAAA,UAAA,GAAa,OAAO,SAAA,CAAU,UAAA,KAAe,QAAA,GAAW,UAAU,UAAA,GAAa,GAAA;AAE/E,MAAA,eAAA,GAAkB;AAAA,QAChB,WAAA,EAAa,OAAA,CAAQ,SAAA,CAAU,WAAW,CAAA;AAAA,QAC1C,QAAA,EAAU,OAAA,CAAQ,SAAA,CAAU,QAAQ,CAAA;AAAA,QACpC,YAAA,EAAc,OAAA,CAAQ,SAAA,CAAU,YAAY,CAAA;AAAA,QAC5C,aAAa,OAAO,SAAA,CAAU,WAAA,KAAgB,QAAA,GAAW,UAAU,WAAA,GAAc,yBAAA;AAAA,QACjF;AAAA,OACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,UAAA,GAAa,OAAO,MAAA,CAAO,UAAA,KAAe,QAAA,GAAW,OAAO,UAAA,GAAa,GAAA;AAAA,IAC3E;AAEA,IAAA,OAAO;AAAA,MACL,EAAA,EAAK,MAAA,CAAO,EAAA,IAAiB,CAAA,CAAA,EAAI,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC1C,IAAA;AAAA,MACA,OAAO,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,OAAO,KAAA,GAAQ,MAAA;AAAA,MACzD,SAAS,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,GAAW,OAAO,OAAA,GAAU,cAAA;AAAA,MAC/D,MAAM,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,GAAO,MAAA;AAAA,MACtD,KAAA;AAAA,MACA,WAAA,EAAa,oBAAA,CAAqB,MAAA,CAAO,WAAqB,CAAA;AAAA,MAC9D,QAAA,EAAU,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,MACjC,SAAA,EAAW,eAAA;AAAA,MACX;AAAA;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,EAAa,MAA8B,GAAA,IAAO,CAAA,CAAE,UAAA,IAAc,GAAA,CAAA,EAAM,CAAC,CAAA;AACjH,EAAA,MAAM,oBAAoB,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,eAAA,GAAkB,QAAQ,MAAA,GAAS,CAAA;AAGlF,EAAA,MAAM,qBAAA,GAAwB,SAAA,GAC1B,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAA4C,aAAA,CAAc,CAAA,EAAG,SAAA,EAAW,eAAe,CAAC,CAAA,GACrG,OAAA;AAGJ,EAAA,MAAM,wBAAA,GAA0C,qBAAA,CAAsB,GAAA,CAAI,CAAC,CAAA,KAA4C;AACrH,IAAA,MAAM,EAAE,UAAA,EAAY,CAAA,EAAG,GAAG,QAAO,GAAI,CAAA;AAErC,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,OAAA,CAAQ,MAAA,CAAO,gBAAgB,CAAA;AAAA,IACjD,cAAA,EAAgB,MAAM,OAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,GAAI,MAAA,CAAO,iBAAiB,EAAC;AAAA,IAChF,OAAA,EAAS,wBAAA;AAAA,IACT;AAAA,GACF;AACF;AAOA,SAAS,aAAA,CACP,MAAA,EACA,SAAA,EACA,eAAA,EACG;AAEH,EAAA,MAAM,cAAc,MAAA,CAAO,KAAA;AAC3B,EAAA,MAAM,eAAA,GAAkB,UAAU,MAAA,CAAO,CAAC,MAAM,WAAA,CAAY,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAE5E,EAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAChC,IAAA,OAAO,MAAA;AAAA,EACT;AAIA,EAAA,IAAI,OAAO,IAAA,KAAS,MAAA,IAAU,OAAO,UAAA,GAAa,GAAA,IAAO,OAAO,SAAA,EAAW;AACzE,IAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAc,QAAA,KAAa,MAAA,CAAO,SAAA;AAGvD,IAAA,IAAI,YAAA,IAAgB,CAAC,WAAA,EAAa;AAChC,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,+CAAA;AAAA;AAClE,OACF;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,IAAY,CAAC,WAAA,EAAa;AAC5B,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,KAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,sBAAA;AAAA;AAClE,OACF;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,iCAAA;AAAA;AAClE,OACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AACtE,EAAA,IAAI,UAAA,IAAc,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AACxC,IAAA,OAAO;AAAA,MACL,GAAG,MAAA;AAAA,MACH,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA,CAAQ,UAAU,SAAS,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,UAAU;AAAA,KACrF;AAAA,EACF;AAGA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC9E,EAAA,MAAM,cAAA,GAAiB,gBAAgB,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC9E,EAAA,MAAM,eAAe,cAAA,GAAiB,cAAA;AAEtC,EAAA,IAAI,eAAe,CAAA,EAAG;AACpB,IAAA,MAAM,gBAAgB,cAAA,GAAiB,YAAA;AAGvC,IAAA,IAAI,aAAA,GAAgB,GAAA,IAAO,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AACjD,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAIA,EAAA,IAAI,eAAA,IAAmB,eAAA,CAAgB,UAAA,GAAa,GAAA,IAAO,gBAAgB,aAAA,EAAe;AACxF,IAAA,MAAM,UAAU,MAAA,CAAO,IAAA;AACvB,IAAA,MAAM,cAAc,eAAA,CAAgB,aAAA;AAGpC,IAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,cAAc,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,UAAU,CAAA;AAExE,EAAA,IAAI,WAAA,IAAe,YAAA,GAAe,CAAA,IAAK,MAAA,CAAO,SAAS,MAAA,EAAQ;AAC7D,IAAA,MAAM,gBAAgB,cAAA,GAAiB,YAAA;AAGvC,IAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAIA,IAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAIA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAElF,EAAA,IAAI,cAAA,IAAkB,eAAA,CAAgB,MAAA,IAAU,EAAA,EAAI;AAClD,IAAA,MAAM,WAAW,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AAClE,IAAA,MAAM,eAAe,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,IAAI,CAAA;AAGtE,IAAA,IAAI,QAAA,IAAY,YAAA,IAAgB,MAAA,CAAO,IAAA,KAAS,OAAA,EAAS;AACvD,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,MAAM,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,MAAM;AAAA,OACrF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,cAAc,IAAA,EAAiC;AACtD,EAAA,MAAM,UAAA,GAAiC;AAAA,IACrC,MAAA;AAAA,IAAQ,KAAA;AAAA,IAAO,UAAA;AAAA,IAAY,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,MAAA;AAAA,IAAQ,OAAA;AAAA,IAAS,IAAA;AAAA,IAAM;AAAA,GACrE;AAEA,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAM,UAAA,GAAa,KAAK,WAAA,EAAY;AACpC,IAAA,IAAI,UAAA,CAAW,QAAA,CAAS,UAAU,CAAA,EAAG;AACnC,MAAA,OAAO,UAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,qBAAqB,IAAA,EAAqD;AACjF,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAM,UAAA,GAAa,KAAK,WAAA,EAAY;AACpC,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA,CAAE,QAAA,CAAS,UAAU,CAAA,EAAG;AAC5D,MAAA,OAAO,UAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;ACn+BO,SAAS,sBAAsB,SAAA,EAAyC;AAC7E,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,MAAM,EAAE,aAAA,EAAe,cAAA,EAAe,GAAI,wBAAwB,SAAS,CAAA;AAE3E,EAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA,EAAM,OAAA;AAAA,MACN,OAAO,iBAAA,CAAkB,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,MAC/C,OAAA,EAAS,qBAAA;AAAA,MACT,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,MAAA;AAAA,MACb,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,4BAA4B,cAAc,CAAA;AAElF,EAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAC,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AACpD,IAAA,MAAM,IAAA,GAAO,qBAAqB,QAAQ,CAAA;AAE1C,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA;AAAA,MACA,OAAO,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,MACxC,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,KAAK,CAAA;AAAA,MACpC,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,gBAAA,CAAiB,IAAW,CAAA;AAAA,MACzC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,aAAa,CAAA;AAEpD,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,CAAA,IAAK,cAAA,EAAgB;AAC9C,IAAA,MAAM,IAAA,GAAO,eAAe,QAAQ,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,WAAW,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAEjD,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,KAAK,CAAA;AAAA,MACpC,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,gBAAA,CAAiB,IAAW,CAAA;AAAA,MACzC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,wBAAwB,SAAA,EAG/B;AACA,EAAA,MAAM,YAAA,GAAe,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAC1E,EAAA,MAAM,UAAA,GAAa,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAEzE,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,IAAA,OAAO,EAAE,aAAA,EAAe,EAAC,EAAG,gBAAgB,SAAA,EAAU;AAAA,EACxD;AAEA,EAAA,MAAM,gBAAiC,EAAC;AACxC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAiB;AAErC,EAAA,KAAA,MAAW,WAAW,YAAA,EAAc;AAClC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AAGnC,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK;AACrC,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA;AAE9B,MAAA,OAAO,OAAA,KAAY,MAAA,IAAU,OAAA,CAAQ,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,IAC9D,CAAC,CAAA;AAGD,IAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK;AACxC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAC5B,MAAA,OACE,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,KAAK,QAAA,CAAS,UAAU,CAAA,IACxB,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,IACrB,IAAA,CAAK,WAAW,GAAG,CAAA;AAAA,IAEvB,CAAC,CAAA;AAED,IAAA,MAAM,KAAA,GAAQ,CAAC,OAAA,EAAS,GAAG,aAAa,CAAA;AACxC,IAAA,aAAA,CAAc,KAAK,KAAK,CAAA;AAExB,IAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AACnB,IAAA,aAAA,CAAc,OAAA,CAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AAE5D,EAAA,OAAO,EAAE,eAAe,cAAA,EAAe;AACzC;AAKA,SAAS,4BAA4B,SAAA,EAGnC;AACA,EAAA,MAAM,YAAY,SAAA,CAAU,MAAA,CAAO,OAAK,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AAC1D,EAAA,MAAM,SAAA,GAAY,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AAE3D,EAAA,MAAM,eAAgC,EAAC;AACvC,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAiB;AACzC,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAiB;AAEzC,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,MAAM,QAAA,GAAW,qBAAA,CAAsB,QAAA,CAAS,IAAI,CAAA;AACpD,IAAA,MAAM,WAAW,SAAA,CAAU,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAExD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,YAAA,CAAa,IAAA,CAAK,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AACtC,MAAA,WAAA,CAAY,IAAI,QAAQ,CAAA;AACxB,MAAA,WAAA,CAAY,IAAI,QAAQ,CAAA;AAAA,IAC1B;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAgB;AAAA,IACpB,GAAG,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IAC5C,GAAG,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC;AAAA,GAC9C;AAEA,EAAA,OAAO,EAAE,cAAc,aAAA,EAAc;AACvC;AAKA,SAAS,WAAW,IAAA,EAAuB;AACzC,EAAA,OACE,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,SAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA;AAE/B;AAMA,SAAS,sBAAsB,QAAA,EAA0B;AAEvD,EAAA,IAAI,QAAA,GAAW,SACZ,OAAA,CAAQ,0BAAA,EAA4B,KAAK,CAAA,CACzC,OAAA,CAAQ,4BAA4B,KAAK,CAAA;AAG5C,EAAA,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA;AAE9C,EAAA,OAAO,QAAA;AACT;AAKA,SAAS,gBAAgB,SAAA,EAAsD;AAC7E,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAE9C,EAAA,KAAA,MAAW,WAAW,SAAA,EAAW;AAC/B,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,OAAA,CAAQ,IAAI,CAAA;AAC5C,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,QAAQ,KAAK,EAAC;AAC1C,IAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AACrB,IAAA,MAAA,CAAO,GAAA,CAAI,UAAU,QAAQ,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,kBAAkB,KAAA,EAAqC;AAC9D,EAAA,MAAM,cAAc,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,QAAA,CAAS,cAAc,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAC,WAAA,EAAa;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAIpC,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,GAAG,CAAA;AACnC,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,qBAAqB,IAAA,EAAsC;AAClE,EAAA,IAAI,CAAC,IAAA,EAAM;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAE3B,EAAA,MAAM,EAAE,SAAA,EAAW,SAAA,EAAW,MAAA,EAAO,GAAI,IAAA;AAGzC,EAAA,IAAI,MAAA,KAAW,OAAA,IAAY,SAAA,GAAY,CAAA,IAAK,cAAc,CAAA,EAAI;AAC5D,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,MAAA,KAAW,SAAA,IAAc,SAAA,GAAY,CAAA,IAAK,cAAc,CAAA,EAAI;AAC9D,IAAA,OAAO,OAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,OAAO,UAAA;AACT;AAKA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AACxB,EAAA,MAAM,IAAA,GAAO,SAAS,IAAI,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AAGxB,EAAA,IACE,KAAK,QAAA,CAAS,QAAQ,KACtB,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,SAAS,WAAW,CAAA,IACzB,IAAI,QAAA,CAAS,QAAQ,KACrB,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,EACtB;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,KAAA,IAAS,GAAA,CAAI,SAAS,QAAQ,CAAA,IAAK,SAAS,WAAA,EAAa;AACnE,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IACE,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IACnB,KAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,CAAC,gBAAgB,eAAA,EAAiB,kBAAkB,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,EACnE;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAGA,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AAC7E,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC/E,IAAA,OAAO,OAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAS,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,MAAA;AACpC,EAAA,OAAO,OAAO,MAAM,CAAA,CAAA;AACtB;AAKA,SAAS,eAAe,QAAA,EAAoC;AAC1D,EAAA,IAAI,aAAa,MAAA,EAAQ;AAAC,IAAA,OAAO,MAAA;AAAA,EAAO;AACxC,EAAA,IAAI,aAAa,MAAA,EAAQ;AAAC,IAAA,OAAO,MAAA;AAAA,EAAO;AACxC,EAAA,IAAI,aAAa,QAAA,EAAU;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAC3C,EAAA,IAAI,aAAa,IAAA,EAAM;AAAC,IAAA,OAAO,IAAA;AAAA,EAAK;AACpC,EAAA,IAAI,aAAa,OAAA,EAAS;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAC1C,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,WAAW,KAAA,EAAqC;AACvD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAG1C,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,QAAQ,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACnD,EAAA,MAAM,QAAA,GAAW,KAAK,CAAC,CAAA;AACvB,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAEjC,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,OAAO,SAAS,MAAA,GAAS,CAAA,GAAI,SAAS,CAAC,CAAA,GAAI,SAAS,CAAC,CAAA;AAAA,EACvD;AAGA,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAA;AACvD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AAClC,IAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,IAAA,IAAI,OAAA,IAAW,KAAK,KAAA,CAAM,CAAC,MAAM,CAAA,CAAE,CAAC,CAAA,KAAM,OAAO,CAAA,EAAG;AAClD,MAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA;AAClD,IAAA,IAAI,KAAA,IAAS,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,KAAA,EAAO;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,eAAA,CAAgB,MAAwB,KAAA,EAA8B;AAC7E,EAAA,MAAM,QAAQ,KAAA,CAAM,MAAA;AAGpB,EAAA,MAAM,WAAW,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AACxD,EAAA,MAAM,aAAa,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AAE5D,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,IAAI,QAAA,EAAU;AAAC,MAAA,OAAO,OAAO,KAAK,CAAA,UAAA,EAAa,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,IAAG;AACtE,IAAA,OAAO,UAAU,KAAK,CAAA,UAAA,EAAa,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,IAAI,QAAA,EAAU;AAAC,MAAA,OAAO,CAAA,iBAAA,CAAA;AAAA,IAAoB;AAC1C,IAAA,OAAO,CAAA,oBAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,IAAA,EAAM;AACjB,IAAA,OAAO,CAAA,uBAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,OAAO,CAAA,0BAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,EAAG;AACtD,MAAA,OAAO,CAAA,mBAAA,CAAA;AAAA,IACT;AACA,IAAA,OAAO,CAAA,oBAAA,CAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAO,OAAO,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO,UAAU,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,UAAU,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AACpD;AAKA,SAAS,gBAAA,CACP,MACA,MAAA,EACsC;AACtC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,MAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;;;AClYO,SAAS,gBAAgB,SAAA,EAA2C;AACzE,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,OAAA;AAAA,MACb,UAAA,EAAY,CAAA;AAAA,MACZ,OAAO,EAAC;AAAA,MACR,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAKA,EAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,EAAG;AAClC,IAAA,MAAM,WAAA,GAAc,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,EAAG,IAAA;AAC1E,IAAA,MAAM,WAAA,GAAc,WAAA,GAAc,kBAAA,CAAmB,WAAW,CAAA,GAAI,SAAA;AAEpE,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,aAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,yBAAyB,WAAW,CAAA,CAAA;AAAA,QACpC,CAAA,EAAG,UAAU,MAAM,CAAA,iCAAA,CAAA;AAAA,QACnB,2CAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,SAAA,EAAW,CAAC,CAAA;AACzC,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,eAAA;AAAA,MACb,UAAA,EAAY,GAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,CAAA,mBAAA,EAAsB,UAAU,MAAM,CAAA,YAAA,CAAA;AAAA,QACtC,CAAA,uCAAA,CAAA;AAAA,QACA,kBAAkB,IAAI,CAAA,SAAA,EAAY,IAAA,KAAS,CAAA,GAAI,MAAM,KAAK,CAAA,CAAA;AAAA,QAC1D;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,6BAAA,CAA8B,SAAS,CAAA,EAAG;AAC5C,IAAA,MAAM,KAAA,GAAQ,uBAAuB,SAAS,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,iBAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,kCAAA;AAAA,QACA,CAAA,oBAAA,EAAA,CAAwB,KAAA,GAAQ,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,QAC/C,wCAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAC9D,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,uBAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAClE,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAClE,EAAA,MAAM,aAAA,GAAgB,YAAY,QAAA,GAAW,QAAA,CAAA;AAE7C,EAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,CAAA,kBAAA,EAAA,CAAsB,aAAA,GAAgB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,QACrD;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,OAAA;AAAA,IACb,UAAA,EAAY,CAAA;AAAA,IACZ,OAAO,EAAC;AAAA,IACR,aAAA,EAAe;AAAA,GACjB;AACF;AAYO,SAAS,oBAAoB,SAAA,EAAmC;AAErE,EAAA,MAAM,cAAA,GAAiB,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAC1E,EAAA,IAAI,CAAC,cAAA,EAAgB;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGnC,EAAA,IAAI,SAAA,CAAU,SAAS,EAAA,EAAI;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGzC,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,OAAO,CAAA;AAC1D,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAG7B,EAAA,MAAM,eAAe,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,cAAc,IAAI,CAAA;AAC9D,EAAA,IAAI,CAAC,YAAA,EAAc;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAIjC,EAAA,MAAM,eAAA,GAAkB,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,CAAG,IAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,KAAA,CAAM,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAGnE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,UAAA,CAAW,UAAA,GAAa,GAAG,CAAC,CAAA;AAChF,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,MAAA,GAAS,SAAA,CAAU,MAAA;AAEzD,EAAA,OAAO,cAAA,GAAiB,GAAA;AAC1B;AAWO,SAAS,kBAAkB,SAAA,EAAmC;AAEnE,EAAA,IAAI,SAAA,CAAU,SAAS,EAAA,EAAI;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGzC,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,OAAO,CAAA;AAC1D,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAG7B,EAAA,MAAM,cAAc,SAAA,CAAU,MAAA,CAAO,OAAK,CAAA,CAAE,SAAA,KAAc,KAAK,CAAA,CAAE,MAAA;AACjE,EAAA,MAAM,WAAA,GAAc,cAAc,SAAA,CAAU,MAAA;AAC5C,EAAA,IAAI,eAAe,GAAA,EAAK;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGtC,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,SAAA,EAAW,CAAC,CAAA;AAC/C,EAAA,OAAO,UAAA,GAAa,CAAA;AACtB;AASO,SAAS,8BAA8B,SAAA,EAAmC;AAE/E,EAAA,MAAM,cAAc,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,UAAU,CAAA;AAChE,EAAA,IAAI,CAAC,WAAA,EAAa;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGhC,EAAA,MAAM,aAAA,GAAgB,uBAAuB,SAAS,CAAA;AACtD,EAAA,OAAO,aAAA,GAAgB,GAAA;AACzB;AAeO,SAAS,eAAA,CAAgB,WAA0B,KAAA,EAAuB;AAC/E,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,EAAA,KAAA,MAAW,WAAW,SAAA,EAAW;AAC/B,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACpC,IAAA,IAAI,KAAA,CAAM,UAAU,KAAA,EAAO;AACzB,MAAA,MAAM,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,KAAK,CAAA,CAAE,KAAK,GAAG,CAAA;AAC9C,MAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAQO,SAAS,uBAAuB,SAAA,EAAkC;AACvE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AACxE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AACxE,EAAA,MAAM,eAAe,cAAA,GAAiB,cAAA;AAEtC,EAAA,IAAI,iBAAiB,CAAA,EAAG;AAAC,IAAA,OAAO,CAAA;AAAA,EAAE;AAElC,EAAA,OAAO,cAAA,GAAiB,YAAA;AAC1B;AAQA,SAAS,mBAAmB,IAAA,EAAsB;AAChD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,OAAA,CAAQ,cAAc,CAAA;AAErD,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,gBAAA,GAAmB,CAAC,CAAA;AAC9C,IAAA,OAAO,WAAA,IAAe,SAAA;AAAA,EACxB;AAEA,EAAA,OAAO,SAAA;AACT;ACtQO,IAAM,oBAAA,GAAN,MAAM,qBAAA,SAA6B,KAAA,CAAM;AAAA,EAC9B,aAAA;AAAA,EAEhB,WAAA,CAAY,SAAwB,OAAA,EAAiB;AACnD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAA;AAGrB,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,qBAAoB,CAAA;AAAA,IACpD;AAAA,EACF;AACF,CAAA;AAmBA,IAAM,oBAAA,GAAuB;AAAA;AAAA,EAE3B,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAGA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,qBAAA;AAAA;AAAA,EAGA,kBAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,sBAAA;AAAA;AAAA,EAGA,YAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAGA,UAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA;AAAA,EAGA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA;AAKA,IAAM,uBAAA,GAAoE;AAAA;AAAA,EAExE,EAAE,OAAA,EAAS,4CAAA,EAA8C,IAAA,EAAM,SAAA,EAAU;AAAA,EACzE,EAAE,OAAA,EAAS,+CAAA,EAAiD,IAAA,EAAM,YAAA,EAAa;AAAA,EAC/E,EAAE,OAAA,EAAS,iDAAA,EAAmD,IAAA,EAAM,cAAA,EAAe;AAAA;AAAA,EAGnF,EAAE,OAAA,EAAS,kBAAA,EAAoB,IAAA,EAAM,mBAAA,EAAoB;AAAA,EACzD,EAAE,OAAA,EAAS,oCAAA,EAAsC,IAAA,EAAM,uBAAA,EAAwB;AAAA;AAAA,EAG/E,EAAE,OAAA,EAAS,wCAAA,EAA0C,IAAA,EAAM,gBAAA,EAAiB;AAAA,EAC5E,EAAE,OAAA,EAAS,sBAAA,EAAwB,IAAA,EAAM,WAAA,EAAY;AAAA;AAAA,EAGrD,EAAE,OAAA,EAAS,6BAAA,EAA+B,IAAA,EAAM,cAAA,EAAe;AAAA;AAAA,EAG/D,EAAE,OAAA,EAAS,uDAAA,EAAyD,IAAA,EAAM,aAAA,EAAc;AAAA;AAAA,EAGxF,EAAE,OAAA,EAAS,sDAAA,EAAwD,IAAA,EAAM,aAAA,EAAc;AAAA;AAAA,EAGvF,EAAE,OAAA,EAAS,uBAAA,EAAyB,IAAA,EAAM,UAAA,EAAW;AAAA;AAAA,EAGrD,EAAE,OAAA,EAAS,qBAAA,EAAuB,IAAA,EAAM,QAAA;AAC1C,CAAA;AAKO,SAAS,aAAa,QAAA,EAA2B;AAEtD,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAElD,EAAA,OAAO,oBAAA,CAAqB,IAAA;AAAA,IAAK,CAAC,YAChC,SAAA,CAAU,cAAA,EAAgB,SAAS,EAAE,SAAA,EAAW,MAAM;AAAA,GACxD;AACF;AAaO,SAAS,kBAAkB,KAAA,EAA2B;AAC3D,EAAA,OAAO,KAAA,CAAM,OAAO,YAAY,CAAA;AAClC;AAuBO,SAAS,qBAAqB,WAAA,EAA+B;AAClE,EAAA,MAAM,QAAQ,WAAA,CAAY,MAAA;AAC1B,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,OAAO,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,+CAAwC,KAAK,CAAA,gCAAA,CAAA;AAAA,IAC7C,SAAA;AAAA,IACA,EAAA;AAAA,IACA,wCAAA;AAAA,IACA,EAAA;AAAA,IACA,oEAAA;AAAA,IACA,mDAAA;AAAA,IACA,EAAA;AAAA,IACA,wBAAA;AAAA,IACA,oCAAA;AAAA,IACA,wEAAA;AAAA,IACA,gFAAA;AAAA,IACA,EAAA;AAAA,IACA,oFAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAMO,SAAS,0BACd,KAAA,EACe;AACf,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,KAAA,CAAM,SAAQ,EAAG;AAC1C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE7B,IAAA,KAAA,IAAS,SAAA,GAAY,CAAA,EAAG,SAAA,GAAY,KAAA,CAAM,QAAQ,SAAA,EAAA,EAAa;AAC7D,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,SAAS,CAAA,IAAK,EAAA;AAEjC,MAAA,KAAA,MAAW,EAAE,OAAA,EAAS,IAAA,EAAK,IAAK,uBAAA,EAAyB;AAEvD,QAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AAEpB,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAC/B,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,MAAM,WAAA,GAAc,MAAM,CAAC,CAAA;AAC3B,UAAA,MAAM,SAAS,KAAA,CAAM,KAAA;AAGrB,UAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,EAAE,CAAA;AAC5C,UAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,IAAA,CAAK,QAAQ,MAAA,GAAS,WAAA,CAAY,SAAS,EAAE,CAAA;AACzE,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,YAAA,EAAc,UAAU,CAAA;AAGvD,UAAA,MAAM,WAAA,GAAc,YAAY,MAAA,GAAS,EAAA,GACrC,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA,GAAI,KAAA,GAC/B,WAAA;AAEJ,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,IAAA;AAAA,YACA,MAAM,SAAA,GAAY,CAAA;AAAA;AAAA,YAClB,QAAQ,MAAA,GAAS,CAAA;AAAA;AAAA,YACjB,SAAS,OAAA,CAAQ,MAAA;AAAA,YACjB,WAAA,EAAa,IAAA;AAAA,YACb,OAAA,EAAS,QAAQ,IAAA,EAAK;AAAA,YACtB,WAAA,EAAa;AAAA,WACd,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,oBAAoB,OAAA,EAAgC;AAClE,EAAA,MAAM,QAAQ,OAAA,CAAQ,MAAA;AACtB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,IAAA;AAEpD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,CAAA,4CAAA,EAAwC,KAAK,CAAA,wBAAA,EAA2B,SAAS,CAAA,QAAA,CAAA;AAAA,IACjF,EAAA;AAAA,IACA,wCAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAC9C,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,WAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,EAAC;AAC5C,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AACnB,IAAA,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,QAAQ,CAAA;AAAA,EACjC;AAGA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,WAAW,CAAA,IAAK,MAAA,CAAO,SAAQ,EAAG;AAClD,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAM,IAAI,CAAA,CAAA,CAAG,CAAA;AACxB,IAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAC/B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,MAAM,CAAA,GAAA,EAAM,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AACxE,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,MAAM,OAAA,CAAQ,MAAA,GAAS,EAAA,GAAK,KAAA,GAAQ,EAAE,CAAA,CAAE,CAAA;AACpG,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,gBAAA,EAAmB,KAAA,CAAM,OAAO,CAAA,GAAA,CAAK,CAAA;AAChD,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,8EAAA;AAAA,IACA,mDAAA;AAAA,IACA,EAAA;AAAA,IACA,wBAAA;AAAA,IACA,yFAAA;AAAA,IACA,iFAAA;AAAA,IACA,gFAAA;AAAA,IACA,EAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;ACjSA,eAAsB,sBAAA,CACpB,QAAA,EACA,YAAA,GAAwB,KAAA,EACxB,cAAuB,KAAA,EACL;AAElB,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA,4BAAA,CAA8B,CAAA;AACrD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAc,QAAA,CAAA,eAAA,CAAgB;AAAA,IAClC,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,QAAQ,OAAA,CAAQ;AAAA,GACjB,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,eAAe,OAAA,GAAU,OAAA;AAC7C,EAAA,MAAM,YAAA,GAAe,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,WAAW,CAAA,EAAA,CAAA;AAE/C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,EAAA,CAAG,QAAA,CAAS,YAAA,EAAc,CAAC,MAAA,KAAW;AACpC,MAAA,EAAA,CAAG,KAAA,EAAM;AAET,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,EAAK,CAAE,WAAA,EAAY;AAE7C,MAAA,IAAI,eAAe,EAAA,EAAI;AACrB,QAAA,OAAA,CAAQ,YAAY,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,KAAA,EAAO;AAC9C,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,IAAA,EAAM;AAC7C,QAAA,OAAA,CAAQ,KAAK,CAAA;AACb,QAAA;AAAA,MACF;AAGA,MAAA,OAAA,CAAQ,YAAY,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;;;ACxBA,IAAM,oBAAA,GAAuB,GAAA;AAG7B,IAAM,eAAA,GAAkB,CAAA;AACxB,IAAM,kBAAA,mBAAqB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,MAAM,CAAC,CAAA;AAE9G,SAAS,kBAAkB,EAAA,EAA4C;AACrE,EAAA,IAAI,CAAC,EAAA,EAAI;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAC7B,EAAA,MAAM,OAAA,GAAU,GAAG,IAAA,EAAK;AACxB,EAAA,IAAI,CAAC,OAAA,EAAS;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAElC,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA,EAAG;AAC3B,IAAA,OAAO,CAAA,CAAA,EAAI,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA;AAAA,EACvC;AAEA,EAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AACzB,IAAA,OAAO,IAAI,OAAO,CAAA,CAAA;AAAA,EACpB;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,qBAAqB,KAAA,EAAyB;AACrD,EAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA;AACzB,EAAA,MAAM,QAAA,GAAW,YAAY,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,SAAA,GAAY,OAAA;AACvE,EAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAI,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAA,GAAK,CAAA,OAAA,EAAU,MAAM,MAAM,CAAA,MAAA,CAAA;AAC3E;AAEA,SAAS,iBAAA,CACP,QACA,EAAA,EACoB;AACpB,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,OAAO,KAAK,CAAA,GACpC,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAyB,OAAO,IAAA,KAAS,QAAA,IAAY,KAAK,MAAA,GAAS,CAAC,IACzF,EAAC;AACL,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,IAAY,kBAAA,CAAmB,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,GAC9E,MAAA,CAAO,IAAA,GACP,OAAA;AACJ,EAAA,MAAM,UAAU,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,IAAY,OAAO,OAAA,CAAQ,IAAA,EAAK,CAAE,MAAA,GAAS,IACjF,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAK,GACpB,qBAAqB,WAAW,CAAA;AACpC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,WAAA,KACrB,IAAA,KAAS,MAAA,GAAS,UAAW,IAAA,KAAS,KAAA,IAAS,IAAA,KAAS,UAAA,GAAa,OAAA,GAAU,MAAA,CAAA;AAErF,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,OAAA;AAAA,IACA,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,KAAA,EAAO,WAAA;AAAA,IACP,WAAA;AAAA,IACA,QAAA,EAAU,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,IACjC,SAAA,EAAW,OAAO,SAAA,IAAa;AAAA,MAC7B,WAAA,EAAa,KAAA;AAAA,MACb,QAAA,EAAU,KAAA;AAAA,MACV,YAAA,EAAc,IAAA;AAAA,MACd,WAAA,EAAa,8EAAA;AAAA,MACb,UAAA,EAAY;AAAA;AACd,GACF;AACF;AAMA,eAAsB,mBAAmB,OAAA,EAA+C;AACtF,EAAA,MAAM,EAAE,GAAA,EAAK,UAAA,EAAW,GAAI,OAAA;AAE5B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAG3B,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,CAAa,GAAG,CAAA;AACxC,EAAA,MAAM,QAAA,GAAW,mBAAmB,SAAS,CAAA;AAE7C,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,OAAO,eAAA,CAAgB,KAAK,SAAS,CAAA;AAAA,EACvC;AAGA,EAAA,MAAM,WAAA,GAAc,kBAAkB,QAAQ,CAAA;AAE9C,EAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAE1B,IAAA,MAAM,YAAA,GAA8B,WAAA,CAAY,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,MAC3D,IAAA;AAAA,MACA,IAAA,EAAM,CAAA;AAAA,MACN,MAAA,EAAQ,CAAA;AAAA,MACR,OAAA,EAAS,qBAAA;AAAA,MACT,WAAA,EAAa,qBAAA;AAAA,MACb,OAAA,EAAS,EAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf,CAAE,CAAA;AAEF,IAAA,MAAM,OAAA,GAAU,qBAAqB,WAAW,CAAA;AAChD,IAAA,MAAM,OAAO,KAAA,CAAM,4BAAA,EAAuB,IAAI,KAAA,CAAM,kBAAkB,CAAA,EAAG;AAAA,MACvE;AAAA,KACD,CAAA;AACD,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,GAAO,OAAA,GAAU,IAAI,CAAA;AAGnC,IAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AAEzB,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR,YAAA;AAAA,QACA,CAAA,oBAAA,EAAuB,YAAY,MAAM,CAAA,iFAAA;AAAA,OAC3C;AAAA,IACF;AAGA,IAAA,OAAA,CAAQ,IAAI,0DAAgD,CAAA;AAC5D,IAAA,MAAM,YAAY,MAAM,sBAAA;AAAA,MACtB,CAAA,sCAAA,EAA+B,YAAY,MAAM,CAAA,kCAAA,CAAA;AAAA,MACjD;AAAA;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,SAAA,EAAW;AAEd,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR,YAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,CAAO,KAAK,mEAAA,EAAqE;AAAA,MACrF,WAAA;AAAA,MACA,WAAA,EAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACrC,CAAA;AACD,IAAA,OAAA,CAAQ,IAAI,gEAA2D,CAAA;AAAA,EACzE;AAGA,EAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAiB,GAAA,EAAK,QAAQ,CAAA;AAGtD,EAAA,MAAM,eAAA,GAAkB,gBAAgB,SAAS,CAAA;AAGjD,EAAA,IAAI,eAAA,CAAgB,aAAa,GAAA,EAAK;AACpC,IAAA,MAAM,SAAA,EAAW,MAAM,yBAAA,EAA2B;AAAA,MAChD,aAAa,eAAA,CAAgB,WAAA;AAAA,MAC7B,YAAY,eAAA,CAAgB,UAAA;AAAA,MAC5B,eAAe,eAAA,CAAgB,aAAA;AAAA,MAC/B,WAAW,SAAA,CAAU,MAAA;AAAA,MACrB,OAAO,eAAA,CAAgB;AAAA,KACxB,CAAA;AAGD,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAA,CAAgB,WAAW,CAAA,cAAA,EAAiB,eAAA,CAAgB,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA,EAAK;AAAA,MAC5H,eAAe,eAAA,CAAgB,aAAA;AAAA,MAC/B,OAAO,eAAA,CAAgB;AAAA,KACxB,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,gBAAgB,OAAA,CAAQ,aAAA,IAAiB,MAAM,gBAAA,CAAiB,KAAK,EAAE,CAAA;AAG7E,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,IAAI;AAEF,MAAA,MAAM,mBAAA,GAAsB,OAAO,GAAA,CAAI,aAAA,KAAkB,UAAA;AAEzD,MAAA,IAAI,MAAA;AAEJ,MAAA,IAAI,mBAAA,EAAqB;AAEvB,QAAA,MAAM,MAAA,CAAO,MAAM,6CAA6C,CAAA;AAChE,QAAA,UAAA,GAAa,gCAAgC,CAAA;AAE7C,QAAA,MAAM,SAAS,MAAM,uBAAA;AAAA,UACnB,GAAA;AAAA,UACA,SAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAA,GAAS,MAAA,CAAO,MAAA;AAChB,QAAA,UAAA,GAAa,MAAA,CAAO,UAAA;AACpB,QAAA,OAAA,GAAU,IAAA;AAAA,MACZ,CAAA,MAAO;AAEL,QAAA,MAAM,MAAA,CAAO,MAAM,qCAAqC,CAAA;AACxD,QAAA,UAAA,GAAa,kCAAkC,CAAA;AAE/C,QAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,SAAA,EAAW,eAAA,EAAiB,aAAa,CAAA;AAE5E,QAAA,MAAM,SAAS,MAAM,YAAA;AAAA,UACnB,MAAM,GAAA,CAAI,QAAA,CAAS,MAAA,EAAQ;AAAA,YACzB,YAAA,EAAc,aAAA;AAAA,YACd,WAAA,EAAa,GAAA;AAAA,YACb,SAAA,EAAW;AAAA,WACZ,CAAA;AAAA,UACD,SAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAA,GAAS,aAAA,CAAc,MAAA,CAAO,OAAA,EAAS,SAAA,EAAW,eAAe,CAAA;AACjE,QAAA,OAAA,GAAU,IAAA;AACV,QAAA,UAAA,GAAa,MAAA,CAAO,UAAA;AAAA,MACtB;AAGA,MAAA,MAAM,iBAAiB,MAAA,CAAO,gBAAA,IACzB,OAAO,iBAAA,GAAoB,oBAAA,IAC3B,UAAU,MAAA,IAAU,EAAA;AAEzB,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,MAAM,MAAA,GAAS,SAAA,CAAU,MAAA,IAAU,EAAA,GAC/B,GAAG,SAAA,CAAU,MAAM,CAAA,iBAAA,CAAA,GACnB,CAAA,WAAA,EAAA,CAAe,MAAA,CAAO,iBAAA,GAAoB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAC7D,QAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,uBAAA,EAA0B,MAAM,CAAA,CAAA,EAAI;AAAA,UACrD,WAAW,SAAA,CAAU,MAAA;AAAA,UACrB,YAAY,MAAA,CAAO,iBAAA;AAAA,UACnB,kBAAkB,MAAA,CAAO,gBAAA;AAAA,UACzB,gBAAgB,MAAA,CAAO;AAAA,SACxB,CAAA;AACD,QAAA,UAAA,GAAa,CAAA,EAAG,MAAM,CAAA,mBAAA,CAAqB,CAAA;AAK3C,QAAA,IAAI,WAAA;AAEJ,QAAA,IAAI,MAAA,CAAO,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAEpC,UAAA,MAAM,UAAA,GAAa,MAAA,CAAO,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,CAAC,CAAC,CAAA;AAC1F,UAAA,WAAA,GAAc,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAEpC,UAAA,IAAI,UAAA,CAAW,SAAS,EAAA,EAAI;AAC1B,YAAA,MAAM,MAAA,CAAO,IAAA,CAAK,CAAA,cAAA,EAAiB,UAAA,CAAW,MAAM,CAAA,qCAAA,CAAA,EAAyC;AAAA,cAC3F,gBAAgB,UAAA,CAAW,MAAA;AAAA,cAC3B,cAAA,EAAgB;AAAA,aACjB,CAAA;AAAA,UACH;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,MAAM,eAAA,GAAkB,CAAC,GAAG,SAAS,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AACpD,YAAA,MAAM,QAAA,GAAA,CAAY,CAAA,CAAE,SAAA,IAAa,CAAA,KAAM,EAAE,SAAA,IAAa,CAAA,CAAA;AACtD,YAAA,MAAM,QAAA,GAAA,CAAY,CAAA,CAAE,SAAA,IAAa,CAAA,KAAM,EAAE,SAAA,IAAa,CAAA,CAAA;AACtD,YAAA,OAAO,QAAA,GAAW,QAAA;AAAA,UACpB,CAAC,CAAA;AAED,UAAA,WAAA,GAAc,eAAA,CAAgB,MAAM,CAAA,EAAG,EAAE,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA;AAE5D,UAAA,MAAM,MAAA,CAAO,MAAM,qDAAA,EAAuD;AAAA,YACxE,YAAY,SAAA,CAAU,MAAA;AAAA,YACtB,eAAe,WAAA,CAAY;AAAA,WAC5B,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,KAAA,GAAQ,MAAM,YAAA,CAAa,GAAA,EAAK,WAAW,CAAA;AAGjD,QAAA,MAAM,aAAA,GAAgB,0BAA0B,KAAK,CAAA;AAErD,QAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAE5B,UAAA,MAAM,MAAA,GAAS,oBAAoB,aAAa,CAAA;AAChD,UAAA,MAAM,OAAO,KAAA,CAAM,4CAAA,EAAuC,IAAI,KAAA,CAAM,iBAAiB,CAAA,EAAG;AAAA,YACtF;AAAA,WACD,CAAA;AACD,UAAA,UAAA,GAAa,oCAA6B,CAAA;AAG1C,UAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,IAAI,CAAA;AAGlC,UAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AAEzB,YAAA,MAAM,IAAI,oBAAA;AAAA,cACR,aAAA;AAAA,cACA,CAAA,oBAAA,EAAuB,cAAc,MAAM,CAAA,8FAAA;AAAA,aAC7C;AAAA,UACF;AAGA,UAAA,OAAA,CAAQ,IAAI,0DAAgD,CAAA;AAC5D,UAAA,MAAM,YAAY,MAAM,sBAAA;AAAA,YACtB,CAAA,2DAAA,EAAoD,cAAc,MAAM,CAAA,qBAAA,CAAA;AAAA,YACxE,KAAA;AAAA;AAAA,YACA,OAAA,CAAQ;AAAA;AAAA,WACV;AAEA,UAAA,IAAI,CAAC,SAAA,EAAW;AAEd,YAAA,MAAM,IAAI,oBAAA;AAAA,cACR,aAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAGA,UAAA,MAAM,MAAA,CAAO,KAAK,kEAAA,EAAoE;AAAA,YACpF,aAAA,EAAe,aAAA,CAAc,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,OAAA,EAAS,CAAA,CAAE,aAAY,CAAE,CAAA;AAAA,YAC9F,WAAA,EAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WACrC,CAAA;AACD,UAAA,OAAA,CAAQ,IAAI,+DAA0D,CAAA;AACtE,UAAA,UAAA,GAAa,6CAA6C,CAAA;AAAA,QAC5D;AAEA,QAAA,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAGlB,UAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,GAAA,CAAI,GAAA,EAAM,GAAA,GAAO,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,EAAE,CAAA,GAAI,GAAG,CAAA;AAErF,UAAA,MAAM,MAAA,CAAO,MAAM,0CAAA,EAA4C;AAAA,YAC7D,eAAe,WAAA,CAAY,MAAA;AAAA,YAC3B;AAAA,WACD,CAAA;AACD,UAAA,UAAA,GAAa,6CAA6C,CAAA;AAE1D,UAAA,IAAI,mBAAA,EAAqB;AAEvB,YAAA,MAAM,iBAAiB,MAAM,6BAAA;AAAA,cAC3B,GAAA;AAAA,cACA,SAAA;AAAA,cACA,KAAA;AAAA,cACA,aAAA;AAAA,cACA,MAAA;AAAA,cACA;AAAA,aACF;AAEA,YAAA,MAAA,GAAS,cAAA,CAAe,MAAA;AACxB,YAAA,UAAA,GAAA,CAAc,UAAA,IAAc,CAAA,KAAM,cAAA,CAAe,UAAA,IAAc,CAAA,CAAA;AAC/D,YAAA,SAAA,GAAY,IAAA;AAAA,UACd,CAAA,MAAO;AAEL,YAAA,MAAM,cAAA,GAAiB,mBAAA,CAAoB,SAAA,EAAW,KAAA,EAAO,aAAa,CAAA;AAE1E,YAAA,MAAM,iBAAiB,MAAM,YAAA;AAAA,cAC3B,MAAM,GAAA,CAAI,QAAA,CAAS,cAAA,EAAgB;AAAA,gBACjC,YAAA,EAAc,uBAAA;AAAA,gBACd,WAAA,EAAa,GAAA;AAAA,gBACb,SAAA,EAAW;AAAA,eACZ,CAAA;AAAA,cACD,SAAA;AAAA,cACA,MAAA;AAAA,cACA;AAAA,aACF;AAEA,YAAA,MAAA,GAAS,aAAA,CAAc,cAAA,CAAe,OAAA,EAAS,SAAA,EAAW,eAAe,CAAA;AACzE,YAAA,UAAA,GAAA,CAAc,UAAA,IAAc,CAAA,KAAM,cAAA,CAAe,UAAA,IAAc,CAAA,CAAA;AAC/D,YAAA,SAAA,GAAY,IAAA;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAA,GAAU,MAAA,CAAO,OAAA;AAGjB,MAAA,OAAA,GAAU,MAAM,qBAAA,CAAsB,OAAA,EAAS,WAAW,GAAA,EAAK,OAAA,EAAS,QAAQ,UAAU,CAAA;AAAA,IAC5F,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,QAAA,MAAM,KAAA;AAAA,MACR;AAGA,MAAA,MAAM,MAAA,CAAO,KAAK,iEAAA,EAAmE;AAAA,QACnF,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC7D,CAAA;AACD,MAAA,UAAA,GAAa,iCAAiC,CAAA;AAC9C,MAAA,OAAA,GAAU,sBAAsB,SAAS,CAAA;AAAA,IAC3C;AAAA,EACF,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,sBAAsB,SAAS,CAAA;AAAA,EAC3C;AAGA,EAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,MAAA,KAAW;AACvD,IAAA,GAAA,CAAI,OAAO,IAAI,CAAA,GAAA,CAAK,IAAI,MAAA,CAAO,IAAI,KAAK,CAAA,IAAK,CAAA;AAC7C,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,EAA4B,CAAA;AAE/B,EAAA,MAAM,SAAA,EAAW,MAAM,4BAAA,EAA8B;AAAA,IACnD,YAAY,SAAA,CAAU,MAAA;AAAA,IACtB,cAAc,OAAA,CAAQ,MAAA;AAAA,IACtB,OAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,IACzB,gBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,KAAA;AAAA,IACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA,EAAU,GAAA;AAAA,IACV,SAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,YAAY,SAAA,CAAU,MAAA;AAAA,MACtB,cAAc,OAAA,CAAQ,MAAA;AAAA,MACtB,OAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA;AACF,GACF;AACF;AAKA,SAAS,eAAA,CAAgB,KAAa,SAAA,EAAkC;AACtE,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,KAAA;AAAA,IACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA,EAAU,GAAA;AAAA,IACV,SAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,QAAA,EAAU;AAAA,MACR,UAAA,EAAY,CAAA;AAAA,MACZ,YAAA,EAAc,CAAA;AAAA,MACd,OAAA,EAAS;AAAA;AACX,GACF;AACF;AAOA,eAAe,wBACb,GAAA,EACA,SAAA,EACA,eAAA,EACA,aAAA,EACA,QACA,WAAA,EAC6D;AAC7D,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AAGA,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,SAAA,EAAW,eAAA,EAAiB,aAAa,CAAA;AAKhF,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,IACjD,KAAA,EAAO,CAAC,gBAAgB,CAAA;AAAA,IACxB,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,KAC3C;AAAA,IACA,WAAA,EAAa;AAAA,GACd,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AAGA,EAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAO1B,EAAA,MAAM,kBAAkB,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM;AAC1D,IAAA,MAAM,UAAA,GAAa,CAAA,CAAE,SAAA,EAAW,UAAA,IAAc,GAAA;AAC9C,IAAA,OAAO,GAAA,GAAM,UAAA;AAAA,EACf,GAAG,CAAC,CAAA;AACJ,EAAA,MAAM,iBAAA,GAAoB,SAAS,OAAA,CAAQ,MAAA,GAAS,IAChD,eAAA,GAAkB,QAAA,CAAS,QAAQ,MAAA,GACnC,CAAA;AAEJ,EAAA,MAAM,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,IAChD,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,cAAA,EAAgB,QAAA,CAAS,cAAA,EAAgB,MAAA,IAAU,CAAA;AAAA,IACnD,YAAA,EAAc,SAAS,OAAA,CAAQ,MAAA;AAAA,IAC/B;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,gBAAA,EAAkB,OAAA,CAAQ,QAAA,CAAS,gBAAgB,CAAA;AAAA,MACnD,cAAA,EAAgB,QAAA,CAAS,cAAA,IAAkB,EAAC;AAAA,MAC5C,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB;AAAA,KACF;AAAA,IACA,UAAA,EAAY,SAAS,KAAA,GAAS,QAAA,CAAS,MAAM,YAAA,GAAe,QAAA,CAAS,MAAM,gBAAA,GAAoB;AAAA,GACjG;AACF;AAOA,eAAe,0BAAA,CACb,GAAA,EACA,gBAAA,EACA,eAAA,EACA,QACA,UAAA,EAC+B;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,sBAAA,GAAyB,eAAA,CAC5B,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,YAAA,GAAe,CAAA,CAAE,KAAA,CAAM,MAAA,IAAU,CAAA,GACnC,EAAE,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GACjB,CAAA,EAAG,CAAA,CAAE,MAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,KAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,KAAA,CAAA;AAC/D,IAAA,OAAO,IAAI,CAAA,CAAE,EAAE,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,EAAG,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,EAAA,EAAK,EAAE,OAAO;AAAA,UAAA,EAAe,YAAY,CAAA,CAAA;AAAA,EACrG,CAAC,CAAA,CACA,IAAA,CAAK,MAAM,CAAA;AAGd,EAAA,MAAM,gBAAA,GAAmB,gBAAA,CACtB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,YAAA,GAAe,CAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,wDAAA,CAAA;AAwDrB,EAAA,MAAM,UAAA,GAAa,CAAA;AAAA,EACnB,sBAAsB;;AAAA,gCAAA,EAEU,iBAAiB,MAAM,CAAA;AAAA,EACvD,gBAAgB;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,2EAAA,CAAA;AAmBhB,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,YAAA,EAAa;AAAA,IACxC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,UAAA;AAAW,GACtC;AAEA,EAAA,IAAI;AACF,IAAA,UAAA,GAAa,0CAA0C,CAAA;AAEvD,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,MACjD,KAAA,EAAO,CAAC,uBAAuB,CAAA;AAAA,MAC/B,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,UAAA;AAAA,QACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,OAC3C;AAAA,MACA,WAAA,EAAa;AAAA,KACd,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,MAAA,MAAM,MAAA,CAAO,KAAK,gDAAgD,CAAA;AAClE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAI1B,IAAA,IAAI,CAAC,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAA,EAAG;AACtD,MAAA,MAAM,MAAA,CAAO,KAAK,qDAAqD,CAAA;AACvE,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,aAA4B,EAAC;AACnC,IAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,IAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,IAAA,KAAA,MAAW,MAAA,IAAU,SAAS,OAAA,EAAS;AACrC,MAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,IAAK,MAAA,CAAO,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7D,QAAA,MAAM,MAAA,CAAO,KAAK,kDAAA,EAAoD;AAAA,UACpE,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,kBAAkB,MAAA,CAAO;AAAA,SAC1B,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,YAAA;AAEhC,MAAA,IAAI,WAAW,iBAAA,EAAmB;AAEhC,QAAA,MAAM,qBAAA,GAAwB,iBAAA,CAAkB,MAAA,CAAO,gBAAgB,CAAA;AACvE,QAAA,MAAM,cAAA,GAAiB,gBAAgB,IAAA,CAAK,CAAA,CAAA,KAAK,kBAAkB,CAAA,CAAE,EAAE,MAAM,qBAAqB,CAAA;AAClG,QAAA,IAAI,cAAA,EAAgB;AAElB,UAAA,cAAA,CAAe,KAAA,CAAM,IAAA,CAAK,GAAG,MAAA,CAAO,KAAK,CAAA;AACzC,UAAA,aAAA,EAAA;AACA,UAAA,MAAM,MAAA,CAAO,MAAM,mCAAA,EAAqC;AAAA,YACtD,UAAU,cAAA,CAAe,EAAA;AAAA,YACzB,SAAS,cAAA,CAAe,OAAA;AAAA,YACxB,UAAA,EAAY,OAAO,KAAA,CAAM;AAAA,WAC1B,CAAA;AAAA,QACH,CAAA,MAAO;AAEL,UAAA,MAAM,MAAA,CAAO,KAAK,oDAAA,EAAsD;AAAA,YACtE,aAAa,MAAA,CAAO,gBAAA;AAAA,YACpB,qBAAA;AAAA,YACA,YAAA,EAAc,gBAAgB,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE;AAAA,WACzD,CAAA;AACD,UAAA,MAAM,UAAA,GAAa,iBAAA;AAAA,YACjB,MAAA;AAAA,YACA,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,WACpD;AACA,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,YAAA,YAAA,EAAA;AAAA,UACF,CAAA,MAAO;AACL,YAAA,MAAM,MAAA,CAAO,KAAK,sDAAA,EAAwD;AAAA,cACxE,aAAa,MAAA,CAAO;AAAA,aACrB,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,MAAM,UAAA,GAAa,iBAAA;AAAA,UACjB,MAAA;AAAA,UACA,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,SACpD;AACA,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,UAAA,YAAA,EAAA;AAAA,QACF,CAAA,MAAO;AACL,UAAA,MAAM,MAAA,CAAO,KAAK,wDAAwD,CAAA;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,CAAO,MAAM,4BAAA,EAA8B;AAAA,MAC/C,KAAA,EAAO,SAAS,OAAA,CAAQ,MAAA;AAAA,MACxB,QAAA,EAAU,aAAA;AAAA,MACV,OAAA,EAAS,YAAA;AAAA,MACT,iBAAiB,UAAA,CAAW;AAAA,KAC7B,CAAA;AAED,IAAA,OAAO,UAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,MAAA,CAAO,KAAK,gCAAA,EAAkC;AAAA,MAClD,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,KAC7D,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAe,8BACb,GAAA,EACA,SAAA,EACA,KAAA,EACA,aAAA,EACA,QACA,WAAA,EAC6D;AAC7D,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AAGA,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,SAAA,EAAW,KAAA,EAAO,aAAa,CAAA;AAGtE,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,IACjD,KAAA,EAAO,CAAC,gBAAgB,CAAA;AAAA,IACxB,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,KAC3C;AAAA,IACA,WAAA,EAAa;AAAA,GACd,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,IAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,EACzE;AAGA,EAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAO1B,EAAA,MAAM,kBAAkB,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM;AAC1D,IAAA,MAAM,UAAA,GAAa,CAAA,CAAE,SAAA,EAAW,UAAA,IAAc,GAAA;AAC9C,IAAA,OAAO,GAAA,GAAM,UAAA;AAAA,EACf,GAAG,CAAC,CAAA;AACJ,EAAA,MAAM,iBAAA,GAAoB,SAAS,OAAA,CAAQ,MAAA,GAAS,IAChD,eAAA,GAAkB,QAAA,CAAS,QAAQ,MAAA,GACnC,CAAA;AAEJ,EAAA,MAAM,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,IAChD,YAAA,EAAc,SAAS,OAAA,CAAQ,MAAA;AAAA,IAC/B;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,gBAAA,EAAkB,KAAA;AAAA;AAAA,MAClB,gBAAgB,EAAC;AAAA,MACjB,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB;AAAA,KACF;AAAA,IACA,UAAA,EAAY,SAAS,KAAA,GAAS,QAAA,CAAS,MAAM,YAAA,GAAe,QAAA,CAAS,MAAM,gBAAA,GAAoB;AAAA,GACjG;AACF;AAgBA,eAAe,sBACb,OAAA,EACA,SAAA,EACA,GAAA,EACA,OAAA,EACA,QACA,UAAA,EACwB;AACxB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAItD,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,QAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,MACtB;AAEA,IACF;AACA,IAAA,MAAA,CAAO,KAAA,GAAQ,UAAA;AAAA,EACjB;AAGA,EAAA,IAAI,eAAA,GAAkB,QAAQ,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAA,CAAM,SAAS,CAAC,CAAA;AAG9D,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,MAAM,aAAsD,EAAC;AAE7D,EAAA,KAAA,MAAW,UAAU,eAAA,EAAiB;AACpC,IAAA,MAAM,cAAwB,EAAC;AAC/B,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,QAAA,WAAA,CAAY,KAAK,IAAI,CAAA;AACrB,QAAA,SAAA,CAAU,IAAI,IAAI,CAAA;AAAA,MACpB,CAAA,MAAO;AACL,QAAA,UAAA,CAAW,KAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,MAC7C;AAAA,IACF;AACA,IAAA,MAAA,CAAO,KAAA,GAAQ,WAAA;AAAA,EACjB;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,aAAA,EAAgB,UAAA,CAAW,MAAM,CAAA,sDAAA,CAAA,EAA0D;AAAA,MACrG,gBAAgB,UAAA,CAAW,MAAA;AAAA,MAC3B,OAAA,EAAS,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,IAAA,EAAO,CAAA,CAAE,MAAM,CAAA,CAAE;AAAA,KACpE,CAAA;AAAA,EACH;AAGA,EAAA,eAAA,GAAkB,gBAAgB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAA,CAAM,SAAS,CAAC,CAAA;AAGlE,EAAA,MAAM,qBAAA,GAAwB,CAAA;AAC9B,EAAA,IAAI,eAAA,GAAkB,CAAA;AAEtB,EAAA,OAAO,kBAAkB,qBAAA,EAAuB;AAE9C,IAAA,MAAM,iBAAA,GAAoB,IAAI,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AACzE,IAAA,MAAM,YAAA,GAAe,SAAA,CAClB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,iBAAA,CAAkB,GAAA,CAAI,CAAC,CAAC,CAAA;AAE1C,IAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE7B,MAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,QAAA,MAAM,MAAA,CAAO,KAAK,+BAAA,EAAiC;AAAA,UACjD,eAAA,EAAiB,eAAA;AAAA,UACjB,cAAc,eAAA,CAAgB;AAAA,SAC/B,CAAA;AAAA,MACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,eAAA,EAAA;AAEA,IAAA,MAAM,OAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAe,CAAA,CAAA,EAAI,qBAAqB,CAAA,CAAA,EAAI;AAAA,MAClF,cAAc,YAAA,CAAa,MAAA;AAAA,MAC3B,cAAA,EAAgB,SAAA,CAAU,MAAA,GAAS,YAAA,CAAa,MAAA;AAAA,MAChD,YAAY,SAAA,CAAU,MAAA;AAAA,MACtB,QAAA,EAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAA,CAAQ,SAAA,CAAU,MAAA,GAAS,YAAA,CAAa,MAAA,IAAU,SAAA,CAAU,MAAA,GAAU,GAAG,CAAC,CAAA,CAAA;AAAA,KAC7F,CAAA;AAGD,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,QAAA,GAAW,KAAK,KAAA,CAAA,CAAQ,SAAA,CAAU,SAAS,YAAA,CAAa,MAAA,IAAU,SAAA,CAAU,MAAA,GAAU,GAAG,CAAA;AAC/F,MAAA,UAAA,CAAW,CAAA,gDAAA,EAAmD,eAAe,CAAA,EAAA,EAAK,QAAQ,CAAA,KAAA,CAAO,CAAA;AAAA,IACnG;AAGA,IAAA,MAAM,gBAAA,GAAmB,UAAU,MAAA,CAAO,CAAC,MAAM,YAAA,CAAa,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAG9E,IAAA,IAAI,cAAA,GAAuC,IAAA;AAE3C,IAAA,IAAI,WAAW,GAAA,EAAK;AAClB,MAAA,cAAA,GAAiB,MAAM,0BAAA;AAAA,QACrB,GAAA;AAAA,QACA,gBAAA;AAAA,QACA,eAAA;AAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,cAAA,IAAkB,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAC/C,QAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAe,CAAA,mBAAA,CAAA,EAAuB;AAAA,UAC5E,aAAa,cAAA,CAAe,MAAA;AAAA,UAC5B,UAAA,EAAY,cAAA,CAAe,MAAA,CAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,CAAM,MAAA,EAAQ,CAAC;AAAA,SACtE,CAAA;AAGD,QAAA,eAAA,CAAgB,IAAA,CAAK,GAAG,cAAc,CAAA;AAAA,MACxC;AAAA,IACF;AAGA,IAAA,MAAM,eAAA,GAAkB,UACrB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,IAAI,GAAA,CAAI,eAAA,CAAgB,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AAEvE,IAAA,IAAI,eAAA,CAAgB,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AAElD,MAAA,MAAM,MAAA,CAAO,KAAK,oDAAA,EAAsD;AAAA,QACtE,SAAA,EAAW,eAAA;AAAA,QACX,cAAc,eAAA,CAAgB;AAAA,OAC/B,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,eAAA,CAAgB,MAAA,IAAU,CAAA,IAAK,eAAA,IAAmB,CAAA,EAAG;AACvD,MAAA,MAAM,MAAA,CAAO,MAAM,iDAAiD,CAAA;AACpE,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,UACvB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,IAAI,GAAA,CAAI,eAAA,CAAgB,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AAEvE,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,MAAA,CAAO,KAAK,kEAAA,EAAoE;AAAA,MACpF,eAAA,EAAiB,eAAA;AAAA,MACjB,gBAAgB,iBAAA,CAAkB;AAAA,KACnC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,kBAAkB,CAAC,CAAA;AACrC,IAAA,MAAM,QAAA,GAAW,YAAY,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,SAAA,GAAY,OAAA;AACvE,IAAA,MAAM,aAAA,GAAgB,kBAAkB,MAAA,KAAW,CAAA,GAC/C,UAAU,QAAQ,CAAA,CAAA,GAClB,CAAA,OAAA,EAAU,iBAAA,CAAkB,MAAM,CAAA,gBAAA,CAAA;AAEtC,IAAA,MAAM,cAAA,GAA8B;AAAA,MAClC,EAAA,EAAI,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,CAAC,CAAA,CAAA;AAAA,MAClC,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,aAAA;AAAA,MACT,KAAA,EAAO,iBAAA;AAAA,MACP,WAAA,EAAa,MAAA;AAAA,MACb,QAAA,EAAU,KAAA;AAAA,MACV,SAAA,EAAW;AAAA,QACT,WAAA,EAAa,KAAA;AAAA,QACb,QAAA,EAAU,KAAA;AAAA,QACV,YAAA,EAAc,IAAA;AAAA,QACd,WAAA,EAAa,8BAA8B,eAAe,CAAA,uBAAA,EAA0B,kBAAkB,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,kBAAkB,MAAA,GAAS,CAAA,GAAI,QAAQ,iBAAA,CAAkB,MAAA,GAAS,CAAC,CAAA,KAAA,CAAA,GAAU,EAAE,CAAA,CAAA;AAAA,QAC9M,UAAA,EAAY;AAAA;AACd,KACF;AAEA,IAAA,eAAA,CAAgB,KAAK,cAAc,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,eAAA;AACT;AAMA,eAAe,YAAA,CACb,KAAA,EACA,KAAA,EACA,MAAA,EACA,UAAA,EACmD;AACnD,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,eAAA,EAAiB,OAAA,EAAA,EAAW;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,EAAM;AAG3B,MAAA,aAAA,CAAc,OAAO,OAAO,CAAA;AAG5B,MAAA,IAAI,UAAU,CAAA,EAAG;AACf,QAAA,MAAM,MAAA,CAAO,MAAM,CAAA,EAAG,KAAK,yBAAyB,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AAAA,MAClF;AACA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAGpE,MAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAA+B,OAAO,KAAK,SAAA,EAAW;AAAA,QACvE,WAAW,SAAA,CAAU,IAAA;AAAA,QACrB,cAAc,SAAA,CAAU,OAAA;AAAA,QACxB,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAGD,MAAA,MAAM,SAAA,GAAY,aAAa,SAAS,CAAA;AAExC,MAAA,IAAI,UAAU,eAAA,EAAiB;AAE7B,QAAA,MAAM,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,KAAK,CAAA,iBAAA,EAAoB,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,GAAA,EAAM,SAAS,CAAA,CAAA,EAAI;AAAA,UACzF,cAAc,SAAA,CAAU,OAAA;AAAA,UACxB,SAAA;AAAA,UACA,OAAA;AAAA,UACA,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,KAAA,CAAM,IAAI,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI;AAAA;AAAA,SAC1D,CAAA;AAGD,QAAA,UAAA,GAAa,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,SAAS,eAAe,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,IAAA,CAAM,CAAA;AAGjF,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC7B,UAAA,UAAA,CAAW,SAAS,GAAA,GAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,GAAU,CAAC,CAAC,CAAA;AAAA,QACrD,CAAC,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,CAAO,MAAM,CAAA,EAAG,KAAK,iBAAiB,eAAe,CAAA,WAAA,EAAc,SAAS,CAAA,CAAA,EAAI,SAAA,EAAW;AAAA,UAC/F;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,IAAI,KAAA,CAAM,GAAG,KAAK,CAAA,cAAA,EAAiB,eAAe,CAAA,SAAA,CAAW,CAAA;AAClF;AAKA,SAAS,aAAa,KAAA,EAAsB;AAC1C,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AAG1C,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,mBAAmB,CAAA,EAAG;AACtG,IAAA,OAAO,oBAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AACjF,IAAA,OAAO,oBAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,QAAA,CAAS,SAAS,KAAK,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG;AAChE,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG;AACpG,IAAA,OAAO,eAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,kBAAkB,CAAA,EAAG;AACjG,IAAA,OAAO,cAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,QAAA,CAAS,SAAS,KAAK,OAAA,CAAQ,QAAA,CAAS,wBAAwB,CAAA,EAAG;AAC7E,IAAA,OAAO,mBAAA;AAAA,EACT;AAGA,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,SAAA,CAAU,GAAG,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACjE,EAAA,OAAO,CAAA,OAAA,EAAU,OAAO,CAAA,EAAG,KAAA,CAAM,QAAQ,MAAA,GAAS,EAAA,GAAK,QAAQ,EAAE,CAAA,CAAA;AACnE","file":"index.js","sourcesContent":["/**\n * Tool definitions for native LLM tool calling\n * Replaces text-based JSON parsing with structured OpenAI Function Calling\n */\n\nimport type { LLMTool } from '@kb-labs/sdk';\n\n/**\n * Tool: generate_commit_plan_phase3\n *\n * Used by Phase 3 to either extend existing commits or create new commits for missing files\n * Supports two actions: extend_existing (add files to existing commit) and create_new (create new commit)\n */\nexport const COMMIT_PLAN_TOOL_PHASE3: LLMTool = {\n name: 'generate_commit_plan',\n description: 'Generate commits for missing files - either extend existing commits or create new ones',\n inputSchema: {\n type: 'object',\n properties: {\n commits: {\n type: 'array',\n description: 'List of commit actions. Can mix extend_existing and create_new actions.',\n items: {\n type: 'object',\n required: ['action', 'files'],\n properties: {\n action: {\n type: 'string',\n enum: ['create_new', 'extend_existing'],\n description: 'Whether to create a new commit or add files to an existing commit. Use \"extend_existing\" to avoid creating unnecessary commits.',\n },\n existingCommitId: {\n type: 'string',\n description: 'ID of existing commit to extend (REQUIRED when action is \"extend_existing\"). Example: \"c1\", \"c2\".',\n pattern: '^c[0-9]+$',\n },\n id: {\n type: 'string',\n description: 'Unique commit identifier (REQUIRED for create_new action, e.g., c1, c2, c3).',\n pattern: '^c[0-9]+$',\n },\n type: {\n type: 'string',\n enum: ['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf'],\n description: 'Conventional commit type (REQUIRED for create_new action).',\n },\n scope: {\n type: 'string',\n description: 'Scope of the commit (optional).',\n },\n message: {\n type: 'string',\n description: 'Commit message in imperative mood (REQUIRED for create_new action).',\n minLength: 5,\n maxLength: 100,\n },\n body: {\n type: 'string',\n description: 'Detailed description (optional).',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of file paths to add to this commit.',\n minItems: 1,\n },\n releaseHint: {\n type: 'string',\n enum: ['none', 'patch', 'minor', 'major'],\n description: 'Semantic versioning impact (REQUIRED for create_new action).',\n },\n breaking: {\n type: 'boolean',\n description: 'Whether this is a breaking change.',\n default: false,\n },\n reasoning: {\n type: 'object',\n description: 'Reasoning for classification (REQUIRED for create_new action).',\n properties: {\n newBehavior: { type: 'boolean' },\n fixesBug: { type: 'boolean' },\n internalOnly: { type: 'boolean' },\n explanation: { type: 'string', minLength: 10, maxLength: 300 },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n },\n },\n },\n },\n },\n required: ['commits'],\n },\n};\n\n/**\n * Tool: generate_commit_plan\n *\n * Used by Phase 1 and Phase 2 to structure commit plan output using OpenAI Function Calling API\n * This guarantees valid JSON output without parsing errors\n */\nexport const COMMIT_PLAN_TOOL: LLMTool = {\n name: 'generate_commit_plan',\n description: 'Generate a structured commit plan with conventional commits following best practices',\n inputSchema: {\n type: 'object',\n properties: {\n needsMoreContext: {\n type: 'boolean',\n description: 'Whether you need to see diff content to make accurate commit type decisions. Set to true if file paths and stats alone are insufficient.',\n default: false,\n },\n requestedFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of SPECIFIC files you need diffs for (MAXIMUM 15 files). Only request files where file path and stats are insufficient. DO NOT request all files - be selective and choose only the most critical/ambiguous ones. Prioritize files with unclear intent or complex changes.',\n default: [],\n },\n commits: {\n type: 'array',\n description: 'List of commit groups. Each commit groups related files by logical change (not by file type or directory).',\n items: {\n type: 'object',\n required: ['id', 'type', 'message', 'files', 'releaseHint', 'breaking', 'reasoning'],\n properties: {\n id: {\n type: 'string',\n description: 'Unique commit identifier (e.g., c1, c2, c3).',\n pattern: '^c[0-9]+$',\n },\n type: {\n type: 'string',\n enum: ['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf'],\n description: 'Conventional commit type. Use refactor for internal changes, feat only for new user-facing features.',\n },\n scope: {\n type: 'string',\n description: 'Scope of the commit (e.g., \"cli\", \"api\", \"core\"). Should reflect affected area, not individual files.',\n },\n message: {\n type: 'string',\n description: 'Commit message in imperative mood, lowercase, no period at end (e.g., \"add authentication middleware\")',\n minLength: 5,\n maxLength: 100,\n },\n body: {\n type: 'string',\n description: 'Detailed description with bullet points listing affected files/changes. Use for commits with 2+ files.',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of file paths in this commit. Each file must appear in exactly ONE commit (no duplicates across commits).',\n minItems: 1,\n },\n releaseHint: {\n type: 'string',\n enum: ['none', 'patch', 'minor', 'major'],\n description: 'Semantic versioning impact. Use \"minor\" for feat, \"patch\" for fix/refactor, \"none\" for chore/docs/test.',\n },\n breaking: {\n type: 'boolean',\n description: 'Whether this is a breaking change (breaks public API compatibility).',\n default: false,\n },\n reasoning: {\n type: 'object',\n required: ['newBehavior', 'fixesBug', 'internalOnly', 'explanation', 'confidence'],\n description: 'Reasoning for commit type classification. Used for validation and debugging.',\n properties: {\n newBehavior: {\n type: 'boolean',\n description: 'Does this change add NEW USER-VISIBLE BEHAVIOR? (new API, feature, capability that users can access)',\n },\n fixesBug: {\n type: 'boolean',\n description: 'Does this change fix BROKEN functionality? (corrects bug or error)',\n },\n internalOnly: {\n type: 'boolean',\n description: 'Is this ONLY INTERNAL restructuring? (code reorganization, renaming, extracting functions without changing behavior)',\n },\n explanation: {\n type: 'string',\n description: 'Explain your classification decision. Why did you choose this commit type?',\n minLength: 10,\n maxLength: 300,\n },\n confidence: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: 'Confidence in this classification (0.0 to 1.0). Use <0.7 if you need more context (will trigger Phase 2).',\n },\n },\n },\n },\n },\n },\n },\n required: ['commits'],\n },\n};\n","/**\n * Git status analysis\n */\n\nimport { simpleGit, type SimpleGit, type StatusResult } from \"simple-git\";\nimport type { GitStatus } from \"@kb-labs/commit-contracts\";\n\n/**\n * Get current git status (staged, unstaged, untracked files).\n * cwd must already point to the resolved scope directory.\n */\nexport async function getGitStatus(cwd: string): Promise<GitStatus> {\n // --ignore-submodules=all: exclude submodule pointer drift in worktrees\n const git: SimpleGit = simpleGit(cwd);\n const status: StatusResult = await git.status(['--ignore-submodules=all']);\n\n return {\n staged: status.staged.filter((f) => !shouldIgnoreFile(f)),\n unstaged: [...status.modified, ...status.deleted]\n .filter((f) => !status.staged.includes(f))\n .filter((f) => !shouldIgnoreFile(f)),\n untracked: status.not_added.filter((f) => !shouldIgnoreFile(f)),\n };\n}\n\n/**\n * Check if file should be ignored (node_modules, dist, etc.)\n */\nfunction shouldIgnoreFile(file: string): boolean {\n const ignoredPaths = [\n \"node_modules/\",\n \".git/\",\n \"dist/\",\n \"build/\",\n \".next/\",\n \".turbo/\",\n \"coverage/\",\n \".cache/\",\n \".temp/\",\n \"tmp/\",\n ];\n\n return ignoredPaths.some((path) => file.includes(path));\n}\n\n/**\n * Get all changed files (staged + unstaged + untracked)\n * Filters out node_modules and other build artifacts\n */\nexport function getAllChangedFiles(status: GitStatus): string[] {\n const allFiles = [\n ...new Set([...status.staged, ...status.unstaged, ...status.untracked]),\n ];\n return allFiles.filter((file) => !shouldIgnoreFile(file));\n}\n\n/**\n * Check if there are any changes\n */\nexport function hasChanges(status: GitStatus): boolean {\n return (\n status.staged.length > 0 ||\n status.unstaged.length > 0 ||\n status.untracked.length > 0\n );\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(cwd: string): Promise<string> {\n const git: SimpleGit = simpleGit(cwd);\n const branch = await git.revparse([\"--abbrev-ref\", \"HEAD\"]);\n return branch.trim();\n}\n\n/**\n * Check if branch is protected (main/master)\n */\nexport function isProtectedBranch(branch: string): boolean {\n const protectedBranches = [\n \"main\",\n \"master\",\n \"develop\",\n \"release\",\n \"production\",\n ];\n return protectedBranches.includes(branch.toLowerCase());\n}\n","/**\n * File summary extraction\n */\n\n/* eslint-disable no-await-in-loop -- Sequential git operations required: must check status, read diffs, compute summaries one-by-one for each file */\n\nimport {\n simpleGit,\n type SimpleGit,\n type DiffResultTextFile,\n type DiffResultBinaryFile,\n} from \"simple-git\";\nimport type { FileSummary } from \"@kb-labs/commit-contracts\";\n\n/**\n * Type guard for text file diff result\n */\nfunction isTextFile(\n file: DiffResultTextFile | DiffResultBinaryFile,\n): file is DiffResultTextFile {\n return !file.binary;\n}\n\n/**\n * Check if file is truly new (doesn't exist in current HEAD commit)\n * Returns true if file doesn't exist in HEAD (the current committed state)\n * Returns false if file exists in HEAD (even if modified/deleted locally)\n * Supports nested git repositories\n */\nasync function isNewFile(cwd: string, filePath: string): Promise<boolean> {\n try {\n // Find the git repository for this file (walks up directory tree)\n const repo = await findGitRepo(cwd, filePath);\n\n if (!repo) {\n // No git repo found - treat as new file\n return true;\n }\n\n const git = simpleGit(repo.repoPath);\n\n // Check if file exists in HEAD (current commit), not in history\n // git ls-tree HEAD -- <file>\n // Returns tree entry if file exists in HEAD, empty if file is new\n // This correctly handles modified/unstaged files (they exist in HEAD = not new)\n const result = await git.raw([\"ls-tree\", \"HEAD\", \"--\", repo.relativePath]);\n\n // If no output, file doesn't exist in HEAD → truly new file\n // If has output, file exists in HEAD → not new (modified/unstaged)\n return result.trim().length === 0;\n } catch {\n // On error, assume it's new (safer to say \"new\" than claim it existed)\n return true;\n }\n}\n\n/**\n * Get file summaries with diff stats for given files\n * Supports nested git repositories by grouping files per repo\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- File summary extraction: groups files by repo, handles nested git repos, computes diff stats, processes staged/unstaged/untracked files\nexport async function getFileSummaries(\n cwd: string,\n files: string[],\n): Promise<FileSummary[]> {\n if (files.length === 0) {\n return [];\n }\n\n const summaries: FileSummary[] = [];\n\n // Group files by repository (walks up directory tree to find .git)\n const filesByRepo = new Map<\n string,\n { repoPath: string; relativePath: string; originalPath: string }[]\n >();\n\n for (const file of files) {\n const repo = await findGitRepo(cwd, file);\n\n if (!repo) {\n // No git repo found - treat as file in cwd\n const group = filesByRepo.get(cwd) ?? [];\n group.push({ repoPath: cwd, relativePath: file, originalPath: file });\n filesByRepo.set(cwd, group);\n continue;\n }\n\n // Group by repository path\n const group = filesByRepo.get(repo.repoPath) ?? [];\n group.push({\n repoPath: repo.repoPath,\n relativePath: repo.relativePath,\n originalPath: file,\n });\n filesByRepo.set(repo.repoPath, group);\n }\n\n // Get diff summaries for each repo separately\n for (const [repoPath, fileInfos] of filesByRepo) {\n const git: SimpleGit = simpleGit(repoPath);\n const relativePaths = fileInfos.map((f) => f.relativePath);\n\n try {\n // Try staged diff first\n const stagedDiff = await git.diffSummary([\n \"--cached\",\n \"--\",\n ...relativePaths,\n ]);\n\n // Then try unstaged diff (working tree changes)\n const unstagedDiff = await git.diffSummary([\"--\", ...relativePaths]);\n\n // Combine results (prefer staged if file appears in both)\n const allDiffFiles = new Map<\n string,\n DiffResultTextFile | DiffResultBinaryFile\n >();\n for (const file of unstagedDiff.files) {\n allDiffFiles.set(file.file, file);\n }\n for (const file of stagedDiff.files) {\n // Staged takes priority\n allDiffFiles.set(file.file, file);\n }\n\n // Process diff results\n for (const file of allDiffFiles.values()) {\n // Find original path (with repo prefix)\n const fileInfo = fileInfos.find((f) => f.relativePath === file.file);\n if (!fileInfo) {\n continue;\n }\n\n // Check if file is truly new (using repoPath as cwd)\n const isNew = await isNewFile(repoPath, file.file);\n\n // Handle both text and binary files\n if (isTextFile(file)) {\n summaries.push({\n path: fileInfo.originalPath,\n status: mapDiffStatus(file.insertions, file.deletions),\n additions: file.insertions,\n deletions: file.deletions,\n binary: false,\n isNewFile: isNew,\n });\n } else {\n // Binary file\n summaries.push({\n path: fileInfo.originalPath,\n status: \"modified\",\n additions: 0,\n deletions: 0,\n binary: true,\n isNewFile: isNew,\n });\n }\n }\n\n // Add any missing files from this repo (untracked - not in git yet)\n const processedPaths = new Set(\n Array.from(allDiffFiles.values()).map((f) => f.file),\n );\n const missingInRepo = fileInfos.filter(\n (f) => !processedPaths.has(f.relativePath),\n );\n\n for (const fileInfo of missingInRepo) {\n // Untracked files are always new (never existed in git)\n summaries.push({\n path: fileInfo.originalPath,\n status: \"added\",\n additions: 0,\n deletions: 0,\n binary: false,\n isNewFile: true,\n });\n }\n } catch {\n // Fallback: create basic summaries for this repo's files\n for (const fileInfo of fileInfos) {\n summaries.push({\n path: fileInfo.originalPath,\n status: \"modified\",\n additions: 0,\n deletions: 0,\n binary: false,\n isNewFile: false, // Conservative assumption\n });\n }\n }\n }\n\n return summaries;\n}\n\n/**\n * Map insertions/deletions to status\n */\nfunction mapDiffStatus(\n insertions: number,\n deletions: number,\n): FileSummary[\"status\"] {\n // Simple heuristic: if only insertions, likely added; if only deletions, likely deleted\n if (deletions === 0 && insertions > 0) {\n return \"added\";\n }\n if (insertions === 0 && deletions > 0) {\n return \"deleted\";\n }\n return \"modified\";\n}\n\n/**\n * Get a short summary string for display\n */\nexport function formatFileSummary(summary: FileSummary): string {\n const stats = summary.binary\n ? \"binary\"\n : `+${summary.additions}/-${summary.deletions}`;\n return `${summary.path} (${summary.status}, ${stats})`;\n}\n\n/**\n * Get diff content for specific files\n * Used when LLM requests more context (Phase 2 escalation)\n * Supports nested git repositories (files with prefix like 'kb-labs-sdk/...')\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Diff extraction: groups files by nested repo, handles staged/unstaged diffs, processes binary files, merges results\nexport async function getFileDiffs(\n cwd: string,\n files: string[],\n): Promise<Map<string, string>> {\n if (files.length === 0) {\n return new Map();\n }\n\n const diffs = new Map<string, string>();\n\n // Group files by repository (walks up directory tree to find .git)\n const filesByRepo = new Map<\n string,\n { repoPath: string; relativePath: string; originalPath: string }[]\n >();\n\n for (const file of files) {\n const repo = await findGitRepo(cwd, file);\n\n if (!repo) {\n // No git repo found - treat as file in cwd\n const group = filesByRepo.get(cwd) ?? [];\n group.push({ repoPath: cwd, relativePath: file, originalPath: file });\n filesByRepo.set(cwd, group);\n continue;\n }\n\n // Group by repository path\n const group = filesByRepo.get(repo.repoPath) ?? [];\n group.push({\n repoPath: repo.repoPath,\n relativePath: repo.relativePath,\n originalPath: file,\n });\n filesByRepo.set(repo.repoPath, group);\n }\n\n // Get diffs for each repo\n for (const [repoPath, fileInfos] of filesByRepo) {\n const git: SimpleGit = simpleGit(repoPath);\n\n for (const { relativePath, originalPath } of fileInfos) {\n try {\n // Try staged diff first, then unstaged\n let diff = await git.diff([\"--cached\", \"--\", relativePath]);\n if (!diff) {\n diff = await git.diff([\"--\", relativePath]);\n }\n if (!diff) {\n // For untracked files, try to read content\n diff = await git.show([`:${relativePath}`]).catch(() => \"\");\n }\n if (diff) {\n diffs.set(originalPath, diff);\n }\n } catch {\n // Skip files that can't be diffed\n }\n }\n }\n\n return diffs;\n}\n\n/**\n * Helper to check if path exists asynchronously\n */\nasync function existsAsync(path: string): Promise<boolean> {\n try {\n const { existsSync } = await import(\"node:fs\");\n return existsSync(path);\n } catch {\n return false;\n }\n}\n\n/**\n * Find the git repository root for a given file path.\n * Walks up the directory tree to find the nearest .git directory.\n *\n * @param basePath - Base path to start searching from (e.g., /Users/user/project)\n * @param filePath - Relative file path (e.g., kb-labs-commit/packages/core/src/index.ts)\n * @returns Object with repoPath (absolute) and relativePath (relative to repo), or null if no repo found\n *\n * @example\n * // For nested repo:\n * findGitRepo('/Users/user/kb-labs', 'kb-labs-commit/packages/core/src/index.ts')\n * // Returns: { repoPath: '/Users/user/kb-labs/kb-labs-commit', relativePath: 'packages/core/src/index.ts' }\n *\n * // For file in root repo:\n * findGitRepo('/Users/user/kb-labs', 'src/index.ts')\n * // Returns: { repoPath: '/Users/user/kb-labs', relativePath: 'src/index.ts' }\n */\nasync function findGitRepo(\n basePath: string,\n filePath: string,\n): Promise<{ repoPath: string; relativePath: string } | null> {\n const segments = filePath.split(\"/\");\n\n // Try progressively shorter paths (walk up the tree)\n // For 'kb-labs-commit/packages/core/src/index.ts', try:\n // 1. basePath/kb-labs-commit/packages/core/src\n // 2. basePath/kb-labs-commit/packages/core\n // 3. basePath/kb-labs-commit/packages\n // 4. basePath/kb-labs-commit\n // 5. basePath (fallback to root)\n\n for (let i = segments.length - 1; i > 0; i--) {\n const potentialRepoSegments = segments.slice(0, i);\n const potentialRepoPath = `${basePath}/${potentialRepoSegments.join(\"/\")}`;\n const gitDir = `${potentialRepoPath}/.git`;\n\n if (await existsAsync(gitDir)) {\n // Found a .git directory - this is the repo root\n const relativePath = segments.slice(i).join(\"/\");\n return { repoPath: potentialRepoPath, relativePath };\n }\n }\n\n // No nested repo found, check if basePath itself is a git repo\n if (await existsAsync(`${basePath}/.git`)) {\n return { repoPath: basePath, relativePath: filePath };\n }\n\n // No git repo found at all\n return null;\n}\n","/**\n * Recent commits analysis for style matching\n */\n\nimport { simpleGit, type SimpleGit } from \"simple-git\";\n\n/**\n * Get recent commit messages for style reference\n *\n * @param cwd - Working directory\n * @param count - Number of commits to retrieve (default: 10)\n * @returns Array of commit messages (subject line only)\n */\nexport async function getRecentCommits(\n cwd: string,\n count: number = 10,\n): Promise<string[]> {\n const git: SimpleGit = simpleGit(cwd);\n\n try {\n const log = await git.log({\n maxCount: count,\n format: {\n message: \"%s\", // Subject line only\n },\n });\n\n return log.all.map((commit) => commit.message);\n } catch {\n // Return empty array if no commits or error\n return [];\n }\n}\n\n/**\n * Detect the commit style from recent commits\n *\n * @returns Detected style hints\n */\nexport function detectCommitStyle(commits: string[]): {\n usesConventional: boolean;\n commonScopes: string[];\n avgLength: number;\n} {\n if (commits.length === 0) {\n return {\n usesConventional: false,\n commonScopes: [],\n avgLength: 50,\n };\n }\n\n // Check for conventional commit pattern: type(scope)?: message\n const conventionalPattern =\n /^(feat|fix|docs|style|refactor|test|chore|ci|perf|build)(\\([^)]+\\))?!?:/i;\n const conventionalMatches = commits.filter((c) =>\n conventionalPattern.test(c),\n );\n const usesConventional = conventionalMatches.length >= commits.length * 0.5;\n\n // Extract scopes\n const scopePattern = /^\\w+\\(([^)]+)\\)/;\n const scopes = commits\n .map((c) => {\n const match = c.match(scopePattern);\n return match ? match[1] : null;\n })\n .filter((s): s is string => s !== null);\n\n // Count scope frequency\n const scopeCounts = scopes.reduce<Record<string, number>>((acc, scope) => {\n acc[scope] = (acc[scope] || 0) + 1;\n return acc;\n }, {});\n\n // Get top 5 most common scopes\n const commonScopes = Object.entries(scopeCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([scope]) => scope);\n\n // Calculate average message length\n const avgLength = Math.round(\n commits.reduce((sum, c) => sum + c.length, 0) / commits.length,\n );\n\n return {\n usesConventional,\n commonScopes,\n avgLength,\n };\n}\n","/**\n * LLM prompt building and response parsing\n */\n\nimport type { FileSummary, CommitGroup, ConventionalType, CommitReasoning } from '@kb-labs/commit-contracts';\nimport type { PatternAnalysis } from './pattern-detector';\n\n/**\n * System prompt for LLM - Phase 1 (file summaries only)\n */\nexport const SYSTEM_PROMPT = `You are a git commit message generator. Analyze the changed files and generate a commit plan.\n\nCRITICAL OUTPUT FORMAT:\n- Return ONLY a valid JSON object\n- Do NOT wrap in markdown code blocks (no \\`\\`\\`json, no \\`\\`\\`)\n- Do NOT add any text before or after the JSON\n- Ensure all strings are properly escaped (use double quotes, escape backslashes and quotes)\n\nIMPORTANT: You must assess your confidence level. If file paths and stats alone are not enough to determine the correct commit type and message, set needsMoreContext to true and list the files you need to see the diff for.\n\nCRITICAL GROUPING RULES:\n- Group files by LOGICAL CHANGE, not by file type or directory\n- If multiple files implement the same feature/fix/refactor, they belong in ONE commit\n- For initial project setup (many new files): group by package or functional area (contracts, core, cli, docs, tests)\n- Target: 3-8 commits for <50 files, 5-12 commits for 50-150 files, 10-20 commits for 150+ files\n- Ask yourself: \"Would a developer make these changes in separate commits?\" If no, group them!\n- CRITICAL: Each file must appear in EXACTLY ONE commit - no duplicates across commits!\n\nCRITICAL: FILE TYPE SHORTCUTS (check FIRST, before other rules):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n🚫 STOP! Check file extensions BEFORE asking questions below:\n\n📝 ALL files are *.md or *.mdx? → Type: docs (SKIP all questions below!)\n🧪 ALL files in test/, __tests__/, *.test.ts, *.spec.ts? → Type: test\n❌ If ANY file has code (.ts, .js, .tsx, .jsx, .py, etc.) → Continue to questions below\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nCRITICAL COMMIT TYPE CLASSIFICATION:\nFor EACH commit, you MUST answer these questions to determine the correct type:\n\n1. Does this change add NEW USER-VISIBLE BEHAVIOR? (yes/no)\n - Can users/developers do something they couldn't before?\n - Is there a new API, feature, or capability?\n → YES = likely feat\n\n2. Does this change fix BROKEN functionality? (yes/no)\n - Was something not working correctly?\n - Is this correcting a bug or error?\n → YES = fix\n\n3. Is this ONLY INTERNAL restructuring? (yes/no)\n - Code reorganization, renaming, extracting functions?\n - Improving structure WITHOUT changing behavior?\n - Modified files with balanced additions/deletions?\n → YES = refactor\n\n4. Is this configuration, build, or maintenance work? (yes/no)\n - Dependencies, build configs, tooling?\n - No code logic changes?\n → YES = chore\n\nDEFAULT BIAS: When uncertain between feat and refactor, choose refactor!\n\nRules:\n1. Use conventional commits: feat, fix, refactor, chore, docs, test, build, ci, perf\n2. Group related files - number of commits should scale with file count (see grouping rules above)\n3. Each commit MUST include \"reasoning\" field explaining your classification\n4. Message should be lowercase, imperative mood, no period at end\n5. breaking: true only for breaking API changes\n6. For commits with 2+ files, add \"body\" with bullet points listing affected files/changes\n7. Scope should reflect the affected area (e.g., \"cli\", \"api\"), not individual files\n8. CRITICAL: If ALL files in a commit have status \"deleted\", use type \"chore\" or \"refactor\", NOT \"feat\"\n9. CRITICAL: If a commit is mostly deletions (>80% deletions), use \"refactor\" or \"chore\", NOT \"feat\"\n\n10. CRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (not generic):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n ❌ BAD (too generic):\n - \"add feature\"\n - \"update files\"\n - \"refactor code\"\n - \"fix bug\"\n - \"improve types\"\n\n ✅ GOOD (specific and descriptive):\n - \"add JWT authentication with refresh token support\"\n - \"update TypeScript configuration for strict mode\"\n - \"refactor plugin execution to use factory pattern\"\n - \"fix null pointer exception in authentication middleware\"\n - \"improve type safety in workflow execution context\"\n\n Guidelines:\n - Include WHAT was changed (specific feature/component)\n - Include HOW if relevant (method, pattern, technology)\n - Use concrete nouns (not \"files\", \"code\", \"feature\")\n - Add context that helps reviewers understand the change\n - For body: list specific changes, not just file names\n\n11. CRITICAL: SPECIFIC TYPE DETECTION (check BEFORE defaulting to refactor):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n 📝 docs: Documentation ONLY (no code changes)\n ✅ ALL files are markdown (*.md, *.mdx) → docs (even if IsNewFile: true)\n ✅ README.md, CONTRIBUTING.md, API docs, ADRs\n ✅ Files in docs/ or doc/ directory with only markdown\n ✅ JSDoc comments only (no logic changes)\n ❌ NOT docs if ANY file has code logic changes\n\n **IMPORTANT**: If ALL files end with .md or .mdx → ALWAYS use docs, NEVER feat!\n\n 🐛 fix: Corrects BROKEN functionality\n ✅ Bug fixes, error handling corrections\n ✅ Fixes crashes, incorrect behavior\n ✅ Corrects typos in USER-FACING text (not code comments)\n ❌ NOT fix if adding new behavior (that's feat)\n\n 🧪 test: Test files ONLY\n ✅ Files in test/, tests/, __tests__/, *.test.ts, *.spec.ts\n ✅ Adding/updating test cases\n ❌ NOT test if also changing source code\n\n12. CRITICAL: IsNewFile flag determines STRONG BIAS against feat:\n\n IsNewFile: FALSE (modified existing file):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n → DEFAULT to refactor/fix/chore (NOT feat!)\n → Only use feat if adds MAJOR new user-facing capability\n\n Common cases where IsNewFile: false = NOT feat:\n ✅ Changed dependencies/imports → chore\n ✅ Added method to existing class → refactor\n ✅ Updated implementation logic → refactor\n ✅ Fixed bug in existing code → fix\n ✅ Renamed/moved code → refactor\n ✅ Modified config files → chore\n\n ❌ WRONG: IsNewFile: false, minor additions → feat\n ✅ RIGHT: IsNewFile: false, minor additions → refactor\n\n\n IsNewFile: TRUE (brand new file):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n → Might be feat IF adds new user capability\n → If only config/tooling/internal → chore\n\n Examples:\n ✅ New API endpoint file → feat\n ✅ New CLI command file → feat\n ✅ New config file → chore\n ✅ New test file → test\n\nEXACT JSON SCHEMA (copy this structure):\n{\n \"needsMoreContext\": false,\n \"requestedFiles\": [\"file1.ts\"],\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"feat\",\n \"scope\": \"auth\",\n \"message\": \"add JWT authentication with refresh token support\",\n \"body\": \"- implement JWT token generation and validation\\\\n- add refresh token rotation mechanism\\\\n- integrate with existing user authentication flow\",\n \"files\": [\"src/auth/jwt-strategy.ts\", \"src/auth/refresh-token.ts\", \"src/middleware/auth.ts\"],\n \"releaseHint\": \"minor\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": true,\n \"fixesBug\": false,\n \"internalOnly\": false,\n \"explanation\": \"Adds new JWT authentication capability with refresh tokens - enables secure stateless authentication for API users\",\n \"confidence\": 0.85\n }\n }\n ]\n}\n\nVALID TYPE VALUES: feat, fix, refactor, chore, docs, test, build, ci, perf\nVALID RELEASEHINT VALUES: none, patch, minor, major\n\nEXAMPLE OUTPUT (use this as template):\n{\n \"needsMoreContext\": false,\n \"requestedFiles\": [],\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"feat\",\n \"scope\": \"cli\",\n \"message\": \"add commit generation command\",\n \"body\": \"- implement generate command\\\\n- add LLM integration\",\n \"files\": [\"src/commands/generate.ts\", \"src/llm.ts\"],\n \"releaseHint\": \"minor\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": true,\n \"fixesBug\": false,\n \"internalOnly\": false,\n \"explanation\": \"New command allows users to generate commits with LLM - new capability\",\n \"confidence\": 0.9\n }\n },\n {\n \"id\": \"c2\",\n \"type\": \"test\",\n \"message\": \"add tests for commit generator\",\n \"files\": [\"tests/generate.test.ts\"],\n \"releaseHint\": \"none\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"Test coverage for new feature - internal quality improvement\",\n \"confidence\": 0.85\n }\n }\n ]\n}\n\nREAL-WORLD EXAMPLES (learn from these patterns):\n\nExample 1: Modified files with low addition ratio → refactor, NOT feat\nFiles:\n - commit-plan.ts (modified, +150/-120)\n - llm-prompt.ts (modified, +80/-60)\nAddition ratio: 230/350 = 65% (low, mostly structural changes)\n❌ WRONG: feat(core): add commit plan and llm prompt generators\n✅ CORRECT: refactor(core): update commit plan and llm prompt logic\nReason: Modified files + low addition ratio = refactoring existing code\n\nExample 2: New package with many files → feat, NOT chore\nFiles: 21 new files in packages/core-resource-broker/\n - package.json (new)\n - src/broker/resource-broker.ts (new)\n - src/queue/priority-queue.ts (new)\n - ... (18 more new files)\n❌ WRONG: chore(core-resource-broker): initialize core resource broker package\n✅ CORRECT: feat(core-resource-broker): add resource broker for rate limiting and queueing\nReason: New package = new functionality = feat (even if many files)\n\nExample 3: Bulk move (many added files but not new) → refactor, NOT feat\nFiles: 100 files with status \"added\" but isNewFile: false\n - packages/analytics/core/file1.ts (added, isNewFile: false)\n - packages/analytics/core/file2.ts (added, isNewFile: false)\n - ... (98 more files, all moved from elsewhere)\n❌ WRONG: feat(analytics): add analytics packages\n✅ CORRECT: refactor(analytics): reorganize analytics package structure\nReason: isNewFile: false means files existed before, just moved/reorganized\n\nExample 4: All deleted files → chore, NOT feat\nFiles: 22 files, all with status \"deleted\"\n - packages/analytics/test1.spec.ts (deleted, +0/-1579)\n - packages/analytics/test2.spec.ts (deleted, +0/-856)\n - ... (20 more deleted files)\n❌ WRONG: feat(analytics): add analytics functionality\n✅ CORRECT: chore(analytics): remove unused test files\nReason: Deleting files is cleanup (chore), not new feature\n\nExample 5: True new feature (genuinely new files) → feat\nFiles: 5 new files with isNewFile: true\n - src/auth/jwt-strategy.ts (added, +200/-0, isNewFile: true)\n - src/auth/auth-middleware.ts (added, +150/-0, isNewFile: true)\n - ... (3 more new files)\n✅ CORRECT: feat(auth): add JWT authentication\nReason: New functionality, truly new files, implements new capability\n\nExample 6: Documentation ONLY → docs, NOT chore or feat\nFiles:\n - README.md (modified, +50/-20, isNewFile: false)\n - CONTRIBUTING.md (modified, +30/-10, isNewFile: false)\n - docs/api.md (modified, +100/-50, isNewFile: false)\n❌ WRONG: chore(docs): update documentation files\n❌ WRONG: feat(docs): add documentation\n✅ CORRECT: docs: improve README and API documentation\nReason: ALL files are markdown = docs (regardless of IsNewFile)\n\nExample 6b: NEW documentation files → docs, NOT feat\nFiles:\n - docs/benchmarks/README.md (added, +200/-0, isNewFile: true)\n - docs/benchmarks/RESULTS.md (added, +100/-0, isNewFile: true)\n❌ WRONG: feat(docs): add benchmarks documentation\n✅ CORRECT: docs(benchmarks): add benchmarks documentation\nReason: ALL files are .md = docs type (even if IsNewFile: true)\n\nExample 7: Bug fix with error handling → fix, NOT refactor\nFiles:\n - src/api/auth.ts (modified, +15/-5, isNewFile: false)\n Diff shows: Added try-catch, null check for token validation\n❌ WRONG: refactor(api): update auth token validation\n✅ CORRECT: fix(api): handle null token in authentication\nReason: Adds error handling to prevent crash = bug fix\n\nExample 8: Test files ONLY → test, NOT chore\nFiles:\n - tests/auth.test.ts (added, +200/-0, isNewFile: true)\n - tests/fixtures/users.json (added, +50/-0, isNewFile: true)\n❌ WRONG: chore(tests): add test files\n✅ CORRECT: test(auth): add authentication test suite\nReason: Test files only = test type\n`;\n\n/**\n * System prompt for LLM - Phase 2 (with diff context)\n */\nexport const SYSTEM_PROMPT_WITH_DIFF = `You are a git commit message generator. You now have the actual diff content for better context.\n\nCRITICAL OUTPUT FORMAT:\n- Return ONLY a valid JSON object\n- Do NOT wrap in markdown code blocks (no \\`\\`\\`json, no \\`\\`\\`)\n- Do NOT add any text before or after the JSON\n- Ensure all strings are properly escaped (use double quotes, escape backslashes and quotes)\n\nCRITICAL: USE IsNewFile METADATA TO DISTINGUISH NEW vs MODIFIED FILES:\n- Each file includes \"IsNewFile: true\" or \"IsNewFile: false\"\n- IsNewFile: false → File EXISTED BEFORE in git history → Use \"refactor\", \"fix\", or \"chore\"\n- IsNewFile: true → File is TRULY NEW (never existed) → Use \"feat\" for new functionality\n- NEVER use \"feat: add initial\" for files with \"IsNewFile: false\" - these are modifications!\n- For files marked \"[EXISTING FILE - was modified]\" in diff section → Use refactor/fix/chore, NOT feat\n\nCRITICAL GROUPING RULES:\n- Group files by LOGICAL CHANGE based on diff content\n- If files are changed for the same reason, they belong in ONE commit\n- IMPORTANT: Most files with status \"modified\" are REFACTORING, not new features\n- For refactoring: analyze the diff to understand what changed (renamed variables, restructured code, etc.)\n- Only use \"add initial\" or \"setup\" messages if you see truly NEW functionality being created from scratch\n- Target: 3-8 commits for <50 files, 5-12 commits for 50-150 files, 10-20 commits for 150+ files\n- Only separate genuinely DIFFERENT changes\n- CRITICAL: Each file must appear in EXACTLY ONE commit - no duplicates across commits!\n\nCRITICAL: FILE TYPE SHORTCUTS (check FIRST, before other rules):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n🚫 STOP! Check file extensions in DIFF BEFORE asking questions below:\n\n📝 ALL files in diff are *.md or *.mdx? → Type: docs (SKIP all questions below!)\n🧪 ALL files in diff are test/, __tests__/, *.test.ts, *.spec.ts? → Type: test\n❌ If ANY file has code (.ts, .js, .tsx, .jsx, .py, etc.) → Continue to questions below\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nCRITICAL COMMIT TYPE CLASSIFICATION (same as Phase 1):\nFor EACH commit, answer these questions using the DIFF content:\n\n1. Does this change add NEW USER-VISIBLE BEHAVIOR?\n - Look at the diff: is there a new API, feature, or capability?\n - Check IsNewFile: false = likely refactor, true = might be feat\n → YES = feat\n\n2. Does this change fix BROKEN functionality?\n - Look for bug fixes, error handling corrections\n → YES = fix\n\n3. Is this ONLY INTERNAL restructuring?\n - Renaming, extracting functions, reorganizing code?\n - IsNewFile: false with balanced +/- = refactor\n → YES = refactor\n\nDEFAULT BIAS: When uncertain between feat and refactor, choose refactor!\n\nRules:\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!! RULE 0 (HIGHEST PRIORITY - OVERRIDES ALL OTHER RULES): !!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!\n!!! IF a file has \"IsNewFile: false\" in its metadata, IT IS A MODIFIED FILE.\n!!! Modified files CANNOT be feat UNLESS they add ENTIRELY NEW user-facing APIs.\n!!!\n!!! BEFORE classifying ANY commit as \"feat\", CHECK ALL files' IsNewFile flags:\n!!! - If ANY file has IsNewFile: false → START with refactor/fix/chore\n!!! - If ALL files have IsNewFile: true → MIGHT be feat (check diff content)\n!!!\n!!! EXAMPLES OF MODIFIED FILES (IsNewFile: false) → NOT FEAT:\n!!! ❌ WRONG: Modified file adds new function → feat\n!!! ✅ RIGHT: Modified file adds new function → refactor\n!!!\n!!! ❌ WRONG: Modified file adds new class → feat\n!!! ✅ RIGHT: Modified file adds new class → refactor\n!!!\n!!! ❌ WRONG: Modified file adds new CLI command → feat\n!!! ✅ RIGHT: Modified file adds new CLI command → refactor\n!!!\n!!! ONLY USE FEAT for modified files if:\n!!! - Diff shows COMPLETELY NEW public API endpoint (e.g., POST /api/new-resource)\n!!! - Diff shows COMPLETELY NEW product feature visible to end users\n!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n1. Use conventional commits: feat, fix, refactor, chore, docs, test, build, ci, perf\n2. Group related files - number of commits should scale with file count (see grouping rules above)\n3. Each commit MUST include \"reasoning\" field based on actual diff content\n4. Message should be lowercase, imperative mood, no period at end\n5. breaking: true only for breaking API changes\n6. Add \"body\" with bullet points explaining the actual changes you see in the diff\n7. Scope should reflect the affected area (e.g., \"cli\", \"api\"), not individual files\n8. CRITICAL: If ALL files in a commit are being DELETED (only deletions in diff), use type \"chore\" or \"refactor\", NOT \"feat\"\n9. CRITICAL: If a commit is mostly deletions (>80% of lines are deletions), use \"refactor\" or \"chore\", NOT \"feat\"\n\n10. CRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (look at diff content):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n ❌ BAD (too generic):\n - \"add feature\"\n - \"update files\"\n - \"refactor code\"\n - \"fix bug\"\n - \"improve implementation\"\n\n ✅ GOOD (specific, based on diff):\n - \"add rate limiting middleware with Redis backend\"\n - \"update API client to support pagination parameters\"\n - \"refactor workflow executor to use async/await pattern\"\n - \"fix memory leak in event listener cleanup\"\n - \"improve error handling in authentication flow\"\n\n Guidelines:\n - Read the DIFF to understand WHAT changed\n - Include specific component/module names from diff\n - Mention the technology/pattern if relevant (Redis, JWT, factory pattern)\n - For body: describe concrete changes, not just \"update X file\"\n - Use technical terms that developers will understand\n\n12. CRITICAL: SPECIFIC TYPE DETECTION (check diff content BEFORE defaulting to refactor):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n 📝 docs: Documentation ONLY (no code logic changes)\n ✅ ALL files in diff are markdown (*.md, *.mdx) → docs (even if IsNewFile: true)\n ✅ Diff shows ONLY markdown content changes\n ✅ README.md, ADR files, API docs, benchmarks docs\n ✅ Files in docs/ or doc/ directory with only markdown\n ❌ NOT docs if diff includes ANY code logic changes\n\n **IMPORTANT**: If ALL files end with .md or .mdx → ALWAYS use docs, NEVER feat!\n\n 🐛 fix: Corrects BROKEN functionality (look for bug-fix patterns in diff)\n ✅ Diff adds try-catch, null checks, validation\n ✅ Diff fixes incorrect calculations or logic errors\n ✅ Diff corrects typos in user-facing strings\n ✅ Commit message/body mentions \"fix\", \"bug\", \"error\", \"crash\"\n ❌ NOT fix if adding new behavior\n\n 🧪 test: Test files ONLY\n ✅ Diff shows files in test/, __tests__/, *.test.ts, *.spec.ts\n ✅ Adding test cases, updating test fixtures\n ❌ NOT test if diff also changes source code\n\n13. IsNewFile flag (see RULE 0 above for detailed logic):\n - IsNewFile: false → refactor/fix/chore/docs/test (NOT feat)\n - IsNewFile: true → might be feat (check diff)\n\nEXACT JSON SCHEMA (copy this structure):\n{\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"refactor\",\n \"scope\": \"workflow\",\n \"message\": \"extract job executor to separate class with dependency injection\",\n \"body\": \"- create JobExecutor class with injectable dependencies\\\\n- move execution logic from runtime to executor\\\\n- add unit tests for isolated executor behavior\",\n \"files\": [\"src/runtime/workflow-runtime.ts\", \"src/executor/job-executor.ts\", \"tests/executor.test.ts\"],\n \"releaseHint\": \"patch\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"Diff shows extraction of JobExecutor class from runtime - improves testability through dependency injection pattern, no user-facing changes\",\n \"confidence\": 0.95\n }\n }\n ]\n}\n\nVALID TYPE VALUES: feat, fix, refactor, chore, docs, test, build, ci, perf\nVALID RELEASEHINT VALUES: none, patch, minor, major\n\nEXAMPLE OUTPUT (based on actual diff content):\n{\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"refactor\",\n \"scope\": \"cli\",\n \"message\": \"migrate command routing to builder pattern with fluent API\",\n \"body\": \"- replace imperative routing with CommandRouterBuilder\\\\n- add fluent API for route registration (addRoute, withMiddleware)\\\\n- extract plugin discovery to PluginDiscoveryService class\\\\n- update integration tests for new routing pattern\",\n \"files\": [\"src/commands/routing.ts\", \"src/commands/router-builder.ts\", \"src/plugins/discovery-service.ts\", \"tests/integration/routing.test.ts\"],\n \"releaseHint\": \"patch\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"IsNewFile: false for routing.ts (modified). Diff shows refactoring to builder pattern - improves code organization and testability without changing CLI behavior\",\n \"confidence\": 0.95\n }\n }\n ]\n}\n\nREAL-WORLD EXAMPLES WITH DIFF CONTEXT (learn from these):\n\nExample 1: Modified files - use diff to determine if feat or refactor\nDiff shows:\n - Renamed variables (oldName → newName)\n - Restructured functions (extract to separate modules)\n - Updated imports and exports\n❌ WRONG: feat(core): add new commit plan logic\n✅ CORRECT: refactor(core): restructure commit plan and prompt generation\nReason: Diff shows reorganization, not new functionality\n\nExample 2: New package - check IsNewFile flags in diff\nAll files show: IsNewFile: true, implements resource broker from scratch\n✅ CORRECT: feat(core-resource-broker): add resource broker for rate limiting\nReason: Genuinely new package with new functionality\n\nExample 3: Moved files - IsNewFile: false despite status \"added\"\nDiff shows: [EXISTING FILE - was modified], same content as before\n✅ CORRECT: refactor(analytics): reorganize analytics package structure\nReason: Files moved/reorganized, not newly created\n\nExample 4: Bug fix in existing files\nDiff shows: Fix null pointer exception, add validation check\n✅ CORRECT: fix(auth): handle null token in authentication middleware\nReason: Fixing broken functionality = fix, not feat\n\nExample 5: Documentation ONLY → docs, NOT chore or feat\nFiles:\n - README.md (modified, +50/-20, IsNewFile: false)\n - docs/API.md (modified, +30/-10, IsNewFile: false)\nDiff shows: Updated markdown content, improved examples, no code changes\n❌ WRONG: chore(docs): update documentation\n❌ WRONG: feat(docs): add documentation\n✅ CORRECT: docs: improve README and API documentation\nReason: ALL files are markdown = docs (regardless of IsNewFile)\n\nExample 5b: NEW documentation files → docs, NOT feat\nFiles:\n - docs/benchmarks/README.md (added, +200/-0, IsNewFile: true)\n - docs/benchmarks/RESULTS.md (added, +100/-0, IsNewFile: true)\nDiff shows: New markdown files with benchmarks documentation\n❌ WRONG: feat(docs): add benchmarks documentation\n✅ CORRECT: docs(benchmarks): add benchmarks documentation\nReason: ALL files are .md = docs type (even if IsNewFile: true)\n\nExample 6: Bug fix with error handling → fix, NOT refactor\nFiles:\n - src/api/auth.ts (modified, +15/-5, IsNewFile: false)\nDiff shows: Added try-catch around token validation, null check before access\n✅ CORRECT: fix(api): handle null token in authentication\nReason: Adds error handling to prevent crash = bug fix\n\nExample 7: Test files ONLY → test, NOT chore\nFiles:\n - tests/auth.test.ts (added, +200/-0, IsNewFile: true)\n - tests/helpers/mock-data.ts (added, +50/-0, IsNewFile: true)\nDiff shows: New test suites for authentication module\n✅ CORRECT: test(auth): add authentication test suite\nReason: Test files only = test type\n`;\n\n/**\n * Build prompt for LLM from file summaries (Phase 1)\n */\nexport function buildPrompt(\n summaries: FileSummary[],\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n\nGenerate commit plan as JSON. If you're unsure about commit type/message from paths alone, set needsMoreContext: true and list files in requestedFiles.`;\n}\n\n/**\n * Build enhanced prompt with pattern analysis hints (Phase 1)\n */\nexport function buildEnhancedPrompt(\n summaries: FileSummary[],\n patternAnalysis: PatternAnalysis,\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n // Add pattern hints if confidence is high\n const patternHint = patternAnalysis.confidence > 0.7\n ? `\\n\\n🎯 PATTERN DETECTED (confidence: ${(patternAnalysis.confidence * 100).toFixed(0)}%):\nPattern type: ${patternAnalysis.patternType}\nSuggested commit type: ${patternAnalysis.suggestedType || 'unknown'}\n\nHints:\n${patternAnalysis.hints.map(h => ` • ${h}`).join('\\n')}\n\n⚠️ IMPORTANT: Consider this pattern analysis when determining commit types!`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n${patternHint}\n\nGenerate commit plan as JSON. If you're unsure about commit type/message from paths alone, set needsMoreContext: true and list files in requestedFiles.`;\n}\n\n/**\n * Build prompt for LLM with diff content (Phase 2 - escalation)\n */\nexport function buildPromptWithDiff(\n summaries: FileSummary[],\n diffs: Map<string, string>,\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const diffContent = Array.from(diffs.entries())\n .map(([path, diff]) => {\n // Find summary for this file to show isNewFile flag\n const summary = summaries.find((s) => s.path === path);\n const isNewLabel = summary?.isNewFile ? ' [NEW FILE - never existed before]' : ' [EXISTING FILE - was modified]';\n\n // Truncate very long diffs\n const truncatedDiff = diff.length > 2000\n ? diff.slice(0, 2000) + '\\n... (truncated)'\n : diff;\n return `### ${path}${isNewLabel}\\n\\`\\`\\`diff\\n${truncatedDiff}\\n\\`\\`\\``;\n })\n .join('\\n\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n\nDiff content for requested files:\n${diffContent}\n\nNow generate accurate commit plan based on the actual changes you see:`;\n}\n\n/**\n * Parsed LLM response with confidence assessment\n */\nexport interface ParsedLLMResponse {\n needsMoreContext: boolean;\n requestedFiles: string[];\n commits: CommitGroup[];\n averageConfidence: number;\n}\n\n/**\n * Clean and extract JSON from LLM response\n * Handles common LLM quirks: markdown blocks, extra text, trailing commas\n */\nfunction cleanJsonResponse(rawResponse: string): string {\n let cleaned = rawResponse.trim();\n\n // Remove markdown code blocks (```json...``` or ```...```)\n cleaned = cleaned.replace(/^```(?:json)?\\s*/i, '');\n cleaned = cleaned.replace(/\\s*```$/i, '');\n cleaned = cleaned.trim();\n\n // Try to find JSON object boundaries if wrapped in text\n const jsonStart = cleaned.indexOf('{');\n const jsonEnd = cleaned.lastIndexOf('}');\n\n if (jsonStart !== -1 && jsonEnd !== -1 && jsonStart < jsonEnd) {\n cleaned = cleaned.substring(jsonStart, jsonEnd + 1);\n }\n\n // Remove trailing commas before closing brackets (common JSON error)\n cleaned = cleaned.replace(/,(\\s*[}\\]])/g, '$1');\n\n return cleaned;\n}\n\n/**\n * Parse LLM response into commit groups with confidence\n */\nexport function parseResponse(\n response: string,\n summaries?: FileSummary[],\n patternAnalysis?: PatternAnalysis\n): ParsedLLMResponse {\n // Step 1: Clean response from markdown and common issues\n const cleaned = cleanJsonResponse(response);\n\n // Step 2: Try to parse JSON\n let parsed: any;\n try {\n parsed = JSON.parse(cleaned);\n } catch (error) {\n // Enhanced error message with cleaned response preview\n const preview = cleaned.substring(0, 300).replace(/\\n/g, ' ');\n throw new Error(\n `Failed to parse LLM response as JSON. ` +\n `Preview: \"${preview}${cleaned.length > 300 ? '...' : ''}\" ` +\n `Error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n // Step 3: Validate structure\n if (!parsed.commits || !Array.isArray(parsed.commits)) {\n throw new Error(\n `LLM response missing \"commits\" array. ` +\n `Got: ${JSON.stringify(parsed).substring(0, 200)}`\n );\n }\n\n // Allow empty commits array ONLY if needsMoreContext is true (escalation to Phase 2)\n if (parsed.commits.length === 0) {\n if (parsed.needsMoreContext) {\n // LLM is requesting escalation to Phase 2 - return early with empty commits\n return {\n needsMoreContext: true,\n requestedFiles: Array.isArray(parsed.requestedFiles) ? parsed.requestedFiles : [],\n commits: [],\n averageConfidence: 0,\n };\n }\n // Empty commits without escalation is an error\n throw new Error('LLM response has empty commits array and needsMoreContext is not set');\n }\n\n // Step 4: Validate and normalize each commit\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Commit validation: checks required fields (type/files/message), normalizes types, validates file arrays, handles edge cases\n const commits = parsed.commits.map((commit: Record<string, unknown>, index: number) => {\n // Validate required fields\n if (!commit.type) {\n throw new Error(`Commit ${index + 1} missing required field \"type\"`);\n }\n if (!commit.files || !Array.isArray(commit.files)) {\n throw new Error(`Commit ${index + 1} missing required field \"files\" array`);\n }\n if (commit.files.length === 0) {\n throw new Error(`Commit ${index + 1} has empty files array`);\n }\n if (!commit.message) {\n throw new Error(`Commit ${index + 1} missing required field \"message\"`);\n }\n\n // Normalize and return\n const type = normalizeType(commit.type as string);\n const files = commit.files as string[];\n\n // Parse reasoning if present\n const reasoning = commit.reasoning as Record<string, unknown> | undefined;\n let parsedReasoning: CommitReasoning | undefined;\n let confidence = 0.5; // default\n\n if (reasoning && typeof reasoning === 'object') {\n // Extract confidence from reasoning if present\n confidence = typeof reasoning.confidence === 'number' ? reasoning.confidence : 0.5;\n\n parsedReasoning = {\n newBehavior: Boolean(reasoning.newBehavior),\n fixesBug: Boolean(reasoning.fixesBug),\n internalOnly: Boolean(reasoning.internalOnly),\n explanation: typeof reasoning.explanation === 'string' ? reasoning.explanation : 'No explanation provided',\n confidence,\n };\n } else {\n // Fallback to old confidence field if no reasoning\n confidence = typeof commit.confidence === 'number' ? commit.confidence : 0.5;\n }\n\n return {\n id: (commit.id as string) || `c${index + 1}`,\n type,\n scope: typeof commit.scope === 'string' ? commit.scope : undefined,\n message: typeof commit.message === 'string' ? commit.message : 'update files',\n body: typeof commit.body === 'string' ? commit.body : undefined,\n files,\n releaseHint: normalizeReleaseHint(commit.releaseHint as string),\n breaking: Boolean(commit.breaking),\n reasoning: parsedReasoning,\n confidence, // keep for internal use\n } satisfies CommitGroup & { confidence: number };\n });\n\n // Step 5: Calculate average confidence\n const totalConfidence = commits.reduce((sum: number, c: { confidence: number }) => sum + (c.confidence ?? 0.5), 0);\n const averageConfidence = commits.length > 0 ? totalConfidence / commits.length : 0;\n\n // Step 6: Post-process - Fix incorrect commit types based on file status and pattern analysis\n const commitsWithFixedTypes = summaries\n ? commits.map((c: CommitGroup & { confidence: number }) => fixCommitType(c, summaries, patternAnalysis))\n : commits;\n\n // Step 7: Extract confidence from commits for the response (CommitGroup doesn't have confidence)\n const commitsWithoutConfidence: CommitGroup[] = commitsWithFixedTypes.map((c: CommitGroup & { confidence: number }) => {\n const { confidence: _, ...commit } = c;\n void _;\n return commit;\n });\n\n return {\n needsMoreContext: Boolean(parsed.needsMoreContext),\n requestedFiles: Array.isArray(parsed.requestedFiles) ? parsed.requestedFiles : [],\n commits: commitsWithoutConfidence,\n averageConfidence,\n };\n}\n\n/**\n * Fix commit type based on file status heuristics and pattern analysis\n * Prevents LLM from marking deletions as 'feat', refactoring as 'feat', etc.\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Type correction logic: checks deletion-only commits, test files, package.json changes, small refactors, and applies pattern-based rules\nfunction fixCommitType<T extends CommitGroup & { confidence: number }>(\n commit: T,\n summaries: FileSummary[],\n patternAnalysis?: PatternAnalysis\n): T {\n // Get summaries for files in this commit\n const commitFiles = commit.files;\n const commitSummaries = summaries.filter((s) => commitFiles.includes(s.path));\n\n if (commitSummaries.length === 0) {\n return commit; // No summaries, can't validate\n }\n\n // Rule 0: Conservative Bias - use reasoning to validate commit type\n // If LLM has low confidence (<0.7) and says feat, double-check with reasoning\n if (commit.type === 'feat' && commit.confidence < 0.7 && commit.reasoning) {\n const { newBehavior, internalOnly, fixesBug } = commit.reasoning;\n\n // If reasoning says \"internalOnly\" but type is \"feat\" → downgrade to refactor\n if (internalOnly && !newBehavior) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. Low confidence + internalOnly → refactor`,\n },\n };\n }\n\n // If reasoning says it fixes a bug but type is \"feat\" → change to fix\n if (fixesBug && !newBehavior) {\n return {\n ...commit,\n type: 'fix' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. Fixes bug → fix`,\n },\n };\n }\n\n // If newBehavior is false but type is feat → downgrade to refactor\n if (!newBehavior) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. No new behavior → refactor`,\n },\n };\n }\n }\n\n // Rule 1: If ALL files are deleted, this is NOT a feat\n const allDeleted = commitSummaries.every((s) => s.status === 'deleted');\n if (allDeleted && commit.type === 'feat') {\n return {\n ...commit,\n type: 'chore' as ConventionalType,\n message: commit.message.replace(/^add /i, 'remove ').replace(/^added /i, 'removed '),\n };\n }\n\n // Rule 2: If mostly deletions (>80% of changes are deletions), likely refactor/chore\n const totalAdditions = commitSummaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDeletions = commitSummaries.reduce((sum, s) => sum + s.deletions, 0);\n const totalChanges = totalAdditions + totalDeletions;\n\n if (totalChanges > 0) {\n const deletionRatio = totalDeletions / totalChanges;\n\n // If >80% deletions and marked as 'feat', downgrade to 'refactor'\n if (deletionRatio > 0.8 && commit.type === 'feat') {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n }\n\n // Rule 3: Pattern cross-check - use pattern detector confidence to override LLM\n // If pattern detector has high confidence (>0.8) and disagrees with LLM, use pattern's suggestion\n if (patternAnalysis && patternAnalysis.confidence > 0.8 && patternAnalysis.suggestedType) {\n const llmType = commit.type;\n const patternType = patternAnalysis.suggestedType;\n\n // Override if there's a mismatch and pattern is confident\n if (llmType !== patternType) {\n return {\n ...commit,\n type: patternType as ConventionalType,\n };\n }\n }\n\n // Rule 4: All modified files with low addition ratio → refactor, NOT feat\n const allModified = commitSummaries.every((s) => s.status === 'modified');\n\n if (allModified && totalChanges > 0 && commit.type === 'feat') {\n const additionRatio = totalAdditions / totalChanges;\n\n // If <40% additions (mostly deletions or renames) → refactor\n if (additionRatio < 0.4) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n\n // If 40-60% additions (balanced changes) → still likely refactor\n // Only keep feat if >60% additions (significant new code)\n if (additionRatio < 0.6) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n }\n\n // Rule 5: New package detection → feat, NOT chore\n // Detect: includes package.json, 10+ new files in same directory\n const hasPackageJson = commitSummaries.some((s) => s.path.endsWith('package.json'));\n\n if (hasPackageJson && commitSummaries.length >= 10) {\n const allAdded = commitSummaries.every((s) => s.status === 'added');\n const allIsNewFile = commitSummaries.every((s) => s.isNewFile === true);\n\n // All files added AND truly new (not moved) → this is a new package\n if (allAdded && allIsNewFile && commit.type === 'chore') {\n return {\n ...commit,\n type: 'feat' as ConventionalType,\n message: commit.message.replace(/^initialize /i, 'add ').replace(/^setup /i, 'add '),\n };\n }\n }\n\n return commit;\n}\n\n/**\n * Normalize commit type to valid conventional type\n */\nfunction normalizeType(type: unknown): ConventionalType {\n const validTypes: ConventionalType[] = [\n 'feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf',\n ];\n\n if (typeof type === 'string') {\n const normalized = type.toLowerCase() as ConventionalType;\n if (validTypes.includes(normalized)) {\n return normalized;\n }\n }\n\n return 'chore';\n}\n\n/**\n * Normalize release hint\n */\nfunction normalizeReleaseHint(hint: unknown): 'none' | 'patch' | 'minor' | 'major' {\n if (typeof hint === 'string') {\n const normalized = hint.toLowerCase();\n if (['none', 'patch', 'minor', 'major'].includes(normalized)) {\n return normalized as 'none' | 'patch' | 'minor' | 'major';\n }\n }\n return 'none';\n}\n","/**\n * Heuristic commit plan generation (fallback when LLM unavailable)\n */\n\n/* eslint-disable sonarjs/no-duplicate-string -- \"package.json\" string used repeatedly for file matching patterns */\n\nimport type { FileSummary, CommitGroup, ConventionalType } from '@kb-labs/commit-contracts';\nimport { dirname, extname, basename } from 'node:path';\n\n/**\n * Generate commit plan using heuristics (no LLM)\n *\n * Enhanced grouping strategy:\n * 1. Package.json changes + related files in same directory\n * 2. Test files paired with their implementation\n * 3. Remaining files grouped by directory + category\n */\nexport function generateHeuristicPlan(summaries: FileSummary[]): CommitGroup[] {\n if (summaries.length === 0) {\n return [];\n }\n\n const commits: CommitGroup[] = [];\n let commitIndex = 1;\n\n // Strategy 1: Group package.json changes with files in same directory\n const { packageGroups, remainingFiles } = groupPackageJsonChanges(summaries);\n\n for (const group of packageGroups) {\n commits.push({\n id: `c${commitIndex++}`,\n type: 'chore',\n scope: inferPackageScope(group.map(f => f.path)),\n message: 'update dependencies',\n files: group.map((f) => f.path),\n releaseHint: 'none',\n breaking: false,\n });\n }\n\n // Strategy 2: Pair test files with their implementation\n const { pairedGroups, unpairedFiles } = pairTestsWithImplementation(remainingFiles);\n\n for (const group of pairedGroups) {\n const implFile = group.find(f => !isTestFile(f.path));\n const type = inferTypeFromChanges(implFile);\n\n commits.push({\n id: `c${commitIndex++}`,\n type,\n scope: inferScope(group.map(f => f.path)),\n message: generateMessage(type, group),\n files: group.map((f) => f.path),\n releaseHint: inferReleaseHint(type, group),\n breaking: false,\n });\n }\n\n // Strategy 3: Group remaining files by category and directory\n const categoryGroups = groupByCategory(unpairedFiles);\n\n for (const [category, files] of categoryGroups) {\n const type = categoryToType(category);\n const scope = inferScope(files.map((f) => f.path));\n\n commits.push({\n id: `c${commitIndex++}`,\n type,\n scope,\n message: generateMessage(type, files),\n files: files.map((f) => f.path),\n releaseHint: inferReleaseHint(type, files),\n breaking: false,\n });\n }\n\n return commits;\n}\n\n/**\n * Group package.json changes with related files in same directory\n */\nfunction groupPackageJsonChanges(summaries: FileSummary[]): {\n packageGroups: FileSummary[][];\n remainingFiles: FileSummary[];\n} {\n const packageFiles = summaries.filter(f => f.path.endsWith('package.json'));\n const otherFiles = summaries.filter(f => !f.path.endsWith('package.json'));\n\n if (packageFiles.length === 0) {\n return { packageGroups: [], remainingFiles: summaries };\n }\n\n const packageGroups: FileSummary[][] = [];\n const claimed = new Set<FileSummary>();\n\n for (const pkgFile of packageFiles) {\n const pkgDir = dirname(pkgFile.path);\n\n // Find files in same directory as package.json\n const related = otherFiles.filter(f => {\n const fileDir = dirname(f.path);\n // Same directory or one level deep\n return fileDir === pkgDir || fileDir.startsWith(pkgDir + '/');\n });\n\n // Limit to config-related files only\n const configRelated = related.filter(f => {\n const name = basename(f.path);\n return (\n name.includes('config') ||\n name.includes('tsconfig') ||\n name.endsWith('.json') ||\n name.startsWith('.')\n );\n });\n\n const group = [pkgFile, ...configRelated];\n packageGroups.push(group);\n\n claimed.add(pkgFile);\n configRelated.forEach(f => claimed.add(f));\n }\n\n const remainingFiles = summaries.filter(f => !claimed.has(f));\n\n return { packageGroups, remainingFiles };\n}\n\n/**\n * Pair test files with their implementation files\n */\nfunction pairTestsWithImplementation(summaries: FileSummary[]): {\n pairedGroups: FileSummary[][];\n unpairedFiles: FileSummary[];\n} {\n const testFiles = summaries.filter(f => isTestFile(f.path));\n const implFiles = summaries.filter(f => !isTestFile(f.path));\n\n const pairedGroups: FileSummary[][] = [];\n const pairedImpls = new Set<FileSummary>();\n const pairedTests = new Set<FileSummary>();\n\n for (const testFile of testFiles) {\n const implPath = getImplementationPath(testFile.path);\n const implFile = implFiles.find(f => f.path === implPath);\n\n if (implFile) {\n pairedGroups.push([implFile, testFile]);\n pairedImpls.add(implFile);\n pairedTests.add(testFile);\n }\n }\n\n const unpairedFiles = [\n ...implFiles.filter(f => !pairedImpls.has(f)),\n ...testFiles.filter(f => !pairedTests.has(f)),\n ];\n\n return { pairedGroups, unpairedFiles };\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(path: string): boolean {\n return (\n path.includes('.test.') ||\n path.includes('.spec.') ||\n path.includes('/__tests__/')\n );\n}\n\n/**\n * Get implementation path from test path\n * Example: src/__tests__/foo.test.ts -> src/foo.ts\n */\nfunction getImplementationPath(testPath: string): string {\n // Remove test suffix\n let implPath = testPath\n .replace(/\\.test\\.(ts|tsx|js|jsx)$/, '.$1')\n .replace(/\\.spec\\.(ts|tsx|js|jsx)$/, '.$1');\n\n // Remove __tests__ directory\n implPath = implPath.replace('/__tests__/', '/');\n\n return implPath;\n}\n\n/**\n * Group files by category (for ungrouped files)\n */\nfunction groupByCategory(summaries: FileSummary[]): Map<string, FileSummary[]> {\n const groups = new Map<string, FileSummary[]>();\n\n for (const summary of summaries) {\n const category = categorizeFile(summary.path);\n const existing = groups.get(category) || [];\n existing.push(summary);\n groups.set(category, existing);\n }\n\n return groups;\n}\n\n/**\n * Infer package scope from paths\n */\nfunction inferPackageScope(paths: string[]): string | undefined {\n const packagePath = paths.find(p => p.endsWith('package.json'));\n if (!packagePath) {return undefined;}\n\n // Extract monorepo package name from path\n // Example: kb-labs-cli/package.json -> kb-labs-cli\n const parts = packagePath.split('/');\n if (parts.length > 1) {\n return parts[parts.length - 2]; // Directory before package.json\n }\n\n return undefined;\n}\n\n/**\n * Infer commit type from file changes (additions vs deletions)\n */\nfunction inferTypeFromChanges(file?: FileSummary): ConventionalType {\n if (!file) {return 'chore';}\n\n const { additions, deletions, status } = file;\n\n // New file -> feat\n if (status === 'added' || (additions > 0 && deletions === 0)) {\n return 'feat';\n }\n\n // Deleted file -> chore\n if (status === 'deleted' || (deletions > 0 && additions === 0)) {\n return 'chore';\n }\n\n // More additions than deletions -> feat\n if (additions > deletions * 2) {\n return 'feat';\n }\n\n // More deletions than additions -> refactor\n if (deletions > additions * 2) {\n return 'refactor';\n }\n\n // Mixed changes -> refactor\n return 'refactor';\n}\n\n/**\n * Categorize file for grouping\n */\nfunction categorizeFile(path: string): string {\n const ext = extname(path);\n const name = basename(path);\n const dir = dirname(path);\n\n // Test files\n if (\n path.includes('.test.') ||\n path.includes('.spec.') ||\n path.includes('__tests__') ||\n dir.includes('/test/') ||\n dir.includes('/tests/')\n ) {\n return 'test';\n }\n\n // Documentation\n if (ext === '.md' || dir.includes('/docs/') || name === 'README.md') {\n return 'docs';\n }\n\n // Config files\n if (\n name.startsWith('.') ||\n name.includes('config') ||\n ['package.json', 'tsconfig.json', 'eslint.config.js'].includes(name)\n ) {\n return 'config';\n }\n\n // CI/CD\n if (dir.includes('.github') || dir.includes('.gitlab') || name.includes('ci')) {\n return 'ci';\n }\n\n // Build related\n if (dir.includes('/build/') || dir.includes('/dist/') || name.includes('build')) {\n return 'build';\n }\n\n // Group by top-level directory\n const topDir = dir.split('/')[0] || 'root';\n return `src:${topDir}`;\n}\n\n/**\n * Map category to conventional commit type\n */\nfunction categoryToType(category: string): ConventionalType {\n if (category === 'test') {return 'test';}\n if (category === 'docs') {return 'docs';}\n if (category === 'config') {return 'chore';}\n if (category === 'ci') {return 'ci';}\n if (category === 'build') {return 'build';}\n return 'chore'; // Default for src:* categories\n}\n\n/**\n * Infer scope from file paths\n */\nfunction inferScope(paths: string[]): string | undefined {\n if (paths.length === 0) {return undefined;}\n\n // Find common directory\n const dirs = paths.map((p) => dirname(p).split('/'));\n const firstDir = dirs[0];\n if (!firstDir) {return undefined;}\n\n if (dirs.length === 1) {\n return firstDir.length > 1 ? firstDir[1] : firstDir[0];\n }\n\n // Find common prefix\n const commonPrefix: string[] = [];\n const minLength = Math.min(...dirs.map((d) => d.length));\n for (let i = 0; i < minLength; i++) {\n const segment = firstDir[i];\n if (segment && dirs.every((d) => d[i] === segment)) {\n commonPrefix.push(segment);\n } else {\n break;\n }\n }\n\n // Use last segment of common prefix as scope\n if (commonPrefix.length > 0) {\n const scope = commonPrefix[commonPrefix.length - 1];\n if (scope && scope !== '.' && scope !== 'src') {\n return scope;\n }\n }\n\n return undefined;\n}\n\n/**\n * Generate commit message\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Message generation logic: checks file statuses (added/deleted/modified), file types (test/docs/config), count pluralization\nfunction generateMessage(type: ConventionalType, files: FileSummary[]): string {\n const count = files.length;\n\n // Check if all additions\n const allAdded = files.every((f) => f.status === 'added');\n const allDeleted = files.every((f) => f.status === 'deleted');\n\n if (type === 'test') {\n if (allAdded) {return `add ${count} test file${count > 1 ? 's' : ''}`;}\n return `update ${count} test file${count > 1 ? 's' : ''}`;\n }\n\n if (type === 'docs') {\n if (allAdded) {return `add documentation`;}\n return `update documentation`;\n }\n\n if (type === 'ci') {\n return `update ci configuration`;\n }\n\n if (type === 'build') {\n return `update build configuration`;\n }\n\n if (type === 'chore') {\n if (files.some((f) => f.path.includes('package.json'))) {\n return `update dependencies`;\n }\n return `update configuration`;\n }\n\n // Default for src files\n if (allAdded) {\n return `add ${count} file${count > 1 ? 's' : ''}`;\n }\n if (allDeleted) {\n return `remove ${count} file${count > 1 ? 's' : ''}`;\n }\n return `update ${count} file${count > 1 ? 's' : ''}`;\n}\n\n/**\n * Infer release hint from type and files\n */\nfunction inferReleaseHint(\n type: ConventionalType,\n _files: FileSummary[]\n): 'none' | 'patch' | 'minor' | 'major' {\n switch (type) {\n case 'feat':\n return 'minor';\n case 'fix':\n return 'patch';\n case 'perf':\n return 'patch';\n case 'refactor':\n return 'patch';\n default:\n return 'none';\n }\n}\n","/**\n * Pattern detection for commit type classification\n * Detects semantic patterns in file changes before LLM analysis\n */\n\nimport type { FileSummary, ConventionalType } from '@kb-labs/commit-contracts';\n\n/**\n * Pattern types detected from file changes\n */\nexport type PatternType =\n | 'new-package' // New package with package.json + many files\n | 'refactor-move' // Bulk file move (added but not new)\n | 'refactor-modify' // Modifications with low addition ratio\n | 'deletions' // Mostly or all deletions\n | 'mixed'; // No clear pattern\n\n/**\n * Result of pattern analysis\n */\nexport interface PatternAnalysis {\n patternType: PatternType;\n confidence: number; // 0.0 - 1.0\n hints: string[]; // Human-readable hints for LLM\n suggestedType: ConventionalType | null; // Suggested commit type\n}\n\n/**\n * Analyze file summaries to detect semantic patterns\n * This runs BEFORE LLM to provide hints and improve accuracy\n */\nexport function analyzePatterns(summaries: FileSummary[]): PatternAnalysis {\n if (summaries.length === 0) {\n return {\n patternType: 'mixed',\n confidence: 0,\n hints: [],\n suggestedType: null,\n };\n }\n\n // Check patterns in priority order (highest confidence first)\n\n // Pattern 1: New package (highest confidence when detected)\n if (isNewPackagePattern(summaries)) {\n const packagePath = summaries.find(s => s.path.endsWith('package.json'))?.path;\n const packageName = packagePath ? extractPackageName(packagePath) : 'unknown';\n\n return {\n patternType: 'new-package',\n confidence: 0.95,\n hints: [\n `New package detected: ${packageName}`,\n `${summaries.length} new files including package.json`,\n 'All files are truly new (isNewFile: true)',\n 'This is a new feature (feat), not chore',\n ],\n suggestedType: 'feat',\n };\n }\n\n // Pattern 2: Bulk move/refactor (high confidence)\n if (isBulkMovePattern(summaries)) {\n const dirs = countUniqueDirs(summaries, 3);\n return {\n patternType: 'refactor-move',\n confidence: 0.90,\n hints: [\n `Bulk move pattern: ${summaries.length} files added`,\n `Files existed before (isNewFile: false)`,\n `Organized into ${dirs} director${dirs === 1 ? 'y' : 'ies'}`,\n 'This is refactoring (reorganization), not new feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // Pattern 3: Refactor modifications (good confidence)\n if (isRefactorModificationPattern(summaries)) {\n const ratio = calculateAdditionRatio(summaries);\n return {\n patternType: 'refactor-modify',\n confidence: 0.85,\n hints: [\n 'All files are modified (not new)',\n `Low addition ratio: ${(ratio * 100).toFixed(0)}%`,\n 'Mostly structural changes or deletions',\n 'This is refactoring, not new feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // Pattern 4: Deletions (handled by existing Rules 1-2)\n const allDeleted = summaries.every(s => s.status === 'deleted');\n if (allDeleted) {\n return {\n patternType: 'deletions',\n confidence: 0.98,\n hints: [\n 'All files are deleted',\n 'This is cleanup (chore), not feature',\n ],\n suggestedType: 'chore',\n };\n }\n\n const totalAdd = summaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDel = summaries.reduce((sum, s) => sum + s.deletions, 0);\n const deletionRatio = totalDel / (totalAdd + totalDel);\n\n if (deletionRatio > 0.8) {\n return {\n patternType: 'deletions',\n confidence: 0.95,\n hints: [\n `Mostly deletions: ${(deletionRatio * 100).toFixed(0)}%`,\n 'This is refactoring or cleanup, not feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // No clear pattern\n return {\n patternType: 'mixed',\n confidence: 0,\n hints: [],\n suggestedType: null,\n };\n}\n\n/**\n * Detect new package pattern\n *\n * Criteria:\n * - Includes package.json\n * - 10+ files\n * - All files status === 'added'\n * - All files isNewFile === true\n * - All files in same package directory\n */\nexport function isNewPackagePattern(summaries: FileSummary[]): boolean {\n // Must have package.json\n const hasPackageJson = summaries.some(s => s.path.endsWith('package.json'));\n if (!hasPackageJson) {return false;}\n\n // Must have 10+ files\n if (summaries.length < 10) {return false;}\n\n // All must be added\n const allAdded = summaries.every(s => s.status === 'added');\n if (!allAdded) {return false;}\n\n // All must be truly new (not moved)\n const allIsNewFile = summaries.every(s => s.isNewFile === true);\n if (!allIsNewFile) {return false;}\n\n // All files should be in same package directory\n // Extract package path from package.json location\n const packageJsonPath = summaries.find(s => s.path.endsWith('package.json'))!.path;\n const packageDir = packageJsonPath.split('/').slice(0, -1).join('/');\n\n // At least 80% of files should be in the same package\n const filesInPackage = summaries.filter(s => s.path.startsWith(packageDir + '/'));\n const inPackageRatio = filesInPackage.length / summaries.length;\n\n return inPackageRatio > 0.8;\n}\n\n/**\n * Detect bulk move/refactor pattern\n *\n * Criteria:\n * - 20+ files\n * - All files status === 'added'\n * - >50% have isNewFile === false (existed before)\n * - Organized into <5 directories\n */\nexport function isBulkMovePattern(summaries: FileSummary[]): boolean {\n // Must have 20+ files\n if (summaries.length < 20) {return false;}\n\n // All must be added\n const allAdded = summaries.every(s => s.status === 'added');\n if (!allAdded) {return false;}\n\n // >50% must be \"not new\" (moved from elsewhere)\n const notNewCount = summaries.filter(s => s.isNewFile === false).length;\n const notNewRatio = notNewCount / summaries.length;\n if (notNewRatio <= 0.5) {return false;}\n\n // Files should be organized into <5 directories (depth 3)\n const uniqueDirs = countUniqueDirs(summaries, 3);\n return uniqueDirs < 5;\n}\n\n/**\n * Detect refactor modification pattern\n *\n * Criteria:\n * - All files status === 'modified'\n * - Addition ratio < 0.4 (mostly deletions or renames)\n */\nexport function isRefactorModificationPattern(summaries: FileSummary[]): boolean {\n // All must be modified\n const allModified = summaries.every(s => s.status === 'modified');\n if (!allModified) {return false;}\n\n // Addition ratio must be low\n const additionRatio = calculateAdditionRatio(summaries);\n return additionRatio < 0.4;\n}\n\n/**\n * Count unique directories at given depth\n *\n * @param summaries - File summaries\n * @param depth - Directory depth (1 = top level, 2 = one level down, etc.)\n * @returns Number of unique directories\n *\n * @example\n * paths: ['packages/foo/src/a.ts', 'packages/foo/src/b.ts', 'packages/bar/src/c.ts']\n * depth 1: 1 (packages)\n * depth 2: 2 (packages/foo, packages/bar)\n * depth 3: 3 (packages/foo/src, packages/bar/src, packages/foo/src)\n */\nexport function countUniqueDirs(summaries: FileSummary[], depth: number): number {\n const dirs = new Set<string>();\n\n for (const summary of summaries) {\n const parts = summary.path.split('/');\n if (parts.length >= depth) {\n const dirPath = parts.slice(0, depth).join('/');\n dirs.add(dirPath);\n }\n }\n\n return dirs.size;\n}\n\n/**\n * Calculate addition ratio (additions / total changes)\n *\n * @param summaries - File summaries\n * @returns Ratio 0.0 - 1.0 (0 = all deletions, 1 = all additions)\n */\nexport function calculateAdditionRatio(summaries: FileSummary[]): number {\n const totalAdditions = summaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDeletions = summaries.reduce((sum, s) => sum + s.deletions, 0);\n const totalChanges = totalAdditions + totalDeletions;\n\n if (totalChanges === 0) {return 0;}\n\n return totalAdditions / totalChanges;\n}\n\n/**\n * Extract package name from package.json path\n *\n * @param path - Path to package.json\n * @returns Package name (e.g., \"core-resource-broker\" from \"packages/core-resource-broker/package.json\")\n */\nfunction extractPackageName(path: string): string {\n const parts = path.split('/');\n const packageJsonIndex = parts.indexOf('package.json');\n\n if (packageJsonIndex > 0) {\n const packageName = parts[packageJsonIndex - 1];\n return packageName ?? 'unknown';\n }\n\n return 'unknown';\n}\n","/**\n * Secrets detection module\n * Detects files that likely contain secrets and should not be sent to LLM\n */\n\nimport { minimatch } from \"minimatch\";\n\n/**\n * Custom error class for secrets detection\n * This error should NEVER be caught and fallback to heuristics\n */\nexport class SecretsDetectedError extends Error {\n public readonly secretMatches: SecretMatch[];\n\n constructor(matches: SecretMatch[], message: string) {\n super(message);\n this.name = 'SecretsDetectedError';\n this.secretMatches = matches;\n\n // Maintain proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, SecretsDetectedError);\n }\n }\n}\n\n/**\n * Detailed information about a detected secret\n */\nexport interface SecretMatch {\n file: string;\n line: number;\n column: number;\n pattern: string; // Which pattern matched\n patternName: string; // Human-readable pattern name\n snippet: string; // Code snippet (with context)\n matchedText: string; // The actual matched text (truncated if long)\n}\n\n/**\n * File patterns that likely contain secrets\n * Based on common secret file conventions\n */\nconst SECRET_FILE_PATTERNS = [\n // Environment files\n \".env\",\n \".env.*\",\n \"*.env\",\n \".envrc\",\n\n // NPM/Node\n \".npmrc\",\n \".yarnrc\",\n \".yarnrc.yml\",\n\n // SSH/GPG keys\n \"*.key\",\n \"*.pem\",\n \"*.p12\",\n \"*.pfx\",\n \"id_rsa\",\n \"id_dsa\",\n \"id_ecdsa\",\n \"id_ed25519\",\n \"*.pub\",\n\n // AWS\n \".aws/**\",\n \"credentials\",\n\n // Docker\n \".docker/config.json\",\n\n // Git credentials\n \".git-credentials\",\n \".netrc\",\n\n // Service account files\n \"*-service-account.json\",\n \"*-serviceaccount.json\",\n \"service-account*.json\",\n \"serviceaccount*.json\",\n\n // Kubernetes\n \"kubeconfig\",\n \"*.kubeconfig\",\n\n // Terraform\n \"*.tfvars\",\n \"terraform.tfstate\",\n \"terraform.tfstate.backup\",\n\n // Other common secrets\n \"secrets.yml\",\n \"secrets.yaml\",\n \"secret.yml\",\n \"secret.yaml\",\n \"passwords.txt\",\n \"password.txt\",\n];\n\n/**\n * Content patterns that indicate secrets (with human-readable names)\n */\nconst SECRET_CONTENT_PATTERNS: Array<{ pattern: RegExp; name: string }> = [\n // API keys/tokens\n { pattern: /api[_-]?key[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'API Key' },\n { pattern: /auth[_-]?token[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'Auth Token' },\n { pattern: /access[_-]?token[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'Access Token' },\n\n // AWS\n { pattern: /AKIA[0-9A-Z]{16}/, name: 'AWS Access Key ID' },\n { pattern: /aws[_-]?secret[_-]?access[_-]?key/i, name: 'AWS Secret Access Key' },\n\n // NPM\n { pattern: /\\/\\/registry\\.npmjs\\.org\\/:_authToken=/, name: 'NPM Auth Token' },\n { pattern: /npm_[A-Za-z0-9]{30,}/, name: 'NPM Token' },\n\n // GitHub\n { pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/, name: 'GitHub Token' },\n\n // Slack\n { pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[A-Za-z0-9]{24,}/, name: 'Slack Token' },\n\n // Private keys\n { pattern: /-----BEGIN (RSA|DSA|EC|OPENSSH|PGP) PRIVATE KEY-----/, name: 'Private Key' },\n\n // Passwords\n { pattern: /password['\":\\s]*['\"]/i, name: 'Password' },\n\n // Generic patterns\n { pattern: /secret['\":\\s]*['\"]/i, name: 'Secret' },\n];\n\n/**\n * Check if file path matches secret file patterns\n */\nexport function isSecretFile(filePath: string): boolean {\n // Normalize path separators\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n\n return SECRET_FILE_PATTERNS.some((pattern) =>\n minimatch(normalizedPath, pattern, { matchBase: true }),\n );\n}\n\n/**\n * Check if file content contains secret patterns\n */\nexport function containsSecrets(content: string): boolean {\n return SECRET_CONTENT_PATTERNS.some(({ pattern }) => pattern.test(content));\n}\n\n/**\n * Scan files for potential secrets\n * Returns list of files that likely contain secrets\n */\nexport function detectSecretFiles(files: string[]): string[] {\n return files.filter(isSecretFile);\n}\n\n/**\n * Scan file diffs for secrets\n * Returns map of files that contain secrets\n */\nexport function detectSecretsInDiffs(\n diffs: Map<string, string>,\n): Map<string, string> {\n const secretDiffs = new Map<string, string>();\n\n for (const [file, diff] of diffs.entries()) {\n if (containsSecrets(diff)) {\n secretDiffs.set(file, diff);\n }\n }\n\n return secretDiffs;\n}\n\n/**\n * Create error message for detected secrets\n */\nexport function formatSecretsWarning(secretFiles: string[]): string {\n const count = secretFiles.length;\n const filesList = secretFiles.map((f) => ` - ${f}`).join(\"\\n\");\n\n return [\n `🚨 CRITICAL SECURITY ERROR: Detected ${count} file(s) with potential secrets:`,\n filesList,\n \"\",\n \"⛔️ COMMIT GENERATION ABORTED\",\n \"\",\n \"These files contain sensitive data (API keys, tokens, credentials)\",\n \"that MUST NOT be committed to git or sent to LLM.\",\n \"\",\n \"✅ Actions to fix:\",\n \" 1. Add these files to .gitignore\",\n \" 2. Remove secrets from the files (use environment variables instead)\",\n \" 3. If already committed, use git filter-branch or BFG to remove from history\",\n \"\",\n \"⚠️ If you already ran commit:generate before, the secrets may have been\",\n \"sent to OpenAI. Rotate your credentials immediately.\",\n ].join(\"\\n\");\n}\n\n/**\n * Detect secrets in file diffs with exact location information\n * Returns array of SecretMatch with file, line, column, pattern info\n */\nexport function detectSecretsWithLocation(\n diffs: Map<string, string>,\n): SecretMatch[] {\n const matches: SecretMatch[] = [];\n\n for (const [file, diff] of diffs.entries()) {\n const lines = diff.split('\\n');\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex] ?? '';\n\n for (const { pattern, name } of SECRET_CONTENT_PATTERNS) {\n // Reset regex lastIndex for global patterns\n pattern.lastIndex = 0;\n\n const match = pattern.exec(line);\n if (match) {\n const matchedText = match[0];\n const column = match.index;\n\n // Create snippet with context (20 chars before, full match, 20 chars after)\n const snippetStart = Math.max(0, column - 20);\n const snippetEnd = Math.min(line.length, column + matchedText.length + 20);\n const snippet = line.substring(snippetStart, snippetEnd);\n\n // Truncate matched text if very long (max 50 chars)\n const displayText = matchedText.length > 50\n ? matchedText.substring(0, 50) + '...'\n : matchedText;\n\n matches.push({\n file,\n line: lineIndex + 1, // 1-based line numbers\n column: column + 1, // 1-based column numbers\n pattern: pattern.source,\n patternName: name,\n snippet: snippet.trim(),\n matchedText: displayText,\n });\n }\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Format detailed secrets report with locations\n */\nexport function formatSecretsReport(matches: SecretMatch[]): string {\n const count = matches.length;\n const fileCount = new Set(matches.map(m => m.file)).size;\n\n const lines = [\n `🚨 CRITICAL SECURITY ERROR: Detected ${count} potential secret(s) in ${fileCount} file(s)`,\n \"\",\n \"⛔️ COMMIT GENERATION BLOCKED\",\n \"\",\n ];\n\n // Group by file\n const byFile = new Map<string, SecretMatch[]>();\n for (const match of matches) {\n const existing = byFile.get(match.file) ?? [];\n existing.push(match);\n byFile.set(match.file, existing);\n }\n\n // Format each file's matches\n for (const [file, fileMatches] of byFile.entries()) {\n lines.push(`📄 ${file}:`);\n for (const match of fileMatches) {\n lines.push(` Line ${match.line}:${match.column} - ${match.patternName}`);\n lines.push(` Pattern: ${match.pattern.substring(0, 60)}${match.pattern.length > 60 ? '...' : ''}`);\n lines.push(` Matched: ${match.matchedText}`);\n lines.push(` Context: ...${match.snippet}...`);\n lines.push('');\n }\n }\n\n lines.push(\n \"🔒 These files contain sensitive data (API keys, tokens, credentials)\",\n \"that MUST NOT be committed to git or sent to LLM.\",\n \"\",\n \"✅ Actions to fix:\",\n \" 1. Review each match above - some may be false positives (e.g., examples in comments)\",\n \" 2. If real secrets: Add files to .gitignore and remove secrets (use env vars)\",\n \" 3. If false positives: Use --allow-secrets flag to proceed with confirmation\",\n \"\",\n \"⚠️ If secrets were already sent to LLM in previous runs, rotate credentials immediately!\",\n );\n\n return lines.join(\"\\n\");\n}\n","/**\n * User confirmation prompt utilities\n */\n\nimport * as readline from 'node:readline';\n\n/**\n * Prompt user for yes/no confirmation\n *\n * @param question - Question to ask\n * @param defaultValue - Default value if user just presses Enter\n * @param autoConfirm - If true, automatically return true without prompting (for --yes flag)\n * @returns Promise resolving to true if user confirms, false otherwise\n */\nexport async function promptUserConfirmation(\n question: string,\n defaultValue: boolean = false,\n autoConfirm: boolean = false\n): Promise<boolean> {\n // Auto-confirm mode (--yes flag)\n if (autoConfirm) {\n console.log(`${question} [auto-confirmed with --yes]`);\n return true;\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const defaultHint = defaultValue ? '[Y/n]' : '[y/N]';\n const fullQuestion = `${question} ${defaultHint}: `;\n\n return new Promise((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n\n const normalized = answer.trim().toLowerCase();\n\n if (normalized === '') {\n resolve(defaultValue);\n return;\n }\n\n if (normalized === 'y' || normalized === 'yes') {\n resolve(true);\n return;\n }\n\n if (normalized === 'n' || normalized === 'no') {\n resolve(false);\n return;\n }\n\n // Invalid input - use default\n resolve(defaultValue);\n });\n });\n}\n","/**\n * Main commit plan generator\n */\n\n/* eslint-disable no-await-in-loop -- Sequential LLM calls and git operations required for commit plan generation phases */\n\nimport type { CommitPlan, GitStatus, FileSummary, CommitGroup } from '@kb-labs/commit-contracts';\nimport type { GenerateOptions } from '../types';\nimport { useLogger, useAnalytics, useLLM, type LLMMessage } from '@kb-labs/sdk';\nimport { COMMIT_PLAN_TOOL, COMMIT_PLAN_TOOL_PHASE3 } from './commit-tools';\nimport { getGitStatus, getAllChangedFiles } from '../analyzer/git-status';\nimport { getFileSummaries, getFileDiffs } from '../analyzer/file-summary';\nimport { getRecentCommits } from '../analyzer/recent-commits';\nimport {\n buildPromptWithDiff,\n buildEnhancedPrompt,\n parseResponse,\n SYSTEM_PROMPT,\n SYSTEM_PROMPT_WITH_DIFF,\n type ParsedLLMResponse,\n} from './llm-prompt';\nimport { generateHeuristicPlan } from './heuristics';\nimport { analyzePatterns, type PatternAnalysis } from './pattern-detector';\nimport {\n detectSecretFiles,\n detectSecretsWithLocation,\n formatSecretsWarning,\n formatSecretsReport,\n SecretsDetectedError,\n type SecretMatch,\n} from '../analyzer/secrets-detector';\nimport { promptUserConfirmation } from '../utils/prompt';\n\n/** Confidence threshold - below this we escalate to Phase 2 with diff */\nconst CONFIDENCE_THRESHOLD = 0.7;\n\n/** Maximum retry attempts for LLM generation (both phases) */\nconst MAX_LLM_RETRIES = 2;\nconst VALID_COMMIT_TYPES = new Set(['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf']);\n\nfunction normalizeCommitId(id: string | undefined): string | undefined {\n if (!id) { return undefined; }\n const trimmed = id.trim();\n if (!trimmed) { return undefined; }\n\n if (/^c\\d+$/i.test(trimmed)) {\n return `c${trimmed.replace(/^c/i, '')}`;\n }\n\n if (/^\\d+$/.test(trimmed)) {\n return `c${trimmed}`;\n }\n\n return trimmed;\n}\n\nfunction buildFallbackMessage(files: string[]): string {\n const firstFile = files[0];\n const fileName = firstFile ? firstFile.split('/').pop() ?? firstFile : 'files';\n return files.length === 1 ? `update ${fileName}` : `update ${files.length} files`;\n}\n\nfunction toSafeCommitGroup(\n commit: Partial<CommitGroup> & { files?: string[] },\n id: string\n): CommitGroup | null {\n const files = Array.isArray(commit.files)\n ? commit.files.filter((file): file is string => typeof file === 'string' && file.length > 0)\n : [];\n if (files.length === 0) {\n return null;\n }\n\n const uniqueFiles = [...new Set(files)];\n const type = typeof commit.type === 'string' && VALID_COMMIT_TYPES.has(commit.type)\n ? commit.type\n : 'chore';\n const message = typeof commit.message === 'string' && commit.message.trim().length > 0\n ? commit.message.trim()\n : buildFallbackMessage(uniqueFiles);\n const releaseHint = commit.releaseHint\n ?? (type === 'feat' ? 'minor' : (type === 'fix' || type === 'refactor' ? 'patch' : 'none'));\n\n return {\n id,\n type,\n scope: commit.scope,\n message,\n body: commit.body,\n files: uniqueFiles,\n releaseHint,\n breaking: Boolean(commit.breaking),\n reasoning: commit.reasoning ?? {\n newBehavior: false,\n fixesBug: false,\n internalOnly: true,\n explanation: 'Generated from Phase 3 fallback due invalid or incomplete LLM commit action.',\n confidence: 0.3,\n },\n };\n}\n\n/**\n * Generate a commit plan from current git changes\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Main orchestrator: scope resolution, git status, file analysis, LLM phases (1 & 2), validation, retry logic, heuristics, anti-hallucination checks\nexport async function generateCommitPlan(options: GenerateOptions): Promise<CommitPlan> {\n const { cwd, onProgress } = options;\n\n const logger = useLogger();\n const analytics = useAnalytics();\n const llm = useLLM();\n const startTime = Date.now();\n\n // 1. Get git status — cwd is already the resolved scope directory\n const gitStatus = await getGitStatus(cwd);\n const allFiles = getAllChangedFiles(gitStatus);\n\n if (allFiles.length === 0) {\n return createEmptyPlan(cwd, gitStatus);\n }\n\n // 3. 🔒 Security: Check for secret files early - ABORT if found!\n const secretFiles = detectSecretFiles(allFiles);\n\n if (secretFiles.length > 0) {\n // Create basic matches for secret files (no location info yet - just filenames)\n const basicMatches: SecretMatch[] = secretFiles.map(file => ({\n file,\n line: 0,\n column: 0,\n pattern: 'SECRET_FILE_PATTERN',\n patternName: 'Secret File Pattern',\n snippet: '',\n matchedText: file,\n }));\n\n const warning = formatSecretsWarning(secretFiles);\n await logger.error('🚨 SECRETS DETECTED', new Error('Secrets detected'), {\n secretFiles,\n });\n console.error('\\n' + warning + '\\n');\n\n // Check if --allow-secrets flag is set\n if (!options.allowSecrets) {\n // No bypass flag - ABORT immediately\n throw new SecretsDetectedError(\n basicMatches,\n `Secrets detected in ${secretFiles.length} file(s). Use --allow-secrets to bypass after review, or add files to .gitignore.`\n );\n }\n\n // --allow-secrets flag is set - ask for user confirmation\n console.log('\\n⚠️ WARNING: --allow-secrets flag detected\\n');\n const confirmed = await promptUserConfirmation(\n `⚠️ Proceed with committing ${secretFiles.length} file(s) that may contain secrets?`,\n false // default: NO\n );\n\n if (!confirmed) {\n // User declined - ABORT\n throw new SecretsDetectedError(\n basicMatches,\n 'User declined to commit files with potential secrets.'\n );\n }\n\n // User confirmed - log warning and continue\n await logger.warn('User confirmed to proceed with files containing potential secrets', {\n secretFiles,\n confirmedAt: new Date().toISOString(),\n });\n console.log('✅ User confirmed - continuing with commit generation...\\n');\n }\n\n // 4. Get file summaries (diff stats)\n const summaries = await getFileSummaries(cwd, allFiles);\n\n // 5. Analyze patterns BEFORE LLM (pre-processing)\n const patternAnalysis = analyzePatterns(summaries);\n\n // Track pattern detection\n if (patternAnalysis.confidence > 0.7) {\n await analytics?.track('commit.pattern-detected', {\n patternType: patternAnalysis.patternType,\n confidence: patternAnalysis.confidence,\n suggestedType: patternAnalysis.suggestedType,\n fileCount: summaries.length,\n hints: patternAnalysis.hints,\n });\n\n // Log pattern detection for debugging\n await logger.debug(`Pattern detected: ${patternAnalysis.patternType} (confidence: ${patternAnalysis.confidence.toFixed(2)})`, {\n suggestedType: patternAnalysis.suggestedType,\n hints: patternAnalysis.hints,\n });\n }\n\n // 6. Get recent commits for style reference\n const recentCommits = options.recentCommits ?? await getRecentCommits(cwd, 10);\n\n // 7. Generate plan using LLM (two-phase) or heuristics\n let commits: CommitGroup[];\n let llmUsed = false;\n let tokensUsed: number | undefined;\n let escalated = false;\n\n if (llm) {\n try {\n // Check if LLM supports native tools (chatWithTools)\n const supportsNativeTools = typeof llm.chatWithTools === 'function';\n\n let parsed: ParsedLLMResponse;\n\n if (supportsNativeTools) {\n // NEW: Use native tools approach (guaranteed structured output)\n await logger.debug('Using native tools approach (chatWithTools)');\n onProgress?.('Analyzing with native tools...');\n\n const result = await generateWithNativeTools(\n llm,\n summaries,\n patternAnalysis,\n recentCommits,\n logger,\n onProgress\n );\n\n parsed = result.parsed;\n tokensUsed = result.tokensUsed;\n llmUsed = true;\n } else {\n // FALLBACK: Text-based parsing for LLMs without chatWithTools support\n await logger.debug('Using text-based parsing (fallback)');\n onProgress?.('Analyzing with text-based LLM...');\n\n const prompt = buildEnhancedPrompt(summaries, patternAnalysis, recentCommits);\n\n const result = await retryLLMCall(\n () => llm.complete(prompt, {\n systemPrompt: SYSTEM_PROMPT,\n temperature: 0.3,\n maxTokens: 2000,\n }),\n 'Phase 1',\n logger,\n onProgress\n );\n\n parsed = parseResponse(result.content, summaries, patternAnalysis);\n llmUsed = true;\n tokensUsed = result.tokensUsed;\n }\n\n // Phase 2: Escalate if LLM requests more context, confidence is low, or 10+ files\n const shouldEscalate = parsed.needsMoreContext\n || parsed.averageConfidence < CONFIDENCE_THRESHOLD\n || summaries.length >= 10;\n\n if (shouldEscalate) {\n const reason = summaries.length >= 10\n ? `${summaries.length} files (≥10)`\n : `confidence ${(parsed.averageConfidence * 100).toFixed(0)}%`;\n await logger.debug(`Escalating to Phase 2: ${reason}`, {\n fileCount: summaries.length,\n confidence: parsed.averageConfidence,\n needsMoreContext: parsed.needsMoreContext,\n requestedFiles: parsed.requestedFiles,\n });\n onProgress?.(`${reason} - fetching diff...`);\n\n // Get diff for requested files with smart selection\n // 1. If LLM specified files, use them (max 15)\n // 2. If empty/none specified, auto-select top 15 most changed files\n let filesToDiff: string[];\n\n if (parsed.requestedFiles.length > 0) {\n // LLM requested specific files - validate they exist and limit to 15\n const validFiles = parsed.requestedFiles.filter((f) => summaries.some((s) => s.path === f));\n filesToDiff = validFiles.slice(0, 15); // Truncate to max 15\n\n if (validFiles.length > 15) {\n await logger.warn(`LLM requested ${validFiles.length} files, truncated to 15 most critical`, {\n requestedCount: validFiles.length,\n truncatedCount: 15,\n });\n }\n } else {\n // No files specified - auto-select top 15 by change size\n const sortedByChanges = [...summaries].sort((a, b) => {\n const aChanges = (a.additions ?? 0) + (a.deletions ?? 0);\n const bChanges = (b.additions ?? 0) + (b.deletions ?? 0);\n return bChanges - aChanges; // Descending order\n });\n\n filesToDiff = sortedByChanges.slice(0, 15).map((s) => s.path);\n\n await logger.debug('Auto-selected top 15 most changed files for Phase 2', {\n totalFiles: summaries.length,\n selectedCount: filesToDiff.length,\n });\n }\n\n const diffs = await getFileDiffs(cwd, filesToDiff);\n\n // 🔒 Security: Check for secrets in diffs with EXACT LOCATION\n const secretMatches = detectSecretsWithLocation(diffs);\n\n if (secretMatches.length > 0) {\n // Found secrets in diff content with exact locations\n const report = formatSecretsReport(secretMatches);\n await logger.error('🚨 SECRETS DETECTED IN DIFF CONTENT', new Error('Secrets in diff'), {\n secretMatches,\n });\n onProgress?.('🚨 Secrets detected in diff');\n\n // Show detailed report to user\n console.error('\\n' + report + '\\n');\n\n // Check if --allow-secrets flag is set\n if (!options.allowSecrets) {\n // No bypass flag - ABORT immediately\n throw new SecretsDetectedError(\n secretMatches,\n `Secrets detected in ${secretMatches.length} location(s). Use --allow-secrets to bypass after review, or remove secrets before committing.`\n );\n }\n\n // --allow-secrets flag is set - ask for user confirmation (or auto-confirm with --yes)\n console.log('\\n⚠️ WARNING: --allow-secrets flag detected\\n');\n const confirmed = await promptUserConfirmation(\n `⚠️ Proceed with committing changes that contain ${secretMatches.length} potential secret(s)?`,\n false, // default: NO\n options.autoConfirm // auto-confirm if --yes flag\n );\n\n if (!confirmed) {\n // User declined - ABORT\n throw new SecretsDetectedError(\n secretMatches,\n 'User declined to commit changes with potential secrets.'\n );\n }\n\n // User confirmed - log warning and continue\n await logger.warn('User confirmed to proceed with diff containing potential secrets', {\n secretMatches: secretMatches.map(m => ({ file: m.file, line: m.line, pattern: m.patternName })),\n confirmedAt: new Date().toISOString(),\n });\n console.log('✅ User confirmed - continuing with Phase 2 analysis...\\n');\n onProgress?.('Re-analyzing with diff context (Phase 2)...');\n }\n\n if (diffs.size > 0) {\n // Phase 2: Re-generate with diff context\n // Scale maxTokens with file count: more files = more commits = more tokens needed\n const maxTokensPhase2 = Math.min(6000, 3000 + Math.floor(summaries.length / 20) * 500);\n\n await logger.debug('Re-analyzing with diff context (Phase 2)', {\n filesWithDiff: filesToDiff.length,\n supportsNativeTools,\n });\n onProgress?.('Re-analyzing with diff context (Phase 2)...');\n\n if (supportsNativeTools) {\n // Phase 2 with native tools\n const resultWithDiff = await generateWithNativeToolsPhase2(\n llm,\n summaries,\n diffs,\n recentCommits,\n logger,\n onProgress\n );\n\n parsed = resultWithDiff.parsed;\n tokensUsed = (tokensUsed ?? 0) + (resultWithDiff.tokensUsed ?? 0);\n escalated = true;\n } else {\n // Phase 2 with text-based parsing (fallback)\n const promptWithDiff = buildPromptWithDiff(summaries, diffs, recentCommits);\n\n const resultWithDiff = await retryLLMCall(\n () => llm.complete(promptWithDiff, {\n systemPrompt: SYSTEM_PROMPT_WITH_DIFF,\n temperature: 0.3,\n maxTokens: maxTokensPhase2,\n }),\n 'Phase 2',\n logger,\n onProgress\n );\n\n parsed = parseResponse(resultWithDiff.content, summaries, patternAnalysis);\n tokensUsed = (tokensUsed ?? 0) + (resultWithDiff.tokensUsed ?? 0);\n escalated = true;\n }\n }\n }\n\n commits = parsed.commits;\n\n // Validate that all files from summaries are included (may invoke Phase 3)\n commits = await validateAndFixCommits(commits, summaries, llm, llmUsed, logger, onProgress);\n } catch (error) {\n // CRITICAL: Re-throw SecretsDetectedError immediately - DO NOT fallback to heuristics!\n if (error instanceof SecretsDetectedError) {\n throw error;\n }\n\n // Fallback to heuristics ONLY for LLM errors (parse, timeout, etc.)\n await logger.warn('LLM generation failed after retries, falling back to heuristics', {\n error: error instanceof Error ? error.message : String(error),\n });\n onProgress?.('LLM failed, using heuristics...');\n commits = generateHeuristicPlan(summaries);\n }\n } else {\n commits = generateHeuristicPlan(summaries);\n }\n\n // 6. Track analytics\n const typeDistribution = commits.reduce((acc, commit) => {\n acc[commit.type] = (acc[commit.type] || 0) + 1;\n return acc;\n }, {} as Record<string, number>);\n\n await analytics?.track('commit.generation-complete', {\n totalFiles: summaries.length,\n totalCommits: commits.length,\n llmUsed,\n escalated,\n tokensUsed,\n durationMs: Date.now() - startTime,\n typeDistribution,\n cwd,\n });\n\n // 7. Build final plan\n return {\n schemaVersion: '1.0',\n createdAt: new Date().toISOString(),\n repoRoot: cwd,\n gitStatus,\n commits,\n metadata: {\n totalFiles: summaries.length,\n totalCommits: commits.length,\n llmUsed,\n tokensUsed,\n escalated,\n },\n };\n}\n\n/**\n * Create empty plan when no changes\n */\nfunction createEmptyPlan(cwd: string, gitStatus: GitStatus): CommitPlan {\n return {\n schemaVersion: '1.0',\n createdAt: new Date().toISOString(),\n repoRoot: cwd,\n gitStatus,\n commits: [],\n metadata: {\n totalFiles: 0,\n totalCommits: 0,\n llmUsed: false,\n },\n };\n}\n\n\n/**\n * Generate commits using native tools (chatWithTools) - Phase 1\n * Returns structured output without JSON parsing errors\n */\nasync function generateWithNativeTools(\n llm: ReturnType<typeof useLLM>,\n summaries: FileSummary[],\n patternAnalysis: PatternAnalysis,\n recentCommits: string[],\n logger: ReturnType<typeof useLogger>,\n _onProgress?: (message: string) => void\n): Promise<{ parsed: ParsedLLMResponse; tokensUsed?: number }> {\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM does not support native tools (chatWithTools)');\n }\n\n // Build user prompt (without JSON format instructions)\n const userPrompt = buildEnhancedPrompt(summaries, patternAnalysis, recentCommits);\n\n // Build messages\n // Note: SYSTEM_PROMPT contains JSON format instructions which are automatically\n // ignored by OpenAI when using native tools (tool schema takes precedence)\n const messages: LLMMessage[] = [\n {\n role: 'system',\n content: SYSTEM_PROMPT,\n },\n {\n role: 'user',\n content: userPrompt,\n },\n ];\n\n // Call LLM with native tools\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n // Extract tool call\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool');\n }\n\n // Tool call input is already parsed JSON (no JSON.parse needed!)\n const toolArgs = toolCall.input as {\n needsMoreContext?: boolean;\n requestedFiles?: string[];\n commits: CommitGroup[];\n };\n\n // Calculate average confidence from commits\n const totalConfidence = toolArgs.commits.reduce((sum, c) => {\n const confidence = c.reasoning?.confidence ?? 0.5;\n return sum + confidence;\n }, 0);\n const averageConfidence = toolArgs.commits.length > 0\n ? totalConfidence / toolArgs.commits.length\n : 0;\n\n await logger.debug('Native tools Phase 1 result', {\n needsMoreContext: toolArgs.needsMoreContext,\n requestedFiles: toolArgs.requestedFiles?.length ?? 0,\n commitsCount: toolArgs.commits.length,\n averageConfidence,\n });\n\n return {\n parsed: {\n needsMoreContext: Boolean(toolArgs.needsMoreContext),\n requestedFiles: toolArgs.requestedFiles ?? [],\n commits: toolArgs.commits,\n averageConfidence,\n },\n tokensUsed: response.usage ? (response.usage.promptTokens + response.usage.completionTokens) : undefined,\n };\n}\n\n/**\n * Generate commits for missing files using native tools (Phase 3)\n * Called when LLM forgot to include some files in Phase 1/2\n * May return multiple commits if files should be grouped differently\n */\nasync function generateMissingFilesCommit(\n llm: ReturnType<typeof useLLM>,\n missingSummaries: FileSummary[],\n existingCommits: CommitGroup[],\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<CommitGroup[] | null> {\n if (!llm || !llm.chatWithTools) {\n return null; // Fallback to generic commit if no LLM\n }\n\n // Build context: what commits were already created (with IDs and files for extend_existing action)\n const existingCommitsContext = existingCommits\n .map((c) => {\n const filesPreview = c.files.length <= 3\n ? c.files.join(', ')\n : `${c.files.slice(0, 3).join(', ')} and ${c.files.length - 3} more`;\n return `[${c.id}] ${c.type}${c.scope ? `(${c.scope})` : ''}: ${c.message}\\n Files: ${filesPreview}`;\n })\n .join('\\n\\n');\n\n // Build prompt for missing files\n const missingFilesList = missingSummaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const systemPrompt = `You are analyzing files that were not included in the initial commit plan.\n\nCONTEXT: These files were not classified by the LLM in previous phases. Your task is to determine:\n1. Why they were missed (config files, minor changes, unrelated changes, etc.)\n2. Whether they belong to an EXISTING commit or need a NEW commit\n3. What type of commit they should be (chore, refactor, fix, feat, docs, test, etc.)\n\nCRITICAL: You have TWO actions available:\n\nACTION 1: extend_existing (PREFER THIS if file is related to existing commit)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nUse when a file logically belongs to an already created commit.\n\nExample: If existing commit is \"feat(fs): add fs adapter\" and you see:\n- packages/adapters-fs/src/secure-storage.test.ts (test for fs adapter)\n\nThen use:\n{\n \"action\": \"extend_existing\",\n \"existingCommitId\": \"c1\",\n \"files\": [\"packages/adapters-fs/src/secure-storage.test.ts\"]\n}\n\nThe file will be added to commit c1 instead of creating a new commit.\n\nACTION 2: create_new (use when file is unrelated to existing commits)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nUse when files don't fit into any existing commit.\n\nDEFAULT to \"chore\" unless you see clear evidence of feat/fix/refactor.\n\nIMPORTANT: These are leftover files - they are usually:\n- Configuration files (package.json, tsconfig.json, etc.)\n- Minor updates to existing files\n- Test files or documentation\n- Build/tooling changes\n\nCRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (not generic):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n❌ BAD (too generic):\n- \"update files\"\n- \"update configuration\"\n- \"update additional files\"\n- \"update 30 files\"\n\n✅ GOOD (specific and descriptive):\n- \"update TypeScript and ESLint configuration for strict mode\"\n- \"update package dependencies for security patches\"\n- \"update build configuration to support ESM modules\"\n\nGuidelines:\n- Include WHAT was changed (specific files/components)\n- Include WHY if relevant (context about the change)\n- Use concrete nouns (not \"files\", \"additional files\")\n- Add context that helps reviewers understand the change`;\n\n const userPrompt = `Existing commits (you can add files to these using extend_existing action):\n${existingCommitsContext}\n\nFiles that need classification (${missingSummaries.length} remaining):\n${missingFilesList}\n\nIMPORTANT: You don't need to classify ALL files in one response if there are too many.\n- If you can confidently classify some files → do it\n- If you're unsure about some files → skip them (they'll be processed in next iteration)\n- Focus on files you can group logically\n\nFor each file, choose the appropriate action:\n1. extend_existing - if file belongs to an existing commit (e.g., test file for fs adapter → add to \"feat(fs): add fs adapter\")\n2. create_new - if file doesn't fit into any existing commit\n\nYou may create:\n- ONE new commit if all remaining files are related (same purpose, same change type)\n- MULTIPLE new commits if files have different purposes (e.g., separate config changes from test updates)\n- MIX of extend_existing and create_new actions (recommended!)\n\nCRITICAL: Be specific in each commit message - describe WHAT is being changed, not just \"update files\".\nPREFER extend_existing when possible to avoid creating unnecessary commits.`;\n\n const messages: LLMMessage[] = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ];\n\n try {\n onProgress?.('Classifying remaining files (Phase 3)...');\n\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL_PHASE3],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n await logger.warn('Phase 3: LLM did not call tool, using fallback');\n return null;\n }\n\n const toolArgs = toolCall.input as {\n commits: Array<CommitGroup & { action?: 'create_new' | 'extend_existing'; existingCommitId?: string }>;\n };\n\n if (!toolArgs.commits || toolArgs.commits.length === 0) {\n await logger.warn('Phase 3: LLM returned empty commits, using fallback');\n return null;\n }\n\n // Process each commit action\n const newCommits: CommitGroup[] = [];\n let extendedCount = 0;\n let createdCount = 0;\n\n for (const commit of toolArgs.commits) {\n if (!Array.isArray(commit.files) || commit.files.length === 0) {\n await logger.warn('Phase 3: Skipping commit action with empty files', {\n action: commit.action,\n existingCommitId: commit.existingCommitId,\n });\n continue;\n }\n\n const action = commit.action || 'create_new'; // Default to create_new for backward compatibility\n\n if (action === 'extend_existing') {\n // Find existing commit by ID\n const normalizedRequestedId = normalizeCommitId(commit.existingCommitId);\n const existingCommit = existingCommits.find(c => normalizeCommitId(c.id) === normalizedRequestedId);\n if (existingCommit) {\n // Add files to existing commit\n existingCommit.files.push(...commit.files);\n extendedCount++;\n await logger.debug('Phase 3: Extended existing commit', {\n commitId: existingCommit.id,\n message: existingCommit.message,\n addedFiles: commit.files.length,\n });\n } else {\n // Fallback: create new commit if ID not found\n await logger.warn('Phase 3: Commit ID not found, creating new instead', {\n requestedId: commit.existingCommitId,\n normalizedRequestedId,\n availableIds: existingCommits.map(c => c.id).slice(0, 10),\n });\n const safeCommit = toSafeCommitGroup(\n commit,\n `c${existingCommits.length + newCommits.length + 1}`\n );\n if (safeCommit) {\n newCommits.push(safeCommit);\n createdCount++;\n } else {\n await logger.warn('Phase 3: Fallback commit had no valid files, skipped', {\n requestedId: commit.existingCommitId,\n });\n }\n }\n } else {\n // action === 'create_new'\n const safeCommit = toSafeCommitGroup(\n commit,\n `c${existingCommits.length + newCommits.length + 1}`\n );\n if (safeCommit) {\n newCommits.push(safeCommit);\n createdCount++;\n } else {\n await logger.warn('Phase 3: create_new action had no valid files, skipped');\n }\n }\n }\n\n await logger.debug('Phase 3: Processed commits', {\n total: toolArgs.commits.length,\n extended: extendedCount,\n created: createdCount,\n newCommitsCount: newCommits.length,\n });\n\n return newCommits;\n } catch (error) {\n await logger.warn('Phase 3 failed, using fallback', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\n/**\n * Generate commits using native tools (chatWithTools) - Phase 2 with diff\n * Returns structured output without JSON parsing errors\n */\nasync function generateWithNativeToolsPhase2(\n llm: ReturnType<typeof useLLM>,\n summaries: FileSummary[],\n diffs: Map<string, string>,\n recentCommits: string[],\n logger: ReturnType<typeof useLogger>,\n _onProgress?: (message: string) => void\n): Promise<{ parsed: ParsedLLMResponse; tokensUsed?: number }> {\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM does not support native tools (chatWithTools)');\n }\n\n // Build user prompt with diff context\n const userPrompt = buildPromptWithDiff(summaries, diffs, recentCommits);\n\n // Build messages\n const messages: LLMMessage[] = [\n {\n role: 'system',\n content: SYSTEM_PROMPT_WITH_DIFF,\n },\n {\n role: 'user',\n content: userPrompt,\n },\n ];\n\n // Call LLM with native tools\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n // Extract tool call\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool in Phase 2');\n }\n\n // Tool call input is already parsed JSON (no JSON.parse needed!)\n const toolArgs = toolCall.input as {\n needsMoreContext?: boolean;\n requestedFiles?: string[];\n commits: CommitGroup[];\n };\n\n // Calculate average confidence from commits\n const totalConfidence = toolArgs.commits.reduce((sum, c) => {\n const confidence = c.reasoning?.confidence ?? 0.5;\n return sum + confidence;\n }, 0);\n const averageConfidence = toolArgs.commits.length > 0\n ? totalConfidence / toolArgs.commits.length\n : 0;\n\n await logger.debug('Native tools Phase 2 result', {\n commitsCount: toolArgs.commits.length,\n averageConfidence,\n });\n\n return {\n parsed: {\n needsMoreContext: false, // Phase 2 is final, no more escalation\n requestedFiles: [],\n commits: toolArgs.commits,\n averageConfidence,\n },\n tokensUsed: response.usage ? (response.usage.promptTokens + response.usage.completionTokens) : undefined,\n };\n}\n\nexport interface ValidationResult {\n commits: CommitGroup[];\n warnings: string[];\n hallucinations: string[];\n}\n\n/**\n * Anti-hallucination validation: ensure LLM output matches reality\n * 1. Remove hallucinated files (files that don't exist in git status)\n * 2. Remove duplicate files (file appears in multiple commits)\n * 3. Add missing files that LLM forgot (Phase 3: use LLM if available)\n * 4. Track warnings for debugging\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Anti-hallucination checks: detects hallucinated files, removes duplicates, groups forgotten files, optional LLM phase 3, tracks warnings\nasync function validateAndFixCommits(\n commits: CommitGroup[],\n summaries: FileSummary[],\n llm: ReturnType<typeof useLLM>,\n llmUsed: boolean,\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<CommitGroup[]> {\n const realFiles = new Set(summaries.map((s) => s.path));\n const hallucinations: string[] = [];\n\n // Step 1: Remove hallucinated files from each commit\n for (const commit of commits) {\n const validFiles: string[] = [];\n for (const file of commit.files) {\n if (realFiles.has(file)) {\n validFiles.push(file);\n } else {\n hallucinations.push(file);\n }\n }\n commit.files = validFiles;\n }\n\n // Step 2: Remove empty commits (all files were hallucinated)\n let nonEmptyCommits = commits.filter((c) => c.files.length > 0);\n\n // Step 3: Remove duplicate files - keep only first occurrence\n const seenFiles = new Set<string>();\n const duplicates: Array<{ file: string; commit: string }> = [];\n\n for (const commit of nonEmptyCommits) {\n const uniqueFiles: string[] = [];\n for (const file of commit.files) {\n if (!seenFiles.has(file)) {\n uniqueFiles.push(file);\n seenFiles.add(file);\n } else {\n duplicates.push({ file, commit: commit.id });\n }\n }\n commit.files = uniqueFiles;\n }\n\n // Log duplicates for debugging LLM behavior\n if (duplicates.length > 0) {\n logger.warn(`LLM returned ${duplicates.length} duplicate file(s) across commits - removed duplicates`, {\n duplicateCount: duplicates.length,\n samples: duplicates.slice(0, 5).map(d => `${d.file} in ${d.commit}`),\n });\n }\n\n // Step 4: Remove commits that became empty after deduplication\n nonEmptyCommits = nonEmptyCommits.filter((c) => c.files.length > 0);\n\n // Step 5: Adaptive Phase 3 loop - process missing files iteratively (up to 5 iterations for heavy cases)\n const MAX_PHASE3_ITERATIONS = 5;\n let phase3Iteration = 0;\n\n while (phase3Iteration < MAX_PHASE3_ITERATIONS) {\n // Recalculate missing files after each iteration\n const allFilesInCommits = new Set(nonEmptyCommits.flatMap((c) => c.files));\n const missingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !allFilesInCommits.has(f));\n\n if (missingFiles.length === 0) {\n // ✅ Success! All files classified\n if (phase3Iteration > 0) {\n await logger.info('Phase 3: All files classified', {\n totalIterations: phase3Iteration,\n totalCommits: nonEmptyCommits.length,\n });\n }\n break;\n }\n\n phase3Iteration++;\n\n await logger.debug(`Phase 3 iteration ${phase3Iteration}/${MAX_PHASE3_ITERATIONS}`, {\n missingFiles: missingFiles.length,\n processedSoFar: summaries.length - missingFiles.length,\n totalFiles: summaries.length,\n progress: `${Math.round(((summaries.length - missingFiles.length) / summaries.length) * 100)}%`,\n });\n\n // Update progress for user\n if (onProgress) {\n const progress = Math.round(((summaries.length - missingFiles.length) / summaries.length) * 100);\n onProgress(`Classifying remaining files (Phase 3, iteration ${phase3Iteration}, ${progress}%)...`);\n }\n\n // Get summaries for missing files only\n const missingSummaries = summaries.filter((s) => missingFiles.includes(s.path));\n\n // Try LLM to generate commits for missing files (may extend existing or create new)\n let missingCommits: CommitGroup[] | null = null;\n\n if (llmUsed && llm) {\n missingCommits = await generateMissingFilesCommit(\n llm,\n missingSummaries,\n nonEmptyCommits, // ← pass updated commits list (includes previous iterations)\n logger,\n onProgress\n );\n\n if (missingCommits && missingCommits.length > 0) {\n await logger.debug(`Phase 3 iteration ${phase3Iteration}: Processed commits`, {\n commitCount: missingCommits.length,\n filesCount: missingCommits.reduce((sum, c) => sum + c.files.length, 0),\n });\n\n // Add new commits to the list (extended commits are already modified in place)\n nonEmptyCommits.push(...missingCommits);\n }\n }\n\n // Safety check: if LLM didn't process ANY files, break to avoid infinite loop\n const newMissingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !new Set(nonEmptyCommits.flatMap(c => c.files)).has(f));\n\n if (newMissingFiles.length === missingFiles.length) {\n // LLM didn't process any files this iteration - something is wrong\n await logger.warn('Phase 3: LLM made no progress, stopping iterations', {\n iteration: phase3Iteration,\n stillMissing: newMissingFiles.length,\n });\n break;\n }\n\n // Safety: if only few files left and many iterations, use fallback to avoid over-iteration\n if (newMissingFiles.length <= 3 && phase3Iteration >= 2) {\n await logger.debug('Phase 3: Few files left, proceeding to fallback');\n break;\n }\n }\n\n // Fallback: if still missing files after MAX_ITERATIONS\n const finalMissingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !new Set(nonEmptyCommits.flatMap(c => c.files)).has(f));\n\n if (finalMissingFiles.length > 0) {\n await logger.warn('Phase 3: Max iterations reached or LLM struggled, using fallback', {\n totalIterations: phase3Iteration,\n remainingFiles: finalMissingFiles.length,\n });\n\n const firstFile = finalMissingFiles[0];\n const fileName = firstFile ? firstFile.split('/').pop() ?? firstFile : 'files';\n const commitMessage = finalMissingFiles.length === 1\n ? `update ${fileName}`\n : `update ${finalMissingFiles.length} remaining files`;\n\n const fallbackCommit: CommitGroup = {\n id: `c${nonEmptyCommits.length + 1}`,\n type: 'chore',\n message: commitMessage,\n files: finalMissingFiles,\n releaseHint: 'none',\n breaking: false,\n reasoning: {\n newBehavior: false,\n fixesBug: false,\n internalOnly: true,\n explanation: `Files not classified after ${phase3Iteration} Phase 3 iteration(s): ${finalMissingFiles.slice(0, 3).join(', ')}${finalMissingFiles.length > 3 ? ` and ${finalMissingFiles.length - 3} more` : ''}`,\n confidence: 0.3,\n },\n };\n\n nonEmptyCommits.push(fallbackCommit);\n }\n\n return nonEmptyCommits;\n}\n\n/**\n * Retry LLM call with automatic fallback on parse errors\n * Tries up to MAX_LLM_RETRIES times before throwing\n */\nasync function retryLLMCall(\n llmFn: () => Promise<{ content: string; tokensUsed?: number }>,\n phase: string,\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<{ content: string; tokensUsed?: number }> {\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= MAX_LLM_RETRIES; attempt++) {\n try {\n const result = await llmFn();\n\n // Try to parse response to validate JSON\n parseResponse(result.content);\n\n // Success - return result\n if (attempt > 1) {\n await logger.debug(`${phase} succeeded on attempt ${attempt}/${MAX_LLM_RETRIES}`);\n }\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // DEBUG: Log full error details\n await logger.error(`🔍 LLM call failed (attempt ${attempt})`, lastError, {\n errorName: lastError.name,\n errorMessage: lastError.message,\n errorStack: lastError.stack,\n });\n\n // Extract error type for better user feedback\n const errorType = getErrorType(lastError);\n\n if (attempt < MAX_LLM_RETRIES) {\n // Log to file with full details\n await logger.warn(`${phase} failed (attempt ${attempt}/${MAX_LLM_RETRIES}): ${errorType}`, {\n errorMessage: lastError.message,\n errorType,\n attempt,\n stack: lastError.stack?.split('\\n').slice(0, 3).join('\\n'), // First 3 lines only\n });\n\n // Show concise user message\n onProgress?.(`${phase} ${errorType}, retrying (${attempt}/${MAX_LLM_RETRIES})...`);\n\n // Short delay before retry (exponential backoff: 1s, 2s, 4s...)\n await new Promise((resolve) => {\n setTimeout(resolve, 1000 * Math.pow(2, attempt - 1));\n });\n } else {\n await logger.error(`${phase} failed after ${MAX_LLM_RETRIES} attempts: ${errorType}`, lastError, {\n errorType,\n });\n }\n }\n }\n\n // All retries exhausted\n throw lastError || new Error(`${phase} failed after ${MAX_LLM_RETRIES} attempts`);\n}\n\n/**\n * Extract user-friendly error type from error message\n */\nfunction getErrorType(error: Error): string {\n const message = error.message.toLowerCase();\n\n // Rate limiting\n if (message.includes('429') || message.includes('rate limit') || message.includes('too many requests')) {\n return 'rate limited (429)';\n }\n\n // Server errors\n if (message.includes('500') || message.includes('502') || message.includes('503')) {\n return 'server error (5xx)';\n }\n\n // Timeout\n if (message.includes('timeout') || message.includes('timed out')) {\n return 'timeout';\n }\n\n // Network errors\n if (message.includes('network') || message.includes('econnrefused') || message.includes('enotfound')) {\n return 'network error';\n }\n\n // Parse errors (invalid JSON from LLM)\n if (message.includes('json') || message.includes('parse') || message.includes('unexpected token')) {\n return 'invalid JSON';\n }\n\n // LLM response validation errors\n if (message.includes('missing') || message.includes('missing required field')) {\n return 'invalid structure';\n }\n\n // Generic - include first 50 chars of error for debugging\n const preview = error.message.substring(0, 50).replace(/\\n/g, ' ');\n return `error: ${preview}${error.message.length > 50 ? '...' : ''}`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/generator/commit-tools.ts","../../src/analyzer/git-status.ts","../../src/analyzer/file-summary.ts","../../src/analyzer/recent-commits.ts","../../src/generator/llm-prompt.ts","../../src/generator/heuristics.ts","../../src/generator/pattern-detector.ts","../../src/analyzer/secrets-detector.ts","../../src/utils/prompt.ts","../../src/generator/commit-plan.ts"],"names":["simpleGit","group"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwStB,IAAM,uBAAA,GAA0B,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmQhC,SAAS,WAAA,CACd,WACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;;AAAA,uJAAA,CAAA;AAGX;AAKO,SAAS,mBAAA,CACd,SAAA,EACA,eAAA,EACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAGJ,EAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,UAAA,GAAa,GAAA,GAC7C;;AAAA,wCAAA,EAAA,CAAyC,eAAA,CAAgB,UAAA,GAAa,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,cAAA,EAC3E,gBAAgB,WAAW;AAAA,uBAAA,EAClB,eAAA,CAAgB,iBAAiB,SAAS;;AAAA;AAAA,EAGjE,eAAA,CAAgB,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,SAAA,EAAO,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;;AAAA,qFAAA,CAAA,GAGjD,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;;AAAA,uJAAA,CAAA;AAGb;AAKO,SAAS,mBAAA,CACd,SAAA,EACA,KAAA,EACA,aAAA,EACQ;AACR,EAAA,MAAM,QAAA,GAAW,SAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAS,CAAA,CAC3C,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,IAAI,CAAA,KAAM;AAErB,IAAA,MAAM,UAAU,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,OAAA,EAAS,SAAA,GAAY,oCAAA,GAAuC,iCAAA;AAG/E,IAAA,MAAM,aAAA,GAAgB,KAAK,MAAA,GAAS,GAAA,GAChC,KAAK,KAAA,CAAM,CAAA,EAAG,GAAI,CAAA,GAAI,mBAAA,GACtB,IAAA;AACJ,IAAA,OAAO,CAAA,IAAA,EAAO,IAAI,CAAA,EAAG,UAAU;AAAA;AAAA,EAAiB,aAAa;AAAA,MAAA,CAAA;AAAA,EAC/D,CAAC,CAAA,CACA,IAAA,CAAK,MAAM,CAAA;AAEd,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,MAAA,GAAS,CAAA,GACrC;AAAA;AAAA,EAA2B,aAAA,CAAc,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACtF,EAAA;AAEJ,EAAA,OAAO,CAAA;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;;AAAA;AAAA,EAGT,WAAW;;AAAA,sEAAA,CAAA;AAGb;AAgBA,SAAS,kBAAkB,WAAA,EAA6B;AACtD,EAAA,IAAI,OAAA,GAAU,YAAY,IAAA,EAAK;AAG/B,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA;AACjD,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AACxC,EAAA,OAAA,GAAU,QAAQ,IAAA,EAAK;AAGvB,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,WAAA,CAAY,GAAG,CAAA;AAEvC,EAAA,IAAI,SAAA,KAAc,EAAA,IAAM,OAAA,KAAY,EAAA,IAAM,YAAY,OAAA,EAAS;AAC7D,IAAA,OAAA,GAAU,OAAA,CAAQ,SAAA,CAAU,SAAA,EAAW,OAAA,GAAU,CAAC,CAAA;AAAA,EACpD;AAGA,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,cAAA,EAAgB,IAAI,CAAA;AAE9C,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,aAAA,CACd,QAAA,EACA,SAAA,EACA,eAAA,EACmB;AAEnB,EAAA,MAAM,OAAA,GAAU,kBAAkB,QAAQ,CAAA;AAG1C,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AAEd,IAAA,MAAM,OAAA,GAAU,QAAQ,SAAA,CAAU,CAAA,EAAG,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC5D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,gDAAA,EACa,OAAO,CAAA,EAAG,OAAA,CAAQ,SAAS,GAAA,GAAM,KAAA,GAAQ,EAAE,CAAA,SAAA,EAC9C,iBAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,KAClE;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,OAAO,OAAA,IAAW,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AACrD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2CAAA,EACQ,KAAK,SAAA,CAAU,MAAM,EAAE,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,KAClD;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,IAAI,OAAO,gBAAA,EAAkB;AAE3B,MAAA,OAAO;AAAA,QACL,gBAAA,EAAkB,IAAA;AAAA,QAClB,cAAA,EAAgB,MAAM,OAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,GAAI,MAAA,CAAO,iBAAiB,EAAC;AAAA,QAChF,SAAS,EAAC;AAAA,QACV,iBAAA,EAAmB;AAAA,OACrB;AAAA,IACF;AAEA,IAAA,MAAM,IAAI,MAAM,sEAAsE,CAAA;AAAA,EACxF;AAIA,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,QAAiC,KAAA,KAAkB;AAErF,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,8BAAA,CAAgC,CAAA;AAAA,IACrE;AACA,IAAA,IAAI,CAAC,OAAO,KAAA,IAAS,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AACjD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,qCAAA,CAAuC,CAAA;AAAA,IAC5E;AACA,IAAA,IAAI,MAAA,CAAO,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,sBAAA,CAAwB,CAAA;AAAA,IAC7D;AACA,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,KAAA,GAAQ,CAAC,CAAA,iCAAA,CAAmC,CAAA;AAAA,IACxE;AAGA,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,MAAA,CAAO,IAAc,CAAA;AAChD,IAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AAGrB,IAAA,MAAM,YAAY,MAAA,CAAO,SAAA;AACzB,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,UAAA,GAAa,GAAA;AAEjB,IAAA,IAAI,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAE9C,MAAA,UAAA,GAAa,OAAO,SAAA,CAAU,UAAA,KAAe,QAAA,GAAW,UAAU,UAAA,GAAa,GAAA;AAE/E,MAAA,eAAA,GAAkB;AAAA,QAChB,WAAA,EAAa,OAAA,CAAQ,SAAA,CAAU,WAAW,CAAA;AAAA,QAC1C,QAAA,EAAU,OAAA,CAAQ,SAAA,CAAU,QAAQ,CAAA;AAAA,QACpC,YAAA,EAAc,OAAA,CAAQ,SAAA,CAAU,YAAY,CAAA;AAAA,QAC5C,aAAa,OAAO,SAAA,CAAU,WAAA,KAAgB,QAAA,GAAW,UAAU,WAAA,GAAc,yBAAA;AAAA,QACjF;AAAA,OACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,UAAA,GAAa,OAAO,MAAA,CAAO,UAAA,KAAe,QAAA,GAAW,OAAO,UAAA,GAAa,GAAA;AAAA,IAC3E;AAEA,IAAA,OAAO;AAAA,MACL,EAAA,EAAK,MAAA,CAAO,EAAA,IAAiB,CAAA,CAAA,EAAI,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC1C,IAAA;AAAA,MACA,OAAO,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,OAAO,KAAA,GAAQ,MAAA;AAAA,MACzD,SAAS,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,GAAW,OAAO,OAAA,GAAU,cAAA;AAAA,MAC/D,MAAM,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,GAAO,MAAA;AAAA,MACtD,KAAA;AAAA,MACA,WAAA,EAAa,oBAAA,CAAqB,MAAA,CAAO,WAAqB,CAAA;AAAA,MAC9D,QAAA,EAAU,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,MACjC,SAAA,EAAW,eAAA;AAAA,MACX;AAAA;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,EAAa,MAA8B,GAAA,IAAO,CAAA,CAAE,UAAA,IAAc,GAAA,CAAA,EAAM,CAAC,CAAA;AACjH,EAAA,MAAM,oBAAoB,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,eAAA,GAAkB,QAAQ,MAAA,GAAS,CAAA;AAGlF,EAAA,MAAM,qBAAA,GAAwB,SAAA,GAC1B,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAA4C,aAAA,CAAc,CAAA,EAAG,SAAA,EAAW,eAAe,CAAC,CAAA,GACrG,OAAA;AAGJ,EAAA,MAAM,wBAAA,GAA0C,qBAAA,CAAsB,GAAA,CAAI,CAAC,CAAA,KAA4C;AACrH,IAAA,MAAM,EAAE,UAAA,EAAY,CAAA,EAAG,GAAG,QAAO,GAAI,CAAA;AAErC,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,OAAA,CAAQ,MAAA,CAAO,gBAAgB,CAAA;AAAA,IACjD,cAAA,EAAgB,MAAM,OAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,GAAI,MAAA,CAAO,iBAAiB,EAAC;AAAA,IAChF,OAAA,EAAS,wBAAA;AAAA,IACT;AAAA,GACF;AACF;AAOA,SAAS,aAAA,CACP,MAAA,EACA,SAAA,EACA,eAAA,EACG;AAEH,EAAA,MAAM,cAAc,MAAA,CAAO,KAAA;AAC3B,EAAA,MAAM,eAAA,GAAkB,UAAU,MAAA,CAAO,CAAC,MAAM,WAAA,CAAY,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAE5E,EAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAChC,IAAA,OAAO,MAAA;AAAA,EACT;AAIA,EAAA,IAAI,OAAO,IAAA,KAAS,MAAA,IAAU,OAAO,UAAA,GAAa,GAAA,IAAO,OAAO,SAAA,EAAW;AACzE,IAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAc,QAAA,KAAa,MAAA,CAAO,SAAA;AAGvD,IAAA,IAAI,YAAA,IAAgB,CAAC,WAAA,EAAa;AAChC,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,+CAAA;AAAA;AAClE,OACF;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,IAAY,CAAC,WAAA,EAAa;AAC5B,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,KAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,sBAAA;AAAA;AAClE,OACF;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,UAAA;AAAA,QACN,SAAA,EAAW;AAAA,UACT,GAAG,MAAA,CAAO,SAAA;AAAA,UACV,WAAA,EAAa,CAAA,oBAAA,EAAuB,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,iCAAA;AAAA;AAClE,OACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AACtE,EAAA,IAAI,UAAA,IAAc,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AACxC,IAAA,OAAO;AAAA,MACL,GAAG,MAAA;AAAA,MACH,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA,CAAQ,UAAU,SAAS,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,UAAU;AAAA,KACrF;AAAA,EACF;AAGA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC9E,EAAA,MAAM,cAAA,GAAiB,gBAAgB,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC9E,EAAA,MAAM,eAAe,cAAA,GAAiB,cAAA;AAEtC,EAAA,IAAI,eAAe,CAAA,EAAG;AACpB,IAAA,MAAM,gBAAgB,cAAA,GAAiB,YAAA;AAGvC,IAAA,IAAI,aAAA,GAAgB,GAAA,IAAO,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AACjD,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAIA,EAAA,IAAI,eAAA,IAAmB,eAAA,CAAgB,UAAA,GAAa,GAAA,IAAO,gBAAgB,aAAA,EAAe;AACxF,IAAA,MAAM,UAAU,MAAA,CAAO,IAAA;AACvB,IAAA,MAAM,cAAc,eAAA,CAAgB,aAAA;AAGpC,IAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,cAAc,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,UAAU,CAAA;AAExE,EAAA,IAAI,WAAA,IAAe,YAAA,GAAe,CAAA,IAAK,MAAA,CAAO,SAAS,MAAA,EAAQ;AAC7D,IAAA,MAAM,gBAAgB,cAAA,GAAiB,YAAA;AAGvC,IAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAIA,IAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AAIA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAElF,EAAA,IAAI,cAAA,IAAkB,eAAA,CAAgB,MAAA,IAAU,EAAA,EAAI;AAClD,IAAA,MAAM,WAAW,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AAClE,IAAA,MAAM,eAAe,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,IAAI,CAAA;AAGtE,IAAA,IAAI,QAAA,IAAY,YAAA,IAAgB,MAAA,CAAO,IAAA,KAAS,OAAA,EAAS;AACvD,MAAA,OAAO;AAAA,QACL,GAAG,MAAA;AAAA,QACH,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,MAAM,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,MAAM;AAAA,OACrF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,cAAc,IAAA,EAAiC;AACtD,EAAA,MAAM,UAAA,GAAiC;AAAA,IACrC,MAAA;AAAA,IAAQ,KAAA;AAAA,IAAO,UAAA;AAAA,IAAY,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,MAAA;AAAA,IAAQ,OAAA;AAAA,IAAS,IAAA;AAAA,IAAM;AAAA,GACrE;AAEA,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAM,UAAA,GAAa,KAAK,WAAA,EAAY;AACpC,IAAA,IAAI,UAAA,CAAW,QAAA,CAAS,UAAU,CAAA,EAAG;AACnC,MAAA,OAAO,UAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,qBAAqB,IAAA,EAAqD;AACjF,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAM,UAAA,GAAa,KAAK,WAAA,EAAY;AACpC,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA,CAAE,QAAA,CAAS,UAAU,CAAA,EAAG;AAC5D,MAAA,OAAO,UAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;ACn+BO,SAAS,sBAAsB,SAAA,EAAyC;AAC7E,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,MAAM,EAAE,aAAA,EAAe,cAAA,EAAe,GAAI,wBAAwB,SAAS,CAAA;AAE3E,EAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA,EAAM,OAAA;AAAA,MACN,OAAO,iBAAA,CAAkB,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,MAC/C,OAAA,EAAS,qBAAA;AAAA,MACT,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,MAAA;AAAA,MACb,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,4BAA4B,cAAc,CAAA;AAElF,EAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAC,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AACpD,IAAA,MAAM,IAAA,GAAO,qBAAqB,QAAQ,CAAA;AAE1C,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA;AAAA,MACA,OAAO,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,MACxC,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,KAAK,CAAA;AAAA,MACpC,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,gBAAA,CAAiB,IAAW,CAAA;AAAA,MACzC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,cAAA,GAAiB,gBAAgB,aAAa,CAAA;AAEpD,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,CAAA,IAAK,cAAA,EAAgB;AAC9C,IAAA,MAAM,IAAA,GAAO,eAAe,QAAQ,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,WAAW,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAEjD,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,EAAA,EAAI,IAAI,WAAA,EAAa,CAAA,CAAA;AAAA,MACrB,IAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,KAAK,CAAA;AAAA,MACpC,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,gBAAA,CAAiB,IAAW,CAAA;AAAA,MACzC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,wBAAwB,SAAA,EAG/B;AACA,EAAA,MAAM,YAAA,GAAe,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAC1E,EAAA,MAAM,UAAA,GAAa,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAEzE,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,IAAA,OAAO,EAAE,aAAA,EAAe,EAAC,EAAG,gBAAgB,SAAA,EAAU;AAAA,EACxD;AAEA,EAAA,MAAM,gBAAiC,EAAC;AACxC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAiB;AAErC,EAAA,KAAA,MAAW,WAAW,YAAA,EAAc;AAClC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AAGnC,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK;AACrC,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA;AAE9B,MAAA,OAAO,OAAA,KAAY,MAAA,IAAU,OAAA,CAAQ,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,IAC9D,CAAC,CAAA;AAGD,IAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK;AACxC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAC5B,MAAA,OACE,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,KAAK,QAAA,CAAS,UAAU,CAAA,IACxB,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,IACrB,IAAA,CAAK,WAAW,GAAG,CAAA;AAAA,IAEvB,CAAC,CAAA;AAED,IAAA,MAAM,KAAA,GAAQ,CAAC,OAAA,EAAS,GAAG,aAAa,CAAA;AACxC,IAAA,aAAA,CAAc,KAAK,KAAK,CAAA;AAExB,IAAA,OAAA,CAAQ,IAAI,OAAO,CAAA;AACnB,IAAA,aAAA,CAAc,OAAA,CAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AAE5D,EAAA,OAAO,EAAE,eAAe,cAAA,EAAe;AACzC;AAKA,SAAS,4BAA4B,SAAA,EAGnC;AACA,EAAA,MAAM,YAAY,SAAA,CAAU,MAAA,CAAO,OAAK,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AAC1D,EAAA,MAAM,SAAA,GAAY,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,UAAA,CAAW,CAAA,CAAE,IAAI,CAAC,CAAA;AAE3D,EAAA,MAAM,eAAgC,EAAC;AACvC,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAiB;AACzC,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAiB;AAEzC,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,MAAM,QAAA,GAAW,qBAAA,CAAsB,QAAA,CAAS,IAAI,CAAA;AACpD,IAAA,MAAM,WAAW,SAAA,CAAU,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAExD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,YAAA,CAAa,IAAA,CAAK,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AACtC,MAAA,WAAA,CAAY,IAAI,QAAQ,CAAA;AACxB,MAAA,WAAA,CAAY,IAAI,QAAQ,CAAA;AAAA,IAC1B;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAgB;AAAA,IACpB,GAAG,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IAC5C,GAAG,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC;AAAA,GAC9C;AAEA,EAAA,OAAO,EAAE,cAAc,aAAA,EAAc;AACvC;AAKA,SAAS,WAAW,IAAA,EAAuB;AACzC,EAAA,OACE,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,SAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA;AAE/B;AAMA,SAAS,sBAAsB,QAAA,EAA0B;AAEvD,EAAA,IAAI,QAAA,GAAW,SACZ,OAAA,CAAQ,0BAAA,EAA4B,KAAK,CAAA,CACzC,OAAA,CAAQ,4BAA4B,KAAK,CAAA;AAG5C,EAAA,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA;AAE9C,EAAA,OAAO,QAAA;AACT;AAKA,SAAS,gBAAgB,SAAA,EAAsD;AAC7E,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAE9C,EAAA,KAAA,MAAW,WAAW,SAAA,EAAW;AAC/B,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,OAAA,CAAQ,IAAI,CAAA;AAC5C,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,QAAQ,KAAK,EAAC;AAC1C,IAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AACrB,IAAA,MAAA,CAAO,GAAA,CAAI,UAAU,QAAQ,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,kBAAkB,KAAA,EAAqC;AAC9D,EAAA,MAAM,cAAc,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,QAAA,CAAS,cAAc,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAC,WAAA,EAAa;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAIpC,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,GAAG,CAAA;AACnC,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,qBAAqB,IAAA,EAAsC;AAClE,EAAA,IAAI,CAAC,IAAA,EAAM;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAE3B,EAAA,MAAM,EAAE,SAAA,EAAW,SAAA,EAAW,MAAA,EAAO,GAAI,IAAA;AAGzC,EAAA,IAAI,MAAA,KAAW,OAAA,IAAY,SAAA,GAAY,CAAA,IAAK,cAAc,CAAA,EAAI;AAC5D,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,MAAA,KAAW,SAAA,IAAc,SAAA,GAAY,CAAA,IAAK,cAAc,CAAA,EAAI;AAC9D,IAAA,OAAO,OAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,OAAO,UAAA;AACT;AAKA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AACxB,EAAA,MAAM,IAAA,GAAO,SAAS,IAAI,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AAGxB,EAAA,IACE,KAAK,QAAA,CAAS,QAAQ,KACtB,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,IAAA,CAAK,SAAS,WAAW,CAAA,IACzB,IAAI,QAAA,CAAS,QAAQ,KACrB,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,EACtB;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,KAAA,IAAS,GAAA,CAAI,SAAS,QAAQ,CAAA,IAAK,SAAS,WAAA,EAAa;AACnE,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,IACE,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IACnB,KAAK,QAAA,CAAS,QAAQ,CAAA,IACtB,CAAC,gBAAgB,eAAA,EAAiB,kBAAkB,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,EACnE;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAGA,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AAC7E,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,SAAS,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC/E,IAAA,OAAO,OAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAS,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,MAAA;AACpC,EAAA,OAAO,OAAO,MAAM,CAAA,CAAA;AACtB;AAKA,SAAS,eAAe,QAAA,EAAoC;AAC1D,EAAA,IAAI,aAAa,MAAA,EAAQ;AAAC,IAAA,OAAO,MAAA;AAAA,EAAO;AACxC,EAAA,IAAI,aAAa,MAAA,EAAQ;AAAC,IAAA,OAAO,MAAA;AAAA,EAAO;AACxC,EAAA,IAAI,aAAa,QAAA,EAAU;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAC3C,EAAA,IAAI,aAAa,IAAA,EAAM;AAAC,IAAA,OAAO,IAAA;AAAA,EAAK;AACpC,EAAA,IAAI,aAAa,OAAA,EAAS;AAAC,IAAA,OAAO,OAAA;AAAA,EAAQ;AAC1C,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,WAAW,KAAA,EAAqC;AACvD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAG1C,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,QAAQ,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACnD,EAAA,MAAM,QAAA,GAAW,KAAK,CAAC,CAAA;AACvB,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,MAAA;AAAA,EAAU;AAEjC,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,OAAO,SAAS,MAAA,GAAS,CAAA,GAAI,SAAS,CAAC,CAAA,GAAI,SAAS,CAAC,CAAA;AAAA,EACvD;AAGA,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAA;AACvD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AAClC,IAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,IAAA,IAAI,OAAA,IAAW,KAAK,KAAA,CAAM,CAAC,MAAM,CAAA,CAAE,CAAC,CAAA,KAAM,OAAO,CAAA,EAAG;AAClD,MAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA;AAClD,IAAA,IAAI,KAAA,IAAS,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,KAAA,EAAO;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,eAAA,CAAgB,MAAwB,KAAA,EAA8B;AAC7E,EAAA,MAAM,QAAQ,KAAA,CAAM,MAAA;AAGpB,EAAA,MAAM,WAAW,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AACxD,EAAA,MAAM,aAAa,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AAE5D,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,IAAI,QAAA,EAAU;AAAC,MAAA,OAAO,OAAO,KAAK,CAAA,UAAA,EAAa,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,IAAG;AACtE,IAAA,OAAO,UAAU,KAAK,CAAA,UAAA,EAAa,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,IAAA,IAAI,QAAA,EAAU;AAAC,MAAA,OAAO,CAAA,iBAAA,CAAA;AAAA,IAAoB;AAC1C,IAAA,OAAO,CAAA,oBAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,IAAA,EAAM;AACjB,IAAA,OAAO,CAAA,uBAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,OAAO,CAAA,0BAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,EAAG;AACtD,MAAA,OAAO,CAAA,mBAAA,CAAA;AAAA,IACT;AACA,IAAA,OAAO,CAAA,oBAAA,CAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAO,OAAO,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO,UAAU,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,UAAU,KAAK,CAAA,KAAA,EAAQ,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA,CAAA;AACpD;AAKA,SAAS,gBAAA,CACP,MACA,MAAA,EACsC;AACtC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,MAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;;;AClYO,SAAS,gBAAgB,SAAA,EAA2C;AACzE,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,OAAA;AAAA,MACb,UAAA,EAAY,CAAA;AAAA,MACZ,OAAO,EAAC;AAAA,MACR,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAKA,EAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,EAAG;AAClC,IAAA,MAAM,WAAA,GAAc,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,EAAG,IAAA;AAC1E,IAAA,MAAM,WAAA,GAAc,WAAA,GAAc,kBAAA,CAAmB,WAAW,CAAA,GAAI,SAAA;AAEpE,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,aAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,yBAAyB,WAAW,CAAA,CAAA;AAAA,QACpC,CAAA,EAAG,UAAU,MAAM,CAAA,iCAAA,CAAA;AAAA,QACnB,2CAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,SAAA,EAAW,CAAC,CAAA;AACzC,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,eAAA;AAAA,MACb,UAAA,EAAY,GAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,CAAA,mBAAA,EAAsB,UAAU,MAAM,CAAA,YAAA,CAAA;AAAA,QACtC,CAAA,uCAAA,CAAA;AAAA,QACA,kBAAkB,IAAI,CAAA,SAAA,EAAY,IAAA,KAAS,CAAA,GAAI,MAAM,KAAK,CAAA,CAAA;AAAA,QAC1D;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,6BAAA,CAA8B,SAAS,CAAA,EAAG;AAC5C,IAAA,MAAM,KAAA,GAAQ,uBAAuB,SAAS,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,iBAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,kCAAA;AAAA,QACA,CAAA,oBAAA,EAAA,CAAwB,KAAA,GAAQ,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,QAC/C,wCAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAC9D,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,uBAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAClE,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAClE,EAAA,MAAM,aAAA,GAAgB,YAAY,QAAA,GAAW,QAAA,CAAA;AAE7C,EAAA,IAAI,gBAAgB,GAAA,EAAK;AACvB,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,IAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,CAAA,kBAAA,EAAA,CAAsB,aAAA,GAAgB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,QACrD;AAAA,OACF;AAAA,MACA,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,OAAA;AAAA,IACb,UAAA,EAAY,CAAA;AAAA,IACZ,OAAO,EAAC;AAAA,IACR,aAAA,EAAe;AAAA,GACjB;AACF;AAYO,SAAS,oBAAoB,SAAA,EAAmC;AAErE,EAAA,MAAM,cAAA,GAAiB,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA;AAC1E,EAAA,IAAI,CAAC,cAAA,EAAgB;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGnC,EAAA,IAAI,SAAA,CAAU,SAAS,EAAA,EAAI;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGzC,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,OAAO,CAAA;AAC1D,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAG7B,EAAA,MAAM,eAAe,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,cAAc,IAAI,CAAA;AAC9D,EAAA,IAAI,CAAC,YAAA,EAAc;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAIjC,EAAA,MAAM,eAAA,GAAkB,UAAU,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,QAAA,CAAS,cAAc,CAAC,CAAA,CAAG,IAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,KAAA,CAAM,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAGnE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,UAAA,CAAW,UAAA,GAAa,GAAG,CAAC,CAAA;AAChF,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,MAAA,GAAS,SAAA,CAAU,MAAA;AAEzD,EAAA,OAAO,cAAA,GAAiB,GAAA;AAC1B;AAWO,SAAS,kBAAkB,SAAA,EAAmC;AAEnE,EAAA,IAAI,SAAA,CAAU,SAAS,EAAA,EAAI;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGzC,EAAA,MAAM,WAAW,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,OAAO,CAAA;AAC1D,EAAA,IAAI,CAAC,QAAA,EAAU;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAG7B,EAAA,MAAM,cAAc,SAAA,CAAU,MAAA,CAAO,OAAK,CAAA,CAAE,SAAA,KAAc,KAAK,CAAA,CAAE,MAAA;AACjE,EAAA,MAAM,WAAA,GAAc,cAAc,SAAA,CAAU,MAAA;AAC5C,EAAA,IAAI,eAAe,GAAA,EAAK;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGtC,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,SAAA,EAAW,CAAC,CAAA;AAC/C,EAAA,OAAO,UAAA,GAAa,CAAA;AACtB;AASO,SAAS,8BAA8B,SAAA,EAAmC;AAE/E,EAAA,MAAM,cAAc,SAAA,CAAU,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,UAAU,CAAA;AAChE,EAAA,IAAI,CAAC,WAAA,EAAa;AAAC,IAAA,OAAO,KAAA;AAAA,EAAM;AAGhC,EAAA,MAAM,aAAA,GAAgB,uBAAuB,SAAS,CAAA;AACtD,EAAA,OAAO,aAAA,GAAgB,GAAA;AACzB;AAeO,SAAS,eAAA,CAAgB,WAA0B,KAAA,EAAuB;AAC/E,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,EAAA,KAAA,MAAW,WAAW,SAAA,EAAW;AAC/B,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACpC,IAAA,IAAI,KAAA,CAAM,UAAU,KAAA,EAAO;AACzB,MAAA,MAAM,UAAU,KAAA,CAAM,KAAA,CAAM,GAAG,KAAK,CAAA,CAAE,KAAK,GAAG,CAAA;AAC9C,MAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAQO,SAAS,uBAAuB,SAAA,EAAkC;AACvE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AACxE,EAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AACxE,EAAA,MAAM,eAAe,cAAA,GAAiB,cAAA;AAEtC,EAAA,IAAI,iBAAiB,CAAA,EAAG;AAAC,IAAA,OAAO,CAAA;AAAA,EAAE;AAElC,EAAA,OAAO,cAAA,GAAiB,YAAA;AAC1B;AAQA,SAAS,mBAAmB,IAAA,EAAsB;AAChD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,OAAA,CAAQ,cAAc,CAAA;AAErD,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,gBAAA,GAAmB,CAAC,CAAA;AAC9C,IAAA,OAAO,WAAA,IAAe,SAAA;AAAA,EACxB;AAEA,EAAA,OAAO,SAAA;AACT;ACtQO,IAAM,oBAAA,GAAN,MAAM,qBAAA,SAA6B,KAAA,CAAM;AAAA,EAC9B,aAAA;AAAA,EAEhB,WAAA,CAAY,SAAwB,OAAA,EAAiB;AACnD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAA;AAGrB,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,qBAAoB,CAAA;AAAA,IACpD;AAAA,EACF;AACF,CAAA;AAmBA,IAAM,oBAAA,GAAuB;AAAA;AAAA,EAE3B,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAGA,SAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,qBAAA;AAAA;AAAA,EAGA,kBAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,sBAAA;AAAA;AAAA,EAGA,YAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAGA,UAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA;AAAA,EAGA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA;AAKA,IAAM,uBAAA,GAAoE;AAAA;AAAA,EAExE,EAAE,OAAA,EAAS,4CAAA,EAA8C,IAAA,EAAM,SAAA,EAAU;AAAA,EACzE,EAAE,OAAA,EAAS,+CAAA,EAAiD,IAAA,EAAM,YAAA,EAAa;AAAA,EAC/E,EAAE,OAAA,EAAS,iDAAA,EAAmD,IAAA,EAAM,cAAA,EAAe;AAAA;AAAA,EAGnF,EAAE,OAAA,EAAS,kBAAA,EAAoB,IAAA,EAAM,mBAAA,EAAoB;AAAA,EACzD,EAAE,OAAA,EAAS,oCAAA,EAAsC,IAAA,EAAM,uBAAA,EAAwB;AAAA;AAAA,EAG/E,EAAE,OAAA,EAAS,wCAAA,EAA0C,IAAA,EAAM,gBAAA,EAAiB;AAAA,EAC5E,EAAE,OAAA,EAAS,sBAAA,EAAwB,IAAA,EAAM,WAAA,EAAY;AAAA;AAAA,EAGrD,EAAE,OAAA,EAAS,6BAAA,EAA+B,IAAA,EAAM,cAAA,EAAe;AAAA;AAAA,EAG/D,EAAE,OAAA,EAAS,uDAAA,EAAyD,IAAA,EAAM,aAAA,EAAc;AAAA;AAAA,EAGxF,EAAE,OAAA,EAAS,sDAAA,EAAwD,IAAA,EAAM,aAAA,EAAc;AAAA;AAAA,EAGvF,EAAE,OAAA,EAAS,uBAAA,EAAyB,IAAA,EAAM,UAAA,EAAW;AAAA;AAAA,EAGrD,EAAE,OAAA,EAAS,qBAAA,EAAuB,IAAA,EAAM,QAAA;AAC1C,CAAA;AAKO,SAAS,aAAa,QAAA,EAA2B;AAEtD,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAElD,EAAA,OAAO,oBAAA,CAAqB,IAAA;AAAA,IAAK,CAAC,YAChC,SAAA,CAAU,cAAA,EAAgB,SAAS,EAAE,SAAA,EAAW,MAAM;AAAA,GACxD;AACF;AAaO,SAAS,kBAAkB,KAAA,EAA2B;AAC3D,EAAA,OAAO,KAAA,CAAM,OAAO,YAAY,CAAA;AAClC;AAuBO,SAAS,qBAAqB,WAAA,EAA+B;AAClE,EAAA,MAAM,QAAQ,WAAA,CAAY,MAAA;AAC1B,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,OAAO,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,+CAAwC,KAAK,CAAA,gCAAA,CAAA;AAAA,IAC7C,SAAA;AAAA,IACA,EAAA;AAAA,IACA,wCAAA;AAAA,IACA,EAAA;AAAA,IACA,oEAAA;AAAA,IACA,mDAAA;AAAA,IACA,EAAA;AAAA,IACA,wBAAA;AAAA,IACA,oCAAA;AAAA,IACA,wEAAA;AAAA,IACA,gFAAA;AAAA,IACA,EAAA;AAAA,IACA,oFAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAMO,SAAS,0BACd,KAAA,EACe;AACf,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,KAAA,CAAM,SAAQ,EAAG;AAC1C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE7B,IAAA,KAAA,IAAS,SAAA,GAAY,CAAA,EAAG,SAAA,GAAY,KAAA,CAAM,QAAQ,SAAA,EAAA,EAAa;AAC7D,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,SAAS,CAAA,IAAK,EAAA;AAEjC,MAAA,KAAA,MAAW,EAAE,OAAA,EAAS,IAAA,EAAK,IAAK,uBAAA,EAAyB;AAEvD,QAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AAEpB,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAC/B,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,MAAM,WAAA,GAAc,MAAM,CAAC,CAAA;AAC3B,UAAA,MAAM,SAAS,KAAA,CAAM,KAAA;AAGrB,UAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,EAAE,CAAA;AAC5C,UAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,IAAA,CAAK,QAAQ,MAAA,GAAS,WAAA,CAAY,SAAS,EAAE,CAAA;AACzE,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,YAAA,EAAc,UAAU,CAAA;AAGvD,UAAA,MAAM,WAAA,GAAc,YAAY,MAAA,GAAS,EAAA,GACrC,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA,GAAI,KAAA,GAC/B,WAAA;AAEJ,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,IAAA;AAAA,YACA,MAAM,SAAA,GAAY,CAAA;AAAA;AAAA,YAClB,QAAQ,MAAA,GAAS,CAAA;AAAA;AAAA,YACjB,SAAS,OAAA,CAAQ,MAAA;AAAA,YACjB,WAAA,EAAa,IAAA;AAAA,YACb,OAAA,EAAS,QAAQ,IAAA,EAAK;AAAA,YACtB,WAAA,EAAa;AAAA,WACd,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,oBAAoB,OAAA,EAAgC;AAClE,EAAA,MAAM,QAAQ,OAAA,CAAQ,MAAA;AACtB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,IAAA;AAEpD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,CAAA,4CAAA,EAAwC,KAAK,CAAA,wBAAA,EAA2B,SAAS,CAAA,QAAA,CAAA;AAAA,IACjF,EAAA;AAAA,IACA,wCAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAC9C,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,WAAW,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,EAAC;AAC5C,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AACnB,IAAA,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,QAAQ,CAAA;AAAA,EACjC;AAGA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,WAAW,CAAA,IAAK,MAAA,CAAO,SAAQ,EAAG;AAClD,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAM,IAAI,CAAA,CAAA,CAAG,CAAA;AACxB,IAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAC/B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,MAAM,CAAA,GAAA,EAAM,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AACxE,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,MAAM,OAAA,CAAQ,MAAA,GAAS,EAAA,GAAK,KAAA,GAAQ,EAAE,CAAA,CAAE,CAAA;AACpG,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,WAAW,CAAA,CAAE,CAAA;AAC9C,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,gBAAA,EAAmB,KAAA,CAAM,OAAO,CAAA,GAAA,CAAK,CAAA;AAChD,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,8EAAA;AAAA,IACA,mDAAA;AAAA,IACA,EAAA;AAAA,IACA,wBAAA;AAAA,IACA,yFAAA;AAAA,IACA,iFAAA;AAAA,IACA,gFAAA;AAAA,IACA,EAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;ACjSA,eAAsB,sBAAA,CACpB,QAAA,EACA,YAAA,GAAwB,KAAA,EACxB,cAAuB,KAAA,EACL;AAElB,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA,4BAAA,CAA8B,CAAA;AACrD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAc,QAAA,CAAA,eAAA,CAAgB;AAAA,IAClC,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,QAAQ,OAAA,CAAQ;AAAA,GACjB,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,eAAe,OAAA,GAAU,OAAA;AAC7C,EAAA,MAAM,YAAA,GAAe,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,WAAW,CAAA,EAAA,CAAA;AAE/C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,EAAA,CAAG,QAAA,CAAS,YAAA,EAAc,CAAC,MAAA,KAAW;AACpC,MAAA,EAAA,CAAG,KAAA,EAAM;AAET,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,EAAK,CAAE,WAAA,EAAY;AAE7C,MAAA,IAAI,eAAe,EAAA,EAAI;AACrB,QAAA,OAAA,CAAQ,YAAY,CAAA;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,KAAA,EAAO;AAC9C,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,UAAA,KAAe,GAAA,IAAO,UAAA,KAAe,IAAA,EAAM;AAC7C,QAAA,OAAA,CAAQ,KAAK,CAAA;AACb,QAAA;AAAA,MACF;AAGA,MAAA,OAAA,CAAQ,YAAY,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;;;ACxBA,IAAM,oBAAA,GAAuB,GAAA;AAG7B,IAAM,eAAA,GAAkB,CAAA;AACxB,IAAM,kBAAA,mBAAqB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,MAAM,CAAC,CAAA;AAE9G,SAAS,kBAAkB,EAAA,EAA4C;AACrE,EAAA,IAAI,CAAC,EAAA,EAAI;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAC7B,EAAA,MAAM,OAAA,GAAU,GAAG,IAAA,EAAK;AACxB,EAAA,IAAI,CAAC,OAAA,EAAS;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAElC,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA,EAAG;AAC3B,IAAA,OAAO,CAAA,CAAA,EAAI,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA;AAAA,EACvC;AAEA,EAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AACzB,IAAA,OAAO,IAAI,OAAO,CAAA,CAAA;AAAA,EACpB;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,qBAAqB,KAAA,EAAyB;AACrD,EAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA;AACzB,EAAA,MAAM,QAAA,GAAW,YAAY,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,SAAA,GAAY,OAAA;AACvE,EAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAI,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAA,GAAK,CAAA,OAAA,EAAU,MAAM,MAAM,CAAA,MAAA,CAAA;AAC3E;AAEA,SAAS,iBAAA,CACP,QACA,EAAA,EACoB;AACpB,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,OAAO,KAAK,CAAA,GACpC,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAyB,OAAO,IAAA,KAAS,QAAA,IAAY,KAAK,MAAA,GAAS,CAAC,IACzF,EAAC;AACL,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,IAAY,kBAAA,CAAmB,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,GAC9E,MAAA,CAAO,IAAA,GACP,OAAA;AACJ,EAAA,MAAM,UAAU,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,IAAY,OAAO,OAAA,CAAQ,IAAA,EAAK,CAAE,MAAA,GAAS,IACjF,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAK,GACpB,qBAAqB,WAAW,CAAA;AACpC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,WAAA,KACrB,IAAA,KAAS,MAAA,GAAS,UAAW,IAAA,KAAS,KAAA,IAAS,IAAA,KAAS,UAAA,GAAa,OAAA,GAAU,MAAA,CAAA;AAErF,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,OAAA;AAAA,IACA,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,KAAA,EAAO,WAAA;AAAA,IACP,WAAA;AAAA,IACA,QAAA,EAAU,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,IACjC,SAAA,EAAW,OAAO,SAAA,IAAa;AAAA,MAC7B,WAAA,EAAa,KAAA;AAAA,MACb,QAAA,EAAU,KAAA;AAAA,MACV,YAAA,EAAc,IAAA;AAAA,MACd,WAAA,EAAa,8EAAA;AAAA,MACb,UAAA,EAAY;AAAA;AACd,GACF;AACF;AAMA,eAAsB,mBAAmB,OAAA,EAA+C;AACtF,EAAA,MAAM,EAAE,GAAA,EAAK,UAAA,EAAW,GAAI,OAAA;AAE5B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAG3B,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,CAAa,GAAG,CAAA;AACxC,EAAA,MAAM,QAAA,GAAW,mBAAmB,SAAS,CAAA;AAE7C,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,OAAO,eAAA,CAAgB,KAAK,SAAS,CAAA;AAAA,EACvC;AAGA,EAAA,MAAM,WAAA,GAAc,kBAAkB,QAAQ,CAAA;AAE9C,EAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAE1B,IAAA,MAAM,YAAA,GAA8B,WAAA,CAAY,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,MAC3D,IAAA;AAAA,MACA,IAAA,EAAM,CAAA;AAAA,MACN,MAAA,EAAQ,CAAA;AAAA,MACR,OAAA,EAAS,qBAAA;AAAA,MACT,WAAA,EAAa,qBAAA;AAAA,MACb,OAAA,EAAS,EAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf,CAAE,CAAA;AAEF,IAAA,MAAM,OAAA,GAAU,qBAAqB,WAAW,CAAA;AAChD,IAAA,MAAM,OAAO,KAAA,CAAM,4BAAA,EAAuB,IAAI,KAAA,CAAM,kBAAkB,CAAA,EAAG;AAAA,MACvE;AAAA,KACD,CAAA;AACD,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,GAAO,OAAA,GAAU,IAAI,CAAA;AAGnC,IAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AAEzB,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR,YAAA;AAAA,QACA,CAAA,oBAAA,EAAuB,YAAY,MAAM,CAAA,iFAAA;AAAA,OAC3C;AAAA,IACF;AAGA,IAAA,OAAA,CAAQ,IAAI,0DAAgD,CAAA;AAC5D,IAAA,OAAA,CAAQ,eAAA,IAAkB;AAC1B,IAAA,MAAM,YAAY,MAAM,sBAAA;AAAA,MACtB,CAAA,sCAAA,EAA+B,YAAY,MAAM,CAAA,kCAAA,CAAA;AAAA,MACjD,KAAA;AAAA;AAAA,MACA,OAAA,CAAQ;AAAA,KACV;AACA,IAAA,OAAA,CAAQ,gBAAA,IAAmB;AAE3B,IAAA,IAAI,CAAC,SAAA,EAAW;AAEd,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR,YAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,CAAO,KAAK,mEAAA,EAAqE;AAAA,MACrF,WAAA;AAAA,MACA,WAAA,EAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACrC,CAAA;AACD,IAAA,OAAA,CAAQ,IAAI,gEAA2D,CAAA;AAAA,EACzE;AAGA,EAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAiB,GAAA,EAAK,QAAQ,CAAA;AAGtD,EAAA,MAAM,eAAA,GAAkB,gBAAgB,SAAS,CAAA;AAGjD,EAAA,IAAI,eAAA,CAAgB,aAAa,GAAA,EAAK;AACpC,IAAA,MAAM,SAAA,EAAW,MAAM,yBAAA,EAA2B;AAAA,MAChD,aAAa,eAAA,CAAgB,WAAA;AAAA,MAC7B,YAAY,eAAA,CAAgB,UAAA;AAAA,MAC5B,eAAe,eAAA,CAAgB,aAAA;AAAA,MAC/B,WAAW,SAAA,CAAU,MAAA;AAAA,MACrB,OAAO,eAAA,CAAgB;AAAA,KACxB,CAAA;AAGD,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAA,CAAgB,WAAW,CAAA,cAAA,EAAiB,eAAA,CAAgB,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA,EAAK;AAAA,MAC5H,eAAe,eAAA,CAAgB,aAAA;AAAA,MAC/B,OAAO,eAAA,CAAgB;AAAA,KACxB,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,gBAAgB,OAAA,CAAQ,aAAA,IAAiB,MAAM,gBAAA,CAAiB,KAAK,EAAE,CAAA;AAG7E,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,IAAI;AAEF,MAAA,MAAM,mBAAA,GAAsB,OAAO,GAAA,CAAI,aAAA,KAAkB,UAAA;AAEzD,MAAA,IAAI,MAAA;AAEJ,MAAA,IAAI,mBAAA,EAAqB;AAEvB,QAAA,MAAM,MAAA,CAAO,MAAM,6CAA6C,CAAA;AAChE,QAAA,UAAA,GAAa,gCAAgC,CAAA;AAE7C,QAAA,MAAM,SAAS,MAAM,uBAAA;AAAA,UACnB,GAAA;AAAA,UACA,SAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAA,GAAS,MAAA,CAAO,MAAA;AAChB,QAAA,UAAA,GAAa,MAAA,CAAO,UAAA;AACpB,QAAA,OAAA,GAAU,IAAA;AAAA,MACZ,CAAA,MAAO;AAEL,QAAA,MAAM,MAAA,CAAO,MAAM,qCAAqC,CAAA;AACxD,QAAA,UAAA,GAAa,kCAAkC,CAAA;AAE/C,QAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,SAAA,EAAW,eAAA,EAAiB,aAAa,CAAA;AAE5E,QAAA,MAAM,SAAS,MAAM,YAAA;AAAA,UACnB,MAAM,GAAA,CAAI,QAAA,CAAS,MAAA,EAAQ;AAAA,YACzB,YAAA,EAAc,aAAA;AAAA,YACd,WAAA,EAAa,GAAA;AAAA,YACb,SAAA,EAAW;AAAA,WACZ,CAAA;AAAA,UACD,SAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAA,GAAS,aAAA,CAAc,MAAA,CAAO,OAAA,EAAS,SAAA,EAAW,eAAe,CAAA;AACjE,QAAA,OAAA,GAAU,IAAA;AACV,QAAA,UAAA,GAAa,MAAA,CAAO,UAAA;AAAA,MACtB;AAGA,MAAA,MAAM,iBAAiB,MAAA,CAAO,gBAAA,IACzB,OAAO,iBAAA,GAAoB,oBAAA,IAC3B,UAAU,MAAA,IAAU,EAAA;AAEzB,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,MAAM,MAAA,GAAS,SAAA,CAAU,MAAA,IAAU,EAAA,GAC/B,GAAG,SAAA,CAAU,MAAM,CAAA,iBAAA,CAAA,GACnB,CAAA,WAAA,EAAA,CAAe,MAAA,CAAO,iBAAA,GAAoB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAC7D,QAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,uBAAA,EAA0B,MAAM,CAAA,CAAA,EAAI;AAAA,UACrD,WAAW,SAAA,CAAU,MAAA;AAAA,UACrB,YAAY,MAAA,CAAO,iBAAA;AAAA,UACnB,kBAAkB,MAAA,CAAO,gBAAA;AAAA,UACzB,gBAAgB,MAAA,CAAO;AAAA,SACxB,CAAA;AACD,QAAA,UAAA,GAAa,CAAA,EAAG,MAAM,CAAA,mBAAA,CAAqB,CAAA;AAK3C,QAAA,IAAI,WAAA;AAEJ,QAAA,IAAI,MAAA,CAAO,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAEpC,UAAA,MAAM,UAAA,GAAa,MAAA,CAAO,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,CAAC,CAAC,CAAA;AAC1F,UAAA,WAAA,GAAc,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAEpC,UAAA,IAAI,UAAA,CAAW,SAAS,EAAA,EAAI;AAC1B,YAAA,MAAM,MAAA,CAAO,IAAA,CAAK,CAAA,cAAA,EAAiB,UAAA,CAAW,MAAM,CAAA,qCAAA,CAAA,EAAyC;AAAA,cAC3F,gBAAgB,UAAA,CAAW,MAAA;AAAA,cAC3B,cAAA,EAAgB;AAAA,aACjB,CAAA;AAAA,UACH;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,MAAM,eAAA,GAAkB,CAAC,GAAG,SAAS,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AACpD,YAAA,MAAM,QAAA,GAAA,CAAY,CAAA,CAAE,SAAA,IAAa,CAAA,KAAM,EAAE,SAAA,IAAa,CAAA,CAAA;AACtD,YAAA,MAAM,QAAA,GAAA,CAAY,CAAA,CAAE,SAAA,IAAa,CAAA,KAAM,EAAE,SAAA,IAAa,CAAA,CAAA;AACtD,YAAA,OAAO,QAAA,GAAW,QAAA;AAAA,UACpB,CAAC,CAAA;AAED,UAAA,WAAA,GAAc,eAAA,CAAgB,MAAM,CAAA,EAAG,EAAE,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA;AAE5D,UAAA,MAAM,MAAA,CAAO,MAAM,qDAAA,EAAuD;AAAA,YACxE,YAAY,SAAA,CAAU,MAAA;AAAA,YACtB,eAAe,WAAA,CAAY;AAAA,WAC5B,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,KAAA,GAAQ,MAAM,YAAA,CAAa,GAAA,EAAK,WAAW,CAAA;AAGjD,QAAA,MAAM,aAAA,GAAgB,0BAA0B,KAAK,CAAA;AAErD,QAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAE5B,UAAA,MAAM,MAAA,GAAS,oBAAoB,aAAa,CAAA;AAChD,UAAA,MAAM,OAAO,KAAA,CAAM,4CAAA,EAAuC,IAAI,KAAA,CAAM,iBAAiB,CAAA,EAAG;AAAA,YACtF;AAAA,WACD,CAAA;AACD,UAAA,UAAA,GAAa,oCAA6B,CAAA;AAG1C,UAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,GAAO,MAAA,GAAS,IAAI,CAAA;AAGlC,UAAA,IAAI,CAAC,QAAQ,YAAA,EAAc;AAEzB,YAAA,MAAM,IAAI,oBAAA;AAAA,cACR,aAAA;AAAA,cACA,CAAA,oBAAA,EAAuB,cAAc,MAAM,CAAA,8FAAA;AAAA,aAC7C;AAAA,UACF;AAGA,UAAA,OAAA,CAAQ,IAAI,0DAAgD,CAAA;AAC5D,UAAA,OAAA,CAAQ,eAAA,IAAkB;AAC1B,UAAA,MAAM,YAAY,MAAM,sBAAA;AAAA,YACtB,CAAA,2DAAA,EAAoD,cAAc,MAAM,CAAA,qBAAA,CAAA;AAAA,YACxE,KAAA;AAAA;AAAA,YACA,OAAA,CAAQ;AAAA;AAAA,WACV;AACA,UAAA,OAAA,CAAQ,gBAAA,IAAmB;AAE3B,UAAA,IAAI,CAAC,SAAA,EAAW;AAEd,YAAA,MAAM,IAAI,oBAAA;AAAA,cACR,aAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAGA,UAAA,MAAM,MAAA,CAAO,KAAK,kEAAA,EAAoE;AAAA,YACpF,aAAA,EAAe,aAAA,CAAc,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,OAAA,EAAS,CAAA,CAAE,aAAY,CAAE,CAAA;AAAA,YAC9F,WAAA,EAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WACrC,CAAA;AACD,UAAA,OAAA,CAAQ,IAAI,+DAA0D,CAAA;AACtE,UAAA,UAAA,GAAa,6CAA6C,CAAA;AAAA,QAC5D;AAEA,QAAA,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAGlB,UAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,GAAA,CAAI,GAAA,EAAM,GAAA,GAAO,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,EAAE,CAAA,GAAI,GAAG,CAAA;AAErF,UAAA,MAAM,MAAA,CAAO,MAAM,0CAAA,EAA4C;AAAA,YAC7D,eAAe,WAAA,CAAY,MAAA;AAAA,YAC3B;AAAA,WACD,CAAA;AACD,UAAA,UAAA,GAAa,6CAA6C,CAAA;AAE1D,UAAA,IAAI,mBAAA,EAAqB;AAEvB,YAAA,MAAM,iBAAiB,MAAM,6BAAA;AAAA,cAC3B,GAAA;AAAA,cACA,SAAA;AAAA,cACA,KAAA;AAAA,cACA,aAAA;AAAA,cACA,MAAA;AAAA,cACA;AAAA,aACF;AAEA,YAAA,MAAA,GAAS,cAAA,CAAe,MAAA;AACxB,YAAA,UAAA,GAAA,CAAc,UAAA,IAAc,CAAA,KAAM,cAAA,CAAe,UAAA,IAAc,CAAA,CAAA;AAC/D,YAAA,SAAA,GAAY,IAAA;AAAA,UACd,CAAA,MAAO;AAEL,YAAA,MAAM,cAAA,GAAiB,mBAAA,CAAoB,SAAA,EAAW,KAAA,EAAO,aAAa,CAAA;AAE1E,YAAA,MAAM,iBAAiB,MAAM,YAAA;AAAA,cAC3B,MAAM,GAAA,CAAI,QAAA,CAAS,cAAA,EAAgB;AAAA,gBACjC,YAAA,EAAc,uBAAA;AAAA,gBACd,WAAA,EAAa,GAAA;AAAA,gBACb,SAAA,EAAW;AAAA,eACZ,CAAA;AAAA,cACD,SAAA;AAAA,cACA,MAAA;AAAA,cACA;AAAA,aACF;AAEA,YAAA,MAAA,GAAS,aAAA,CAAc,cAAA,CAAe,OAAA,EAAS,SAAA,EAAW,eAAe,CAAA;AACzE,YAAA,UAAA,GAAA,CAAc,UAAA,IAAc,CAAA,KAAM,cAAA,CAAe,UAAA,IAAc,CAAA,CAAA;AAC/D,YAAA,SAAA,GAAY,IAAA;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAA,GAAU,MAAA,CAAO,OAAA;AAGjB,MAAA,OAAA,GAAU,MAAM,qBAAA,CAAsB,OAAA,EAAS,WAAW,GAAA,EAAK,OAAA,EAAS,QAAQ,UAAU,CAAA;AAAA,IAC5F,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,QAAA,MAAM,KAAA;AAAA,MACR;AAGA,MAAA,MAAM,MAAA,CAAO,KAAK,iEAAA,EAAmE;AAAA,QACnF,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC7D,CAAA;AACD,MAAA,UAAA,GAAa,iCAAiC,CAAA;AAC9C,MAAA,OAAA,GAAU,sBAAsB,SAAS,CAAA;AAAA,IAC3C;AAAA,EACF,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,sBAAsB,SAAS,CAAA;AAAA,EAC3C;AAGA,EAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,MAAA,KAAW;AACvD,IAAA,GAAA,CAAI,OAAO,IAAI,CAAA,GAAA,CAAK,IAAI,MAAA,CAAO,IAAI,KAAK,CAAA,IAAK,CAAA;AAC7C,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,EAA4B,CAAA;AAE/B,EAAA,MAAM,SAAA,EAAW,MAAM,4BAAA,EAA8B;AAAA,IACnD,YAAY,SAAA,CAAU,MAAA;AAAA,IACtB,cAAc,OAAA,CAAQ,MAAA;AAAA,IACtB,OAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA,EAAY,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,IACzB,gBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,KAAA;AAAA,IACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA,EAAU,GAAA;AAAA,IACV,SAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,YAAY,SAAA,CAAU,MAAA;AAAA,MACtB,cAAc,OAAA,CAAQ,MAAA;AAAA,MACtB,OAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA;AACF,GACF;AACF;AAKA,SAAS,eAAA,CAAgB,KAAa,SAAA,EAAkC;AACtE,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,KAAA;AAAA,IACf,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,QAAA,EAAU,GAAA;AAAA,IACV,SAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,QAAA,EAAU;AAAA,MACR,UAAA,EAAY,CAAA;AAAA,MACZ,YAAA,EAAc,CAAA;AAAA,MACd,OAAA,EAAS;AAAA;AACX,GACF;AACF;AAOA,eAAe,wBACb,GAAA,EACA,SAAA,EACA,eAAA,EACA,aAAA,EACA,QACA,WAAA,EAC6D;AAC7D,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AAGA,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,SAAA,EAAW,eAAA,EAAiB,aAAa,CAAA;AAKhF,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,IACjD,KAAA,EAAO,CAAC,gBAAgB,CAAA;AAAA,IACxB,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,KAC3C;AAAA,IACA,WAAA,EAAa;AAAA,GACd,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AAGA,EAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAO1B,EAAA,MAAM,kBAAkB,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM;AAC1D,IAAA,MAAM,UAAA,GAAa,CAAA,CAAE,SAAA,EAAW,UAAA,IAAc,GAAA;AAC9C,IAAA,OAAO,GAAA,GAAM,UAAA;AAAA,EACf,GAAG,CAAC,CAAA;AACJ,EAAA,MAAM,iBAAA,GAAoB,SAAS,OAAA,CAAQ,MAAA,GAAS,IAChD,eAAA,GAAkB,QAAA,CAAS,QAAQ,MAAA,GACnC,CAAA;AAEJ,EAAA,MAAM,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,IAChD,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,cAAA,EAAgB,QAAA,CAAS,cAAA,EAAgB,MAAA,IAAU,CAAA;AAAA,IACnD,YAAA,EAAc,SAAS,OAAA,CAAQ,MAAA;AAAA,IAC/B;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,gBAAA,EAAkB,OAAA,CAAQ,QAAA,CAAS,gBAAgB,CAAA;AAAA,MACnD,cAAA,EAAgB,QAAA,CAAS,cAAA,IAAkB,EAAC;AAAA,MAC5C,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB;AAAA,KACF;AAAA,IACA,UAAA,EAAY,SAAS,KAAA,GAAS,QAAA,CAAS,MAAM,YAAA,GAAe,QAAA,CAAS,MAAM,gBAAA,GAAoB;AAAA,GACjG;AACF;AAOA,eAAe,0BAAA,CACb,GAAA,EACA,gBAAA,EACA,eAAA,EACA,QACA,UAAA,EAC+B;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,sBAAA,GAAyB,eAAA,CAC5B,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,YAAA,GAAe,CAAA,CAAE,KAAA,CAAM,MAAA,IAAU,CAAA,GACnC,EAAE,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GACjB,CAAA,EAAG,CAAA,CAAE,MAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,KAAA,EAAQ,CAAA,CAAE,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,KAAA,CAAA;AAC/D,IAAA,OAAO,IAAI,CAAA,CAAE,EAAE,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,EAAG,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,EAAA,EAAK,EAAE,OAAO;AAAA,UAAA,EAAe,YAAY,CAAA,CAAA;AAAA,EACrG,CAAC,CAAA,CACA,IAAA,CAAK,MAAM,CAAA;AAGd,EAAA,MAAM,gBAAA,GAAmB,gBAAA,CACtB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,KAAA,GAAQ,EAAE,MAAA,GAAS,QAAA,GAAW,IAAI,CAAA,CAAE,SAAS,CAAA,EAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAA;AACnE,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,SAAA,GAAY,iBAAA,GAAoB,kBAAA;AAChD,IAAA,OAAO,CAAA,EAAA,EAAK,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EACrD,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,MAAM,YAAA,GAAe,CAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,wDAAA,CAAA;AAwDrB,EAAA,MAAM,UAAA,GAAa,CAAA;AAAA,EACnB,sBAAsB;;AAAA,gCAAA,EAEU,iBAAiB,MAAM,CAAA;AAAA,EACvD,gBAAgB;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,2EAAA,CAAA;AAmBhB,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,YAAA,EAAa;AAAA,IACxC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,UAAA;AAAW,GACtC;AAEA,EAAA,IAAI;AACF,IAAA,UAAA,GAAa,0CAA0C,CAAA;AAEvD,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,MACjD,KAAA,EAAO,CAAC,uBAAuB,CAAA;AAAA,MAC/B,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,UAAA;AAAA,QACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,OAC3C;AAAA,MACA,WAAA,EAAa;AAAA,KACd,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,MAAA,MAAM,MAAA,CAAO,KAAK,gDAAgD,CAAA;AAClE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAI1B,IAAA,IAAI,CAAC,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAA,EAAG;AACtD,MAAA,MAAM,MAAA,CAAO,KAAK,qDAAqD,CAAA;AACvE,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,aAA4B,EAAC;AACnC,IAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,IAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,IAAA,KAAA,MAAW,MAAA,IAAU,SAAS,OAAA,EAAS;AACrC,MAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,IAAK,MAAA,CAAO,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC7D,QAAA,MAAM,MAAA,CAAO,KAAK,kDAAA,EAAoD;AAAA,UACpE,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,kBAAkB,MAAA,CAAO;AAAA,SAC1B,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,YAAA;AAEhC,MAAA,IAAI,WAAW,iBAAA,EAAmB;AAEhC,QAAA,MAAM,qBAAA,GAAwB,iBAAA,CAAkB,MAAA,CAAO,gBAAgB,CAAA;AACvE,QAAA,MAAM,cAAA,GAAiB,gBAAgB,IAAA,CAAK,CAAA,CAAA,KAAK,kBAAkB,CAAA,CAAE,EAAE,MAAM,qBAAqB,CAAA;AAClG,QAAA,IAAI,cAAA,EAAgB;AAElB,UAAA,cAAA,CAAe,KAAA,CAAM,IAAA,CAAK,GAAG,MAAA,CAAO,KAAK,CAAA;AACzC,UAAA,aAAA,EAAA;AACA,UAAA,MAAM,MAAA,CAAO,MAAM,mCAAA,EAAqC;AAAA,YACtD,UAAU,cAAA,CAAe,EAAA;AAAA,YACzB,SAAS,cAAA,CAAe,OAAA;AAAA,YACxB,UAAA,EAAY,OAAO,KAAA,CAAM;AAAA,WAC1B,CAAA;AAAA,QACH,CAAA,MAAO;AAEL,UAAA,MAAM,MAAA,CAAO,KAAK,oDAAA,EAAsD;AAAA,YACtE,aAAa,MAAA,CAAO,gBAAA;AAAA,YACpB,qBAAA;AAAA,YACA,YAAA,EAAc,gBAAgB,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE;AAAA,WACzD,CAAA;AACD,UAAA,MAAM,UAAA,GAAa,iBAAA;AAAA,YACjB,MAAA;AAAA,YACA,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,WACpD;AACA,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,YAAA,YAAA,EAAA;AAAA,UACF,CAAA,MAAO;AACL,YAAA,MAAM,MAAA,CAAO,KAAK,sDAAA,EAAwD;AAAA,cACxE,aAAa,MAAA,CAAO;AAAA,aACrB,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,MAAM,UAAA,GAAa,iBAAA;AAAA,UACjB,MAAA;AAAA,UACA,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,SACpD;AACA,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,UAAA,YAAA,EAAA;AAAA,QACF,CAAA,MAAO;AACL,UAAA,MAAM,MAAA,CAAO,KAAK,wDAAwD,CAAA;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,CAAO,MAAM,4BAAA,EAA8B;AAAA,MAC/C,KAAA,EAAO,SAAS,OAAA,CAAQ,MAAA;AAAA,MACxB,QAAA,EAAU,aAAA;AAAA,MACV,OAAA,EAAS,YAAA;AAAA,MACT,iBAAiB,UAAA,CAAW;AAAA,KAC7B,CAAA;AAED,IAAA,OAAO,UAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,MAAA,CAAO,KAAK,gCAAA,EAAkC;AAAA,MAClD,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,KAC7D,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAe,8BACb,GAAA,EACA,SAAA,EACA,KAAA,EACA,aAAA,EACA,QACA,WAAA,EAC6D;AAC7D,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,aAAA,EAAe;AAC9B,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AAGA,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,SAAA,EAAW,KAAA,EAAO,aAAa,CAAA;AAGtE,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,QAAA,EAAU;AAAA,IACjD,KAAA,EAAO,CAAC,gBAAgB,CAAA;AAAA,IACxB,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,EAAE,IAAA,EAAM,sBAAA;AAAuB,KAC3C;AAAA,IACA,WAAA,EAAa;AAAA,GACd,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,SAAA,GAAY,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,KAAS,sBAAA,EAAwB;AACzD,IAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,EACzE;AAGA,EAAA,MAAM,WAAW,QAAA,CAAS,KAAA;AAO1B,EAAA,MAAM,kBAAkB,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM;AAC1D,IAAA,MAAM,UAAA,GAAa,CAAA,CAAE,SAAA,EAAW,UAAA,IAAc,GAAA;AAC9C,IAAA,OAAO,GAAA,GAAM,UAAA;AAAA,EACf,GAAG,CAAC,CAAA;AACJ,EAAA,MAAM,iBAAA,GAAoB,SAAS,OAAA,CAAQ,MAAA,GAAS,IAChD,eAAA,GAAkB,QAAA,CAAS,QAAQ,MAAA,GACnC,CAAA;AAEJ,EAAA,MAAM,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,IAChD,YAAA,EAAc,SAAS,OAAA,CAAQ,MAAA;AAAA,IAC/B;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,gBAAA,EAAkB,KAAA;AAAA;AAAA,MAClB,gBAAgB,EAAC;AAAA,MACjB,SAAS,QAAA,CAAS,OAAA;AAAA,MAClB;AAAA,KACF;AAAA,IACA,UAAA,EAAY,SAAS,KAAA,GAAS,QAAA,CAAS,MAAM,YAAA,GAAe,QAAA,CAAS,MAAM,gBAAA,GAAoB;AAAA,GACjG;AACF;AAgBA,eAAe,sBACb,OAAA,EACA,SAAA,EACA,GAAA,EACA,OAAA,EACA,QACA,UAAA,EACwB;AACxB,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAItD,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,QAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,MACtB;AAEA,IACF;AACA,IAAA,MAAA,CAAO,KAAA,GAAQ,UAAA;AAAA,EACjB;AAGA,EAAA,IAAI,eAAA,GAAkB,QAAQ,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAA,CAAM,SAAS,CAAC,CAAA;AAG9D,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,MAAM,aAAsD,EAAC;AAE7D,EAAA,KAAA,MAAW,UAAU,eAAA,EAAiB;AACpC,IAAA,MAAM,cAAwB,EAAC;AAC/B,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,QAAA,WAAA,CAAY,KAAK,IAAI,CAAA;AACrB,QAAA,SAAA,CAAU,IAAI,IAAI,CAAA;AAAA,MACpB,CAAA,MAAO;AACL,QAAA,UAAA,CAAW,KAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,MAC7C;AAAA,IACF;AACA,IAAA,MAAA,CAAO,KAAA,GAAQ,WAAA;AAAA,EACjB;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,aAAA,EAAgB,UAAA,CAAW,MAAM,CAAA,sDAAA,CAAA,EAA0D;AAAA,MACrG,gBAAgB,UAAA,CAAW,MAAA;AAAA,MAC3B,OAAA,EAAS,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,IAAA,EAAO,CAAA,CAAE,MAAM,CAAA,CAAE;AAAA,KACpE,CAAA;AAAA,EACH;AAGA,EAAA,eAAA,GAAkB,gBAAgB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAA,CAAM,SAAS,CAAC,CAAA;AAGlE,EAAA,MAAM,qBAAA,GAAwB,CAAA;AAC9B,EAAA,IAAI,eAAA,GAAkB,CAAA;AAEtB,EAAA,OAAO,kBAAkB,qBAAA,EAAuB;AAE9C,IAAA,MAAM,iBAAA,GAAoB,IAAI,GAAA,CAAI,eAAA,CAAgB,QAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AACzE,IAAA,MAAM,YAAA,GAAe,SAAA,CAClB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,iBAAA,CAAkB,GAAA,CAAI,CAAC,CAAC,CAAA;AAE1C,IAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE7B,MAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,QAAA,MAAM,MAAA,CAAO,KAAK,+BAAA,EAAiC;AAAA,UACjD,eAAA,EAAiB,eAAA;AAAA,UACjB,cAAc,eAAA,CAAgB;AAAA,SAC/B,CAAA;AAAA,MACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,eAAA,EAAA;AAEA,IAAA,MAAM,OAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAe,CAAA,CAAA,EAAI,qBAAqB,CAAA,CAAA,EAAI;AAAA,MAClF,cAAc,YAAA,CAAa,MAAA;AAAA,MAC3B,cAAA,EAAgB,SAAA,CAAU,MAAA,GAAS,YAAA,CAAa,MAAA;AAAA,MAChD,YAAY,SAAA,CAAU,MAAA;AAAA,MACtB,QAAA,EAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAA,CAAQ,SAAA,CAAU,MAAA,GAAS,YAAA,CAAa,MAAA,IAAU,SAAA,CAAU,MAAA,GAAU,GAAG,CAAC,CAAA,CAAA;AAAA,KAC7F,CAAA;AAGD,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,QAAA,GAAW,KAAK,KAAA,CAAA,CAAQ,SAAA,CAAU,SAAS,YAAA,CAAa,MAAA,IAAU,SAAA,CAAU,MAAA,GAAU,GAAG,CAAA;AAC/F,MAAA,UAAA,CAAW,CAAA,gDAAA,EAAmD,eAAe,CAAA,EAAA,EAAK,QAAQ,CAAA,KAAA,CAAO,CAAA;AAAA,IACnG;AAGA,IAAA,MAAM,gBAAA,GAAmB,UAAU,MAAA,CAAO,CAAC,MAAM,YAAA,CAAa,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAG9E,IAAA,IAAI,cAAA,GAAuC,IAAA;AAE3C,IAAA,IAAI,WAAW,GAAA,EAAK;AAClB,MAAA,cAAA,GAAiB,MAAM,0BAAA;AAAA,QACrB,GAAA;AAAA,QACA,gBAAA;AAAA,QACA,eAAA;AAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,cAAA,IAAkB,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAC/C,QAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,eAAe,CAAA,mBAAA,CAAA,EAAuB;AAAA,UAC5E,aAAa,cAAA,CAAe,MAAA;AAAA,UAC5B,UAAA,EAAY,cAAA,CAAe,MAAA,CAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,CAAM,MAAA,EAAQ,CAAC;AAAA,SACtE,CAAA;AAGD,QAAA,eAAA,CAAgB,IAAA,CAAK,GAAG,cAAc,CAAA;AAAA,MACxC;AAAA,IACF;AAGA,IAAA,MAAM,eAAA,GAAkB,UACrB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,IAAI,GAAA,CAAI,eAAA,CAAgB,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AAEvE,IAAA,IAAI,eAAA,CAAgB,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AAElD,MAAA,MAAM,MAAA,CAAO,KAAK,oDAAA,EAAsD;AAAA,QACtE,SAAA,EAAW,eAAA;AAAA,QACX,cAAc,eAAA,CAAgB;AAAA,OAC/B,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,eAAA,CAAgB,MAAA,IAAU,CAAA,IAAK,eAAA,IAAmB,CAAA,EAAG;AACvD,MAAA,MAAM,MAAA,CAAO,MAAM,iDAAiD,CAAA;AACpE,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,UACvB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,IAAI,GAAA,CAAI,eAAA,CAAgB,OAAA,CAAQ,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AAEvE,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,MAAM,MAAA,CAAO,KAAK,kEAAA,EAAoE;AAAA,MACpF,eAAA,EAAiB,eAAA;AAAA,MACjB,gBAAgB,iBAAA,CAAkB;AAAA,KACnC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,kBAAkB,CAAC,CAAA;AACrC,IAAA,MAAM,QAAA,GAAW,YAAY,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,SAAA,GAAY,OAAA;AACvE,IAAA,MAAM,aAAA,GAAgB,kBAAkB,MAAA,KAAW,CAAA,GAC/C,UAAU,QAAQ,CAAA,CAAA,GAClB,CAAA,OAAA,EAAU,iBAAA,CAAkB,MAAM,CAAA,gBAAA,CAAA;AAEtC,IAAA,MAAM,cAAA,GAA8B;AAAA,MAClC,EAAA,EAAI,CAAA,CAAA,EAAI,eAAA,CAAgB,MAAA,GAAS,CAAC,CAAA,CAAA;AAAA,MAClC,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,aAAA;AAAA,MACT,KAAA,EAAO,iBAAA;AAAA,MACP,WAAA,EAAa,MAAA;AAAA,MACb,QAAA,EAAU,KAAA;AAAA,MACV,SAAA,EAAW;AAAA,QACT,WAAA,EAAa,KAAA;AAAA,QACb,QAAA,EAAU,KAAA;AAAA,QACV,YAAA,EAAc,IAAA;AAAA,QACd,WAAA,EAAa,8BAA8B,eAAe,CAAA,uBAAA,EAA0B,kBAAkB,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,kBAAkB,MAAA,GAAS,CAAA,GAAI,QAAQ,iBAAA,CAAkB,MAAA,GAAS,CAAC,CAAA,KAAA,CAAA,GAAU,EAAE,CAAA,CAAA;AAAA,QAC9M,UAAA,EAAY;AAAA;AACd,KACF;AAEA,IAAA,eAAA,CAAgB,KAAK,cAAc,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,eAAA;AACT;AAMA,eAAe,YAAA,CACb,KAAA,EACA,KAAA,EACA,MAAA,EACA,UAAA,EACmD;AACnD,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,eAAA,EAAiB,OAAA,EAAA,EAAW;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,EAAM;AAG3B,MAAA,aAAA,CAAc,OAAO,OAAO,CAAA;AAG5B,MAAA,IAAI,UAAU,CAAA,EAAG;AACf,QAAA,MAAM,MAAA,CAAO,MAAM,CAAA,EAAG,KAAK,yBAAyB,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,CAAE,CAAA;AAAA,MAClF;AACA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAGpE,MAAA,MAAM,MAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAA+B,OAAO,KAAK,SAAA,EAAW;AAAA,QACvE,WAAW,SAAA,CAAU,IAAA;AAAA,QACrB,cAAc,SAAA,CAAU,OAAA;AAAA,QACxB,YAAY,SAAA,CAAU;AAAA,OACvB,CAAA;AAGD,MAAA,MAAM,SAAA,GAAY,aAAa,SAAS,CAAA;AAExC,MAAA,IAAI,UAAU,eAAA,EAAiB;AAE7B,QAAA,MAAM,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,KAAK,CAAA,iBAAA,EAAoB,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,GAAA,EAAM,SAAS,CAAA,CAAA,EAAI;AAAA,UACzF,cAAc,SAAA,CAAU,OAAA;AAAA,UACxB,SAAA;AAAA,UACA,OAAA;AAAA,UACA,KAAA,EAAO,SAAA,CAAU,KAAA,EAAO,KAAA,CAAM,IAAI,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI;AAAA;AAAA,SAC1D,CAAA;AAGD,QAAA,UAAA,GAAa,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,SAAS,eAAe,OAAO,CAAA,CAAA,EAAI,eAAe,CAAA,IAAA,CAAM,CAAA;AAGjF,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC7B,UAAA,UAAA,CAAW,SAAS,GAAA,GAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,GAAU,CAAC,CAAC,CAAA;AAAA,QACrD,CAAC,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,CAAO,MAAM,CAAA,EAAG,KAAK,iBAAiB,eAAe,CAAA,WAAA,EAAc,SAAS,CAAA,CAAA,EAAI,SAAA,EAAW;AAAA,UAC/F;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,aAAa,IAAI,KAAA,CAAM,GAAG,KAAK,CAAA,cAAA,EAAiB,eAAe,CAAA,SAAA,CAAW,CAAA;AAClF;AAKA,SAAS,aAAa,KAAA,EAAsB;AAC1C,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,WAAA,EAAY;AAG1C,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,mBAAmB,CAAA,EAAG;AACtG,IAAA,OAAO,oBAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AACjF,IAAA,OAAO,oBAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,QAAA,CAAS,SAAS,KAAK,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG;AAChE,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG;AACpG,IAAA,OAAO,eAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,kBAAkB,CAAA,EAAG;AACjG,IAAA,OAAO,cAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,QAAA,CAAS,SAAS,KAAK,OAAA,CAAQ,QAAA,CAAS,wBAAwB,CAAA,EAAG;AAC7E,IAAA,OAAO,mBAAA;AAAA,EACT;AAGA,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,SAAA,CAAU,GAAG,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACjE,EAAA,OAAO,CAAA,OAAA,EAAU,OAAO,CAAA,EAAG,KAAA,CAAM,QAAQ,MAAA,GAAS,EAAA,GAAK,QAAQ,EAAE,CAAA,CAAA;AACnE","file":"index.js","sourcesContent":["/**\n * Tool definitions for native LLM tool calling\n * Replaces text-based JSON parsing with structured OpenAI Function Calling\n */\n\nimport type { LLMTool } from '@kb-labs/sdk';\n\n/**\n * Tool: generate_commit_plan_phase3\n *\n * Used by Phase 3 to either extend existing commits or create new commits for missing files\n * Supports two actions: extend_existing (add files to existing commit) and create_new (create new commit)\n */\nexport const COMMIT_PLAN_TOOL_PHASE3: LLMTool = {\n name: 'generate_commit_plan',\n description: 'Generate commits for missing files - either extend existing commits or create new ones',\n inputSchema: {\n type: 'object',\n properties: {\n commits: {\n type: 'array',\n description: 'List of commit actions. Can mix extend_existing and create_new actions.',\n items: {\n type: 'object',\n required: ['action', 'files'],\n properties: {\n action: {\n type: 'string',\n enum: ['create_new', 'extend_existing'],\n description: 'Whether to create a new commit or add files to an existing commit. Use \"extend_existing\" to avoid creating unnecessary commits.',\n },\n existingCommitId: {\n type: 'string',\n description: 'ID of existing commit to extend (REQUIRED when action is \"extend_existing\"). Example: \"c1\", \"c2\".',\n pattern: '^c[0-9]+$',\n },\n id: {\n type: 'string',\n description: 'Unique commit identifier (REQUIRED for create_new action, e.g., c1, c2, c3).',\n pattern: '^c[0-9]+$',\n },\n type: {\n type: 'string',\n enum: ['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf'],\n description: 'Conventional commit type (REQUIRED for create_new action).',\n },\n scope: {\n type: 'string',\n description: 'Scope of the commit (optional).',\n },\n message: {\n type: 'string',\n description: 'Commit message in imperative mood (REQUIRED for create_new action).',\n minLength: 5,\n maxLength: 100,\n },\n body: {\n type: 'string',\n description: 'Detailed description (optional).',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of file paths to add to this commit.',\n minItems: 1,\n },\n releaseHint: {\n type: 'string',\n enum: ['none', 'patch', 'minor', 'major'],\n description: 'Semantic versioning impact (REQUIRED for create_new action).',\n },\n breaking: {\n type: 'boolean',\n description: 'Whether this is a breaking change.',\n default: false,\n },\n reasoning: {\n type: 'object',\n description: 'Reasoning for classification (REQUIRED for create_new action).',\n properties: {\n newBehavior: { type: 'boolean' },\n fixesBug: { type: 'boolean' },\n internalOnly: { type: 'boolean' },\n explanation: { type: 'string', minLength: 10, maxLength: 300 },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n },\n },\n },\n },\n },\n required: ['commits'],\n },\n};\n\n/**\n * Tool: generate_commit_plan\n *\n * Used by Phase 1 and Phase 2 to structure commit plan output using OpenAI Function Calling API\n * This guarantees valid JSON output without parsing errors\n */\nexport const COMMIT_PLAN_TOOL: LLMTool = {\n name: 'generate_commit_plan',\n description: 'Generate a structured commit plan with conventional commits following best practices',\n inputSchema: {\n type: 'object',\n properties: {\n needsMoreContext: {\n type: 'boolean',\n description: 'Whether you need to see diff content to make accurate commit type decisions. Set to true if file paths and stats alone are insufficient.',\n default: false,\n },\n requestedFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of SPECIFIC files you need diffs for (MAXIMUM 15 files). Only request files where file path and stats are insufficient. DO NOT request all files - be selective and choose only the most critical/ambiguous ones. Prioritize files with unclear intent or complex changes.',\n default: [],\n },\n commits: {\n type: 'array',\n description: 'List of commit groups. Each commit groups related files by logical change (not by file type or directory).',\n items: {\n type: 'object',\n required: ['id', 'type', 'message', 'files', 'releaseHint', 'breaking', 'reasoning'],\n properties: {\n id: {\n type: 'string',\n description: 'Unique commit identifier (e.g., c1, c2, c3).',\n pattern: '^c[0-9]+$',\n },\n type: {\n type: 'string',\n enum: ['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf'],\n description: 'Conventional commit type. Use refactor for internal changes, feat only for new user-facing features.',\n },\n scope: {\n type: 'string',\n description: 'Scope of the commit (e.g., \"cli\", \"api\", \"core\"). Should reflect affected area, not individual files.',\n },\n message: {\n type: 'string',\n description: 'Commit message in imperative mood, lowercase, no period at end (e.g., \"add authentication middleware\")',\n minLength: 5,\n maxLength: 100,\n },\n body: {\n type: 'string',\n description: 'Detailed description with bullet points listing affected files/changes. Use for commits with 2+ files.',\n },\n files: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of file paths in this commit. Each file must appear in exactly ONE commit (no duplicates across commits).',\n minItems: 1,\n },\n releaseHint: {\n type: 'string',\n enum: ['none', 'patch', 'minor', 'major'],\n description: 'Semantic versioning impact. Use \"minor\" for feat, \"patch\" for fix/refactor, \"none\" for chore/docs/test.',\n },\n breaking: {\n type: 'boolean',\n description: 'Whether this is a breaking change (breaks public API compatibility).',\n default: false,\n },\n reasoning: {\n type: 'object',\n required: ['newBehavior', 'fixesBug', 'internalOnly', 'explanation', 'confidence'],\n description: 'Reasoning for commit type classification. Used for validation and debugging.',\n properties: {\n newBehavior: {\n type: 'boolean',\n description: 'Does this change add NEW USER-VISIBLE BEHAVIOR? (new API, feature, capability that users can access)',\n },\n fixesBug: {\n type: 'boolean',\n description: 'Does this change fix BROKEN functionality? (corrects bug or error)',\n },\n internalOnly: {\n type: 'boolean',\n description: 'Is this ONLY INTERNAL restructuring? (code reorganization, renaming, extracting functions without changing behavior)',\n },\n explanation: {\n type: 'string',\n description: 'Explain your classification decision. Why did you choose this commit type?',\n minLength: 10,\n maxLength: 300,\n },\n confidence: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description: 'Confidence in this classification (0.0 to 1.0). Use <0.7 if you need more context (will trigger Phase 2).',\n },\n },\n },\n },\n },\n },\n },\n required: ['commits'],\n },\n};\n","/**\n * Git status analysis\n */\n\nimport { simpleGit, type SimpleGit, type StatusResult } from \"simple-git\";\nimport type { GitStatus } from \"@kb-labs/commit-contracts\";\n\n/**\n * Get current git status (staged, unstaged, untracked files).\n * cwd must already point to the resolved scope directory.\n */\nexport async function getGitStatus(cwd: string): Promise<GitStatus> {\n // --ignore-submodules=all: exclude submodule pointer drift in worktrees\n const git: SimpleGit = simpleGit(cwd);\n const status: StatusResult = await git.status(['--ignore-submodules=all']);\n\n return {\n staged: status.staged.filter((f) => !shouldIgnoreFile(f)),\n unstaged: [...status.modified, ...status.deleted]\n .filter((f) => !status.staged.includes(f))\n .filter((f) => !shouldIgnoreFile(f)),\n untracked: status.not_added.filter((f) => !shouldIgnoreFile(f)),\n };\n}\n\n/**\n * Check if file should be ignored (node_modules, dist, etc.)\n */\nfunction shouldIgnoreFile(file: string): boolean {\n const ignoredPaths = [\n \"node_modules/\",\n \".git/\",\n \"dist/\",\n \"build/\",\n \".next/\",\n \".turbo/\",\n \"coverage/\",\n \".cache/\",\n \".temp/\",\n \"tmp/\",\n ];\n\n return ignoredPaths.some((path) => file.includes(path));\n}\n\n/**\n * Get all changed files (staged + unstaged + untracked)\n * Filters out node_modules and other build artifacts\n */\nexport function getAllChangedFiles(status: GitStatus): string[] {\n const allFiles = [\n ...new Set([...status.staged, ...status.unstaged, ...status.untracked]),\n ];\n return allFiles.filter((file) => !shouldIgnoreFile(file));\n}\n\n/**\n * Check if there are any changes\n */\nexport function hasChanges(status: GitStatus): boolean {\n return (\n status.staged.length > 0 ||\n status.unstaged.length > 0 ||\n status.untracked.length > 0\n );\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(cwd: string): Promise<string> {\n const git: SimpleGit = simpleGit(cwd);\n const branch = await git.revparse([\"--abbrev-ref\", \"HEAD\"]);\n return branch.trim();\n}\n\n/**\n * Check if branch is protected (main/master)\n */\nexport function isProtectedBranch(branch: string): boolean {\n const protectedBranches = [\n \"main\",\n \"master\",\n \"develop\",\n \"release\",\n \"production\",\n ];\n return protectedBranches.includes(branch.toLowerCase());\n}\n","/**\n * File summary extraction\n */\n\n/* eslint-disable no-await-in-loop -- Sequential git operations required: must check status, read diffs, compute summaries one-by-one for each file */\n\nimport {\n simpleGit,\n type SimpleGit,\n type DiffResultTextFile,\n type DiffResultBinaryFile,\n} from \"simple-git\";\nimport type { FileSummary } from \"@kb-labs/commit-contracts\";\n\n/**\n * Type guard for text file diff result\n */\nfunction isTextFile(\n file: DiffResultTextFile | DiffResultBinaryFile,\n): file is DiffResultTextFile {\n return !file.binary;\n}\n\n/**\n * Check if file is truly new (doesn't exist in current HEAD commit)\n * Returns true if file doesn't exist in HEAD (the current committed state)\n * Returns false if file exists in HEAD (even if modified/deleted locally)\n * Supports nested git repositories\n */\nasync function isNewFile(cwd: string, filePath: string): Promise<boolean> {\n try {\n // Find the git repository for this file (walks up directory tree)\n const repo = await findGitRepo(cwd, filePath);\n\n if (!repo) {\n // No git repo found - treat as new file\n return true;\n }\n\n const git = simpleGit(repo.repoPath);\n\n // Check if file exists in HEAD (current commit), not in history\n // git ls-tree HEAD -- <file>\n // Returns tree entry if file exists in HEAD, empty if file is new\n // This correctly handles modified/unstaged files (they exist in HEAD = not new)\n const result = await git.raw([\"ls-tree\", \"HEAD\", \"--\", repo.relativePath]);\n\n // If no output, file doesn't exist in HEAD → truly new file\n // If has output, file exists in HEAD → not new (modified/unstaged)\n return result.trim().length === 0;\n } catch {\n // On error, assume it's new (safer to say \"new\" than claim it existed)\n return true;\n }\n}\n\n/**\n * Get file summaries with diff stats for given files\n * Supports nested git repositories by grouping files per repo\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- File summary extraction: groups files by repo, handles nested git repos, computes diff stats, processes staged/unstaged/untracked files\nexport async function getFileSummaries(\n cwd: string,\n files: string[],\n): Promise<FileSummary[]> {\n if (files.length === 0) {\n return [];\n }\n\n const summaries: FileSummary[] = [];\n\n // Group files by repository (walks up directory tree to find .git)\n const filesByRepo = new Map<\n string,\n { repoPath: string; relativePath: string; originalPath: string }[]\n >();\n\n for (const file of files) {\n const repo = await findGitRepo(cwd, file);\n\n if (!repo) {\n // No git repo found - treat as file in cwd\n const group = filesByRepo.get(cwd) ?? [];\n group.push({ repoPath: cwd, relativePath: file, originalPath: file });\n filesByRepo.set(cwd, group);\n continue;\n }\n\n // Group by repository path\n const group = filesByRepo.get(repo.repoPath) ?? [];\n group.push({\n repoPath: repo.repoPath,\n relativePath: repo.relativePath,\n originalPath: file,\n });\n filesByRepo.set(repo.repoPath, group);\n }\n\n // Get diff summaries for each repo separately\n for (const [repoPath, fileInfos] of filesByRepo) {\n const git: SimpleGit = simpleGit(repoPath);\n const relativePaths = fileInfos.map((f) => f.relativePath);\n\n try {\n // Try staged diff first\n const stagedDiff = await git.diffSummary([\n \"--cached\",\n \"--\",\n ...relativePaths,\n ]);\n\n // Then try unstaged diff (working tree changes)\n const unstagedDiff = await git.diffSummary([\"--\", ...relativePaths]);\n\n // Combine results (prefer staged if file appears in both)\n const allDiffFiles = new Map<\n string,\n DiffResultTextFile | DiffResultBinaryFile\n >();\n for (const file of unstagedDiff.files) {\n allDiffFiles.set(file.file, file);\n }\n for (const file of stagedDiff.files) {\n // Staged takes priority\n allDiffFiles.set(file.file, file);\n }\n\n // Process diff results\n for (const file of allDiffFiles.values()) {\n // Find original path (with repo prefix)\n const fileInfo = fileInfos.find((f) => f.relativePath === file.file);\n if (!fileInfo) {\n continue;\n }\n\n // Check if file is truly new (using repoPath as cwd)\n const isNew = await isNewFile(repoPath, file.file);\n\n // Handle both text and binary files\n if (isTextFile(file)) {\n summaries.push({\n path: fileInfo.originalPath,\n status: mapDiffStatus(file.insertions, file.deletions),\n additions: file.insertions,\n deletions: file.deletions,\n binary: false,\n isNewFile: isNew,\n });\n } else {\n // Binary file\n summaries.push({\n path: fileInfo.originalPath,\n status: \"modified\",\n additions: 0,\n deletions: 0,\n binary: true,\n isNewFile: isNew,\n });\n }\n }\n\n // Add any missing files from this repo (untracked - not in git yet)\n const processedPaths = new Set(\n Array.from(allDiffFiles.values()).map((f) => f.file),\n );\n const missingInRepo = fileInfos.filter(\n (f) => !processedPaths.has(f.relativePath),\n );\n\n for (const fileInfo of missingInRepo) {\n // Untracked files are always new (never existed in git)\n summaries.push({\n path: fileInfo.originalPath,\n status: \"added\",\n additions: 0,\n deletions: 0,\n binary: false,\n isNewFile: true,\n });\n }\n } catch {\n // Fallback: create basic summaries for this repo's files\n for (const fileInfo of fileInfos) {\n summaries.push({\n path: fileInfo.originalPath,\n status: \"modified\",\n additions: 0,\n deletions: 0,\n binary: false,\n isNewFile: false, // Conservative assumption\n });\n }\n }\n }\n\n return summaries;\n}\n\n/**\n * Map insertions/deletions to status\n */\nfunction mapDiffStatus(\n insertions: number,\n deletions: number,\n): FileSummary[\"status\"] {\n // Simple heuristic: if only insertions, likely added; if only deletions, likely deleted\n if (deletions === 0 && insertions > 0) {\n return \"added\";\n }\n if (insertions === 0 && deletions > 0) {\n return \"deleted\";\n }\n return \"modified\";\n}\n\n/**\n * Get a short summary string for display\n */\nexport function formatFileSummary(summary: FileSummary): string {\n const stats = summary.binary\n ? \"binary\"\n : `+${summary.additions}/-${summary.deletions}`;\n return `${summary.path} (${summary.status}, ${stats})`;\n}\n\n/**\n * Get diff content for specific files\n * Used when LLM requests more context (Phase 2 escalation)\n * Supports nested git repositories (files with prefix like 'kb-labs-sdk/...')\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Diff extraction: groups files by nested repo, handles staged/unstaged diffs, processes binary files, merges results\nexport async function getFileDiffs(\n cwd: string,\n files: string[],\n): Promise<Map<string, string>> {\n if (files.length === 0) {\n return new Map();\n }\n\n const diffs = new Map<string, string>();\n\n // Group files by repository (walks up directory tree to find .git)\n const filesByRepo = new Map<\n string,\n { repoPath: string; relativePath: string; originalPath: string }[]\n >();\n\n for (const file of files) {\n const repo = await findGitRepo(cwd, file);\n\n if (!repo) {\n // No git repo found - treat as file in cwd\n const group = filesByRepo.get(cwd) ?? [];\n group.push({ repoPath: cwd, relativePath: file, originalPath: file });\n filesByRepo.set(cwd, group);\n continue;\n }\n\n // Group by repository path\n const group = filesByRepo.get(repo.repoPath) ?? [];\n group.push({\n repoPath: repo.repoPath,\n relativePath: repo.relativePath,\n originalPath: file,\n });\n filesByRepo.set(repo.repoPath, group);\n }\n\n // Get diffs for each repo\n for (const [repoPath, fileInfos] of filesByRepo) {\n const git: SimpleGit = simpleGit(repoPath);\n\n for (const { relativePath, originalPath } of fileInfos) {\n try {\n // Try staged diff first, then unstaged\n let diff = await git.diff([\"--cached\", \"--\", relativePath]);\n if (!diff) {\n diff = await git.diff([\"--\", relativePath]);\n }\n if (!diff) {\n // For untracked files, try to read content\n diff = await git.show([`:${relativePath}`]).catch(() => \"\");\n }\n if (diff) {\n diffs.set(originalPath, diff);\n }\n } catch {\n // Skip files that can't be diffed\n }\n }\n }\n\n return diffs;\n}\n\n/**\n * Helper to check if path exists asynchronously\n */\nasync function existsAsync(path: string): Promise<boolean> {\n try {\n const { existsSync } = await import(\"node:fs\");\n return existsSync(path);\n } catch {\n return false;\n }\n}\n\n/**\n * Find the git repository root for a given file path.\n * Walks up the directory tree to find the nearest .git directory.\n *\n * @param basePath - Base path to start searching from (e.g., /Users/user/project)\n * @param filePath - Relative file path (e.g., kb-labs-commit/packages/core/src/index.ts)\n * @returns Object with repoPath (absolute) and relativePath (relative to repo), or null if no repo found\n *\n * @example\n * // For nested repo:\n * findGitRepo('/Users/user/kb-labs', 'kb-labs-commit/packages/core/src/index.ts')\n * // Returns: { repoPath: '/Users/user/kb-labs/kb-labs-commit', relativePath: 'packages/core/src/index.ts' }\n *\n * // For file in root repo:\n * findGitRepo('/Users/user/kb-labs', 'src/index.ts')\n * // Returns: { repoPath: '/Users/user/kb-labs', relativePath: 'src/index.ts' }\n */\nasync function findGitRepo(\n basePath: string,\n filePath: string,\n): Promise<{ repoPath: string; relativePath: string } | null> {\n const segments = filePath.split(\"/\");\n\n // Try progressively shorter paths (walk up the tree)\n // For 'kb-labs-commit/packages/core/src/index.ts', try:\n // 1. basePath/kb-labs-commit/packages/core/src\n // 2. basePath/kb-labs-commit/packages/core\n // 3. basePath/kb-labs-commit/packages\n // 4. basePath/kb-labs-commit\n // 5. basePath (fallback to root)\n\n for (let i = segments.length - 1; i > 0; i--) {\n const potentialRepoSegments = segments.slice(0, i);\n const potentialRepoPath = `${basePath}/${potentialRepoSegments.join(\"/\")}`;\n const gitDir = `${potentialRepoPath}/.git`;\n\n if (await existsAsync(gitDir)) {\n // Found a .git directory - this is the repo root\n const relativePath = segments.slice(i).join(\"/\");\n return { repoPath: potentialRepoPath, relativePath };\n }\n }\n\n // No nested repo found, check if basePath itself is a git repo\n if (await existsAsync(`${basePath}/.git`)) {\n return { repoPath: basePath, relativePath: filePath };\n }\n\n // No git repo found at all\n return null;\n}\n","/**\n * Recent commits analysis for style matching\n */\n\nimport { simpleGit, type SimpleGit } from \"simple-git\";\n\n/**\n * Get recent commit messages for style reference\n *\n * @param cwd - Working directory\n * @param count - Number of commits to retrieve (default: 10)\n * @returns Array of commit messages (subject line only)\n */\nexport async function getRecentCommits(\n cwd: string,\n count: number = 10,\n): Promise<string[]> {\n const git: SimpleGit = simpleGit(cwd);\n\n try {\n const log = await git.log({\n maxCount: count,\n format: {\n message: \"%s\", // Subject line only\n },\n });\n\n return log.all.map((commit) => commit.message);\n } catch {\n // Return empty array if no commits or error\n return [];\n }\n}\n\n/**\n * Detect the commit style from recent commits\n *\n * @returns Detected style hints\n */\nexport function detectCommitStyle(commits: string[]): {\n usesConventional: boolean;\n commonScopes: string[];\n avgLength: number;\n} {\n if (commits.length === 0) {\n return {\n usesConventional: false,\n commonScopes: [],\n avgLength: 50,\n };\n }\n\n // Check for conventional commit pattern: type(scope)?: message\n const conventionalPattern =\n /^(feat|fix|docs|style|refactor|test|chore|ci|perf|build)(\\([^)]+\\))?!?:/i;\n const conventionalMatches = commits.filter((c) =>\n conventionalPattern.test(c),\n );\n const usesConventional = conventionalMatches.length >= commits.length * 0.5;\n\n // Extract scopes\n const scopePattern = /^\\w+\\(([^)]+)\\)/;\n const scopes = commits\n .map((c) => {\n const match = c.match(scopePattern);\n return match ? match[1] : null;\n })\n .filter((s): s is string => s !== null);\n\n // Count scope frequency\n const scopeCounts = scopes.reduce<Record<string, number>>((acc, scope) => {\n acc[scope] = (acc[scope] || 0) + 1;\n return acc;\n }, {});\n\n // Get top 5 most common scopes\n const commonScopes = Object.entries(scopeCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([scope]) => scope);\n\n // Calculate average message length\n const avgLength = Math.round(\n commits.reduce((sum, c) => sum + c.length, 0) / commits.length,\n );\n\n return {\n usesConventional,\n commonScopes,\n avgLength,\n };\n}\n","/**\n * LLM prompt building and response parsing\n */\n\nimport type { FileSummary, CommitGroup, ConventionalType, CommitReasoning } from '@kb-labs/commit-contracts';\nimport type { PatternAnalysis } from './pattern-detector';\n\n/**\n * System prompt for LLM - Phase 1 (file summaries only)\n */\nexport const SYSTEM_PROMPT = `You are a git commit message generator. Analyze the changed files and generate a commit plan.\n\nCRITICAL OUTPUT FORMAT:\n- Return ONLY a valid JSON object\n- Do NOT wrap in markdown code blocks (no \\`\\`\\`json, no \\`\\`\\`)\n- Do NOT add any text before or after the JSON\n- Ensure all strings are properly escaped (use double quotes, escape backslashes and quotes)\n\nIMPORTANT: You must assess your confidence level. If file paths and stats alone are not enough to determine the correct commit type and message, set needsMoreContext to true and list the files you need to see the diff for.\n\nCRITICAL GROUPING RULES:\n- Group files by LOGICAL CHANGE, not by file type or directory\n- If multiple files implement the same feature/fix/refactor, they belong in ONE commit\n- For initial project setup (many new files): group by package or functional area (contracts, core, cli, docs, tests)\n- Target: 3-8 commits for <50 files, 5-12 commits for 50-150 files, 10-20 commits for 150+ files\n- Ask yourself: \"Would a developer make these changes in separate commits?\" If no, group them!\n- CRITICAL: Each file must appear in EXACTLY ONE commit - no duplicates across commits!\n\nCRITICAL: FILE TYPE SHORTCUTS (check FIRST, before other rules):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n🚫 STOP! Check file extensions BEFORE asking questions below:\n\n📝 ALL files are *.md or *.mdx? → Type: docs (SKIP all questions below!)\n🧪 ALL files in test/, __tests__/, *.test.ts, *.spec.ts? → Type: test\n❌ If ANY file has code (.ts, .js, .tsx, .jsx, .py, etc.) → Continue to questions below\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nCRITICAL COMMIT TYPE CLASSIFICATION:\nFor EACH commit, you MUST answer these questions to determine the correct type:\n\n1. Does this change add NEW USER-VISIBLE BEHAVIOR? (yes/no)\n - Can users/developers do something they couldn't before?\n - Is there a new API, feature, or capability?\n → YES = likely feat\n\n2. Does this change fix BROKEN functionality? (yes/no)\n - Was something not working correctly?\n - Is this correcting a bug or error?\n → YES = fix\n\n3. Is this ONLY INTERNAL restructuring? (yes/no)\n - Code reorganization, renaming, extracting functions?\n - Improving structure WITHOUT changing behavior?\n - Modified files with balanced additions/deletions?\n → YES = refactor\n\n4. Is this configuration, build, or maintenance work? (yes/no)\n - Dependencies, build configs, tooling?\n - No code logic changes?\n → YES = chore\n\nDEFAULT BIAS: When uncertain between feat and refactor, choose refactor!\n\nRules:\n1. Use conventional commits: feat, fix, refactor, chore, docs, test, build, ci, perf\n2. Group related files - number of commits should scale with file count (see grouping rules above)\n3. Each commit MUST include \"reasoning\" field explaining your classification\n4. Message should be lowercase, imperative mood, no period at end\n5. breaking: true only for breaking API changes\n6. For commits with 2+ files, add \"body\" with bullet points listing affected files/changes\n7. Scope should reflect the affected area (e.g., \"cli\", \"api\"), not individual files\n8. CRITICAL: If ALL files in a commit have status \"deleted\", use type \"chore\" or \"refactor\", NOT \"feat\"\n9. CRITICAL: If a commit is mostly deletions (>80% deletions), use \"refactor\" or \"chore\", NOT \"feat\"\n\n10. CRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (not generic):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n ❌ BAD (too generic):\n - \"add feature\"\n - \"update files\"\n - \"refactor code\"\n - \"fix bug\"\n - \"improve types\"\n\n ✅ GOOD (specific and descriptive):\n - \"add JWT authentication with refresh token support\"\n - \"update TypeScript configuration for strict mode\"\n - \"refactor plugin execution to use factory pattern\"\n - \"fix null pointer exception in authentication middleware\"\n - \"improve type safety in workflow execution context\"\n\n Guidelines:\n - Include WHAT was changed (specific feature/component)\n - Include HOW if relevant (method, pattern, technology)\n - Use concrete nouns (not \"files\", \"code\", \"feature\")\n - Add context that helps reviewers understand the change\n - For body: list specific changes, not just file names\n\n11. CRITICAL: SPECIFIC TYPE DETECTION (check BEFORE defaulting to refactor):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n 📝 docs: Documentation ONLY (no code changes)\n ✅ ALL files are markdown (*.md, *.mdx) → docs (even if IsNewFile: true)\n ✅ README.md, CONTRIBUTING.md, API docs, ADRs\n ✅ Files in docs/ or doc/ directory with only markdown\n ✅ JSDoc comments only (no logic changes)\n ❌ NOT docs if ANY file has code logic changes\n\n **IMPORTANT**: If ALL files end with .md or .mdx → ALWAYS use docs, NEVER feat!\n\n 🐛 fix: Corrects BROKEN functionality\n ✅ Bug fixes, error handling corrections\n ✅ Fixes crashes, incorrect behavior\n ✅ Corrects typos in USER-FACING text (not code comments)\n ❌ NOT fix if adding new behavior (that's feat)\n\n 🧪 test: Test files ONLY\n ✅ Files in test/, tests/, __tests__/, *.test.ts, *.spec.ts\n ✅ Adding/updating test cases\n ❌ NOT test if also changing source code\n\n12. CRITICAL: IsNewFile flag determines STRONG BIAS against feat:\n\n IsNewFile: FALSE (modified existing file):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n → DEFAULT to refactor/fix/chore (NOT feat!)\n → Only use feat if adds MAJOR new user-facing capability\n\n Common cases where IsNewFile: false = NOT feat:\n ✅ Changed dependencies/imports → chore\n ✅ Added method to existing class → refactor\n ✅ Updated implementation logic → refactor\n ✅ Fixed bug in existing code → fix\n ✅ Renamed/moved code → refactor\n ✅ Modified config files → chore\n\n ❌ WRONG: IsNewFile: false, minor additions → feat\n ✅ RIGHT: IsNewFile: false, minor additions → refactor\n\n\n IsNewFile: TRUE (brand new file):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n → Might be feat IF adds new user capability\n → If only config/tooling/internal → chore\n\n Examples:\n ✅ New API endpoint file → feat\n ✅ New CLI command file → feat\n ✅ New config file → chore\n ✅ New test file → test\n\nEXACT JSON SCHEMA (copy this structure):\n{\n \"needsMoreContext\": false,\n \"requestedFiles\": [\"file1.ts\"],\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"feat\",\n \"scope\": \"auth\",\n \"message\": \"add JWT authentication with refresh token support\",\n \"body\": \"- implement JWT token generation and validation\\\\n- add refresh token rotation mechanism\\\\n- integrate with existing user authentication flow\",\n \"files\": [\"src/auth/jwt-strategy.ts\", \"src/auth/refresh-token.ts\", \"src/middleware/auth.ts\"],\n \"releaseHint\": \"minor\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": true,\n \"fixesBug\": false,\n \"internalOnly\": false,\n \"explanation\": \"Adds new JWT authentication capability with refresh tokens - enables secure stateless authentication for API users\",\n \"confidence\": 0.85\n }\n }\n ]\n}\n\nVALID TYPE VALUES: feat, fix, refactor, chore, docs, test, build, ci, perf\nVALID RELEASEHINT VALUES: none, patch, minor, major\n\nEXAMPLE OUTPUT (use this as template):\n{\n \"needsMoreContext\": false,\n \"requestedFiles\": [],\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"feat\",\n \"scope\": \"cli\",\n \"message\": \"add commit generation command\",\n \"body\": \"- implement generate command\\\\n- add LLM integration\",\n \"files\": [\"src/commands/generate.ts\", \"src/llm.ts\"],\n \"releaseHint\": \"minor\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": true,\n \"fixesBug\": false,\n \"internalOnly\": false,\n \"explanation\": \"New command allows users to generate commits with LLM - new capability\",\n \"confidence\": 0.9\n }\n },\n {\n \"id\": \"c2\",\n \"type\": \"test\",\n \"message\": \"add tests for commit generator\",\n \"files\": [\"tests/generate.test.ts\"],\n \"releaseHint\": \"none\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"Test coverage for new feature - internal quality improvement\",\n \"confidence\": 0.85\n }\n }\n ]\n}\n\nREAL-WORLD EXAMPLES (learn from these patterns):\n\nExample 1: Modified files with low addition ratio → refactor, NOT feat\nFiles:\n - commit-plan.ts (modified, +150/-120)\n - llm-prompt.ts (modified, +80/-60)\nAddition ratio: 230/350 = 65% (low, mostly structural changes)\n❌ WRONG: feat(core): add commit plan and llm prompt generators\n✅ CORRECT: refactor(core): update commit plan and llm prompt logic\nReason: Modified files + low addition ratio = refactoring existing code\n\nExample 2: New package with many files → feat, NOT chore\nFiles: 21 new files in packages/core-resource-broker/\n - package.json (new)\n - src/broker/resource-broker.ts (new)\n - src/queue/priority-queue.ts (new)\n - ... (18 more new files)\n❌ WRONG: chore(core-resource-broker): initialize core resource broker package\n✅ CORRECT: feat(core-resource-broker): add resource broker for rate limiting and queueing\nReason: New package = new functionality = feat (even if many files)\n\nExample 3: Bulk move (many added files but not new) → refactor, NOT feat\nFiles: 100 files with status \"added\" but isNewFile: false\n - packages/analytics/core/file1.ts (added, isNewFile: false)\n - packages/analytics/core/file2.ts (added, isNewFile: false)\n - ... (98 more files, all moved from elsewhere)\n❌ WRONG: feat(analytics): add analytics packages\n✅ CORRECT: refactor(analytics): reorganize analytics package structure\nReason: isNewFile: false means files existed before, just moved/reorganized\n\nExample 4: All deleted files → chore, NOT feat\nFiles: 22 files, all with status \"deleted\"\n - packages/analytics/test1.spec.ts (deleted, +0/-1579)\n - packages/analytics/test2.spec.ts (deleted, +0/-856)\n - ... (20 more deleted files)\n❌ WRONG: feat(analytics): add analytics functionality\n✅ CORRECT: chore(analytics): remove unused test files\nReason: Deleting files is cleanup (chore), not new feature\n\nExample 5: True new feature (genuinely new files) → feat\nFiles: 5 new files with isNewFile: true\n - src/auth/jwt-strategy.ts (added, +200/-0, isNewFile: true)\n - src/auth/auth-middleware.ts (added, +150/-0, isNewFile: true)\n - ... (3 more new files)\n✅ CORRECT: feat(auth): add JWT authentication\nReason: New functionality, truly new files, implements new capability\n\nExample 6: Documentation ONLY → docs, NOT chore or feat\nFiles:\n - README.md (modified, +50/-20, isNewFile: false)\n - CONTRIBUTING.md (modified, +30/-10, isNewFile: false)\n - docs/api.md (modified, +100/-50, isNewFile: false)\n❌ WRONG: chore(docs): update documentation files\n❌ WRONG: feat(docs): add documentation\n✅ CORRECT: docs: improve README and API documentation\nReason: ALL files are markdown = docs (regardless of IsNewFile)\n\nExample 6b: NEW documentation files → docs, NOT feat\nFiles:\n - docs/benchmarks/README.md (added, +200/-0, isNewFile: true)\n - docs/benchmarks/RESULTS.md (added, +100/-0, isNewFile: true)\n❌ WRONG: feat(docs): add benchmarks documentation\n✅ CORRECT: docs(benchmarks): add benchmarks documentation\nReason: ALL files are .md = docs type (even if IsNewFile: true)\n\nExample 7: Bug fix with error handling → fix, NOT refactor\nFiles:\n - src/api/auth.ts (modified, +15/-5, isNewFile: false)\n Diff shows: Added try-catch, null check for token validation\n❌ WRONG: refactor(api): update auth token validation\n✅ CORRECT: fix(api): handle null token in authentication\nReason: Adds error handling to prevent crash = bug fix\n\nExample 8: Test files ONLY → test, NOT chore\nFiles:\n - tests/auth.test.ts (added, +200/-0, isNewFile: true)\n - tests/fixtures/users.json (added, +50/-0, isNewFile: true)\n❌ WRONG: chore(tests): add test files\n✅ CORRECT: test(auth): add authentication test suite\nReason: Test files only = test type\n`;\n\n/**\n * System prompt for LLM - Phase 2 (with diff context)\n */\nexport const SYSTEM_PROMPT_WITH_DIFF = `You are a git commit message generator. You now have the actual diff content for better context.\n\nCRITICAL OUTPUT FORMAT:\n- Return ONLY a valid JSON object\n- Do NOT wrap in markdown code blocks (no \\`\\`\\`json, no \\`\\`\\`)\n- Do NOT add any text before or after the JSON\n- Ensure all strings are properly escaped (use double quotes, escape backslashes and quotes)\n\nCRITICAL: USE IsNewFile METADATA TO DISTINGUISH NEW vs MODIFIED FILES:\n- Each file includes \"IsNewFile: true\" or \"IsNewFile: false\"\n- IsNewFile: false → File EXISTED BEFORE in git history → Use \"refactor\", \"fix\", or \"chore\"\n- IsNewFile: true → File is TRULY NEW (never existed) → Use \"feat\" for new functionality\n- NEVER use \"feat: add initial\" for files with \"IsNewFile: false\" - these are modifications!\n- For files marked \"[EXISTING FILE - was modified]\" in diff section → Use refactor/fix/chore, NOT feat\n\nCRITICAL GROUPING RULES:\n- Group files by LOGICAL CHANGE based on diff content\n- If files are changed for the same reason, they belong in ONE commit\n- IMPORTANT: Most files with status \"modified\" are REFACTORING, not new features\n- For refactoring: analyze the diff to understand what changed (renamed variables, restructured code, etc.)\n- Only use \"add initial\" or \"setup\" messages if you see truly NEW functionality being created from scratch\n- Target: 3-8 commits for <50 files, 5-12 commits for 50-150 files, 10-20 commits for 150+ files\n- Only separate genuinely DIFFERENT changes\n- CRITICAL: Each file must appear in EXACTLY ONE commit - no duplicates across commits!\n\nCRITICAL: FILE TYPE SHORTCUTS (check FIRST, before other rules):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n🚫 STOP! Check file extensions in DIFF BEFORE asking questions below:\n\n📝 ALL files in diff are *.md or *.mdx? → Type: docs (SKIP all questions below!)\n🧪 ALL files in diff are test/, __tests__/, *.test.ts, *.spec.ts? → Type: test\n❌ If ANY file has code (.ts, .js, .tsx, .jsx, .py, etc.) → Continue to questions below\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nCRITICAL COMMIT TYPE CLASSIFICATION (same as Phase 1):\nFor EACH commit, answer these questions using the DIFF content:\n\n1. Does this change add NEW USER-VISIBLE BEHAVIOR?\n - Look at the diff: is there a new API, feature, or capability?\n - Check IsNewFile: false = likely refactor, true = might be feat\n → YES = feat\n\n2. Does this change fix BROKEN functionality?\n - Look for bug fixes, error handling corrections\n → YES = fix\n\n3. Is this ONLY INTERNAL restructuring?\n - Renaming, extracting functions, reorganizing code?\n - IsNewFile: false with balanced +/- = refactor\n → YES = refactor\n\nDEFAULT BIAS: When uncertain between feat and refactor, choose refactor!\n\nRules:\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!! RULE 0 (HIGHEST PRIORITY - OVERRIDES ALL OTHER RULES): !!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!\n!!! IF a file has \"IsNewFile: false\" in its metadata, IT IS A MODIFIED FILE.\n!!! Modified files CANNOT be feat UNLESS they add ENTIRELY NEW user-facing APIs.\n!!!\n!!! BEFORE classifying ANY commit as \"feat\", CHECK ALL files' IsNewFile flags:\n!!! - If ANY file has IsNewFile: false → START with refactor/fix/chore\n!!! - If ALL files have IsNewFile: true → MIGHT be feat (check diff content)\n!!!\n!!! EXAMPLES OF MODIFIED FILES (IsNewFile: false) → NOT FEAT:\n!!! ❌ WRONG: Modified file adds new function → feat\n!!! ✅ RIGHT: Modified file adds new function → refactor\n!!!\n!!! ❌ WRONG: Modified file adds new class → feat\n!!! ✅ RIGHT: Modified file adds new class → refactor\n!!!\n!!! ❌ WRONG: Modified file adds new CLI command → feat\n!!! ✅ RIGHT: Modified file adds new CLI command → refactor\n!!!\n!!! ONLY USE FEAT for modified files if:\n!!! - Diff shows COMPLETELY NEW public API endpoint (e.g., POST /api/new-resource)\n!!! - Diff shows COMPLETELY NEW product feature visible to end users\n!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n1. Use conventional commits: feat, fix, refactor, chore, docs, test, build, ci, perf\n2. Group related files - number of commits should scale with file count (see grouping rules above)\n3. Each commit MUST include \"reasoning\" field based on actual diff content\n4. Message should be lowercase, imperative mood, no period at end\n5. breaking: true only for breaking API changes\n6. Add \"body\" with bullet points explaining the actual changes you see in the diff\n7. Scope should reflect the affected area (e.g., \"cli\", \"api\"), not individual files\n8. CRITICAL: If ALL files in a commit are being DELETED (only deletions in diff), use type \"chore\" or \"refactor\", NOT \"feat\"\n9. CRITICAL: If a commit is mostly deletions (>80% of lines are deletions), use \"refactor\" or \"chore\", NOT \"feat\"\n\n10. CRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (look at diff content):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n ❌ BAD (too generic):\n - \"add feature\"\n - \"update files\"\n - \"refactor code\"\n - \"fix bug\"\n - \"improve implementation\"\n\n ✅ GOOD (specific, based on diff):\n - \"add rate limiting middleware with Redis backend\"\n - \"update API client to support pagination parameters\"\n - \"refactor workflow executor to use async/await pattern\"\n - \"fix memory leak in event listener cleanup\"\n - \"improve error handling in authentication flow\"\n\n Guidelines:\n - Read the DIFF to understand WHAT changed\n - Include specific component/module names from diff\n - Mention the technology/pattern if relevant (Redis, JWT, factory pattern)\n - For body: describe concrete changes, not just \"update X file\"\n - Use technical terms that developers will understand\n\n12. CRITICAL: SPECIFIC TYPE DETECTION (check diff content BEFORE defaulting to refactor):\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n 📝 docs: Documentation ONLY (no code logic changes)\n ✅ ALL files in diff are markdown (*.md, *.mdx) → docs (even if IsNewFile: true)\n ✅ Diff shows ONLY markdown content changes\n ✅ README.md, ADR files, API docs, benchmarks docs\n ✅ Files in docs/ or doc/ directory with only markdown\n ❌ NOT docs if diff includes ANY code logic changes\n\n **IMPORTANT**: If ALL files end with .md or .mdx → ALWAYS use docs, NEVER feat!\n\n 🐛 fix: Corrects BROKEN functionality (look for bug-fix patterns in diff)\n ✅ Diff adds try-catch, null checks, validation\n ✅ Diff fixes incorrect calculations or logic errors\n ✅ Diff corrects typos in user-facing strings\n ✅ Commit message/body mentions \"fix\", \"bug\", \"error\", \"crash\"\n ❌ NOT fix if adding new behavior\n\n 🧪 test: Test files ONLY\n ✅ Diff shows files in test/, __tests__/, *.test.ts, *.spec.ts\n ✅ Adding test cases, updating test fixtures\n ❌ NOT test if diff also changes source code\n\n13. IsNewFile flag (see RULE 0 above for detailed logic):\n - IsNewFile: false → refactor/fix/chore/docs/test (NOT feat)\n - IsNewFile: true → might be feat (check diff)\n\nEXACT JSON SCHEMA (copy this structure):\n{\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"refactor\",\n \"scope\": \"workflow\",\n \"message\": \"extract job executor to separate class with dependency injection\",\n \"body\": \"- create JobExecutor class with injectable dependencies\\\\n- move execution logic from runtime to executor\\\\n- add unit tests for isolated executor behavior\",\n \"files\": [\"src/runtime/workflow-runtime.ts\", \"src/executor/job-executor.ts\", \"tests/executor.test.ts\"],\n \"releaseHint\": \"patch\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"Diff shows extraction of JobExecutor class from runtime - improves testability through dependency injection pattern, no user-facing changes\",\n \"confidence\": 0.95\n }\n }\n ]\n}\n\nVALID TYPE VALUES: feat, fix, refactor, chore, docs, test, build, ci, perf\nVALID RELEASEHINT VALUES: none, patch, minor, major\n\nEXAMPLE OUTPUT (based on actual diff content):\n{\n \"commits\": [\n {\n \"id\": \"c1\",\n \"type\": \"refactor\",\n \"scope\": \"cli\",\n \"message\": \"migrate command routing to builder pattern with fluent API\",\n \"body\": \"- replace imperative routing with CommandRouterBuilder\\\\n- add fluent API for route registration (addRoute, withMiddleware)\\\\n- extract plugin discovery to PluginDiscoveryService class\\\\n- update integration tests for new routing pattern\",\n \"files\": [\"src/commands/routing.ts\", \"src/commands/router-builder.ts\", \"src/plugins/discovery-service.ts\", \"tests/integration/routing.test.ts\"],\n \"releaseHint\": \"patch\",\n \"breaking\": false,\n \"reasoning\": {\n \"newBehavior\": false,\n \"fixesBug\": false,\n \"internalOnly\": true,\n \"explanation\": \"IsNewFile: false for routing.ts (modified). Diff shows refactoring to builder pattern - improves code organization and testability without changing CLI behavior\",\n \"confidence\": 0.95\n }\n }\n ]\n}\n\nREAL-WORLD EXAMPLES WITH DIFF CONTEXT (learn from these):\n\nExample 1: Modified files - use diff to determine if feat or refactor\nDiff shows:\n - Renamed variables (oldName → newName)\n - Restructured functions (extract to separate modules)\n - Updated imports and exports\n❌ WRONG: feat(core): add new commit plan logic\n✅ CORRECT: refactor(core): restructure commit plan and prompt generation\nReason: Diff shows reorganization, not new functionality\n\nExample 2: New package - check IsNewFile flags in diff\nAll files show: IsNewFile: true, implements resource broker from scratch\n✅ CORRECT: feat(core-resource-broker): add resource broker for rate limiting\nReason: Genuinely new package with new functionality\n\nExample 3: Moved files - IsNewFile: false despite status \"added\"\nDiff shows: [EXISTING FILE - was modified], same content as before\n✅ CORRECT: refactor(analytics): reorganize analytics package structure\nReason: Files moved/reorganized, not newly created\n\nExample 4: Bug fix in existing files\nDiff shows: Fix null pointer exception, add validation check\n✅ CORRECT: fix(auth): handle null token in authentication middleware\nReason: Fixing broken functionality = fix, not feat\n\nExample 5: Documentation ONLY → docs, NOT chore or feat\nFiles:\n - README.md (modified, +50/-20, IsNewFile: false)\n - docs/API.md (modified, +30/-10, IsNewFile: false)\nDiff shows: Updated markdown content, improved examples, no code changes\n❌ WRONG: chore(docs): update documentation\n❌ WRONG: feat(docs): add documentation\n✅ CORRECT: docs: improve README and API documentation\nReason: ALL files are markdown = docs (regardless of IsNewFile)\n\nExample 5b: NEW documentation files → docs, NOT feat\nFiles:\n - docs/benchmarks/README.md (added, +200/-0, IsNewFile: true)\n - docs/benchmarks/RESULTS.md (added, +100/-0, IsNewFile: true)\nDiff shows: New markdown files with benchmarks documentation\n❌ WRONG: feat(docs): add benchmarks documentation\n✅ CORRECT: docs(benchmarks): add benchmarks documentation\nReason: ALL files are .md = docs type (even if IsNewFile: true)\n\nExample 6: Bug fix with error handling → fix, NOT refactor\nFiles:\n - src/api/auth.ts (modified, +15/-5, IsNewFile: false)\nDiff shows: Added try-catch around token validation, null check before access\n✅ CORRECT: fix(api): handle null token in authentication\nReason: Adds error handling to prevent crash = bug fix\n\nExample 7: Test files ONLY → test, NOT chore\nFiles:\n - tests/auth.test.ts (added, +200/-0, IsNewFile: true)\n - tests/helpers/mock-data.ts (added, +50/-0, IsNewFile: true)\nDiff shows: New test suites for authentication module\n✅ CORRECT: test(auth): add authentication test suite\nReason: Test files only = test type\n`;\n\n/**\n * Build prompt for LLM from file summaries (Phase 1)\n */\nexport function buildPrompt(\n summaries: FileSummary[],\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n\nGenerate commit plan as JSON. If you're unsure about commit type/message from paths alone, set needsMoreContext: true and list files in requestedFiles.`;\n}\n\n/**\n * Build enhanced prompt with pattern analysis hints (Phase 1)\n */\nexport function buildEnhancedPrompt(\n summaries: FileSummary[],\n patternAnalysis: PatternAnalysis,\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n // Add pattern hints if confidence is high\n const patternHint = patternAnalysis.confidence > 0.7\n ? `\\n\\n🎯 PATTERN DETECTED (confidence: ${(patternAnalysis.confidence * 100).toFixed(0)}%):\nPattern type: ${patternAnalysis.patternType}\nSuggested commit type: ${patternAnalysis.suggestedType || 'unknown'}\n\nHints:\n${patternAnalysis.hints.map(h => ` • ${h}`).join('\\n')}\n\n⚠️ IMPORTANT: Consider this pattern analysis when determining commit types!`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n${patternHint}\n\nGenerate commit plan as JSON. If you're unsure about commit type/message from paths alone, set needsMoreContext: true and list files in requestedFiles.`;\n}\n\n/**\n * Build prompt for LLM with diff content (Phase 2 - escalation)\n */\nexport function buildPromptWithDiff(\n summaries: FileSummary[],\n diffs: Map<string, string>,\n recentCommits: string[]\n): string {\n const fileList = summaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const diffContent = Array.from(diffs.entries())\n .map(([path, diff]) => {\n // Find summary for this file to show isNewFile flag\n const summary = summaries.find((s) => s.path === path);\n const isNewLabel = summary?.isNewFile ? ' [NEW FILE - never existed before]' : ' [EXISTING FILE - was modified]';\n\n // Truncate very long diffs\n const truncatedDiff = diff.length > 2000\n ? diff.slice(0, 2000) + '\\n... (truncated)'\n : diff;\n return `### ${path}${isNewLabel}\\n\\`\\`\\`diff\\n${truncatedDiff}\\n\\`\\`\\``;\n })\n .join('\\n\\n');\n\n const styleHint = recentCommits.length > 0\n ? `\\nRecent commit style:\\n${recentCommits.slice(0, 5).map((c) => `- \"${c}\"`).join('\\n')}`\n : '';\n\n return `Files changed:\n${fileList}\n${styleHint}\n\nDiff content for requested files:\n${diffContent}\n\nNow generate accurate commit plan based on the actual changes you see:`;\n}\n\n/**\n * Parsed LLM response with confidence assessment\n */\nexport interface ParsedLLMResponse {\n needsMoreContext: boolean;\n requestedFiles: string[];\n commits: CommitGroup[];\n averageConfidence: number;\n}\n\n/**\n * Clean and extract JSON from LLM response\n * Handles common LLM quirks: markdown blocks, extra text, trailing commas\n */\nfunction cleanJsonResponse(rawResponse: string): string {\n let cleaned = rawResponse.trim();\n\n // Remove markdown code blocks (```json...``` or ```...```)\n cleaned = cleaned.replace(/^```(?:json)?\\s*/i, '');\n cleaned = cleaned.replace(/\\s*```$/i, '');\n cleaned = cleaned.trim();\n\n // Try to find JSON object boundaries if wrapped in text\n const jsonStart = cleaned.indexOf('{');\n const jsonEnd = cleaned.lastIndexOf('}');\n\n if (jsonStart !== -1 && jsonEnd !== -1 && jsonStart < jsonEnd) {\n cleaned = cleaned.substring(jsonStart, jsonEnd + 1);\n }\n\n // Remove trailing commas before closing brackets (common JSON error)\n cleaned = cleaned.replace(/,(\\s*[}\\]])/g, '$1');\n\n return cleaned;\n}\n\n/**\n * Parse LLM response into commit groups with confidence\n */\nexport function parseResponse(\n response: string,\n summaries?: FileSummary[],\n patternAnalysis?: PatternAnalysis\n): ParsedLLMResponse {\n // Step 1: Clean response from markdown and common issues\n const cleaned = cleanJsonResponse(response);\n\n // Step 2: Try to parse JSON\n let parsed: any;\n try {\n parsed = JSON.parse(cleaned);\n } catch (error) {\n // Enhanced error message with cleaned response preview\n const preview = cleaned.substring(0, 300).replace(/\\n/g, ' ');\n throw new Error(\n `Failed to parse LLM response as JSON. ` +\n `Preview: \"${preview}${cleaned.length > 300 ? '...' : ''}\" ` +\n `Error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n // Step 3: Validate structure\n if (!parsed.commits || !Array.isArray(parsed.commits)) {\n throw new Error(\n `LLM response missing \"commits\" array. ` +\n `Got: ${JSON.stringify(parsed).substring(0, 200)}`\n );\n }\n\n // Allow empty commits array ONLY if needsMoreContext is true (escalation to Phase 2)\n if (parsed.commits.length === 0) {\n if (parsed.needsMoreContext) {\n // LLM is requesting escalation to Phase 2 - return early with empty commits\n return {\n needsMoreContext: true,\n requestedFiles: Array.isArray(parsed.requestedFiles) ? parsed.requestedFiles : [],\n commits: [],\n averageConfidence: 0,\n };\n }\n // Empty commits without escalation is an error\n throw new Error('LLM response has empty commits array and needsMoreContext is not set');\n }\n\n // Step 4: Validate and normalize each commit\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Commit validation: checks required fields (type/files/message), normalizes types, validates file arrays, handles edge cases\n const commits = parsed.commits.map((commit: Record<string, unknown>, index: number) => {\n // Validate required fields\n if (!commit.type) {\n throw new Error(`Commit ${index + 1} missing required field \"type\"`);\n }\n if (!commit.files || !Array.isArray(commit.files)) {\n throw new Error(`Commit ${index + 1} missing required field \"files\" array`);\n }\n if (commit.files.length === 0) {\n throw new Error(`Commit ${index + 1} has empty files array`);\n }\n if (!commit.message) {\n throw new Error(`Commit ${index + 1} missing required field \"message\"`);\n }\n\n // Normalize and return\n const type = normalizeType(commit.type as string);\n const files = commit.files as string[];\n\n // Parse reasoning if present\n const reasoning = commit.reasoning as Record<string, unknown> | undefined;\n let parsedReasoning: CommitReasoning | undefined;\n let confidence = 0.5; // default\n\n if (reasoning && typeof reasoning === 'object') {\n // Extract confidence from reasoning if present\n confidence = typeof reasoning.confidence === 'number' ? reasoning.confidence : 0.5;\n\n parsedReasoning = {\n newBehavior: Boolean(reasoning.newBehavior),\n fixesBug: Boolean(reasoning.fixesBug),\n internalOnly: Boolean(reasoning.internalOnly),\n explanation: typeof reasoning.explanation === 'string' ? reasoning.explanation : 'No explanation provided',\n confidence,\n };\n } else {\n // Fallback to old confidence field if no reasoning\n confidence = typeof commit.confidence === 'number' ? commit.confidence : 0.5;\n }\n\n return {\n id: (commit.id as string) || `c${index + 1}`,\n type,\n scope: typeof commit.scope === 'string' ? commit.scope : undefined,\n message: typeof commit.message === 'string' ? commit.message : 'update files',\n body: typeof commit.body === 'string' ? commit.body : undefined,\n files,\n releaseHint: normalizeReleaseHint(commit.releaseHint as string),\n breaking: Boolean(commit.breaking),\n reasoning: parsedReasoning,\n confidence, // keep for internal use\n } satisfies CommitGroup & { confidence: number };\n });\n\n // Step 5: Calculate average confidence\n const totalConfidence = commits.reduce((sum: number, c: { confidence: number }) => sum + (c.confidence ?? 0.5), 0);\n const averageConfidence = commits.length > 0 ? totalConfidence / commits.length : 0;\n\n // Step 6: Post-process - Fix incorrect commit types based on file status and pattern analysis\n const commitsWithFixedTypes = summaries\n ? commits.map((c: CommitGroup & { confidence: number }) => fixCommitType(c, summaries, patternAnalysis))\n : commits;\n\n // Step 7: Extract confidence from commits for the response (CommitGroup doesn't have confidence)\n const commitsWithoutConfidence: CommitGroup[] = commitsWithFixedTypes.map((c: CommitGroup & { confidence: number }) => {\n const { confidence: _, ...commit } = c;\n void _;\n return commit;\n });\n\n return {\n needsMoreContext: Boolean(parsed.needsMoreContext),\n requestedFiles: Array.isArray(parsed.requestedFiles) ? parsed.requestedFiles : [],\n commits: commitsWithoutConfidence,\n averageConfidence,\n };\n}\n\n/**\n * Fix commit type based on file status heuristics and pattern analysis\n * Prevents LLM from marking deletions as 'feat', refactoring as 'feat', etc.\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Type correction logic: checks deletion-only commits, test files, package.json changes, small refactors, and applies pattern-based rules\nfunction fixCommitType<T extends CommitGroup & { confidence: number }>(\n commit: T,\n summaries: FileSummary[],\n patternAnalysis?: PatternAnalysis\n): T {\n // Get summaries for files in this commit\n const commitFiles = commit.files;\n const commitSummaries = summaries.filter((s) => commitFiles.includes(s.path));\n\n if (commitSummaries.length === 0) {\n return commit; // No summaries, can't validate\n }\n\n // Rule 0: Conservative Bias - use reasoning to validate commit type\n // If LLM has low confidence (<0.7) and says feat, double-check with reasoning\n if (commit.type === 'feat' && commit.confidence < 0.7 && commit.reasoning) {\n const { newBehavior, internalOnly, fixesBug } = commit.reasoning;\n\n // If reasoning says \"internalOnly\" but type is \"feat\" → downgrade to refactor\n if (internalOnly && !newBehavior) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. Low confidence + internalOnly → refactor`,\n },\n };\n }\n\n // If reasoning says it fixes a bug but type is \"feat\" → change to fix\n if (fixesBug && !newBehavior) {\n return {\n ...commit,\n type: 'fix' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. Fixes bug → fix`,\n },\n };\n }\n\n // If newBehavior is false but type is feat → downgrade to refactor\n if (!newBehavior) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n reasoning: {\n ...commit.reasoning,\n explanation: `[Conservative bias] ${commit.reasoning.explanation}. No new behavior → refactor`,\n },\n };\n }\n }\n\n // Rule 1: If ALL files are deleted, this is NOT a feat\n const allDeleted = commitSummaries.every((s) => s.status === 'deleted');\n if (allDeleted && commit.type === 'feat') {\n return {\n ...commit,\n type: 'chore' as ConventionalType,\n message: commit.message.replace(/^add /i, 'remove ').replace(/^added /i, 'removed '),\n };\n }\n\n // Rule 2: If mostly deletions (>80% of changes are deletions), likely refactor/chore\n const totalAdditions = commitSummaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDeletions = commitSummaries.reduce((sum, s) => sum + s.deletions, 0);\n const totalChanges = totalAdditions + totalDeletions;\n\n if (totalChanges > 0) {\n const deletionRatio = totalDeletions / totalChanges;\n\n // If >80% deletions and marked as 'feat', downgrade to 'refactor'\n if (deletionRatio > 0.8 && commit.type === 'feat') {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n }\n\n // Rule 3: Pattern cross-check - use pattern detector confidence to override LLM\n // If pattern detector has high confidence (>0.8) and disagrees with LLM, use pattern's suggestion\n if (patternAnalysis && patternAnalysis.confidence > 0.8 && patternAnalysis.suggestedType) {\n const llmType = commit.type;\n const patternType = patternAnalysis.suggestedType;\n\n // Override if there's a mismatch and pattern is confident\n if (llmType !== patternType) {\n return {\n ...commit,\n type: patternType as ConventionalType,\n };\n }\n }\n\n // Rule 4: All modified files with low addition ratio → refactor, NOT feat\n const allModified = commitSummaries.every((s) => s.status === 'modified');\n\n if (allModified && totalChanges > 0 && commit.type === 'feat') {\n const additionRatio = totalAdditions / totalChanges;\n\n // If <40% additions (mostly deletions or renames) → refactor\n if (additionRatio < 0.4) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n\n // If 40-60% additions (balanced changes) → still likely refactor\n // Only keep feat if >60% additions (significant new code)\n if (additionRatio < 0.6) {\n return {\n ...commit,\n type: 'refactor' as ConventionalType,\n };\n }\n }\n\n // Rule 5: New package detection → feat, NOT chore\n // Detect: includes package.json, 10+ new files in same directory\n const hasPackageJson = commitSummaries.some((s) => s.path.endsWith('package.json'));\n\n if (hasPackageJson && commitSummaries.length >= 10) {\n const allAdded = commitSummaries.every((s) => s.status === 'added');\n const allIsNewFile = commitSummaries.every((s) => s.isNewFile === true);\n\n // All files added AND truly new (not moved) → this is a new package\n if (allAdded && allIsNewFile && commit.type === 'chore') {\n return {\n ...commit,\n type: 'feat' as ConventionalType,\n message: commit.message.replace(/^initialize /i, 'add ').replace(/^setup /i, 'add '),\n };\n }\n }\n\n return commit;\n}\n\n/**\n * Normalize commit type to valid conventional type\n */\nfunction normalizeType(type: unknown): ConventionalType {\n const validTypes: ConventionalType[] = [\n 'feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf',\n ];\n\n if (typeof type === 'string') {\n const normalized = type.toLowerCase() as ConventionalType;\n if (validTypes.includes(normalized)) {\n return normalized;\n }\n }\n\n return 'chore';\n}\n\n/**\n * Normalize release hint\n */\nfunction normalizeReleaseHint(hint: unknown): 'none' | 'patch' | 'minor' | 'major' {\n if (typeof hint === 'string') {\n const normalized = hint.toLowerCase();\n if (['none', 'patch', 'minor', 'major'].includes(normalized)) {\n return normalized as 'none' | 'patch' | 'minor' | 'major';\n }\n }\n return 'none';\n}\n","/**\n * Heuristic commit plan generation (fallback when LLM unavailable)\n */\n\n/* eslint-disable sonarjs/no-duplicate-string -- \"package.json\" string used repeatedly for file matching patterns */\n\nimport type { FileSummary, CommitGroup, ConventionalType } from '@kb-labs/commit-contracts';\nimport { dirname, extname, basename } from 'node:path';\n\n/**\n * Generate commit plan using heuristics (no LLM)\n *\n * Enhanced grouping strategy:\n * 1. Package.json changes + related files in same directory\n * 2. Test files paired with their implementation\n * 3. Remaining files grouped by directory + category\n */\nexport function generateHeuristicPlan(summaries: FileSummary[]): CommitGroup[] {\n if (summaries.length === 0) {\n return [];\n }\n\n const commits: CommitGroup[] = [];\n let commitIndex = 1;\n\n // Strategy 1: Group package.json changes with files in same directory\n const { packageGroups, remainingFiles } = groupPackageJsonChanges(summaries);\n\n for (const group of packageGroups) {\n commits.push({\n id: `c${commitIndex++}`,\n type: 'chore',\n scope: inferPackageScope(group.map(f => f.path)),\n message: 'update dependencies',\n files: group.map((f) => f.path),\n releaseHint: 'none',\n breaking: false,\n });\n }\n\n // Strategy 2: Pair test files with their implementation\n const { pairedGroups, unpairedFiles } = pairTestsWithImplementation(remainingFiles);\n\n for (const group of pairedGroups) {\n const implFile = group.find(f => !isTestFile(f.path));\n const type = inferTypeFromChanges(implFile);\n\n commits.push({\n id: `c${commitIndex++}`,\n type,\n scope: inferScope(group.map(f => f.path)),\n message: generateMessage(type, group),\n files: group.map((f) => f.path),\n releaseHint: inferReleaseHint(type, group),\n breaking: false,\n });\n }\n\n // Strategy 3: Group remaining files by category and directory\n const categoryGroups = groupByCategory(unpairedFiles);\n\n for (const [category, files] of categoryGroups) {\n const type = categoryToType(category);\n const scope = inferScope(files.map((f) => f.path));\n\n commits.push({\n id: `c${commitIndex++}`,\n type,\n scope,\n message: generateMessage(type, files),\n files: files.map((f) => f.path),\n releaseHint: inferReleaseHint(type, files),\n breaking: false,\n });\n }\n\n return commits;\n}\n\n/**\n * Group package.json changes with related files in same directory\n */\nfunction groupPackageJsonChanges(summaries: FileSummary[]): {\n packageGroups: FileSummary[][];\n remainingFiles: FileSummary[];\n} {\n const packageFiles = summaries.filter(f => f.path.endsWith('package.json'));\n const otherFiles = summaries.filter(f => !f.path.endsWith('package.json'));\n\n if (packageFiles.length === 0) {\n return { packageGroups: [], remainingFiles: summaries };\n }\n\n const packageGroups: FileSummary[][] = [];\n const claimed = new Set<FileSummary>();\n\n for (const pkgFile of packageFiles) {\n const pkgDir = dirname(pkgFile.path);\n\n // Find files in same directory as package.json\n const related = otherFiles.filter(f => {\n const fileDir = dirname(f.path);\n // Same directory or one level deep\n return fileDir === pkgDir || fileDir.startsWith(pkgDir + '/');\n });\n\n // Limit to config-related files only\n const configRelated = related.filter(f => {\n const name = basename(f.path);\n return (\n name.includes('config') ||\n name.includes('tsconfig') ||\n name.endsWith('.json') ||\n name.startsWith('.')\n );\n });\n\n const group = [pkgFile, ...configRelated];\n packageGroups.push(group);\n\n claimed.add(pkgFile);\n configRelated.forEach(f => claimed.add(f));\n }\n\n const remainingFiles = summaries.filter(f => !claimed.has(f));\n\n return { packageGroups, remainingFiles };\n}\n\n/**\n * Pair test files with their implementation files\n */\nfunction pairTestsWithImplementation(summaries: FileSummary[]): {\n pairedGroups: FileSummary[][];\n unpairedFiles: FileSummary[];\n} {\n const testFiles = summaries.filter(f => isTestFile(f.path));\n const implFiles = summaries.filter(f => !isTestFile(f.path));\n\n const pairedGroups: FileSummary[][] = [];\n const pairedImpls = new Set<FileSummary>();\n const pairedTests = new Set<FileSummary>();\n\n for (const testFile of testFiles) {\n const implPath = getImplementationPath(testFile.path);\n const implFile = implFiles.find(f => f.path === implPath);\n\n if (implFile) {\n pairedGroups.push([implFile, testFile]);\n pairedImpls.add(implFile);\n pairedTests.add(testFile);\n }\n }\n\n const unpairedFiles = [\n ...implFiles.filter(f => !pairedImpls.has(f)),\n ...testFiles.filter(f => !pairedTests.has(f)),\n ];\n\n return { pairedGroups, unpairedFiles };\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(path: string): boolean {\n return (\n path.includes('.test.') ||\n path.includes('.spec.') ||\n path.includes('/__tests__/')\n );\n}\n\n/**\n * Get implementation path from test path\n * Example: src/__tests__/foo.test.ts -> src/foo.ts\n */\nfunction getImplementationPath(testPath: string): string {\n // Remove test suffix\n let implPath = testPath\n .replace(/\\.test\\.(ts|tsx|js|jsx)$/, '.$1')\n .replace(/\\.spec\\.(ts|tsx|js|jsx)$/, '.$1');\n\n // Remove __tests__ directory\n implPath = implPath.replace('/__tests__/', '/');\n\n return implPath;\n}\n\n/**\n * Group files by category (for ungrouped files)\n */\nfunction groupByCategory(summaries: FileSummary[]): Map<string, FileSummary[]> {\n const groups = new Map<string, FileSummary[]>();\n\n for (const summary of summaries) {\n const category = categorizeFile(summary.path);\n const existing = groups.get(category) || [];\n existing.push(summary);\n groups.set(category, existing);\n }\n\n return groups;\n}\n\n/**\n * Infer package scope from paths\n */\nfunction inferPackageScope(paths: string[]): string | undefined {\n const packagePath = paths.find(p => p.endsWith('package.json'));\n if (!packagePath) {return undefined;}\n\n // Extract monorepo package name from path\n // Example: kb-labs-cli/package.json -> kb-labs-cli\n const parts = packagePath.split('/');\n if (parts.length > 1) {\n return parts[parts.length - 2]; // Directory before package.json\n }\n\n return undefined;\n}\n\n/**\n * Infer commit type from file changes (additions vs deletions)\n */\nfunction inferTypeFromChanges(file?: FileSummary): ConventionalType {\n if (!file) {return 'chore';}\n\n const { additions, deletions, status } = file;\n\n // New file -> feat\n if (status === 'added' || (additions > 0 && deletions === 0)) {\n return 'feat';\n }\n\n // Deleted file -> chore\n if (status === 'deleted' || (deletions > 0 && additions === 0)) {\n return 'chore';\n }\n\n // More additions than deletions -> feat\n if (additions > deletions * 2) {\n return 'feat';\n }\n\n // More deletions than additions -> refactor\n if (deletions > additions * 2) {\n return 'refactor';\n }\n\n // Mixed changes -> refactor\n return 'refactor';\n}\n\n/**\n * Categorize file for grouping\n */\nfunction categorizeFile(path: string): string {\n const ext = extname(path);\n const name = basename(path);\n const dir = dirname(path);\n\n // Test files\n if (\n path.includes('.test.') ||\n path.includes('.spec.') ||\n path.includes('__tests__') ||\n dir.includes('/test/') ||\n dir.includes('/tests/')\n ) {\n return 'test';\n }\n\n // Documentation\n if (ext === '.md' || dir.includes('/docs/') || name === 'README.md') {\n return 'docs';\n }\n\n // Config files\n if (\n name.startsWith('.') ||\n name.includes('config') ||\n ['package.json', 'tsconfig.json', 'eslint.config.js'].includes(name)\n ) {\n return 'config';\n }\n\n // CI/CD\n if (dir.includes('.github') || dir.includes('.gitlab') || name.includes('ci')) {\n return 'ci';\n }\n\n // Build related\n if (dir.includes('/build/') || dir.includes('/dist/') || name.includes('build')) {\n return 'build';\n }\n\n // Group by top-level directory\n const topDir = dir.split('/')[0] || 'root';\n return `src:${topDir}`;\n}\n\n/**\n * Map category to conventional commit type\n */\nfunction categoryToType(category: string): ConventionalType {\n if (category === 'test') {return 'test';}\n if (category === 'docs') {return 'docs';}\n if (category === 'config') {return 'chore';}\n if (category === 'ci') {return 'ci';}\n if (category === 'build') {return 'build';}\n return 'chore'; // Default for src:* categories\n}\n\n/**\n * Infer scope from file paths\n */\nfunction inferScope(paths: string[]): string | undefined {\n if (paths.length === 0) {return undefined;}\n\n // Find common directory\n const dirs = paths.map((p) => dirname(p).split('/'));\n const firstDir = dirs[0];\n if (!firstDir) {return undefined;}\n\n if (dirs.length === 1) {\n return firstDir.length > 1 ? firstDir[1] : firstDir[0];\n }\n\n // Find common prefix\n const commonPrefix: string[] = [];\n const minLength = Math.min(...dirs.map((d) => d.length));\n for (let i = 0; i < minLength; i++) {\n const segment = firstDir[i];\n if (segment && dirs.every((d) => d[i] === segment)) {\n commonPrefix.push(segment);\n } else {\n break;\n }\n }\n\n // Use last segment of common prefix as scope\n if (commonPrefix.length > 0) {\n const scope = commonPrefix[commonPrefix.length - 1];\n if (scope && scope !== '.' && scope !== 'src') {\n return scope;\n }\n }\n\n return undefined;\n}\n\n/**\n * Generate commit message\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Message generation logic: checks file statuses (added/deleted/modified), file types (test/docs/config), count pluralization\nfunction generateMessage(type: ConventionalType, files: FileSummary[]): string {\n const count = files.length;\n\n // Check if all additions\n const allAdded = files.every((f) => f.status === 'added');\n const allDeleted = files.every((f) => f.status === 'deleted');\n\n if (type === 'test') {\n if (allAdded) {return `add ${count} test file${count > 1 ? 's' : ''}`;}\n return `update ${count} test file${count > 1 ? 's' : ''}`;\n }\n\n if (type === 'docs') {\n if (allAdded) {return `add documentation`;}\n return `update documentation`;\n }\n\n if (type === 'ci') {\n return `update ci configuration`;\n }\n\n if (type === 'build') {\n return `update build configuration`;\n }\n\n if (type === 'chore') {\n if (files.some((f) => f.path.includes('package.json'))) {\n return `update dependencies`;\n }\n return `update configuration`;\n }\n\n // Default for src files\n if (allAdded) {\n return `add ${count} file${count > 1 ? 's' : ''}`;\n }\n if (allDeleted) {\n return `remove ${count} file${count > 1 ? 's' : ''}`;\n }\n return `update ${count} file${count > 1 ? 's' : ''}`;\n}\n\n/**\n * Infer release hint from type and files\n */\nfunction inferReleaseHint(\n type: ConventionalType,\n _files: FileSummary[]\n): 'none' | 'patch' | 'minor' | 'major' {\n switch (type) {\n case 'feat':\n return 'minor';\n case 'fix':\n return 'patch';\n case 'perf':\n return 'patch';\n case 'refactor':\n return 'patch';\n default:\n return 'none';\n }\n}\n","/**\n * Pattern detection for commit type classification\n * Detects semantic patterns in file changes before LLM analysis\n */\n\nimport type { FileSummary, ConventionalType } from '@kb-labs/commit-contracts';\n\n/**\n * Pattern types detected from file changes\n */\nexport type PatternType =\n | 'new-package' // New package with package.json + many files\n | 'refactor-move' // Bulk file move (added but not new)\n | 'refactor-modify' // Modifications with low addition ratio\n | 'deletions' // Mostly or all deletions\n | 'mixed'; // No clear pattern\n\n/**\n * Result of pattern analysis\n */\nexport interface PatternAnalysis {\n patternType: PatternType;\n confidence: number; // 0.0 - 1.0\n hints: string[]; // Human-readable hints for LLM\n suggestedType: ConventionalType | null; // Suggested commit type\n}\n\n/**\n * Analyze file summaries to detect semantic patterns\n * This runs BEFORE LLM to provide hints and improve accuracy\n */\nexport function analyzePatterns(summaries: FileSummary[]): PatternAnalysis {\n if (summaries.length === 0) {\n return {\n patternType: 'mixed',\n confidence: 0,\n hints: [],\n suggestedType: null,\n };\n }\n\n // Check patterns in priority order (highest confidence first)\n\n // Pattern 1: New package (highest confidence when detected)\n if (isNewPackagePattern(summaries)) {\n const packagePath = summaries.find(s => s.path.endsWith('package.json'))?.path;\n const packageName = packagePath ? extractPackageName(packagePath) : 'unknown';\n\n return {\n patternType: 'new-package',\n confidence: 0.95,\n hints: [\n `New package detected: ${packageName}`,\n `${summaries.length} new files including package.json`,\n 'All files are truly new (isNewFile: true)',\n 'This is a new feature (feat), not chore',\n ],\n suggestedType: 'feat',\n };\n }\n\n // Pattern 2: Bulk move/refactor (high confidence)\n if (isBulkMovePattern(summaries)) {\n const dirs = countUniqueDirs(summaries, 3);\n return {\n patternType: 'refactor-move',\n confidence: 0.90,\n hints: [\n `Bulk move pattern: ${summaries.length} files added`,\n `Files existed before (isNewFile: false)`,\n `Organized into ${dirs} director${dirs === 1 ? 'y' : 'ies'}`,\n 'This is refactoring (reorganization), not new feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // Pattern 3: Refactor modifications (good confidence)\n if (isRefactorModificationPattern(summaries)) {\n const ratio = calculateAdditionRatio(summaries);\n return {\n patternType: 'refactor-modify',\n confidence: 0.85,\n hints: [\n 'All files are modified (not new)',\n `Low addition ratio: ${(ratio * 100).toFixed(0)}%`,\n 'Mostly structural changes or deletions',\n 'This is refactoring, not new feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // Pattern 4: Deletions (handled by existing Rules 1-2)\n const allDeleted = summaries.every(s => s.status === 'deleted');\n if (allDeleted) {\n return {\n patternType: 'deletions',\n confidence: 0.98,\n hints: [\n 'All files are deleted',\n 'This is cleanup (chore), not feature',\n ],\n suggestedType: 'chore',\n };\n }\n\n const totalAdd = summaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDel = summaries.reduce((sum, s) => sum + s.deletions, 0);\n const deletionRatio = totalDel / (totalAdd + totalDel);\n\n if (deletionRatio > 0.8) {\n return {\n patternType: 'deletions',\n confidence: 0.95,\n hints: [\n `Mostly deletions: ${(deletionRatio * 100).toFixed(0)}%`,\n 'This is refactoring or cleanup, not feature',\n ],\n suggestedType: 'refactor',\n };\n }\n\n // No clear pattern\n return {\n patternType: 'mixed',\n confidence: 0,\n hints: [],\n suggestedType: null,\n };\n}\n\n/**\n * Detect new package pattern\n *\n * Criteria:\n * - Includes package.json\n * - 10+ files\n * - All files status === 'added'\n * - All files isNewFile === true\n * - All files in same package directory\n */\nexport function isNewPackagePattern(summaries: FileSummary[]): boolean {\n // Must have package.json\n const hasPackageJson = summaries.some(s => s.path.endsWith('package.json'));\n if (!hasPackageJson) {return false;}\n\n // Must have 10+ files\n if (summaries.length < 10) {return false;}\n\n // All must be added\n const allAdded = summaries.every(s => s.status === 'added');\n if (!allAdded) {return false;}\n\n // All must be truly new (not moved)\n const allIsNewFile = summaries.every(s => s.isNewFile === true);\n if (!allIsNewFile) {return false;}\n\n // All files should be in same package directory\n // Extract package path from package.json location\n const packageJsonPath = summaries.find(s => s.path.endsWith('package.json'))!.path;\n const packageDir = packageJsonPath.split('/').slice(0, -1).join('/');\n\n // At least 80% of files should be in the same package\n const filesInPackage = summaries.filter(s => s.path.startsWith(packageDir + '/'));\n const inPackageRatio = filesInPackage.length / summaries.length;\n\n return inPackageRatio > 0.8;\n}\n\n/**\n * Detect bulk move/refactor pattern\n *\n * Criteria:\n * - 20+ files\n * - All files status === 'added'\n * - >50% have isNewFile === false (existed before)\n * - Organized into <5 directories\n */\nexport function isBulkMovePattern(summaries: FileSummary[]): boolean {\n // Must have 20+ files\n if (summaries.length < 20) {return false;}\n\n // All must be added\n const allAdded = summaries.every(s => s.status === 'added');\n if (!allAdded) {return false;}\n\n // >50% must be \"not new\" (moved from elsewhere)\n const notNewCount = summaries.filter(s => s.isNewFile === false).length;\n const notNewRatio = notNewCount / summaries.length;\n if (notNewRatio <= 0.5) {return false;}\n\n // Files should be organized into <5 directories (depth 3)\n const uniqueDirs = countUniqueDirs(summaries, 3);\n return uniqueDirs < 5;\n}\n\n/**\n * Detect refactor modification pattern\n *\n * Criteria:\n * - All files status === 'modified'\n * - Addition ratio < 0.4 (mostly deletions or renames)\n */\nexport function isRefactorModificationPattern(summaries: FileSummary[]): boolean {\n // All must be modified\n const allModified = summaries.every(s => s.status === 'modified');\n if (!allModified) {return false;}\n\n // Addition ratio must be low\n const additionRatio = calculateAdditionRatio(summaries);\n return additionRatio < 0.4;\n}\n\n/**\n * Count unique directories at given depth\n *\n * @param summaries - File summaries\n * @param depth - Directory depth (1 = top level, 2 = one level down, etc.)\n * @returns Number of unique directories\n *\n * @example\n * paths: ['packages/foo/src/a.ts', 'packages/foo/src/b.ts', 'packages/bar/src/c.ts']\n * depth 1: 1 (packages)\n * depth 2: 2 (packages/foo, packages/bar)\n * depth 3: 3 (packages/foo/src, packages/bar/src, packages/foo/src)\n */\nexport function countUniqueDirs(summaries: FileSummary[], depth: number): number {\n const dirs = new Set<string>();\n\n for (const summary of summaries) {\n const parts = summary.path.split('/');\n if (parts.length >= depth) {\n const dirPath = parts.slice(0, depth).join('/');\n dirs.add(dirPath);\n }\n }\n\n return dirs.size;\n}\n\n/**\n * Calculate addition ratio (additions / total changes)\n *\n * @param summaries - File summaries\n * @returns Ratio 0.0 - 1.0 (0 = all deletions, 1 = all additions)\n */\nexport function calculateAdditionRatio(summaries: FileSummary[]): number {\n const totalAdditions = summaries.reduce((sum, s) => sum + s.additions, 0);\n const totalDeletions = summaries.reduce((sum, s) => sum + s.deletions, 0);\n const totalChanges = totalAdditions + totalDeletions;\n\n if (totalChanges === 0) {return 0;}\n\n return totalAdditions / totalChanges;\n}\n\n/**\n * Extract package name from package.json path\n *\n * @param path - Path to package.json\n * @returns Package name (e.g., \"core-resource-broker\" from \"packages/core-resource-broker/package.json\")\n */\nfunction extractPackageName(path: string): string {\n const parts = path.split('/');\n const packageJsonIndex = parts.indexOf('package.json');\n\n if (packageJsonIndex > 0) {\n const packageName = parts[packageJsonIndex - 1];\n return packageName ?? 'unknown';\n }\n\n return 'unknown';\n}\n","/**\n * Secrets detection module\n * Detects files that likely contain secrets and should not be sent to LLM\n */\n\nimport { minimatch } from \"minimatch\";\n\n/**\n * Custom error class for secrets detection\n * This error should NEVER be caught and fallback to heuristics\n */\nexport class SecretsDetectedError extends Error {\n public readonly secretMatches: SecretMatch[];\n\n constructor(matches: SecretMatch[], message: string) {\n super(message);\n this.name = 'SecretsDetectedError';\n this.secretMatches = matches;\n\n // Maintain proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, SecretsDetectedError);\n }\n }\n}\n\n/**\n * Detailed information about a detected secret\n */\nexport interface SecretMatch {\n file: string;\n line: number;\n column: number;\n pattern: string; // Which pattern matched\n patternName: string; // Human-readable pattern name\n snippet: string; // Code snippet (with context)\n matchedText: string; // The actual matched text (truncated if long)\n}\n\n/**\n * File patterns that likely contain secrets\n * Based on common secret file conventions\n */\nconst SECRET_FILE_PATTERNS = [\n // Environment files\n \".env\",\n \".env.*\",\n \"*.env\",\n \".envrc\",\n\n // NPM/Node\n \".npmrc\",\n \".yarnrc\",\n \".yarnrc.yml\",\n\n // SSH/GPG keys\n \"*.key\",\n \"*.pem\",\n \"*.p12\",\n \"*.pfx\",\n \"id_rsa\",\n \"id_dsa\",\n \"id_ecdsa\",\n \"id_ed25519\",\n \"*.pub\",\n\n // AWS\n \".aws/**\",\n \"credentials\",\n\n // Docker\n \".docker/config.json\",\n\n // Git credentials\n \".git-credentials\",\n \".netrc\",\n\n // Service account files\n \"*-service-account.json\",\n \"*-serviceaccount.json\",\n \"service-account*.json\",\n \"serviceaccount*.json\",\n\n // Kubernetes\n \"kubeconfig\",\n \"*.kubeconfig\",\n\n // Terraform\n \"*.tfvars\",\n \"terraform.tfstate\",\n \"terraform.tfstate.backup\",\n\n // Other common secrets\n \"secrets.yml\",\n \"secrets.yaml\",\n \"secret.yml\",\n \"secret.yaml\",\n \"passwords.txt\",\n \"password.txt\",\n];\n\n/**\n * Content patterns that indicate secrets (with human-readable names)\n */\nconst SECRET_CONTENT_PATTERNS: Array<{ pattern: RegExp; name: string }> = [\n // API keys/tokens\n { pattern: /api[_-]?key[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'API Key' },\n { pattern: /auth[_-]?token[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'Auth Token' },\n { pattern: /access[_-]?token[s]?['\":\\s]*[a-zA-Z0-9_-]{20,}/i, name: 'Access Token' },\n\n // AWS\n { pattern: /AKIA[0-9A-Z]{16}/, name: 'AWS Access Key ID' },\n { pattern: /aws[_-]?secret[_-]?access[_-]?key/i, name: 'AWS Secret Access Key' },\n\n // NPM\n { pattern: /\\/\\/registry\\.npmjs\\.org\\/:_authToken=/, name: 'NPM Auth Token' },\n { pattern: /npm_[A-Za-z0-9]{30,}/, name: 'NPM Token' },\n\n // GitHub\n { pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/, name: 'GitHub Token' },\n\n // Slack\n { pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[A-Za-z0-9]{24,}/, name: 'Slack Token' },\n\n // Private keys\n { pattern: /-----BEGIN (RSA|DSA|EC|OPENSSH|PGP) PRIVATE KEY-----/, name: 'Private Key' },\n\n // Passwords\n { pattern: /password['\":\\s]*['\"]/i, name: 'Password' },\n\n // Generic patterns\n { pattern: /secret['\":\\s]*['\"]/i, name: 'Secret' },\n];\n\n/**\n * Check if file path matches secret file patterns\n */\nexport function isSecretFile(filePath: string): boolean {\n // Normalize path separators\n const normalizedPath = filePath.replace(/\\\\/g, \"/\");\n\n return SECRET_FILE_PATTERNS.some((pattern) =>\n minimatch(normalizedPath, pattern, { matchBase: true }),\n );\n}\n\n/**\n * Check if file content contains secret patterns\n */\nexport function containsSecrets(content: string): boolean {\n return SECRET_CONTENT_PATTERNS.some(({ pattern }) => pattern.test(content));\n}\n\n/**\n * Scan files for potential secrets\n * Returns list of files that likely contain secrets\n */\nexport function detectSecretFiles(files: string[]): string[] {\n return files.filter(isSecretFile);\n}\n\n/**\n * Scan file diffs for secrets\n * Returns map of files that contain secrets\n */\nexport function detectSecretsInDiffs(\n diffs: Map<string, string>,\n): Map<string, string> {\n const secretDiffs = new Map<string, string>();\n\n for (const [file, diff] of diffs.entries()) {\n if (containsSecrets(diff)) {\n secretDiffs.set(file, diff);\n }\n }\n\n return secretDiffs;\n}\n\n/**\n * Create error message for detected secrets\n */\nexport function formatSecretsWarning(secretFiles: string[]): string {\n const count = secretFiles.length;\n const filesList = secretFiles.map((f) => ` - ${f}`).join(\"\\n\");\n\n return [\n `🚨 CRITICAL SECURITY ERROR: Detected ${count} file(s) with potential secrets:`,\n filesList,\n \"\",\n \"⛔️ COMMIT GENERATION ABORTED\",\n \"\",\n \"These files contain sensitive data (API keys, tokens, credentials)\",\n \"that MUST NOT be committed to git or sent to LLM.\",\n \"\",\n \"✅ Actions to fix:\",\n \" 1. Add these files to .gitignore\",\n \" 2. Remove secrets from the files (use environment variables instead)\",\n \" 3. If already committed, use git filter-branch or BFG to remove from history\",\n \"\",\n \"⚠️ If you already ran commit:generate before, the secrets may have been\",\n \"sent to OpenAI. Rotate your credentials immediately.\",\n ].join(\"\\n\");\n}\n\n/**\n * Detect secrets in file diffs with exact location information\n * Returns array of SecretMatch with file, line, column, pattern info\n */\nexport function detectSecretsWithLocation(\n diffs: Map<string, string>,\n): SecretMatch[] {\n const matches: SecretMatch[] = [];\n\n for (const [file, diff] of diffs.entries()) {\n const lines = diff.split('\\n');\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex] ?? '';\n\n for (const { pattern, name } of SECRET_CONTENT_PATTERNS) {\n // Reset regex lastIndex for global patterns\n pattern.lastIndex = 0;\n\n const match = pattern.exec(line);\n if (match) {\n const matchedText = match[0];\n const column = match.index;\n\n // Create snippet with context (20 chars before, full match, 20 chars after)\n const snippetStart = Math.max(0, column - 20);\n const snippetEnd = Math.min(line.length, column + matchedText.length + 20);\n const snippet = line.substring(snippetStart, snippetEnd);\n\n // Truncate matched text if very long (max 50 chars)\n const displayText = matchedText.length > 50\n ? matchedText.substring(0, 50) + '...'\n : matchedText;\n\n matches.push({\n file,\n line: lineIndex + 1, // 1-based line numbers\n column: column + 1, // 1-based column numbers\n pattern: pattern.source,\n patternName: name,\n snippet: snippet.trim(),\n matchedText: displayText,\n });\n }\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Format detailed secrets report with locations\n */\nexport function formatSecretsReport(matches: SecretMatch[]): string {\n const count = matches.length;\n const fileCount = new Set(matches.map(m => m.file)).size;\n\n const lines = [\n `🚨 CRITICAL SECURITY ERROR: Detected ${count} potential secret(s) in ${fileCount} file(s)`,\n \"\",\n \"⛔️ COMMIT GENERATION BLOCKED\",\n \"\",\n ];\n\n // Group by file\n const byFile = new Map<string, SecretMatch[]>();\n for (const match of matches) {\n const existing = byFile.get(match.file) ?? [];\n existing.push(match);\n byFile.set(match.file, existing);\n }\n\n // Format each file's matches\n for (const [file, fileMatches] of byFile.entries()) {\n lines.push(`📄 ${file}:`);\n for (const match of fileMatches) {\n lines.push(` Line ${match.line}:${match.column} - ${match.patternName}`);\n lines.push(` Pattern: ${match.pattern.substring(0, 60)}${match.pattern.length > 60 ? '...' : ''}`);\n lines.push(` Matched: ${match.matchedText}`);\n lines.push(` Context: ...${match.snippet}...`);\n lines.push('');\n }\n }\n\n lines.push(\n \"🔒 These files contain sensitive data (API keys, tokens, credentials)\",\n \"that MUST NOT be committed to git or sent to LLM.\",\n \"\",\n \"✅ Actions to fix:\",\n \" 1. Review each match above - some may be false positives (e.g., examples in comments)\",\n \" 2. If real secrets: Add files to .gitignore and remove secrets (use env vars)\",\n \" 3. If false positives: Use --allow-secrets flag to proceed with confirmation\",\n \"\",\n \"⚠️ If secrets were already sent to LLM in previous runs, rotate credentials immediately!\",\n );\n\n return lines.join(\"\\n\");\n}\n","/**\n * User confirmation prompt utilities\n */\n\nimport * as readline from 'node:readline';\n\n/**\n * Prompt user for yes/no confirmation\n *\n * @param question - Question to ask\n * @param defaultValue - Default value if user just presses Enter\n * @param autoConfirm - If true, automatically return true without prompting (for --yes flag)\n * @returns Promise resolving to true if user confirms, false otherwise\n */\nexport async function promptUserConfirmation(\n question: string,\n defaultValue: boolean = false,\n autoConfirm: boolean = false\n): Promise<boolean> {\n // Auto-confirm mode (--yes flag)\n if (autoConfirm) {\n console.log(`${question} [auto-confirmed with --yes]`);\n return true;\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const defaultHint = defaultValue ? '[Y/n]' : '[y/N]';\n const fullQuestion = `${question} ${defaultHint}: `;\n\n return new Promise((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n\n const normalized = answer.trim().toLowerCase();\n\n if (normalized === '') {\n resolve(defaultValue);\n return;\n }\n\n if (normalized === 'y' || normalized === 'yes') {\n resolve(true);\n return;\n }\n\n if (normalized === 'n' || normalized === 'no') {\n resolve(false);\n return;\n }\n\n // Invalid input - use default\n resolve(defaultValue);\n });\n });\n}\n","/**\n * Main commit plan generator\n */\n\n/* eslint-disable no-await-in-loop -- Sequential LLM calls and git operations required for commit plan generation phases */\n\nimport type { CommitPlan, GitStatus, FileSummary, CommitGroup } from '@kb-labs/commit-contracts';\nimport type { GenerateOptions } from '../types';\nimport { useLogger, useAnalytics, useLLM, type LLMMessage } from '@kb-labs/sdk';\nimport { COMMIT_PLAN_TOOL, COMMIT_PLAN_TOOL_PHASE3 } from './commit-tools';\nimport { getGitStatus, getAllChangedFiles } from '../analyzer/git-status';\nimport { getFileSummaries, getFileDiffs } from '../analyzer/file-summary';\nimport { getRecentCommits } from '../analyzer/recent-commits';\nimport {\n buildPromptWithDiff,\n buildEnhancedPrompt,\n parseResponse,\n SYSTEM_PROMPT,\n SYSTEM_PROMPT_WITH_DIFF,\n type ParsedLLMResponse,\n} from './llm-prompt';\nimport { generateHeuristicPlan } from './heuristics';\nimport { analyzePatterns, type PatternAnalysis } from './pattern-detector';\nimport {\n detectSecretFiles,\n detectSecretsWithLocation,\n formatSecretsWarning,\n formatSecretsReport,\n SecretsDetectedError,\n type SecretMatch,\n} from '../analyzer/secrets-detector';\nimport { promptUserConfirmation } from '../utils/prompt';\n\n/** Confidence threshold - below this we escalate to Phase 2 with diff */\nconst CONFIDENCE_THRESHOLD = 0.7;\n\n/** Maximum retry attempts for LLM generation (both phases) */\nconst MAX_LLM_RETRIES = 2;\nconst VALID_COMMIT_TYPES = new Set(['feat', 'fix', 'refactor', 'chore', 'docs', 'test', 'build', 'ci', 'perf']);\n\nfunction normalizeCommitId(id: string | undefined): string | undefined {\n if (!id) { return undefined; }\n const trimmed = id.trim();\n if (!trimmed) { return undefined; }\n\n if (/^c\\d+$/i.test(trimmed)) {\n return `c${trimmed.replace(/^c/i, '')}`;\n }\n\n if (/^\\d+$/.test(trimmed)) {\n return `c${trimmed}`;\n }\n\n return trimmed;\n}\n\nfunction buildFallbackMessage(files: string[]): string {\n const firstFile = files[0];\n const fileName = firstFile ? firstFile.split('/').pop() ?? firstFile : 'files';\n return files.length === 1 ? `update ${fileName}` : `update ${files.length} files`;\n}\n\nfunction toSafeCommitGroup(\n commit: Partial<CommitGroup> & { files?: string[] },\n id: string\n): CommitGroup | null {\n const files = Array.isArray(commit.files)\n ? commit.files.filter((file): file is string => typeof file === 'string' && file.length > 0)\n : [];\n if (files.length === 0) {\n return null;\n }\n\n const uniqueFiles = [...new Set(files)];\n const type = typeof commit.type === 'string' && VALID_COMMIT_TYPES.has(commit.type)\n ? commit.type\n : 'chore';\n const message = typeof commit.message === 'string' && commit.message.trim().length > 0\n ? commit.message.trim()\n : buildFallbackMessage(uniqueFiles);\n const releaseHint = commit.releaseHint\n ?? (type === 'feat' ? 'minor' : (type === 'fix' || type === 'refactor' ? 'patch' : 'none'));\n\n return {\n id,\n type,\n scope: commit.scope,\n message,\n body: commit.body,\n files: uniqueFiles,\n releaseHint,\n breaking: Boolean(commit.breaking),\n reasoning: commit.reasoning ?? {\n newBehavior: false,\n fixesBug: false,\n internalOnly: true,\n explanation: 'Generated from Phase 3 fallback due invalid or incomplete LLM commit action.',\n confidence: 0.3,\n },\n };\n}\n\n/**\n * Generate a commit plan from current git changes\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Main orchestrator: scope resolution, git status, file analysis, LLM phases (1 & 2), validation, retry logic, heuristics, anti-hallucination checks\nexport async function generateCommitPlan(options: GenerateOptions): Promise<CommitPlan> {\n const { cwd, onProgress } = options;\n\n const logger = useLogger();\n const analytics = useAnalytics();\n const llm = useLLM();\n const startTime = Date.now();\n\n // 1. Get git status — cwd is already the resolved scope directory\n const gitStatus = await getGitStatus(cwd);\n const allFiles = getAllChangedFiles(gitStatus);\n\n if (allFiles.length === 0) {\n return createEmptyPlan(cwd, gitStatus);\n }\n\n // 3. 🔒 Security: Check for secret files early - ABORT if found!\n const secretFiles = detectSecretFiles(allFiles);\n\n if (secretFiles.length > 0) {\n // Create basic matches for secret files (no location info yet - just filenames)\n const basicMatches: SecretMatch[] = secretFiles.map(file => ({\n file,\n line: 0,\n column: 0,\n pattern: 'SECRET_FILE_PATTERN',\n patternName: 'Secret File Pattern',\n snippet: '',\n matchedText: file,\n }));\n\n const warning = formatSecretsWarning(secretFiles);\n await logger.error('🚨 SECRETS DETECTED', new Error('Secrets detected'), {\n secretFiles,\n });\n console.error('\\n' + warning + '\\n');\n\n // Check if --allow-secrets flag is set\n if (!options.allowSecrets) {\n // No bypass flag - ABORT immediately\n throw new SecretsDetectedError(\n basicMatches,\n `Secrets detected in ${secretFiles.length} file(s). Use --allow-secrets to bypass after review, or add files to .gitignore.`\n );\n }\n\n // --allow-secrets flag is set - ask for user confirmation\n console.log('\\n⚠️ WARNING: --allow-secrets flag detected\\n');\n options.onPauseProgress?.();\n const confirmed = await promptUserConfirmation(\n `⚠️ Proceed with committing ${secretFiles.length} file(s) that may contain secrets?`,\n false, // default: NO\n options.autoConfirm\n );\n options.onResumeProgress?.();\n\n if (!confirmed) {\n // User declined - ABORT\n throw new SecretsDetectedError(\n basicMatches,\n 'User declined to commit files with potential secrets.'\n );\n }\n\n // User confirmed - log warning and continue\n await logger.warn('User confirmed to proceed with files containing potential secrets', {\n secretFiles,\n confirmedAt: new Date().toISOString(),\n });\n console.log('✅ User confirmed - continuing with commit generation...\\n');\n }\n\n // 4. Get file summaries (diff stats)\n const summaries = await getFileSummaries(cwd, allFiles);\n\n // 5. Analyze patterns BEFORE LLM (pre-processing)\n const patternAnalysis = analyzePatterns(summaries);\n\n // Track pattern detection\n if (patternAnalysis.confidence > 0.7) {\n await analytics?.track('commit.pattern-detected', {\n patternType: patternAnalysis.patternType,\n confidence: patternAnalysis.confidence,\n suggestedType: patternAnalysis.suggestedType,\n fileCount: summaries.length,\n hints: patternAnalysis.hints,\n });\n\n // Log pattern detection for debugging\n await logger.debug(`Pattern detected: ${patternAnalysis.patternType} (confidence: ${patternAnalysis.confidence.toFixed(2)})`, {\n suggestedType: patternAnalysis.suggestedType,\n hints: patternAnalysis.hints,\n });\n }\n\n // 6. Get recent commits for style reference\n const recentCommits = options.recentCommits ?? await getRecentCommits(cwd, 10);\n\n // 7. Generate plan using LLM (two-phase) or heuristics\n let commits: CommitGroup[];\n let llmUsed = false;\n let tokensUsed: number | undefined;\n let escalated = false;\n\n if (llm) {\n try {\n // Check if LLM supports native tools (chatWithTools)\n const supportsNativeTools = typeof llm.chatWithTools === 'function';\n\n let parsed: ParsedLLMResponse;\n\n if (supportsNativeTools) {\n // NEW: Use native tools approach (guaranteed structured output)\n await logger.debug('Using native tools approach (chatWithTools)');\n onProgress?.('Analyzing with native tools...');\n\n const result = await generateWithNativeTools(\n llm,\n summaries,\n patternAnalysis,\n recentCommits,\n logger,\n onProgress\n );\n\n parsed = result.parsed;\n tokensUsed = result.tokensUsed;\n llmUsed = true;\n } else {\n // FALLBACK: Text-based parsing for LLMs without chatWithTools support\n await logger.debug('Using text-based parsing (fallback)');\n onProgress?.('Analyzing with text-based LLM...');\n\n const prompt = buildEnhancedPrompt(summaries, patternAnalysis, recentCommits);\n\n const result = await retryLLMCall(\n () => llm.complete(prompt, {\n systemPrompt: SYSTEM_PROMPT,\n temperature: 0.3,\n maxTokens: 2000,\n }),\n 'Phase 1',\n logger,\n onProgress\n );\n\n parsed = parseResponse(result.content, summaries, patternAnalysis);\n llmUsed = true;\n tokensUsed = result.tokensUsed;\n }\n\n // Phase 2: Escalate if LLM requests more context, confidence is low, or 10+ files\n const shouldEscalate = parsed.needsMoreContext\n || parsed.averageConfidence < CONFIDENCE_THRESHOLD\n || summaries.length >= 10;\n\n if (shouldEscalate) {\n const reason = summaries.length >= 10\n ? `${summaries.length} files (≥10)`\n : `confidence ${(parsed.averageConfidence * 100).toFixed(0)}%`;\n await logger.debug(`Escalating to Phase 2: ${reason}`, {\n fileCount: summaries.length,\n confidence: parsed.averageConfidence,\n needsMoreContext: parsed.needsMoreContext,\n requestedFiles: parsed.requestedFiles,\n });\n onProgress?.(`${reason} - fetching diff...`);\n\n // Get diff for requested files with smart selection\n // 1. If LLM specified files, use them (max 15)\n // 2. If empty/none specified, auto-select top 15 most changed files\n let filesToDiff: string[];\n\n if (parsed.requestedFiles.length > 0) {\n // LLM requested specific files - validate they exist and limit to 15\n const validFiles = parsed.requestedFiles.filter((f) => summaries.some((s) => s.path === f));\n filesToDiff = validFiles.slice(0, 15); // Truncate to max 15\n\n if (validFiles.length > 15) {\n await logger.warn(`LLM requested ${validFiles.length} files, truncated to 15 most critical`, {\n requestedCount: validFiles.length,\n truncatedCount: 15,\n });\n }\n } else {\n // No files specified - auto-select top 15 by change size\n const sortedByChanges = [...summaries].sort((a, b) => {\n const aChanges = (a.additions ?? 0) + (a.deletions ?? 0);\n const bChanges = (b.additions ?? 0) + (b.deletions ?? 0);\n return bChanges - aChanges; // Descending order\n });\n\n filesToDiff = sortedByChanges.slice(0, 15).map((s) => s.path);\n\n await logger.debug('Auto-selected top 15 most changed files for Phase 2', {\n totalFiles: summaries.length,\n selectedCount: filesToDiff.length,\n });\n }\n\n const diffs = await getFileDiffs(cwd, filesToDiff);\n\n // 🔒 Security: Check for secrets in diffs with EXACT LOCATION\n const secretMatches = detectSecretsWithLocation(diffs);\n\n if (secretMatches.length > 0) {\n // Found secrets in diff content with exact locations\n const report = formatSecretsReport(secretMatches);\n await logger.error('🚨 SECRETS DETECTED IN DIFF CONTENT', new Error('Secrets in diff'), {\n secretMatches,\n });\n onProgress?.('🚨 Secrets detected in diff');\n\n // Show detailed report to user\n console.error('\\n' + report + '\\n');\n\n // Check if --allow-secrets flag is set\n if (!options.allowSecrets) {\n // No bypass flag - ABORT immediately\n throw new SecretsDetectedError(\n secretMatches,\n `Secrets detected in ${secretMatches.length} location(s). Use --allow-secrets to bypass after review, or remove secrets before committing.`\n );\n }\n\n // --allow-secrets flag is set - ask for user confirmation (or auto-confirm with --yes)\n console.log('\\n⚠️ WARNING: --allow-secrets flag detected\\n');\n options.onPauseProgress?.();\n const confirmed = await promptUserConfirmation(\n `⚠️ Proceed with committing changes that contain ${secretMatches.length} potential secret(s)?`,\n false, // default: NO\n options.autoConfirm // auto-confirm if --yes flag\n );\n options.onResumeProgress?.();\n\n if (!confirmed) {\n // User declined - ABORT\n throw new SecretsDetectedError(\n secretMatches,\n 'User declined to commit changes with potential secrets.'\n );\n }\n\n // User confirmed - log warning and continue\n await logger.warn('User confirmed to proceed with diff containing potential secrets', {\n secretMatches: secretMatches.map(m => ({ file: m.file, line: m.line, pattern: m.patternName })),\n confirmedAt: new Date().toISOString(),\n });\n console.log('✅ User confirmed - continuing with Phase 2 analysis...\\n');\n onProgress?.('Re-analyzing with diff context (Phase 2)...');\n }\n\n if (diffs.size > 0) {\n // Phase 2: Re-generate with diff context\n // Scale maxTokens with file count: more files = more commits = more tokens needed\n const maxTokensPhase2 = Math.min(6000, 3000 + Math.floor(summaries.length / 20) * 500);\n\n await logger.debug('Re-analyzing with diff context (Phase 2)', {\n filesWithDiff: filesToDiff.length,\n supportsNativeTools,\n });\n onProgress?.('Re-analyzing with diff context (Phase 2)...');\n\n if (supportsNativeTools) {\n // Phase 2 with native tools\n const resultWithDiff = await generateWithNativeToolsPhase2(\n llm,\n summaries,\n diffs,\n recentCommits,\n logger,\n onProgress\n );\n\n parsed = resultWithDiff.parsed;\n tokensUsed = (tokensUsed ?? 0) + (resultWithDiff.tokensUsed ?? 0);\n escalated = true;\n } else {\n // Phase 2 with text-based parsing (fallback)\n const promptWithDiff = buildPromptWithDiff(summaries, diffs, recentCommits);\n\n const resultWithDiff = await retryLLMCall(\n () => llm.complete(promptWithDiff, {\n systemPrompt: SYSTEM_PROMPT_WITH_DIFF,\n temperature: 0.3,\n maxTokens: maxTokensPhase2,\n }),\n 'Phase 2',\n logger,\n onProgress\n );\n\n parsed = parseResponse(resultWithDiff.content, summaries, patternAnalysis);\n tokensUsed = (tokensUsed ?? 0) + (resultWithDiff.tokensUsed ?? 0);\n escalated = true;\n }\n }\n }\n\n commits = parsed.commits;\n\n // Validate that all files from summaries are included (may invoke Phase 3)\n commits = await validateAndFixCommits(commits, summaries, llm, llmUsed, logger, onProgress);\n } catch (error) {\n // CRITICAL: Re-throw SecretsDetectedError immediately - DO NOT fallback to heuristics!\n if (error instanceof SecretsDetectedError) {\n throw error;\n }\n\n // Fallback to heuristics ONLY for LLM errors (parse, timeout, etc.)\n await logger.warn('LLM generation failed after retries, falling back to heuristics', {\n error: error instanceof Error ? error.message : String(error),\n });\n onProgress?.('LLM failed, using heuristics...');\n commits = generateHeuristicPlan(summaries);\n }\n } else {\n commits = generateHeuristicPlan(summaries);\n }\n\n // 6. Track analytics\n const typeDistribution = commits.reduce((acc, commit) => {\n acc[commit.type] = (acc[commit.type] || 0) + 1;\n return acc;\n }, {} as Record<string, number>);\n\n await analytics?.track('commit.generation-complete', {\n totalFiles: summaries.length,\n totalCommits: commits.length,\n llmUsed,\n escalated,\n tokensUsed,\n durationMs: Date.now() - startTime,\n typeDistribution,\n cwd,\n });\n\n // 7. Build final plan\n return {\n schemaVersion: '1.0',\n createdAt: new Date().toISOString(),\n repoRoot: cwd,\n gitStatus,\n commits,\n metadata: {\n totalFiles: summaries.length,\n totalCommits: commits.length,\n llmUsed,\n tokensUsed,\n escalated,\n },\n };\n}\n\n/**\n * Create empty plan when no changes\n */\nfunction createEmptyPlan(cwd: string, gitStatus: GitStatus): CommitPlan {\n return {\n schemaVersion: '1.0',\n createdAt: new Date().toISOString(),\n repoRoot: cwd,\n gitStatus,\n commits: [],\n metadata: {\n totalFiles: 0,\n totalCommits: 0,\n llmUsed: false,\n },\n };\n}\n\n\n/**\n * Generate commits using native tools (chatWithTools) - Phase 1\n * Returns structured output without JSON parsing errors\n */\nasync function generateWithNativeTools(\n llm: ReturnType<typeof useLLM>,\n summaries: FileSummary[],\n patternAnalysis: PatternAnalysis,\n recentCommits: string[],\n logger: ReturnType<typeof useLogger>,\n _onProgress?: (message: string) => void\n): Promise<{ parsed: ParsedLLMResponse; tokensUsed?: number }> {\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM does not support native tools (chatWithTools)');\n }\n\n // Build user prompt (without JSON format instructions)\n const userPrompt = buildEnhancedPrompt(summaries, patternAnalysis, recentCommits);\n\n // Build messages\n // Note: SYSTEM_PROMPT contains JSON format instructions which are automatically\n // ignored by OpenAI when using native tools (tool schema takes precedence)\n const messages: LLMMessage[] = [\n {\n role: 'system',\n content: SYSTEM_PROMPT,\n },\n {\n role: 'user',\n content: userPrompt,\n },\n ];\n\n // Call LLM with native tools\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n // Extract tool call\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool');\n }\n\n // Tool call input is already parsed JSON (no JSON.parse needed!)\n const toolArgs = toolCall.input as {\n needsMoreContext?: boolean;\n requestedFiles?: string[];\n commits: CommitGroup[];\n };\n\n // Calculate average confidence from commits\n const totalConfidence = toolArgs.commits.reduce((sum, c) => {\n const confidence = c.reasoning?.confidence ?? 0.5;\n return sum + confidence;\n }, 0);\n const averageConfidence = toolArgs.commits.length > 0\n ? totalConfidence / toolArgs.commits.length\n : 0;\n\n await logger.debug('Native tools Phase 1 result', {\n needsMoreContext: toolArgs.needsMoreContext,\n requestedFiles: toolArgs.requestedFiles?.length ?? 0,\n commitsCount: toolArgs.commits.length,\n averageConfidence,\n });\n\n return {\n parsed: {\n needsMoreContext: Boolean(toolArgs.needsMoreContext),\n requestedFiles: toolArgs.requestedFiles ?? [],\n commits: toolArgs.commits,\n averageConfidence,\n },\n tokensUsed: response.usage ? (response.usage.promptTokens + response.usage.completionTokens) : undefined,\n };\n}\n\n/**\n * Generate commits for missing files using native tools (Phase 3)\n * Called when LLM forgot to include some files in Phase 1/2\n * May return multiple commits if files should be grouped differently\n */\nasync function generateMissingFilesCommit(\n llm: ReturnType<typeof useLLM>,\n missingSummaries: FileSummary[],\n existingCommits: CommitGroup[],\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<CommitGroup[] | null> {\n if (!llm || !llm.chatWithTools) {\n return null; // Fallback to generic commit if no LLM\n }\n\n // Build context: what commits were already created (with IDs and files for extend_existing action)\n const existingCommitsContext = existingCommits\n .map((c) => {\n const filesPreview = c.files.length <= 3\n ? c.files.join(', ')\n : `${c.files.slice(0, 3).join(', ')} and ${c.files.length - 3} more`;\n return `[${c.id}] ${c.type}${c.scope ? `(${c.scope})` : ''}: ${c.message}\\n Files: ${filesPreview}`;\n })\n .join('\\n\\n');\n\n // Build prompt for missing files\n const missingFilesList = missingSummaries\n .map((s) => {\n const stats = s.binary ? 'binary' : `+${s.additions}/-${s.deletions}`;\n const isNew = s.isNewFile ? 'IsNewFile: true' : 'IsNewFile: false';\n return `- ${s.path} (${s.status}, ${stats}, ${isNew})`;\n })\n .join('\\n');\n\n const systemPrompt = `You are analyzing files that were not included in the initial commit plan.\n\nCONTEXT: These files were not classified by the LLM in previous phases. Your task is to determine:\n1. Why they were missed (config files, minor changes, unrelated changes, etc.)\n2. Whether they belong to an EXISTING commit or need a NEW commit\n3. What type of commit they should be (chore, refactor, fix, feat, docs, test, etc.)\n\nCRITICAL: You have TWO actions available:\n\nACTION 1: extend_existing (PREFER THIS if file is related to existing commit)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nUse when a file logically belongs to an already created commit.\n\nExample: If existing commit is \"feat(fs): add fs adapter\" and you see:\n- packages/adapters-fs/src/secure-storage.test.ts (test for fs adapter)\n\nThen use:\n{\n \"action\": \"extend_existing\",\n \"existingCommitId\": \"c1\",\n \"files\": [\"packages/adapters-fs/src/secure-storage.test.ts\"]\n}\n\nThe file will be added to commit c1 instead of creating a new commit.\n\nACTION 2: create_new (use when file is unrelated to existing commits)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nUse when files don't fit into any existing commit.\n\nDEFAULT to \"chore\" unless you see clear evidence of feat/fix/refactor.\n\nIMPORTANT: These are leftover files - they are usually:\n- Configuration files (package.json, tsconfig.json, etc.)\n- Minor updates to existing files\n- Test files or documentation\n- Build/tooling changes\n\nCRITICAL: WRITE INFORMATIVE COMMIT MESSAGES (not generic):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n❌ BAD (too generic):\n- \"update files\"\n- \"update configuration\"\n- \"update additional files\"\n- \"update 30 files\"\n\n✅ GOOD (specific and descriptive):\n- \"update TypeScript and ESLint configuration for strict mode\"\n- \"update package dependencies for security patches\"\n- \"update build configuration to support ESM modules\"\n\nGuidelines:\n- Include WHAT was changed (specific files/components)\n- Include WHY if relevant (context about the change)\n- Use concrete nouns (not \"files\", \"additional files\")\n- Add context that helps reviewers understand the change`;\n\n const userPrompt = `Existing commits (you can add files to these using extend_existing action):\n${existingCommitsContext}\n\nFiles that need classification (${missingSummaries.length} remaining):\n${missingFilesList}\n\nIMPORTANT: You don't need to classify ALL files in one response if there are too many.\n- If you can confidently classify some files → do it\n- If you're unsure about some files → skip them (they'll be processed in next iteration)\n- Focus on files you can group logically\n\nFor each file, choose the appropriate action:\n1. extend_existing - if file belongs to an existing commit (e.g., test file for fs adapter → add to \"feat(fs): add fs adapter\")\n2. create_new - if file doesn't fit into any existing commit\n\nYou may create:\n- ONE new commit if all remaining files are related (same purpose, same change type)\n- MULTIPLE new commits if files have different purposes (e.g., separate config changes from test updates)\n- MIX of extend_existing and create_new actions (recommended!)\n\nCRITICAL: Be specific in each commit message - describe WHAT is being changed, not just \"update files\".\nPREFER extend_existing when possible to avoid creating unnecessary commits.`;\n\n const messages: LLMMessage[] = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ];\n\n try {\n onProgress?.('Classifying remaining files (Phase 3)...');\n\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL_PHASE3],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n await logger.warn('Phase 3: LLM did not call tool, using fallback');\n return null;\n }\n\n const toolArgs = toolCall.input as {\n commits: Array<CommitGroup & { action?: 'create_new' | 'extend_existing'; existingCommitId?: string }>;\n };\n\n if (!toolArgs.commits || toolArgs.commits.length === 0) {\n await logger.warn('Phase 3: LLM returned empty commits, using fallback');\n return null;\n }\n\n // Process each commit action\n const newCommits: CommitGroup[] = [];\n let extendedCount = 0;\n let createdCount = 0;\n\n for (const commit of toolArgs.commits) {\n if (!Array.isArray(commit.files) || commit.files.length === 0) {\n await logger.warn('Phase 3: Skipping commit action with empty files', {\n action: commit.action,\n existingCommitId: commit.existingCommitId,\n });\n continue;\n }\n\n const action = commit.action || 'create_new'; // Default to create_new for backward compatibility\n\n if (action === 'extend_existing') {\n // Find existing commit by ID\n const normalizedRequestedId = normalizeCommitId(commit.existingCommitId);\n const existingCommit = existingCommits.find(c => normalizeCommitId(c.id) === normalizedRequestedId);\n if (existingCommit) {\n // Add files to existing commit\n existingCommit.files.push(...commit.files);\n extendedCount++;\n await logger.debug('Phase 3: Extended existing commit', {\n commitId: existingCommit.id,\n message: existingCommit.message,\n addedFiles: commit.files.length,\n });\n } else {\n // Fallback: create new commit if ID not found\n await logger.warn('Phase 3: Commit ID not found, creating new instead', {\n requestedId: commit.existingCommitId,\n normalizedRequestedId,\n availableIds: existingCommits.map(c => c.id).slice(0, 10),\n });\n const safeCommit = toSafeCommitGroup(\n commit,\n `c${existingCommits.length + newCommits.length + 1}`\n );\n if (safeCommit) {\n newCommits.push(safeCommit);\n createdCount++;\n } else {\n await logger.warn('Phase 3: Fallback commit had no valid files, skipped', {\n requestedId: commit.existingCommitId,\n });\n }\n }\n } else {\n // action === 'create_new'\n const safeCommit = toSafeCommitGroup(\n commit,\n `c${existingCommits.length + newCommits.length + 1}`\n );\n if (safeCommit) {\n newCommits.push(safeCommit);\n createdCount++;\n } else {\n await logger.warn('Phase 3: create_new action had no valid files, skipped');\n }\n }\n }\n\n await logger.debug('Phase 3: Processed commits', {\n total: toolArgs.commits.length,\n extended: extendedCount,\n created: createdCount,\n newCommitsCount: newCommits.length,\n });\n\n return newCommits;\n } catch (error) {\n await logger.warn('Phase 3 failed, using fallback', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\n/**\n * Generate commits using native tools (chatWithTools) - Phase 2 with diff\n * Returns structured output without JSON parsing errors\n */\nasync function generateWithNativeToolsPhase2(\n llm: ReturnType<typeof useLLM>,\n summaries: FileSummary[],\n diffs: Map<string, string>,\n recentCommits: string[],\n logger: ReturnType<typeof useLogger>,\n _onProgress?: (message: string) => void\n): Promise<{ parsed: ParsedLLMResponse; tokensUsed?: number }> {\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM does not support native tools (chatWithTools)');\n }\n\n // Build user prompt with diff context\n const userPrompt = buildPromptWithDiff(summaries, diffs, recentCommits);\n\n // Build messages\n const messages: LLMMessage[] = [\n {\n role: 'system',\n content: SYSTEM_PROMPT_WITH_DIFF,\n },\n {\n role: 'user',\n content: userPrompt,\n },\n ];\n\n // Call LLM with native tools\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n // Extract tool call\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool in Phase 2');\n }\n\n // Tool call input is already parsed JSON (no JSON.parse needed!)\n const toolArgs = toolCall.input as {\n needsMoreContext?: boolean;\n requestedFiles?: string[];\n commits: CommitGroup[];\n };\n\n // Calculate average confidence from commits\n const totalConfidence = toolArgs.commits.reduce((sum, c) => {\n const confidence = c.reasoning?.confidence ?? 0.5;\n return sum + confidence;\n }, 0);\n const averageConfidence = toolArgs.commits.length > 0\n ? totalConfidence / toolArgs.commits.length\n : 0;\n\n await logger.debug('Native tools Phase 2 result', {\n commitsCount: toolArgs.commits.length,\n averageConfidence,\n });\n\n return {\n parsed: {\n needsMoreContext: false, // Phase 2 is final, no more escalation\n requestedFiles: [],\n commits: toolArgs.commits,\n averageConfidence,\n },\n tokensUsed: response.usage ? (response.usage.promptTokens + response.usage.completionTokens) : undefined,\n };\n}\n\nexport interface ValidationResult {\n commits: CommitGroup[];\n warnings: string[];\n hallucinations: string[];\n}\n\n/**\n * Anti-hallucination validation: ensure LLM output matches reality\n * 1. Remove hallucinated files (files that don't exist in git status)\n * 2. Remove duplicate files (file appears in multiple commits)\n * 3. Add missing files that LLM forgot (Phase 3: use LLM if available)\n * 4. Track warnings for debugging\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Anti-hallucination checks: detects hallucinated files, removes duplicates, groups forgotten files, optional LLM phase 3, tracks warnings\nasync function validateAndFixCommits(\n commits: CommitGroup[],\n summaries: FileSummary[],\n llm: ReturnType<typeof useLLM>,\n llmUsed: boolean,\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<CommitGroup[]> {\n const realFiles = new Set(summaries.map((s) => s.path));\n const hallucinations: string[] = [];\n\n // Step 1: Remove hallucinated files from each commit\n for (const commit of commits) {\n const validFiles: string[] = [];\n for (const file of commit.files) {\n if (realFiles.has(file)) {\n validFiles.push(file);\n } else {\n hallucinations.push(file);\n }\n }\n commit.files = validFiles;\n }\n\n // Step 2: Remove empty commits (all files were hallucinated)\n let nonEmptyCommits = commits.filter((c) => c.files.length > 0);\n\n // Step 3: Remove duplicate files - keep only first occurrence\n const seenFiles = new Set<string>();\n const duplicates: Array<{ file: string; commit: string }> = [];\n\n for (const commit of nonEmptyCommits) {\n const uniqueFiles: string[] = [];\n for (const file of commit.files) {\n if (!seenFiles.has(file)) {\n uniqueFiles.push(file);\n seenFiles.add(file);\n } else {\n duplicates.push({ file, commit: commit.id });\n }\n }\n commit.files = uniqueFiles;\n }\n\n // Log duplicates for debugging LLM behavior\n if (duplicates.length > 0) {\n logger.warn(`LLM returned ${duplicates.length} duplicate file(s) across commits - removed duplicates`, {\n duplicateCount: duplicates.length,\n samples: duplicates.slice(0, 5).map(d => `${d.file} in ${d.commit}`),\n });\n }\n\n // Step 4: Remove commits that became empty after deduplication\n nonEmptyCommits = nonEmptyCommits.filter((c) => c.files.length > 0);\n\n // Step 5: Adaptive Phase 3 loop - process missing files iteratively (up to 5 iterations for heavy cases)\n const MAX_PHASE3_ITERATIONS = 5;\n let phase3Iteration = 0;\n\n while (phase3Iteration < MAX_PHASE3_ITERATIONS) {\n // Recalculate missing files after each iteration\n const allFilesInCommits = new Set(nonEmptyCommits.flatMap((c) => c.files));\n const missingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !allFilesInCommits.has(f));\n\n if (missingFiles.length === 0) {\n // ✅ Success! All files classified\n if (phase3Iteration > 0) {\n await logger.info('Phase 3: All files classified', {\n totalIterations: phase3Iteration,\n totalCommits: nonEmptyCommits.length,\n });\n }\n break;\n }\n\n phase3Iteration++;\n\n await logger.debug(`Phase 3 iteration ${phase3Iteration}/${MAX_PHASE3_ITERATIONS}`, {\n missingFiles: missingFiles.length,\n processedSoFar: summaries.length - missingFiles.length,\n totalFiles: summaries.length,\n progress: `${Math.round(((summaries.length - missingFiles.length) / summaries.length) * 100)}%`,\n });\n\n // Update progress for user\n if (onProgress) {\n const progress = Math.round(((summaries.length - missingFiles.length) / summaries.length) * 100);\n onProgress(`Classifying remaining files (Phase 3, iteration ${phase3Iteration}, ${progress}%)...`);\n }\n\n // Get summaries for missing files only\n const missingSummaries = summaries.filter((s) => missingFiles.includes(s.path));\n\n // Try LLM to generate commits for missing files (may extend existing or create new)\n let missingCommits: CommitGroup[] | null = null;\n\n if (llmUsed && llm) {\n missingCommits = await generateMissingFilesCommit(\n llm,\n missingSummaries,\n nonEmptyCommits, // ← pass updated commits list (includes previous iterations)\n logger,\n onProgress\n );\n\n if (missingCommits && missingCommits.length > 0) {\n await logger.debug(`Phase 3 iteration ${phase3Iteration}: Processed commits`, {\n commitCount: missingCommits.length,\n filesCount: missingCommits.reduce((sum, c) => sum + c.files.length, 0),\n });\n\n // Add new commits to the list (extended commits are already modified in place)\n nonEmptyCommits.push(...missingCommits);\n }\n }\n\n // Safety check: if LLM didn't process ANY files, break to avoid infinite loop\n const newMissingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !new Set(nonEmptyCommits.flatMap(c => c.files)).has(f));\n\n if (newMissingFiles.length === missingFiles.length) {\n // LLM didn't process any files this iteration - something is wrong\n await logger.warn('Phase 3: LLM made no progress, stopping iterations', {\n iteration: phase3Iteration,\n stillMissing: newMissingFiles.length,\n });\n break;\n }\n\n // Safety: if only few files left and many iterations, use fallback to avoid over-iteration\n if (newMissingFiles.length <= 3 && phase3Iteration >= 2) {\n await logger.debug('Phase 3: Few files left, proceeding to fallback');\n break;\n }\n }\n\n // Fallback: if still missing files after MAX_ITERATIONS\n const finalMissingFiles = summaries\n .map((s) => s.path)\n .filter((f) => !new Set(nonEmptyCommits.flatMap(c => c.files)).has(f));\n\n if (finalMissingFiles.length > 0) {\n await logger.warn('Phase 3: Max iterations reached or LLM struggled, using fallback', {\n totalIterations: phase3Iteration,\n remainingFiles: finalMissingFiles.length,\n });\n\n const firstFile = finalMissingFiles[0];\n const fileName = firstFile ? firstFile.split('/').pop() ?? firstFile : 'files';\n const commitMessage = finalMissingFiles.length === 1\n ? `update ${fileName}`\n : `update ${finalMissingFiles.length} remaining files`;\n\n const fallbackCommit: CommitGroup = {\n id: `c${nonEmptyCommits.length + 1}`,\n type: 'chore',\n message: commitMessage,\n files: finalMissingFiles,\n releaseHint: 'none',\n breaking: false,\n reasoning: {\n newBehavior: false,\n fixesBug: false,\n internalOnly: true,\n explanation: `Files not classified after ${phase3Iteration} Phase 3 iteration(s): ${finalMissingFiles.slice(0, 3).join(', ')}${finalMissingFiles.length > 3 ? ` and ${finalMissingFiles.length - 3} more` : ''}`,\n confidence: 0.3,\n },\n };\n\n nonEmptyCommits.push(fallbackCommit);\n }\n\n return nonEmptyCommits;\n}\n\n/**\n * Retry LLM call with automatic fallback on parse errors\n * Tries up to MAX_LLM_RETRIES times before throwing\n */\nasync function retryLLMCall(\n llmFn: () => Promise<{ content: string; tokensUsed?: number }>,\n phase: string,\n logger: ReturnType<typeof useLogger>,\n onProgress?: (message: string) => void\n): Promise<{ content: string; tokensUsed?: number }> {\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= MAX_LLM_RETRIES; attempt++) {\n try {\n const result = await llmFn();\n\n // Try to parse response to validate JSON\n parseResponse(result.content);\n\n // Success - return result\n if (attempt > 1) {\n await logger.debug(`${phase} succeeded on attempt ${attempt}/${MAX_LLM_RETRIES}`);\n }\n return result;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // DEBUG: Log full error details\n await logger.error(`🔍 LLM call failed (attempt ${attempt})`, lastError, {\n errorName: lastError.name,\n errorMessage: lastError.message,\n errorStack: lastError.stack,\n });\n\n // Extract error type for better user feedback\n const errorType = getErrorType(lastError);\n\n if (attempt < MAX_LLM_RETRIES) {\n // Log to file with full details\n await logger.warn(`${phase} failed (attempt ${attempt}/${MAX_LLM_RETRIES}): ${errorType}`, {\n errorMessage: lastError.message,\n errorType,\n attempt,\n stack: lastError.stack?.split('\\n').slice(0, 3).join('\\n'), // First 3 lines only\n });\n\n // Show concise user message\n onProgress?.(`${phase} ${errorType}, retrying (${attempt}/${MAX_LLM_RETRIES})...`);\n\n // Short delay before retry (exponential backoff: 1s, 2s, 4s...)\n await new Promise((resolve) => {\n setTimeout(resolve, 1000 * Math.pow(2, attempt - 1));\n });\n } else {\n await logger.error(`${phase} failed after ${MAX_LLM_RETRIES} attempts: ${errorType}`, lastError, {\n errorType,\n });\n }\n }\n }\n\n // All retries exhausted\n throw lastError || new Error(`${phase} failed after ${MAX_LLM_RETRIES} attempts`);\n}\n\n/**\n * Extract user-friendly error type from error message\n */\nfunction getErrorType(error: Error): string {\n const message = error.message.toLowerCase();\n\n // Rate limiting\n if (message.includes('429') || message.includes('rate limit') || message.includes('too many requests')) {\n return 'rate limited (429)';\n }\n\n // Server errors\n if (message.includes('500') || message.includes('502') || message.includes('503')) {\n return 'server error (5xx)';\n }\n\n // Timeout\n if (message.includes('timeout') || message.includes('timed out')) {\n return 'timeout';\n }\n\n // Network errors\n if (message.includes('network') || message.includes('econnrefused') || message.includes('enotfound')) {\n return 'network error';\n }\n\n // Parse errors (invalid JSON from LLM)\n if (message.includes('json') || message.includes('parse') || message.includes('unexpected token')) {\n return 'invalid JSON';\n }\n\n // LLM response validation errors\n if (message.includes('missing') || message.includes('missing required field')) {\n return 'invalid structure';\n }\n\n // Generic - include first 50 chars of error for debugging\n const preview = error.message.substring(0, 50).replace(/\\n/g, ' ');\n return `error: ${preview}${error.message.length > 50 ? '...' : ''}`;\n}\n"]}
|