@typecaast/capture 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/chunk-2UORYZUZ.js +80 -0
- package/dist/chunk-2UORYZUZ.js.map +1 -0
- package/dist/chunk-MJRHEKPU.js +569 -0
- package/dist/chunk-MJRHEKPU.js.map +1 -0
- package/dist/distill-DviDU75P.d.ts +37 -0
- package/dist/distill-kGI5Nt9q.d.cts +37 -0
- package/dist/draft.cjs +85 -0
- package/dist/draft.cjs.map +1 -0
- package/dist/draft.d.cts +94 -0
- package/dist/draft.d.ts +94 -0
- package/dist/draft.js +3 -0
- package/dist/draft.js.map +1 -0
- package/dist/import-page.cjs +624 -0
- package/dist/import-page.cjs.map +1 -0
- package/dist/import-page.d.cts +26 -0
- package/dist/import-page.d.ts +26 -0
- package/dist/import-page.js +53 -0
- package/dist/import-page.js.map +1 -0
- package/dist/index.cjs +841 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +68 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sanitize.ts","../src/tokens.ts","../src/distill.ts","../src/import-page.ts"],"names":["createDOMPurify","getWindow","JSDOM"],"mappings":";;;;;;;;;;AAiBA,IAAM,YAAA,GAAe;AAAA,EACnB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA;AAOA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA;AAQO,SAAS,SAAS,GAAA,EAAqB;AAC5C,EAAA,IAAI,GAAA,GAAM,GAAA;AAEV,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,mBAAA,EAAqB,cAAc,CAAA;AACrD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,oBAAA,EAAsB,cAAc,CAAA;AACtD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,gBAAA,EAAkB,cAAc,CAAA;AAClD,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,kBAAA,EAAoB,oBAAoB,CAAA;AAE1D,EAAA,GAAA,GAAM,IAAI,OAAA,CAAQ,mCAAA,EAAqC,CAAC,KAAA,EAAO,IAAI,GAAA,KAAQ;AACzE,IAAA,MAAM,IAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AACzC,IAAA,MAAM,UACJ,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA,IAC1B,EAAE,UAAA,CAAW,WAAW,CAAA,IACvB,CAAA,CAAE,WAAW,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,WAAW,aAAa,CAAA;AACvD,IAAA,OAAO,UAAU,MAAA,GAAS,KAAA;AAAA,EAC5B,CAAC,CAAA;AAED,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,eAAA,EAAiB,UAAU,CAAA;AAC7C,EAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,aAAA,EAAe,UAAU,CAAA;AAC3C,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,UAAU,GAAA,EAA8B;AAC/C,EAAA,IAAI,KAAK,OAAO,GAAA;AAChB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,MAAM,IAAI,KAAA;AAAA,IACR;AAAA,GACF;AACF;AAEA,IAAI,MAAA,GAAkB,IAAA;AAItB,SAAS,YAAY,GAAA,EAAqD;AACxE,EAAA,MAAM,MAAA,GAASA,iCAAgB,GAA8B,CAAA;AAE7D,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,MAAA,CAAO,OAAA,CAAQ,yBAAA,EAA2B,CAAC,IAAA,KAAS;AAClD,MAAA,MAAM,EAAA,GAAK,IAAA;AAEX,MAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,YAAA,GAAe,OAAO,CAAA;AACvC,MAAA,IAAI,OAAO,EAAA,CAAG,YAAA,CAAa,OAAA,EAAS,QAAA,CAAS,KAAK,CAAC,CAAA;AAEnD,MAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,GAAe,KAAK,CAAA;AACnC,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AACjC,QAAA,IAAI,CAAA,CAAE,WAAW,OAAO,CAAA,IAAK,CAAC,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA,EAAG;AACzD,UAAA,EAAA,CAAG,gBAAgB,KAAK,CAAA;AAAA,QAC1B;AAAA,MACF;AAEA,MAAA,IAAI,EAAA,CAAG,YAAY,GAAA,EAAK;AACtB,QAAA,EAAA,CAAG,gBAAgB,MAAM,CAAA;AACzB,QAAA,EAAA,CAAG,YAAA,CAAa,QAAQ,MAAM,CAAA;AAAA,MAChC;AAEA,MAAA,IAAI,GAAG,YAAA,GAAe,QAAQ,CAAA,EAAG,EAAA,CAAG,gBAAgB,QAAQ,CAAA;AAAA,IAC9D,CAAC,CAAA;AACD,IAAA,MAAA,GAAS,MAAA;AAAA,EACX;AACA,EAAA,OAAO,MAAA;AACT;AAYO,SAAS,YAAA,CAAa,IAAA,EAAc,IAAA,GAAwB,EAAC,EAAW;AAC7E,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AACjC,EAAA,MAAM,MAAA,GAAS,YAAY,GAAG,CAAA;AAC9B,EAAA,OAAO,MAAA,CAAO,SAAS,IAAA,EAAM;AAAA,IAC3B,YAAA;AAAA,IACA,YAAA;AAAA;AAAA,IAEA,QAAA,EAAU,CAAC,cAAc,CAAA;AAAA,IACzB,eAAA,EAAiB,KAAA;AAAA,IACjB,eAAA,EAAiB,IAAA;AAAA,IACjB,WAAA,EAAa;AAAA,MACX,QAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,WAAA,EAAa,CAAC,QAAA,EAAU,YAAA,EAAc,YAAY;AAAA,GACnD,CAAA;AACH;;;ACjNA,SAAS,WAAW,KAAA,EAAoC;AACtD,EAAA,MAAM,CAAA,uBAAQ,GAAA,EAAoB;AAClC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,EAAG;AACnC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC5B,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AACnD,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAC,EAAE,IAAA,EAAK;AACrC,IAAA,IAAI,IAAA,IAAQ,GAAA,EAAK,CAAA,CAAE,GAAA,CAAI,MAAM,GAAG,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AAEA,IAAM,QAAA,GAAW,oDAAA;AAEV,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAE/B,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,KAAgB;AAC5B,IAAA,MAAM,CAAA,GAAI,IAAI,IAAA,EAAK;AACnB,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,KAAM,aAAA,IAAiB,CAAA,KAAM,aAAa,CAAA,KAAM,cAAA;AACxD,MAAA;AACF,IAAA,SAAA,CAAU,IAAI,CAAA,EAAA,CAAI,SAAA,CAAU,IAAI,CAAC,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,EAC9C,CAAA;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,CAAC,IAAA,EAAM,GAAG,KAAK,gBAAA,CAAiB,GAAG,CAAC,CAAA,EAAG;AACtD,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA;AACrC,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,KAAA,GAAQ,WAAW,KAAK,CAAA;AAC9B,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,KAAA,EAAO;AAC/B,MAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,UAAA,CAAW,YAAY,CAAA,EAAG;AACrD,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AAClC,QAAA,IAAI,OAAA,EAAS,KAAA,MAAW,CAAA,IAAK,OAAA,OAAc,CAAC,CAAA;AAAA,MAC9C;AACA,MAAA,IAAI,IAAA,KAAS,aAAA,EAAe,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AACzC,MAAA,IAAI,IAAA,KAAS,eAAA,EAAiB,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAC3C,MAAA,IAAI,SAAS,SAAA,IAAa,IAAA,KAAS,KAAA,EAAO,MAAA,CAAO,IAAI,GAAG,CAAA;AAAA,IAC1D;AAAA,EACF;AAEA,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,CAAC,GAAG,SAAA,CAAU,OAAA,EAAS,CAAA,CACpB,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,GAAI,EAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CACX,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,EAAG,CAAA,KAAM;AACnB,IAAA,MAAA,CAAO,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA,GAAI,CAAA;AAAA,EAC7B,CAAC,CAAA;AAEH,EAAA,MAAM,GAAA,GAAc,EAAE,MAAA,EAAO;AAC7B,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,GAAA,CAAI,QAAQ,EAAC;AACb,IAAA,CAAC,GAAG,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvC,MAAA,GAAA,CAAI,KAAA,CAAO,CAAA,KAAA,EAAQ,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,GAAA,CAAI,SAAS,EAAC;AACd,IAAA,CAAC,GAAG,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvC,MAAA,GAAA,CAAI,MAAA,CAAQ,CAAA,OAAA,EAAU,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,GAAA,CAAI,QAAQ,EAAC;AACb,IAAA,CAAC,GAAG,MAAM,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACxC,MAAA,GAAA,CAAI,KAAA,CAAO,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA;AAAA,IACjC,CAAC,CAAA;AAAA,EACH;AACA,EAAA,OAAO,GAAA;AACT;;;AC5CO,IAAM,SAAA,GAAY,cAAA;AAGzB,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA;AAAA,EACA,kBAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,eAAA,GAAkB,sCAAA;AAExB,SAASC,WAAU,GAAA,EAA8B;AAC/C,EAAA,IAAI,KAAK,OAAO,GAAA;AAChB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,MAAM,IAAI,MAAM,+DAA0D,CAAA;AAC5E;AAEA,SAAS,QAAA,CAAS,IAAa,GAAA,EAA0B;AACvD,EAAA,IAAI,EAAA,CAAG,YAAA,CAAa,aAAa,CAAA,KAAM,QAAQ,OAAO,IAAA;AACtD,EAAA,IAAI,EAAA,CAAG,YAAA,CAAa,QAAQ,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,EAAA;AACxC,EAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,MAAM,UAAU,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,IAAI,WAAA,EAAY;AAC5D,EAAA,IAAI,oBAAA,CAAqB,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA;AAC9C,EAAA,IAAI,yBAAA,CAA0B,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA;AACnD,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,gBAAA,GAAmB,EAAE,CAAA;AACpC,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,IAAI,EAAA,CAAG,OAAA,KAAY,MAAA,EAAQ,OAAO,IAAA;AAClC,IAAA,IAAI,EAAA,CAAG,UAAA,KAAe,QAAA,EAAU,OAAO,IAAA;AAAA,EACzC;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,YAAA,CAAa,IAAA,EAAe,KAAA,EAAgB,GAAA,EAAuB;AAC1E,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,gBAAA,GAAmB,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,EAAA,EAAI;AACT,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAC/B,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,gBAAA,CAAiB,IAAI,CAAA;AAClC,IAAA,IAAI,KAAK,CAAA,KAAM,MAAA,IAAU,MAAM,QAAA,IAAY,CAAA,CAAE,MAAK,KAAM,EAAA;AACtD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAC9B;AACA,EAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,CAAM,YAAA,CAAa,SAAS,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAChE;AAGA,SAAS,cAAA,CACP,IAAA,EACA,KAAA,EACA,GAAA,EACA,QACA,OAAA,EACM;AACN,EAAA,IAAI,MAAA,EAAQ,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,GAAG,CAAA;AAEzC,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,GAAG,KAAA,CAAM,UAAU,CAAA,EAAG;AACxC,IAAA,IAAI,IAAA,CAAK,KAAK,UAAA,CAAW,OAAO,GAAG,KAAA,CAAM,eAAA,CAAgB,KAAK,IAAI,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,QAAA,GAAW,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,CAAC,GAAG,KAAA,CAAM,QAAQ,CAAA;AACpC,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AACpB,IAAA,MAAM,CAAA,GAAI,UAAU,CAAC,CAAA;AACrB,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG;AACd,IAAA,IAAI,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA,EAAG;AACpB,MAAA,MAAA,CAAO,KAAK,CAAC,CAAA;AACb,MAAA,OAAA,CAAQ,KAAA,EAAA;AACR,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,GAAA,EAAK,MAAA,EAAQ,OAAO,CAAA;AAAA,EAC3C;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO;AACnC;AAGA,SAAS,UAAU,EAAA,EAAqB;AACtC,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,OAAA,CAAQ,WAAA,EAAY;AACnC,EAAA,MAAM,OAAA,GAAA,CAAW,EAAA,CAAG,YAAA,CAAa,OAAO,KAAK,EAAA,EAC1C,KAAA,CAAM,KAAK,CAAA,CACX,OAAO,OAAO,CAAA,CACd,IAAA,EAAK,CACL,KAAK,GAAG,CAAA;AACX,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,EAAA,CAAG,QAAQ,CAAA,CAC5B,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,OAAA,CAAQ,WAAA,EAAa,CAAA,CAClC,KAAK,GAAG,CAAA;AACX,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,OAAO,IAAI,OAAO,CAAA,CAAA;AACrC;AAQA,SAAS,kBAAkB,IAAA,EAAkC;AAC3D,EAAA,IAAI,IAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAAgB;AAC7B,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAuB;AAC1C,IAAA,KAAA,MAAW,KAAA,IAAS,GAAG,QAAA,EAAU;AAC/B,MAAA,MAAM,GAAA,GAAM,UAAU,KAAK,CAAA;AAC3B,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,GAAG,KAAK,EAAC;AAChC,MAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AACd,MAAA,MAAA,CAAO,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,EAAO,EAAG;AAClC,MAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AAGrB,MAAA,MAAM,UAAU,IAAA,CAAK,MAAA;AAAA,QACnB,CAAC,GAAG,CAAA,KAAM,CAAA,GAAA,CAAK,EAAE,WAAA,IAAe,EAAA,EAAI,MAAK,CAAE,MAAA;AAAA,QAC3C;AAAA,OACF;AACA,MAAA,MAAM,QAAQ,IAAA,CAAK,MAAA,GAAS,KAAK,IAAA,CAAK,GAAA,CAAI,SAAS,GAAG,CAAA;AACtD,MAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,IAAA,GAAO,EAAE,SAAA,EAAW,EAAA,EAAI,IAAA,EAAK;AAAA,MAC/B;AAAA,IACF;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,EAAA,CAAG,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA;AAAA,EAC9C,CAAA;AACA,EAAA,KAAA,CAAM,IAAI,CAAA;AACV,EAAA,OAAO,IAAA;AACT;AAEA,IAAM,SAAA,GACJ,8DAAA;AACF,IAAM,SAAA,GAAY,uDAAA;AAClB,IAAM,OAAA,GAAU,yCAAA;AAChB,IAAM,OAAA,GAAU,wDAAA;AAChB,IAAM,YAAA,GACJ,6GAAA;AAEF,SAAS,QAAQ,EAAA,EAAqB;AACpC,EAAA,OAAO,EAAA,CAAG,YAAA,CAAa,OAAO,CAAA,IAAK,EAAA;AACrC;AAEA,SAAS,QAAA,CAAS,EAAA,EAAa,IAAA,EAAc,KAAA,EAAqB;AAChE,EAAA,EAAA,CAAG,YAAA,CAAa,WAAW,IAAI,CAAA;AAC/B,EAAA,EAAA,CAAG,WAAA,GAAc,KAAA;AACnB;AAGA,SAAS,WAAW,GAAA,EAGlB;AACA,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,MAAM,MAAM,CAAC,GAAG,GAAA,CAAI,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAGzC,EAAA,IAAI,MAAA,GACF,GAAA,CAAI,aAAA,CAAc,KAAK,KACvB,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,UAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,IAC1C,IAAA;AACF,EAAA,IAAI,MAAA,EAAQ;AAEV,IAAA,IAAI,MAAA,CAAO,YAAY,KAAA,EAAO;AAC5B,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,aAAA,CAAc,aAAA,CAAc,KAAK,CAAA;AACjD,MAAA,MAAM,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC1B,MAAA,IAAI,GAAA,EAAK,GAAA,CAAI,YAAA,CAAa,OAAA,EAAS,GAAG,CAAA;AACtC,MAAA,MAAM,EAAA,GAAK,MAAA,CAAO,YAAA,CAAa,OAAO,CAAA;AACtC,MAAA,IAAI,EAAA,EAAI,GAAA,CAAI,YAAA,CAAa,OAAA,EAAS,EAAE,CAAA;AACpC,MAAA,MAAA,CAAO,YAAY,GAAG,CAAA;AACtB,MAAA,MAAA,GAAS,GAAA;AAAA,IACX;AACA,IAAA,QAAA,CAAS,MAAA,EAAQ,UAAU,YAAY,CAAA;AACvC,IAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,EACxB;AAGA,EAAA,IAAI,SAAS,GAAA,CAAI,IAAA;AAAA,IACf,CAAC,CAAA,KACC,CAAA,KAAM,MAAA,IACN,SAAA,CAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAA,CACxB,CAAA,CAAE,WAAA,IAAe,IAAI,IAAA;AAAK,GAC/B;AACA,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM;AACvB,MAAA,IAAI,MAAM,MAAA,IAAU,CAAA,CAAE,YAAA,CAAa,SAAS,GAAG,OAAO,KAAA;AACtD,MAAA,MAAM,CAAA,GAAA,CAAK,CAAA,CAAE,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACrC,MAAA,MAAM,EAAA,GAAA,CAAM,CAAA,CAAE,YAAA,CAAa,OAAO,KAAK,EAAA,EAAI,KAAA;AAAA,QACzC;AAAA,OACF;AACA,MAAA,MAAM,OACJ,CAAA,CAAE,OAAA,KAAY,GAAA,IACd,CAAA,CAAE,YAAY,QAAA,KACb,EAAA,GAAK,EAAA,CAAG,CAAC,MAAM,MAAA,IAAU,MAAA,CAAO,GAAG,CAAC,CAAC,KAAK,GAAA,GAAM,KAAA,CAAA;AACnD,MAAA,OAAO,IAAA,IAAQ,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,EAAE,MAAA,GAAS,EAAA;AAAA,IAC5C,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,YAAA,CAAa,SAAS,CAAA,EAAG;AAC7C,IAAA,QAAA,CAAS,MAAA,EAAQ,UAAU,YAAY,CAAA;AACvC,IAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,EACxB;AAGA,EAAA,MAAM,IAAA,GACJ,IAAI,aAAA,CAAc,MAAM,KACxB,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,CAAC,EAAE,YAAA,CAAa,SAAS,KAAK,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAC,CAAA,IACtE,GAAA,CAAI,IAAA;AAAA,IACF,CAAC,CAAA,KACC,CAAC,CAAA,CAAE,YAAA,CAAa,SAAS,CAAA,IACzB,CAAA,CAAE,QAAA,CAAS,MAAA,KAAW,KACtB,YAAA,CAAa,IAAA,CAAA,CAAM,EAAE,WAAA,IAAe,EAAA,EAAI,MAAM;AAAA,GAClD;AACF,EAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG;AACzC,IAAA,QAAA,CAAS,IAAA,EAAM,QAAQ,UAAU,CAAA;AACjC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAIA,EAAA,MAAM,QAAQ,GAAA,CAAI,IAAA;AAAA,IAChB,CAAC,CAAA,KACC,CAAC,EAAE,YAAA,CAAa,SAAS,KACzB,CAAC,CAAA,CAAE,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAG,CAAA,IACjC,QAAQ,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC;AAAA,GAC3B;AACA,EAAA,IAAI,OAAO,KAAA,IAAS,IAAA;AACpB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,IAAI,OAAA,GAAU,EAAA;AACd,IAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,MAAA,IAAI,CAAA,CAAE,YAAA,CAAa,SAAS,CAAA,EAAG;AAC/B,MAAA,IAAI,CAAA,CAAE,aAAA,CAAc,CAAA,CAAA,EAAI,SAAS,GAAG,CAAA,EAAG;AACvC,MAAA,MAAM,CAAA,GAAA,CAAK,CAAA,CAAE,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACrC,MAAA,IAAI,CAAA,CAAE,SAAS,OAAA,EAAS;AACtB,QAAA,OAAA,GAAU,CAAA,CAAE,MAAA;AACZ,QAAA,IAAA,GAAO,CAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG;AACzC,IAAA,QAAA,CAAS,IAAA,EAAM,QAAQ,UAAU,CAAA;AACjC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB,CAAA,MAAA,IAAW,CAAC,IAAA,EAAM;AAEhB,IAAA,QAAA,CAAS,GAAA,EAAK,QAAQ,UAAU,CAAA;AAChC,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,GAAA,CAAI,SAAA,EAAW,QAAA,EAAS;AACzC;AAEA,IAAM,WAAA,GACJ,4FAAA;AAEF,SAAS,YAAA,CAAa,MAAe,OAAA,EAAkC;AACrE,EAAA,MAAM,aAAa,CAAC,GAAG,KAAK,gBAAA,CAAiB,GAAG,CAAC,CAAA,CAAE,MAAA;AAAA,IACjD,CAAC,CAAA,KAAM,CAAC,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,OAAO;AAAA,GACpD;AACA,EAAA,OACE,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,CAAa,MAAM,CAAA,KAAM,SAAS,CAAA,IAC3D,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,CAAa,iBAAiB,CAAC,CAAA,IACxD,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,WAAA,CAAY,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,IACnD,IAAA;AAEJ;AAEA,SAAS,WAAA,GAA0B;AACjC,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,UAAU,EAAC,EAAG,YAAY,CAAA,EAAE;AACrD;AAEO,SAAS,OAAA,CAAQ,IAAA,EAAe,IAAA,GAAuB,EAAC,EAAc;AAC3E,EAAA,MAAM,GAAA,GAAMA,UAAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AACjC,EAAA,MAAM,MAAM,GAAA,CAAI,QAAA;AAChB,EAAA,MAAM,WAAqB,EAAC;AAG5B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACjC,EAAA,MAAM,OAAA,GAAU,EAAE,KAAA,EAAO,CAAA,EAAE;AAC3B,EAAA,cAAA,CAAe,MAAM,KAAA,EAAO,GAAA,EAAK,IAAA,CAAK,oBAAA,IAAwB,OAAO,OAAO,CAAA;AAC5E,EAAA,IAAI,QAAQ,KAAA,GAAQ,CAAA;AAClB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,CAAA,QAAA,EAAW,QAAQ,KAAK,CAAA,oCAAA;AAAA,KAC1B;AAGF,EAAA,MAAM,OAAO,YAAA,CAAa,KAAA,CAAM,WAAW,EAAE,MAAA,EAAQ,KAAK,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,aAAA,CAAc,KAAK,CAAA;AACpC,EAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,EAAA,MAAM,SAAA,GAAa,KAAK,iBAAA,IAAwC,IAAA;AAGhE,EAAA,MAAM,IAAA,GAAO,kBAAkB,SAAS,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,OAAO,WAAA,EAAY;AAAA,IACnB,SAAS,WAAA,EAAY;AAAA,IACrB,UAAU,WAAA,EAAY;AAAA,IACtB,QAAQ,WAAA;AAAY,GACtB;AAEA,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,YAAA;AAEJ,EAAA,IAAI,IAAA,EAAM;AAER,IAAA,MAAM,SAAU,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CAAc,UAAU,IAAI,CAAA;AACvD,IAAA,MAAM,OAAA,GAAU,WAAW,MAAM,CAAA;AACjC,IAAA,WAAA,GAAc,OAAA,CAAQ,IAAA;AACtB,IAAA,SAAA,CAAU,OAAA,GAAU;AAAA,MAClB,KAAA,EAAO,IAAA;AAAA,MACP,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAC;AAAA,KACrD;AAGA,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,aAAA,CAAc,KAAK,CAAA;AACpC,IAAA,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AACvC,IAAA,IAAA,CAAK,WAAA,GAAc,cAAA;AACnB,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA;AACtC,IAAA,IAAI,SAAS,IAAA,CAAK,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG,OAAO,CAAA,YAAA,CAAc,CAAA;AAChE,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,KAAK,CAAA;AAErD,IAAA,IAAI,cAAA,CAAe,aAAa,OAAO,CAAA;AACrC,MAAA,IAAA,CAAK,YAAA;AAAA,QACH,OAAA;AAAA,QACA,cAAA,CAAe,aAAa,OAAO;AAAA,OACrC;AAEF,IAAA,MAAM,UAAA,GAAa,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AAC3C,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AAC7C,IAAA,MAAM,aAAA,GAAgB,IAAA,GAAO,UAAA,CAAW,UAAA,EAAY,IAAI,CAAA,GAAI,IAAA;AAC5D,IAAA,IAAI,aAAA,IAAiB,cAAc,aAAA,EAAe;AAChD,MAAA,aAAA,CAAc,YAAY,IAAI,CAAA;AAC9B,MAAA,SAAA,GAAY,UAAA,CAAW,SAAA;AACvB,MAAA,SAAA,CAAU,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAA,EAAM,UAAU,CAAC,UAAU,CAAA,EAAG,UAAA,EAAY,CAAA,EAAE;AAAA,IACzE,CAAA,MAAO;AAEL,MAAA,SAAA,GAAY,IAAA,CAAK,SAAA;AACjB,MAAA,SAAA,CAAU,KAAA,GAAQ;AAAA,QAChB,KAAA,EAAO,IAAA;AAAA,QACP,QAAA,EAAU,CAAC,UAAU,CAAA;AAAA,QACrB,UAAA,EAAY;AAAA,OACd;AACA,MAAA,QAAA,CAAS,IAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AACvD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,CAAA,GAAI,QAAA,CAAS,SAAA,CAAU,IAAI,CAAA;AACjC,MAAA,CAAA,CAAE,YAAA,CAAa,WAAW,UAAU,CAAA;AACpC,MAAA,CAAA,CAAE,gBAAgB,iBAAiB,CAAA;AACnC,MAAA,CAAA,CAAE,WAAA,GAAc,cAAA;AAChB,MAAA,YAAA,GAAe,CAAA,CAAE,SAAA;AACjB,MAAA,SAAA,CAAU,QAAA,GAAW;AAAA,QACnB,KAAA,EAAO,IAAA;AAAA,QACP,QAAA,EAAU,CAAC,UAAU,CAAA;AAAA,QACrB,UAAA,EAAY;AAAA,OACd;AAAA,IACF,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,IAAA;AAAA,QACP;AAAA,OACF;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,IAAA;AAAA,MACP;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,cAAc,SAAS,CAAA;AAGtC,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,IAAA,GACJ,KACA,qBAAA,IAAwB;AAC1B,EAAA,IAAI,QAAQ,IAAA,CAAK,KAAA,GAAQ,CAAA,IAAK,IAAA,CAAK,SAAS,CAAA,EAAG;AAC7C,IAAA,MAAA,GAAS,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,EAAG,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,EAAE;AAAA,EAC5E;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA;AAAA,IACT,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,KAAK,IAAA,IAAQ,eAAA;AAAA,MACnB,GAAI,KAAK,SAAA,GAAY,EAAE,WAAW,IAAA,CAAK,SAAA,KAAc,EAAC;AAAA,MACtD,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU,EAAC;AAAA,MAC1C,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,KAC7B;AAAA,IACA,KAAA,EAAO;AAAA,MACL,GAAI,SAAA,GAAY,EAAE,KAAA,EAAO,SAAA,KAAc,EAAC;AAAA,MACxC,GAAI,WAAA,GAAc,EAAE,OAAA,EAAS,WAAA,KAAgB,EAAC;AAAA,MAC9C,GAAI,YAAA,GAAe,EAAE,QAAA,EAAU,YAAA,KAAiB;AAAC,KACnD;AAAA,IACA,GAAA,EAAK,EAAA;AAAA,IACL,MAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAGA,SAAS,MAAA,CAAO,MAAe,MAAA,EAAkC;AAC/D,EAAA,IAAI,IAAA,KAAS,MAAA,EAAQ,OAAO,EAAC;AAC7B,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA;AAC7B,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,EAAO,MAAM,CAAA;AAChC,IAAA,IAAI,GAAA,EAAK,OAAO,CAAC,CAAA,EAAG,GAAG,GAAG,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,UAAA,CAAW,MAAe,IAAA,EAAgC;AACjE,EAAA,IAAI,IAAA,GAAuB,IAAA;AAC3B,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,IAAK,IAAA;AAAA,EAC7B;AACA,EAAA,OAAO,IAAA;AACT;;;ACxcA,SAAS,YAAY,GAAA,EAAqB;AAExC,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,6BAA6B,CAAA;AACpD,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,GAAA;AACvB,EAAA,IAAI,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAExB,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,YAAY,CAAA;AACtC,EAAA,IAAI,UAAU,EAAA,EAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAC,CAAA;AAE7C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA;AACtC,EAAA,IAAI,aAAa,EAAA,EAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,QAAQ,CAAA;AAElD,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AACjC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA;AAAA,IAAQ,oBAAA;AAAA,IAAsB,CAAC,IAAI,GAAA,KAC7C,MAAA,CAAO,aAAa,QAAA,CAAS,GAAA,EAAK,EAAE,CAAC;AAAA,GACvC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,cAAA;AAAA,EACA,eAAA;AAAA,EACA,2BAAA;AAAA,EACA,2BAAA;AAAA,EACA,uBAAA;AAAA,EACA,qBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAA;AAEA,SAAS,YAAY,GAAA,EAAwB;AAC3C,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,aAAA,CAAc,GAAG,CAAA;AAChC,IAAA,IAAI,IAAI,OAAO,EAAA;AAAA,EACjB;AACA,EAAA,OAAO,GAAA,CAAI,IAAA;AACb;AAMO,SAAS,UAAA,CACd,OAAA,EACA,IAAA,GAA4C,EAAC,EAClC;AACX,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,WAAA,CAAY,OAAO,CAAA,GAAI,OAAA;AACjD,EAAA,MAAM,GAAA,GAAM,IAAIC,WAAA,CAAM,IAAI,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAI,MAAA,CAAO,QAAA;AACvB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,GACb,GAAA,CAAI,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA,IAAK,WAAA,CAAY,GAAG,CAAA,GACpD,WAAA,CAAY,GAAG,CAAA;AACnB,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,OAAO,MAAA,EAAQ,GAAG,MAAK,GAAI,IAAA;AAGxD,EAAA,OAAO,QAAQ,IAAA,EAAM;AAAA,IACnB,GAAG,IAAA;AAAA,IACH,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,GAAA,CAAI,KAAA,IAAS,eAAA;AAAA;AAAA,IAEhC,oBAAA,EAAsB;AAAA,GACvB,CAAA;AACH","file":"import-page.cjs","sourcesContent":["import createDOMPurify from \"dompurify\";\n\n/**\n * Allowlist sanitizer for captured / imported HTML+CSS (PLAN §10). Captured\n * markup is **untrusted** — it can carry scripts, event handlers, hostile\n * `url(javascript:)` CSS, `data:text/html` payloads, and framed content. We do\n * not roll our own: the heavy lifting is a maintained, audited sanitizer\n * (DOMPurify), wrapped here with a strict allowlist and a CSS scrubber, and the\n * `TemplateSkinAdapter` *additionally* renders in a shadow root so a sanitizer\n * miss still can't reach the host page. Defense in depth, not a single gate.\n */\n\ninterface WindowLike {\n document: Document;\n}\n\n/** Tags we keep — pure presentational/structural HTML. No scripts, forms, media. */\nconst ALLOWED_TAGS = [\n \"div\",\n \"span\",\n \"p\",\n \"a\",\n \"b\",\n \"strong\",\n \"i\",\n \"em\",\n \"u\",\n \"s\",\n \"small\",\n \"sub\",\n \"sup\",\n \"br\",\n \"hr\",\n \"ul\",\n \"ol\",\n \"li\",\n \"img\",\n \"svg\",\n \"path\",\n \"g\",\n \"circle\",\n \"rect\",\n \"line\",\n \"polyline\",\n \"polygon\",\n \"ellipse\",\n \"defs\",\n \"use\",\n \"title\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"time\",\n \"header\",\n \"footer\",\n \"section\",\n \"article\",\n \"aside\",\n \"nav\",\n \"figure\",\n \"figcaption\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"td\",\n \"th\",\n];\n\n/**\n * Attributes we keep. `data-*` is dropped via `ALLOW_DATA_ATTR: false`, with the\n * single exception of our own `data-tc-slot` marker, which is re-allowed via\n * `ADD_ATTR` below so the slot contract survives a re-sanitize.\n */\nconst ALLOWED_ATTR = [\n \"class\",\n \"style\",\n \"role\",\n \"alt\",\n \"src\",\n \"srcset\",\n \"width\",\n \"height\",\n \"dir\",\n \"title\",\n \"viewbox\",\n \"fill\",\n \"stroke\",\n \"stroke-width\",\n \"d\",\n \"points\",\n \"cx\",\n \"cy\",\n \"r\",\n \"x\",\n \"y\",\n \"x1\",\n \"x2\",\n \"y1\",\n \"y2\",\n \"rx\",\n \"ry\",\n \"transform\",\n \"xmlns\",\n \"href\",\n];\n\n/**\n * Strip CSS-level code execution and exfiltration vectors from a style string\n * (inline `style=\"\"` or a stylesheet body). Inline styles survive sanitize, so\n * this is where `expression()`, `url(javascript:)`, `@import`, `behavior:`, and\n * non-image `data:` URLs are removed.\n */\nexport function scrubCss(css: string): string {\n let out = css;\n // Hostile functions / properties.\n out = out.replace(/expression\\s*\\(/gi, \"/*blocked*/(\");\n out = out.replace(/-moz-binding\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/behavior\\s*:/gi, \"/*blocked*/:\");\n out = out.replace(/@import[^;]*;?/gi, \"/*blocked-import*/\");\n // url(...) targets: block scripting protocols and non-image data URLs.\n out = out.replace(/url\\(\\s*(['\"]?)([^)'\"]*)\\1\\s*\\)/gi, (whole, _q, uri) => {\n const u = String(uri).trim().toLowerCase();\n const blocked =\n u.startsWith(\"javascript:\") ||\n u.startsWith(\"vbscript:\") ||\n (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\"));\n return blocked ? \"none\" : whole;\n });\n // Bare scripting protocols anywhere in the declaration.\n out = out.replace(/javascript:/gi, \"blocked:\");\n out = out.replace(/vbscript:/gi, \"blocked:\");\n return out;\n}\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\n \"sanitizeHtml requires a DOM window — pass { window } in non-browser environments.\",\n );\n}\n\nlet hooked: unknown = null;\n\ntype PurifyWindow = Parameters<typeof createDOMPurify>[0];\n\nfunction purifierFor(win: WindowLike): ReturnType<typeof createDOMPurify> {\n const purify = createDOMPurify(win as unknown as PurifyWindow);\n // Install hooks once per purifier instance.\n if (hooked !== purify) {\n purify.addHook(\"afterSanitizeAttributes\", (node) => {\n const el = node as Element;\n // Scrub inline styles for CSS hazards.\n const style = el.getAttribute?.(\"style\");\n if (style) el.setAttribute(\"style\", scrubCss(style));\n // Enforce image-only data: URLs on src.\n const src = el.getAttribute?.(\"src\");\n if (src) {\n const u = src.trim().toLowerCase();\n if (u.startsWith(\"data:\") && !u.startsWith(\"data:image/\")) {\n el.removeAttribute(\"src\");\n }\n }\n // Force links inert and safe — no navigation out of a simulation.\n if (el.tagName === \"A\") {\n el.removeAttribute(\"href\");\n el.setAttribute(\"role\", \"link\");\n }\n // target=_blank/opener hygiene (belt-and-braces; href already removed).\n if (el.getAttribute?.(\"target\")) el.removeAttribute(\"target\");\n });\n hooked = purify;\n }\n return purify;\n}\n\nexport interface SanitizeOptions {\n /** DOM window to use (required in Node; defaults to global `window`). */\n window?: WindowLike;\n}\n\n/**\n * Sanitize an untrusted HTML string to the capture allowlist. Returns inert,\n * presentational HTML safe to parse and slot-ify. Always pair with shadow-DOM\n * isolation at render time (`TemplateSkinAdapter`).\n */\nexport function sanitizeHtml(html: string, opts: SanitizeOptions = {}): string {\n const win = getWindow(opts.window);\n const purify = purifierFor(win);\n return purify.sanitize(html, {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n // Keep our slot marker even though data-* is otherwise dropped.\n ADD_ATTR: [\"data-tc-slot\"],\n ALLOW_DATA_ATTR: false,\n ALLOW_ARIA_ATTR: true,\n FORBID_TAGS: [\n \"script\",\n \"style\",\n \"iframe\",\n \"object\",\n \"embed\",\n \"form\",\n \"input\",\n \"button\",\n \"textarea\",\n \"select\",\n \"link\",\n \"meta\",\n \"base\",\n \"video\",\n \"audio\",\n \"source\",\n ],\n FORBID_ATTR: [\"srcdoc\", \"formaction\", \"xlink:href\"],\n }) as string;\n}\n","/**\n * Best-effort design-token extraction from the inline styles of a distilled\n * tree (PLAN §10). This is a starting palette for the skin author to rename and\n * curate — not an authoritative theme. We pull distinct colors (most-frequent\n * first), font families, border radii, and padding scales.\n */\n\ninterface Tokens {\n colors: Record<string, string>;\n fonts?: Record<string, string>;\n space?: Record<string, string>;\n radius?: Record<string, string>;\n}\n\nfunction parseStyle(style: string): Map<string, string> {\n const m = new Map<string, string>();\n for (const decl of style.split(\";\")) {\n const idx = decl.indexOf(\":\");\n if (idx === -1) continue;\n const prop = decl.slice(0, idx).trim().toLowerCase();\n const val = decl.slice(idx + 1).trim();\n if (prop && val) m.set(prop, val);\n }\n return m;\n}\n\nconst COLOR_RE = /(#[0-9a-f]{3,8}\\b|rgba?\\([^)]*\\)|hsla?\\([^)]*\\))/gi;\n\nexport function extractTokens(root: Element): Tokens {\n const colorFreq = new Map<string, number>();\n const fonts = new Set<string>();\n const radii = new Set<string>();\n const spaces = new Set<string>();\n\n const bump = (raw: string) => {\n const v = raw.trim();\n if (!v || v === \"transparent\" || v === \"inherit\" || v === \"currentcolor\")\n return;\n colorFreq.set(v, (colorFreq.get(v) ?? 0) + 1);\n };\n\n for (const el of [root, ...root.querySelectorAll(\"*\")]) {\n const style = el.getAttribute(\"style\");\n if (!style) continue;\n const decls = parseStyle(style);\n for (const [prop, val] of decls) {\n if (prop === \"color\" || prop.startsWith(\"background\")) {\n const matches = val.match(COLOR_RE);\n if (matches) for (const c of matches) bump(c);\n }\n if (prop === \"font-family\") fonts.add(val);\n if (prop === \"border-radius\") radii.add(val);\n if (prop === \"padding\" || prop === \"gap\") spaces.add(val);\n }\n }\n\n const colors: Record<string, string> = {};\n [...colorFreq.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 12)\n .forEach(([c], i) => {\n colors[`color-${i + 1}`] = c;\n });\n\n const out: Tokens = { colors };\n if (fonts.size) {\n out.fonts = {};\n [...fonts].slice(0, 4).forEach((f, i) => {\n out.fonts![`font-${i + 1}`] = f;\n });\n }\n if (radii.size) {\n out.radius = {};\n [...radii].slice(0, 6).forEach((r, i) => {\n out.radius![`radius-${i + 1}`] = r;\n });\n }\n if (spaces.size) {\n out.space = {};\n [...spaces].slice(0, 8).forEach((s, i) => {\n out.space![`space-${i + 1}`] = s;\n });\n }\n return out;\n}\n","import { sanitizeHtml } from \"./sanitize.js\";\nimport { extractTokens } from \"./tokens.js\";\nimport type { SkinDraft, SlotReport } from \"./draft.js\";\n\n/**\n * The distiller (PLAN §10): given a chat-UI subtree, produce a sanitized,\n * slotted `SkinDraft`. The pipeline is\n *\n * clone → inline computed styles (live capture) → drop hidden/`data-*` →\n * sanitize (allowlist) → find the repeating message row → slot-ify\n * (author/avatar/body/time) → carve the frame chrome → find the composer →\n * extract tokens → report.\n *\n * Capture gets you ~80% of the way; the emitted `detection` report and\n * `warnings` tell the author exactly what to confirm by hand (the §10 quality\n * bar treats anything below the bar as \"draft only\", never a finished skin).\n * The function is DOM-agnostic — the extension passes a live element, the\n * saved-page importer passes a jsdom element.\n */\n\ninterface WindowLike {\n document: Document;\n getComputedStyle?: (el: Element) => CSSStyleDeclaration;\n}\n\nexport interface DistillOptions {\n /** DOM window (defaults to global `window`). Required in Node. */\n window?: WindowLike;\n /** Display name for the draft. */\n name?: string;\n sourceUrl?: string;\n theme?: \"light\" | \"dark\";\n /**\n * Inline computed styles from the live page so fidelity survives losing the\n * cascade. Off for saved-page import (the source CSS comes inline already).\n */\n inlineComputedStyles?: boolean;\n}\n\n/** The slot-marker attribute the `TemplateSkinAdapter` keys off. */\nexport const SLOT_ATTR = \"data-tc-slot\";\n\n/** Computed properties worth inlining — look, not frozen layout geometry. */\nconst INLINE_PROPS = [\n \"color\",\n \"background-color\",\n \"background\",\n \"font-family\",\n \"font-size\",\n \"font-weight\",\n \"font-style\",\n \"line-height\",\n \"letter-spacing\",\n \"text-align\",\n \"text-transform\",\n \"border\",\n \"border-radius\",\n \"padding\",\n \"margin\",\n \"gap\",\n \"display\",\n \"flex-direction\",\n \"align-items\",\n \"justify-content\",\n \"box-shadow\",\n \"opacity\",\n];\n\nconst HIDDEN_CLASS_RE = /\\b(sr-only|visually-hidden|hidden)\\b/;\n\nfunction getWindow(win?: WindowLike): WindowLike {\n if (win) return win;\n if (typeof window !== \"undefined\") return window as unknown as WindowLike;\n throw new Error(\"distill requires a DOM window — pass { window } in Node.\");\n}\n\nfunction isHidden(el: Element, win: WindowLike): boolean {\n if (el.getAttribute(\"aria-hidden\") === \"true\") return true;\n if (el.hasAttribute(\"hidden\")) return true;\n const cls = el.getAttribute(\"class\") ?? \"\";\n if (HIDDEN_CLASS_RE.test(cls)) return true;\n const inline = (el.getAttribute(\"style\") ?? \"\").toLowerCase();\n if (/display\\s*:\\s*none/.test(inline)) return true;\n if (/visibility\\s*:\\s*hidden/.test(inline)) return true;\n const cs = win.getComputedStyle?.(el);\n if (cs) {\n if (cs.display === \"none\") return true;\n if (cs.visibility === \"hidden\") return true;\n }\n return false;\n}\n\nfunction inlineStyles(orig: Element, clone: Element, win: WindowLike): void {\n const cs = win.getComputedStyle?.(orig);\n if (!cs) return;\n const decls: string[] = [];\n for (const prop of INLINE_PROPS) {\n const v = cs.getPropertyValue(prop);\n if (v && v !== \"none\" && v !== \"normal\" && v.trim() !== \"\")\n decls.push(`${prop}: ${v}`);\n }\n if (decls.length) clone.setAttribute(\"style\", decls.join(\"; \"));\n}\n\n/** Recursively inline styles + drop hidden nodes, walking orig/clone in step. */\nfunction pruneAndInline(\n orig: Element,\n clone: Element,\n win: WindowLike,\n inline: boolean,\n dropped: { count: number },\n): void {\n if (inline) inlineStyles(orig, clone, win);\n // Strip data-* (defense-in-depth; sanitize also does this later).\n for (const attr of [...clone.attributes]) {\n if (attr.name.startsWith(\"data-\")) clone.removeAttribute(attr.name);\n }\n const origKids = [...orig.children];\n const cloneKids = [...clone.children];\n const remove: Element[] = [];\n for (let i = 0; i < origKids.length; i++) {\n const o = origKids[i];\n const c = cloneKids[i];\n if (!o || !c) continue;\n if (isHidden(o, win)) {\n remove.push(c);\n dropped.count++;\n continue;\n }\n pruneAndInline(o, c, win, inline, dropped);\n }\n for (const c of remove) c.remove();\n}\n\n/** A structural signature for grouping repeated rows. */\nfunction signature(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = (el.getAttribute(\"class\") ?? \"\")\n .split(/\\s+/)\n .filter(Boolean)\n .sort()\n .join(\".\");\n const kidTags = [...el.children]\n .map((c) => c.tagName.toLowerCase())\n .join(\",\");\n return `${tag}|${classes}|${kidTags}`;\n}\n\ninterface RepeatPick {\n container: Element;\n rows: Element[];\n}\n\n/** Find the container whose children are the most-repeated similar rows. */\nfunction findRepeatingRows(root: Element): RepeatPick | null {\n let best: RepeatPick | null = null;\n let bestScore = 0;\n const visit = (el: Element) => {\n const groups = new Map<string, Element[]>();\n for (const child of el.children) {\n const sig = signature(child);\n const arr = groups.get(sig) ?? [];\n arr.push(child);\n groups.set(sig, arr);\n }\n for (const rows of groups.values()) {\n if (rows.length < 2) continue;\n // Score: repetition count weighted by how much text the rows carry, so\n // a list of message bubbles beats e.g. a repeated row of icon buttons.\n const textLen = rows.reduce(\n (n, r) => n + (r.textContent ?? \"\").trim().length,\n 0,\n );\n const score = rows.length * 10 + Math.min(textLen, 400);\n if (score > bestScore) {\n bestScore = score;\n best = { container: el, rows };\n }\n }\n for (const child of el.children) visit(child);\n };\n visit(root);\n return best;\n}\n\nconst AUTHOR_RE =\n /\\b(name|author|sender|user|handle|username|display-?name)\\b/i;\nconst AVATAR_RE = /\\b(avatar|photo|userpic|profile-?pic|pic|gravatar)\\b/i;\nconst TIME_RE = /\\b(time|timestamp|date|ago|sent-?at)\\b/i;\nconst BODY_RE = /\\b(body|text|content|message|bubble|markdown|prose)\\b/i;\nconst TIME_TEXT_RE =\n /^\\s*(\\d{1,2}:\\d{2}(\\s?[ap]\\.?m\\.?)?|\\d+\\s*(m|min|h|hr|d|days?|hours?|minutes?)( ago)?|yesterday|today)\\s*$/i;\n\nfunction classOf(el: Element): string {\n return el.getAttribute(\"class\") ?? \"\";\n}\n\nfunction markSlot(el: Element, slot: string, token: string): void {\n el.setAttribute(SLOT_ATTR, slot);\n el.textContent = token;\n}\n\n/** Identify and mark author/avatar/body/time inside a representative row. */\nfunction slotifyRow(row: Element): {\n html: string;\n detected: string[];\n} {\n const detected: string[] = [];\n const all = [...row.querySelectorAll(\"*\")];\n\n // Avatar: an <img> or an element whose class names it.\n let avatar =\n row.querySelector(\"img\") ??\n all.find((e) => AVATAR_RE.test(classOf(e))) ??\n null;\n if (avatar) {\n // Convert an <img> avatar into a styled container we can fill.\n if (avatar.tagName === \"IMG\") {\n const div = row.ownerDocument.createElement(\"div\");\n const cls = classOf(avatar);\n if (cls) div.setAttribute(\"class\", cls);\n const st = avatar.getAttribute(\"style\");\n if (st) div.setAttribute(\"style\", st);\n avatar.replaceWith(div);\n avatar = div;\n }\n markSlot(avatar, \"avatar\", \"{{avatar}}\");\n detected.push(\"avatar\");\n }\n\n // Author: a named element, else the first short bold-ish text run.\n let author = all.find(\n (e) =>\n e !== avatar &&\n AUTHOR_RE.test(classOf(e)) &&\n (e.textContent ?? \"\").trim(),\n );\n if (!author) {\n author = all.find((e) => {\n if (e === avatar || e.getAttribute(SLOT_ATTR)) return false;\n const t = (e.textContent ?? \"\").trim();\n const fw = (e.getAttribute(\"style\") ?? \"\").match(\n /font-weight:\\s*(\\d+|bold)/i,\n );\n const bold =\n e.tagName === \"B\" ||\n e.tagName === \"STRONG\" ||\n (fw ? fw[1] === \"bold\" || Number(fw[1]) >= 600 : false);\n return bold && t.length > 0 && t.length < 40;\n });\n }\n if (author && !author.getAttribute(SLOT_ATTR)) {\n markSlot(author, \"author\", \"{{author}}\");\n detected.push(\"author\");\n }\n\n // Time: a <time>, a named element, or an element whose text reads as a time.\n const time =\n row.querySelector(\"time\") ??\n all.find((e) => !e.getAttribute(SLOT_ATTR) && TIME_RE.test(classOf(e))) ??\n all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n e.children.length === 0 &&\n TIME_TEXT_RE.test((e.textContent ?? \"\").trim()),\n );\n if (time && !time.getAttribute(SLOT_ATTR)) {\n markSlot(time, \"time\", \"{{time}}\");\n detected.push(\"time\");\n }\n\n // Body: the remaining element with the most text (or a named one). Never an\n // ancestor of an already-marked slot, or filling it would wipe author/time.\n const named = all.find(\n (e) =>\n !e.getAttribute(SLOT_ATTR) &&\n !e.querySelector(`[${SLOT_ATTR}]`) &&\n BODY_RE.test(classOf(e)),\n );\n let body = named ?? null;\n if (!body) {\n let bestLen = -1;\n for (const e of all) {\n if (e.getAttribute(SLOT_ATTR)) continue;\n if (e.querySelector(`[${SLOT_ATTR}]`)) continue; // don't pick an ancestor of a slot\n const t = (e.textContent ?? \"\").trim();\n if (t.length > bestLen) {\n bestLen = t.length;\n body = e;\n }\n }\n }\n if (body && !body.getAttribute(SLOT_ATTR)) {\n markSlot(body, \"body\", \"{{body}}\");\n detected.push(\"body\");\n } else if (!body) {\n // Fall back: slot the row itself.\n markSlot(row, \"body\", \"{{body}}\");\n detected.push(\"body\");\n }\n\n return { html: row.outerHTML, detected };\n}\n\nconst COMPOSER_RE =\n /\\b(composer|compose|reply|message-?box|message-?input|input-?box|textbox|editor|prompt)\\b/i;\n\nfunction findComposer(root: Element, exclude: Element): Element | null {\n const candidates = [...root.querySelectorAll(\"*\")].filter(\n (e) => !exclude.contains(e) && !e.contains(exclude),\n );\n return (\n candidates.find((e) => e.getAttribute(\"role\") === \"textbox\") ??\n candidates.find((e) => e.hasAttribute(\"contenteditable\")) ??\n candidates.find((e) => COMPOSER_RE.test(classOf(e))) ??\n null\n );\n}\n\nfunction emptyReport(): SlotReport {\n return { found: false, detected: [], confidence: 0 };\n}\n\nexport function distill(root: Element, opts: DistillOptions = {}): SkinDraft {\n const win = getWindow(opts.window);\n const doc = win.document;\n const warnings: string[] = [];\n\n // 1. Clone, inline styles, drop hidden + data-*.\n const clone = root.cloneNode(true) as Element;\n const dropped = { count: 0 };\n pruneAndInline(root, clone, win, opts.inlineComputedStyles ?? false, dropped);\n if (dropped.count > 0)\n warnings.push(\n `Dropped ${dropped.count} hidden element(s) from the capture.`,\n );\n\n // 2. Sanitize (allowlist) and re-parse.\n const safe = sanitizeHtml(clone.outerHTML, { window: win });\n const host = doc.createElement(\"div\");\n host.innerHTML = safe;\n const frameRoot = (host.firstElementChild as Element | null) ?? host;\n\n // 3. Find the repeating message row.\n const pick = findRepeatingRows(frameRoot);\n const detection = {\n frame: emptyReport(),\n message: emptyReport(),\n composer: emptyReport(),\n typing: emptyReport(),\n };\n\n let messageHtml: string | undefined;\n let frameHtml: string | undefined;\n let composerHtml: string | undefined;\n\n if (pick) {\n // 4. Slot-ify a representative row.\n const sample = (pick.rows[0] as Element).cloneNode(true) as Element;\n const slotted = slotifyRow(sample);\n messageHtml = slotted.html;\n detection.message = {\n found: true,\n detected: slotted.detected,\n confidence: Math.min(1, slotted.detected.length / 4),\n };\n\n // 5. Carve the frame: replace the message list with a {{messages}} slot.\n const slot = doc.createElement(\"div\");\n slot.setAttribute(SLOT_ATTR, \"messages\");\n slot.textContent = \"{{messages}}\";\n const listCls = classOf(pick.container);\n if (listCls) slot.setAttribute(\"class\", `${listCls} tc-messages`);\n const containerClone = pick.container.cloneNode(false) as Element;\n // Preserve the list container's own styling, but it now holds only the slot.\n if (containerClone.getAttribute(\"style\"))\n slot.setAttribute(\n \"style\",\n containerClone.getAttribute(\"style\") as string,\n );\n // Build the frame by replacing the container subtree with the slot.\n const frameClone = frameRoot.cloneNode(true) as Element;\n const path = pathTo(frameRoot, pick.container);\n const targetInClone = path ? nodeAtPath(frameClone, path) : null;\n if (targetInClone && targetInClone.parentElement) {\n targetInClone.replaceWith(slot);\n frameHtml = frameClone.outerHTML;\n detection.frame = { found: true, detected: [\"messages\"], confidence: 1 };\n } else {\n // The list *is* the root; frame is just the slot.\n frameHtml = slot.outerHTML;\n detection.frame = {\n found: true,\n detected: [\"messages\"],\n confidence: 0.5,\n };\n warnings.push(\n \"Message list is the captured root; no surrounding chrome was found.\",\n );\n }\n\n // 6. Composer (outside the message list).\n const composer = findComposer(frameRoot, pick.container);\n if (composer) {\n const c = composer.cloneNode(true) as Element;\n c.setAttribute(SLOT_ATTR, \"composer\");\n c.removeAttribute(\"contenteditable\");\n c.textContent = \"{{composer}}\";\n composerHtml = c.outerHTML;\n detection.composer = {\n found: true,\n detected: [\"composer\"],\n confidence: 1,\n };\n } else {\n warnings.push(\n \"No composer detected — add one by hand if the skin needs it.\",\n );\n }\n } else {\n warnings.push(\n \"No repeating message row found — capture a tighter subtree around the thread.\",\n );\n }\n\n // 7. Tokens.\n const tokens = extractTokens(frameRoot);\n\n // 8. Canvas suggestion from the captured box (best effort).\n let canvas: { width: number; height: number } | undefined;\n const rect = (\n root as Element & { getBoundingClientRect?: () => DOMRect }\n ).getBoundingClientRect?.();\n if (rect && rect.width > 0 && rect.height > 0) {\n canvas = { width: Math.round(rect.width), height: Math.round(rect.height) };\n }\n\n return {\n version: 1,\n meta: {\n name: opts.name ?? \"Captured skin\",\n ...(opts.sourceUrl ? { sourceUrl: opts.sourceUrl } : {}),\n ...(opts.theme ? { theme: opts.theme } : {}),\n ...(canvas ? { canvas } : {}),\n },\n slots: {\n ...(frameHtml ? { frame: frameHtml } : {}),\n ...(messageHtml ? { message: messageHtml } : {}),\n ...(composerHtml ? { composer: composerHtml } : {}),\n },\n css: \"\",\n tokens,\n detection,\n warnings,\n };\n}\n\n/** Index path from `root` down to `target` (list of child indices). */\nfunction pathTo(root: Element, target: Element): number[] | null {\n if (root === target) return [];\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i];\n if (!child) continue;\n const sub = pathTo(child, target);\n if (sub) return [i, ...sub];\n }\n return null;\n}\n\nfunction nodeAtPath(root: Element, path: number[]): Element | null {\n let node: Element | null = root;\n for (const i of path) {\n if (!node) return null;\n node = node.children[i] ?? null;\n }\n return node;\n}\n","import { JSDOM } from \"jsdom\";\nimport { distill, type DistillOptions } from \"./distill.js\";\nimport type { SkinDraft } from \"./draft.js\";\n\n/**\n * Saved-page importer (PLAN §10) — the Node counterpart to the extension. It\n * ingests a saved `.html`/`.mhtml` file, parses it in a jsdom window, picks the\n * thread subtree (by selector or a best-effort guess), and runs the **same\n * distiller** the extension does, so both paths converge on one `SkinDraft`.\n *\n * Lives behind the `@typecaast/capture/import` entry so the browser bundle never\n * pulls in jsdom.\n */\n\nexport interface ImportOptions extends Omit<DistillOptions, \"window\"> {\n /** CSS selector for the thread root; otherwise a heuristic guess is used. */\n selector?: string;\n}\n\n/** Strip MHTML quoted-printable framing down to the HTML part, best effort. */\nfunction mhtmlToHtml(raw: string): string {\n // Find the first text/html part.\n const idx = raw.search(/Content-Type:\\s*text\\/html/i);\n if (idx === -1) return raw;\n let body = raw.slice(idx);\n // Skip to the blank line after the part headers.\n const start = body.search(/\\r?\\n\\r?\\n/);\n if (start !== -1) body = body.slice(start + 2);\n // Cut at the next MIME boundary.\n const boundary = body.search(/\\r?\\n--/);\n if (boundary !== -1) body = body.slice(0, boundary);\n // Decode quoted-printable soft breaks + =XX escapes.\n body = body.replace(/=\\r?\\n/g, \"\");\n body = body.replace(/=([0-9A-Fa-f]{2})/g, (_m, hex: string) =>\n String.fromCharCode(parseInt(hex, 16)),\n );\n return body;\n}\n\nconst THREAD_GUESS = [\n '[role=\"log\"]',\n '[role=\"list\"]',\n '[aria-label*=\"message\" i]',\n '[class*=\"message-list\" i]',\n '[class*=\"messages\" i]',\n '[class*=\"thread\" i]',\n '[class*=\"conversation\" i]',\n \"main\",\n];\n\nfunction guessThread(doc: Document): Element {\n for (const sel of THREAD_GUESS) {\n const el = doc.querySelector(sel);\n if (el) return el;\n }\n return doc.body;\n}\n\n/**\n * Parse saved-page markup and distill it. `content` is the file's text; set\n * `mhtml` when importing a `.mhtml` archive.\n */\nexport function importHtml(\n content: string,\n opts: ImportOptions & { mhtml?: boolean } = {},\n): SkinDraft {\n const html = opts.mhtml ? mhtmlToHtml(content) : content;\n const dom = new JSDOM(html);\n const doc = dom.window.document;\n const root = opts.selector\n ? (doc.querySelector(opts.selector) ?? guessThread(doc))\n : guessThread(doc);\n const { selector: _selector, mhtml: _mhtml, ...rest } = opts;\n void _selector;\n void _mhtml;\n return distill(root, {\n ...rest,\n window: dom.window as unknown as DistillOptions[\"window\"],\n name: rest.name ?? doc.title ?? \"Imported skin\",\n // Saved pages carry their styles inline/in <style>; don't compute.\n inlineComputedStyles: false,\n });\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { D as DistillOptions } from './distill-kGI5Nt9q.cjs';
|
|
2
|
+
import { SkinDraft } from './draft.cjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Saved-page importer (PLAN §10) — the Node counterpart to the extension. It
|
|
7
|
+
* ingests a saved `.html`/`.mhtml` file, parses it in a jsdom window, picks the
|
|
8
|
+
* thread subtree (by selector or a best-effort guess), and runs the **same
|
|
9
|
+
* distiller** the extension does, so both paths converge on one `SkinDraft`.
|
|
10
|
+
*
|
|
11
|
+
* Lives behind the `@typecaast/capture/import` entry so the browser bundle never
|
|
12
|
+
* pulls in jsdom.
|
|
13
|
+
*/
|
|
14
|
+
interface ImportOptions extends Omit<DistillOptions, "window"> {
|
|
15
|
+
/** CSS selector for the thread root; otherwise a heuristic guess is used. */
|
|
16
|
+
selector?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse saved-page markup and distill it. `content` is the file's text; set
|
|
20
|
+
* `mhtml` when importing a `.mhtml` archive.
|
|
21
|
+
*/
|
|
22
|
+
declare function importHtml(content: string, opts?: ImportOptions & {
|
|
23
|
+
mhtml?: boolean;
|
|
24
|
+
}): SkinDraft;
|
|
25
|
+
|
|
26
|
+
export { type ImportOptions, importHtml };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { D as DistillOptions } from './distill-DviDU75P.js';
|
|
2
|
+
import { SkinDraft } from './draft.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Saved-page importer (PLAN §10) — the Node counterpart to the extension. It
|
|
7
|
+
* ingests a saved `.html`/`.mhtml` file, parses it in a jsdom window, picks the
|
|
8
|
+
* thread subtree (by selector or a best-effort guess), and runs the **same
|
|
9
|
+
* distiller** the extension does, so both paths converge on one `SkinDraft`.
|
|
10
|
+
*
|
|
11
|
+
* Lives behind the `@typecaast/capture/import` entry so the browser bundle never
|
|
12
|
+
* pulls in jsdom.
|
|
13
|
+
*/
|
|
14
|
+
interface ImportOptions extends Omit<DistillOptions, "window"> {
|
|
15
|
+
/** CSS selector for the thread root; otherwise a heuristic guess is used. */
|
|
16
|
+
selector?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse saved-page markup and distill it. `content` is the file's text; set
|
|
20
|
+
* `mhtml` when importing a `.mhtml` archive.
|
|
21
|
+
*/
|
|
22
|
+
declare function importHtml(content: string, opts?: ImportOptions & {
|
|
23
|
+
mhtml?: boolean;
|
|
24
|
+
}): SkinDraft;
|
|
25
|
+
|
|
26
|
+
export { type ImportOptions, importHtml };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { distill } from './chunk-MJRHEKPU.js';
|
|
2
|
+
import { JSDOM } from 'jsdom';
|
|
3
|
+
|
|
4
|
+
function mhtmlToHtml(raw) {
|
|
5
|
+
const idx = raw.search(/Content-Type:\s*text\/html/i);
|
|
6
|
+
if (idx === -1) return raw;
|
|
7
|
+
let body = raw.slice(idx);
|
|
8
|
+
const start = body.search(/\r?\n\r?\n/);
|
|
9
|
+
if (start !== -1) body = body.slice(start + 2);
|
|
10
|
+
const boundary = body.search(/\r?\n--/);
|
|
11
|
+
if (boundary !== -1) body = body.slice(0, boundary);
|
|
12
|
+
body = body.replace(/=\r?\n/g, "");
|
|
13
|
+
body = body.replace(
|
|
14
|
+
/=([0-9A-Fa-f]{2})/g,
|
|
15
|
+
(_m, hex) => String.fromCharCode(parseInt(hex, 16))
|
|
16
|
+
);
|
|
17
|
+
return body;
|
|
18
|
+
}
|
|
19
|
+
var THREAD_GUESS = [
|
|
20
|
+
'[role="log"]',
|
|
21
|
+
'[role="list"]',
|
|
22
|
+
'[aria-label*="message" i]',
|
|
23
|
+
'[class*="message-list" i]',
|
|
24
|
+
'[class*="messages" i]',
|
|
25
|
+
'[class*="thread" i]',
|
|
26
|
+
'[class*="conversation" i]',
|
|
27
|
+
"main"
|
|
28
|
+
];
|
|
29
|
+
function guessThread(doc) {
|
|
30
|
+
for (const sel of THREAD_GUESS) {
|
|
31
|
+
const el = doc.querySelector(sel);
|
|
32
|
+
if (el) return el;
|
|
33
|
+
}
|
|
34
|
+
return doc.body;
|
|
35
|
+
}
|
|
36
|
+
function importHtml(content, opts = {}) {
|
|
37
|
+
const html = opts.mhtml ? mhtmlToHtml(content) : content;
|
|
38
|
+
const dom = new JSDOM(html);
|
|
39
|
+
const doc = dom.window.document;
|
|
40
|
+
const root = opts.selector ? doc.querySelector(opts.selector) ?? guessThread(doc) : guessThread(doc);
|
|
41
|
+
const { selector: _selector, mhtml: _mhtml, ...rest } = opts;
|
|
42
|
+
return distill(root, {
|
|
43
|
+
...rest,
|
|
44
|
+
window: dom.window,
|
|
45
|
+
name: rest.name ?? doc.title ?? "Imported skin",
|
|
46
|
+
// Saved pages carry their styles inline/in <style>; don't compute.
|
|
47
|
+
inlineComputedStyles: false
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { importHtml };
|
|
52
|
+
//# sourceMappingURL=import-page.js.map
|
|
53
|
+
//# sourceMappingURL=import-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/import-page.ts"],"names":[],"mappings":";;;AAoBA,SAAS,YAAY,GAAA,EAAqB;AAExC,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,6BAA6B,CAAA;AACpD,EAAA,IAAI,GAAA,KAAQ,IAAI,OAAO,GAAA;AACvB,EAAA,IAAI,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAExB,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,YAAY,CAAA;AACtC,EAAA,IAAI,UAAU,EAAA,EAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAC,CAAA;AAE7C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA;AACtC,EAAA,IAAI,aAAa,EAAA,EAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,QAAQ,CAAA;AAElD,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AACjC,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA;AAAA,IAAQ,oBAAA;AAAA,IAAsB,CAAC,IAAI,GAAA,KAC7C,MAAA,CAAO,aAAa,QAAA,CAAS,GAAA,EAAK,EAAE,CAAC;AAAA,GACvC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,cAAA;AAAA,EACA,eAAA;AAAA,EACA,2BAAA;AAAA,EACA,2BAAA;AAAA,EACA,uBAAA;AAAA,EACA,qBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAA;AAEA,SAAS,YAAY,GAAA,EAAwB;AAC3C,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,aAAA,CAAc,GAAG,CAAA;AAChC,IAAA,IAAI,IAAI,OAAO,EAAA;AAAA,EACjB;AACA,EAAA,OAAO,GAAA,CAAI,IAAA;AACb;AAMO,SAAS,UAAA,CACd,OAAA,EACA,IAAA,GAA4C,EAAC,EAClC;AACX,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,WAAA,CAAY,OAAO,CAAA,GAAI,OAAA;AACjD,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,IAAI,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAI,MAAA,CAAO,QAAA;AACvB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,GACb,GAAA,CAAI,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA,IAAK,WAAA,CAAY,GAAG,CAAA,GACpD,WAAA,CAAY,GAAG,CAAA;AACnB,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,OAAO,MAAA,EAAQ,GAAG,MAAK,GAAI,IAAA;AAGxD,EAAA,OAAO,QAAQ,IAAA,EAAM;AAAA,IACnB,GAAG,IAAA;AAAA,IACH,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,GAAA,CAAI,KAAA,IAAS,eAAA;AAAA;AAAA,IAEhC,oBAAA,EAAsB;AAAA,GACvB,CAAA;AACH","file":"import-page.js","sourcesContent":["import { JSDOM } from \"jsdom\";\nimport { distill, type DistillOptions } from \"./distill.js\";\nimport type { SkinDraft } from \"./draft.js\";\n\n/**\n * Saved-page importer (PLAN §10) — the Node counterpart to the extension. It\n * ingests a saved `.html`/`.mhtml` file, parses it in a jsdom window, picks the\n * thread subtree (by selector or a best-effort guess), and runs the **same\n * distiller** the extension does, so both paths converge on one `SkinDraft`.\n *\n * Lives behind the `@typecaast/capture/import` entry so the browser bundle never\n * pulls in jsdom.\n */\n\nexport interface ImportOptions extends Omit<DistillOptions, \"window\"> {\n /** CSS selector for the thread root; otherwise a heuristic guess is used. */\n selector?: string;\n}\n\n/** Strip MHTML quoted-printable framing down to the HTML part, best effort. */\nfunction mhtmlToHtml(raw: string): string {\n // Find the first text/html part.\n const idx = raw.search(/Content-Type:\\s*text\\/html/i);\n if (idx === -1) return raw;\n let body = raw.slice(idx);\n // Skip to the blank line after the part headers.\n const start = body.search(/\\r?\\n\\r?\\n/);\n if (start !== -1) body = body.slice(start + 2);\n // Cut at the next MIME boundary.\n const boundary = body.search(/\\r?\\n--/);\n if (boundary !== -1) body = body.slice(0, boundary);\n // Decode quoted-printable soft breaks + =XX escapes.\n body = body.replace(/=\\r?\\n/g, \"\");\n body = body.replace(/=([0-9A-Fa-f]{2})/g, (_m, hex: string) =>\n String.fromCharCode(parseInt(hex, 16)),\n );\n return body;\n}\n\nconst THREAD_GUESS = [\n '[role=\"log\"]',\n '[role=\"list\"]',\n '[aria-label*=\"message\" i]',\n '[class*=\"message-list\" i]',\n '[class*=\"messages\" i]',\n '[class*=\"thread\" i]',\n '[class*=\"conversation\" i]',\n \"main\",\n];\n\nfunction guessThread(doc: Document): Element {\n for (const sel of THREAD_GUESS) {\n const el = doc.querySelector(sel);\n if (el) return el;\n }\n return doc.body;\n}\n\n/**\n * Parse saved-page markup and distill it. `content` is the file's text; set\n * `mhtml` when importing a `.mhtml` archive.\n */\nexport function importHtml(\n content: string,\n opts: ImportOptions & { mhtml?: boolean } = {},\n): SkinDraft {\n const html = opts.mhtml ? mhtmlToHtml(content) : content;\n const dom = new JSDOM(html);\n const doc = dom.window.document;\n const root = opts.selector\n ? (doc.querySelector(opts.selector) ?? guessThread(doc))\n : guessThread(doc);\n const { selector: _selector, mhtml: _mhtml, ...rest } = opts;\n void _selector;\n void _mhtml;\n return distill(root, {\n ...rest,\n window: dom.window as unknown as DistillOptions[\"window\"],\n name: rest.name ?? doc.title ?? \"Imported skin\",\n // Saved pages carry their styles inline/in <style>; don't compute.\n inlineComputedStyles: false,\n });\n}\n"]}
|