speckeeper 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -0
- package/bin/speckeeper.js +10 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1110 -0
- package/dist/cli.js.map +1 -0
- package/dist/dsl/index.d.ts +2 -0
- package/dist/dsl/index.js +3 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/index.d.ts +1377 -0
- package/dist/index.js +1364 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/init/design/_models/component.ts +70 -0
- package/dist/templates/init/design/_models/entity.ts +82 -0
- package/dist/templates/init/design/_models/index.ts +33 -0
- package/dist/templates/init/design/_models/requirement.ts +95 -0
- package/dist/templates/init/design/_models/term.ts +58 -0
- package/dist/templates/init/design/_models/usecase.ts +99 -0
- package/dist/templates/init/design/index.ts +8 -0
- package/dist/templates/init/design/requirements.ts +20 -0
- package/dist/templates/init/package.json.template +17 -0
- package/dist/templates/init/speckeeper.config.ts +11 -0
- package/dist/templates/init/tsconfig.json +14 -0
- package/package.json +80 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/config-loader.ts","../src/utils/file-writer.ts","../src/core/relation.ts","../src/core/model.ts","../src/cli/build.ts","../src/utils/model-loader.ts","../src/cli/lint.ts","../src/cli/drift.ts","../src/cli/check.ts","../src/cli/new.ts","../src/cli/impact.ts","../src/cli/init.ts","../src/cli/index.ts"],"names":["parseYaml","existsSync","dirname","readFileSync","chalk","join","resolve","getSpecsFromRegistry","models","model","writeFileSync","__filename","__dirname","readdirSync","statSync","mkdirSync"],"mappings":";;;;;;;;;;;AAgHA,IAAM,aAAA,GAAkC;AAAA,EACtC,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,QAAA;AAAA;AAAA,EACX,OAAA,EAAS,MAAA;AAAA,EACT,QAAA,EAAU;AACZ,CAAA;AAyFA,IAAM,YAAA,GAAe;AAAA,EACnB,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA,sBAAA;AAAA,EACA;AACF,CAAA;AAEO,SAAS,cAAA,CAAe,QAAA,GAAmB,OAAA,CAAQ,GAAA,EAAI,EAAkB;AAC9E,EAAA,IAAI,UAAA,GAAa,QAAA;AAEjB,EAAA,OAAO,UAAA,KAAe,OAAA,CAAQ,UAAU,CAAA,EAAG;AACzC,IAAA,KAAA,MAAW,cAAc,YAAA,EAAc;AACrC,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,UAAA,EAAY,UAAU,CAAA;AACjD,MAAA,IAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,QAAA,OAAO,UAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,UAAA,GAAa,QAAQ,UAAU,CAAA;AAAA,EACjC;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,eAAsB,UAAA,CACpB,UAAA,EACA,GAAA,GAAc,OAAA,CAAQ,KAAI,EACC;AAC3B,EAAA,MAAM,YAAA,GAAe,UAAA,IAAc,cAAA,CAAe,GAAG,CAAA;AAErD,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B;AAEA,EAAA,MAAM,MAAM,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,IAAO,WAAA,EAAY;AAEvD,EAAA,IAAI;AACF,IAAA,IAAI,GAAA,KAAQ,MAAA,IAAU,GAAA,KAAQ,KAAA,EAAO;AACnC,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,YAAA,EAAc,OAAO,CAAA;AAClD,MAAA,MAAM,MAAA,GAASA,MAAU,OAAO,CAAA;AAChC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,YAAA,EAAc,OAAO,CAAA;AAClD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,IAAA,EAAM;AAEhC,MAAA,MAAM,MAAA,GAAS,MAAM,OAAO,YAAA,CAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAO,OAAA,IAAW,MAAA;AACjC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,2BAAA,EAA8B,YAAY,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAClE,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B;AACF;AC5PO,SAAS,UAAU,OAAA,EAAuB;AAC/C,EAAA,IAAI,CAACC,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,IAAA,SAAA,CAAU,OAAA,EAAS,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAAA,EACxC;AACF;AAEO,SAAS,SAAA,CAAU,UAAkB,OAAA,EAA8B;AACxE,EAAA,MAAM,GAAA,GAAMC,QAAQ,QAAQ,CAAA;AAC5B,EAAA,SAAA,CAAU,GAAG,CAAA;AAEb,EAAA,MAAM,OAAA,GAAUD,WAAW,QAAQ,CAAA;AACnC,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,eAAA,GAAkBE,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AACtD,IAAA,SAAA,GAAY,eAAA,KAAoB,OAAA;AAAA,EAClC;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,aAAA,CAAc,QAAA,EAAU,SAAS,OAAO,CAAA;AAAA,EAC1C;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,SAAS,CAAC,OAAA;AAAA,IACV,OAAA,EAAS,WAAW,CAAC,SAAA;AAAA,IACrB;AAAA,GACF;AACF;AAmBO,SAAS,gBACd,KAAA,EACkB;AAClB,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,OAAA,EAAQ,IAAK,KAAA,EAAO;AACrC,IAAA,OAAA,CAAQ,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,MAAA;AAAA,IACxC,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,MAAA;AAAA,IACxC,WAAW,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,CAAA,CAAE,MAAA;AAAA,IAC5C,OAAO,OAAA,CAAQ;AAAA,GACjB;AACF;ACzCO,IAAM,cAAA,GAAiB;AAAA,EAC5B,WAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;AAOO,IAAM,cAAA,GAAiB,EAAE,MAAA,CAAO;AAAA;AAAA,EAErC,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,cAAc,CAAA;AAAA;AAAA,EAE3B,MAAA,EAAQ,EAAE,MAAA,EAAO;AAAA;AAAA,EAEjB,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC1B,CAAC,CAAA;AAMmC,CAAA,CAAE,KAAA,CAAM,cAAc,EAAE,QAAA;;;ACqY5D,IAAM,aAAA,uBAAoB,GAAA,EAAwB;AAM3C,SAAS,cAAc,KAAA,EAAyB;AACrD,EAAA,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAK,CAAA;AACnC;AAcO,SAAS,YAAA,GAA6B;AAC3C,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,CAAA;AAC1C;;;ACpcA,eAAsB,aAAa,OAAA,EAA6C;AAC9E,EAAA,OAAA,CAAQ,GAAA,CAAIC,MAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAGxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,WAAA,EAAc,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACrE,EAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,cAAc,MAAA,CAAO,OAAO,GAAG,CAAC,CAAA;AACvD,EAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,cAAc,MAAA,CAAO,QAAQ,GAAG,CAAC,CAAA;AACxD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,SAAA,CAAUC,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAO,CAAC,CAAA;AACnC,IAAA,SAAA,CAAUA,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,QAAQ,CAAC,CAAA;AAEpC,IAAA,MAAM,QAAkD,EAAC;AACzD,IAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,OAAA,CAAQ,GAAA,CAAID,MAAA,CAAM,MAAA,CAAO,uDAAuD,CAAC,CAAA;AACjF,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,MAAM,iBAAiB,CAAC,CAAA;AAGtE,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,YAAA,EAAa;AAErC,MAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,OAAO,KAAA,CAAM,IAAI,wBAAwB,CAAC,CAAA;AAAA,QACnE;AACA,QAAA;AAAA,MACF;AAKA,MAAA,MAAM,QAAmB,EAAC;AAE1B,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,OAAO,KAAA,CAAM,IAAI,kBAAkB,CAAC,CAAA;AAAA,QAC7D;AACA,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,MAAM,SAAA,GAAY,QAAA,CAAS,SAAA,GACvBC,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA,GAC5CA,IAAAA,CAAK,GAAA,EAAK,OAAO,OAAO,CAAA;AAE5B,QAAA,SAAA,CAAU,SAAS,CAAA;AAGnB,QAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AACpC,YAAA,MAAM,WAAW,KAAA,CAAM,WAAA,CAAY,MAAM,QAAA,CAAS,MAAM,KAAM,IAAA,CAAwB,EAAA;AACtF,YAAA,KAAA,CAAM,IAAA,CAAK;AAAA,cACT,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,GAAA,CAAK,CAAA;AAAA,cACtC;AAAA,aACD,CAAA;AAAA,UACH;AAAA,QACF;AAGA,QAAA,IAAI,SAAS,KAAA,EAAO;AAClB,UAAA,MAAM,YAAA,GAAe,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACzC,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAAA,YAChC,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ,IAAID,MAAA,CAAM,KAAA,CAAM,cAAS,KAAA,CAAM,IAAI,EAAE,CAAC,CAAA;AAAA,IAChD;AAGA,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,aAAa,KAAA,CAAM,MAAM,WAAW,CAAC,CAAA;AAE5D,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,KAAK,CAAA;AAE1C,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAA,CAAM,KAAA,CAAM,CAAA,uBAAA,CAAoB,CAAC,CAAA;AAC7C,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AACxD,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AACxD,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,kBAAkB,MAAA,CAAO,SAAS,EAAE,CAAC,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAA,CAAM,MAAA,CAAO,yBAAyB,CAAC,CAAA;AAAA,IACrD;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAA,CAAM,GAAA,CAAI,eAAe,GAAG,KAAK,CAAA;AAC/C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AC9FO,SAAS,mBAAA,GAAqC;AACnD,EAAA,OAAO;AAAA,IACL,YAAA,sBAAkB,GAAA,EAAI;AAAA,IACtB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,KAAA,sBAAW,GAAA,EAAI;AAAA,IACf,OAAA,sBAAa,GAAA,EAAI;AAAA,IACjB,WAAA,sBAAiB,GAAA,EAAI;AAAA,IACrB,KAAA,sBAAW,GAAA,EAAI;AAAA,IACf,YAAA,sBAAkB,GAAA,EAAI;AAAA,IACtB,aAAA,sBAAmB,GAAA,EAAI;AAAA,IACvB,OAAA,sBAAa,GAAA,EAAI;AAAA,IACjB,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,SAAA,sBAAe,GAAA;AAAI,GACrB;AACF;AAMA,IAAI,iBAAgC,mBAAA,EAAoB;AAEjD,SAAS,iBAAA,GAAmC;AACjD,EAAA,OAAO,cAAA;AACT;AAEO,SAAS,mBAAA,GAA4B;AAC1C,EAAA,cAAA,GAAiB,mBAAA,EAAoB;AACvC;AAoBA,SAAS,gBAAgB,KAAA,EAA0F;AACjH,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,OACE,OAAO,IAAI,EAAA,KAAO,QAAA,IAClB,OAAO,GAAA,CAAI,IAAA,KAAS,YACpB,OAAO,GAAA,CAAI,aAAa,QAAA,IACxB,GAAA,CAAI,WAAW,MAAA,IACf,OAAO,IAAI,QAAA,KAAa,UAAA,IACxB,OAAO,GAAA,CAAI,IAAA,KAAS,UAAA;AAExB;AAKA,SAAS,uBAAuB,MAAA,EAAuC;AACrE,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,WAAW,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC9D,IAAA,IAAI,CAAC,WAAA,IAAe,OAAO,WAAA,KAAgB,QAAA,EAAU;AAGrD,IAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAGhC,MAAA,aAAA,CAAkB,WAAkB,CAAA;AACpC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC9B,MAAA,kBAAA,CAAmB,YAAY,WAAW,CAAA;AAC1C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,WAAA;AAGd,IAAA,IAAI,MAAM,UAAA,IAAc,KAAA,CAAM,UAAU,KAAA,CAAM,UAAA,IAAc,MAAM,SAAA,EAAW;AAC3E,MAAA,MAAM,IAAA,GAAO,KAAA;AAOb,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,UAAA,EAAY;AAClC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,WAAW,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MAC1D;AACA,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,MAAA,EAAQ;AAC/B,QAAA,IAAI,MAAM,EAAA,EAAI,cAAA,CAAe,OAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,MACzD;AACA,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,UAAA,EAAY;AACtC,QAAA,IAAI,SAAS,EAAA,EAAI,cAAA,CAAe,WAAW,GAAA,CAAI,QAAA,CAAS,IAAI,QAAQ,CAAA;AAAA,MACtE;AACA,MAAA,KAAA,MAAW,GAAA,IAAO,KAAK,SAAA,EAAW;AAChC,QAAA,IAAI,IAAI,EAAA,EAAI,cAAA,CAAe,UAAU,GAAA,CAAI,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,MACtD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,YAAY,KAAA,CAAM,SAAA,IAAa,MAAM,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,EAAG;AACtE,MAAA,MAAM,OAAA,GAAU,KAAA;AAKhB,MAAA,KAAA,MAAW,MAAA,IAAU,QAAQ,QAAA,EAAU;AACrC,QAAA,IAAI,OAAO,EAAA,EAAI,cAAA,CAAe,SAAS,GAAA,CAAI,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,MAC9D;AACA,MAAA,KAAA,MAAW,GAAA,IAAO,QAAQ,SAAA,EAAW;AACnC,QAAA,IAAI,IAAI,EAAA,EAAI,cAAA,CAAe,UAAU,GAAA,CAAI,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,MACtD;AACA,MAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG;AACtC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,MAAM,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MACrD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,MAAA,EAAQ;AAClC,MAAA,MAAM,OAAA,GAAU,KAAA;AAIhB,MAAA,KAAA,MAAW,EAAA,IAAM,QAAQ,QAAA,EAAU;AACjC,QAAA,IAAI,GAAG,EAAA,EAAI,cAAA,CAAe,SAAS,GAAA,CAAI,EAAA,CAAG,IAAI,EAAE,CAAA;AAAA,MAClD;AACA,MAAA,KAAA,MAAW,KAAA,IAAS,QAAQ,MAAA,EAAQ;AAClC,QAAA,IAAI,MAAM,EAAA,EAAI,cAAA,CAAe,OAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,MACzD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,KAAA,IAAS,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC7C,MAAA,MAAM,QAAA,GAAW,KAAA;AACjB,MAAA,KAAA,MAAW,IAAA,IAAQ,SAAS,KAAA,EAAO;AACjC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,cAAc,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MAC7D;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,MAAM,KAAA,CAAM,KAAA,KAAU,MAAM,IAAA,IAAQ,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,UAAA,CAAA,EAAa;AAC7E,MAAA,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACzD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,cAAc,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAA,EAAG;AACjF,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACrD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,EAAA,IAAM,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA,IAAS,MAAM,QAAA,EAAU;AAC3D,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACrD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,IAAA,IAAQ,MAAM,IAAA,IAAQ,CAAC,OAAA,EAAS,QAAA,EAAU,UAAU,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,IAAc,CAAA,EAAG;AAC1G,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACnD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,EAAA,KAAO,KAAA,CAAM,QAAQ,KAAA,CAAM,YAAA,CAAA,IAAiB,MAAM,UAAA,EAAY;AACtE,MAAA,cAAA,CAAe,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AAC1D,MAAA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,kBAAA,CAAmB,YAAoB,KAAA,EAAwB;AACtE,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA;AACZ,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,OAAO,GAAA,CAAI,OAAO,QAAA,EAAU;AAI3C,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,aAAa,CAAA,IAC/C,UAAA,CAAW,WAAA,EAAY,CAAE,SAAS,aAAa,CAAA,IAC9C,GAAA,CAAI,IAAA,IAAQ,IAAI,kBAAA,EAAqB;AACxC,MAAA,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC5C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC1C,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,QAAA,EAAW;AAC/B,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAW,WAAA,EAAY,CAAE,SAAS,OAAO,CAAA,IACxC,IAAI,IAAA,IAAQ,CAAC,SAAS,QAAA,EAAU,UAAU,EAAE,QAAA,CAAS,GAAA,CAAI,IAAc,CAAA,IAAK,CAAC,IAAI,QAAA,EAAW;AAC/F,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACtC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,IAC7C,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,WAAW,KAC5C,GAAA,CAAI,IAAA,IAAQ,CAAC,QAAA,EAAU,QAAA,EAAU,WAAA,EAAa,WAAW,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,IAAc,CAAA,EAAI;AAC7F,MAAA,cAAA,CAAe,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC1C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA,IACxC,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,UAAA,IAAc,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA,EAAI;AACjE,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,MAAM,CAAA,IACxC,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC3C,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,UAAA,EAAa;AAChC,MAAA,cAAA,CAAe,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC7C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,EAAA,IAAM,GAAA,CAAI,KAAA,EAAQ;AACrC,MAAA,cAAA,CAAe,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACzC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA,IACxC,GAAA,CAAI,IAAA,IAAQ,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,EAAW;AAC/C,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACtC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAW,WAAA,EAAY,CAAE,SAAS,SAAS,CAAA,IAC1C,IAAI,IAAA,IAAQ,CAAC,UAAU,SAAA,EAAW,WAAA,EAAa,YAAY,CAAA,CAAE,QAAA,CAAS,IAAI,IAAc,CAAA,IAAK,IAAI,WAAA,EAAc;AAClH,MAAA,cAAA,CAAe,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC1C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,QAAQ,CAAA,IACzC,GAAA,CAAI,QAAQ,CAAC,MAAA,EAAQ,SAAS,QAAA,EAAU,OAAA,EAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,IAAI,IAAc,CAAA,IAAK,IAAI,IAAA,EAAO;AACzG,MAAA,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACvC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC3C,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,UAAU,GAAA,CAAI,oBAAA,IAAwB,MAAM,OAAA,CAAQ,GAAA,CAAI,oBAAoB,CAAA,EAAI;AACvF,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,YAAY,GAAA,CAAI,QAAA,IAAY,IAAI,OAAA,IACpC,CAAC,QAAQ,gBAAA,EAAkB,kBAAA,EAAoB,gBAAgB,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,QAAkB,CAAA,EAAI;AACvG,MAAA,cAAA,CAAe,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACzC,MAAA;AAAA,IACF;AAAA,EACF;AACF;AASA,eAAsB,uBAAA,CACpB,OAAA,EACA,OAAA,GAAmC,EAAC,EACjB;AACnB,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,IAAI,CAACH,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,YAAY,OAAO,CAAA;AAEnC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,QAAA,GAAWI,IAAAA,CAAK,OAAA,EAAS,KAAK,CAAA;AACpC,IAAA,MAAM,IAAA,GAAO,SAAS,QAAQ,CAAA;AAE9B,IAAA,IAAI,IAAA,CAAK,WAAA,EAAY,IAAK,OAAA,CAAQ,SAAA,EAAW;AAC3C,MAAA,MAAM,QAAA,GAAW,MAAM,uBAAA,CAAwB,QAAA,EAAU,OAAO,CAAA;AAChE,MAAA,WAAA,CAAY,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA,IAC9B,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,EAAO,EAAG;AACxB,MAAA,MAAM,GAAA,GAAM,QAAQ,KAAK,CAAA;AAEzB,MAAA,IAAI,CAAC,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAAK,CAAC,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AAE5E,QAAA,IAAI,QAAA,CAAS,KAAA,EAAO,GAAG,CAAA,KAAM,OAAA,EAAS;AACpC,UAAA;AAAA,QACF;AAEA,QAAA,IAAI;AAEF,UAAA,MAAM,MAAA,GAAS,MAAM,OAAO,QAAA,CAAA;AAC5B,UAAA,WAAA,CAAY,KAAK,QAAQ,CAAA;AAGzB,UAAA,sBAAA,CAAuB,MAAM,CAAA;AAAA,QAC/B,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAQ,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,WAAA;AACT;AAKA,eAAsB,aAAA,CACpB,MAAA,EACA,GAAA,GAAc,OAAA,CAAQ,KAAI,EAKzB;AAED,EAAA,mBAAA,EAAoB;AAEpB,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,SAAkD,EAAC;AAGzD,EAAA,MAAM,SAAA,GAAYC,OAAAA,CAAQ,GAAA,EAAK,MAAA,CAAO,aAAa,QAAQ,CAAA;AAG3D,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,EAAE,IAAA,EAAMD,IAAAA,CAAK,SAAA,EAAW,cAAc,CAAA,EAAE;AAAA,IACxC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA,EAAE;AAAA,IACpC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,cAAc,CAAA,EAAE;AAAA,IACxC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,YAAY,CAAA,EAAE;AAAA,IACtC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,SAAS,CAAA,EAAE;AAAA,IACnC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,OAAO,CAAA,EAAE;AAAA,IACjC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA,EAAE;AAAA;AAAA,IAEpC,EAAE,MAAM,SAAA;AAAU,GACpB;AAEA,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,OAAA,EAAQ,IAAK,SAAA,EAAW;AACzC,IAAA,IAAI,CAACJ,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,MAAM,uBAAA,CAAwB,SAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AACxE,MAAA,WAAA,CAAY,IAAA,CAAK,GAAG,KAAK,CAAA;AAAA,IAC3B,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAU,iBAAA,EAAkB;AAAA,IAC5B,WAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACrYA,eAAsB,YAAY,OAAA,EAA4C;AAC5E,EAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,IAAA,CAAK,iBAAiB,CAAC,CAAA;AACzC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAE9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,OAAA,CAAQ,KAAK,EAAE,CAAC,CAAA;AAAA,EACtD;AACA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,UAAU,WAAA,EAAa,MAAA,EAAQ,YAAW,GAAI,MAAM,aAAA,CAAc,MAAA,EAAQ,GAAG,CAAA;AAErF,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,UAAA,CAAW,MAAM,yBAAyB,CAAC,CAAA;AAC3E,MAAA,KAAA,MAAW,EAAE,IAAA,EAAM,KAAA,EAAM,IAAK,UAAA,EAAY;AACxC,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,MAAA,EAAS,QAAA,CAAS,GAAA,EAAK,IAAI,CAAC,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAC,CAAA;AAAA,MACpE;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,WAAA,CAAY,MAAM,QAAQ,CAAC,CAAA;AAC/D,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAGd,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,0BAA0B,CAAC,CAAA;AAClD,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAG7C,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,iBAAA,CAAkB,QAAQ,OAAO,CAAA;AAGjC,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,cAAc,GAAG,KAAK,CAAA;AAC9C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAAS,YAAA,CAAa,UAAyB,OAAA,EAAyC;AACtF,EAAA,MAAM,SAAsB,EAAC;AAC7B,EAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,IAAA,MAAM,KAAA,GAAQ,oBAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AAErD,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAGxB,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAEvC,IAAA,KAAA,MAAW,UAAU,WAAA,EAAa;AAChC,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,MAAM,MAAA,CAAO,MAAA;AAAA,QACb,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,WAAW,KAAA,CAAM;AAAA,OAClB,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA,CAAE,MAAA;AAC1D,EAAA,MAAM,WAAW,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,SAAS,CAAA,CAAE,MAAA;AAC9D,EAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,MAAM,CAAA,CAAE,MAAA;AAGxD,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAO;AAAA,MACL,QAAQ,MAAA,CAAO,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,aAAa,MAAM,CAAA;AAAA,MAChD,MAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAM;AAC3C;AAEA,SAAS,oBAAA,CAAqB,UAAyB,OAAA,EAA4B;AAEjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa,YAAA;AAAA,IACb,UAAA,EAAY,YAAA;AAAA,IACZ,OAAA,EAAS,QAAA;AAAA,IACT,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAMA,SAAS,iBAAA,CAAkB,QAAoB,OAAA,EAAmC;AAChF,EAAA,IAAI,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAC7B,IAAA,OAAA,CAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,QAAA,EAAU;AAC/B,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,KAAa,OAAA,GAAU,UAAU,KAAA,CAAM,QAAA,KAAa,YAAY,SAAA,GAAY,QAAA;AAChG,MAAA,OAAA,CAAQ,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,EAAA,EAAK,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,MAAA,GAAS,CAAA,EAAA,EAAK,MAAM,MAAM,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAE,CAAA;AAAA,IACvG;AACA,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC9B,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,0BAAqB,CAAC,CAAA;AAC9C,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,KAAa,OAAA,GAAU,WAAM,KAAA,CAAM,QAAA,KAAa,YAAY,QAAA,GAAM,QAAA;AACrF,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,KAAa,OAAA,GAAUA,MAAAA,CAAM,GAAA,GAAM,KAAA,CAAM,QAAA,KAAa,SAAA,GAAYA,MAAAA,CAAM,MAAA,GAASA,MAAAA,CAAM,IAAA;AAE3G,IAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,GAAO,EAAA;AACrD,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAA;AACxD,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,KAAA,CAAM,IAAI,EAAE,CAAC,CAAA;AAAA,EACnD;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,MAAA,CAAO,MAAM,CAAA,SAAA,EAAY,MAAA,CAAO,QAAQ,CAAA,WAAA,EAAc,MAAA,CAAO,KAAK,QAAQ,CAAC,CAAA;AAClH;AClKA,eAAsB,aAAa,OAAA,EAA6C;AAC9E,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,MAAA,CAAO,OAAO,GAAG,CAAC,CAAA;AACtD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAEpD,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,MAAM,SAAS,YAAA,EAAa;AAG5B,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,MAAA,KAAA,MAAW,QAAA,IAAY,KAAA,CAAM,YAAA,EAAa,EAAG;AAC3C,QAAA,IAAI,QAAA,CAAS,WAAW,UAAA,EAAY;AAEpC,QAAA,MAAM,SAAA,GAAY,QAAA,CAAS,SAAA,GACvBF,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA,GAC5CA,IAAAA,CAAK,GAAA,EAAK,OAAO,OAAO,CAAA;AAG5B,QAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,WAAW,KAAA,CAAM,WAAA,CAAY,IAAA,EAAM,UAAU,KAAM,IAAA,CAAwB,EAAA;AACjF,YAAA,MAAM,QAAA,GAAWA,IAAAA,CAAK,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,GAAA,CAAK,CAAA;AAEjD,YAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAA;AAClD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,QAAA,GAAW,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AACrC,YAAA,MAAM,MAAA,GAASE,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAE7C,YAAA,IAAI,gBAAA,CAAiB,QAAQ,CAAA,KAAM,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC3D,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAA;AAAA,YACpD,CAAA,MAAO;AACL,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,YAC/C;AAAA,UACF;AAAA,QACF;AAGA,QAAA,IAAI,SAAS,KAAA,EAAO;AAClB,UAAA,MAAM,SAAA,GAAYE,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAE5C,UAAA,IAAI,CAACJ,UAAAA,CAAW,SAAS,CAAA,EAAG;AAC1B,YAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AAAA,UACrD,CAAA,MAAO;AACL,YAAA,MAAM,QAAA,GAAW,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACrC,YAAA,MAAM,MAAA,GAASE,YAAAA,CAAa,SAAA,EAAW,OAAO,CAAA;AAE9C,YAAA,IAAI,gBAAA,CAAiB,QAAQ,CAAA,KAAM,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC3D,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AAAA,YACrD,CAAA,MAAO;AACL,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,MAAM,CAAA;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,kBAAA,CAAmB,SAAS,OAAO,CAAA;AAGnC,IAAA,MAAM,QAAA,GAAW,QAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,MAAA,KAAW,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA;AACnF,IAAA,IAAI,QAAA,IAAY,QAAQ,WAAA,EAAa;AACnC,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMC,MAAAA,CAAM,GAAA,CAAI,qBAAqB,GAAG,KAAK,CAAA;AACrD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAASG,qBAAAA,CAAqB,UAAyB,OAAA,EAA4B;AACjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa;AAAA,GACf;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAEA,SAAS,iBAAiB,OAAA,EAAyB;AACjD,EAAA,OAAO,OAAA,CAAQ,IAAA,EAAK,CAAE,OAAA,CAAQ,SAAS,IAAI,CAAA;AAC7C;AAEA,SAAS,kBAAA,CAAmB,SAAwB,QAAA,EAAqC;AACvF,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,KAAK,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,IAAI,CAAA;AAChD,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAC1D,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAE1D,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,WAAW,CAAA,EAAG;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIH,MAAAA,CAAM,KAAA,CAAM,4BAAuB,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,gBAAgB,OAAA,CAAQ,MAAM,QAAQ,CAAC,CAAA;AAC9D,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,OAAA,CAAQ,MAAM,wBAAwB,CAAC,CAAA;AACvE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,SAAS,MAAA,CAAO,IAAI,EAAE,CAAC,CAAA;AAAA,IAClD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,GAAA,CAAI,YAAO,OAAA,CAAQ,MAAM,uBAAuB,CAAC,CAAA;AACnE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,GAAA,CAAI,SAAS,MAAA,CAAO,IAAI,EAAE,CAAC,CAAA;AAAA,IAC/C;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,EAAA,CAAG,MAAM,CAAA,KAAA,EAAQ,OAAA,CAAQ,MAAM,CAAA,UAAA,EAAa,OAAA,CAAQ,MAAM,UAAU,CAAC,CAAA;AAC5G;ACvIA,eAAsB,YAAA,CACpB,MACA,OAAA,EACe;AACf,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAC9C,EAAA,MAAM,SAAA,GAAY,IAAA,IAAQ,OAAA,CAAQ,IAAA,IAAQ,KAAA;AAE1C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,SAAS,EAAE,CAAC,CAAA;AAChD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAEpD,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,qBAAA,EAAwB,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,EAAE,CAAC,CAAA;AAAA,IACpF;AAGA,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,MAAM,UAAA,GAAa,KAAA,CAAM,qBAAA,CAAsB,IAAI,CAAA;AACnD,QAAA,IAAI,CAAC,UAAA,EAAY;AAEjB,QAAA,MAAM,QAAA,GAAWF,IAAAA,CAAK,GAAA,EAAK,UAAU,CAAA;AACrC,QAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,MAAM,KAAA,CAAM,EAAA;AAAA,YACZ,OAAA,EAAS,KAAA;AAAA,YACT,QAAQ,CAAC;AAAA,cACP,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,8BAA8B,UAAU,CAAA,CAAA;AAAA,cACjD,QAAS,IAAA,CAAwB;AAAA,aAClC;AAAA,WACF,CAAA;AACD,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,YAAA,GAAe,iBAAiB,QAAQ,CAAA;AAG9C,QAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,YAAY,CAAA;AAElD,QAAA,IAAI,CAAC,WAAA,CAAY,OAAA,IAAW,WAAA,CAAY,MAAA,CAAO,SAAS,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC5F,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,MAAM,KAAA,CAAM,EAAA;AAAA,YACZ,SAAS,WAAA,CAAY,OAAA;AAAA,YACrB,MAAA,EAAQ;AAAA,cACN,GAAG,WAAA,CAAY,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAkB,OAAA,EAAS,CAAA,CAAE,SAAS,MAAA,EAAQ,CAAA,CAAE,QAAQ,KAAA,EAAO,CAAA,CAAE,OAAM,CAAE,CAAA;AAAA,cACrH,GAAG,WAAA,CAAY,QAAA,CAAS,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAoB,OAAA,EAAS,CAAA,CAAE,SAAS,MAAA,EAAQ,CAAA,CAAE,QAAQ,KAAA,EAAO,CAAA,CAAE,OAAM,CAAE;AAAA;AAC3H,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,IAAA,kBAAA,CAAmB,OAAO,CAAA;AAG1B,IAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,IAAA,CAAK,sBAAsB,CAAC,CAAA;AAC9C,MAAA,MAAM,eAAA,GAAkB,qBAAqB,QAAQ,CAAA;AAErD,MAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,QAAA,wBAAA,CAAyB,eAAe,CAAA;AAGxC,QAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACnC,UAAA,IAAI,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAC1C,YAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,cACX,IAAA,EAAM,CAAA,SAAA,EAAY,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,cAC/B,OAAA,EAAS,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA;AAAA;AAAA,cACzC,MAAA,EAAQ,MAAM,MAAA,CAAO,cAAA,CAAe,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,gBAC5D,QAAA,EAAU,SAAA;AAAA,gBACV,SAAS,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,CAAA,MAAA,EAAI,MAAM,WAAW,CAAA,GAAA,EAAM,IAAA,CAAK,EAAE,IAAI,IAAA,CAAK,QAAA,GAAW,KAAK,IAAA,CAAK,QAAQ,MAAM,EAAE,CAAA,YAAA,CAAA;AAAA,gBAC5G,QAAQ,IAAA,CAAK;AAAA,eACf,CAAE;AAAA,aACH,CAAA;AAAA,UACH;AAAA,QACF;AAGA,QAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kOAAyC,CAAC,CAAA;AACjE,QAAA,MAAM,YAAY,eAAA,CAAgB,KAAA,CAAM,OAAK,CAAA,CAAE,MAAA,CAAO,mBAAmB,EAAE,CAAA;AAC3E,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,iDAAuC,CAAC,CAAA;AAAA,QAClE,CAAA,MAAO;AACL,UAAA,MAAM,SAAS,eAAA,CAAgB,MAAA,CAAO,OAAK,CAAA,CAAE,MAAA,CAAO,kBAAkB,EAAE,CAAA;AACxE,UAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,MAAA,CAAO,MAAM,8BAA8B,CAAC,CAAA;AAAA,QAC9E;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,6BAA6B,CAAC,CAAA;AAAA,MACvD;AAAA,IACF;AAGA,IAAA,MAAM,YAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,CAAC,EAAE,OAAO,CAAA;AAC9C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,eAAe,GAAG,KAAK,CAAA;AAC/C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAASG,qBAAAA,CAAqB,UAAyB,OAAA,EAA4B;AACjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa,YAAA;AAAA,IACb,SAAA,EAAW,SAAA;AAAA,IACX,WAAA,EAAa,WAAA;AAAA,IACb,UAAA,EAAY,UAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAEA,SAAS,iBAAiB,QAAA,EAA2B;AACnD,EAAA,MAAM,OAAA,GAAUJ,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAE9C,EAAA,IAAI,SAAS,QAAA,CAAS,OAAO,KAAK,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3D,IAAA,OAAOH,MAAU,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,mBAAmB,OAAA,EAA8B;AACxD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,GAAA,CAAII,MAAAA,CAAM,KAAA,CAAM,4BAAuB,CAAC,CAAA;AAChD,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,KAAa,OAAA,GAAU,QAAA,GAAM,QAAA;AAChD,MAAA,MAAM,QAAQ,KAAA,CAAM,QAAA,KAAa,OAAA,GAAUA,MAAAA,CAAM,MAAMA,MAAAA,CAAM,MAAA;AAE7D,MAAA,IAAI,KAAA,CAAM,aAAa,OAAA,EAAS,WAAA,EAAA;AAAA,WAC3B,aAAA,EAAA;AAEL,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,GAAO,EAAA;AACrD,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAA;AAAA,IAC1D;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,WAAA,EAAc,WAAW,CAAA,SAAA,EAAY,aAAa,WAAW,CAAC,CAAA;AACvF;AAoBA,SAAS,qBAAqB,QAAA,EAAgD;AAC5E,EAAA,MAAM,SAAS,YAAA,EAAa;AAC5B,EAAA,MAAM,UAAiC,EAAC;AAGxC,EAAA,MAAM,iBAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACnD,IAAA,IAAI,iBAAiB,GAAA,EAAK;AACxB,MAAA,cAAA,CAAe,GAAG,CAAA,GAAI,KAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,OAAA,GAAU,MAAM,kBAAA,EAAmB;AACzC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,aAAA,CAAc,KAAA,EAAO,cAAc,CAAA;AAExD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,SAAS,KAAA,CAAM,EAAA;AAAA,UACf,WAAW,KAAA,CAAM,IAAA;AAAA,UACjB,aAAa,OAAA,CAAQ,WAAA;AAAA,UACrB,aAAa,OAAA,CAAQ,WAAA;AAAA,UACrB;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,yBAAyB,MAAA,EAAqC;AACrE,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,GAAA,CAAIH,MAAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,SAAS,CAAA,QAAA,EAAM,KAAA,CAAM,WAAW,CAAA,CAAE,CAAC,CAAA;AAC/E,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,KAAK,KAAA,CAAM,WAAW,EAAE,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,gOAAA,CAAyC,CAAC,CAAA;AACjE,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,KAAK,EAAE,CAAC,CAAA;AAC5D,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,KAAA,CAAM,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AAC/D,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,SAAS,EAAE,CAAC,CAAA;AAElE,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA,GAAKA,MAAAA,CAAM,KAAA,GAC3C,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA,GAAKA,MAAAA,CAAM,SAASA,MAAAA,CAAM,GAAA;AACxE,IAAA,OAAA,CAAQ,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,eAAe,GAAG,CAAC,CAAA;AAElE,IAAA,IAAI,KAAA,CAAM,OAAO,cAAA,CAAe,MAAA,GAAS,KAAK,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,MAAA,IAAU,EAAA,EAAI;AACtF,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,oBAAoB,CAAC,CAAA;AAC9C,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,MAAA,CAAO,cAAA,EAAgB;AAC9C,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,GAAc,CAAA,EAAA,EAAK,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA,GAAK,EAAA;AAC3E,QAAA,MAAM,SAAS,IAAA,CAAK,QAAA,GAAW,CAAA,EAAA,EAAK,IAAA,CAAK,QAAQ,CAAA,CAAA,CAAA,GAAM,EAAA;AACvD,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,MAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,CAAC,CAAA;AAAA,MAC9D;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,SAAS,EAAA,EAAI;AAClD,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,GAAA,EAAM,MAAM,MAAA,CAAO,cAAA,CAAe,MAAM,CAAA,mCAAA,CAAqC,CAAC,CAAA;AACvG,MAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,MAAA,CAAO,eAAe,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAAG;AAC1D,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,GAAc,CAAA,EAAA,EAAK,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA,GAAK,EAAA;AAC3E,QAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,MAAA,EAAS,KAAK,EAAE,CAAA,EAAG,IAAI,CAAA,CAAE,CAAC,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AChSA,eAAsB,WAAW,OAAA,EAA2C;AAC1E,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,gBAAgB,CAAC,CAAA;AACxC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,IAAI,CAAC,QAAQ,IAAA,EAAM;AACjB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,0BAA0B,CAAC,CAAA;AAClD,IAAA,MAAMI,UAAS,YAAA,EAAa;AAC5B,IAAA,KAAA,MAAWC,UAASD,OAAAA,EAAQ;AAC1B,MAAA,OAAA,CAAQ,GAAA,CAAIJ,MAAAA,CAAM,IAAA,CAAK,CAAA,MAAA,EAASK,MAAAA,CAAM,EAAE,CAAA,EAAA,EAAKA,MAAAA,CAAM,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,IAC7D;AACA,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,GAAA,CAAIL,MAAAA,CAAM,IAAA,CAAK,mDAAmD,CAAC,CAAA;AAC3E,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,SAAS,YAAA,EAAa;AAC5B,EAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,OAAK,CAAA,CAAE,EAAA,KAAO,QAAQ,IAAI,CAAA;AAEpD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAA,CAAQ,MAAMA,MAAAA,CAAM,GAAA,CAAI,gCAAgC,OAAA,CAAQ,IAAI,GAAG,CAAC,CAAA;AACxE,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,+CAA+C,CAAC,CAAA;AACvE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,EAAG,MAAM,QAAQ,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,CAAA,CAAE,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AAG1E,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,KAAA,EAAO,EAAE,CAAA;AAE3C,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uBAAuB,CAAC,CAAA;AAC/C,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACpB,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,YAAY,OAAA,CAAQ,MAAA,IAAUC,KAAK,GAAA,EAAK,MAAA,CAAO,aAAa,QAAQ,CAAA;AAC1E,EAAA,MAAM,UAAA,GAAaA,KAAK,SAAA,EAAW,CAAA,EAAG,MAAM,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,GAAA,CAAK,CAAA;AAEzD,EAAA,IAAIJ,UAAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,MAAMG,MAAAA,CAAM,GAAA,CAAI,CAAA,8BAAA,EAAiC,UAAU,EAAE,CAAC,CAAA;AACtE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAAM,aAAAA,CAAc,YAAY,QAAQ,CAAA;AAClC,EAAA,OAAA,CAAQ,IAAIN,MAAAA,CAAM,KAAA,CAAM,CAAA,kBAAA,EAAgB,UAAU,EAAE,CAAC,CAAA;AACvD;AAOA,SAAS,gBAAA,CAAiB,OAAY,EAAA,EAAoB;AACxD,EAAA,MAAM,WAAW,KAAA,CAAM,IAAA;AACvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,GAAA,EAAM,QAAQ,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAA;AAClC,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,CAAA,8BAAA,CAAgC,CAAA;AAC3C,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,CAAA,cAAA,EAAiB,QAAQ,CAAA,mBAAA,EAAsB,KAAA,CAAM,EAAE,CAAA,EAAA,CAAI,CAAA;AACtE,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,SAAA,CAAU,EAAE,CAAC,CAAA,EAAA,EAAK,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC3D,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,EAAE,CAAA,EAAA,CAAI,CAAA;AAC3B,EAAA,KAAA,CAAM,KAAK,CAAA,sCAAA,CAAwC,CAAA;AACnD,EAAA,KAAA,CAAM,KAAK,CAAA,EAAA,CAAI,CAAA;AACf,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CACJ,WAAA,EAAY,CACZ,OAAA,CAAQ,UAAA,EAAY,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAClD;AC1EA,eAAsB,aAAA,CAAc,UAAkB,OAAA,EAA8C;AAClG,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,mBAAmB,CAAC,CAAA;AAC3C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,uBAAuB,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,iCAAiC,CAAC,CAAA;AACzD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAC9C,EAAA,MAAM,WAAW,OAAA,CAAQ,KAAA,GAAQ,SAAS,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,CAAA;AAE/D,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAQ,EAAE,CAAC,CAAA;AAC/C,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAQ,EAAE,CAAC,CAAA;AAC/C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAGpD,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,QAAA,EAAU,QAAQ,CAAA;AAC1C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAA,CAAQ,MAAMA,MAAAA,CAAM,GAAA,CAAI,CAAA,iBAAA,EAAoB,QAAQ,aAAa,CAAC,CAAA;AAClE,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAGA,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uBAAuB,CAAC,CAAA;AAC/C,IAAA,MAAM,SAAS,aAAA,CAAc,QAAA,EAAU,QAAA,EAAU,MAAA,CAAO,MAAM,QAAQ,CAAA;AAGtE,IAAA,mBAAA,CAAoB,QAAQ,OAAO,CAAA;AAAA,EAErC,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,yBAAyB,GAAG,KAAK,CAAA;AACzD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAAS,QAAA,CAAS,UAAyB,EAAA,EAAoD;AAC7F,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAClD,IAAA,IAAI,GAAA,YAAe,GAAA,IAAO,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AACrC,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAE;AAAA,IACnC;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,aAAA,CACP,QAAA,EACA,QAAA,EACA,UAAA,EACA,QAAA,EACc;AACd,EAAA,MAAM,gBAA8B,EAAC;AACrC,EAAA,MAAM,OAAA,mBAAU,IAAI,GAAA,CAAY,CAAC,QAAQ,CAAC,CAAA;AAG1C,EAAA,SAAS,cAAA,CAAe,IAAY,KAAA,EAAqB;AACvD,IAAA,IAAI,QAAQ,QAAA,EAAU;AAEtB,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAClD,MAAA,IAAI,EAAE,eAAe,GAAA,CAAA,EAAM;AAE3B,MAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,IAAI,CAAA,IAAK,GAAA,EAAK;AAChC,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAG;AAGzB,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACnC,QAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,CAAA,CAAA,EAAI,EAAE,GAAG,CAAA,EAAG;AAC/B,UAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAClB,UAAA,aAAA,CAAc,IAAA,CAAK;AAAA,YACjB,EAAA,EAAI,MAAA;AAAA,YACJ,IAAA;AAAA,YACA,KAAA;AAAA,YACA,UAAA,EAAY,KAAA,KAAU,CAAA,GAAI,QAAA,GAAW;AAAA,WACtC,CAAA;AAGD,UAAA,cAAA,CAAe,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,cAAA,CAAe,UAAU,CAAC,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,QAAA;AAAA,IACR,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAMA,SAAS,mBAAA,CAAoB,QAAsB,OAAA,EAAqC;AACtF,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAC7B,IAAA,OAAA,CAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,SAAA,EAAW;AAChC,IAAA,OAAA,CAAQ,IAAI,YAAY,CAAA;AACxB,IAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AACtB,IAAA,OAAA,CAAQ,IAAI,CAAA,IAAA,EAAO,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AACpD,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,aAAA,EAAe;AACvC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,KAAe,QAAA,GAAW,aAAA,GAAgB,gBAAA;AAC7D,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,IAAA,EAAO,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACpE;AACA,IAAA,OAAA,CAAQ,IAAI,KAAK,CAAA;AACjB,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG;AACrC,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,8BAA8B,CAAC,CAAA;AACvD,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,eAAe,QAAQ,CAAA;AACzE,EAAA,MAAM,WAAW,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,eAAe,UAAU,CAAA;AAE7E,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,oBAAoB,MAAA,CAAO,MAAM,IAAI,CAAC,CAAA;AAC/D,IAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,WAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAA,EAAK,IAAA,CAAK,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,IAC7D;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,sBAAsB,QAAA,CAAS,MAAM,IAAI,CAAC,CAAA;AACjE,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAA,EAAK,IAAA,CAAK,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,KAAK,GAAG,CAAC,CAAA;AAAA,IACjF;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,SAAA,EAAY,OAAO,aAAA,CAAc,MAAM,oBAAoB,CAAC,CAAA;AACrF;AC/KA,IAAMO,YAAA,GAAa,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAMC,WAAA,GAAYV,QAAQS,YAAU,CAAA;AAEpC,eAAsB,OAAA,CAAQ,OAAA,GAAuB,EAAC,EAAkB;AACtE,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAExB,EAAA,OAAA,CAAQ,GAAA,CAAIP,MAAAA,CAAM,IAAA,CAAK,iBAAiB,CAAC,CAAA;AACzC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAGd,EAAA,MAAM,SAAA,GAAYC,IAAAA,CAAK,GAAA,EAAK,QAAQ,CAAA;AACpC,EAAA,MAAM,UAAA,GAAaA,IAAAA,CAAK,GAAA,EAAK,sBAAsB,CAAA;AAEnD,EAAA,IAAI,CAAC,QAAQ,KAAA,KAAUJ,UAAAA,CAAW,SAAS,CAAA,IAAKA,UAAAA,CAAW,UAAU,CAAA,CAAA,EAAI;AACvE,IAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,MAAA,CAAO,gCAAgC,CAAC,CAAA;AAC1D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,4CAA4C,CAAC,CAAA;AACpE,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,cAAc,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,YAAA;AAG5C,EAAA,MAAM,YAAA,GAAeC,IAAAA,CAAKO,WAAA,EAAW,WAAA,EAAa,MAAM,CAAA;AAExD,EAAA,IAAI,CAACX,UAAAA,CAAW,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAA,CAAQ,IAAIG,MAAAA,CAAM,GAAA,CAAI,CAAA,0CAAA,EAA6C,YAAY,EAAE,CAAC,CAAA;AAClF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,oDAAoD,CAAC,CAAA;AAC5E,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,EAAA,eAAA,CAAgB,YAAA,EAAc,KAAK,WAAA,EAAa,OAAA,CAAQ,SAAS,KAAA,EAAO,CAAC,cAAc,OAAA,KAAY;AACjG,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,KAAA,CAAM,CAAA,WAAA,EAAc,YAAY,EAAE,CAAC,CAAA;AACrD,MAAA,IAAI,iBAAiB,cAAA,EAAgB;AACnC,QAAA,kBAAA,GAAqB,IAAA;AAAA,MACvB;AAAA,IACF,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,WAAA,EAAc,YAAY,mBAAmB,CAAC,CAAA;AAAA,IACzE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qCAAqC,CAAC,CAAA;AAC7D,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,IAAI,eAAe,CAAA;AAC3B,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kDAAkD,CAAC,CAAA;AAC1E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sDAAsD,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sCAAsC,CAAC,CAAA;AAC9D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,8CAA8C,CAAC,CAAA;AAAA,EACxE,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,iEAAiE,CAAC,CAAA;AACzF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uDAAuD,CAAC,CAAA;AAC/E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sDAAsD,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sCAAsC,CAAC,CAAA;AAC9D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,8CAA8C,CAAC,CAAA;AAAA,EACxE;AACF;AAKA,SAAS,gBACP,MAAA,EACA,OAAA,EACA,aACA,KAAA,EACA,MAAA,EACA,eAAuB,EAAA,EACjB;AACN,EAAA,MAAM,OAAA,GAAUS,YAAY,MAAM,CAAA;AAElC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,OAAA,GAAUR,IAAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAClC,IAAA,MAAM,IAAA,GAAOS,SAAS,OAAO,CAAA;AAG7B,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,WAAW,IAAI,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,KAAA;AACrE,IAAA,MAAM,QAAA,GAAWT,IAAAA,CAAK,OAAA,EAAS,SAAS,CAAA;AACxC,IAAA,MAAM,OAAA,GAAU,YAAA,GAAeA,IAAAA,CAAK,YAAA,EAAc,SAAS,CAAA,GAAI,SAAA;AAE/D,IAAA,IAAI,IAAA,CAAK,aAAY,EAAG;AAEtB,MAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,QAAAc,SAAAA,CAAU,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,QAAA,MAAA,CAAO,OAAA,GAAU,KAAK,IAAI,CAAA;AAAA,MAC5B;AAEA,MAAA,eAAA,CAAgB,OAAA,EAAS,QAAA,EAAU,WAAA,EAAa,KAAA,EAAO,QAAQ,OAAO,CAAA;AAAA,IACxE,CAAA,MAAO;AAEL,MAAA,IAAI,CAAC,KAAA,IAASd,UAAAA,CAAW,QAAQ,CAAA,EAAG;AAClC,QAAA,MAAA,CAAO,SAAS,KAAK,CAAA;AACrB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,OAAA,GAAUE,YAAAA,CAAa,OAAA,EAAS,OAAO,CAAA;AAG3C,MAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,uBAAA,EAAyB,WAAW,CAAA;AAG9D,MAAA,MAAM,GAAA,GAAMD,QAAQ,QAAQ,CAAA;AAC5B,MAAA,IAAI,CAACD,UAAAA,CAAW,GAAG,CAAA,EAAG;AACpB,QAAAc,SAAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,MACpC;AACA,MAAAL,aAAAA,CAAc,UAAU,OAAO,CAAA;AAC/B,MAAA,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,IACtB;AAAA,EACF;AACF;;;ACrHA,IAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAE5B,OAAA,CACG,KAAK,YAAY,CAAA,CACjB,YAAY,kEAAkE,CAAA,CAC9E,QAAQ,OAAO,CAAA;AAIlB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,kDAAkD,CAAA,CAC9D,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,4BAAA,EAA8B,GAAG,CAAA,CAC/D,MAAA,CAAO,uBAAA,EAAyB,qCAAA,EAAuC,MAAM,CAAA,CAC7E,MAAA,CAAO,aAAA,EAAe,uCAAuC,CAAA,CAC7D,MAAA,CAAO,eAAA,EAAiB,sBAAsB,CAAA,CAC9C,OAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,MAAM,CAAA,CACd,WAAA,CAAY,4EAA4E,CAAA,CACxF,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,kDAAkD,CAAA,CAChF,MAAA,CAAO,cAAA,EAAgB,0BAA0B,CAAA,CACjD,MAAA,CAAO,OAAA,EAAS,oCAAoC,CAAA,CACpD,MAAA,CAAO,uBAAA,EAAyB,mCAAA,EAAqC,MAAM,CAAA,CAC3E,MAAA,CAAO,WAAW,CAAA;AAIrB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,oDAAoD,CAAA,CAChE,MAAA,CAAO,uBAAuB,qBAAqB,CAAA,CACnD,OAAO,cAAA,EAAgB,sCAAsC,EAC7D,MAAA,CAAO,uBAAA,EAAyB,mCAAmC,MAAM,CAAA,CACzE,OAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,2DAA2D,CAAA,CACvE,QAAA,CAAS,QAAA,EAAU,oEAAoE,CAAA,CACvF,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,UAAA,EAAY,0BAA0B,CAAA,CAC7C,MAAA,CAAO,eAAA,EAAiB,sBAAsB,CAAA,CAC9C,MAAA,CAAO,YAAA,EAAc,mEAAmE,CAAA,CACxF,MAAA,CAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,KAAK,CAAA,CACb,WAAA,CAAY,6CAA6C,CAAA,CACzD,QAAA,CAAS,QAAA,EAAU,+EAA+E,CAAA,CAClG,MAAA,CAAO,mBAAA,EAAqB,8DAA8D,CAAA,CAC1F,MAAA,CAAO,mBAAA,EAAqB,qBAAqB,CAAA,CACjD,MAAA,CAAO,qBAAA,EAAuB,uBAAuB,CAAA,CACrD,MAAA,CAAO,uBAAA,EAAyB,uBAAuB,CAAA,CACvD,MAAA,CAAO,UAAU,CAAA;AAIpB,OAAA,CACG,OAAA,CAAQ,QAAQ,CAAA,CAChB,WAAA,CAAY,oCAAoC,CAAA,CAChD,QAAA,CAAS,MAAA,EAAQ,0CAA0C,CAAA,CAC3D,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,2CAAA,EAA6C,GAAG,CAAA,CAC9E,MAAA,CAAO,yBAAA,EAA2B,gDAAA,EAAkD,MAAM,CAAA,CAC1F,MAAA,CAAO,uBAAA,EAAyB,oCAAA,EAAsC,MAAM,CAAA,CAC5E,OAAO,aAAa,CAAA;AAGvB,OAAA,CACG,OAAA,CAAQ,MAAM,CAAA,CACd,WAAA,CAAY,4DAA4D,CAAA,CACxE,MAAA,CAAO,aAAA,EAAe,0BAA0B,CAAA,CAChD,MAAA,CAAO,OAAO,CAAA;AAGjB,OAAA,CAAQ,KAAA,EAAM","file":"cli.js","sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Specification-compliant output path definitions\n * \n * Human-readable artifacts (docs/):\n * requirements/ - Requirements Markdown\n * usecases/ - Use cases\n * architecture/ - Architecture (C4 diagrams)\n * data-model/ - Conceptual model (ER diagrams)\n * screens/ - Screen specifications\n * flows/ - Process flows\n * glossary/ - Glossary\n * \n * Machine-readable artifacts (specs/):\n * schemas/entities/ - Entity JSON Schema\n * index.json - Aggregated data\n */\nexport interface OutputPaths {\n // docs/ subdirectories\n requirements: string;\n usecases: string;\n architecture: string;\n dataModel: string;\n screens: string;\n flows: string;\n glossary: string;\n component: string;\n \n // specs/ subdirectories\n schemasEntities: string;\n}\n\nexport interface SpeckeeperConfig {\n // Project info\n projectName?: string;\n version?: string;\n \n // Source paths\n srcDir: string;\n requirementsDir?: string;\n designDir?: string;\n usecasesDir?: string;\n \n // Output paths\n docsDir: string;\n specsDir: string;\n \n // External SSOT paths\n externalSsot?: {\n openapi?: {\n enabled: boolean;\n paths: string[];\n microContracts?: {\n enabled: boolean;\n requiredExtensions?: string[];\n strictMode?: boolean;\n };\n };\n ddl?: {\n enabled: boolean;\n paths: string[];\n type: 'ddl' | 'prisma' | 'typeorm' | 'drizzle';\n };\n iac?: {\n enabled: boolean;\n paths: string[];\n type: 'cloudformation' | 'terraform' | 'cdk';\n };\n };\n \n // Lint configuration\n lint?: {\n architecture?: {\n allowCrossBoundaryDependencies?: boolean;\n allowCrossLayerViolations?: boolean;\n maxComponentsPerDiagram?: number;\n };\n conceptModel?: {\n requireEntityDescription?: boolean;\n requireAggregateRoot?: boolean;\n warnOnOrphanEntities?: boolean;\n namingConvention?: 'PascalCase' | 'camelCase' | 'snake_case' | 'none';\n };\n screen?: {\n warnOnOrphanScreens?: boolean;\n warnOnDeadEnds?: boolean;\n checkAuthPaths?: boolean;\n };\n phaseGate?: {\n currentPhase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strictMode?: boolean;\n };\n };\n \n // Build configuration\n build?: {\n generateMermaidImages?: boolean;\n mermaidCliPath?: string;\n };\n \n // Custom model definitions\n models?: unknown[];\n}\n\n// Default configuration\nconst defaultConfig: SpeckeeperConfig = {\n srcDir: 'src',\n designDir: 'design', // Directory for requirements/design TS models\n docsDir: 'docs',\n specsDir: 'specs',\n};\n\n// ============================================================================\n// Output Paths (spec-compliant)\n// ============================================================================\n\n/**\n * Get output paths compliant with specification\n */\nexport function getOutputPaths(config: SpeckeeperConfig, cwd: string = process.cwd()): OutputPaths {\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n return {\n // docs/ subdirectories (compliant with spec section 7.1)\n requirements: join(docsDir, 'requirements'),\n usecases: join(docsDir, 'usecases'),\n architecture: join(docsDir, 'architecture'),\n dataModel: join(docsDir, 'data-model'),\n screens: join(docsDir, 'screens'),\n flows: join(docsDir, 'flows'),\n glossary: join(docsDir, 'glossary'),\n component: join(docsDir, 'component'),\n \n // specs/ subdirectories (compliant with spec section 7.1)\n schemasEntities: join(specsDir, 'schemas', 'entities'),\n };\n}\n\n/**\n * List of expected output paths (for drift check)\n */\nexport function getExpectedOutputDirs(config: SpeckeeperConfig, cwd: string = process.cwd()): string[] {\n const paths = getOutputPaths(config, cwd);\n return [\n paths.requirements,\n paths.usecases,\n paths.architecture,\n paths.dataModel,\n paths.screens,\n paths.flows,\n paths.glossary,\n paths.component,\n paths.schemasEntities,\n ];\n}\n\n/**\n * Validate if output path complies with specification\n */\nexport function validateOutputPaths(actualPath: string, config: SpeckeeperConfig, cwd: string = process.cwd()): {\n valid: boolean;\n expectedPaths: string[];\n message?: string;\n} {\n const expectedDirs = getExpectedOutputDirs(config, cwd);\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n // Check if actualPath is under docs/ or specs/\n const isUnderDocs = actualPath.startsWith(docsDir);\n const isUnderSpecs = actualPath.startsWith(specsDir);\n \n if (!isUnderDocs && !isUnderSpecs) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" is not under docs/ or specs/`,\n };\n }\n \n // Check if under any of the expected paths\n const isValidPath = expectedDirs.some(dir => actualPath.startsWith(dir));\n \n if (!isValidPath) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" does not match spec-compliant paths. Expected one of: ${expectedDirs.map(d => d.replace(cwd + '/', '')).join(', ')}`,\n };\n }\n \n return { valid: true, expectedPaths: expectedDirs };\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nconst CONFIG_FILES = [\n 'speckeeper.config.yaml',\n 'speckeeper.config.yml',\n 'speckeeper.config.json',\n 'speckeeper.config.ts',\n 'speckeeper.config.js',\n];\n\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n \n while (currentDir !== dirname(currentDir)) {\n for (const configFile of CONFIG_FILES) {\n const configPath = resolve(currentDir, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n \n return null;\n}\n\nexport async function loadConfig(\n configPath?: string,\n cwd: string = process.cwd()\n): Promise<SpeckeeperConfig> {\n const resolvedPath = configPath ?? findConfigFile(cwd);\n \n if (!resolvedPath) {\n return { ...defaultConfig };\n }\n \n const ext = resolvedPath.split('.').pop()?.toLowerCase();\n \n try {\n if (ext === 'yaml' || ext === 'yml') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = parseYaml(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'json') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'ts' || ext === 'js') {\n // Dynamic import for TS/JS config\n const module = await import(resolvedPath);\n const parsed = module.default ?? module;\n return { ...defaultConfig, ...parsed };\n }\n \n return { ...defaultConfig };\n } catch (error) {\n console.error(`Failed to load config from ${resolvedPath}:`, error);\n return { ...defaultConfig };\n }\n}\n\n// ============================================================================\n// Configuration Validation\n// ============================================================================\n\nexport function validateConfig(config: SpeckeeperConfig): string[] {\n const errors: string[] = [];\n \n if (!config.srcDir) {\n errors.push('srcDir is required');\n }\n \n if (!config.docsDir) {\n errors.push('docsDir is required');\n }\n \n if (!config.specsDir) {\n errors.push('specsDir is required');\n }\n \n return errors;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\nexport interface WriteResult {\n path: string;\n created: boolean;\n updated: boolean;\n unchanged: boolean;\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\nexport function writeFile(filePath: string, content: string): WriteResult {\n const dir = dirname(filePath);\n ensureDir(dir);\n \n const existed = existsSync(filePath);\n let unchanged = false;\n \n if (existed) {\n const existingContent = readFileSync(filePath, 'utf-8');\n unchanged = existingContent === content;\n }\n \n if (!unchanged) {\n writeFileSync(filePath, content, 'utf-8');\n }\n \n return {\n path: filePath,\n created: !existed,\n updated: existed && !unchanged,\n unchanged,\n };\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, indent: number = 2): WriteResult {\n const content = JSON.stringify(data, null, indent) + '\\n';\n return writeFile(filePath, content);\n}\n\n// ============================================================================\n// Batch Writing\n// ============================================================================\n\nexport interface BatchWriteResult {\n results: WriteResult[];\n created: number;\n updated: number;\n unchanged: number;\n total: number;\n}\n\nexport function batchWriteFiles(\n files: Array<{ path: string; content: string }>\n): BatchWriteResult {\n const results: WriteResult[] = [];\n \n for (const { path, content } of files) {\n results.push(writeFile(path, content));\n }\n \n return {\n results,\n created: results.filter(r => r.created).length,\n updated: results.filter(r => r.updated).length,\n unchanged: results.filter(r => r.unchanged).length,\n total: results.length,\n };\n}\n\n// ============================================================================\n// Drift Detection\n// ============================================================================\n\nexport interface DriftResult {\n file: string;\n hasDrift: boolean;\n expectedHash?: string;\n actualHash?: string;\n missing?: boolean;\n}\n\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function checkFileDrift(\n filePath: string,\n expectedContent: string\n): DriftResult {\n const expectedHash = computeHash(expectedContent);\n \n if (!existsSync(filePath)) {\n return {\n file: filePath,\n hasDrift: true,\n expectedHash,\n missing: true,\n };\n }\n \n const actualContent = readFileSync(filePath, 'utf-8');\n const actualHash = computeHash(actualContent);\n \n return {\n file: filePath,\n hasDrift: expectedHash !== actualHash,\n expectedHash,\n actualHash,\n };\n}\n\nexport function checkBatchDrift(\n files: Array<{ path: string; content: string }>\n): DriftResult[] {\n return files.map(({ path, content }) => checkFileDrift(path, content));\n}\n\n// ============================================================================\n// File Discovery\n// ============================================================================\n\nimport { glob } from 'glob';\n\nexport async function findFiles(\n pattern: string,\n cwd: string = process.cwd()\n): Promise<string[]> {\n return glob(pattern, { cwd, absolute: true });\n}\n\nexport async function findTypeScriptFiles(\n srcDir: string\n): Promise<string[]> {\n return findFiles('**/*.ts', srcDir);\n}\n\nexport async function findDefinitionFiles(\n srcDir: string,\n subDir: string\n): Promise<string[]> {\n const pattern = join(srcDir, subDir, '**/*.ts');\n return glob(pattern, { absolute: true, ignore: ['**/*.d.ts', '**/index.ts'] });\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\nexport function generateDocsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n\nexport function generateSpecsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n","/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Model base class\n * \n * All model definitions inherit from this class\n */\nimport { z, ZodType } from 'zod';\nimport {\n type ModelLevel,\n type Relation,\n type RelationValidationError,\n validateRelationLevel,\n detectCycles,\n inferModelIdFromSpecId,\n} from './relation.js';\n\n// Re-export relation types\nexport type { ModelLevel, Relation, RelationValidationError };\nexport { RELATION_TYPES, RELATION_CONSTRAINTS, RelationSchema, RelationsFieldSchema } from './relation.js';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Lint rule definition\n */\nexport interface LintRule<T> {\n id: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n check: (spec: T) => boolean; // true if there is an issue\n}\n\n/**\n * Lint result\n */\nexport interface LintResult {\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n specId?: string;\n}\n\n/**\n * Exporter definition\n */\nexport interface Exporter<T> {\n format: 'markdown' | 'json' | 'mermaid';\n single?: (spec: T) => string;\n index?: (specs: T[]) => string;\n outputDir?: string;\n filename?: (spec: T) => string;\n}\n\n/**\n * External checker definition\n */\nexport interface ExternalChecker<T> {\n targetType: string; // 'openapi' | 'ddl' | 'cli' etc.\n sourcePath: (spec: T) => string;\n check: (spec: T, externalData: unknown) => CheckResult;\n}\n\n/**\n * Check result\n */\nexport interface CheckResult {\n success: boolean;\n errors: { message: string; field?: string; specId?: string }[];\n warnings: { message: string; field?: string; specId?: string }[];\n}\n\n/**\n * Coverage result\n */\nexport interface CoverageResult {\n /** Total target count */\n total: number;\n /** Covered count */\n covered: number;\n /** Uncovered count */\n uncovered: number;\n /** Coverage rate (%) */\n coveragePercent: number;\n /** Details of covered items */\n coveredItems: { id: string; description?: string }[];\n /** Details of uncovered items */\n uncoveredItems: { id: string; description?: string; sourceId?: string }[];\n}\n\n/**\n * Coverage checker definition\n * \n * Verify cross-model consistency (coverage).\n * Example: Whether TestRef covers acceptanceCriteria of Requirement\n */\nexport interface CoverageChecker<T> {\n /** Target model ID for coverage (e.g. 'requirement') */\n targetModel: string;\n /** Description of coverage check */\n description: string;\n /** Execute coverage check */\n check: (\n specs: T[],\n registry: Record<string, Map<string, unknown>>\n ) => CoverageResult;\n}\n\n// ============================================================================\n// Renderer (for embeds)\n// ============================================================================\n\n/**\n * Render context\n * Simplified version compatible with embedoc's EmbedContext\n */\nexport interface RenderContext {\n /** Parameters (filter conditions other than format, etc.) */\n params: Record<string, string | undefined>;\n /** Markdown helpers */\n markdown: {\n /** Generate table */\n table: (headers: string[], rows: (string | unknown)[][]) => string;\n };\n}\n\n/**\n * Renderer definition\n * \n * Model-specific rendering called from embeds\n */\nexport interface Renderer<T> {\n /** Format ID ('table', 'list', 'detail', 'spec-chapter', etc.) */\n format: string;\n /** Rendering process */\n render: (specs: T[], ctx: RenderContext) => string;\n}\n\n// ============================================================================\n// Model Base Class\n// ============================================================================\n\n/**\n * Model base class\n * \n * @template TSchema - Zod schema type\n */\nexport abstract class Model<TSchema extends ZodType> {\n /** Singleton instance storage (per subclass) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _instances: WeakMap<new () => any, Model<ZodType>> = new WeakMap();\n\n /**\n * Get singleton instance of the model\n * Usage: RequirementModel.instance\n */\n static get instance(): Model<ZodType> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctor = this as unknown as new () => any;\n if (!this._instances.has(ctor)) {\n this._instances.set(ctor, new ctor());\n }\n return this._instances.get(ctor)!;\n }\n\n /** Model ID ('requirement', 'usecase', etc.) */\n abstract readonly id: string;\n \n /** Model name ('Requirement', 'UseCase', etc.) */\n abstract readonly name: string;\n \n /** ID prefix ('REQ', 'UC', etc.) */\n abstract readonly idPrefix: string;\n \n /** Zod schema */\n abstract readonly schema: TSchema;\n \n /** Model description (optional) */\n readonly description?: string;\n \n /** External SSOT type (optional, e.g. 'OpenAPI', 'DDL/Prisma') */\n readonly externalSsotType?: string;\n \n /** Spec instance type */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected get specType(): z.infer<TSchema> { return undefined as any; }\n \n /** Lint rules (override in subclass) */\n protected lintRules: LintRule<z.infer<TSchema>>[] = [];\n \n /** Exporters (override in subclass) */\n protected exporters: Exporter<z.infer<TSchema>>[] = [];\n \n /** External checker (optional) */\n protected externalChecker?: ExternalChecker<z.infer<TSchema>>;\n \n /** Coverage checker (optional) */\n protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;\n \n /** Model level (set in _models/) */\n protected modelLevel?: ModelLevel;\n \n /** Renderers (for embeds, override in subclass) */\n protected renderers: Renderer<z.infer<TSchema>>[] = [];\n \n /**\n * Get model level\n * Returns modelLevel set in _models/\n */\n get level(): ModelLevel | undefined {\n return this.modelLevel;\n }\n \n /**\n * Execute schema validation\n */\n validate(spec: unknown): z.infer<TSchema> {\n return this.schema.parse(spec);\n }\n \n /**\n * Schema validation (safe version, returns error object on failure)\n */\n safeParse(spec: unknown): { success: true; data: z.infer<TSchema> } | { success: false; error: z.ZodError } {\n return this.schema.safeParse(spec);\n }\n \n /**\n * Execute lint\n */\n lint(spec: z.infer<TSchema>): LintResult[] {\n const specId = (spec as { id?: string }).id;\n return this.lintRules\n .filter(rule => rule.check(spec))\n .map(rule => ({\n ruleId: rule.id,\n severity: rule.severity,\n message: rule.message,\n specId,\n }));\n }\n \n /**\n * Execute lint for multiple specs\n */\n lintAll(specs: z.infer<TSchema>[]): LintResult[] {\n return specs.flatMap(spec => this.lint(spec));\n }\n \n /**\n * Validate level constraints of relations\n * @param spec - Spec instance (if it has relations property)\n * @returns Array of validation errors\n */\n validateRelations(spec: z.infer<TSchema>): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n \n if (!specWithRelations.relations || !specWithRelations.id) {\n return errors;\n }\n \n // Get all models to retrieve target model levels\n const allModels = getAllModels();\n const modelLevelMap = new Map<string, ModelLevel | undefined>();\n for (const model of allModels) {\n modelLevelMap.set(model.id, model.level);\n }\n \n for (const relation of specWithRelations.relations) {\n // Infer target model ID\n const targetModelId = inferModelIdFromSpecId(relation.target);\n if (!targetModelId) {\n continue; // Skip if model ID cannot be inferred\n }\n \n const targetLevel = modelLevelMap.get(targetModelId);\n \n const error = validateRelationLevel(\n this.level,\n specWithRelations.id,\n relation,\n targetLevel,\n );\n \n if (error) {\n errors.push(error);\n }\n }\n \n return errors;\n }\n \n /**\n * Validate relations of multiple specs (including circular reference check)\n */\n validateAllRelations(specs: z.infer<TSchema>[]): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const allRelations: Array<{ sourceId: string; targetId: string; type: string }> = [];\n \n for (const spec of specs) {\n // Individual level constraint check\n errors.push(...this.validateRelations(spec));\n \n // Collect relations for circular reference check\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n if (specWithRelations.relations && specWithRelations.id) {\n for (const rel of specWithRelations.relations) {\n allRelations.push({\n sourceId: specWithRelations.id,\n targetId: rel.target,\n type: rel.type,\n });\n }\n }\n }\n \n // Circular reference check\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors.push(...detectCycles(allRelations as any));\n \n return errors;\n }\n \n /**\n * Export in specified format (single spec)\n */\n exportSingle(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.single) return null;\n return exporter.single(spec);\n }\n \n /**\n * Export in specified format (index)\n */\n exportIndex(specs: z.infer<TSchema>[], format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.index) return null;\n return exporter.index(specs);\n }\n \n /**\n * Get exporter output directory\n */\n getOutputDir(format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n return exporter?.outputDir ?? null;\n }\n \n /**\n * Get filename\n */\n getFilename(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.filename) return null;\n return exporter.filename(spec);\n }\n \n /**\n * Check consistency with external SSOT\n */\n check(spec: z.infer<TSchema>, externalData: unknown): CheckResult {\n if (!this.externalChecker) {\n return { success: true, errors: [], warnings: [] };\n }\n return this.externalChecker.check(spec, externalData);\n }\n \n /**\n * Get external SSOT path\n */\n getExternalSourcePath(spec: z.infer<TSchema>): string | null {\n if (!this.externalChecker) return null;\n return this.externalChecker.sourcePath(spec);\n }\n \n /**\n * Execute coverage check\n * @param specs - Array of spec instances for this model\n * @param registry - Registry of all models\n */\n checkCoverage(\n specs: z.infer<TSchema>[],\n registry: Record<string, Map<string, unknown>>\n ): CoverageResult | null {\n if (!this.coverageChecker) return null;\n return this.coverageChecker.check(specs, registry);\n }\n \n /**\n * Get coverage checker\n */\n getCoverageChecker(): CoverageChecker<z.infer<TSchema>> | undefined {\n return this.coverageChecker;\n }\n \n /**\n * Get lint rules\n */\n getLintRules(): LintRule<z.infer<TSchema>>[] {\n return this.lintRules;\n }\n \n /**\n * Get exporters\n */\n getExporters(): Exporter<z.infer<TSchema>>[] {\n return this.exporters;\n }\n \n // ============================================================================\n // Renderer (for embeds)\n // ============================================================================\n \n /**\n * Render in specified format\n * @param format - Format ID ('table', 'list', 'detail', etc.)\n * @param specs - Array of specs to render\n * @param ctx - Render context\n * @returns Rendered result (Markdown string), null if no matching renderer\n */\n render(format: string, specs: z.infer<TSchema>[], ctx: RenderContext): string | null {\n const renderer = this.renderers.find(r => r.format === format);\n if (!renderer) return null;\n return renderer.render(specs, ctx);\n }\n \n /**\n * Get list of available formats\n */\n getAvailableFormats(): string[] {\n return this.renderers.map(r => r.format);\n }\n \n /**\n * Get renderers\n */\n getRenderers(): Renderer<z.infer<TSchema>>[] {\n return this.renderers;\n }\n \n /**\n * Check if renderer exists for specific format\n */\n hasRenderer(format: string): boolean {\n return this.renderers.some(r => r.format === format);\n }\n}\n\n// ============================================================================\n// Model Registry\n// ============================================================================\n\n/** Map of registered models */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modelRegistry = new Map<string, Model<any>>();\n\n/**\n * Register model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerModel(model: Model<any>): void {\n modelRegistry.set(model.id, model);\n}\n\n/**\n * Get model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getModel(id: string): Model<any> | undefined {\n return modelRegistry.get(id);\n}\n\n/**\n * Get all registered models\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getAllModels(): Model<any>[] {\n return Array.from(modelRegistry.values());\n}\n\n/**\n * Clear registry\n */\nexport function clearModelRegistry(): void {\n modelRegistry.clear();\n}\n","/**\n * Build Command\n * \n * Generate documents and schemas using model class exporters\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { batchWriteFiles, ensureDir } from '../utils/file-writer.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Build Command Options\n// ============================================================================\n\nexport interface BuildCommandOptions {\n config?: string;\n output?: string;\n format?: 'markdown' | 'json' | 'both';\n verbose?: boolean;\n clean?: boolean;\n}\n\n// ============================================================================\n// Build Command\n// ============================================================================\n\nexport async function buildCommand(options: BuildCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper build'));\n console.log('');\n \n const cwd = process.cwd();\n \n // Load config\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths(config, cwd) if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log(chalk.gray(` Specs: ${config.specsDir}/`));\n console.log('');\n \n try {\n // Ensure base output directories exist\n ensureDir(join(cwd, config.docsDir));\n ensureDir(join(cwd, config.specsDir));\n \n const files: Array<{ path: string; content: string }> = [];\n const models = getAllModels();\n \n if (models.length === 0) {\n console.log(chalk.yellow(' No models registered. Run model registration first.'));\n return;\n }\n \n console.log(chalk.blue(` Processing ${models.length} model types...`));\n \n // Process each model type\n for (const model of models) {\n const exporters = model.getExporters();\n \n if (exporters.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no exporters defined`));\n }\n continue;\n }\n \n // TODO: Load specs for this model from design/ directory\n // For now, this is a placeholder - actual implementation needs\n // to load specs from the appropriate design/*.ts files\n const specs: unknown[] = [];\n \n if (specs.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no specs found`));\n }\n continue;\n }\n \n for (const exporter of exporters) {\n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n ensureDir(outputDir);\n \n // Generate individual files\n if (exporter.single) {\n for (const spec of specs) {\n const content = exporter.single(spec);\n const filename = model.getFilename(spec, exporter.format) || (spec as { id: string }).id;\n files.push({\n path: join(outputDir, `${filename}.md`),\n content,\n });\n }\n }\n \n // Generate index file\n if (exporter.index) {\n const indexContent = exporter.index(specs);\n files.push({\n path: join(outputDir, 'index.md'),\n content: indexContent,\n });\n }\n }\n \n console.log(chalk.green(` ✓ ${model.name}`));\n }\n \n // Write all files\n if (files.length > 0) {\n console.log('');\n console.log(chalk.blue(` Writing ${files.length} files...`));\n \n const result = await batchWriteFiles(files);\n \n console.log('');\n console.log(chalk.green(` ✓ Build complete`));\n console.log(chalk.gray(` Created: ${result.created}`));\n console.log(chalk.gray(` Updated: ${result.updated}`));\n console.log(chalk.gray(` Unchanged: ${result.unchanged}`));\n } else {\n console.log(chalk.yellow(' No files to generate.'));\n }\n \n } catch (error) {\n console.error(chalk.red('Build failed:'), error);\n process.exit(1);\n }\n}\n","/**\n * Model Loader\n * \n * Load models defined in TypeScript and convert to usable format for build command\n */\n\nimport { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve, extname, basename } from 'node:path';\nimport type { SpeckeeperConfig } from './config-loader.js';\nimport { registerModel as coreRegisterModel } from '../core/model.js';\n\n// ============================================================================\n// Registry Types\n// ============================================================================\n\n/**\n * Model registry - stores all loaded models\n */\nexport interface ModelRegistry {\n requirements: Map<string, unknown>;\n useCases: Map<string, unknown>;\n actors: Map<string, unknown>;\n components: Map<string, unknown>;\n entities: Map<string, unknown>;\n relations: Map<string, unknown>;\n rules: Map<string, unknown>;\n screens: Map<string, unknown>;\n transitions: Map<string, unknown>;\n forms: Map<string, unknown>;\n processFlows: Map<string, unknown>;\n glossaryTerms: Map<string, unknown>;\n apiRefs: Map<string, unknown>;\n tableRefs: Map<string, unknown>;\n testRefs: Map<string, unknown>;\n layers: Map<string, unknown>;\n boundaries: Map<string, unknown>;\n artifacts: Map<string, unknown>;\n}\n\nexport function createEmptyRegistry(): ModelRegistry {\n return {\n requirements: new Map(),\n useCases: new Map(),\n actors: new Map(),\n components: new Map(),\n entities: new Map(),\n relations: new Map(),\n rules: new Map(),\n screens: new Map(),\n transitions: new Map(),\n forms: new Map(),\n processFlows: new Map(),\n glossaryTerms: new Map(),\n apiRefs: new Map(),\n tableRefs: new Map(),\n testRefs: new Map(),\n layers: new Map(),\n boundaries: new Map(),\n artifacts: new Map(),\n };\n}\n\n// ============================================================================\n// Global Registry (shared registry for DSL functions to register to)\n// ============================================================================\n\nlet globalRegistry: ModelRegistry = createEmptyRegistry();\n\nexport function getGlobalRegistry(): ModelRegistry {\n return globalRegistry;\n}\n\nexport function resetGlobalRegistry(): void {\n globalRegistry = createEmptyRegistry();\n}\n\n/**\n * Function for DSL functions to register models\n */\nexport function registerModel(\n type: keyof ModelRegistry,\n id: string,\n model: unknown\n): void {\n globalRegistry[type].set(id, model);\n}\n\n// ============================================================================\n// Model Registration from Exports\n// ============================================================================\n\n/**\n * Determine if value is a Model class instance\n */\nfunction isModelInstance(value: unknown): value is { id: string; name: string; idPrefix: string; schema: unknown } {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === 'string' &&\n typeof obj.name === 'string' &&\n typeof obj.idPrefix === 'string' &&\n obj.schema !== undefined &&\n typeof obj.validate === 'function' &&\n typeof obj.lint === 'function'\n );\n}\n\n/**\n * Detect models from imported module exports and register to globalRegistry\n */\nfunction registerExportedModels(module: Record<string, unknown>): void {\n for (const [exportName, exportValue] of Object.entries(module)) {\n if (!exportValue || typeof exportValue !== 'object') continue;\n \n // Detect and register Model class instances\n if (isModelInstance(exportValue)) {\n // Register to core model registry\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n coreRegisterModel(exportValue as any);\n continue;\n }\n \n // Process arrays\n if (Array.isArray(exportValue)) {\n registerArrayItems(exportName, exportValue);\n continue;\n }\n \n const value = exportValue as Record<string, unknown>;\n \n // Detect ArchitectureModel (has components, layers, boundaries, relations)\n if (value.components && value.layers && value.boundaries && value.relations) {\n const arch = value as { \n name?: string;\n components: { id?: string }[]; \n layers: { id?: string }[]; \n boundaries: { id?: string }[];\n relations: { id?: string }[];\n };\n for (const comp of arch.components) {\n if (comp.id) globalRegistry.components.set(comp.id, comp);\n }\n for (const layer of arch.layers) {\n if (layer.id) globalRegistry.layers.set(layer.id, layer);\n }\n for (const boundary of arch.boundaries) {\n if (boundary.id) globalRegistry.boundaries.set(boundary.id, boundary);\n }\n for (const rel of arch.relations) {\n if (rel.id) globalRegistry.relations.set(rel.id, rel);\n }\n continue;\n }\n \n // Detect ConceptModel (has entities, relations, rules)\n if (value.entities && value.relations && Array.isArray(value.entities)) {\n const concept = value as { \n entities: { id?: string }[]; \n relations: { id?: string }[];\n rules?: { id?: string }[];\n };\n for (const entity of concept.entities) {\n if (entity.id) globalRegistry.entities.set(entity.id, entity);\n }\n for (const rel of concept.relations) {\n if (rel.id) globalRegistry.relations.set(rel.id, rel);\n }\n for (const rule of concept.rules || []) {\n if (rule.id) globalRegistry.rules.set(rule.id, rule);\n }\n continue;\n }\n \n // Detect UseCaseModel (has useCases, actors)\n if (value.useCases && value.actors) {\n const ucModel = value as { \n useCases: { id?: string }[]; \n actors: { id?: string }[];\n };\n for (const uc of ucModel.useCases) {\n if (uc.id) globalRegistry.useCases.set(uc.id, uc);\n }\n for (const actor of ucModel.actors) {\n if (actor.id) globalRegistry.actors.set(actor.id, actor);\n }\n continue;\n }\n \n // Detect Glossary (array with terms or {terms: []} format)\n if (value.terms && Array.isArray(value.terms)) {\n const glossary = value as { terms: { id?: string }[] };\n for (const term of glossary.terms) {\n if (term.id) globalRegistry.glossaryTerms.set(term.id, term);\n }\n continue;\n }\n \n // Detect single Requirement\n if (value.id && value.title && (value.kind || value.type || value.acceptance)) {\n globalRegistry.requirements.set(value.id as string, value);\n continue;\n }\n \n // Detect single Entity\n if (value.id && value.name && value.attributes && Array.isArray(value.attributes)) {\n globalRegistry.entities.set(value.id as string, value);\n continue;\n }\n \n // Detect single UseCase\n if (value.id && value.name && value.actor && value.mainFlow) {\n globalRegistry.useCases.set(value.id as string, value);\n continue;\n }\n \n // Detect single Actor\n if (value.id && value.name && value.type && ['human', 'system', 'external'].includes(value.type as string)) {\n globalRegistry.actors.set(value.id as string, value);\n continue;\n }\n \n // Detect single Term\n if (value.id && (value.term || value.abbreviation) && value.definition) {\n globalRegistry.glossaryTerms.set(value.id as string, value);\n continue;\n }\n }\n}\n\n/**\n * Detect items from array and register to registry\n */\nfunction registerArrayItems(exportName: string, items: unknown[]): void {\n for (const item of items) {\n if (!item || typeof item !== 'object') continue;\n const obj = item as Record<string, unknown>;\n if (!obj.id || typeof obj.id !== 'string') continue;\n \n // Infer type from export name or object structure\n // requirements / allRequirements / functionalRequirements etc.\n if (exportName.toLowerCase().includes('requirement') || \n exportName.toLowerCase().includes('constraints') ||\n (obj.type && obj.acceptanceCriteria)) {\n globalRegistry.requirements.set(obj.id, item);\n continue;\n }\n \n // useCases / usecases\n if (exportName.toLowerCase().includes('usecase') || \n (obj.actor && obj.mainFlow)) {\n globalRegistry.useCases.set(obj.id, item);\n continue;\n }\n \n // actors\n if (exportName.toLowerCase().includes('actor') ||\n (obj.type && ['human', 'system', 'external'].includes(obj.type as string) && !obj.mainFlow)) {\n globalRegistry.actors.set(obj.id, item);\n continue;\n }\n \n // components / containers\n if (exportName.toLowerCase().includes('component') ||\n exportName.toLowerCase().includes('container') ||\n (obj.type && ['person', 'system', 'container', 'component'].includes(obj.type as string))) {\n globalRegistry.components.set(obj.id, item);\n continue;\n }\n \n // entities\n if (exportName.toLowerCase().includes('entit') ||\n (obj.name && obj.attributes && Array.isArray(obj.attributes))) {\n globalRegistry.entities.set(obj.id, item);\n continue;\n }\n \n // terms / acronyms / glossary\n if (exportName.toLowerCase().includes('term') ||\n exportName.toLowerCase().includes('acronym') ||\n exportName.toLowerCase().includes('glossary') ||\n (obj.term && obj.definition)) {\n globalRegistry.glossaryTerms.set(obj.id, item);\n continue;\n }\n \n // relations\n if (exportName.toLowerCase().includes('relation') ||\n (obj.from && obj.to && obj.label)) {\n globalRegistry.relations.set(obj.id, item);\n continue;\n }\n \n // layers\n if (exportName.toLowerCase().includes('layer') ||\n (obj.name && typeof obj.order === 'number')) {\n globalRegistry.layers.set(obj.id, item);\n continue;\n }\n \n // boundaries\n if (exportName.toLowerCase().includes('boundar') ||\n (obj.type && ['system', 'context', 'container', 'deployment'].includes(obj.type as string) && obj.description)) {\n globalRegistry.boundaries.set(obj.id, item);\n continue;\n }\n \n // screens\n if (exportName.toLowerCase().includes('screen') ||\n (obj.type && ['page', 'modal', 'drawer', 'panel', 'wizard'].includes(obj.type as string) && obj.auth)) {\n globalRegistry.screens.set(obj.id, item);\n continue;\n }\n \n // testRefs\n if (exportName.toLowerCase().includes('testref') ||\n exportName.toLowerCase().includes('test-ref') ||\n (obj.source && obj.verifiesRequirements && Array.isArray(obj.verifiesRequirements))) {\n globalRegistry.testRefs.set(obj.id, item);\n continue;\n }\n \n // artifacts\n if (exportName.toLowerCase().includes('artifact') ||\n (obj.category && obj.location && obj.purpose &&\n ['ssot', 'human-readable', 'machine-readable', 'implementation'].includes(obj.category as string))) {\n globalRegistry.artifacts.set(obj.id, item);\n continue;\n }\n }\n}\n\n// ============================================================================\n// Model Loading\n// ============================================================================\n\n/**\n * Dynamically import TS files from specified directory and collect models\n */\nexport async function loadModelsFromDirectory(\n dirPath: string,\n options: { recursive?: boolean } = {}\n): Promise<string[]> {\n const loadedFiles: string[] = [];\n \n if (!existsSync(dirPath)) {\n return loadedFiles;\n }\n \n const entries = readdirSync(dirPath);\n \n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n const stat = statSync(fullPath);\n \n if (stat.isDirectory() && options.recursive) {\n const subFiles = await loadModelsFromDirectory(fullPath, options);\n loadedFiles.push(...subFiles);\n } else if (stat.isFile()) {\n const ext = extname(entry);\n // Target .ts, .js, .mts, .mjs files\n if (['.ts', '.js', '.mts', '.mjs'].includes(ext) && !entry.endsWith('.d.ts')) {\n // Exclude index.ts (possibly a re-export file)\n if (basename(entry, ext) === 'index') {\n continue;\n }\n \n try {\n // Dynamic import\n const module = await import(fullPath);\n loadedFiles.push(fullPath);\n \n // Register exported models to globalRegistry\n registerExportedModels(module);\n } catch (error) {\n console.error(`Failed to load model from ${fullPath}:`, error);\n }\n }\n }\n }\n \n return loadedFiles;\n}\n\n/**\n * Load all models based on configuration\n */\nexport async function loadAllModels(\n config: SpeckeeperConfig,\n cwd: string = process.cwd()\n): Promise<{\n registry: ModelRegistry;\n loadedFiles: string[];\n errors: Array<{ file: string; error: unknown }>;\n}> {\n // Reset registry\n resetGlobalRegistry();\n \n const loadedFiles: string[] = [];\n const errors: Array<{ file: string; error: unknown }> = [];\n \n // Load from design/ directory (compliant with spec section 7.1)\n const designDir = resolve(cwd, config.designDir || 'design');\n \n // Standard directory structure (compliant with spec section 7.1)\n const modelDirs = [\n { path: join(designDir, 'requirements') },\n { path: join(designDir, 'usecases') },\n { path: join(designDir, 'architecture') },\n { path: join(designDir, 'data-model') },\n { path: join(designDir, 'screens') },\n { path: join(designDir, 'flows') },\n { path: join(designDir, 'glossary') },\n // Also load files directly under design/ by default (index.ts, etc.)\n { path: designDir },\n ];\n \n for (const { path: dirPath } of modelDirs) {\n if (!existsSync(dirPath)) {\n continue;\n }\n \n try {\n const files = await loadModelsFromDirectory(dirPath, { recursive: true });\n loadedFiles.push(...files);\n } catch (error) {\n errors.push({ file: dirPath, error });\n }\n }\n \n return {\n registry: getGlobalRegistry(),\n loadedFiles,\n errors,\n };\n}\n\n// ============================================================================\n// Registry Helpers\n// ============================================================================\n\n/**\n * Get registry statistics\n */\nexport function getRegistryStats(registry: ModelRegistry): Record<string, number> {\n const stats: Record<string, number> = {};\n \n for (const [key, map] of Object.entries(registry)) {\n stats[key] = (map as Map<string, unknown>).size;\n }\n \n return stats;\n}\n\n/**\n * Get all IDs in registry\n */\nexport function getAllIds(registry: ModelRegistry): Set<string> {\n const allIds = new Set<string>();\n \n for (const map of Object.values(registry)) {\n for (const id of (map as Map<string, unknown>).keys()) {\n allIds.add(id);\n }\n }\n \n return allIds;\n}\n\n/**\n * Identify model type from ID\n */\nexport function findModelType(\n registry: ModelRegistry,\n id: string\n): keyof ModelRegistry | null {\n for (const [type, map] of Object.entries(registry)) {\n if ((map as Map<string, unknown>).has(id)) {\n return type as keyof ModelRegistry;\n }\n }\n return null;\n}\n\n/**\n * Get model by ID\n */\nexport function getModelById(\n registry: ModelRegistry,\n id: string\n): { type: keyof ModelRegistry; model: unknown } | null {\n const type = findModelType(registry, id);\n if (!type) return null;\n \n return {\n type,\n model: registry[type].get(id),\n };\n}\n","/**\n * Lint Command\n * \n * Execute design consistency checks using model class lintRules\n */\n\nimport chalk from 'chalk';\nimport { relative } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LintCommandOptions {\n config?: string;\n phase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strict?: boolean;\n fix?: boolean;\n format?: 'text' | 'json' | 'github';\n}\n\nexport type LintSeverity = 'error' | 'warning' | 'info';\n\nexport interface LintIssue {\n rule: string;\n severity: LintSeverity;\n message: string;\n specId?: string;\n modelType?: string;\n}\n\nexport interface LintResult {\n issues: LintIssue[];\n errors: number;\n warnings: number;\n infos: number;\n}\n\n// ============================================================================\n// Lint Command\n// ============================================================================\n\nexport async function lintCommand(options: LintCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper lint'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n if (options.phase) {\n console.log(chalk.gray(` Phase: ${options.phase}`));\n }\n console.log('');\n \n try {\n // Load all models from design/\n console.log(chalk.blue(' Loading models...'));\n const { registry, loadedFiles, errors: loadErrors } = await loadAllModels(config, cwd);\n \n if (loadErrors.length > 0) {\n console.log(chalk.yellow(` ⚠ ${loadErrors.length} file(s) failed to load`));\n for (const { file, error } of loadErrors) {\n console.log(chalk.yellow(` - ${relative(cwd, file)}: ${error}`));\n }\n }\n \n console.log(chalk.gray(` Loaded: ${loadedFiles.length} files`));\n console.log('');\n \n // Run lint using model classes\n console.log(chalk.blue(' Running lint checks...'));\n const result = runModelLint(registry, options);\n \n // Output results\n console.log('');\n outputLintResults(result, options);\n \n // Exit with error code if there are errors\n if (result.errors > 0) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Lint failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Lint Runner\n// ============================================================================\n\nfunction runModelLint(registry: ModelRegistry, options: LintCommandOptions): LintResult {\n const issues: LintIssue[] = [];\n const models = getAllModels();\n \n for (const model of models) {\n // Get specs from registry for this model type\n const specs = getSpecsFromRegistry(registry, model.id);\n \n if (specs.length === 0) continue;\n \n // Run lint rules\n const lintResults = model.lintAll(specs);\n \n for (const result of lintResults) {\n issues.push({\n rule: result.ruleId,\n severity: result.severity,\n message: result.message,\n specId: result.specId,\n modelType: model.name,\n });\n }\n }\n \n // Count by severity\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n // Filter by strict mode\n if (!options.strict) {\n return {\n issues: issues.filter(i => i.severity !== 'info'),\n errors,\n warnings,\n infos,\n };\n }\n \n return { issues, errors, warnings, infos };\n}\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n // Map model IDs to registry keys\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n 'boundary': 'boundaries',\n 'layer': 'layers',\n 'relation': 'relations',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputLintResults(result: LintResult, options: LintCommandOptions): void {\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'github') {\n for (const issue of result.issues) {\n const level = issue.severity === 'error' ? 'error' : issue.severity === 'warning' ? 'warning' : 'notice';\n console.log(`::${level}::${issue.message} [${issue.rule}]${issue.specId ? ` (${issue.specId})` : ''}`);\n }\n return;\n }\n \n // Default text format\n if (result.issues.length === 0) {\n console.log(chalk.green(' ✓ No issues found'));\n return;\n }\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';\n const color = issue.severity === 'error' ? chalk.red : issue.severity === 'warning' ? chalk.yellow : chalk.blue;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n console.log(chalk.gray(` Rule: ${issue.rule}`));\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${result.errors} errors, ${result.warnings} warnings, ${result.infos} infos`));\n}\n","/**\n * Drift Command\n * \n * Detect drift between generated artifacts and SSOT\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DriftCommandOptions {\n config?: string;\n verbose?: boolean;\n failOnDrift?: boolean;\n}\n\nexport interface DriftResult {\n file: string;\n status: 'ok' | 'drifted' | 'missing';\n details?: string;\n}\n\n// ============================================================================\n// Drift Command\n// ============================================================================\n\nexport async function driftCommand(options: DriftCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper drift'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: DriftResult[] = [];\n const models = getAllModels();\n \n // Check each model's generated files\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const exporter of model.getExporters()) {\n if (exporter.format !== 'markdown') continue;\n \n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n // Check individual files\n if (exporter.single) {\n for (const spec of specs) {\n const filename = model.getFilename(spec, 'markdown') || (spec as { id: string }).id;\n const filePath = join(outputDir, `${filename}.md`);\n \n if (!existsSync(filePath)) {\n results.push({ file: filePath, status: 'missing' });\n continue;\n }\n \n const expected = exporter.single(spec);\n const actual = readFileSync(filePath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: filePath, status: 'drifted' });\n } else {\n results.push({ file: filePath, status: 'ok' });\n }\n }\n }\n \n // Check index file\n if (exporter.index) {\n const indexPath = join(outputDir, 'index.md');\n \n if (!existsSync(indexPath)) {\n results.push({ file: indexPath, status: 'missing' });\n } else {\n const expected = exporter.index(specs);\n const actual = readFileSync(indexPath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: indexPath, status: 'drifted' });\n } else {\n results.push({ file: indexPath, status: 'ok' });\n }\n }\n }\n }\n }\n \n // Output results\n outputDriftResults(results, options);\n \n // Exit with error code if drift detected and failOnDrift is set\n const hasDrift = results.some(r => r.status === 'drifted' || r.status === 'missing');\n if (hasDrift && options.failOnDrift) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Drift check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\nfunction normalizeContent(content: string): string {\n return content.trim().replace(/\\r\\n/g, '\\n');\n}\n\nfunction outputDriftResults(results: DriftResult[], _options: DriftCommandOptions): void {\n console.log('');\n \n const ok = results.filter(r => r.status === 'ok');\n const drifted = results.filter(r => r.status === 'drifted');\n const missing = results.filter(r => r.status === 'missing');\n \n if (drifted.length === 0 && missing.length === 0) {\n console.log(chalk.green(' ✓ No drift detected'));\n console.log(chalk.gray(` Checked: ${results.length} files`));\n return;\n }\n \n if (drifted.length > 0) {\n console.log(chalk.yellow(` ⚠ ${drifted.length} file(s) have drifted:`));\n for (const result of drifted) {\n console.log(chalk.yellow(` - ${result.file}`));\n }\n }\n \n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} file(s) are missing:`));\n for (const result of missing) {\n console.log(chalk.red(` - ${result.file}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${ok.length} ok, ${drifted.length} drifted, ${missing.length} missing`));\n}\n","/**\n * Check Command\n * \n * Check consistency with external SSOT using model class externalChecker\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels, type CoverageResult } from '../core/model.js';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CheckCommandOptions {\n config?: string;\n type?: 'openapi' | 'ddl' | 'iac' | 'all';\n verbose?: boolean;\n coverage?: boolean;\n}\n\nexport interface CheckIssue {\n severity: 'error' | 'warning';\n message: string;\n specId?: string;\n field?: string;\n}\n\nexport interface CheckResult {\n type: string;\n success: boolean;\n issues: CheckIssue[];\n}\n\n// ============================================================================\n// Check Command\n// ============================================================================\n\nexport async function checkCommand(\n type: string | undefined,\n options: CheckCommandOptions\n): Promise<void> {\n console.log(chalk.blue('speckeeper check'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const checkType = type || options.type || 'all';\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Type: ${checkType}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: CheckResult[] = [];\n const models = getAllModels();\n \n if (options.verbose) {\n console.log(chalk.gray(` Registered models: ${models.map(m => m.id).join(', ')}`));\n }\n \n // Run checks for each model that has an external checker\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const spec of specs) {\n const sourcePath = model.getExternalSourcePath(spec);\n if (!sourcePath) continue;\n \n const fullPath = join(cwd, sourcePath);\n if (!existsSync(fullPath)) {\n results.push({\n type: model.id,\n success: false,\n issues: [{\n severity: 'error',\n message: `External source not found: ${sourcePath}`,\n specId: (spec as { id: string }).id,\n }],\n });\n continue;\n }\n \n // Load external data\n const externalData = loadExternalData(fullPath);\n \n // Run check\n const checkResult = model.check(spec, externalData);\n \n if (!checkResult.success || checkResult.errors.length > 0 || checkResult.warnings.length > 0) {\n results.push({\n type: model.id,\n success: checkResult.success,\n issues: [\n ...checkResult.errors.map(e => ({ severity: 'error' as const, message: e.message, specId: e.specId, field: e.field })),\n ...checkResult.warnings.map(w => ({ severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field })),\n ],\n });\n }\n }\n }\n \n // Output results\n outputCheckResults(results);\n \n // Coverage check (if --coverage flag is set)\n if (options.coverage) {\n console.log('');\n console.log(chalk.blue(' Coverage checks...'));\n const coverageResults = runAllCoverageChecks(registry);\n \n if (coverageResults.length > 0) {\n outputAllCoverageResults(coverageResults);\n \n // Add uncovered items as warnings\n for (const check of coverageResults) {\n if (check.result.uncoveredItems.length > 0) {\n results.push({\n type: `coverage-${check.modelId}`,\n success: check.result.coveragePercent >= 80, // fail if below 80%\n issues: check.result.uncoveredItems.slice(0, 10).map(item => ({\n severity: 'warning' as const,\n message: `[${check.modelName}→${check.targetModel}] '${item.id}'${item.sourceId ? ` (${item.sourceId})` : ''} not covered`,\n specId: item.id,\n })),\n });\n }\n }\n \n // Summary\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n const allPassed = coverageResults.every(c => c.result.coveragePercent >= 80);\n if (allPassed) {\n console.log(chalk.green(' ✓ All coverage checks passed (≥80%)'));\n } else {\n const failed = coverageResults.filter(c => c.result.coveragePercent < 80);\n console.log(chalk.yellow(` ⚠ ${failed.length} coverage check(s) below 80%`));\n }\n } else {\n console.log(chalk.gray(' No coverage checker found'));\n }\n }\n \n // Exit with error code if there are errors\n const hasErrors = results.some(r => !r.success);\n if (hasErrors) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n 'api-ref': 'apiRefs',\n 'table-ref': 'tableRefs',\n 'test-ref': 'testRefs',\n 'artifact': 'artifacts',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\nfunction loadExternalData(filePath: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n \n if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {\n return parseYaml(content);\n }\n \n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n \n return content;\n}\n\nfunction outputCheckResults(results: CheckResult[]): void {\n console.log('');\n \n if (results.length === 0) {\n console.log(chalk.green(' ✓ All checks passed'));\n return;\n }\n \n let totalErrors = 0;\n let totalWarnings = 0;\n \n for (const result of results) {\n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : '⚠';\n const color = issue.severity === 'error' ? chalk.red : chalk.yellow;\n \n if (issue.severity === 'error') totalErrors++;\n else totalWarnings++;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${totalErrors} errors, ${totalWarnings} warnings`));\n}\n\n// ============================================================================\n// Coverage Check\n// ============================================================================\n\ninterface CoverageCheckResult {\n modelId: string;\n modelName: string;\n description: string;\n targetModel: string;\n result: CoverageResult;\n}\n\n/**\n * Execute all coverage checks\n * \n * Detect all models with coverageChecker and run coverage checks.\n * Logic is defined in each model (design/_models/).\n */\nfunction runAllCoverageChecks(registry: ModelRegistry): CoverageCheckResult[] {\n const models = getAllModels();\n const results: CoverageCheckResult[] = [];\n \n // Convert registry to Record format\n const registryRecord: Record<string, Map<string, unknown>> = {};\n for (const [key, value] of Object.entries(registry)) {\n if (value instanceof Map) {\n registryRecord[key] = value;\n }\n }\n \n // Search for models with coverageChecker and execute\n for (const model of models) {\n const checker = model.getCoverageChecker();\n if (checker) {\n const specs = getSpecsFromRegistry(registry, model.id);\n const result = model.checkCoverage(specs, registryRecord);\n \n if (result) {\n results.push({\n modelId: model.id,\n modelName: model.name,\n description: checker.description,\n targetModel: checker.targetModel,\n result,\n });\n }\n }\n }\n \n return results;\n}\n\nfunction outputAllCoverageResults(checks: CoverageCheckResult[]): void {\n for (const check of checks) {\n console.log('');\n console.log(chalk.blue(` Coverage: ${check.modelName} → ${check.targetModel}`));\n console.log(chalk.gray(` ${check.description}`));\n console.log(chalk.gray(` ─────────────────────────────────────`));\n console.log(chalk.gray(` Total: ${check.result.total}`));\n console.log(chalk.green(` Covered: ${check.result.covered}`));\n console.log(chalk.yellow(` Uncovered: ${check.result.uncovered}`));\n \n const color = check.result.coveragePercent >= 80 ? chalk.green : \n check.result.coveragePercent >= 50 ? chalk.yellow : chalk.red;\n console.log(color(` Coverage: ${check.result.coveragePercent}%`));\n \n if (check.result.uncoveredItems.length > 0 && check.result.uncoveredItems.length <= 10) {\n console.log('');\n console.log(chalk.yellow(' Uncovered items:'));\n for (const item of check.result.uncoveredItems) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n const source = item.sourceId ? ` (${item.sourceId})` : '';\n console.log(chalk.yellow(` - ${item.id}${source}${desc}`));\n }\n } else if (check.result.uncoveredItems.length > 10) {\n console.log('');\n console.log(chalk.yellow(` (${check.result.uncoveredItems.length} uncovered items - showing first 5)`));\n for (const item of check.result.uncoveredItems.slice(0, 5)) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n console.log(chalk.yellow(` - ${item.id}${desc}`));\n }\n }\n }\n}\n","/**\n * New Command\n * \n * Generate templates for new model instances\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NewCommandOptions {\n config?: string;\n type?: string;\n id?: string;\n output?: string;\n dryRun?: boolean;\n}\n\n// ============================================================================\n// New Command\n// ============================================================================\n\nexport async function newCommand(options: NewCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper new'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n // List available types if no type specified\n if (!options.type) {\n console.log(chalk.gray(' Available model types:'));\n const models = getAllModels();\n for (const model of models) {\n console.log(chalk.gray(` - ${model.id} (${model.name})`));\n }\n console.log('');\n console.log(chalk.gray(' Usage: speckeeper new --type <type> [--id <id>]'));\n return;\n }\n \n // Find model\n const models = getAllModels();\n const model = models.find(m => m.id === options.type);\n \n if (!model) {\n console.error(chalk.red(` Error: Unknown model type '${options.type}'`));\n console.log(chalk.gray(' Run `speckeeper new` to see available types'));\n process.exit(1);\n }\n \n // Generate ID if not provided\n const id = options.id || `${model.idPrefix}-${String(Date.now()).slice(-6)}`;\n \n // Generate template\n const template = generateTemplate(model, id);\n \n if (options.dryRun) {\n console.log(chalk.gray(' Template (dry run):'));\n console.log('');\n console.log(template);\n return;\n }\n \n // Write template to file\n const outputDir = options.output || join(cwd, config.designDir || 'design');\n const outputFile = join(outputDir, `${model.id}-${id}.ts`);\n \n if (existsSync(outputFile)) {\n console.error(chalk.red(` Error: File already exists: ${outputFile}`));\n process.exit(1);\n }\n \n writeFileSync(outputFile, template);\n console.log(chalk.green(` ✓ Created: ${outputFile}`));\n}\n\n// ============================================================================\n// Template Generation\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction generateTemplate(model: any, id: string): string {\n const typeName = model.name;\n const lines: string[] = [];\n \n lines.push(`/**`);\n lines.push(` * ${typeName}: ${id}`);\n lines.push(` * `);\n lines.push(` * Generated by speckeeper new`);\n lines.push(` */`);\n lines.push(`import type { ${typeName} } from './_models/${model.id}';`);\n lines.push('');\n lines.push(`export const ${camelCase(id)}: ${typeName} = {`);\n lines.push(` id: '${id}',`);\n lines.push(` // TODO: Fill in the required fields`);\n lines.push(`};`);\n lines.push('');\n \n return lines.join('\\n');\n}\n\nfunction camelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Impact Command\n * \n * Analyze the impact scope of changes\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImpactCommandOptions {\n config?: string;\n depth?: string;\n direction?: 'upstream' | 'downstream' | 'both';\n format?: 'text' | 'json' | 'mermaid';\n}\n\nexport interface ImpactNode {\n id: string;\n type: string;\n depth: number;\n impactType: 'direct' | 'indirect';\n}\n\nexport interface ImpactResult {\n target: string;\n targetType: string;\n impactedNodes: ImpactNode[];\n}\n\n// ============================================================================\n// Impact Command\n// ============================================================================\n\nexport async function impactCommand(targetId: string, options: ImpactCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper impact'));\n console.log('');\n \n if (!targetId) {\n console.error(chalk.red('Error: ID is required'));\n console.log(chalk.gray(' Usage: speckeeper impact <id>'));\n process.exit(1);\n }\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const maxDepth = options.depth ? parseInt(options.depth, 10) : 3;\n \n console.log(chalk.gray(` Target: ${targetId}`));\n console.log(chalk.gray(` Depth: ${maxDepth}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n // Find target\n const target = findById(registry, targetId);\n if (!target) {\n console.error(chalk.red(` Error: Target '${targetId}' not found`));\n process.exit(1);\n }\n \n // Analyze impact\n console.log(chalk.blue(' Analyzing impact...'));\n const result = analyzeImpact(registry, targetId, target.type, maxDepth);\n \n // Output results\n outputImpactResults(result, options);\n \n } catch (error) {\n console.error(chalk.red('Impact analysis failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Impact Analysis\n// ============================================================================\n\nfunction findById(registry: ModelRegistry, id: string): { type: string; data: unknown } | null {\n for (const [type, map] of Object.entries(registry)) {\n if (map instanceof Map && map.has(id)) {\n return { type, data: map.get(id) };\n }\n }\n return null;\n}\n\nfunction analyzeImpact(\n registry: ModelRegistry,\n targetId: string,\n targetType: string,\n maxDepth: number\n): ImpactResult {\n const impactedNodes: ImpactNode[] = [];\n const visited = new Set<string>([targetId]);\n \n // Find references to the target\n function findReferences(id: string, depth: number): void {\n if (depth > maxDepth) return;\n \n for (const [type, map] of Object.entries(registry)) {\n if (!(map instanceof Map)) continue;\n \n for (const [itemId, item] of map) {\n if (visited.has(itemId)) continue;\n \n // Check if this item references the target\n const itemStr = JSON.stringify(item);\n if (itemStr.includes(`\"${id}\"`)) {\n visited.add(itemId);\n impactedNodes.push({\n id: itemId,\n type,\n depth,\n impactType: depth === 1 ? 'direct' : 'indirect',\n });\n \n // Recursively find references to this item\n findReferences(itemId, depth + 1);\n }\n }\n }\n }\n \n findReferences(targetId, 1);\n \n return {\n target: targetId,\n targetType,\n impactedNodes,\n };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputImpactResults(result: ImpactResult, options: ImpactCommandOptions): void {\n console.log('');\n \n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'mermaid') {\n console.log('```mermaid');\n console.log('graph TD');\n console.log(` ${result.target}[${result.target}]`);\n for (const node of result.impactedNodes) {\n const style = node.impactType === 'direct' ? '-->|direct|' : '-.->|indirect|';\n console.log(` ${result.target} ${style} ${node.id}[${node.id}]`);\n }\n console.log('```');\n return;\n }\n \n // Default text format\n if (result.impactedNodes.length === 0) {\n console.log(chalk.green(' No impacted elements found'));\n return;\n }\n \n const direct = result.impactedNodes.filter(n => n.impactType === 'direct');\n const indirect = result.impactedNodes.filter(n => n.impactType === 'indirect');\n \n if (direct.length > 0) {\n console.log(chalk.yellow(` Direct impact (${direct.length}):`));\n for (const node of direct) {\n console.log(chalk.yellow(` → ${node.id} (${node.type})`));\n }\n }\n \n if (indirect.length > 0) {\n console.log(chalk.gray(` Indirect impact (${indirect.length}):`));\n for (const node of indirect) {\n console.log(chalk.gray(` ⤳ ${node.id} (${node.type}, depth: ${node.depth})`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Total: ${result.impactedNodes.length} impacted elements`));\n}\n","/**\n * speckeeper init command\n * \n * Generate starter templates for a new speckeeper project\n */\nimport chalk from 'chalk';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport async function runInit(options: InitOptions = {}): Promise<void> {\n const cwd = process.cwd();\n \n console.log(chalk.cyan('speckeeper init'));\n console.log('');\n \n // Check if already initialized\n const designDir = join(cwd, 'design');\n const configFile = join(cwd, 'speckeeper.config.ts');\n \n if (!options.force && (existsSync(designDir) || existsSync(configFile))) {\n console.log(chalk.yellow(' Project already initialized.'));\n console.log(chalk.gray(' Use --force to overwrite existing files.'));\n return;\n }\n \n // Get project name from directory\n const projectName = cwd.split('/').pop() || 'my-project';\n \n // Find templates directory\n const templatesDir = join(__dirname, 'templates', 'init');\n \n if (!existsSync(templatesDir)) {\n console.log(chalk.red(` Error: Templates directory not found at ${templatesDir}`));\n console.log(chalk.gray(' Please ensure the package is properly installed.'));\n return;\n }\n \n // Copy template files\n let packageJsonCreated = false;\n copyTemplateDir(templatesDir, cwd, projectName, options.force || false, (relativePath, created) => {\n if (created) {\n console.log(chalk.green(` Created: ${relativePath}`));\n if (relativePath === 'package.json') {\n packageJsonCreated = true;\n }\n } else {\n console.log(chalk.yellow(` Skipped: ${relativePath} (already exists)`));\n }\n });\n \n console.log('');\n console.log(chalk.cyan(' Project initialized successfully!'));\n console.log('');\n console.log(' Next steps:');\n if (packageJsonCreated) {\n console.log(chalk.gray(' 1. Run `npm install` to install dependencies'));\n console.log(chalk.gray(' 2. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 3. Add specifications in design/'));\n console.log(chalk.gray(' 4. Run `npx speckeeper lint` to validate'));\n } else {\n console.log(chalk.gray(' 1. Add speckeeper and zod to your package.json dependencies'));\n console.log(chalk.gray(' 2. Ensure \"type\": \"module\" is set in package.json'));\n console.log(chalk.gray(' 3. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 4. Add specifications in design/'));\n console.log(chalk.gray(' 5. Run `npx speckeeper lint` to validate'));\n }\n}\n\n/**\n * Recursively copy template directory\n */\nfunction copyTemplateDir(\n srcDir: string,\n destDir: string,\n projectName: string,\n force: boolean,\n onFile: (relativePath: string, created: boolean) => void,\n relativePath: string = ''\n): void {\n const entries = readdirSync(srcDir);\n \n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const stat = statSync(srcPath);\n \n // Handle .template extension\n const destEntry = entry.endsWith('.template') ? entry.slice(0, -9) : entry;\n const destPath = join(destDir, destEntry);\n const relPath = relativePath ? join(relativePath, destEntry) : destEntry;\n \n if (stat.isDirectory()) {\n // Create directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true });\n onFile(relPath + '/', true);\n }\n // Recurse into directory\n copyTemplateDir(srcPath, destPath, projectName, force, onFile, relPath);\n } else {\n // Skip if file exists and not force\n if (!force && existsSync(destPath)) {\n onFile(relPath, false);\n continue;\n }\n \n // Read and process template\n let content = readFileSync(srcPath, 'utf-8');\n \n // Replace template variables\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName);\n \n // Write file\n const dir = dirname(destPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(destPath, content);\n onFile(relPath, true);\n }\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { buildCommand } from './build.js';\nimport { lintCommand } from './lint.js';\nimport { driftCommand } from './drift.js';\nimport { checkCommand } from './check.js';\nimport { newCommand } from './new.js';\nimport { impactCommand } from './impact.js';\nimport { runInit } from './init.js';\n\nconst program = new Command();\n\nprogram\n .name('speckeeper')\n .description('Requirements and design management framework with TypeScript DSL')\n .version('0.1.0');\n\n// Build command\n// Spec: design/cli-commands.ts CMD-BUILD\nprogram\n .command('build')\n .description('Generate docs/ and specs/ from TypeScript models')\n .option('-c, --config <path>', 'Path to config file')\n .option('-o, --output <path>', 'Base output directory path', '.')\n .option('-f, --format <format>', 'Output format: markdown, json, both', 'both')\n .option('-w, --watch', 'Watch for changes and auto-regenerate')\n .option('-v, --verbose', 'Show detailed output')\n .action(buildCommand);\n\n// Lint command\n// Spec: design/cli-commands.ts CMD-LINT\nprogram\n .command('lint')\n .description('Check design integrity (ID duplicates, references, layer violations, etc.)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-p, --phase <phase>', 'Phase gate to check against (REQ, HLD, LLD, OPS)')\n .option('-s, --strict', 'Treat warnings as errors')\n .option('--fix', 'Attempt to fix auto-fixable issues')\n .option('-f, --format <format>', 'Output format: text, json, github', 'text')\n .action(lintCommand);\n\n// Drift command\n// Spec: design/cli-commands.ts CMD-DRIFT\nprogram\n .command('drift')\n .description('Check if generated files have been manually edited')\n .option('-c, --config <path>', 'Path to config file')\n .option('-u, --update', 'Auto-update if differences are found')\n .option('-f, --format <format>', 'Output format: text, json, diff', 'text')\n .action(driftCommand);\n\n// Check command\n// Spec: design/cli-commands.ts CMD-CHECK\nprogram\n .command('check')\n .description('Check external SSOT conformance (including custom models)')\n .argument('[type]', 'Type of check: external-ssot, openapi, ddl, iac, custom, all, test')\n .option('-c, --config <path>', 'Path to config file')\n .option('--strict', 'Treat warnings as errors')\n .option('-v, --verbose', 'Show detailed output')\n .option('--coverage', 'Check if all testable acceptance criteria are covered by TestRefs')\n .action(checkCommand);\n\n// New command\n// Spec: design/cli-commands.ts CMD-NEW\nprogram\n .command('new')\n .description('Create a new element with auto-generated ID')\n .argument('<type>', 'Type: requirement, usecase, entity, component, screen, flow, error-case, term')\n .option('-k, --kind <kind>', 'Sub-kind (e.g., functional, non-functional for requirements)')\n .option('-n, --name <name>', 'Name of the element')\n .option('-o, --output <path>', 'Output directory path')\n .option('-t, --template <path>', 'Path to template file')\n .action(newCommand);\n\n// Impact command\n// Spec: design/cli-commands.ts CMD-IMPACT\nprogram\n .command('impact')\n .description('Analyze impact of changes to an ID')\n .argument('<id>', 'ID to analyze (e.g., REQ-001, ENT-ORDER)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --depth <depth>', 'Analysis depth (reference tracking level)', '3')\n .option('--direction <direction>', 'Analysis direction: upstream, downstream, both', 'both')\n .option('-f, --format <format>', 'Output format: text, json, mermaid', 'text')\n .action(impactCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new speckeeper project with starter templates')\n .option('-f, --force', 'Overwrite existing files')\n .action(runInit);\n\n// Parse arguments\nprogram.parse();\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|