docusaurus-plugin-mcp-server 0.5.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/index.ts","../src/plugin/route-collector.ts","../src/processing/html-parser.ts","../src/processing/html-to-markdown.ts","../src/processing/heading-extractor.ts","../src/search/flexsearch-indexer.ts","../src/plugin/docusaurus-plugin.ts","../src/mcp/tools/docs-search.ts","../src/mcp/tools/docs-get-page.ts","../src/mcp/tools/docs-get-section.ts","../src/mcp/server.ts"],"names":["fs","path","unified","rehypeParse","results","searchIndex","lines"],"mappings":";;;;;;;;;;;;;;;;;;;AA0MO,IAAM,eAAA,GAAyC;AAAA,EACpD,SAAA,EAAW,KAAA;AAAA,EACX,gBAAA,EAAkB,CAAC,SAAA,EAAW,MAAA,EAAQ,iBAAiB,eAAe,CAAA;AAAA,EACtE,gBAAA,EAAkB;AAAA,IAChB,KAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,qBAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,gBAAA,EAAkB,EAAA;AAAA,EAClB,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,iBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,aAAA,EAAe,CAAC,OAAA,EAAS,UAAU;AACrC;AC5JO,SAAS,YAAA,CACd,QACA,eAAA,EACkB;AAClB,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,CAAC,KAAA,KAAU;AAC9B,IAAA,OAAO,CAAC,eAAA,CAAgB,IAAA,CAAK,CAAC,OAAA,KAAY;AAExC,MAAA,MAAM,YAAA,GAAe,QAAQ,OAAA,CAAQ,KAAA,EAAO,IAAI,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AACpE,MAAA,MAAM,KAAA,GAAQ,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,YAAY,CAAA,CAAA,CAAG,CAAA;AAC5C,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAAA,IAC9B,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAMA,eAAsB,kBAAkB,MAAA,EAA2C;AACjF,EAAA,MAAM,SAA2B,EAAC;AAElC,EAAA,eAAe,cAAc,GAAA,EAA4B;AACvD,IAAA,MAAM,OAAA,GAAU,MAAMA,GAAA,CAAG,OAAA,CAAQ,KAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAE7D,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,MAAM,QAAA,GAAWC,KAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AAE1C,MAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AAEvB,QAAA,IAAI,CAAC,UAAU,KAAA,EAAO,QAAQ,EAAE,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EAAG;AACpD,UAAA;AAAA,QACF;AACA,QAAA,MAAM,cAAc,QAAQ,CAAA;AAAA,MAC9B,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AAEtC,QAAA,MAAM,YAAA,GAAeA,KAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,QAAQ,CAAA;AACnD,QAAA,IAAI,SAAA,GAAY,MAAMA,KAAA,CAAK,OAAA,CAAQ,YAAY,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAGnE,QAAA,IAAI,cAAc,IAAA,EAAM;AACtB,UAAA,SAAA,GAAY,GAAA;AAAA,QACd;AAEA,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,SAAA;AAAA,UACN,QAAA,EAAU;AAAA,SACX,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,cAAc,MAAM,CAAA;AAC1B,EAAA,OAAO,MAAA;AACT;AA4BA,eAAsB,aAAA,CACpB,QACA,eAAA,EAC2B;AAE3B,EAAA,MAAM,SAAA,GAAY,MAAM,iBAAA,CAAkB,MAAM,CAAA;AAGhD,EAAA,MAAM,cAAA,GAAiB,YAAA,CAAa,SAAA,EAAW,eAAe,CAAA;AAG9D,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA4B;AACrD,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,IAAI,CAAC,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AACjC,MAAA,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,KAAK,CAAA;AAAA,IACpC;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ,CAAA;AACzC;ACzJO,SAAS,UAAU,IAAA,EAAoB;AAC5C,EAAA,MAAM,SAAA,GAAY,OAAA,EAAQ,CAAE,GAAA,CAAI,WAAW,CAAA;AAC3C,EAAA,OAAO,SAAA,CAAU,MAAM,IAAI,CAAA;AAC7B;AAKA,eAAsB,cAAc,QAAA,EAAiC;AACnE,EAAA,MAAM,IAAA,GAAO,MAAMD,GAAAA,CAAG,QAAA,CAAS,UAAU,OAAO,CAAA;AAChD,EAAA,OAAO,UAAU,IAAI,CAAA;AACvB;AAQO,SAAS,aAAa,IAAA,EAAoB;AAE/C,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,EAAM,IAAI,CAAA;AACnC,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,OAAO,QAAA,CAAS,SAAS,CAAA,CAAE,IAAA,EAAK;AAAA,EAClC;AAGA,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,OAAA,EAAS,IAAI,CAAA;AACzC,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,OAAO,QAAA,CAAS,YAAY,CAAA,CAAE,IAAA,EAAK;AAAA,EACrC;AAEA,EAAA,OAAO,UAAA;AACT;AAKO,SAAS,mBAAmB,IAAA,EAAoB;AACrD,EAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,0BAAA,EAA4B,IAAI,CAAA;AAC/D,EAAA,IAAI,eAAA,IAAmB,eAAA,CAAgB,UAAA,EAAY,OAAA,EAAS;AAC1D,IAAA,OAAO,MAAA,CAAO,eAAA,CAAgB,UAAA,CAAW,OAAO,CAAA;AAAA,EAClD;AAGA,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,iCAAA,EAAmC,IAAI,CAAA;AACpE,EAAA,IAAI,aAAA,IAAiB,aAAA,CAAc,UAAA,EAAY,OAAA,EAAS;AACtD,IAAA,OAAO,MAAA,CAAO,aAAA,CAAc,UAAA,CAAW,OAAO,CAAA;AAAA,EAChD;AAEA,EAAA,OAAO,EAAA;AACT;AAKO,SAAS,kBAAA,CAAmB,MAAY,SAAA,EAAqC;AAClF,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,QAAA,EAAU,IAAI,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,OAAO,CAAA,CAAE,IAAA,EAAK;AACpC,MAAA,IAAI,IAAA,CAAK,SAAS,EAAA,EAAI;AACpB,QAAA,OAAO,OAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,IAAM,eAAA,GAAkB,CAAC,QAAA,EAAU,OAAA,EAAS,UAAU,CAAA;AAQ/C,SAAS,mBAAA,CAAoB,SAAkB,gBAAA,EAAqC;AACzF,EAAA,MAAM,YAAA,GAAe,CAAC,GAAG,eAAA,EAAiB,GAAG,gBAAgB,CAAA;AAG7D,EAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA;AAEjD,EAAA,SAAS,eAAe,IAAA,EAAqB;AAC3C,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAEpB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,CAAC,KAAA,KAAU;AAC9C,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,SAAA,EAAW,OAAO,IAAA;AAErC,MAAA,MAAM,YAAA,GAAe,KAAA;AAGrB,MAAA,KAAA,MAAW,YAAY,YAAA,EAAc;AACnC,QAAA,IAAI,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAE5B,UAAA,MAAM,SAAA,GAAY,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA;AAClC,UAAA,MAAM,OAAA,GAAU,aAAa,UAAA,EAAY,SAAA;AACzC,UAAA,IAAI,MAAM,OAAA,CAAQ,OAAO,KAAK,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,EAAG;AACzD,YAAA,OAAO,KAAA;AAAA,UACT;AACA,UAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,EAAG;AAC9D,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,QACF,CAAA,MAAA,IAAW,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAEnC,UAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,uBAAuB,CAAA;AACpD,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,MAAM,GAAG,IAAA,EAAM,KAAK,CAAA,GAAI,KAAA;AACxB,YAAA,IAAI,IAAA,IAAQ,YAAA,CAAa,UAAA,GAAa,IAAI,MAAM,KAAA,EAAO;AACrD,cAAA,OAAO,KAAA;AAAA,YACT;AAAA,UACF;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,IAAI,YAAA,CAAa,YAAY,QAAA,EAAU;AACrC,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAGA,MAAA,cAAA,CAAe,YAAY,CAAA;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,cAAA,CAAe,MAAM,CAAA;AACrB,EAAA,OAAO,MAAA;AACT;AAeA,eAAsB,cAAA,CACpB,UACA,OAAA,EAC2B;AAC3B,EAAA,MAAM,IAAA,GAAO,MAAM,aAAA,CAAc,QAAQ,CAAA;AAEzC,EAAA,MAAM,KAAA,GAAQ,aAAa,IAAI,CAAA;AAC/B,EAAA,MAAM,WAAA,GAAc,mBAAmB,IAAI,CAAA;AAG3C,EAAA,IAAI,cAAA,GAAiB,kBAAA,CAAmB,IAAA,EAAM,OAAA,CAAQ,gBAAgB,CAAA;AAEtE,EAAA,IAAI,CAAC,cAAA,EAAgB;AAEnB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,EAAQ,IAAI,CAAA;AAChC,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,cAAA,GAAiB,IAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,GAAc,EAAA;AAClB,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,MAAM,cAAA,GAAiB,mBAAA,CAAoB,cAAA,EAAgB,OAAA,CAAQ,gBAAgB,CAAA;AAEnF,IAAA,WAAA,GAAc,iBAAiB,cAAc,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AACF;AAKA,SAAS,iBAAiB,OAAA,EAA0B;AAClD,EAAA,MAAM,YAAA,uBAAmB,GAAA,CAAI;AAAA,IAC3B,MAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,SAAS,UAAU,IAAA,EAAuB;AACxC,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,EAAA;AAE9C,IAAA,MAAM,CAAA,GAAI,IAAA;AAQV,IAAA,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ;AACrB,MAAA,OAAO,EAAE,KAAA,IAAS,EAAA;AAAA,IACpB;AAEA,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,CAAA,CAAE,OAAA,EAAS;AACrC,MAAA,MAAM,UAAU,CAAA,CAAE,OAAA;AAClB,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,UAAA,IAAc,EAAC;AAG/B,MAAA,MAAM,QAAkB,EAAC;AACzB,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,QAAA,IAAI,GAAA,KAAQ,WAAA,IAAe,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/C,UAAA,KAAA,CAAM,KAAK,CAAA,OAAA,EAAU,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,QACzC,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,SAAA,EAAW;AACrC,UAAA,IAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AAAA,QAC3B,CAAA,MAAA,IAAW,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAChD,UAAA,KAAA,CAAM,KAAK,CAAA,EAAG,GAAG,KAAK,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,QACxC;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,GAAS,CAAA,GAAI,MAAM,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,GAAI,EAAA;AAE3D,MAAA,IAAI,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA,EAAG;AAC7B,QAAA,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,EAAG,OAAO,CAAA,GAAA,CAAA;AAAA,MAC9B;AAEA,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,IAAY,EAAC;AAChC,MAAA,MAAM,eAAe,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA,CAAE,KAAK,EAAE,CAAA;AAEpD,MAAA,OAAO,IAAI,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,YAAY,KAAK,OAAO,CAAA,CAAA,CAAA;AAAA,IAC1D;AAEA,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,QAAA,EAAU;AACnC,MAAA,OAAO,EAAE,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA,CAAE,KAAK,EAAE,CAAA;AAAA,IAC1C;AAEA,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,OAAO,UAAU,OAAO,CAAA;AAC1B;AChQA,eAAsB,eAAe,IAAA,EAA+B;AAClE,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AACrC,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,YAAYE,OAAAA,EAAQ,CACvB,GAAA,CAAIC,WAAAA,EAAa,EAAE,QAAA,EAAU,IAAA,EAAM,CAAA,CACnC,IAAI,YAAY,CAAA,CAChB,IAAI,SAAS,CAAA,CACb,IAAI,eAAA,EAAiB;AAAA,MACpB,MAAA,EAAQ,GAAA;AAAA,MACR,MAAA,EAAQ;AAAA,KACT,CAAA;AAEH,IAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAC3C,IAAA,IAAI,QAAA,GAAW,OAAO,MAAM,CAAA;AAG5B,IAAA,QAAA,GAAW,cAAc,QAAQ,CAAA;AAEjC,IAAA,OAAO,QAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AAEzD,IAAA,OAAO,oBAAoB,IAAI,CAAA;AAAA,EACjC;AACF;AAKA,SAAS,cAAc,QAAA,EAA0B;AAC/C,EAAA,OACE,SAEG,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA,CAEzB,KAAA,CAAM,IAAI,CAAA,CACV,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,SAAS,CAAA,CAC5B,KAAK,IAAI,CAAA,CAET,MAAK,GAAI,IAAA;AAEhB;AAKA,SAAS,oBAAoB,IAAA,EAAsB;AAEjD,EAAA,IAAI,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,mCAAA,EAAqC,EAAE,CAAA;AAC/D,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,iCAAA,EAAmC,EAAE,CAAA;AAGzD,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,EAAgB,IAAI,CAAA;AACxC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA;AACrC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,EAAgB,MAAM,CAAA;AAC1C,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,IAAI,CAAA;AACpC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAa,IAAI,CAAA;AAGrC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGlC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA;AAClC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA;AACjC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA;AAChC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA;AAChC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA;AAClC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA;AAGjC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA;AAClC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA;AAErC,EAAA,OAAO,KAAK,IAAA,EAAK;AACnB;;;ACjFO,SAAS,4BAA4B,QAAA,EAAgC;AAC1E,EAAA,MAAM,WAAyB,EAAC;AAChC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA;AACjC,EAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA;AACzB,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,wCAAwC,CAAA;AAExE,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,MAAA,GAAS,YAAA,CAAa,CAAC,CAAA,IAAK,EAAA;AAClC,MAAA,MAAM,QAAQ,MAAA,CAAO,MAAA;AACrB,MAAA,IAAI,IAAA,GAAO,YAAA,CAAa,CAAC,CAAA,IAAK,EAAA;AAC9B,MAAA,IAAI,EAAA,GAAK,YAAA,CAAa,CAAC,CAAA,IAAK,EAAA;AAG5B,MAAA,IAAI,CAAC,EAAA,EAAI;AACP,QAAA,EAAA,GAAK,kBAAkB,IAAI,CAAA;AAAA,MAC7B;AAGA,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,kBAAA,EAAoB,IAAI,CAAA;AAC5C,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc,IAAI,CAAA;AACtC,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc,IAAI,CAAA;AAEtC,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,KAAA;AAAA,QACA,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,QAChB,EAAA;AAAA,QACA,WAAA,EAAa,aAAA;AAAA,QACb,SAAA,EAAW;AAAA;AAAA,OACZ,CAAA;AAAA,IACH;AAEA,IAAA,aAAA,IAAiB,KAAK,MAAA,GAAS,CAAA;AAAA,EACjC;AAGA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,OAAA,GAAU,SAAS,CAAC,CAAA;AAC1B,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,YAAY,QAAA,CAAS,MAAA;AAGzB,IAAA,KAAA,IAAS,IAAI,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC5C,MAAA,MAAM,IAAA,GAAO,SAAS,CAAC,CAAA;AACvB,MAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,KAAA,IAAS,OAAA,CAAQ,KAAA,EAAO;AACvC,QAAA,SAAA,GAAY,IAAA,CAAK,WAAA;AACjB,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AAAA,EACtB;AAEA,EAAA,OAAO,QAAA;AACT;AAKO,SAAS,kBAAkB,IAAA,EAAsB;AACtD,EAAA,OACE,KACG,WAAA,EAAY,CAEZ,OAAA,CAAQ,WAAA,EAAa,EAAE,CAAA,CAEvB,OAAA,CAAQ,MAAA,EAAQ,GAAG,EAEnB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAElB,OAAA,CAAQ,UAAU,EAAE,CAAA;AAE3B;AAKO,SAAS,cAAA,CACd,QAAA,EACA,SAAA,EACA,QAAA,EACe;AACf,EAAA,MAAM,UAAU,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,SAAS,CAAA;AAEvD,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAS,KAAA,CAAM,OAAA,CAAQ,aAAa,OAAA,CAAQ,SAAS,EAAE,IAAA,EAAK;AACrE;ACvFA,IAAM,aAAA,GAAgB;AAAA,EACpB,KAAA,EAAO,CAAA;AAAA,EACP,QAAA,EAAU,CAAA;AAAA,EACV,WAAA,EAAa,GAAA;AAAA,EACb,OAAA,EAAS;AACX,CAAA;AAMA,SAAS,eAAe,IAAA,EAAsB;AAE5C,EAAA,IAAI,IAAA,CAAK,MAAA,IAAU,CAAA,EAAG,OAAO,IAAA;AAE7B,EAAA,OACE,KAEG,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAElB,QAAQ,OAAA,EAAS,GAAG,CAAA,CACpB,OAAA,CAAQ,SAAS,GAAG,CAAA,CAEpB,QAAQ,eAAA,EAAiB,IAAI,EAE7B,OAAA,CAAQ,eAAA,EAAiB,IAAI,CAAA,CAE7B,QAAQ,KAAA,EAAO,EAAE,EAEjB,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA,CAEnB,OAAA,CAAQ,OAAA,EAAS,EAAE,EAEnB,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAEnB,OAAA,CAAQ,YAAY,IAAI,CAAA;AAE/B;AAWO,SAAS,iBAAA,GAAwC;AACtD,EAAA,OAAO,IAAI,WAAW,QAAA,CAAsC;AAAA;AAAA;AAAA,IAG1D,QAAA,EAAU,MAAA;AAAA;AAAA,IAGV,KAAA,EAAO,GAAA;AAAA;AAAA,IAGP,UAAA,EAAY,CAAA;AAAA;AAAA,IAGZ,OAAA,EAAS;AAAA,MACP,UAAA,EAAY,CAAA;AAAA,MACZ,KAAA,EAAO,CAAA;AAAA,MACP,aAAA,EAAe;AAAA,KACjB;AAAA;AAAA,IAGA,MAAA,EAAQ,CAAC,GAAA,KAAgB;AAEvB,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,MAAM,yBAAyB,CAAA;AAE/D,MAAA,OAAO,KAAA,CAAM,MAAA,CAAO,OAAO,CAAA,CAAE,IAAI,cAAc,CAAA;AAAA,IACjD,CAAA;AAAA;AAAA,IAGA,QAAA,EAAU;AAAA,MACR,EAAA,EAAI,IAAA;AAAA;AAAA,MAEJ,KAAA,EAAO,CAAC,OAAA,EAAS,SAAA,EAAW,YAAY,aAAa,CAAA;AAAA;AAAA,MAErD,KAAA,EAAO,CAAC,OAAA,EAAS,aAAa;AAAA;AAChC,GACD,CAAA;AACH;AAKO,SAAS,kBAAA,CAAmB,OAA2B,GAAA,EAAyB;AACrF,EAAA,MAAM,SAAA,GAA+B;AAAA,IACnC,IAAI,GAAA,CAAI,KAAA;AAAA,IACR,OAAO,GAAA,CAAI,KAAA;AAAA,IACX,SAAS,GAAA,CAAI,QAAA;AAAA,IACb,QAAA,EAAU,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,IAClD,aAAa,GAAA,CAAI;AAAA,GACnB;AAEA,EAAA,KAAA,CAAM,IAAI,SAAS,CAAA;AACrB;AAKO,SAAS,iBAAiB,IAAA,EAA0C;AACzE,EAAA,MAAM,QAAQ,iBAAA,EAAkB;AAEhC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,kBAAA,CAAmB,OAAO,GAAG,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,KAAA;AACT;AASO,SAAS,YACd,KAAA,EACA,IAAA,EACA,KAAA,EACA,OAAA,GAA8B,EAAC,EACf;AAChB,EAAA,MAAM,EAAE,KAAA,GAAQ,CAAA,EAAE,GAAI,OAAA;AAGtB,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO;AAAA,IACrC,OAAO,KAAA,GAAQ,CAAA;AAAA;AAAA,IACf,MAAA,EAAQ;AAAA,GACT,CAAA;AAGD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAE1C,EAAA,KAAA,MAAW,eAAe,UAAA,EAAY;AAEpC,IAAA,MAAM,QAAQ,WAAA,CAAY,KAAA;AAC1B,IAAA,MAAM,WAAA,GAAc,aAAA,CAAc,KAAK,CAAA,IAAK,CAAA;AAG5C,IAAA,MAAMC,WAAU,WAAA,CAAY,MAAA;AAE5B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAIA,QAAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,MAAA,MAAM,IAAA,GAAOA,SAAQ,CAAC,CAAA;AACtB,MAAA,IAAI,CAAC,IAAA,EAAM;AAEX,MAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,CAAK,EAAA;AAGrD,MAAA,MAAM,aAAA,GAAA,CAAiBA,QAAAA,CAAQ,MAAA,GAAS,CAAA,IAAKA,QAAAA,CAAQ,MAAA;AAGrD,MAAA,MAAM,gBAAgB,aAAA,GAAgB,WAAA;AAGtC,MAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,IAAK,CAAA;AAC9C,MAAA,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,aAAA,GAAgB,aAAa,CAAA;AAAA,IACpD;AAAA,EACF;AAGA,EAAA,MAAM,UAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,SAAA,EAAW;AACtC,IAAA,MAAM,GAAA,GAAM,KAAK,KAAK,CAAA;AACtB,IAAA,IAAI,CAAC,GAAA,EAAK;AAEV,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,KAAA;AAAA,MACA,OAAA,EAAS,eAAA,CAAgB,GAAA,CAAI,QAAA,EAAU,KAAK,CAAA;AAAA,MAC5C,gBAAA,EAAkB,oBAAA,CAAqB,GAAA,EAAK,KAAK;AAAA,KAClD,CAAA;AAAA,EACH;AAGA,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACxC,EAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAC/B;AAKO,SAAS,eAAA,CAAgB,UAAkB,KAAA,EAAuB;AACvE,EAAA,MAAM,SAAA,GAAY,GAAA;AAClB,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAElE,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO,QAAA,CAAS,MAAM,CAAA,EAAG,SAAS,KAAK,QAAA,CAAS,MAAA,GAAS,YAAY,KAAA,GAAQ,EAAA,CAAA;AAAA,EAC/E;AAEA,EAAA,MAAM,aAAA,GAAgB,SAAS,WAAA,EAAY;AAC3C,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,IAAI,QAAA,GAAW,EAAA;AAGf,EAAA,MAAM,QAAA,GAAW,CAAC,GAAG,UAAA,EAAY,GAAG,UAAA,CAAW,GAAA,CAAI,cAAc,CAAC,CAAA;AAElE,EAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,IAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAA;AACxC,IAAA,IAAI,KAAA,KAAU,EAAA,KAAO,SAAA,KAAc,EAAA,IAAM,QAAQ,SAAA,CAAA,EAAY;AAC3D,MAAA,SAAA,GAAY,KAAA;AACZ,MAAA,QAAA,GAAW,IAAA;AAAA,IACb;AAAA,EACF;AAEA,EAAA,IAAI,cAAc,EAAA,EAAI;AAEpB,IAAA,OAAO,QAAA,CAAS,MAAM,CAAA,EAAG,SAAS,KAAK,QAAA,CAAS,MAAA,GAAS,YAAY,KAAA,GAAQ,EAAA,CAAA;AAAA,EAC/E;AAEA,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,YAAY,EAAE,CAAA;AAC/C,EAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,QAAA,CAAS,QAAQ,SAAA,GAAY,QAAA,CAAS,SAAS,GAAG,CAAA;AAE9E,EAAA,IAAI,OAAA,GAAU,QAAA,CAAS,KAAA,CAAM,YAAA,EAAc,UAAU,CAAA;AAErD,EAAA,OAAA,GAAU,OAAA,CAEP,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA,CAE1B,QAAQ,wBAAA,EAA0B,IAAI,CAAA,CAEtC,OAAA,CAAQ,yBAAA,EAA2B,EAAE,EAErC,OAAA,CAAQ,eAAA,EAAiB,EAAE,CAAA,CAE3B,OAAA,CAAQ,YAAA,EAAc,IAAI,CAAA,CAE1B,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,EAAK;AAER,EAAA,MAAM,MAAA,GAAS,YAAA,GAAe,CAAA,GAAI,KAAA,GAAQ,EAAA;AAC1C,EAAA,MAAM,MAAA,GAAS,UAAA,GAAa,QAAA,CAAS,MAAA,GAAS,KAAA,GAAQ,EAAA;AAEtD,EAAA,OAAO,SAAS,OAAA,GAAU,MAAA;AAC5B;AAKA,SAAS,oBAAA,CAAqB,KAAmB,KAAA,EAAyB;AACxE,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAElE,EAAA,MAAM,QAAA,GAAW,CAAC,GAAG,UAAA,EAAY,GAAG,UAAA,CAAW,GAAA,CAAI,cAAc,CAAC,CAAA;AAClE,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,KAAA,MAAW,OAAA,IAAW,IAAI,QAAA,EAAU;AAClC,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,CAAK,WAAA,EAAY;AAC9C,IAAA,MAAM,cAAA,GAAiB,aAAa,KAAA,CAAM,KAAK,EAAE,GAAA,CAAI,cAAc,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAG7E,IAAA,IACE,QAAA,CAAS,IAAA;AAAA,MACP,CAAC,IAAA,KAAS,YAAA,CAAa,QAAA,CAAS,IAAI,KAAK,cAAA,CAAe,QAAA,CAAS,cAAA,CAAe,IAAI,CAAC;AAAA,KACvF,EACA;AACA,MAAA,QAAA,CAAS,IAAA,CAAK,QAAQ,IAAI,CAAA;AAAA,IAC5B;AAAA,EACF;AAEA,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AAC5B;AAKA,eAAsB,kBAAkB,KAAA,EAA6C;AACnF,EAAA,MAAM,aAAsC,EAAC;AAE7C,EAAA,MAAM,KAAA,CAAM,MAAA,CAAO,CAAC,GAAA,EAAK,IAAA,KAAS;AAChC,IAAA,UAAA,CAAW,GAAa,CAAA,GAAI,IAAA;AAAA,EAC9B,CAAC,CAAA;AAED,EAAA,OAAO,UAAA;AACT;AAKA,eAAsB,kBACpB,IAAA,EAC6B;AAC7B,EAAA,MAAM,QAAQ,iBAAA,EAAkB;AAEhC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAE/C,IAAA,MAAO,KAAA,CAA+E,MAAA;AAAA,MACpF,GAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;;;AChSA,SAAS,eAAe,OAAA,EAAwD;AAC9E,EAAA,OAAO;AAAA,IACL,GAAG,eAAA;AAAA,IACH,GAAG,OAAA;AAAA,IACH,MAAA,EAAQ;AAAA,MACN,GAAG,eAAA,CAAgB,MAAA;AAAA,MACnB,GAAG,OAAA,CAAQ;AAAA;AACb,GACF;AACF;AAcA,eAAe,eAAA,CACb,QAAA,EACA,KAAA,EACA,OAAA,EAC8B;AAC9B,EAAA,IAAI;AAEF,IAAA,MAAM,cAAA,GAAwC;AAAA,MAC5C,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,MAC1B,kBAAkB,OAAA,CAAQ;AAAA,KAC5B;AACA,IAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,QAAA,EAAU,cAAc,CAAA;AAE/D,IAAA,IAAI,CAAC,UAAU,WAAA,EAAa;AAC1B,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,0BAAA,EAA6B,QAAQ,CAAA,CAAE,CAAA;AACpD,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,MAAM,cAAA,CAAe,SAAA,CAAU,WAAW,CAAA;AAE3D,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,MAAK,CAAE,MAAA,GAAS,QAAQ,gBAAA,EAAkB;AAClE,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,8BAAA,EAAiC,QAAQ,CAAA,CAAE,CAAA;AACxD,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,4BAA4B,QAAQ,CAAA;AAErD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,OAAO,SAAA,CAAU,KAAA;AAAA,MACjB,aAAa,SAAA,CAAU,WAAA;AAAA,MACvB,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,uBAAA,EAA0B,QAAQ,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAC1D,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAKe,SAAR,eAAA,CACL,SACA,OAAA,EACQ;AACR,EAAA,MAAM,eAAA,GAAkB,eAAe,OAAO,CAAA;AAE9C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,8BAAA;AAAA;AAAA,IAGN,MAAM,aAAA,CAAc,EAAE,OAAA,EAAQ,EAAG;AAC/B,MAAA,MAAM,EAAE,eAAc,GAAI,OAAA;AAG1B,MAAA,MAAM,YAAY,CAAA,EAAG,OAAA,CAAQ,WAAW,GAAG,CAAA,CAAA,EAAI,gBAAgB,SAAS,CAAA,CAAA;AAExE,MAAA,aAAA,CAAc;AAAA,QACZ,SAAA;AAAA,QACA,UAAA,EAAY,gBAAgB,MAAA,CAAO;AAAA,OACpC,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,SAAA,CAAU,EAAE,MAAA,EAAO,EAAG;AAC1B,MAAA,OAAA,CAAQ,IAAI,2CAA2C,CAAA;AACvD,MAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAG3B,MAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,MAAA,EAAQ,gBAAgB,aAAa,CAAA;AACxE,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,YAAA,EAAe,MAAA,CAAO,MAAM,CAAA,kBAAA,CAAoB,CAAA;AAE5D,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,OAAA,CAAQ,KAAK,kCAAkC,CAAA;AAC/C,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,cAAA,GAAqC;AAAA,QACzC,kBAAkB,eAAA,CAAgB,gBAAA;AAAA,QAClC,kBAAkB,eAAA,CAAgB,gBAAA;AAAA,QAClC,kBAAkB,eAAA,CAAgB;AAAA,OACpC;AAEA,MAAA,MAAM,gBAAgB,MAAM,IAAA;AAAA,QAC1B,MAAA;AAAA,QACA,OAAO,KAAA,KAAU;AACf,UAAA,OAAO,eAAA,CAAgB,KAAA,CAAM,QAAA,EAAU,KAAA,CAAM,MAAM,cAAc,CAAA;AAAA,QACnE,CAAA;AAAA,QACA,EAAE,aAAa,EAAA;AAAG,OACpB;AAGA,MAAA,MAAM,YAAY,aAAA,CAAc,MAAA,CAAO,CAAC,GAAA,KAA6B,QAAQ,IAAI,CAAA;AACjF,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,6BAAA,EAAgC,SAAA,CAAU,MAAM,CAAA,UAAA,CAAY,CAAA;AAExE,MAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,QAAA,OAAA,CAAQ,KAAK,mCAAmC,CAAA;AAChD,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,YAA0C,EAAC;AACjD,MAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,QAAA,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,GAAI,GAAA;AAAA,MACzB;AAGA,MAAA,OAAA,CAAQ,IAAI,gCAAgC,CAAA;AAC5C,MAAA,MAAMC,YAAAA,GAAc,iBAAiB,SAAS,CAAA;AAC9C,MAAA,MAAM,aAAA,GAAgB,MAAM,iBAAA,CAAkBA,YAAW,CAAA;AAGzD,MAAA,MAAM,QAAA,GAAwB;AAAA,QAC5B,OAAA,EAAS,gBAAgB,MAAA,CAAO,OAAA;AAAA,QAChC,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAClC,UAAU,SAAA,CAAU,MAAA;AAAA,QACpB,UAAA,EAAY,gBAAgB,MAAA,CAAO,IAAA;AAAA,QACnC,OAAA,EAAS,QAAQ,UAAA,CAAW;AAAA,OAC9B;AAGA,MAAA,MAAM,YAAA,GAAeJ,KAAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,gBAAgB,SAAS,CAAA;AAChE,MAAA,MAAMD,GAAAA,CAAG,UAAU,YAAY,CAAA;AAE/B,MAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,QAChBA,GAAAA,CAAG,SAAA,CAAUC,KAAAA,CAAK,IAAA,CAAK,YAAA,EAAc,WAAW,CAAA,EAAG,SAAA,EAAW,EAAE,MAAA,EAAQ,CAAA,EAAG,CAAA;AAAA,QAC3ED,GAAAA,CAAG,SAAA,CAAUC,KAAAA,CAAK,IAAA,CAAK,YAAA,EAAc,mBAAmB,CAAA,EAAG,aAAA,EAAe,EAAE,MAAA,EAAQ,CAAA,EAAG,CAAA;AAAA,QACvFD,GAAAA,CAAG,SAAA,CAAUC,KAAAA,CAAK,IAAA,CAAK,YAAA,EAAc,eAAe,CAAA,EAAG,QAAA,EAAU,EAAE,MAAA,EAAQ,CAAA,EAAG;AAAA,OAC/E,CAAA;AAED,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC7B,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,2BAAA,EAA8B,YAAY,CAAA,CAAE,CAAA;AACxD,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,6BAAA,EAAgC,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,IACzD;AAAA,GACF;AACF;;;AChLO,IAAM,cAAA,GAAiB;AAAA,EAC5B,IAAA,EAAM,aAAA;AAAA,EACN,WAAA,EACE,oGAAA;AAAA,EACF,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa,2DAAA;AAAA,QACb,OAAA,EAAS;AAAA;AACX,KACF;AAAA,IACA,QAAA,EAAU,CAAC,OAAO;AAAA;AAEtB;AAKO,SAAS,iBAAA,CACd,MAAA,EACA,KAAA,EACA,IAAA,EACgB;AAChB,EAAA,MAAM,EAAE,KAAA,EAAO,KAAA,GAAQ,CAAA,EAAE,GAAI,MAAA;AAG7B,EAAA,IAAI,CAAC,SAAS,OAAO,KAAA,KAAU,YAAY,KAAA,CAAM,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AACpE,IAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,EAC9E;AAEA,EAAA,MAAM,cAAA,GAAiB,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,KAAK,GAAG,EAAE,CAAA;AAGtD,EAAA,MAAM,UAAU,WAAA,CAAY,KAAA,EAAO,IAAA,EAAM,KAAA,CAAM,MAAK,EAAG;AAAA,IACrD,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,mBAAA,CAAoB,SAAyB,OAAA,EAA0B;AACrF,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,8BAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAkB,CAAC,CAAA,MAAA,EAAS,OAAA,CAAQ,MAAM,CAAA;AAAA,CAAe,CAAA;AAE/D,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AACxB,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,KAAA,CAAM,KAAK,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,IAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAA,CAAI,CAAA;AAG1C,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,OAAA,GAAU,GAAG,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAC,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,CAAA;AAC5D,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE,CAAA;AAAA,IACjC;AAEA,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AAEtC,IAAA,IAAI,MAAA,CAAO,gBAAA,IAAoB,MAAA,CAAO,gBAAA,CAAiB,SAAS,CAAA,EAAG;AACjE,MAAA,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAA,CAAO,iBAAiB,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IAC1E;AAEA,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,GAAA,EAAM,MAAA,CAAO,OAAO,CAAA,CAAE,CAAA;AACjC,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;AChFO,IAAM,eAAA,GAAkB;AAAA,EAC7B,IAAA,EAAM,eAAA;AAAA,EACN,WAAA,EACE,uHAAA;AAAA,EACF,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA;AACf,KACF;AAAA,IACA,QAAA,EAAU,CAAC,OAAO;AAAA;AAEtB;AAKO,SAAS,kBAAA,CACd,QACA,IAAA,EACqB;AACrB,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAGlB,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AAGA,EAAA,IAAI,eAAA,GAAkB,MAAM,IAAA,EAAK;AACjC,EAAA,IAAI,CAAC,eAAA,CAAgB,UAAA,CAAW,GAAG,CAAA,EAAG;AACpC,IAAA,eAAA,GAAkB,GAAA,GAAM,eAAA;AAAA,EAC1B;AACA,EAAA,IAAI,gBAAgB,MAAA,GAAS,CAAA,IAAK,eAAA,CAAgB,QAAA,CAAS,GAAG,CAAA,EAAG;AAC/D,IAAA,eAAA,GAAkB,eAAA,CAAgB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,GAAA,GAAM,KAAK,eAAe,CAAA;AAEhC,EAAA,IAAI,CAAC,GAAA,EAAK;AAER,IAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA;AACxC,IAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AAClB,MAAA,OAAO,IAAA,CAAK,QAAQ,CAAA,IAAK,IAAA;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,GAAA;AACT;AAKO,SAAS,iBAAA,CAAkB,KAA0B,OAAA,EAA0B;AACpF,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,4DAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,GAAA,CAAI,KAAK,CAAA,CAAE,CAAA;AAC3B,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,IAAI,WAAA,EAAa;AACnB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,GAAA,CAAI,WAAW,CAAA,CAAE,CAAA;AACjC,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AAGA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,OAAA,GAAU,GAAG,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAC,CAAA,EAAG,GAAA,CAAI,KAAK,CAAA,CAAA;AACzD,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,OAAO,CAAA,CAAE,CAAA;AAAA,EAClC;AAEA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,GAAA,CAAI,KAAK,CAAA,CAAE,CAAA;AACpC,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC3B,IAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,IAAI,QAAA,EAAU;AAClC,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAC5C,QAAA,KAAA,CAAM,IAAA,CAAK,GAAG,MAAM,CAAA,GAAA,EAAM,QAAQ,IAAI,CAAA,GAAA,EAAM,OAAA,CAAQ,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,MAC3D;AAAA,IACF;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AAGA,EAAA,KAAA,CAAM,IAAA,CAAK,IAAI,QAAQ,CAAA;AAEvB,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;ACrGO,IAAM,kBAAA,GAAqB;AAAA,EAChC,IAAA,EAAM,kBAAA;AAAA,EACN,WAAA,EACE,wHAAA;AAAA,EACF,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,SAAA,EAAW;AAAA,QACT,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA;AACf,KACF;AAAA,IACA,QAAA,EAAU,CAAC,OAAA,EAAS,WAAW;AAAA;AAEnC;AAmBO,SAAS,qBAAA,CACd,QACA,IAAA,EACe;AACf,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,MAAA;AAG7B,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,EACxE;AAGA,EAAA,IAAI,eAAA,GAAkB,MAAM,IAAA,EAAK;AACjC,EAAA,IAAI,CAAC,eAAA,CAAgB,UAAA,CAAW,GAAG,CAAA,EAAG;AACpC,IAAA,eAAA,GAAkB,GAAA,GAAM,eAAA;AAAA,EAC1B;AACA,EAAA,IAAI,gBAAgB,MAAA,GAAS,CAAA,IAAK,eAAA,CAAgB,QAAA,CAAS,GAAG,CAAA,EAAG;AAC/D,IAAA,eAAA,GAAkB,eAAA,CAAgB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,GAAA,GAAM,KAAK,eAAe,CAAA;AAEhC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,GAAA,EAAK,IAAA;AAAA,MACL,WAAA,EAAa,IAAA;AAAA,MACb,mBAAmB;AAAC,KACtB;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACjD,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,OAAO,CAAA,CAAE;AAAA,GACX,CAAE,CAAA;AAGF,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,SAAA,CAAU,IAAA,EAAM,CAAA;AAElE,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,GAAA;AAAA,MACA,WAAA,EAAa,IAAA;AAAA,MACb;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU,eAAe,GAAA,CAAI,QAAA,EAAU,UAAU,IAAA,EAAK,EAAG,IAAI,QAAQ,CAAA;AAE3E,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,GAAA;AAAA,IACA,aAAa,OAAA,CAAQ,IAAA;AAAA,IACrB;AAAA,GACF;AACF;AAKO,SAAS,oBAAA,CACd,MAAA,EACA,SAAA,EACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAO,GAAA,EAAK;AACf,IAAA,OAAO,4DAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAMK,SAAQ,CAAC,CAAA,SAAA,EAAY,SAAS,CAAA,6BAAA,CAAA,EAAiC,IAAI,qBAAqB,CAAA;AAE9F,IAAA,KAAA,MAAW,OAAA,IAAW,OAAO,iBAAA,EAAmB;AAC9C,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAC5C,MAAAA,MAAAA,CAAM,IAAA,CAAK,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,QAAQ,IAAI,CAAA,MAAA,EAAS,OAAA,CAAQ,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IAC7D;AAEA,IAAA,OAAOA,MAAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACxB;AAEA,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,MAAM,OAAA,GAAU,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,QAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,GAAK,IAAA;AAG5F,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,MAAA,CAAO,WAAW,CAAA,CAAE,CAAA;AACpC,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,MAAA,CAAO,IAAI,KAAK,CAAA,GAAA,EAAM,OAAO,CAAA,CAAE,CAAA;AAAA,EACvD,CAAA,MAAO;AACL,IAAA,KAAA,CAAM,IAAA,CAAK,WAAW,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,EAAA,EAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EAChE;AACA,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,KAAA,CAAM,IAAA,CAAK,OAAO,OAAO,CAAA;AAEzB,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;ACnIA,SAAS,aAAa,MAAA,EAAwD;AAC5E,EAAA,OAAO,UAAA,IAAc,UAAU,WAAA,IAAe,MAAA;AAChD;AAKA,SAAS,aAAa,MAAA,EAAwD;AAC5E,EAAA,OAAO,MAAA,IAAU,UAAU,iBAAA,IAAqB,MAAA;AAClD;AAcO,IAAM,gBAAN,MAAoB;AAAA,EACjB,MAAA;AAAA,EACA,IAAA,GAA4C,IAAA;AAAA,EAC5C,WAAA,GAAyC,IAAA;AAAA,EACzC,SAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EAEtB,YAAY,MAAA,EAAyB;AACnC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAGd,IAAA,IAAA,CAAK,YAAY,IAAI,SAAA;AAAA,MACnB;AAAA,QACE,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,OAAA,EAAS,OAAO,OAAA,IAAW;AAAA,OAC7B;AAAA,MACA;AAAA,QACE,YAAA,EAAc;AAAA,UACZ,OAAO;AAAC;AACV;AACF,KACF;AAEA,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GAAsB;AAE5B,IAAA,IAAA,CAAK,SAAA,CAAU,YAAA;AAAA,MACb,aAAA;AAAA,MACA;AAAA,QACE,WAAA,EACE,oKAAA;AAAA,QACF,WAAA,EAAa;AAAA,UACX,KAAA,EAAO,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,SAAS,yBAAyB,CAAA;AAAA,UAC3D,OAAO,CAAA,CACJ,MAAA,GACA,GAAA,EAAI,CACJ,IAAI,CAAC,CAAA,CACL,GAAA,CAAI,EAAE,EACN,QAAA,EAAS,CACT,QAAQ,CAAC,CAAA,CACT,SAAS,wDAAwD;AAAA;AACtE,OACF;AAAA,MACA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAM,KAAM;AAC1B,QAAA,MAAM,KAAK,UAAA,EAAW;AAEtB,QAAA,IAAI,CAAC,IAAA,CAAK,IAAA,IAAQ,CAAC,KAAK,WAAA,EAAa;AACnC,UAAA,OAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,MAAA,EAAiB,IAAA,EAAM,6CAA6C,CAAA;AAAA,YACtF,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAEA,QAAA,MAAM,OAAA,GAAU,kBAAkB,EAAE,KAAA,EAAO,OAAM,EAAG,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,IAAI,CAAA;AAC/E,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP,EAAE,MAAM,MAAA,EAAiB,IAAA,EAAM,oBAAoB,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA;AAAE;AACnF,SACF;AAAA,MACF;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,SAAA,CAAU,YAAA;AAAA,MACb,eAAA;AAAA,MACA;AAAA,QACE,WAAA,EACE,gIAAA;AAAA,QACF,WAAA,EAAa;AAAA,UACX,KAAA,EAAO,EACJ,MAAA,EAAO,CACP,IAAI,CAAC,CAAA,CACL,SAAS,yEAAyE;AAAA;AACvF,OACF;AAAA,MACA,OAAO,EAAE,KAAA,EAAM,KAAM;AACnB,QAAA,MAAM,KAAK,UAAA,EAAW;AAEtB,QAAA,IAAI,CAAC,KAAK,IAAA,EAAM;AACd,UAAA,OAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,MAAA,EAAiB,IAAA,EAAM,6CAA6C,CAAA;AAAA,YACtF,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAEA,QAAA,MAAM,MAAM,kBAAA,CAAmB,EAAE,KAAA,EAAM,EAAG,KAAK,IAAI,CAAA;AACnD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,iBAAA,CAAkB,GAAA,EAAK,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AAAA,SACxF;AAAA,MACF;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,SAAA,CAAU,YAAA;AAAA,MACb,kBAAA;AAAA,MACA;AAAA,QACE,WAAA,EACE,0JAAA;AAAA,QACF,WAAA,EAAa;AAAA,UACX,KAAA,EAAO,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,SAAS,qBAAqB,CAAA;AAAA,UACvD,WAAW,CAAA,CACR,MAAA,EAAO,CACP,GAAA,CAAI,CAAC,CAAA,CACL,QAAA;AAAA,YACC;AAAA;AACF;AACJ,OACF;AAAA,MACA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAU,KAAM;AAC9B,QAAA,MAAM,KAAK,UAAA,EAAW;AAEtB,QAAA,IAAI,CAAC,KAAK,IAAA,EAAM;AACd,UAAA,OAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,MAAA,EAAiB,IAAA,EAAM,6CAA6C,CAAA;AAAA,YACtF,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAEA,QAAA,MAAM,SAAS,qBAAA,CAAsB,EAAE,OAAO,SAAA,EAAU,EAAG,KAAK,IAAI,CAAA;AACpE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,MAAM,oBAAA,CAAqB,MAAA,EAAQ,SAAA,EAAW,IAAA,CAAK,OAAO,OAAO;AAAA;AACnE;AACF,SACF;AAAA,MACF;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,IAAI,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA,EAAG;AAE7B,QAAA,IAAA,CAAK,IAAA,GAAO,KAAK,MAAA,CAAO,IAAA;AACxB,QAAA,IAAA,CAAK,WAAA,GAAc,MAAM,iBAAA,CAAkB,IAAA,CAAK,OAAO,eAAe,CAAA;AAAA,MACxE,CAAA,MAAA,IAAW,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA,EAAG;AAEpC,QAAA,IAAI,MAAMN,GAAAA,CAAG,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,EAAG;AAC7C,UAAA,IAAA,CAAK,OAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,QACpD,CAAA,MAAO;AACL,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,CAAE,CAAA;AAAA,QAChE;AAEA,QAAA,IAAI,MAAMA,GAAAA,CAAG,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,EAAG;AAC9C,UAAA,MAAM,YAAY,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,OAAO,SAAS,CAAA;AACzD,UAAA,IAAA,CAAK,WAAA,GAAc,MAAM,iBAAA,CAAkB,SAAS,CAAA;AAAA,QACtD,CAAA,MAAO;AACL,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,CAAE,CAAA;AAAA,QACpE;AAAA,MACF,CAAA,MAAO;AACL,QAAA,MAAM,IAAI,MAAM,0EAA0E,CAAA;AAAA,MAC5F;AAEA,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iBAAA,CACJ,GAAA,EACA,GAAA,EACA,UAAA,EACe;AACf,IAAA,MAAM,KAAK,UAAA,EAAW;AAItB,IAAA,MAAM,SAAA,GAAY,IAAI,6BAAA,CAA8B;AAAA,MAClD,kBAAA,EAAoB,MAAA;AAAA;AAAA,MACpB,kBAAA,EAAoB;AAAA;AAAA,KACrB,CAAA;AAGD,IAAA,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,SAAS,CAAA;AAEtC,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,CAAU,aAAA,CAAc,GAAA,EAAK,GAAA,EAAK,UAAU,CAAA;AAAA,IACpD,CAAA,SAAE;AAEA,MAAA,MAAM,UAAU,KAAA,EAAM;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,iBAAiB,OAAA,EAAqC;AAC1D,IAAA,MAAM,KAAK,UAAA,EAAW;AAGtB,IAAA,MAAM,SAAA,GAAY,IAAI,wCAAA,CAAyC;AAAA,MAC7D,kBAAA,EAAoB,MAAA;AAAA;AAAA,MACpB,kBAAA,EAAoB;AAAA,KACrB,CAAA;AAGD,IAAA,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,SAAS,CAAA;AAEtC,IAAA,IAAI;AAEF,MAAA,OAAO,MAAM,SAAA,CAAU,aAAA,CAAc,OAAO,CAAA;AAAA,IAC9C,CAAA,SAAE;AAEA,MAAA,MAAM,UAAU,KAAA,EAAM;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAA,GAMH;AACD,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,KAAK,MAAA,CAAO,IAAA;AAAA,MAClB,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,OAAA;AAAA,MAChC,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,QAAA,EAAU,KAAK,IAAA,GAAO,MAAA,CAAO,KAAK,IAAA,CAAK,IAAI,EAAE,MAAA,GAAS,CAAA;AAAA,MACtD,OAAA,EAAS,KAAK,MAAA,CAAO;AAAA,KACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AACF","file":"index.mjs","sourcesContent":["/**\n * Configuration options for the MCP server plugin\n */\nexport interface McpServerPluginOptions {\n /** Output directory for MCP artifacts (relative to build dir). Default: 'mcp' */\n outputDir?: string;\n /** CSS selectors for content extraction, in order of priority */\n contentSelectors?: string[];\n /** CSS selectors for elements to remove from content before processing */\n excludeSelectors?: string[];\n /** Minimum content length (in characters) to consider a page valid. Default: 50 */\n minContentLength?: number;\n /** Server configuration */\n server?: {\n /** Name of the MCP server */\n name?: string;\n /** Version of the MCP server */\n version?: string;\n };\n /** Routes to exclude from processing (glob patterns) */\n excludeRoutes?: string[];\n}\n\n/**\n * Resolved plugin options with defaults applied\n */\nexport interface ResolvedPluginOptions {\n outputDir: string;\n contentSelectors: string[];\n excludeSelectors: string[];\n minContentLength: number;\n server: {\n name: string;\n version: string;\n };\n excludeRoutes: string[];\n}\n\n/**\n * A processed documentation page\n */\nexport interface ProcessedDoc {\n /** URL route path (e.g., /docs/getting-started) */\n route: string;\n /** Page title extracted from HTML */\n title: string;\n /** Meta description if available */\n description: string;\n /** Full page content as markdown */\n markdown: string;\n /** Headings with IDs for section navigation */\n headings: DocHeading[];\n}\n\n/**\n * A heading within a document\n */\nexport interface DocHeading {\n /** Heading level (1-6) */\n level: number;\n /** Heading text content */\n text: string;\n /** Anchor ID for linking */\n id: string;\n /** Character offset where this section starts in the markdown */\n startOffset: number;\n /** Character offset where this section ends in the markdown */\n endOffset: number;\n}\n\n/**\n * A flattened route from Docusaurus\n */\nexport interface FlattenedRoute {\n /** The URL path */\n path: string;\n /** Path to the corresponding HTML file */\n htmlPath: string;\n}\n\n/**\n * Search result from FlexSearch\n */\nexport interface SearchResult {\n /** Route of the matching document */\n route: string;\n /** Title of the document */\n title: string;\n /** Relevance score */\n score: number;\n /** Snippet of matching content */\n snippet: string;\n /** Matching headings if any */\n matchingHeadings?: string[];\n}\n\n/**\n * Manifest metadata for the MCP artifacts\n */\nexport interface McpManifest {\n /** Plugin version */\n version: string;\n /** Build timestamp */\n buildTime: string;\n /** Number of documents indexed */\n docCount: number;\n /** Server name */\n serverName: string;\n /** Base URL of the documentation site */\n baseUrl?: string;\n}\n\n/**\n * MCP Server configuration for file-based loading\n */\nexport interface McpServerFileConfig {\n /** Path to docs.json file */\n docsPath: string;\n /** Path to search-index.json file */\n indexPath: string;\n /** Server name */\n name: string;\n /** Server version */\n version?: string;\n /** Base URL for constructing full page URLs (e.g., https://docs.example.com) */\n baseUrl?: string;\n}\n\n/**\n * MCP Server configuration for pre-loaded data (e.g., Cloudflare Workers)\n */\nexport interface McpServerDataConfig {\n /** Pre-loaded docs data */\n docs: Record<string, ProcessedDoc>;\n /** Pre-loaded search index data (exported from FlexSearch via exportSearchIndex) */\n searchIndexData: Record<string, unknown>;\n /** Server name */\n name: string;\n /** Server version */\n version?: string;\n /** Base URL for constructing full page URLs (e.g., https://docs.example.com) */\n baseUrl?: string;\n}\n\n/**\n * MCP Server configuration - supports both file-based and pre-loaded data modes\n */\nexport type McpServerConfig = McpServerFileConfig | McpServerDataConfig;\n\n/**\n * Internal representation of the docs index\n */\nexport interface DocsIndex {\n /** All processed documents keyed by route */\n docs: Record<string, ProcessedDoc>;\n /** Manifest metadata */\n manifest: McpManifest;\n}\n\n/**\n * Input parameters for docs_search tool\n */\nexport interface DocsSearchParams {\n /** Search query string */\n query: string;\n /** Maximum number of results (default: 5, max: 20) */\n limit?: number;\n}\n\n/**\n * Input parameters for docs_get_page tool\n */\nexport interface DocsGetPageParams {\n /** Route path of the page */\n route: string;\n}\n\n/**\n * Input parameters for docs_get_section tool\n */\nexport interface DocsGetSectionParams {\n /** Route path of the page */\n route: string;\n /** Heading ID of the section */\n headingId: string;\n}\n\n/**\n * Content extraction result from HTML\n */\nexport interface ExtractedContent {\n /** Page title */\n title: string;\n /** Meta description */\n description: string;\n /** Main content as HTML */\n contentHtml: string;\n}\n\n/**\n * Default plugin options\n */\nexport const DEFAULT_OPTIONS: ResolvedPluginOptions = {\n outputDir: 'mcp',\n contentSelectors: ['article', 'main', '.main-wrapper', '[role=\"main\"]'],\n excludeSelectors: [\n 'nav',\n 'header',\n 'footer',\n 'aside',\n '[role=\"navigation\"]',\n '[role=\"banner\"]',\n '[role=\"contentinfo\"]',\n ],\n minContentLength: 50,\n server: {\n name: 'docs-mcp-server',\n version: '1.0.0',\n },\n excludeRoutes: ['/404*', '/search*'],\n};\n","import path from 'path';\nimport fs from 'fs-extra';\nimport type { RouteConfig } from '@docusaurus/types';\nimport type { FlattenedRoute } from '../types/index.js';\n\n/**\n * Flatten nested Docusaurus routes into a simple array\n */\nexport function flattenRoutes(routes: RouteConfig[]): FlattenedRoute[] {\n const flattened: FlattenedRoute[] = [];\n\n function traverse(route: RouteConfig): void {\n // Add the route if it has a path\n if (route.path) {\n flattened.push({\n path: route.path,\n htmlPath: '', // Will be resolved later\n });\n }\n\n // Recursively process child routes\n if (route.routes && Array.isArray(route.routes)) {\n for (const childRoute of route.routes) {\n traverse(childRoute);\n }\n }\n }\n\n for (const route of routes) {\n traverse(route);\n }\n\n return flattened;\n}\n\n/**\n * Convert a URL path to the corresponding HTML file path in the build directory\n *\n * Examples:\n * - /guides/chat/overview -> build/guides/chat/overview/index.html\n * - / -> build/index.html\n * - /api -> build/api/index.html\n */\nexport function routeToHtmlPath(routePath: string, outDir: string): string {\n // Normalize the route path\n let normalizedPath = routePath;\n\n // Remove trailing slash if present (except for root)\n if (normalizedPath.length > 1 && normalizedPath.endsWith('/')) {\n normalizedPath = normalizedPath.slice(0, -1);\n }\n\n // Handle root path\n if (normalizedPath === '/') {\n return path.join(outDir, 'index.html');\n }\n\n // For all other paths, append /index.html\n return path.join(outDir, normalizedPath, 'index.html');\n}\n\n/**\n * Filter out routes that should not be processed\n */\nexport function filterRoutes(\n routes: FlattenedRoute[],\n excludePatterns: string[]\n): FlattenedRoute[] {\n return routes.filter((route) => {\n return !excludePatterns.some((pattern) => {\n // Convert glob pattern to regex\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.');\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(route.path);\n });\n });\n}\n\n/**\n * Discover all HTML files in the build directory and create routes for them.\n * This is more reliable than using Docusaurus routes as it captures all built pages.\n */\nexport async function discoverHtmlFiles(outDir: string): Promise<FlattenedRoute[]> {\n const routes: FlattenedRoute[] = [];\n\n async function scanDirectory(dir: string): Promise<void> {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip common non-content directories\n if (['assets', 'img', 'static'].includes(entry.name)) {\n continue;\n }\n await scanDirectory(fullPath);\n } else if (entry.name === 'index.html') {\n // Convert file path back to route\n const relativePath = path.relative(outDir, fullPath);\n let routePath = '/' + path.dirname(relativePath).replace(/\\\\/g, '/');\n\n // Handle root index.html\n if (routePath === '/.') {\n routePath = '/';\n }\n\n routes.push({\n path: routePath,\n htmlPath: fullPath,\n });\n }\n }\n }\n\n await scanDirectory(outDir);\n return routes;\n}\n\n/**\n * Resolve HTML paths for flattened routes, filtering out those that don't exist\n */\nexport async function resolveHtmlPaths(\n routes: FlattenedRoute[],\n outDir: string\n): Promise<FlattenedRoute[]> {\n const resolved: FlattenedRoute[] = [];\n\n for (const route of routes) {\n const htmlPath = routeToHtmlPath(route.path, outDir);\n\n if (await fs.pathExists(htmlPath)) {\n resolved.push({\n ...route,\n htmlPath,\n });\n }\n }\n\n return resolved;\n}\n\n/**\n * Get all processable routes from the build directory\n */\nexport async function collectRoutes(\n outDir: string,\n excludePatterns: string[]\n): Promise<FlattenedRoute[]> {\n // Discover all HTML files in the build directory\n const allRoutes = await discoverHtmlFiles(outDir);\n\n // Filter out excluded routes\n const filteredRoutes = filterRoutes(allRoutes, excludePatterns);\n\n // Deduplicate routes by path\n const uniqueRoutes = new Map<string, FlattenedRoute>();\n for (const route of filteredRoutes) {\n if (!uniqueRoutes.has(route.path)) {\n uniqueRoutes.set(route.path, route);\n }\n }\n\n return Array.from(uniqueRoutes.values());\n}\n","import fs from 'fs-extra';\nimport { unified } from 'unified';\nimport rehypeParse from 'rehype-parse';\nimport { select } from 'hast-util-select';\nimport { toString } from 'hast-util-to-string';\nimport type { Root, Element } from 'hast';\nimport type { ExtractedContent } from '../types/index.js';\n\n/**\n * Parse HTML string into HAST (HTML AST)\n */\nexport function parseHtml(html: string): Root {\n const processor = unified().use(rehypeParse);\n return processor.parse(html);\n}\n\n/**\n * Parse HTML file into HAST\n */\nexport async function parseHtmlFile(filePath: string): Promise<Root> {\n const html = await fs.readFile(filePath, 'utf-8');\n return parseHtml(html);\n}\n\n/**\n * Extract page title from the HTML document\n *\n * Uses h1 as primary source (most reliable for page title),\n * falls back to <title> tag if no h1 is found.\n */\nexport function extractTitle(tree: Root): string {\n // Prefer h1 as it's the actual page heading\n const h1Element = select('h1', tree);\n if (h1Element) {\n return toString(h1Element).trim();\n }\n\n // Fall back to title tag\n const titleElement = select('title', tree);\n if (titleElement) {\n return toString(titleElement).trim();\n }\n\n return 'Untitled';\n}\n\n/**\n * Extract meta description from the HTML document\n */\nexport function extractDescription(tree: Root): string {\n const metaDescription = select('meta[name=\"description\"]', tree) as Element | null;\n if (metaDescription && metaDescription.properties?.content) {\n return String(metaDescription.properties.content);\n }\n\n // Try og:description as fallback\n const ogDescription = select('meta[property=\"og:description\"]', tree) as Element | null;\n if (ogDescription && ogDescription.properties?.content) {\n return String(ogDescription.properties.content);\n }\n\n return '';\n}\n\n/**\n * Find the main content element using CSS selectors in priority order\n */\nexport function findContentElement(tree: Root, selectors: string[]): Element | null {\n for (const selector of selectors) {\n const element = select(selector, tree) as Element | null;\n if (element) {\n // Verify the element has meaningful content\n const text = toString(element).trim();\n if (text.length > 50) {\n return element;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Always-excluded elements that should never appear in content\n */\nconst ALWAYS_EXCLUDED = ['script', 'style', 'noscript'];\n\n/**\n * Remove unwanted elements from content\n *\n * @param element - The HAST element to clean\n * @param excludeSelectors - CSS selectors for elements to remove (tag names or .class-names)\n */\nexport function cleanContentElement(element: Element, excludeSelectors: string[]): Element {\n const allSelectors = [...ALWAYS_EXCLUDED, ...excludeSelectors];\n\n // Deep clone the element to avoid mutating the original\n const cloned = JSON.parse(JSON.stringify(element)) as Element;\n\n function removeUnwanted(node: Element): void {\n if (!node.children) return;\n\n node.children = node.children.filter((child) => {\n if (child.type !== 'element') return true;\n\n const childElement = child as Element;\n\n // Check if this element matches any unwanted selectors\n for (const selector of allSelectors) {\n if (selector.startsWith('.')) {\n // Class selector\n const className = selector.slice(1);\n const classes = childElement.properties?.className;\n if (Array.isArray(classes) && classes.includes(className)) {\n return false;\n }\n if (typeof classes === 'string' && classes.includes(className)) {\n return false;\n }\n } else if (selector.startsWith('[')) {\n // Attribute selector like [role=\"navigation\"]\n const match = selector.match(/\\[([^=]+)=\"([^\"]+)\"\\]/);\n if (match) {\n const [, attr, value] = match;\n if (attr && childElement.properties?.[attr] === value) {\n return false;\n }\n }\n } else {\n // Tag selector\n if (childElement.tagName === selector) {\n return false;\n }\n }\n }\n\n // Recursively clean children\n removeUnwanted(childElement);\n return true;\n });\n }\n\n removeUnwanted(cloned);\n return cloned;\n}\n\n/**\n * Options for content extraction\n */\nexport interface ExtractContentOptions {\n /** CSS selectors for content containers, in priority order */\n contentSelectors: string[];\n /** CSS selectors for elements to exclude from content */\n excludeSelectors: string[];\n}\n\n/**\n * Extract content from HTML file\n */\nexport async function extractContent(\n filePath: string,\n options: ExtractContentOptions\n): Promise<ExtractedContent> {\n const tree = await parseHtmlFile(filePath);\n\n const title = extractTitle(tree);\n const description = extractDescription(tree);\n\n // Find main content element\n let contentElement = findContentElement(tree, options.contentSelectors);\n\n if (!contentElement) {\n // Last resort: try to find any element with substantial text\n const body = select('body', tree) as Element | null;\n if (body) {\n contentElement = body;\n }\n }\n\n let contentHtml = '';\n if (contentElement) {\n const cleanedElement = cleanContentElement(contentElement, options.excludeSelectors);\n // Serialize back to HTML string for markdown conversion\n contentHtml = serializeElement(cleanedElement);\n }\n\n return {\n title,\n description,\n contentHtml,\n };\n}\n\n/**\n * Simple serialization of HAST element to HTML string\n */\nfunction serializeElement(element: Element): string {\n const voidElements = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n ]);\n\n function serialize(node: unknown): string {\n if (!node || typeof node !== 'object') return '';\n\n const n = node as {\n type?: string;\n value?: string;\n tagName?: string;\n properties?: Record<string, unknown>;\n children?: unknown[];\n };\n\n if (n.type === 'text') {\n return n.value ?? '';\n }\n\n if (n.type === 'element' && n.tagName) {\n const tagName = n.tagName;\n const props = n.properties ?? {};\n\n // Build attributes string\n const attrs: string[] = [];\n for (const [key, value] of Object.entries(props)) {\n if (key === 'className' && Array.isArray(value)) {\n attrs.push(`class=\"${value.join(' ')}\"`);\n } else if (typeof value === 'boolean') {\n if (value) attrs.push(key);\n } else if (value !== undefined && value !== null) {\n attrs.push(`${key}=\"${String(value)}\"`);\n }\n }\n\n const attrStr = attrs.length > 0 ? ' ' + attrs.join(' ') : '';\n\n if (voidElements.has(tagName)) {\n return `<${tagName}${attrStr} />`;\n }\n\n const children = n.children ?? [];\n const childrenHtml = children.map(serialize).join('');\n\n return `<${tagName}${attrStr}>${childrenHtml}</${tagName}>`;\n }\n\n if (n.type === 'root' && n.children) {\n return n.children.map(serialize).join('');\n }\n\n return '';\n }\n\n return serialize(element);\n}\n","import { unified } from 'unified';\nimport rehypeParse from 'rehype-parse';\nimport rehypeRemark from 'rehype-remark';\nimport remarkStringify from 'remark-stringify';\nimport remarkGfm from 'remark-gfm';\n\n/**\n * Convert HTML string to Markdown\n */\nexport async function htmlToMarkdown(html: string): Promise<string> {\n if (!html || html.trim().length === 0) {\n return '';\n }\n\n try {\n const processor = unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeRemark)\n .use(remarkGfm)\n .use(remarkStringify, {\n bullet: '-',\n fences: true,\n });\n\n const result = await processor.process(html);\n let markdown = String(result);\n\n // Post-process: clean up excessive whitespace\n markdown = cleanMarkdown(markdown);\n\n return markdown;\n } catch (error) {\n console.error('Error converting HTML to Markdown:', error);\n // Return a basic text extraction as fallback\n return extractTextFallback(html);\n }\n}\n\n/**\n * Clean up markdown output\n */\nfunction cleanMarkdown(markdown: string): string {\n return (\n markdown\n // Remove excessive blank lines (more than 2 in a row)\n .replace(/\\n{3,}/g, '\\n\\n')\n // Remove trailing whitespace from lines\n .split('\\n')\n .map((line) => line.trimEnd())\n .join('\\n')\n // Ensure single newline at end\n .trim() + '\\n'\n );\n}\n\n/**\n * Fallback text extraction when markdown conversion fails\n */\nfunction extractTextFallback(html: string): string {\n // Remove script and style tags\n let text = html.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '');\n text = text.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '');\n\n // Convert common HTML elements to text\n text = text.replace(/<br\\s*\\/?>/gi, '\\n');\n text = text.replace(/<\\/p>/gi, '\\n\\n');\n text = text.replace(/<\\/h[1-6]>/gi, '\\n\\n');\n text = text.replace(/<\\/li>/gi, '\\n');\n text = text.replace(/<\\/div>/gi, '\\n');\n\n // Remove remaining HTML tags\n text = text.replace(/<[^>]+>/g, '');\n\n // Decode common HTML entities\n text = text.replace(/&nbsp;/g, ' ');\n text = text.replace(/&amp;/g, '&');\n text = text.replace(/&lt;/g, '<');\n text = text.replace(/&gt;/g, '>');\n text = text.replace(/&quot;/g, '\"');\n text = text.replace(/&#39;/g, \"'\");\n\n // Clean up whitespace\n text = text.replace(/[ \\t]+/g, ' ');\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n","import type { DocHeading } from '../types/index.js';\n\n/**\n * Extract headings from markdown content with their positions\n */\nexport function extractHeadingsFromMarkdown(markdown: string): DocHeading[] {\n const headings: DocHeading[] = [];\n const lines = markdown.split('\\n');\n let currentOffset = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? '';\n const headingMatch = line.match(/^(#{1,6})\\s+(.+?)(?:\\s+\\{#([^}]+)\\})?$/);\n\n if (headingMatch) {\n const hashes = headingMatch[1] ?? '';\n const level = hashes.length;\n let text = headingMatch[2] ?? '';\n let id = headingMatch[3] ?? '';\n\n // If no explicit ID, generate one from text (Docusaurus style)\n if (!id) {\n id = generateHeadingId(text);\n }\n\n // Clean up text (remove any remaining markdown formatting)\n text = text.replace(/\\*\\*([^*]+)\\*\\*/g, '$1'); // Remove bold\n text = text.replace(/_([^_]+)_/g, '$1'); // Remove italic\n text = text.replace(/`([^`]+)`/g, '$1'); // Remove code\n\n headings.push({\n level,\n text: text.trim(),\n id,\n startOffset: currentOffset,\n endOffset: -1, // Will be calculated below\n });\n }\n\n currentOffset += line.length + 1; // +1 for newline\n }\n\n // Calculate end offsets (each heading ends where the next same-or-higher level heading starts)\n for (let i = 0; i < headings.length; i++) {\n const current = headings[i];\n if (!current) continue;\n\n let endOffset = markdown.length;\n\n // Find the next heading at the same or higher level\n for (let j = i + 1; j < headings.length; j++) {\n const next = headings[j];\n if (next && next.level <= current.level) {\n endOffset = next.startOffset;\n break;\n }\n }\n\n current.endOffset = endOffset;\n }\n\n return headings;\n}\n\n/**\n * Generate a URL-safe heading ID (Docusaurus style)\n */\nexport function generateHeadingId(text: string): string {\n return (\n text\n .toLowerCase()\n // Remove any non-alphanumeric characters except spaces and hyphens\n .replace(/[^\\w\\s-]/g, '')\n // Replace spaces with hyphens\n .replace(/\\s+/g, '-')\n // Remove consecutive hyphens\n .replace(/-+/g, '-')\n // Remove leading/trailing hyphens\n .replace(/^-|-$/g, '')\n );\n}\n\n/**\n * Extract a specific section from markdown by heading ID\n */\nexport function extractSection(\n markdown: string,\n headingId: string,\n headings: DocHeading[]\n): string | null {\n const heading = headings.find((h) => h.id === headingId);\n\n if (!heading) {\n return null;\n }\n\n return markdown.slice(heading.startOffset, heading.endOffset).trim();\n}\n","import FlexSearch from 'flexsearch';\nimport type { ProcessedDoc, SearchResult } from '../types/index.js';\nimport type { IndexableDocument } from './types.js';\n\nexport type FlexSearchDocument = FlexSearch.Document<IndexableDocument, string[]>;\n\n/**\n * Field weights for search ranking\n * Higher values = more importance\n */\nconst FIELD_WEIGHTS = {\n title: 3.0,\n headings: 2.0,\n description: 1.5,\n content: 1.0,\n} as const;\n\n/**\n * Simple English stemmer\n * Handles common suffixes for better matching\n */\nfunction englishStemmer(word: string): string {\n // Only process words longer than 3 characters\n if (word.length <= 3) return word;\n\n return (\n word\n // -ing endings\n .replace(/ing$/, '')\n // -tion, -sion endings -> t, s\n .replace(/tion$/, 't')\n .replace(/sion$/, 's')\n // -ed endings (careful with short words)\n .replace(/([^aeiou])ed$/, '$1')\n // -es endings\n .replace(/([^aeiou])es$/, '$1')\n // -ly endings\n .replace(/ly$/, '')\n // -ment endings\n .replace(/ment$/, '')\n // -ness endings\n .replace(/ness$/, '')\n // -ies -> y\n .replace(/ies$/, 'y')\n // -s endings (simple plural)\n .replace(/([^s])s$/, '$1')\n );\n}\n\n/**\n * Create a FlexSearch document index with enhanced configuration\n *\n * Features:\n * - Full substring matching (finds \"auth\" in \"authentication\")\n * - English stemming (finds \"authenticate\" when searching \"authentication\")\n * - Context-aware scoring for phrase matching\n * - Optimized resolution for relevance ranking\n */\nexport function createSearchIndex(): FlexSearchDocument {\n return new FlexSearch.Document<IndexableDocument, string[]>({\n // Use 'full' tokenization for substring matching\n // This allows \"auth\" to match \"authentication\"\n tokenize: 'full',\n\n // Enable caching for faster repeated queries\n cache: 100,\n\n // Higher resolution = more granular ranking (1-9)\n resolution: 9,\n\n // Enable context for phrase/proximity matching\n context: {\n resolution: 2,\n depth: 2,\n bidirectional: true,\n },\n\n // Apply stemming to normalize word forms\n encode: (str: string) => {\n // Normalize to lowercase and split into words\n const words = str.toLowerCase().split(/[\\s\\-_.,;:!?'\"()[\\]{}]+/);\n // Apply stemmer to each word\n return words.filter(Boolean).map(englishStemmer);\n },\n\n // Document schema\n document: {\n id: 'id',\n // Index these fields for searching\n index: ['title', 'content', 'headings', 'description'],\n // Store these fields in results (for enriched queries)\n store: ['title', 'description'],\n },\n });\n}\n\n/**\n * Add a document to the search index\n */\nexport function addDocumentToIndex(index: FlexSearchDocument, doc: ProcessedDoc): void {\n const indexable: IndexableDocument = {\n id: doc.route,\n title: doc.title,\n content: doc.markdown,\n headings: doc.headings.map((h) => h.text).join(' '),\n description: doc.description,\n };\n\n index.add(indexable);\n}\n\n/**\n * Build the search index from processed documents\n */\nexport function buildSearchIndex(docs: ProcessedDoc[]): FlexSearchDocument {\n const index = createSearchIndex();\n\n for (const doc of docs) {\n addDocumentToIndex(index, doc);\n }\n\n return index;\n}\n\n/**\n * Search the index and return results with weighted ranking\n *\n * Ranking combines:\n * - Field importance (title > headings > description > content)\n * - Position in results (earlier = more relevant)\n */\nexport function searchIndex(\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>,\n query: string,\n options: { limit?: number } = {}\n): SearchResult[] {\n const { limit = 5 } = options;\n\n // Search across all fields\n const rawResults = index.search(query, {\n limit: limit * 3, // Get extra results for better ranking after weighting\n enrich: true,\n });\n\n // Aggregate scores across fields with weighting\n const docScores = new Map<string, number>();\n\n for (const fieldResult of rawResults) {\n // Determine which field this result is from\n const field = fieldResult.field as keyof typeof FIELD_WEIGHTS;\n const fieldWeight = FIELD_WEIGHTS[field] ?? 1.0;\n\n // With enrich: true, results are objects with id property\n const results = fieldResult.result as unknown as Array<{ id: string } | string>;\n\n for (let i = 0; i < results.length; i++) {\n const item = results[i];\n if (!item) continue;\n\n const docId = typeof item === 'string' ? item : item.id;\n\n // Position-based score (earlier = higher)\n const positionScore = (results.length - i) / results.length;\n\n // Apply field weight to position score\n const weightedScore = positionScore * fieldWeight;\n\n // Combine with existing score (additive for multi-field matches)\n const existingScore = docScores.get(docId) ?? 0;\n docScores.set(docId, existingScore + weightedScore);\n }\n }\n\n // Build results array\n const results: SearchResult[] = [];\n\n for (const [docId, score] of docScores) {\n const doc = docs[docId];\n if (!doc) continue;\n\n results.push({\n route: doc.route,\n title: doc.title,\n score,\n snippet: generateSnippet(doc.markdown, query),\n matchingHeadings: findMatchingHeadings(doc, query),\n });\n }\n\n // Sort by score (highest first) and limit\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n/**\n * Generate a snippet from the markdown content around the query terms\n */\nexport function generateSnippet(markdown: string, query: string): string {\n const maxLength = 200;\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n if (queryTerms.length === 0) {\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const lowerMarkdown = markdown.toLowerCase();\n let bestIndex = -1;\n let bestTerm = '';\n\n // Also try stemmed versions of query terms\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n\n for (const term of allTerms) {\n const index = lowerMarkdown.indexOf(term);\n if (index !== -1 && (bestIndex === -1 || index < bestIndex)) {\n bestIndex = index;\n bestTerm = term;\n }\n }\n\n if (bestIndex === -1) {\n // No term found, return beginning of document\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const snippetStart = Math.max(0, bestIndex - 50);\n const snippetEnd = Math.min(markdown.length, bestIndex + bestTerm.length + 150);\n\n let snippet = markdown.slice(snippetStart, snippetEnd);\n\n snippet = snippet\n // Remove markdown headings\n .replace(/^#{1,6}\\s+/gm, '')\n // Remove markdown links but keep text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n // Remove markdown images\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Remove code block markers\n .replace(/```[a-z]*\\n?/g, '')\n // Remove inline code backticks\n .replace(/`([^`]+)`/g, '$1')\n // Clean up whitespace\n .replace(/\\s+/g, ' ')\n .trim();\n\n const prefix = snippetStart > 0 ? '...' : '';\n const suffix = snippetEnd < markdown.length ? '...' : '';\n\n return prefix + snippet + suffix;\n}\n\n/**\n * Find headings that match the query (including stemmed forms)\n */\nfunction findMatchingHeadings(doc: ProcessedDoc, query: string): string[] {\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n // Include stemmed versions for better matching\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n const matching: string[] = [];\n\n for (const heading of doc.headings) {\n const headingLower = heading.text.toLowerCase();\n const headingStemmed = headingLower.split(/\\s+/).map(englishStemmer).join(' ');\n\n // Check if any query term matches the heading or its stemmed form\n if (\n allTerms.some(\n (term) => headingLower.includes(term) || headingStemmed.includes(englishStemmer(term))\n )\n ) {\n matching.push(heading.text);\n }\n }\n\n return matching.slice(0, 3); // Limit to 3 matching headings\n}\n\n/**\n * Export the search index to a serializable format\n */\nexport async function exportSearchIndex(index: FlexSearchDocument): Promise<unknown> {\n const exportData: Record<string, unknown> = {};\n\n await index.export((key, data) => {\n exportData[key as string] = data;\n });\n\n return exportData;\n}\n\n/**\n * Import a search index from serialized data\n */\nexport async function importSearchIndex(\n data: Record<string, unknown>\n): Promise<FlexSearchDocument> {\n const index = createSearchIndex();\n\n for (const [key, value] of Object.entries(data)) {\n // FlexSearch's import expects the data in a specific format\n await (index as unknown as { import: (key: string, data: unknown) => Promise<void> }).import(\n key,\n value\n );\n }\n\n return index;\n}\n","import path from 'path';\nimport fs from 'fs-extra';\nimport pMap from 'p-map';\nimport type { LoadContext, Plugin } from '@docusaurus/types';\nimport type {\n McpServerPluginOptions,\n ResolvedPluginOptions,\n ProcessedDoc,\n McpManifest,\n} from '../types/index.js';\nimport { DEFAULT_OPTIONS } from '../types/index.js';\nimport { collectRoutes } from './route-collector.js';\nimport { extractContent, type ExtractContentOptions } from '../processing/html-parser.js';\nimport { htmlToMarkdown } from '../processing/html-to-markdown.js';\nimport { extractHeadingsFromMarkdown } from '../processing/heading-extractor.js';\nimport { buildSearchIndex, exportSearchIndex } from '../search/flexsearch-indexer.js';\n\n/**\n * Resolve plugin options with defaults\n */\nfunction resolveOptions(options: McpServerPluginOptions): ResolvedPluginOptions {\n return {\n ...DEFAULT_OPTIONS,\n ...options,\n server: {\n ...DEFAULT_OPTIONS.server,\n ...options.server,\n },\n };\n}\n\n/**\n * Options for processing an HTML file\n */\ninterface ProcessHtmlOptions {\n contentSelectors: string[];\n excludeSelectors: string[];\n minContentLength: number;\n}\n\n/**\n * Process a single HTML file into a ProcessedDoc\n */\nasync function processHtmlFile(\n htmlPath: string,\n route: string,\n options: ProcessHtmlOptions\n): Promise<ProcessedDoc | null> {\n try {\n // Extract content from HTML\n const extractOptions: ExtractContentOptions = {\n contentSelectors: options.contentSelectors,\n excludeSelectors: options.excludeSelectors,\n };\n const extracted = await extractContent(htmlPath, extractOptions);\n\n if (!extracted.contentHtml) {\n console.warn(`[MCP] No content found in ${htmlPath}`);\n return null;\n }\n\n // Convert to markdown\n const markdown = await htmlToMarkdown(extracted.contentHtml);\n\n if (!markdown || markdown.trim().length < options.minContentLength) {\n console.warn(`[MCP] Insufficient content in ${htmlPath}`);\n return null;\n }\n\n // Extract headings\n const headings = extractHeadingsFromMarkdown(markdown);\n\n return {\n route,\n title: extracted.title,\n description: extracted.description,\n markdown,\n headings,\n };\n } catch (error) {\n console.error(`[MCP] Error processing ${htmlPath}:`, error);\n return null;\n }\n}\n\n/**\n * Docusaurus plugin that generates MCP server artifacts during build\n */\nexport default function mcpServerPlugin(\n context: LoadContext,\n options: McpServerPluginOptions\n): Plugin {\n const resolvedOptions = resolveOptions(options);\n\n return {\n name: 'docusaurus-plugin-mcp-server',\n\n // Expose configuration to theme components via globalData\n async contentLoaded({ actions }) {\n const { setGlobalData } = actions;\n\n // Construct server URL from site URL + output directory\n const serverUrl = `${context.siteConfig.url}/${resolvedOptions.outputDir}`;\n\n setGlobalData({\n serverUrl,\n serverName: resolvedOptions.server.name,\n });\n },\n\n async postBuild({ outDir }) {\n console.log('[MCP] Starting MCP artifact generation...');\n const startTime = Date.now();\n\n // Collect routes from the build output\n const routes = await collectRoutes(outDir, resolvedOptions.excludeRoutes);\n console.log(`[MCP] Found ${routes.length} routes to process`);\n\n if (routes.length === 0) {\n console.warn('[MCP] No routes found to process');\n return;\n }\n\n // Process all HTML files in parallel (with concurrency limit)\n const processOptions: ProcessHtmlOptions = {\n contentSelectors: resolvedOptions.contentSelectors,\n excludeSelectors: resolvedOptions.excludeSelectors,\n minContentLength: resolvedOptions.minContentLength,\n };\n\n const processedDocs = await pMap(\n routes,\n async (route) => {\n return processHtmlFile(route.htmlPath, route.path, processOptions);\n },\n { concurrency: 10 }\n );\n\n // Filter out null results\n const validDocs = processedDocs.filter((doc): doc is ProcessedDoc => doc !== null);\n console.log(`[MCP] Successfully processed ${validDocs.length} documents`);\n\n if (validDocs.length === 0) {\n console.warn('[MCP] No valid documents to index');\n return;\n }\n\n // Build docs index\n const docsIndex: Record<string, ProcessedDoc> = {};\n for (const doc of validDocs) {\n docsIndex[doc.route] = doc;\n }\n\n // Build search index\n console.log('[MCP] Building search index...');\n const searchIndex = buildSearchIndex(validDocs);\n const exportedIndex = await exportSearchIndex(searchIndex);\n\n // Create manifest\n const manifest: McpManifest = {\n version: resolvedOptions.server.version,\n buildTime: new Date().toISOString(),\n docCount: validDocs.length,\n serverName: resolvedOptions.server.name,\n baseUrl: context.siteConfig.url,\n };\n\n // Write output files\n const mcpOutputDir = path.join(outDir, resolvedOptions.outputDir);\n await fs.ensureDir(mcpOutputDir);\n\n await Promise.all([\n fs.writeJson(path.join(mcpOutputDir, 'docs.json'), docsIndex, { spaces: 0 }),\n fs.writeJson(path.join(mcpOutputDir, 'search-index.json'), exportedIndex, { spaces: 0 }),\n fs.writeJson(path.join(mcpOutputDir, 'manifest.json'), manifest, { spaces: 2 }),\n ]);\n\n const elapsed = Date.now() - startTime;\n console.log(`[MCP] Artifacts written to ${mcpOutputDir}`);\n console.log(`[MCP] Generation complete in ${elapsed}ms`);\n },\n };\n}\n\n// Named export for ESM compatibility\nexport { mcpServerPlugin };\n","import type { ProcessedDoc, SearchResult, DocsSearchParams } from '../../types/index.js';\nimport { searchIndex, type FlexSearchDocument } from '../../search/flexsearch-indexer.js';\n\n/**\n * Tool definition for docs_search\n */\nexport const docsSearchTool = {\n name: 'docs_search',\n description:\n 'Search across developer documentation. Returns ranked results with snippets and matching headings.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Search query string',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5, max: 20)',\n default: 5,\n },\n },\n required: ['query'],\n },\n};\n\n/**\n * Execute the docs_search tool\n */\nexport function executeDocsSearch(\n params: DocsSearchParams,\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>\n): SearchResult[] {\n const { query, limit = 5 } = params;\n\n // Validate parameters\n if (!query || typeof query !== 'string' || query.trim().length === 0) {\n throw new Error('Query parameter is required and must be a non-empty string');\n }\n\n const effectiveLimit = Math.min(Math.max(1, limit), 20);\n\n // Search the index\n const results = searchIndex(index, docs, query.trim(), {\n limit: effectiveLimit,\n });\n\n return results;\n}\n\n/**\n * Format search results for MCP response\n */\nexport function formatSearchResults(results: SearchResult[], baseUrl?: string): string {\n if (results.length === 0) {\n return 'No matching documents found.';\n }\n\n const lines: string[] = [`Found ${results.length} result(s):\\n`];\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (!result) continue;\n\n lines.push(`${i + 1}. **${result.title}**`);\n\n // Include full URL if baseUrl is provided\n if (baseUrl) {\n const fullUrl = `${baseUrl.replace(/\\/$/, '')}${result.route}`;\n lines.push(` URL: ${fullUrl}`);\n }\n\n lines.push(` Route: ${result.route}`);\n\n if (result.matchingHeadings && result.matchingHeadings.length > 0) {\n lines.push(` Matching sections: ${result.matchingHeadings.join(', ')}`);\n }\n\n lines.push(` ${result.snippet}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { ProcessedDoc, DocsGetPageParams } from '../../types/index.js';\n\n/**\n * Tool definition for docs_get_page\n */\nexport const docsGetPageTool = {\n name: 'docs_get_page',\n description:\n 'Retrieve the full content of a documentation page as markdown. Use this after searching to get complete page content.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n route: {\n type: 'string',\n description: 'The route path of the page (e.g., /docs/getting-started)',\n },\n },\n required: ['route'],\n },\n};\n\n/**\n * Execute the docs_get_page tool\n */\nexport function executeDocsGetPage(\n params: DocsGetPageParams,\n docs: Record<string, ProcessedDoc>\n): ProcessedDoc | null {\n const { route } = params;\n\n // Validate parameters\n if (!route || typeof route !== 'string') {\n throw new Error('Route parameter is required and must be a string');\n }\n\n // Normalize route (ensure leading slash, remove trailing slash)\n let normalizedRoute = route.trim();\n if (!normalizedRoute.startsWith('/')) {\n normalizedRoute = '/' + normalizedRoute;\n }\n if (normalizedRoute.length > 1 && normalizedRoute.endsWith('/')) {\n normalizedRoute = normalizedRoute.slice(0, -1);\n }\n\n // Look up the document\n const doc = docs[normalizedRoute];\n\n if (!doc) {\n // Try without leading slash\n const altRoute = normalizedRoute.slice(1);\n if (docs[altRoute]) {\n return docs[altRoute] ?? null;\n }\n return null;\n }\n\n return doc;\n}\n\n/**\n * Format page content for MCP response\n */\nexport function formatPageContent(doc: ProcessedDoc | null, baseUrl?: string): string {\n if (!doc) {\n return 'Page not found. Please check the route path and try again.';\n }\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${doc.title}`);\n lines.push('');\n\n // Metadata\n if (doc.description) {\n lines.push(`> ${doc.description}`);\n lines.push('');\n }\n\n // Include full URL if baseUrl is provided\n if (baseUrl) {\n const fullUrl = `${baseUrl.replace(/\\/$/, '')}${doc.route}`;\n lines.push(`**URL:** ${fullUrl}`);\n }\n\n lines.push(`**Route:** ${doc.route}`);\n lines.push('');\n\n // Table of contents (if there are headings)\n if (doc.headings.length > 0) {\n lines.push('## Contents');\n lines.push('');\n for (const heading of doc.headings) {\n if (heading.level <= 3) {\n const indent = ' '.repeat(heading.level - 1);\n lines.push(`${indent}- [${heading.text}](#${heading.id})`);\n }\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Main content\n lines.push(doc.markdown);\n\n return lines.join('\\n');\n}\n","import type { ProcessedDoc, DocsGetSectionParams } from '../../types/index.js';\nimport { extractSection } from '../../processing/heading-extractor.js';\n\n/**\n * Tool definition for docs_get_section\n */\nexport const docsGetSectionTool = {\n name: 'docs_get_section',\n description:\n 'Retrieve a specific section of a documentation page by heading ID. Use this to get focused content from a larger page.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n route: {\n type: 'string',\n description: 'The route path of the page (e.g., /docs/getting-started)',\n },\n headingId: {\n type: 'string',\n description: 'The ID of the heading to retrieve (e.g., authentication)',\n },\n },\n required: ['route', 'headingId'],\n },\n};\n\n/**\n * Result of executing docs_get_section\n */\nexport interface SectionResult {\n /** The section content as markdown */\n content: string | null;\n /** The document the section belongs to */\n doc: ProcessedDoc | null;\n /** The heading text */\n headingText: string | null;\n /** Available headings in the document */\n availableHeadings: Array<{ id: string; text: string; level: number }>;\n}\n\n/**\n * Execute the docs_get_section tool\n */\nexport function executeDocsGetSection(\n params: DocsGetSectionParams,\n docs: Record<string, ProcessedDoc>\n): SectionResult {\n const { route, headingId } = params;\n\n // Validate parameters\n if (!route || typeof route !== 'string') {\n throw new Error('Route parameter is required and must be a string');\n }\n if (!headingId || typeof headingId !== 'string') {\n throw new Error('HeadingId parameter is required and must be a string');\n }\n\n // Normalize route\n let normalizedRoute = route.trim();\n if (!normalizedRoute.startsWith('/')) {\n normalizedRoute = '/' + normalizedRoute;\n }\n if (normalizedRoute.length > 1 && normalizedRoute.endsWith('/')) {\n normalizedRoute = normalizedRoute.slice(0, -1);\n }\n\n // Look up the document\n const doc = docs[normalizedRoute];\n\n if (!doc) {\n return {\n content: null,\n doc: null,\n headingText: null,\n availableHeadings: [],\n };\n }\n\n // Get available headings\n const availableHeadings = doc.headings.map((h) => ({\n id: h.id,\n text: h.text,\n level: h.level,\n }));\n\n // Find the heading\n const heading = doc.headings.find((h) => h.id === headingId.trim());\n\n if (!heading) {\n return {\n content: null,\n doc,\n headingText: null,\n availableHeadings,\n };\n }\n\n // Extract the section content\n const content = extractSection(doc.markdown, headingId.trim(), doc.headings);\n\n return {\n content,\n doc,\n headingText: heading.text,\n availableHeadings,\n };\n}\n\n/**\n * Format section content for MCP response\n */\nexport function formatSectionContent(\n result: SectionResult,\n headingId: string,\n baseUrl?: string\n): string {\n if (!result.doc) {\n return 'Page not found. Please check the route path and try again.';\n }\n\n if (!result.content) {\n const lines = [`Section \"${headingId}\" not found in this document.`, '', 'Available sections:'];\n\n for (const heading of result.availableHeadings) {\n const indent = ' '.repeat(heading.level - 1);\n lines.push(`${indent}- ${heading.text} (id: ${heading.id})`);\n }\n\n return lines.join('\\n');\n }\n\n const lines: string[] = [];\n\n // Build URL with anchor if baseUrl is provided\n const fullUrl = baseUrl ? `${baseUrl.replace(/\\/$/, '')}${result.doc.route}#${headingId}` : null;\n\n // Header\n lines.push(`# ${result.headingText}`);\n if (fullUrl) {\n lines.push(`> From: ${result.doc.title} - ${fullUrl}`);\n } else {\n lines.push(`> From: ${result.doc.title} (${result.doc.route})`);\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // Section content\n lines.push(result.content);\n\n return lines.join('\\n');\n}\n","import fs from 'fs-extra';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';\nimport { z } from 'zod';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type {\n ProcessedDoc,\n McpServerConfig,\n McpServerFileConfig,\n McpServerDataConfig,\n} from '../types/index.js';\nimport { importSearchIndex, type FlexSearchDocument } from '../search/flexsearch-indexer.js';\nimport { executeDocsSearch, formatSearchResults } from './tools/docs-search.js';\nimport { executeDocsGetPage, formatPageContent } from './tools/docs-get-page.js';\nimport { executeDocsGetSection, formatSectionContent } from './tools/docs-get-section.js';\n\n/**\n * Type guard to check if config uses file-based loading\n */\nfunction isFileConfig(config: McpServerConfig): config is McpServerFileConfig {\n return 'docsPath' in config && 'indexPath' in config;\n}\n\n/**\n * Type guard to check if config uses pre-loaded data\n */\nfunction isDataConfig(config: McpServerConfig): config is McpServerDataConfig {\n return 'docs' in config && 'searchIndexData' in config;\n}\n\n/**\n * MCP Server for documentation\n *\n * This class provides the MCP server implementation that can be used\n * with any HTTP framework (Express, Vercel, Cloudflare Workers, etc.)\n *\n * Supports two modes:\n * - File-based: Load docs and search index from filesystem (Node.js)\n * - Pre-loaded: Accept docs and search index data directly (Workers)\n *\n * Uses the official MCP SDK for proper protocol handling.\n */\nexport class McpDocsServer {\n private config: McpServerConfig;\n private docs: Record<string, ProcessedDoc> | null = null;\n private searchIndex: FlexSearchDocument | null = null;\n private mcpServer: McpServer;\n private initialized = false;\n\n constructor(config: McpServerConfig) {\n this.config = config;\n\n // Create MCP server using the high-level API\n this.mcpServer = new McpServer(\n {\n name: config.name,\n version: config.version ?? '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n this.registerTools();\n }\n\n /**\n * Register all MCP tools using the SDK's registerTool API\n */\n private registerTools(): void {\n // docs_search - Search across documentation\n this.mcpServer.registerTool(\n 'docs_search',\n {\n description:\n 'Search the documentation for relevant pages. Returns matching documents with snippets and relevance scores. Use this to find information across all documentation.',\n inputSchema: {\n query: z.string().min(1).describe('The search query string'),\n limit: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .default(5)\n .describe('Maximum number of results to return (1-20, default: 5)'),\n },\n },\n async ({ query, limit }) => {\n await this.initialize();\n\n if (!this.docs || !this.searchIndex) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n const results = executeDocsSearch({ query, limit }, this.searchIndex, this.docs);\n return {\n content: [\n { type: 'text' as const, text: formatSearchResults(results, this.config.baseUrl) },\n ],\n };\n }\n );\n\n // docs_get_page - Retrieve full page content\n this.mcpServer.registerTool(\n 'docs_get_page',\n {\n description:\n 'Retrieve the complete content of a documentation page as markdown. Use this when you need the full content of a specific page.',\n inputSchema: {\n route: z\n .string()\n .min(1)\n .describe('The page route path (e.g., \"/docs/getting-started\" or \"/api/reference\")'),\n },\n },\n async ({ route }) => {\n await this.initialize();\n\n if (!this.docs) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n const doc = executeDocsGetPage({ route }, this.docs);\n return {\n content: [{ type: 'text' as const, text: formatPageContent(doc, this.config.baseUrl) }],\n };\n }\n );\n\n // docs_get_section - Retrieve a specific section\n this.mcpServer.registerTool(\n 'docs_get_section',\n {\n description:\n 'Retrieve a specific section from a documentation page by its heading ID. Use this when you need only a portion of a page rather than the entire content.',\n inputSchema: {\n route: z.string().min(1).describe('The page route path'),\n headingId: z\n .string()\n .min(1)\n .describe(\n 'The heading ID of the section to extract (e.g., \"installation\", \"api-reference\")'\n ),\n },\n },\n async ({ route, headingId }) => {\n await this.initialize();\n\n if (!this.docs) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n const result = executeDocsGetSection({ route, headingId }, this.docs);\n return {\n content: [\n {\n type: 'text' as const,\n text: formatSectionContent(result, headingId, this.config.baseUrl),\n },\n ],\n };\n }\n );\n }\n\n /**\n * Load docs and search index\n *\n * For file-based config: reads from disk\n * For data config: uses pre-loaded data directly\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n try {\n if (isDataConfig(this.config)) {\n // Pre-loaded data mode (Cloudflare Workers, etc.)\n this.docs = this.config.docs;\n this.searchIndex = await importSearchIndex(this.config.searchIndexData);\n } else if (isFileConfig(this.config)) {\n // File-based mode (Node.js)\n if (await fs.pathExists(this.config.docsPath)) {\n this.docs = await fs.readJson(this.config.docsPath);\n } else {\n throw new Error(`Docs file not found: ${this.config.docsPath}`);\n }\n\n if (await fs.pathExists(this.config.indexPath)) {\n const indexData = await fs.readJson(this.config.indexPath);\n this.searchIndex = await importSearchIndex(indexData);\n } else {\n throw new Error(`Search index not found: ${this.config.indexPath}`);\n }\n } else {\n throw new Error('Invalid server config: must provide either file paths or pre-loaded data');\n }\n\n this.initialized = true;\n } catch (error) {\n console.error('[MCP] Failed to initialize:', error);\n throw error;\n }\n }\n\n /**\n * Handle an HTTP request using the MCP SDK's transport\n *\n * This method is designed for serverless environments (Vercel, Netlify).\n * It creates a stateless transport instance and processes the request.\n *\n * @param req - Node.js IncomingMessage or compatible request object\n * @param res - Node.js ServerResponse or compatible response object\n * @param parsedBody - Optional pre-parsed request body\n */\n async handleHttpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n parsedBody?: unknown\n ): Promise<void> {\n await this.initialize();\n\n // Create a stateless transport for this request\n // enableJsonResponse: true means we get simple JSON responses instead of SSE\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode - no session tracking\n enableJsonResponse: true, // Return JSON instead of SSE streams\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request\n await transport.handleRequest(req, res, parsedBody);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Handle a Web Standard Request (Cloudflare Workers, Deno, Bun)\n *\n * This method is designed for Web Standard environments that use\n * the Fetch API Request/Response pattern.\n *\n * @param request - Web Standard Request object\n * @returns Web Standard Response object\n */\n async handleWebRequest(request: Request): Promise<Response> {\n await this.initialize();\n\n // Create a stateless transport for Web Standards\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode\n enableJsonResponse: true,\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request and return the response\n return await transport.handleRequest(request);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Get server status information\n *\n * Useful for health checks and debugging\n */\n async getStatus(): Promise<{\n name: string;\n version: string;\n initialized: boolean;\n docCount: number;\n baseUrl?: string;\n }> {\n return {\n name: this.config.name,\n version: this.config.version ?? '1.0.0',\n initialized: this.initialized,\n docCount: this.docs ? Object.keys(this.docs).length : 0,\n baseUrl: this.config.baseUrl,\n };\n }\n\n /**\n * Get the underlying McpServer instance\n *\n * Useful for advanced use cases like custom transports\n */\n getMcpServer(): McpServer {\n return this.mcpServer;\n }\n}\n"]}
@@ -0,0 +1,87 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ClientId, MCPConfigRegistry, RegistryOptions } from '@gleanwork/mcp-config-schema/browser';
3
+
4
+ /**
5
+ * Props for the McpInstallButton component
6
+ */
7
+ interface McpInstallButtonProps {
8
+ /** Server URL. If not provided, uses plugin configuration. */
9
+ serverUrl?: string;
10
+ /** Server name. If not provided, uses plugin configuration. */
11
+ serverName?: string;
12
+ /** Button label (default: "Install MCP") */
13
+ label?: string;
14
+ /** Optional className for styling */
15
+ className?: string;
16
+ /** Clients to show. Defaults to all HTTP-capable clients from registry. */
17
+ clients?: ClientId[];
18
+ }
19
+ /**
20
+ * A dropdown button component for installing MCP servers in various AI tools.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <McpInstallButton
25
+ * serverUrl="https://docs.example.com/mcp"
26
+ * serverName="my-docs"
27
+ * />
28
+ * ```
29
+ */
30
+ declare function McpInstallButton({ serverUrl: serverUrlProp, serverName: serverNameProp, label, className, clients: clientsProp, }: McpInstallButtonProps): react_jsx_runtime.JSX.Element | null;
31
+
32
+ /**
33
+ * Configuration from the plugin
34
+ */
35
+ interface McpConfig {
36
+ /** Full URL to the MCP server endpoint */
37
+ serverUrl: string;
38
+ /** Name of the MCP server for configuration */
39
+ serverName: string;
40
+ }
41
+ /**
42
+ * Registry options for the docs MCP server.
43
+ * Similar to GLEAN_REGISTRY_OPTIONS in @gleanwork/mcp-config-glean
44
+ */
45
+ declare function createDocsRegistryOptions(config: McpConfig): RegistryOptions;
46
+ /**
47
+ * Creates an MCPConfigRegistry pre-configured with the docs server settings.
48
+ *
49
+ * Similar to createGleanRegistry() from @gleanwork/mcp-config-glean
50
+ *
51
+ * @param config - The server configuration from plugin
52
+ * @returns Object with registry instance and bound config
53
+ */
54
+ declare function createDocsRegistry(config: McpConfig): {
55
+ registry: MCPConfigRegistry;
56
+ config: McpConfig;
57
+ };
58
+ /**
59
+ * Hook to access the pre-configured MCP registry and config.
60
+ *
61
+ * Reads configuration from plugin globalData and creates a registry
62
+ * with the serverUrl and serverName pre-bound in the config object.
63
+ *
64
+ * @returns { registry, config } or undefined if plugin not configured
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * function MyComponent() {
69
+ * const mcp = useMcpRegistry();
70
+ * if (!mcp) return null;
71
+ *
72
+ * const { registry, config } = mcp;
73
+ * const builder = registry.createBuilder('claude-code');
74
+ * const json = builder.buildConfiguration({
75
+ * transport: 'http',
76
+ * serverUrl: config.serverUrl,
77
+ * serverName: config.serverName,
78
+ * });
79
+ * }
80
+ * ```
81
+ */
82
+ declare function useMcpRegistry(): {
83
+ registry: MCPConfigRegistry;
84
+ config: McpConfig;
85
+ } | undefined;
86
+
87
+ export { type McpConfig, McpInstallButton, type McpInstallButtonProps, createDocsRegistry, createDocsRegistryOptions, McpInstallButton as default, useMcpRegistry };
@@ -0,0 +1,87 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ClientId, MCPConfigRegistry, RegistryOptions } from '@gleanwork/mcp-config-schema/browser';
3
+
4
+ /**
5
+ * Props for the McpInstallButton component
6
+ */
7
+ interface McpInstallButtonProps {
8
+ /** Server URL. If not provided, uses plugin configuration. */
9
+ serverUrl?: string;
10
+ /** Server name. If not provided, uses plugin configuration. */
11
+ serverName?: string;
12
+ /** Button label (default: "Install MCP") */
13
+ label?: string;
14
+ /** Optional className for styling */
15
+ className?: string;
16
+ /** Clients to show. Defaults to all HTTP-capable clients from registry. */
17
+ clients?: ClientId[];
18
+ }
19
+ /**
20
+ * A dropdown button component for installing MCP servers in various AI tools.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <McpInstallButton
25
+ * serverUrl="https://docs.example.com/mcp"
26
+ * serverName="my-docs"
27
+ * />
28
+ * ```
29
+ */
30
+ declare function McpInstallButton({ serverUrl: serverUrlProp, serverName: serverNameProp, label, className, clients: clientsProp, }: McpInstallButtonProps): react_jsx_runtime.JSX.Element | null;
31
+
32
+ /**
33
+ * Configuration from the plugin
34
+ */
35
+ interface McpConfig {
36
+ /** Full URL to the MCP server endpoint */
37
+ serverUrl: string;
38
+ /** Name of the MCP server for configuration */
39
+ serverName: string;
40
+ }
41
+ /**
42
+ * Registry options for the docs MCP server.
43
+ * Similar to GLEAN_REGISTRY_OPTIONS in @gleanwork/mcp-config-glean
44
+ */
45
+ declare function createDocsRegistryOptions(config: McpConfig): RegistryOptions;
46
+ /**
47
+ * Creates an MCPConfigRegistry pre-configured with the docs server settings.
48
+ *
49
+ * Similar to createGleanRegistry() from @gleanwork/mcp-config-glean
50
+ *
51
+ * @param config - The server configuration from plugin
52
+ * @returns Object with registry instance and bound config
53
+ */
54
+ declare function createDocsRegistry(config: McpConfig): {
55
+ registry: MCPConfigRegistry;
56
+ config: McpConfig;
57
+ };
58
+ /**
59
+ * Hook to access the pre-configured MCP registry and config.
60
+ *
61
+ * Reads configuration from plugin globalData and creates a registry
62
+ * with the serverUrl and serverName pre-bound in the config object.
63
+ *
64
+ * @returns { registry, config } or undefined if plugin not configured
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * function MyComponent() {
69
+ * const mcp = useMcpRegistry();
70
+ * if (!mcp) return null;
71
+ *
72
+ * const { registry, config } = mcp;
73
+ * const builder = registry.createBuilder('claude-code');
74
+ * const json = builder.buildConfiguration({
75
+ * transport: 'http',
76
+ * serverUrl: config.serverUrl,
77
+ * serverName: config.serverName,
78
+ * });
79
+ * }
80
+ * ```
81
+ */
82
+ declare function useMcpRegistry(): {
83
+ registry: MCPConfigRegistry;
84
+ config: McpConfig;
85
+ } | undefined;
86
+
87
+ export { type McpConfig, McpInstallButton, type McpInstallButtonProps, createDocsRegistry, createDocsRegistryOptions, McpInstallButton as default, useMcpRegistry };