@particle-academy/fancy-3d-babylon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/painters.ts","../src/primitives.ts","../src/layouts.ts","../src/index.ts"],"names":["StandardMaterial","Color3","DynamicTexture","MeshBuilder","Mesh","box","Vector4","Vector3"],"mappings":";;;;;;;AAEO,IAAM,SAAA,GAAY;AAKzB,SAAS,MAAA,CAAO,IAAY,CAAA,EAAmB;AAC7C,EAAA,OAAO,CAAA,GAAI,GAAA;AACb;AAEA,SAAS,WAAA,CAAY,GAAA,EAA+B,CAAA,EAAW,CAAA,EAAW,QAAA,EAAmB;AAC3F,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AACrB,EAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,EAAA,SAAA,CAAU,KAAK,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAK,CAAC,CAAA;AACjC,EAAA,GAAA,CAAI,IAAA,EAAK;AACT,EAAA,GAAA,CAAI,WAAA,GAAc,WAAW,SAAA,GAAY,SAAA;AACzC,EAAA,GAAA,CAAI,SAAA,GAAA,CAAa,QAAA,GAAW,CAAA,GAAI,CAAA,IAAK,CAAA;AACrC,EAAA,GAAA,CAAI,MAAA,EAAO;AACb;AAEA,SAAS,UAAU,GAAA,EAA+B,CAAA,EAAW,CAAA,EAAW,CAAA,EAAW,GAAW,CAAA,EAAW;AACvG,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA;AACnB,EAAA,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AACnC,EAAA,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG,CAAA,GAAI,GAAG,CAAA,EAAG,CAAA,GAAI,GAAG,CAAC,CAAA;AACnC,EAAA,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AAC3B,EAAA,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,GAAG,CAAC,CAAA;AAC3B,EAAA,GAAA,CAAI,SAAA,EAAU;AAChB;AAEA,SAAS,UAAA,CAAW,GAAA,EAA+B,IAAA,EAAc,CAAA,EAAW,CAAA,EAAW;AACrF,EAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,EAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,EAAA,GAAA,CAAI,YAAA,GAAe,KAAA;AACnB,EAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,WAAA,EAAY,EAAG,GAAG,CAAC,CAAA;AACvC;AAEA,SAAS,cAAA,CAAe,KAA+B,MAAA,EAAkB,CAAA,EAAW,GAAW,CAAA,EAAW,CAAA,EAAW,SAAkC,KAAA,EAAe;AACpK,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAC,CAAA;AACjC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAC,CAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,IAAO,CAAA;AAC3B,EAAA,MAAM,OAAO,CAAA,GAAI,IAAA,CAAK,IAAI,MAAA,CAAO,MAAA,GAAS,GAAG,CAAC,CAAA;AAE9C,EAAA,IAAI,YAAY,KAAA,EAAO;AACrB,IAAA,MAAM,EAAA,GAAK,CAAA,GAAI,MAAA,CAAO,MAAA,GAAS,CAAA;AAC/B,IAAA,GAAA,CAAI,SAAA,GAAY,KAAA;AAChB,IAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvB,MAAA,MAAM,EAAA,GAAA,CAAO,CAAA,GAAI,GAAA,IAAO,KAAA,GAAS,CAAA;AACjC,MAAA,GAAA,CAAI,QAAA,CAAS,CAAA,GAAI,CAAA,IAAK,EAAA,GAAK,CAAA,CAAA,EAAI,CAAA,GAAI,CAAA,GAAI,EAAA,EAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAC,CAAA;AAAA,IAChE,CAAC,CAAA;AACD,IAAA;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,SAAA,EAAU;AACd,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvB,IAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,IAAA;AACnB,IAAA,MAAM,EAAA,GAAK,CAAA,GAAI,CAAA,GAAA,CAAM,CAAA,GAAI,OAAO,KAAA,GAAS,CAAA;AACzC,IAAA,IAAI,CAAA,KAAM,CAAA,EAAG,GAAA,CAAI,MAAA,CAAO,IAAI,EAAE,CAAA;AAAA,SACzB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,EAAE,CAAA;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA;AACvB,IAAA,GAAA,CAAI,MAAA,CAAO,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA;AACnB,IAAA,GAAA,CAAI,SAAA,EAAU;AACd,IAAA,GAAA,CAAI,YAAY,KAAA,GAAQ,IAAA;AACxB,IAAA,GAAA,CAAI,IAAA,EAAK;AACT,IAAA,GAAA,CAAI,SAAA,EAAU;AACd,IAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvB,MAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,IAAA;AACnB,MAAA,MAAM,EAAA,GAAK,CAAA,GAAI,CAAA,GAAA,CAAM,CAAA,GAAI,OAAO,KAAA,GAAS,CAAA;AACzC,MAAA,IAAI,CAAA,KAAM,CAAA,EAAG,GAAA,CAAI,MAAA,CAAO,IAAI,EAAE,CAAA;AAAA,WACzB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,EAAE,CAAA;AAAA,IACxB,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,GAAA,CAAI,WAAA,GAAc,KAAA;AAClB,EAAA,GAAA,CAAI,SAAA,GAAY,CAAA;AAChB,EAAA,GAAA,CAAI,MAAA,EAAO;AACb;AACO,SAAS,WAAA,CAAY,GAAA,EAA+B,IAAA,EAAkB,CAAA,EAAW,GAAW,QAAA,EAAmB;AACpH,EAAA,WAAA,CAAY,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,QAAQ,CAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,EAAA;AAEZ,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,KAAA,EAAO;AACV,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,CAAA;AACtC,MAAA,IAAI,KAAK,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,SAAA,GAAY,KAAK,KAAA,KAAU,IAAA,GAAO,YAAY,IAAA,CAAK,KAAA,KAAU,SAAS,SAAA,GAAY,SAAA;AACtF,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,CAAA;AAAA,MACxC;AACA,MAAA;AAAA,IACF;AAAA,IACA,KAAK,OAAA,EAAS;AACZ,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,cAAA,CAAe,KAAK,IAAA,CAAK,MAAA,EAAQ,GAAA,EAAK,GAAA,GAAM,IAAI,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,CAAA,GAAI,MAAM,CAAA,GAAI,EAAA,EAAI,KAAK,OAAA,EAAS,IAAA,CAAK,SAAS,SAAS,CAAA;AACpH,MAAA;AAAA,IACF;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,GAAI,GAAA,GAAM,CAAA,GAAA,CAAK,IAAA,CAAK,QAAQ,MAAA,GAAS,CAAA,IAAK,EAAA,IAAM,IAAA,CAAK,OAAA,CAAQ,MAAA;AAC3E,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAA,EAAK,CAAA,KAAM;AAC/B,QAAA,MAAM,EAAA,GAAK,GAAA,GAAM,CAAA,IAAK,IAAA,GAAO,EAAA,CAAA;AAC7B,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,SAAA,CAAU,KAAK,EAAA,EAAI,GAAA,EAAK,MAAM,CAAA,GAAI,GAAA,GAAM,GAAG,CAAC,CAAA;AAC5C,QAAA,GAAA,CAAI,IAAA,EAAK;AACT,QAAA,UAAA,CAAW,KAAK,GAAA,CAAI,KAAA,EAAO,EAAA,GAAK,CAAA,EAAG,MAAM,EAAE,CAAA;AAC3C,QAAA,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AAC1B,UAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,UAAA,SAAA,CAAU,GAAA,EAAK,EAAA,GAAK,CAAA,EAAG,GAAA,GAAM,EAAA,GAAK,IAAI,EAAA,EAAI,IAAA,GAAO,EAAA,EAAI,EAAA,EAAI,CAAC,CAAA;AAC1D,UAAA,GAAA,CAAI,IAAA,EAAK;AACT,UAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,UAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,UAAA,GAAA,CAAI,SAAS,CAAA,EAAG,EAAA,GAAK,IAAI,GAAA,GAAM,EAAA,GAAK,IAAI,EAAE,CAAA;AAAA,QAC5C,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,OAAA,EAAS;AACZ,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,GAAI,GAAA,GAAM,CAAA,IAAK,KAAK,OAAA,CAAQ,MAAA;AAC1C,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,GAAA,GAAM,CAAA,GAAI,IAAA,EAAM,GAAA,GAAM,EAAE,CAAC,CAAA;AACxE,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,EAAK,EAAA,KAAO;AAC7B,QAAA,GAAA,CAAI,QAAQ,CAAC,IAAA,EAAM,EAAA,KAAO,GAAA,CAAI,SAAS,MAAA,CAAO,IAAI,CAAA,EAAG,GAAA,GAAM,KAAK,IAAA,EAAM,GAAA,GAAM,EAAA,GAAK,EAAA,GAAK,EAAE,CAAC,CAAA;AAAA,MAC3F,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,SAAA,EAAW;AACd,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,SAAA,EAAU;AACd,MAAA,GAAA,CAAI,GAAA,CAAI,MAAM,EAAA,EAAI,GAAA,GAAM,IAAI,EAAA,EAAI,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAC9C,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,SAAA,GAAY,QAAA;AAChB,MAAA,GAAA,CAAI,SAAS,IAAA,CAAK,QAAA,EAAU,GAAA,GAAM,EAAA,EAAI,MAAM,EAAE,CAAA;AAC9C,MAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,SAAS,IAAA,CAAK,IAAA,EAAM,GAAA,GAAM,EAAA,EAAI,MAAM,EAAE,CAAA;AAC1C,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,SAAS,IAAA,CAAK,IAAA,EAAM,GAAA,GAAM,EAAA,EAAI,MAAM,EAAE,CAAA;AAC1C,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,GAAA,CAAI,SAAA,GAAY,KAAK,MAAA,KAAW,QAAA,GAAW,YAAY,IAAA,CAAK,MAAA,KAAW,SAAS,SAAA,GAAY,SAAA;AAC5F,QAAA,GAAA,CAAI,SAAA,EAAU;AACd,QAAA,GAAA,CAAI,GAAA,CAAI,MAAM,EAAA,EAAI,GAAA,GAAM,IAAI,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAC7C,QAAA,GAAA,CAAI,IAAA,EAAK;AAAA,MACX;AACA,MAAA;AAAA,IACF;AAAA,IACA,KAAK,SAAA,EAAW;AACd,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,SAAA,GAAY,IAAA,CAAK,IAAA,KAAS,SAAA,GAAY,SAAA,GAAY,IAAA,CAAK,IAAA,KAAS,SAAA,GAAY,SAAA,GAAY,SAAA;AAC9H,MAAA,GAAA,CAAI,YAAY,IAAA,GAAO,IAAA;AACvB,MAAA,SAAA,CAAU,KAAK,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,EAAG,CAAA,GAAI,GAAG,EAAE,CAAA;AACrC,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,IAAA;AAChB,MAAA,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,IAAI,EAAE,CAAA;AAC9B,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,KAAA,EAAO,EAAA,EAAI,GAAG,CAAA;AAChC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,QAAA,CAAS,GAAA,EAAK,KAAK,IAAA,EAAM,EAAA,EAAI,MAAM,EAAA,EAAI,CAAA,GAAI,IAAI,EAAE,CAAA;AACjD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AAC5B,QAAA,MAAM,CAAA,GAAI,GAAA,GAAM,EAAA,GAAK,CAAA,GAAI,EAAA;AACzB,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,QAAA,CAAS,CAAA,CAAE,KAAA,EAAO,GAAA,EAAK,CAAC,CAAA;AAC5B,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,SAAA,CAAU,GAAA,EAAK,IAAI,GAAA,GAAM,GAAA,EAAK,IAAI,CAAA,EAAG,GAAA,EAAK,IAAI,CAAC,CAAA;AAC/C,QAAA,GAAA,CAAI,IAAA,EAAK;AACT,QAAA,IAAI,CAAA,CAAE,SAAS,QAAA,EAAU;AACvB,UAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,UAAA,SAAA,CAAU,GAAA,EAAK,IAAI,GAAA,GAAM,EAAA,EAAI,IAAI,CAAA,EAAG,EAAA,EAAI,IAAI,EAAE,CAAA;AAC9C,UAAA,GAAA,CAAI,IAAA,EAAK;AACT,UAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,UAAA,GAAA,CAAI,SAAA,EAAU;AACd,UAAA,GAAA,CAAI,GAAA,CAAI,CAAA,GAAI,GAAA,GAAM,EAAA,EAAI,CAAA,GAAI,IAAI,EAAA,EAAI,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAChD,UAAA,GAAA,CAAI,IAAA,EAAK;AAAA,QACX;AAAA,MACF,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,IAAI,EAAA,GAAK,GAAA;AACT,MAAA,MAAM,KAAK,GAAA,GAAM,EAAA;AACjB,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC1B,QAAA,MAAM,KAAK,GAAA,CAAI,WAAA,CAAY,CAAA,CAAE,KAAK,EAAE,KAAA,GAAQ,EAAA;AAC5C,QAAA,GAAA,CAAI,SAAA,GAAY,EAAE,OAAA,KAAY,SAAA,GAAY,YAAY,CAAA,CAAE,OAAA,KAAY,UAAU,aAAA,GAAgB,SAAA;AAC9F,QAAA,IAAI,CAAA,CAAE,YAAY,OAAA,EAAS;AACzB,UAAA,SAAA,CAAU,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAC,CAAA;AAChC,UAAA,GAAA,CAAI,IAAA,EAAK;AAAA,QACX;AACA,QAAA,GAAA,CAAI,SAAA,GAAY,CAAA,CAAE,OAAA,KAAY,SAAA,GAAY,MAAA,GAAS,SAAA;AACnD,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,SAAS,CAAA,CAAE,KAAA,EAAO,EAAA,GAAK,EAAA,EAAI,KAAK,CAAC,CAAA;AACrC,QAAA,EAAA,IAAM,EAAA,GAAK,CAAA;AAAA,MACb,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,UAAA,EAAY;AACf,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AAC5B,QAAA,MAAM,CAAA,GAAI,GAAA,GAAM,EAAA,GAAK,CAAA,GAAI,EAAA;AACzB,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,SAAA,EAAU;AACd,QAAA,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,GAAI,IAAI,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAC1C,QAAA,GAAA,CAAI,IAAA,EAAK;AACT,QAAA,GAAA,CAAI,WAAA,GAAc,SAAA;AAClB,QAAA,IAAI,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC9B,UAAA,GAAA,CAAI,SAAA,EAAU;AACd,UAAA,GAAA,CAAI,MAAA,CAAO,GAAA,GAAM,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA;AAC1B,UAAA,GAAA,CAAI,MAAA,CAAO,GAAA,GAAM,CAAA,EAAG,CAAA,GAAI,EAAE,CAAA;AAC1B,UAAA,GAAA,CAAI,MAAA,EAAO;AAAA,QACb;AACA,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,IAAA,GAAO,kCAAA;AACX,QAAA,GAAA,CAAI,QAAA,CAAS,CAAA,CAAE,EAAA,EAAI,GAAA,GAAM,IAAI,CAAC,CAAA;AAC9B,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,QAAA,CAAS,CAAA,CAAE,KAAA,EAAO,GAAA,GAAM,IAAI,CAAC,CAAA;AAAA,MACnC,CAAC,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,UAAA,CAAW,GAAA,EAAK,IAAA,CAAK,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA;AACpC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,SAAA,CAAU,GAAA,EAAK,GAAA,EAAK,GAAA,GAAM,EAAA,EAAI,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,CAAA,GAAI,GAAA,GAAM,CAAA,GAAI,EAAA,EAAI,CAAC,CAAA;AAC9D,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,kCAAA;AACX,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAClC,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,EAAA,EAAI,CAAA,KAAM,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,GAAA,GAAM,EAAA,EAAI,GAAA,GAAM,EAAA,GAAK,CAAA,GAAI,EAAE,CAAC,CAAA;AACtE,MAAA;AAAA,IACF;AAAA,IACA,KAAK,OAAA,EAAS;AACZ,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,SAAA,CAAU,GAAA,EAAK,KAAK,GAAA,EAAK,CAAA,GAAI,MAAM,CAAA,EAAG,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,CAAC,CAAA;AACpD,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,SAAA,GAAY,QAAA;AAChB,MAAA,GAAA,CAAI,SAAS,IAAA,CAAK,GAAA,EAAK,CAAA,GAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AACnC,MAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,MAAA;AAAA,IACF;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,OAAA,EAAS,GAAA,EAAK,GAAG,CAAA;AACnC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,MAAA,QAAA,CAAS,GAAA,EAAK,KAAK,IAAA,EAAM,GAAA,EAAK,MAAM,EAAA,EAAI,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,EAAE,CAAA;AACvD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,SAAA;AAC5B,MAAA,MAAM,CAAA,GAAI,KAAK,cAAA,IAAkB,EAAA;AACjC,MAAA,MAAM,EAAA,GAAK,KAAK,EAAA,IAAM,IAAA;AACtB,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,KAAe,EAAA,GAAK,CAAA,GAAI,IAAA,CAAA;AAChD,MAAA,MAAM,EAAA,GAAK,KAAK,UAAA,IAAc,SAAA;AAG9B,MAAA,GAAA,CAAI,SAAA,GAAY,KAAA;AAChB,MAAA,SAAA,CAAU,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,EAAE,CAAA;AAC7B,MAAA,GAAA,CAAI,IAAA,EAAK;AAET,MAAA,MAAM,EAAA,GAAK,CAAA;AACX,MAAA,MAAM,EAAA,GAAK,CAAA;AACX,MAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,CAAA;AACnB,MAAA,MAAM,EAAA,GAAK,IAAI,CAAA,GAAI,CAAA;AACnB,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,EAAA;AAChB,MAAA,SAAA,CAAU,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAC,CAAA;AAChC,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,EAAU;AACd,MAAA,SAAA,CAAU,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAC,CAAA;AAChC,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,CAAU,IAAI,EAAE,CAAA;AAEpB,MAAA,GAAA,CAAI,WAAA,GAAc,UAAA;AAClB,MAAA,MAAM,IAAI,IAAA,CAAK,OAAA;AACf,MAAA,IAAI,CAAA,CAAE,SAAS,OAAA,EAAS;AACtB,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,SAAA,GAAY,QAAA;AAChB,QAAA,GAAA,CAAI,YAAA,GAAe,QAAA;AACnB,QAAA,GAAA,CAAI,QAAA,CAAS,CAAA,CAAE,KAAA,EAAO,EAAA,GAAK,CAAA,EAAG,KAAK,CAAA,IAAK,CAAA,CAAE,QAAA,GAAW,EAAA,GAAK,CAAA,CAAE,CAAA;AAC5D,QAAA,IAAI,EAAE,QAAA,EAAU;AACd,UAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,UAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,UAAA,GAAA,CAAI,SAAS,CAAA,CAAE,QAAA,EAAU,KAAK,CAAA,EAAG,EAAA,GAAK,IAAI,EAAE,CAAA;AAAA,QAC9C;AACA,QAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,QAAA,GAAA,CAAI,YAAA,GAAe,YAAA;AAAA,MACrB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,OAAA,EAAS;AAC7B,QAAA,CAAA,CAAE,KAAA,CAAM,GAAA,EAAK,EAAA,EAAI,EAAE,CAAA;AAAA,MACrB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,OAAA,EAAS;AAG7B,QAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,QAAA,GAAA,CAAI,IAAA,GAAO,+CAAA;AACX,QAAA,GAAA,CAAI,SAAA,GAAY,QAAA;AAChB,QAAA,GAAA,CAAI,SAAS,CAAA,CAAE,GAAA,IAAO,SAAS,EAAA,GAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AAC7C,QAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAAA,MAClB;AACA,MAAA,GAAA,CAAI,WAAA,GAAc,CAAA;AAClB,MAAA,GAAA,CAAI,OAAA,EAAQ;AAEZ,MAAA,GAAA,CAAI,SAAA,GAAY,KAAK,SAAA,GAAY,SAAA;AACjC,MAAA,GAAA,CAAI,SAAA,EAAU;AACd,MAAA,GAAA,CAAI,GAAA,CAAI,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAC/C,MAAA,GAAA,CAAI,IAAA,EAAK;AAET,MAAA,MAAM,OAAO,GAAA,CAAI,oBAAA,CAAqB,IAAI,EAAA,EAAI,EAAA,EAAI,KAAK,EAAE,CAAA;AACzD,MAAA,IAAA,CAAK,YAAA,CAAa,GAAG,wBAAwB,CAAA;AAC7C,MAAA,IAAA,CAAK,YAAA,CAAa,KAAK,qBAAqB,CAAA;AAC5C,MAAA,GAAA,CAAI,SAAA,GAAY,IAAA;AAChB,MAAA,GAAA,CAAI,SAAA,EAAU;AACd,MAAA,SAAA,CAAU,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAI,CAAC,CAAA;AAChC,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA;AAAA,IACF;AAAA,IACA,KAAK,UAAA,EAAY;AACf,MAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AACrB,MAAA,MAAM,OAAO,CAAA,GAAI,IAAA;AACjB,MAAA,MAAM,UAAU,CAAA,GAAI,IAAA;AACpB,MAAA,MAAM,MAAA,GAAS,UAAU,CAAA,GAAI,IAAA;AAC7B,MAAA,MAAM,YAAY,CAAA,GAAI,IAAA;AACtB,MAAA,MAAM,KAAA,GAAQ,SAAS,SAAA,GAAY,GAAA;AACnC,MAAA,MAAM,WAAW,CAAA,GAAI,KAAA;AACrB,MAAA,MAAM,WAAW,QAAA,GAAW,GAAA;AAC5B,MAAA,MAAM,WAAW,CAAA,GAAI,KAAA;AACrB,MAAA,MAAM,WAAW,CAAA,GAAI,KAAA;AACrB,MAAA,MAAM,UAAU,CAAA,GAAI,KAAA;AACpB,MAAA,MAAM,OAAO,OAAA,GAAU,CAAA;AAGvB,MAAA,GAAA,CAAI,YAAY,IAAA,CAAK,MAAA;AACrB,MAAA,SAAA,CAAU,KAAK,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,KAAK,CAAC,CAAA;AACvC,MAAA,GAAA,CAAI,IAAA,EAAK;AAET,MAAA,GAAA,CAAI,SAAS,CAAA,EAAG,OAAA,GAAU,KAAK,CAAA,EAAG,CAAA,EAAG,KAAK,CAAC,CAAA;AAG3C,MAAA,GAAA,CAAI,SAAA,GAAY,wBAAA;AAChB,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,WAAA,EAAY;AAC3C,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,QAAQ,CAAA,uCAAA,CAAA;AAC1B,MAAA,GAAA,CAAI,YAAA,GAAe,KAAA;AACnB,MAAA,MAAM,UAAU,QAAA,GAAW,GAAA;AAC3B,MAAA,MAAM,QAAQ,GAAA,CAAI,WAAA,CAAY,QAAQ,CAAA,CAAE,QAAQ,OAAA,GAAU,CAAA;AAC1D,MAAA,MAAM,QAAQ,QAAA,GAAW,IAAA;AACzB,MAAA,MAAM,KAAA,GAAA,CAAS,UAAU,KAAA,IAAS,CAAA;AAClC,MAAA,SAAA,CAAU,KAAK,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,QAAQ,CAAC,CAAA;AACnD,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,MAAA;AAChB,MAAA,GAAA,CAAI,SAAS,QAAA,EAAU,IAAA,GAAO,SAAS,KAAA,GAAA,CAAS,KAAA,GAAQ,YAAY,CAAC,CAAA;AAGrE,MAAA,GAAA,CAAI,SAAA,GAAY,uBAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,QAAQ,CAAA,0BAAA,CAAA;AAC1B,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,CAAE,KAAA;AACzC,MAAA,GAAA,CAAI,QAAA,CAAS,KAAK,IAAA,EAAM,CAAA,GAAI,OAAO,KAAA,EAAO,KAAA,GAAA,CAAS,KAAA,GAAQ,QAAA,IAAY,CAAC,CAAA;AAGxE,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,SAAS,CAAA,uCAAA,CAAA;AAC3B,MAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,MAAM,CAAA;AAGpC,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,QAAQ,CAAA,uCAAA,CAAA;AAC1B,MAAA,MAAM,IAAA,GAAO,IAAI,IAAA,GAAO,IAAA;AACxB,MAAA,QAAA,CAAS,GAAA,EAAK,IAAA,CAAK,WAAA,EAAa,IAAA,EAAM,KAAA,EAAO,IAAI,IAAA,GAAO,CAAA,EAAG,QAAA,EAAU,IAAA,GAAO,QAAQ,CAAA;AAGpF,MAAA,GAAA,CAAI,YAAY,IAAA,CAAK,MAAA;AACrB,MAAA,MAAM,OAAA,GAAU,kBAAA;AAChB,MAAA,GAAA,CAAI,IAAA,GAAO,OAAO,OAAO,CAAA,uCAAA,CAAA;AACzB,MAAA,MAAM,aAAa,OAAA,GAAU,GAAA;AAC7B,MAAA,MAAM,OAAO,GAAA,CAAI,WAAA,CAAY,OAAO,CAAA,CAAE,QAAQ,UAAA,GAAa,CAAA;AAC3D,MAAA,SAAA,CAAU,KAAK,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,OAAO,IAAI,CAAA;AAClD,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,GAAA,CAAI,SAAA,GAAY,SAAA;AAChB,MAAA,GAAA,CAAI,SAAS,OAAA,EAAS,IAAA,GAAO,YAAY,IAAA,GAAA,CAAQ,IAAA,GAAO,WAAW,CAAC,CAAA;AACpE,MAAA,GAAA,CAAI,YAAA,GAAe,YAAA;AACnB,MAAA;AAAA,IACF;AAAA;AAEJ;AAEA,SAAS,SACP,GAAA,EACA,IAAA,EACA,GACA,CAAA,EACA,IAAA,EACA,OACA,IAAA,EACA;AACA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,OAAO,IAAA,GAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,IAAA;AACxC,IAAA,IAAI,IAAI,WAAA,CAAY,IAAI,CAAA,CAAE,KAAA,GAAQ,QAAQ,IAAA,EAAM;AAC9C,MAAA,IAAI,IAAA,KAAS,MAAA,IAAa,EAAA,GAAK,IAAA,EAAM;AACrC,MAAA,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,EAAE,CAAA;AACxB,MAAA,IAAA,GAAO,IAAA;AACP,MAAA,EAAA,IAAM,KAAA;AAAA,IACR,CAAA,MAAO;AACL,MAAA,IAAA,GAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,IAAI,IAAA,KAAS,SAAS,MAAA,IAAa,EAAA,IAAM,OAAO,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,EAAE,CAAA;AAC1E;AC7YA,IAAM,eAAA,GAAkB,GAAA;AACxB,IAAM,gBAAA,GAAmB,IAAA;AAEzB,SAAS,aAAA,CAAc,UAAA,EAAoB,WAAA,EAAqB,OAAA,GAAU,eAAA,EAAiB;AACzF,EAAA,IAAI,CAAA,GAAI,KAAK,GAAA,CAAI,EAAA,EAAI,KAAK,KAAA,CAAM,UAAA,GAAa,OAAO,CAAC,CAAA;AACrD,EAAA,IAAI,CAAA,GAAI,KAAK,GAAA,CAAI,EAAA,EAAI,KAAK,KAAA,CAAM,WAAA,GAAc,OAAO,CAAC,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,mBAAmB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA;AAC3D,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,KAAK,CAAA;AACxB,IAAA,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,KAAK,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAChB;AAOA,SAAS,YAAA,CACP,KAAA,EACA,IAAA,EACA,OAAA,EACA,QAAA,EACgB;AAChB,EAAA,MAAM,MAAM,IAAIA,qBAAA,CAAiB,CAAA,EAAG,IAAI,QAAQ,KAAK,CAAA;AACrD,EAAA,GAAA,CAAI,aAAA,GAAgB,IAAIC,WAAA,CAAO,IAAA,EAAM,MAAM,IAAI,CAAA;AAE/C,EAAA,IAAI,OAAA,CAAQ,SAAS,OAAA,EAAS;AAC5B,IAAA,GAAA,CAAI,YAAA,GAAeA,WAAA,CAAO,aAAA,CAAc,OAAA,CAAQ,KAAK,CAAA;AACrD,IAAA,GAAA,CAAI,gBAAgBA,WAAA,CAAO,aAAA,CAAc,QAAQ,KAAK,CAAA,CAAE,MAAM,IAAI,CAAA;AAClE,IAAA,OAAO,EAAE,QAAA,EAAU,GAAA,EAAK,OAAA,EAAS,IAAA,EAAK;AAAA,EACxC;AAEA,EAAA,IAAI,IAAI,OAAA,CAAQ,UAAA;AAChB,EAAA,IAAI,IAAI,OAAA,CAAQ,WAAA;AAChB,EAAA,IAAA,CAAK,CAAA,IAAK,IAAA,IAAQ,CAAA,IAAK,IAAA,KAAS,QAAA,EAAU;AACxC,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,QAAA,CAAS,UAAA,EAAY,SAAS,WAAW,CAAA;AACpE,IAAA,CAAA,GAAI,KAAK,IAAA,CAAK,CAAA;AACd,IAAA,CAAA,GAAI,KAAK,IAAA,CAAK,CAAA;AAAA,EAChB;AACA,EAAA,CAAA,GAAI,CAAA,IAAK,GAAA;AACT,EAAA,CAAA,GAAI,CAAA,IAAK,GAAA;AACT,EAAA,MAAM,GAAA,GAAM,IAAIC,mBAAA,CAAe,CAAA,EAAG,IAAI,CAAA,IAAA,CAAA,EAAQ,EAAE,KAAA,EAAO,CAAA,GAAI,WAAW,MAAA,EAAQ,CAAA,GAAI,SAAA,EAAU,EAAG,OAAO,IAAI,CAAA;AAE1G,EAAA,GAAA,CAAI,MAAA,GAAS,EAAA;AACb,EAAA,GAAA,CAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,OAAA,IAAW,OAAA,CAAQ,WAAA,EAAa;AACnD,IAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AAAA,EACjB;AACA,EAAA,IAAI,OAAA,CAAQ,SAAS,QAAA,EAAU;AAC7B,IAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AAAA,EACjB;AACA,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,EAAW;AAC3B,EAAA,GAAA,CAAI,KAAA,CAAM,WAAW,SAAS,CAAA;AAC9B,EAAA,IAAI,OAAA,CAAQ,SAAS,OAAA,EAAS;AAC5B,IAAA,OAAA,CAAQ,KAAA,CAAM,GAAA,EAAK,CAAA,EAAG,CAAC,CAAA;AAAA,EACzB,CAAA,MAAO;AACL,IAAA,WAAA,CAAY,KAAK,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,EAAG,OAAA,CAAQ,YAAY,KAAK,CAAA;AAAA,EAClE;AACA,EAAA,GAAA,CAAI,OAAO,KAAK,CAAA;AAEhB,EAAA,GAAA,CAAI,cAAA,GAAiB,GAAA;AACrB,EAAA,GAAA,CAAI,eAAA,GAAkB,GAAA;AACtB,EAAA,GAAA,CAAI,aAAA,GAAgB,IAAID,WAAA,CAAO,GAAA,EAAK,KAAK,GAAG,CAAA;AAC5C,EAAA,IAAI,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,0BAAA,GAA6B,IAAA;AAEnD,EAAA,OAAO,EAAE,QAAA,EAAU,GAAA,EAAK,OAAA,EAAS,GAAA,EAAI;AACvC;AAiBO,SAAS,YAAY,IAAA,EAAuB;AACjD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,OAAA;AAC1B,EAAA,MAAM,IAAIE,gBAAA,CAAY,WAAA,CAAY,IAAA,EAAM,EAAE,OAAO,IAAA,CAAK,KAAA,EAAO,MAAA,EAAQ,IAAA,CAAK,QAAQ,eAAA,EAAiB,IAAA,CAAK,eAAA,EAAgB,EAAG,KAAK,KAAK,CAAA;AACrI,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,YAAY,IAAA,CAAK,KAAA;AAAA,IACjB,aAAa,IAAA,CAAK;AAAA,GACnB,CAAA;AACD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,OAAO,CAAA;AACT;AAWO,SAAS,gBAAgB,IAAA,EAA2B;AACzD,EAAA,MAAM,CAAA,GAAI,YAAY,EAAE,GAAG,MAAM,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,WAAA,EAAa,CAAA;AACjE,EAAA,IAAI,KAAK,UAAA,EAAY;AACnB,IAAA,CAAA,CAAE,gBAAgBC,SAAA,CAAK,iBAAA;AAAA,EACzB;AACA,EAAA,OAAO,CAAA;AACT;AAqBA,IAAM,iBAA4B,CAAC,OAAA,EAAS,QAAQ,OAAA,EAAS,MAAA,EAAQ,OAAO,QAAQ,CAAA;AAE7E,SAAS,eAAe,IAAA,EAA0B;AACvD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,UAAA;AAE1B,EAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,KAAA,EAAO;AAC/B,IAAA,MAAMC,OAAMF,gBAAA,CAAY,SAAA,CAAU,IAAA,EAAM,EAAE,OAAO,IAAA,CAAK,KAAA,EAAO,MAAA,EAAQ,IAAA,CAAK,QAAQ,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,EAAG,KAAK,KAAK,CAAA;AACjH,IAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,MAChE,YAAY,IAAA,CAAK,KAAA;AAAA,MACjB,aAAa,IAAA,CAAK;AAAA,KACnB,CAAA;AACD,IAAAE,KAAI,QAAA,GAAW,QAAA;AACf,IAAA,OAAOA,IAAAA;AAAA,EACT;AAIA,EAAA,MAAM,KAAA,GAAQ,GAAA;AACd,EAAA,MAAM,KAAA,GAAQ,GAAA;AACd,EAAA,MAAM,SAAS,KAAA,GAAQ,CAAA;AACvB,EAAA,MAAM,SAAS,KAAA,GAAQ,CAAA;AACvB,EAAA,MAAM,MAAM,IAAIH,mBAAA,CAAe,CAAA,EAAG,IAAI,UAAU,EAAE,KAAA,EAAO,MAAA,GAAS,SAAA,EAAW,QAAQ,MAAA,GAAS,SAAA,EAAU,EAAG,IAAA,CAAK,OAAO,IAAI,CAAA;AAC3H,EAAA,GAAA,CAAI,MAAA,GAAS,EAAA;AACb,EAAA,GAAA,CAAI,OAAA,GAAU,CAAA;AACd,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,EAAW;AAC3B,EAAA,GAAA,CAAI,KAAA,CAAM,WAAW,SAAS,CAAA;AAE9B,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,cAAA,CAAe,OAAA,CAAQ,CAAC,IAAA,EAAM,CAAA,KAAM;AAClC,IAAA,MAAM,MAAM,CAAA,GAAI,CAAA;AAChB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC5B,IAAA,MAAM,KAAK,GAAA,GAAM,KAAA;AACjB,IAAA,MAAM,KAAK,GAAA,GAAM,KAAA;AACjB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,GAAQ,IAAI,CAAA,IAAK,IAAA,CAAK,OAAA,IAAW,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,SAAA,EAAU;AACxF,IAAA,GAAA,CAAI,IAAA,EAAK;AACT,IAAA,GAAA,CAAI,SAAA,CAAU,IAAI,EAAE,CAAA;AACpB,IAAA,IAAI,OAAA,CAAQ,SAAS,OAAA,EAAS;AAC5B,MAAA,GAAA,CAAI,YAAY,OAAA,CAAQ,KAAA;AACxB,MAAA,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,KAAK,CAAA;AAAA,IACjC,CAAA,MAAA,IAAW,OAAA,CAAQ,IAAA,KAAS,OAAA,EAAS;AACnC,MAAA,OAAA,CAAQ,KAAA,CAAM,GAAA,EAAK,KAAA,EAAO,KAAK,CAAA;AAAA,IACjC,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,KAAK,OAAA,CAAQ,MAAA,EAAQ,OAAO,KAAA,EAAO,OAAA,CAAQ,YAAY,KAAK,CAAA;AAAA,IAC1E;AACA,IAAA,GAAA,CAAI,OAAA,EAAQ;AAGZ,IAAA,MAAA,CAAO,IAAA,CAAK,IAAII,YAAA,CAAQ,EAAA,GAAK,QAAQ,CAAA,GAAA,CAAK,EAAA,GAAK,KAAA,IAAS,MAAA,EAAA,CAAS,KAAK,KAAA,IAAS,MAAA,EAAQ,CAAA,GAAI,EAAA,GAAK,MAAM,CAAC,CAAA;AAAA,EACzG,CAAC,CAAA;AACD,EAAA,GAAA,CAAI,OAAO,KAAK,CAAA;AAEhB,EAAA,MAAM,MAAM,IAAIN,qBAAA,CAAiB,GAAG,IAAI,CAAA,IAAA,CAAA,EAAQ,KAAK,KAAK,CAAA;AAC1D,EAAA,GAAA,CAAI,cAAA,GAAiB,GAAA;AACrB,EAAA,GAAA,CAAI,eAAA,GAAkB,GAAA;AACtB,EAAA,GAAA,CAAI,aAAA,GAAgB,IAAIC,WAAA,CAAO,GAAA,EAAK,KAAK,GAAG,CAAA;AAC5C,EAAA,GAAA,CAAI,aAAA,GAAgB,IAAIA,WAAA,CAAO,IAAA,EAAM,MAAM,IAAI,CAAA;AAE/C,EAAA,MAAM,GAAA,GAAME,gBAAA,CAAY,SAAA,CAAU,IAAA,EAAM;AAAA,IACtC,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,MAAA;AAAA,IACA,IAAA,EAAM;AAAA,GACR,EAAG,KAAK,KAAK,CAAA;AACb,EAAA,GAAA,CAAI,QAAA,GAAW,GAAA;AACf,EAAA,OAAO,GAAA;AACT;AAcO,SAAS,aAAa,IAAA,EAAwB;AACnD,EAAA,OAAO,cAAA,CAAe;AAAA,IACpB,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,IAAA,EAAM,KAAK,IAAA,IAAQ,QAAA;AAAA,IACnB,OAAO,IAAA,CAAK,SAAA;AAAA,IACZ,OAAO,IAAA,CAAK,SAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,SAAS,IAAA,CAAK;AAAA,GACf,CAAA;AACH;AAeO,SAAS,eAAe,IAAA,EAA0B;AACvD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,UAAA;AAC1B,EAAA,MAAM,CAAA,GAAIA,gBAAA,CAAY,cAAA,CAAe,IAAA,EAAM;AAAA,IACzC,QAAA,EAAU,KAAK,MAAA,GAAS,CAAA;AAAA,IACxB,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,YAAA,EAAc,KAAK,YAAA,IAAgB;AAAA,GACrC,EAAG,KAAK,KAAK,CAAA;AACb,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,UAAA,EAAY,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,IAAA,CAAK,EAAA;AAAA,IACnC,aAAa,IAAA,CAAK;AAAA,GACnB,CAAA;AACD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,OAAO,CAAA;AACT;AAgBO,SAAS,kBAAkB,IAAA,EAA6B;AAC7D,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,cAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,GAAA;AAEjC,EAAA,MAAM,IAAA,GAAO,KAAK,YAAA,IAAgB,EAAA;AAClC,EAAA,MAAM,kBAAA,GAAqB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAM,IAAA,IAAQ,IAAA,CAAK,EAAA,GAAK,CAAA,CAAA,GAAM,IAAA,CAAK,GAAG,CAAC,CAAA;AACnF,EAAA,MAAM,CAAA,GAAIA,gBAAA,CAAY,cAAA,CAAe,IAAA,EAAM;AAAA,IACzC,UAAU,MAAA,GAAS,CAAA;AAAA,IACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,YAAA,EAAc,kBAAA;AAAA,IACd,GAAA,EAAK,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,EAAA,GAAK,CAAA,CAAA;AAAA,IAC3B,KAAKC,SAAA,CAAK,MAAA;AAAA,IACV,iBAAiBA,SAAA,CAAK;AAAA,GACxB,EAAG,KAAK,KAAK,CAAA;AACb,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,YAAY,IAAA,CAAK,KAAA;AAAA,IACjB,aAAa,IAAA,CAAK;AAAA,GACnB,CAAA;AACD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,OAAO,CAAA;AACT;AAcO,SAAS,aAAa,IAAA,EAAwB;AACnD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,QAAA;AAC1B,EAAA,MAAM,CAAA,GAAID,gBAAA,CAAY,YAAA,CAAa,IAAA,EAAM,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,QAAA,EAAU,IAAA,CAAK,QAAA,IAAY,EAAA,EAAG,EAAG,KAAK,KAAK,CAAA;AAC/G,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,UAAA,EAAY,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,EAAA;AAAA,IACjC,WAAA,EAAa,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,EAAA,GAAK;AAAA,GACxC,CAAA;AACD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,OAAO,CAAA;AACT;AAcO,SAAS,WAAW,IAAA,EAAsB;AAC/C,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,MAAA;AAC1B,EAAA,MAAM,CAAA,GAAIA,gBAAA,CAAY,UAAA,CAAW,IAAA,EAAM,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,YAAA,EAAc,IAAA,CAAK,YAAA,IAAgB,EAAA,EAAG,EAAG,KAAK,KAAK,CAAA;AACjH,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,UAAA,EAAY,KAAK,MAAA,GAAS,CAAA;AAAA,IAC1B,WAAA,EAAa,KAAK,MAAA,GAAS;AAAA,GAC5B,CAAA;AACD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,OAAO,CAAA;AACT;AAmBO,SAAS,aAAa,IAAA,EAAwB;AACnD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,QAAA;AAC1B,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC5B,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA,IAAQ,EAAE,IAAA,EAAM,OAAA,EAAkB,OAAO,SAAA,EAAU;AACrE,EAAA,OAAO,cAAA,CAAe;AAAA,IACpB,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,IAAA;AAAA,IACA,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,KAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,IAAA,EAAM,IAAA;AAAA,MACN,GAAA,EAAK,IAAA;AAAA,MACL,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACT,GACD,CAAA;AACH;AA6BO,SAAS,WAAW,IAAA,EAA4B;AACrD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,MAAA;AAC1B,EAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,GAAA;AACtC,EAAA,MAAM,aAAA,GAAgB,KAAK,aAAA,IAAiB,IAAA;AAC5C,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,SAAA;AAEpC,EAAA,MAAM,OAAO,IAAIC,SAAA,CAAK,GAAG,IAAI,CAAA,KAAA,CAAA,EAAS,KAAK,KAAK,CAAA;AAEhD,EAAA,MAAM,QAAQ,eAAA,CAAgB;AAAA,IAC5B,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,IAAA,EAAM,GAAG,IAAI,CAAA,MAAA,CAAA;AAAA,IACb,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,SAAS,IAAA,CAAK;AAAA,GACf,CAAA;AACD,EAAA,KAAA,CAAM,QAAA,GAAW,IAAIG,YAAA,CAAQ,CAAA,EAAG,aAAa,IAAA,CAAK,MAAA,GAAS,GAAG,CAAC,CAAA;AAC/D,EAAA,KAAA,CAAM,MAAA,GAAS,IAAA;AAEf,EAAA,MAAM,IAAA,GAAOJ,gBAAA,CAAY,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,KAAA,CAAA,EAAS;AAAA,IACjD,KAAA,EAAO,aAAA;AAAA,IACP,MAAA,EAAQ,UAAA;AAAA,IACR,KAAA,EAAO;AAAA,GACT,EAAG,KAAK,KAAK,CAAA;AACb,EAAA,IAAA,CAAK,WAAW,IAAII,YAAA,CAAQ,CAAA,EAAG,UAAA,GAAa,GAAG,CAAC,CAAA;AAChD,EAAA,MAAM,UAAU,IAAIP,qBAAA,CAAiB,GAAG,IAAI,CAAA,SAAA,CAAA,EAAa,KAAK,KAAK,CAAA;AACnE,EAAA,OAAA,CAAQ,YAAA,GAAeC,WAAA,CAAO,aAAA,CAAc,SAAS,CAAA;AACrD,EAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,EAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAEd,EAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAC7B;AA4BO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,SAAA;AAC1B,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC5B,EAAA,MAAM,UAAA,GAAa,KAAK,KAAA,IAAS,SAAA;AAEjC,EAAA,MAAM,OAAO,IAAIG,SAAA,CAAK,GAAG,IAAI,CAAA,KAAA,CAAA,EAAS,KAAK,KAAK,CAAA;AAGhD,EAAA,MAAM,IAAA,GAAOD,gBAAA,CAAY,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,KAAA,CAAA,EAAS;AAAA,IACjD,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb;AAAA,GACF,EAAG,KAAK,KAAK,CAAA;AACb,EAAA,MAAM,UAAU,IAAIH,qBAAA,CAAiB,GAAG,IAAI,CAAA,SAAA,CAAA,EAAa,KAAK,KAAK,CAAA;AACnE,EAAA,OAAA,CAAQ,YAAA,GAAeC,WAAA,CAAO,aAAA,CAAc,UAAU,CAAA;AACtD,EAAA,OAAA,CAAQ,aAAA,GAAgB,IAAIA,WAAA,CAAO,IAAA,EAAM,MAAM,IAAI,CAAA;AACnD,EAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,EAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AASd,EAAA,MAAM,WAAA,GAAc,IAAA;AACpB,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,GAAQ,WAAA,GAAc,CAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,GAAS,WAAA,GAAc,CAAA;AAK5C,EAAA,MAAM,SAAS,YAAA,CAAa;AAAA,IAC1B,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,IAAA,EAAM,GAAG,IAAI,CAAA,OAAA,CAAA;AAAA,IACb,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,OAAA;AAAA,IACR,KAAA,EAAO,IAAA;AAAA,IACP,OAAO,IAAA,CAAK,MAAA;AAAA,IACZ,IAAA,EAAM,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,UAAA;AAAW,GAC1C,CAAA;AACD,EAAA,MAAA,CAAO,WAAW,IAAIM,YAAA,CAAQ,GAAG,CAAA,EAAG,KAAA,GAAQ,IAAI,IAAK,CAAA;AACrD,EAAA,MAAA,CAAO,MAAA,GAAS,IAAA;AAEhB,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,WAAA,GAAc,CAAA,EAAG;AAC5C,IAAA,KAAA,GAAQJ,gBAAA,CAAY,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,MAAA,CAAA,EAAU;AAAA,MAC7C,KAAA,EAAO,KAAK,KAAA,GAAQ,GAAA;AAAA,MACpB,QAAQ,IAAA,CAAK,WAAA;AAAA,MACb,OAAO,KAAA,GAAQ;AAAA,KACjB,EAAG,KAAK,KAAK,CAAA;AACb,IAAA,KAAA,CAAM,QAAA,GAAW,IAAII,YAAA,CAAQ,CAAA,EAAG,CAAC,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,IAAA,CAAK,WAAA,GAAc,CAAA,EAAG,CAAC,CAAA;AAC1E,IAAA,KAAA,CAAM,QAAA,GAAW,OAAA;AACjB,IAAA,KAAA,CAAM,MAAA,GAAS,IAAA;AAAA,EACjB;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAM;AACrC;AA4BO,SAAS,YAAY,IAAA,EAAuB;AACjD,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,OAAA;AAC1B,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA,IAAU,IAAIA,YAAA,CAAQ,CAAA,EAAG,GAAG,EAAE,CAAA;AAClD,EAAA,MAAM,IAAA,GAAO,IAAIA,YAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,KAAA,IAAS,CAAC,CAAA;AAEhF,EAAA,MAAM,KAAA,GAAQJ,gBAAA,CAAY,WAAA,CAAY,IAAA,EAAM,KAAK,MAAA,EAAQ;AAAA,IACvD,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,MAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAO,IAAA,CAAK;AAAA,GACb,CAAA;AAED,EAAA,MAAM,EAAE,UAAS,GAAI,YAAA,CAAa,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,OAAA,EAAS;AAAA,IAChE,UAAA,EAAY,KAAK,IAAA,CAAK,KAAA;AAAA,IACtB,WAAA,EAAa,KAAK,IAAA,CAAK;AAAA,GACxB,CAAA;AAED,EAAA,IAAI,cAAe,QAAA,EAA+B;AAChD,IAAC,SAA8B,0BAAA,GAA6B,IAAA;AAAA,EAC9D;AACA,EAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AACjB,EAAA,OAAO,KAAA;AACT;AAMO,SAAS,oBACd,KAAA,EACA,IAAA,EACA,QACA,UAAA,EACA,WAAA,EACA,WAAW,KAAA,EACK;AAChB,EAAA,MAAM,GAAA,GAAM,IAAID,mBAAA,CAAe,IAAA,EAAM,EAAE,KAAA,EAAO,UAAA,GAAa,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,SAAA,EAAU,EAAG,OAAO,IAAI,CAAA;AACpH,EAAA,GAAA,CAAI,MAAA,GAAS,EAAA;AACb,EAAA,GAAA,CAAI,OAAA,GAAU,CAAA;AACd,EAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AACf,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,EAAW;AAC3B,EAAA,GAAA,CAAI,KAAA,CAAM,WAAW,SAAS,CAAA;AAC9B,EAAA,WAAA,CAAY,GAAA,EAAK,MAAA,EAAQ,UAAA,EAAY,WAAA,EAAa,QAAQ,CAAA;AAC1D,EAAA,GAAA,CAAI,OAAO,KAAK,CAAA;AAChB,EAAA,OAAO,GAAA;AACT;ACxlBA,SAAS,OAAO,IAAA,EAA2C;AACzD,EAAA,OAAO,EAAE,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,CAAA,IAAK,KAAK,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,CAAA,IAAK,GAAA,EAAI;AAC1D;AAEA,SAAS,gBAAA,CAAiB,MAAiB,MAAA,EAAgB;AACzD,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAE,GAAI,OAAO,IAAI,CAAA;AAC5B,EAAA,MAAM,EAAA,GAAA,CAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,IAAI,CAAA,GAAI,MAAA,CAAO,IAAA,IAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAA,CAAO,IAAA,GAAO,OAAO,IAAI,CAAA;AAC1F,EAAA,MAAM,EAAA,GAAA,CAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,IAAI,CAAA,GAAI,MAAA,CAAO,IAAA,IAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAA,CAAO,IAAA,GAAO,OAAO,IAAI,CAAA;AAC1F,EAAA,OAAO,EAAE,IAAI,EAAA,EAAG;AAClB;AAkBO,SAAS,YAAY,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAgB,IAAA,GAAuB,EAAC,EAAG;AAClG,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,CAAA,GAAI,GAAA;AAChC,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA,IAAU,IAAIK,YAAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AACjD,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAE,GAAI,OAAO,IAAI,CAAA;AAC5B,EAAA,MAAM,EAAA,GAAK,KAAK,QAAA,CAAS,CAAA,GAAI,IAAI,CAAA,GAAA,CAAK,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,CAAA;AACnE,EAAA,MAAM,EAAA,GAAK,KAAK,QAAA,CAAS,CAAA,GAAI,IAAI,CAAA,GAAA,CAAK,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,CAAA;AACnE,EAAA,IAAA,CAAK,QAAA,GAAW,IAAIA,YAAAA,CAAQ,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,KAAA,EAAO,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,KAAA,EAAO,MAAA,CAAO,CAAC,CAAA;AACpF;AAqBO,SAAS,YAAY,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAgB,IAAA,GAAuB,EAAC,EAAG;AAClG,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,EAAA;AAChC,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,GAAA;AAChC,EAAA,MAAM,CAAA,GAAI,KAAK,CAAA,IAAK,CAAA;AACpB,EAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,gBAAA,CAAiB,MAAM,MAAM,CAAA;AAChD,EAAA,IAAA,CAAK,QAAA,GAAW,IAAIA,YAAAA,CAAAA,CAAS,EAAA,GAAK,GAAA,IAAO,SAAS,OAAA,GAAA,CAAW,GAAA,GAAM,EAAA,IAAM,OAAA,EAAS,CAAC,CAAA;AACnF,EAAA,IAAA,CAAK,SAAS,CAAA,GAAI,CAAA;AACpB;AAsBO,SAAS,WAAW,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAgB,IAAA,GAAsB,EAAC,EAAG;AAChG,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,CAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,EAAA,GAAK,GAAA;AAClC,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,CAAA;AAC5B,EAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,gBAAA,CAAiB,MAAM,MAAM,CAAA;AAChD,EAAA,MAAM,KAAA,GAAA,CAAS,KAAK,GAAA,IAAO,GAAA;AAC3B,EAAA,IAAA,CAAK,WAAW,IAAIA,YAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,MAAA,EAAQ,KAAA,GAAA,CAAS,GAAA,GAAM,MAAM,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,MAAM,CAAA;AAC3G,EAAA,IAAA,CAAK,SAAS,CAAA,GAAI,KAAA;AACpB;AAiBA,SAAS,QAAA,CAAS,WAAsB,CAAA,EAA+C;AACrF,EAAA,IAAI,UAAU,MAAA,KAAW,CAAA,SAAU,EAAE,GAAA,EAAK,IAAIA,YAAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,GAAG,OAAA,EAAS,IAAIA,aAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAE;AAC9F,EAAA,IAAI,UAAU,MAAA,KAAW,CAAA,EAAG,OAAO,EAAE,KAAK,SAAA,CAAU,CAAC,CAAA,CAAE,KAAA,IAAS,OAAA,EAAS,IAAIA,aAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAE;AAC9F,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,GAAS,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA,GAAI,QAAA;AAC7C,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,QAAA,GAAW,GAAG,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAA;AACnD,EAAA,MAAM,QAAQ,MAAA,GAAS,CAAA;AACvB,EAAA,MAAM,CAAA,GAAI,UAAU,CAAC,CAAA;AACrB,EAAA,MAAM,CAAA,GAAI,SAAA,CAAU,CAAA,GAAI,CAAC,CAAA;AACzB,EAAA,MAAM,GAAA,GAAMA,YAAAA,CAAQ,IAAA,CAAK,CAAA,EAAG,GAAG,KAAK,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,CAAA,CAAE,QAAA,CAAS,CAAC,EAAE,SAAA,EAAU;AACxC,EAAA,OAAO,EAAE,KAAK,OAAA,EAAQ;AACxB;AAOO,SAAS,WAAA,CAAY,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAgB,IAAA,EAAsB;AAC7F,EAAA,MAAM,WAAA,GAAc,KAAK,WAAA,IAAe,IAAA;AACxC,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI,KAAK,OAAA,EAAS;AAChB,IAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,IAAa,IAAA,CAAK,IAAI,CAAA,EAAG,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAI,CAAA;AACrE,IAAA,MAAM,GAAA,GAAM,KAAK,QAAA,CAAS,CAAA;AAC1B,IAAA,CAAA,GAAI,KAAA,GAAQ,CAAA,GAAI,GAAA,IAAO,KAAA,GAAQ,CAAA,CAAA,GAAK,GAAA;AAAA,EACtC,CAAA,MAAO;AACL,IAAA,MAAM,EAAE,EAAA,EAAG,GAAI,gBAAA,CAAiB,MAAM,MAAM,CAAA;AAC5C,IAAA,CAAA,GAAI,EAAA;AAAA,EACN;AACA,EAAA,MAAM,EAAE,GAAA,EAAK,OAAA,KAAY,QAAA,CAAS,IAAA,CAAK,WAAW,CAAC,CAAA;AACnD,EAAA,IAAA,CAAK,QAAA,GAAW,GAAA;AAChB,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,IAAA,CAAK,SAAS,CAAA,GAAI,IAAA,CAAK,MAAM,OAAA,CAAQ,CAAA,EAAG,QAAQ,CAAC,CAAA;AAAA,EACnD;AACF;AAqBO,SAAS,cAAc,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAgB,IAAA,GAAyB,EAAC,EAAG;AACtG,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,CAAA;AAC9B,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA,IAAU,IAAIA,YAAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AACjD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,EAAA,GAAK,GAAA;AAC1C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,EAAA,GAAK,CAAA;AAC1C,EAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,gBAAA,CAAiB,MAAM,MAAM,CAAA;AAChD,EAAA,MAAM,GAAA,GAAA,CAAO,KAAK,GAAA,IAAO,OAAA;AACzB,EAAA,MAAM,GAAA,GAAA,CAAO,MAAM,EAAA,IAAM,OAAA;AACzB,EAAA,MAAM,CAAA,GAAI,MAAA;AACV,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA,CAAK,IAAI,GAAG,CAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAC1B,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA,CAAK,IAAI,GAAG,CAAA;AAC1C,EAAA,IAAA,CAAK,QAAA,GAAW,IAAIA,YAAAA,CAAQ,MAAA,CAAO,CAAA,GAAI,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AACpE,EAAA,IAAA,CAAK,SAAS,CAAA,GAAI,GAAA;AACpB;;;AC1KA,IAAM,cAAc,CAAA,GAAI,GAAA;AAajB,SAAS,qBAAqB,IAAA,EAA+C;AAClF,EAAA,OAAO;AAAA,IACL,MAAA,CAAO,MAAkB,GAAA,EAA2B;AAClD,MAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAE,GAAI,IAAA,CAAK,QAAQ,IAAI,CAAA;AAClC,MAAA,MAAM,MAAM,IAAIL,mBAAAA,CAAe,CAAA,IAAA,EAAO,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,EAAE,KAAA,EAAO,CAAA,GAAI,WAAW,MAAA,EAAQ,CAAA,GAAI,WAAU,EAAG,IAAA,CAAK,SAAS,IAAI,CAAA;AACvH,MAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AAGf,MAAA,GAAA,CAAI,MAAA,GAAS,EAAA;AACb,MAAA,GAAA,CAAI,OAAA,GAAU,CAAA;AACd,MAAA,MAAM,CAAA,GAAI,IAAI,UAAA,EAAW;AACzB,MAAA,CAAA,CAAE,KAAA,CAAM,WAAW,SAAS,CAAA;AAC5B,MAAA,WAAA,CAAY,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,CAAA,EAAG,IAAI,QAAQ,CAAA;AACvC,MAAA,GAAA,CAAI,OAAO,KAAK,CAAA;AAEhB,MAAA,MAAM,GAAA,GAAM,IAAIF,qBAAAA,CAAiB,CAAA,IAAA,EAAO,IAAI,MAAM,CAAA,CAAA,EAAI,KAAK,OAAO,CAAA;AAClE,MAAA,GAAA,CAAI,cAAA,GAAiB,GAAA;AACrB,MAAA,GAAA,CAAI,eAAA,GAAkB,GAAA;AACtB,MAAA,GAAA,CAAI,aAAA,GAAgB,IAAIC,WAAAA,CAAO,CAAA,EAAG,GAAG,CAAC,CAAA;AACtC,MAAA,GAAA,CAAI,eAAA,GAAkB,KAAA;AACtB,MAAA,GAAA,CAAI,0BAAA,GAA6B,IAAA;AAEjC,MAAA,MAAM,QAAQE,gBAAAA,CAAY,WAAA,CAAY,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,EAAE,KAAA,EAAO,CAAA,GAAI,aAAa,MAAA,EAAQ,CAAA,GAAI,WAAA,EAAY,EAAG,KAAK,OAAO,CAAA;AAC7H,MAAA,KAAA,CAAM,QAAA,GAAW,GAAA;AACjB,MAAA,KAAA,CAAM,WAAW,EAAE,MAAA,EAAQ,IAAI,MAAA,EAAQ,IAAA,EAAM,KAAK,IAAA,EAAK;AACvD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACF;AACF;AAWO,SAAS,gBAAgB,IAAA,EAAiB,IAAA,EAAY,MAAA,EAAoE,IAAA,GAA0C,EAAC,EAAG;AAC7K,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,CAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,EAAA,GAAK,GAAA;AAClC,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,CAAA;AAC5C,EAAA,MAAM,EAAA,GAAA,CAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAA,CAAK,IAAA,CAAK,MAAM,CAAA,IAAK,GAAA,IAAO,CAAA,GAAI,MAAA,CAAO,IAAA,IAAQ,MAAA;AACzE,EAAA,MAAM,EAAA,GAAA,CAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAA,CAAK,IAAA,CAAK,MAAM,CAAA,IAAK,GAAA,IAAO,CAAA,GAAI,MAAA,CAAO,IAAA,IAAQ,MAAA;AACzE,EAAA,MAAM,KAAA,GAAA,CAAS,KAAK,GAAA,IAAO,GAAA;AAC3B,EAAA,MAAM,MAAA,GAAA,CAAU,MAAM,EAAA,IAAM,CAAA;AAC5B,EAAA,IAAA,CAAK,QAAA,GAAW,IAAII,YAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,MAAA,EAAQ,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,MAAM,CAAA;AAItF,EAAA,IAAA,CAAK,QAAA,GAAW,IAAIA,YAAAA,CAAQ,CAAA,EAAG,OAAO,CAAC,CAAA;AACzC;AAEO,SAAS,YAAY,KAAA,EAAc;AACxC,EAAA,MAAM,EAAA,GAAK,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9C,EAAA,MAAM,EAAA,GAAK,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9C,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,CAAA,IAAK,CAAA,CAAE,IAAA,EAAM,CAAA,IAAK,GAAA,CAAI,CAAA;AACnE,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,CAAA,IAAK,CAAA,CAAE,IAAA,EAAM,CAAA,IAAK,GAAA,CAAI,CAAA;AACnE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAA;AAAA,IACpB,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAA;AAAA,IACpB,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAA;AAAA,IACpB,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE;AAAA,GACtB;AACF","file":"index.cjs","sourcesContent":["import type { WidgetSpec } from \"@particle-academy/fancy-3d\";\n\nexport const TEX_SCALE = 2; // retina-ish texture sharpness\n\n/** Scale factor against the painters' design-time canvas (240px tall). All\n * widget painters multiply their padding / font sizes by this so the layout\n * looks the same at any pixel resolution. */\nfunction unitOf(_w: number, h: number): number {\n return h / 240;\n}\n\nfunction paintCardBg(ctx: CanvasRenderingContext2D, w: number, h: number, selected: boolean) {\n const u = unitOf(w, h);\n ctx.fillStyle = \"#0f172a\";\n roundRect(ctx, 0, 0, w, h, 14 * u);\n ctx.fill();\n ctx.strokeStyle = selected ? \"#6366f1\" : \"#1e293b\";\n ctx.lineWidth = (selected ? 4 : 2) * u;\n ctx.stroke();\n}\n\nfunction roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.arcTo(x + w, y, x + w, y + h, r);\n ctx.arcTo(x + w, y + h, x, y + h, r);\n ctx.arcTo(x, y + h, x, y, r);\n ctx.arcTo(x, y, x + w, y, r);\n ctx.closePath();\n}\n\nfunction paintLabel(ctx: CanvasRenderingContext2D, text: string, x: number, y: number) {\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.textBaseline = \"top\";\n ctx.fillText(text.toUpperCase(), x, y);\n}\n\nfunction paintSparkline(ctx: CanvasRenderingContext2D, values: number[], x: number, y: number, w: number, h: number, variant: \"line\" | \"bar\" | \"area\", color: string) {\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = max - min || 1;\n const step = w / Math.max(values.length - 1, 1);\n\n if (variant === \"bar\") {\n const bw = w / values.length - 4;\n ctx.fillStyle = color;\n values.forEach((v, i) => {\n const bh = ((v - min) / range) * h;\n ctx.fillRect(x + i * (bw + 4), y + h - bh, bw, Math.max(bh, 1));\n });\n return;\n }\n\n ctx.beginPath();\n values.forEach((v, i) => {\n const px = x + i * step;\n const py = y + h - ((v - min) / range) * h;\n if (i === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n });\n\n if (variant === \"area\") {\n ctx.lineTo(x + w, y + h);\n ctx.lineTo(x, y + h);\n ctx.closePath();\n ctx.fillStyle = color + \"44\";\n ctx.fill();\n ctx.beginPath();\n values.forEach((v, i) => {\n const px = x + i * step;\n const py = y + h - ((v - min) / range) * h;\n if (i === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n });\n }\n\n ctx.strokeStyle = color;\n ctx.lineWidth = 3;\n ctx.stroke();\n}\nexport function paintWidget(ctx: CanvasRenderingContext2D, spec: WidgetSpec, w: number, h: number, selected: boolean) {\n paintCardBg(ctx, w, h, selected);\n const pad = 20;\n\n switch (spec.kind) {\n case \"kpi\": {\n paintLabel(ctx, spec.label, pad, pad);\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"700 56px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.value, pad, pad + 32);\n if (spec.delta) {\n ctx.fillStyle = spec.trend === \"up\" ? \"#10b981\" : spec.trend === \"down\" ? \"#f43f5e\" : \"#94a3b8\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.delta, pad, pad + 92);\n }\n break;\n }\n case \"chart\": {\n paintLabel(ctx, spec.title, pad, pad);\n paintSparkline(ctx, spec.series, pad, pad + 36, w - pad * 2, h - pad * 2 - 36, spec.variant, spec.color ?? \"#6366f1\");\n break;\n }\n case \"kanban\": {\n const colW = (w - pad * 2 - (spec.columns.length - 1) * 10) / spec.columns.length;\n spec.columns.forEach((col, i) => {\n const cx = pad + i * (colW + 10);\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, cx, pad, colW, h - pad * 2, 8);\n ctx.fill();\n paintLabel(ctx, col.title, cx + 8, pad + 10);\n col.cards.forEach((c, j) => {\n ctx.fillStyle = \"#0f172a\";\n roundRect(ctx, cx + 8, pad + 44 + j * 38, colW - 16, 30, 6);\n ctx.fill();\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"500 20px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(c, cx + 16, pad + 50 + j * 38);\n });\n });\n break;\n }\n case \"table\": {\n paintLabel(ctx, spec.title, pad, pad);\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"600 18px ui-sans-serif, system-ui, sans-serif\";\n const colW = (w - pad * 2) / spec.columns.length;\n spec.columns.forEach((c, i) => ctx.fillText(c, pad + i * colW, pad + 38));\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n spec.rows.forEach((row, ri) => {\n row.forEach((cell, ci) => ctx.fillText(String(cell), pad + ci * colW, pad + 70 + ri * 28));\n });\n break;\n }\n case \"profile\": {\n ctx.fillStyle = \"#6366f1\";\n ctx.beginPath();\n ctx.arc(pad + 30, pad + 30, 28, 0, Math.PI * 2);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.font = \"700 24px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(spec.initials, pad + 30, pad + 22);\n ctx.textAlign = \"left\";\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"600 24px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.name, pad + 76, pad + 12);\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"400 20px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.role, pad + 76, pad + 40);\n if (spec.status) {\n ctx.fillStyle = spec.status === \"online\" ? \"#10b981\" : spec.status === \"away\" ? \"#f59e0b\" : \"#64748b\";\n ctx.beginPath();\n ctx.arc(pad + 50, pad + 50, 6, 0, Math.PI * 2);\n ctx.fill();\n }\n break;\n }\n case \"callout\": {\n const tone = spec.tone === \"danger\" ? \"#f43f5e\" : spec.tone === \"warning\" ? \"#f59e0b\" : spec.tone === \"success\" ? \"#10b981\" : \"#3b82f6\";\n ctx.fillStyle = tone + \"22\";\n roundRect(ctx, 4, 4, w - 8, h - 8, 12);\n ctx.fill();\n ctx.fillStyle = tone;\n ctx.fillRect(12, 12, 4, h - 24);\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"600 22px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.title, 28, pad);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n wrapText(ctx, spec.body, 28, pad + 32, w - 40, 22);\n break;\n }\n case \"form\": {\n paintLabel(ctx, spec.title, pad, pad);\n spec.fields.forEach((f, i) => {\n const y = pad + 40 + i * 44;\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"500 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(f.label, pad, y);\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, w - pad - 100, y - 4, 100, 28, 6);\n ctx.fill();\n if (f.type === \"switch\") {\n ctx.fillStyle = \"#6366f1\";\n roundRect(ctx, w - pad - 60, y - 4, 60, 28, 14);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.beginPath();\n ctx.arc(w - pad - 18, y + 10, 10, 0, Math.PI * 2);\n ctx.fill();\n }\n });\n break;\n }\n case \"action\": {\n paintLabel(ctx, spec.title, pad, pad);\n let bx = pad;\n const by = pad + 40;\n spec.buttons.forEach((b) => {\n const tw = ctx.measureText(b.label).width + 24;\n ctx.fillStyle = b.variant === \"primary\" ? \"#6366f1\" : b.variant === \"ghost\" ? \"transparent\" : \"#1e293b\";\n if (b.variant !== \"ghost\") {\n roundRect(ctx, bx, by, tw, 36, 8);\n ctx.fill();\n }\n ctx.fillStyle = b.variant === \"primary\" ? \"#fff\" : \"#cbd5e1\";\n ctx.font = \"600 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(b.label, bx + 12, by + 9);\n bx += tw + 8;\n });\n break;\n }\n case \"timeline\": {\n paintLabel(ctx, spec.title, pad, pad);\n spec.events.forEach((e, i) => {\n const y = pad + 40 + i * 32;\n ctx.fillStyle = \"#6366f1\";\n ctx.beginPath();\n ctx.arc(pad + 4, y + 10, 4, 0, Math.PI * 2);\n ctx.fill();\n ctx.strokeStyle = \"#1e293b\";\n if (i < spec.events.length - 1) {\n ctx.beginPath();\n ctx.moveTo(pad + 4, y + 14);\n ctx.lineTo(pad + 4, y + 32);\n ctx.stroke();\n }\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"500 14px ui-monospace, monospace\";\n ctx.fillText(e.at, pad + 16, y);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(e.label, pad + 60, y);\n });\n break;\n }\n case \"code\": {\n paintLabel(ctx, spec.title, pad, pad);\n ctx.fillStyle = \"#020617\";\n roundRect(ctx, pad, pad + 36, w - pad * 2, h - pad * 2 - 36, 8);\n ctx.fill();\n ctx.fillStyle = \"#a5b4fc\";\n ctx.font = \"400 16px ui-monospace, monospace\";\n const lines = spec.code.split(\"\\n\");\n lines.forEach((ln, i) => ctx.fillText(ln, pad + 14, pad + 56 + i * 22));\n break;\n }\n case \"image\": {\n ctx.fillStyle = \"#1e293b\";\n roundRect(ctx, pad, pad, w - pad * 2, h - pad * 2, 8);\n ctx.fill();\n ctx.fillStyle = \"#64748b\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(spec.alt, w / 2, h / 2);\n ctx.textAlign = \"left\";\n break;\n }\n case \"text\": {\n ctx.fillStyle = \"#f1f5f9\";\n ctx.font = \"700 26px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(spec.heading, pad, pad);\n ctx.fillStyle = \"#cbd5e1\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n wrapText(ctx, spec.body, pad, pad + 38, w - pad * 2, 22);\n break;\n }\n case \"screen\": {\n const bezel = spec.bezel ?? \"#0b0f17\";\n const t = spec.bezelThickness ?? 14;\n const on = spec.on ?? true;\n const brightness = spec.brightness ?? (on ? 1 : 0.06);\n const bg = spec.background ?? \"#020617\";\n\n // Outer bezel\n ctx.fillStyle = bezel;\n roundRect(ctx, 0, 0, w, h, 18);\n ctx.fill();\n // Inner screen area\n const sx = t;\n const sy = t;\n const sw = w - t * 2;\n const sh = h - t * 2;\n ctx.save();\n ctx.fillStyle = bg;\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.fill();\n ctx.beginPath();\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.clip();\n ctx.translate(sx, sy);\n // Apply brightness as global alpha multiplier\n ctx.globalAlpha = brightness;\n const c = spec.content;\n if (c.type === \"label\") {\n ctx.fillStyle = \"#e2e8f0\";\n ctx.font = \"700 32px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(c.title, sw / 2, sh / 2 - (c.subtitle ? 16 : 0));\n if (c.subtitle) {\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = \"400 18px ui-sans-serif, system-ui, sans-serif\";\n ctx.fillText(c.subtitle, sw / 2, sh / 2 + 18);\n }\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n } else if (c.type === \"paint\") {\n c.paint(ctx, sw, sh);\n } else if (c.type === \"image\") {\n // Image content is best painted by the consumer via \"paint\" — labels\n // serve as a fallback so the screen still has identifiable content.\n ctx.fillStyle = \"#475569\";\n ctx.font = \"500 16px ui-sans-serif, system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n ctx.fillText(c.alt ?? \"image\", sw / 2, sh / 2);\n ctx.textAlign = \"left\";\n }\n ctx.globalAlpha = 1;\n ctx.restore();\n // Power LED\n ctx.fillStyle = on ? \"#10b981\" : \"#475569\";\n ctx.beginPath();\n ctx.arc(w - t - 6, h - t - 6, 4, 0, Math.PI * 2);\n ctx.fill();\n // Subtle glass reflection\n const grad = ctx.createLinearGradient(sx, sy, sx, sy + sh);\n grad.addColorStop(0, \"rgba(255,255,255,0.08)\");\n grad.addColorStop(0.4, \"rgba(255,255,255,0)\");\n ctx.fillStyle = grad;\n ctx.beginPath();\n roundRect(ctx, sx, sy, sw, sh, 8);\n ctx.fill();\n break;\n }\n case \"demoPage\": {\n const u = unitOf(w, h);\n const padX = w * 0.06;\n const headerH = h * 0.22;\n const titleY = headerH + h * 0.12;\n const titleSize = h * 0.16;\n const descY = titleY + titleSize * 0.6;\n const descSize = h * 0.072;\n const descLine = descSize * 1.4;\n const chipSize = h * 0.052;\n const pathSize = h * 0.052;\n const ctaSize = h * 0.075;\n const ctaH = ctaSize * 2;\n\n // Accent header bar — slightly overlaps card top to visually anchor\n ctx.fillStyle = spec.accent;\n roundRect(ctx, 0, 0, w, headerH, 14 * u);\n ctx.fill();\n // Squared bottom on the accent bar (cancel rounded bottom corners)\n ctx.fillRect(0, headerH - 14 * u, w, 14 * u);\n\n // Category chip\n ctx.fillStyle = \"rgba(255,255,255,0.22)\";\n const chipText = spec.category.toUpperCase();\n ctx.font = `700 ${chipSize}px ui-sans-serif, system-ui, sans-serif`;\n ctx.textBaseline = \"top\";\n const chipPad = chipSize * 0.7;\n const chipW = ctx.measureText(chipText).width + chipPad * 2;\n const chipH = chipSize * 1.85;\n const chipY = (headerH - chipH) / 2;\n roundRect(ctx, padX, chipY, chipW, chipH, chipH / 2);\n ctx.fill();\n ctx.fillStyle = \"#fff\";\n ctx.fillText(chipText, padX + chipPad, chipY + (chipH - chipSize) / 2);\n\n // Path on right\n ctx.fillStyle = \"rgba(255,255,255,0.9)\";\n ctx.font = `500 ${pathSize}px ui-monospace, monospace`;\n const pathW = ctx.measureText(spec.path).width;\n ctx.fillText(spec.path, w - padX - pathW, chipY + (chipH - chipSize) / 2);\n\n // Title\n ctx.fillStyle = \"#f8fafc\";\n ctx.font = `800 ${titleSize}px ui-sans-serif, system-ui, sans-serif`;\n ctx.fillText(spec.name, padX, titleY);\n\n // Description (wrapped, clipped before reaching the CTA)\n ctx.fillStyle = \"#94a3b8\";\n ctx.font = `400 ${descSize}px ui-sans-serif, system-ui, sans-serif`;\n const ctaY = h - padX - ctaH;\n wrapText(ctx, spec.description, padX, descY, w - padX * 2, descLine, ctaY - descLine);\n\n // CTA at bottom\n ctx.fillStyle = spec.accent;\n const ctaText = \"Open demo →\";\n ctx.font = `600 ${ctaSize}px ui-sans-serif, system-ui, sans-serif`;\n const ctaTextPad = ctaSize * 0.9;\n const ctaW = ctx.measureText(ctaText).width + ctaTextPad * 2;\n roundRect(ctx, padX, ctaY, ctaW, ctaH, ctaH * 0.25);\n ctx.fill();\n ctx.fillStyle = \"#0f172a\";\n ctx.fillText(ctaText, padX + ctaTextPad, ctaY + (ctaH - ctaSize) / 2);\n ctx.textBaseline = \"alphabetic\";\n break;\n }\n }\n}\n\nfunction wrapText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n maxW: number,\n lineH: number,\n maxY?: number\n) {\n const words = text.split(\" \");\n let line = \"\";\n let yy = y;\n for (const word of words) {\n const test = line ? `${line} ${word}` : word;\n if (ctx.measureText(test).width > maxW && line) {\n if (maxY !== undefined && yy > maxY) return;\n ctx.fillText(line, x, yy);\n line = word;\n yy += lineH;\n } else {\n line = test;\n }\n }\n if (line && (maxY === undefined || yy <= maxY)) ctx.fillText(line, x, yy);\n}\n","/**\n * 3D shape primitives for `@particle-academy/fancy-3d`.\n *\n * A primitive is a Babylon mesh that can host UI content on its surface —\n * either a flat color, a freeform 2D paint callback, or a `WidgetSpec`\n * rendered through the same painters as the Babylon adapter.\n *\n * Every primitive returns a `Mesh`, ready to position in your scene.\n */\nimport {\n Color3,\n DynamicTexture,\n Mesh,\n MeshBuilder,\n StandardMaterial,\n Vector3,\n Vector4,\n type Scene,\n} from \"@babylonjs/core\";\nimport type { WidgetSpec } from \"@particle-academy/fancy-3d\";\nimport { TEX_SCALE, paintWidget } from \"./painters\";\n\nexport type PaintFn = (ctx: CanvasRenderingContext2D, width: number, height: number) => void;\n\nexport type SurfaceContent =\n | { type: \"color\"; color: string }\n | { type: \"paint\"; paint: PaintFn; pixelWidth?: number; pixelHeight?: number; transparent?: boolean }\n | { type: \"widget\"; widget: WidgetSpec; pixelWidth?: number; pixelHeight?: number; selected?: boolean };\n\n/** Default pixel density when a primitive auto-sizes a widget surface from\n * world-space dimensions (1 world unit ≈ 1 meter). Higher values produce\n * sharper textures at the cost of GPU memory. */\nconst DEFAULT_DENSITY = 120;\nconst MAX_TEXTURE_AXIS = 1024;\n\nfunction autoPixelSize(worldWidth: number, worldHeight: number, density = DEFAULT_DENSITY) {\n let w = Math.max(96, Math.round(worldWidth * density));\n let h = Math.max(96, Math.round(worldHeight * density));\n const scale = Math.min(1, MAX_TEXTURE_AXIS / Math.max(w, h));\n if (scale < 1) {\n w = Math.round(w * scale);\n h = Math.round(h * scale);\n }\n return { w, h };\n}\n\ninterface SurfaceTexture {\n material: StandardMaterial;\n texture: DynamicTexture | null;\n}\n\nfunction buildSurface(\n scene: Scene,\n name: string,\n surface: SurfaceContent,\n autoSize?: { worldWidth: number; worldHeight: number }\n): SurfaceTexture {\n const mat = new StandardMaterial(`${name}-mat`, scene);\n mat.specularColor = new Color3(0.05, 0.05, 0.05);\n\n if (surface.type === \"color\") {\n mat.diffuseColor = Color3.FromHexString(surface.color);\n mat.emissiveColor = Color3.FromHexString(surface.color).scale(0.15);\n return { material: mat, texture: null };\n }\n\n let w = surface.pixelWidth;\n let h = surface.pixelHeight;\n if ((w == null || h == null) && autoSize) {\n const auto = autoPixelSize(autoSize.worldWidth, autoSize.worldHeight);\n w = w ?? auto.w;\n h = h ?? auto.h;\n }\n w = w ?? 512;\n h = h ?? 512;\n const tex = new DynamicTexture(`${name}-tex`, { width: w * TEX_SCALE, height: h * TEX_SCALE }, scene, true);\n // Babylon plane UVs run V=0 at the bottom; canvas Y runs top-to-bottom.\n tex.vScale = -1;\n tex.vOffset = 1;\n if (surface.type === \"paint\" && surface.transparent) {\n tex.hasAlpha = true;\n }\n if (surface.type === \"widget\") {\n tex.hasAlpha = true;\n }\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n if (surface.type === \"paint\") {\n surface.paint(ctx, w, h);\n } else {\n paintWidget(ctx, surface.widget, w, h, surface.selected ?? false);\n }\n tex.update(false);\n\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(0.6, 0.6, 0.6);\n if (tex.hasAlpha) mat.useAlphaFromDiffuseTexture = true;\n\n return { material: mat, texture: tex };\n}\n\n/* ------------------------------------------------------------------ */\n/* Panel — flat 2D plane with one surface */\n/* ------------------------------------------------------------------ */\n\nexport interface PanelOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n surface: SurfaceContent;\n /** Babylon sideOrientation. Use `Mesh.DOUBLESIDE` for panels you want visible\n * from both directions (e.g. self-luminous screens). Default is FRONTSIDE. */\n sideOrientation?: number;\n}\n\nexport function createPanel(opts: PanelOpts): Mesh {\n const name = opts.name ?? \"panel\";\n const m = MeshBuilder.CreatePlane(name, { width: opts.width, height: opts.height, sideOrientation: opts.sideOrientation }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Billboard — panel that can be set to always face the camera */\n/* ------------------------------------------------------------------ */\n\nexport interface BillboardOpts extends PanelOpts {\n /** When true, mesh.billboardMode = ALL — always faces the camera. */\n faceCamera?: boolean;\n}\n\nexport function createBillboard(opts: BillboardOpts): Mesh {\n const m = createPanel({ ...opts, name: opts.name ?? \"billboard\" });\n if (opts.faceCamera) {\n m.billboardMode = Mesh.BILLBOARDMODE_ALL;\n }\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Building — rectangular box with optional facade texture */\n/* ------------------------------------------------------------------ */\n\nexport interface BuildingOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n depth: number;\n /** Surface applied to all 6 faces (cheap path). */\n surface?: SurfaceContent;\n /** Per-face surfaces; missing faces use `surface` or a default grey. */\n faces?: Partial<Record<BoxFace, SurfaceContent>>;\n}\n\n/** Babylon box face indices (CreateBox): 0=front (-Z), 1=back (+Z), 2=right (+X), 3=left (-X), 4=top (+Y), 5=bottom (-Y). */\nexport type BoxFace = \"front\" | \"back\" | \"right\" | \"left\" | \"top\" | \"bottom\";\n\nconst BOX_FACE_ORDER: BoxFace[] = [\"front\", \"back\", \"right\", \"left\", \"top\", \"bottom\"];\n\nexport function createBuilding(opts: BuildingOpts): Mesh {\n const name = opts.name ?? \"building\";\n // If only a single uniform surface is given, take the cheap path.\n if (opts.surface && !opts.faces) {\n const box = MeshBuilder.CreateBox(name, { width: opts.width, height: opts.height, depth: opts.depth }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n box.material = material;\n return box;\n }\n\n // Per-face surfaces — Babylon's CreateBox supports `faceUV` to map sub-rects\n // of a single texture onto each face. We composite 6 sub-textures into one.\n const faceW = 256;\n const faceH = 256;\n const atlasW = faceW * 3;\n const atlasH = faceH * 2;\n const tex = new DynamicTexture(`${name}-atlas`, { width: atlasW * TEX_SCALE, height: atlasH * TEX_SCALE }, opts.scene, true);\n tex.vScale = -1;\n tex.vOffset = 1;\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n\n const faceUV: Vector4[] = [];\n BOX_FACE_ORDER.forEach((face, i) => {\n const col = i % 3;\n const row = Math.floor(i / 3);\n const fx = col * faceW;\n const fy = row * faceH;\n const surface = opts.faces?.[face] ?? opts.surface ?? { type: \"color\", color: \"#475569\" };\n ctx.save();\n ctx.translate(fx, fy);\n if (surface.type === \"color\") {\n ctx.fillStyle = surface.color;\n ctx.fillRect(0, 0, faceW, faceH);\n } else if (surface.type === \"paint\") {\n surface.paint(ctx, faceW, faceH);\n } else {\n paintWidget(ctx, surface.widget, faceW, faceH, surface.selected ?? false);\n }\n ctx.restore();\n\n // UV rect for this face within the atlas.\n faceUV.push(new Vector4(fx / atlasW, 1 - (fy + faceH) / atlasH, (fx + faceW) / atlasW, 1 - fy / atlasH));\n });\n tex.update(false);\n\n const mat = new StandardMaterial(`${name}-mat`, opts.scene);\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(0.4, 0.4, 0.4);\n mat.specularColor = new Color3(0.05, 0.05, 0.05);\n\n const box = MeshBuilder.CreateBox(name, {\n width: opts.width,\n height: opts.height,\n depth: opts.depth,\n faceUV,\n wrap: true,\n }, opts.scene);\n box.material = mat;\n return box;\n}\n\n/* ------------------------------------------------------------------ */\n/* Pillar — alias for a tall narrow building */\n/* ------------------------------------------------------------------ */\n\nexport interface PillarOpts {\n scene: Scene;\n name?: string;\n thickness: number;\n height: number;\n surface?: SurfaceContent;\n}\n\nexport function createPillar(opts: PillarOpts): Mesh {\n return createBuilding({\n scene: opts.scene,\n name: opts.name ?? \"pillar\",\n width: opts.thickness,\n depth: opts.thickness,\n height: opts.height,\n surface: opts.surface,\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Cylinder — tube with content wrapping the side */\n/* ------------------------------------------------------------------ */\n\nexport interface CylinderOpts {\n scene: Scene;\n name?: string;\n radius: number;\n height: number;\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createCylinder(opts: CylinderOpts): Mesh {\n const name = opts.name ?? \"cylinder\";\n const m = MeshBuilder.CreateCylinder(name, {\n diameter: opts.radius * 2,\n height: opts.height,\n tessellation: opts.tessellation ?? 48,\n }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.radius * 2 * Math.PI,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* CurvedPanel — a partial cylindrical sheet (like a wraparound ad) */\n/* ------------------------------------------------------------------ */\n\nexport interface CurvedPanelOpts {\n scene: Scene;\n name?: string;\n width: number; // arc length\n height: number;\n arc: number; // radians spanned\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createCurvedPanel(opts: CurvedPanelOpts): Mesh {\n const name = opts.name ?? \"curved-panel\";\n const radius = opts.width / opts.arc;\n // Build by creating a partial cylinder (arc fraction) with no caps.\n const tess = opts.tessellation ?? 48;\n const fullCircleSegments = Math.max(8, Math.ceil((tess * (Math.PI * 2)) / opts.arc));\n const m = MeshBuilder.CreateCylinder(name, {\n diameter: radius * 2,\n height: opts.height,\n tessellation: fullCircleSegments,\n arc: opts.arc / (Math.PI * 2),\n cap: Mesh.NO_CAP,\n sideOrientation: Mesh.DOUBLESIDE,\n }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.width,\n worldHeight: opts.height,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Sphere — full sphere with equirectangular surface */\n/* ------------------------------------------------------------------ */\n\nexport interface SphereOpts {\n scene: Scene;\n name?: string;\n diameter: number;\n surface: SurfaceContent;\n segments?: number;\n}\n\nexport function createSphere(opts: SphereOpts): Mesh {\n const name = opts.name ?? \"sphere\";\n const m = MeshBuilder.CreateSphere(name, { diameter: opts.diameter, segments: opts.segments ?? 32 }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.diameter * Math.PI,\n worldHeight: opts.diameter * Math.PI / 2,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Disc — flat disc/circle */\n/* ------------------------------------------------------------------ */\n\nexport interface DiscOpts {\n scene: Scene;\n name?: string;\n radius: number;\n surface: SurfaceContent;\n tessellation?: number;\n}\n\nexport function createDisc(opts: DiscOpts): Mesh {\n const name = opts.name ?? \"disc\";\n const m = MeshBuilder.CreateDisc(name, { radius: opts.radius, tessellation: opts.tessellation ?? 64 }, opts.scene);\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.radius * 2,\n worldHeight: opts.radius * 2,\n });\n m.material = material;\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n/* Card3D — an extruded panel (gives panels physical depth) */\n/* ------------------------------------------------------------------ */\n\nexport interface Card3DOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n /** Extrusion depth. Defaults to a thin 0.06 — like real foam-board signage. */\n depth?: number;\n /** Surface for the front face (the visible UI). */\n front: SurfaceContent;\n /** Surface for the side and back faces. Defaults to a dark color. */\n edge?: SurfaceContent;\n}\n\nexport function createCard3D(opts: Card3DOpts): Mesh {\n const name = opts.name ?? \"card3d\";\n const depth = opts.depth ?? 0.06;\n const edge = opts.edge ?? { type: \"color\" as const, color: \"#0b0f17\" };\n return createBuilding({\n scene: opts.scene,\n name,\n width: opts.width,\n height: opts.height,\n depth,\n faces: {\n front: opts.front,\n back: edge,\n top: edge,\n bottom: edge,\n left: edge,\n right: edge,\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Sign — a panel mounted on a post */\n/* ------------------------------------------------------------------ */\n\nexport interface SignOpts {\n scene: Scene;\n name?: string;\n /** Panel dimensions. */\n width: number;\n height: number;\n /** How tall the post is (from ground to bottom of panel). */\n postHeight?: number;\n /** Post thickness (square cross-section). */\n postThickness?: number;\n /** Panel surface (color, paint, or widget). */\n surface: SurfaceContent;\n /** Post color. */\n postColor?: string;\n}\n\nexport interface SignResult {\n /** Group containing the panel + post, parented at ground level. */\n root: Mesh;\n panel: Mesh;\n post: Mesh;\n}\n\nexport function createSign(opts: SignOpts): SignResult {\n const name = opts.name ?? \"sign\";\n const postHeight = opts.postHeight ?? 1.4;\n const postThickness = opts.postThickness ?? 0.12;\n const postColor = opts.postColor ?? \"#1f2937\";\n\n const root = new Mesh(`${name}-root`, opts.scene);\n\n const panel = createBillboard({\n scene: opts.scene,\n name: `${name}-panel`,\n width: opts.width,\n height: opts.height,\n surface: opts.surface,\n });\n panel.position = new Vector3(0, postHeight + opts.height / 2, 0);\n panel.parent = root;\n\n const post = MeshBuilder.CreateBox(`${name}-post`, {\n width: postThickness,\n height: postHeight,\n depth: postThickness,\n }, opts.scene);\n post.position = new Vector3(0, postHeight / 2, 0);\n const postMat = new StandardMaterial(`${name}-post-mat`, opts.scene);\n postMat.diffuseColor = Color3.FromHexString(postColor);\n post.material = postMat;\n post.parent = root;\n\n return { root, panel, post };\n}\n\n/* ------------------------------------------------------------------ */\n/* Monitor — a 3D display: extruded bezel + recessed screen face */\n/* ------------------------------------------------------------------ */\n\nexport interface MonitorOpts {\n scene: Scene;\n name?: string;\n width: number;\n height: number;\n /** Front-to-back depth of the display chassis. Defaults to 0.18. */\n depth?: number;\n /** Bezel color. Defaults to near-black. */\n bezel?: string;\n /** Screen surface — color, paint, or widget. */\n screen: SurfaceContent;\n /** Optional kickstand height — when set, the monitor sits on a base. */\n standHeight?: number;\n}\n\nexport interface MonitorResult {\n root: Mesh;\n body: Mesh;\n screen: Mesh;\n stand?: Mesh;\n}\n\nexport function createMonitor(opts: MonitorOpts): MonitorResult {\n const name = opts.name ?? \"monitor\";\n const depth = opts.depth ?? 0.18;\n const bezelColor = opts.bezel ?? \"#0b0f17\";\n\n const root = new Mesh(`${name}-root`, opts.scene);\n\n // Body — extruded bezel\n const body = MeshBuilder.CreateBox(`${name}-body`, {\n width: opts.width,\n height: opts.height,\n depth,\n }, opts.scene);\n const bodyMat = new StandardMaterial(`${name}-body-mat`, opts.scene);\n bodyMat.diffuseColor = Color3.FromHexString(bezelColor);\n bodyMat.specularColor = new Color3(0.08, 0.08, 0.08);\n body.material = bodyMat;\n body.parent = root;\n\n // Screen face — sits flush at the front (+Z) face of the bezel.\n // Babylon's default plane has its visible face on -Z (per the docs:\n // \"default plane faces the negative Z direction\"). The default\n // ArcRotateCamera sits at +Z, so we need the screen's visible face to\n // point +Z. `BACKSIDE` orientation flips visibility from -Z to +Z without\n // rotating the plane (which would also mirror the texture). The screen\n // sits 0.001 in front of the body's +Z face so it's not occluded.\n const screenInset = 0.04;\n const screenW = opts.width - screenInset * 2;\n const screenH = opts.height - screenInset * 2;\n // Use a very thin extruded card for the screen face. This delegates to\n // createBuilding's per-face Box atlas, which handles UV orientation\n // correctly out of the box (a flat Plane's UVs render mirrored from the\n // default camera angle without orientation gymnastics).\n const screen = createCard3D({\n scene: opts.scene,\n name: `${name}-screen`,\n width: screenW,\n height: screenH,\n depth: 0.01,\n front: opts.screen,\n edge: { type: \"color\", color: bezelColor },\n });\n screen.position = new Vector3(0, 0, depth / 2 + 0.005);\n screen.parent = root;\n\n let stand: Mesh | undefined;\n if (opts.standHeight && opts.standHeight > 0) {\n stand = MeshBuilder.CreateBox(`${name}-stand`, {\n width: opts.width * 0.3,\n height: opts.standHeight,\n depth: depth * 1.5,\n }, opts.scene);\n stand.position = new Vector3(0, -opts.height / 2 - opts.standHeight / 2, 0);\n stand.material = bodyMat;\n stand.parent = root;\n }\n\n return { root, body, screen, stand };\n}\n\n/* ------------------------------------------------------------------ */\n/* Decal — project a 2D pattern onto another mesh's surface */\n/* ------------------------------------------------------------------ */\n\nexport interface DecalOpts {\n scene: Scene;\n name?: string;\n /** The mesh to project the decal onto. */\n target: Mesh;\n /** World-space position the projector sits at. */\n position: Vector3;\n /** Direction the projector points. Defaults to -Z. */\n normal?: Vector3;\n /** Size of the decal box. */\n size: { width: number; height: number; depth?: number };\n /** Rotation around the projection axis (radians). */\n angle?: number;\n /** Surface to project. */\n surface: SurfaceContent;\n}\n\n/**\n * Projects a SurfaceContent onto `target`'s geometry. The decal conforms to\n * the underlying surface — useful for signage on curved walls, logos on\n * irregular terrain, graffiti on cylindrical surfaces, etc.\n */\nexport function createDecal(opts: DecalOpts): Mesh {\n const name = opts.name ?? \"decal\";\n const normal = opts.normal ?? new Vector3(0, 0, -1);\n const size = new Vector3(opts.size.width, opts.size.height, opts.size.depth ?? 1);\n\n const decal = MeshBuilder.CreateDecal(name, opts.target, {\n position: opts.position,\n normal,\n size,\n angle: opts.angle,\n });\n\n const { material } = buildSurface(opts.scene, name, opts.surface, {\n worldWidth: opts.size.width,\n worldHeight: opts.size.height,\n });\n // Decals need transparency to show the underlying mesh through their borders.\n if (\"hasAlpha\" in (material as StandardMaterial)) {\n (material as StandardMaterial).useAlphaFromDiffuseTexture = true;\n }\n decal.material = material;\n return decal;\n}\n\n/* ------------------------------------------------------------------ */\n/* Helper: paint a widget onto a fresh DynamicTexture (escape hatch) */\n/* ------------------------------------------------------------------ */\n\nexport function createWidgetTexture(\n scene: Scene,\n name: string,\n widget: WidgetSpec,\n pixelWidth: number,\n pixelHeight: number,\n selected = false\n): DynamicTexture {\n const tex = new DynamicTexture(name, { width: pixelWidth * TEX_SCALE, height: pixelHeight * TEX_SCALE }, scene, true);\n tex.vScale = -1;\n tex.vOffset = 1;\n tex.hasAlpha = true;\n const ctx = tex.getContext() as CanvasRenderingContext2D;\n ctx.scale(TEX_SCALE, TEX_SCALE);\n paintWidget(ctx, widget, pixelWidth, pixelHeight, selected);\n tex.update(false);\n return tex;\n}\n","/**\n * Layout helpers — map 2D scene-node positions onto 3D arrangements.\n *\n * All layout functions take the same shape: a SceneNode, the Mesh that was\n * built for it, the scene's bounds, and layout-specific options. They mutate\n * `mesh.position` (and sometimes `mesh.rotation`) in place.\n *\n * Pair with `sceneBounds(scene)` from `./babylon` to compute the bounds.\n */\nimport { Vector3, type Mesh } from \"@babylonjs/core\";\nimport type { SceneNode } from \"@particle-academy/fancy-3d\";\n\ninterface Bounds {\n minX: number;\n maxX: number;\n minY: number;\n maxY: number;\n}\n\nfunction sizeOf(node: SceneNode): { w: number; h: number } {\n return { w: node.size?.w ?? 200, h: node.size?.h ?? 120 };\n}\n\nfunction normalizedCenter(node: SceneNode, bounds: Bounds) {\n const { w, h } = sizeOf(node);\n const cx = (node.position.x + w / 2 - bounds.minX) / Math.max(1, bounds.maxX - bounds.minX);\n const cy = (node.position.y + h / 2 - bounds.minY) / Math.max(1, bounds.maxY - bounds.minY);\n return { cx, cy };\n}\n\n/* ------------------------------------------------------------------ */\n/* Grid — flat XY grid in front of the camera */\n/* ------------------------------------------------------------------ */\n\nexport interface GridLayoutOpts {\n /** Pixel-to-world unit ratio. Defaults to 1/120. */\n scale?: number;\n /** World-space center of the grid. Defaults to (0, 0, 0). */\n origin?: Vector3;\n}\n\n/**\n * Direct 2D-to-3D mapping. DOM (x, y) becomes world (x, -y, 0) — the most\n * literal layout. Useful when you want the scene to look identical to its\n * DOM rendering, just rendered as floating panels.\n */\nexport function placeOnGrid(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: GridLayoutOpts = {}) {\n const scale = opts.scale ?? 1 / 120;\n const origin = opts.origin ?? new Vector3(0, 0, 0);\n const { w, h } = sizeOf(node);\n const cx = node.position.x + w / 2 - (bounds.minX + bounds.maxX) / 2;\n const cy = node.position.y + h / 2 - (bounds.minY + bounds.maxY) / 2;\n mesh.position = new Vector3(origin.x + cx * scale, origin.y - cy * scale, origin.z);\n}\n\n/* ------------------------------------------------------------------ */\n/* Wall — gallery layout against a vertical plane */\n/* ------------------------------------------------------------------ */\n\nexport interface WallLayoutOpts {\n /** Distance from origin along the wall's normal. Defaults to 0. */\n z?: number;\n /** Spread along world X. Defaults to 10 world units. */\n spreadX?: number;\n /** Spread along world Y. Defaults to 4 world units. */\n spreadY?: number;\n /** Wall vertical center. Defaults to 1.5 world units. */\n centerY?: number;\n}\n\n/**\n * Hangs panels on a flat virtual wall, centered on the world origin and\n * facing +Z.\n */\nexport function placeOnWall(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: WallLayoutOpts = {}) {\n const spreadX = opts.spreadX ?? 10;\n const spreadY = opts.spreadY ?? 4;\n const centerY = opts.centerY ?? 1.5;\n const z = opts.z ?? 0;\n const { cx, cy } = normalizedCenter(node, bounds);\n mesh.position = new Vector3((cx - 0.5) * spreadX, centerY + (0.5 - cy) * spreadY, z);\n mesh.rotation.y = 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Arc — partial cylinder (alias of placeOnCylinder with friendlier name) */\n/* ------------------------------------------------------------------ */\n\nexport interface ArcLayoutOpts {\n /** Cylinder radius. Defaults to 6. */\n radius?: number;\n /** Total arc spanned in radians. Defaults to π * 0.9 (~160°). */\n arc?: number;\n /** Vertical extent. Defaults to 6. */\n height?: number;\n /** Base Y of the arc. Defaults to 0. */\n baseY?: number;\n}\n\n/**\n * Wraps DOM x onto an angle around a vertical axis; DOM y becomes height.\n * Same math as `placeOnCylinder` from `./babylon`, exposed here with a\n * clearer name and consistent options shape.\n */\nexport function placeOnArc(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: ArcLayoutOpts = {}) {\n const radius = opts.radius ?? 6;\n const arc = opts.arc ?? Math.PI * 0.9;\n const height = opts.height ?? 6;\n const baseY = opts.baseY ?? 0;\n const { cx, cy } = normalizedCenter(node, bounds);\n const angle = (cx - 0.5) * arc;\n mesh.position = new Vector3(Math.sin(angle) * radius, baseY + (0.5 - cy) * height, Math.cos(angle) * radius);\n mesh.rotation.y = angle;\n}\n\n/* ------------------------------------------------------------------ */\n/* Path — distribute along a sequence of waypoints */\n/* ------------------------------------------------------------------ */\n\nexport interface PathLayoutOpts {\n /** Waypoints along the path. */\n waypoints: Vector3[];\n /** Should each mesh face the next waypoint? Defaults to true. */\n faceForward?: boolean;\n /** Distribute by node index (0..n-1) instead of normalized x. Defaults to false. */\n byIndex?: boolean;\n /** Total node count when using `byIndex`. Defaults to inferred from bounds. */\n nodeCount?: number;\n}\n\nfunction lerpPath(waypoints: Vector3[], t: number): { pos: Vector3; tangent: Vector3 } {\n if (waypoints.length === 0) return { pos: new Vector3(0, 0, 0), tangent: new Vector3(0, 0, 1) };\n if (waypoints.length === 1) return { pos: waypoints[0].clone(), tangent: new Vector3(0, 0, 1) };\n const segments = waypoints.length - 1;\n const scaled = Math.max(0, Math.min(1, t)) * segments;\n const i = Math.min(segments - 1, Math.floor(scaled));\n const local = scaled - i;\n const a = waypoints[i];\n const b = waypoints[i + 1];\n const pos = Vector3.Lerp(a, b, local);\n const tangent = b.subtract(a).normalize();\n return { pos, tangent };\n}\n\n/**\n * Distributes nodes along a polyline. Each mesh sits on the path; if\n * `faceForward` is true, each mesh's +Y rotation aligns with the path\n * tangent.\n */\nexport function placeOnPath(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: PathLayoutOpts) {\n const faceForward = opts.faceForward ?? true;\n let t: number;\n if (opts.byIndex) {\n const total = opts.nodeCount ?? Math.max(1, bounds.maxX - bounds.minX);\n const idx = node.position.x;\n t = total > 1 ? idx / (total - 1) : 0.5;\n } else {\n const { cx } = normalizedCenter(node, bounds);\n t = cx;\n }\n const { pos, tangent } = lerpPath(opts.waypoints, t);\n mesh.position = pos;\n if (faceForward) {\n mesh.rotation.y = Math.atan2(tangent.x, tangent.z);\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Sphere — wrap nodes onto a sphere surface */\n/* ------------------------------------------------------------------ */\n\nexport interface SphereLayoutOpts {\n /** Sphere radius. Defaults to 5. */\n radius?: number;\n /** World-space center. Defaults to (0, 0, 0). */\n center?: Vector3;\n /** Latitude span in radians (0..π). Defaults to π * 0.7 (avoids poles). */\n latSpan?: number;\n /** Longitude span in radians (0..2π). Defaults to 2π. */\n lonSpan?: number;\n}\n\n/**\n * DOM x → longitude, DOM y → latitude. Useful for \"globe of widgets\" or\n * any kind of spherical immersive layout.\n */\nexport function placeOnSphere(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: SphereLayoutOpts = {}) {\n const radius = opts.radius ?? 5;\n const center = opts.center ?? new Vector3(0, 0, 0);\n const latSpan = opts.latSpan ?? Math.PI * 0.7;\n const lonSpan = opts.lonSpan ?? Math.PI * 2;\n const { cx, cy } = normalizedCenter(node, bounds);\n const lon = (cx - 0.5) * lonSpan;\n const lat = (0.5 - cy) * latSpan;\n const r = radius;\n const x = r * Math.cos(lat) * Math.sin(lon);\n const y = r * Math.sin(lat);\n const z = r * Math.cos(lat) * Math.cos(lon);\n mesh.position = new Vector3(center.x + x, center.y + y, center.z + z);\n mesh.rotation.y = lon;\n}\n","/**\n * BabylonJS adapter for `@particle-academy/fancy-3d`.\n *\n * Each widget kind paints onto a 2D HTMLCanvasElement that is uploaded to a\n * Babylon `DynamicTexture`, which is then applied to a plane mesh sized to\n * the widget's pixel rect. Edges become line meshes between node centers.\n *\n * `@babylonjs/core` is an OPTIONAL peer dependency — only consumers building\n * 3D scenes need to install it.\n */\nimport {\n Color3,\n DynamicTexture,\n MeshBuilder,\n StandardMaterial,\n Vector3,\n type Mesh,\n type Scene as BJScene,\n} from \"@babylonjs/core\";\nimport type {\n AdapterContext,\n Scene,\n SceneNode,\n WidgetAdapter,\n WidgetSpec,\n} from \"@particle-academy/fancy-3d\";\n\nimport { TEX_SCALE, paintWidget } from \"./painters\";\nexport { TEX_SCALE, paintWidget } from \"./painters\";\n\nconst WORLD_SCALE = 1 / 180; // pixels → world units\n\n\n/* ------------------------------------------------------------------ */\n/* Adapter */\n/* ------------------------------------------------------------------ */\n\nexport interface BabylonAdapterDeps {\n scene3D: BJScene;\n /** Pixel size for the widget (the scene node's `size` field). */\n sizeFor(spec: WidgetSpec): { w: number; h: number };\n}\n\nexport function createBabylonAdapter(deps: BabylonAdapterDeps): WidgetAdapter<Mesh> {\n return {\n render(spec: WidgetSpec, ctx: AdapterContext): Mesh {\n const { w, h } = deps.sizeFor(spec);\n const tex = new DynamicTexture(`tex-${ctx.nodeId}`, { width: w * TEX_SCALE, height: h * TEX_SCALE }, deps.scene3D, true);\n tex.hasAlpha = true;\n // Babylon plane UVs run V=0 at the bottom; canvas Y runs top-to-bottom.\n // Without this flip, painted content appears upside down on the mesh.\n tex.vScale = -1;\n tex.vOffset = 1;\n const c = tex.getContext() as CanvasRenderingContext2D;\n c.scale(TEX_SCALE, TEX_SCALE);\n paintWidget(c, spec, w, h, ctx.selected);\n tex.update(false);\n\n const mat = new StandardMaterial(`mat-${ctx.nodeId}`, deps.scene3D);\n mat.diffuseTexture = tex;\n mat.emissiveTexture = tex;\n mat.emissiveColor = new Color3(1, 1, 1);\n mat.disableLighting = false;\n mat.useAlphaFromDiffuseTexture = true;\n\n const plane = MeshBuilder.CreatePlane(`node-${ctx.nodeId}`, { width: w * WORLD_SCALE, height: h * WORLD_SCALE }, deps.scene3D);\n plane.material = mat;\n plane.metadata = { nodeId: ctx.nodeId, kind: spec.kind };\n return plane;\n },\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Layout helpers */\n/* ------------------------------------------------------------------ */\n\n/**\n * \"3D Desktop\" layout — wraps the scene's 2D positions onto a partial\n * cylinder facing the camera. DOM `x` becomes angle around the cylinder,\n * DOM `y` becomes height.\n */\nexport function placeOnCylinder(node: SceneNode, mesh: Mesh, bounds: { minX: number; maxX: number; minY: number; maxY: number }, opts: { radius?: number; arc?: number } = {}) {\n const radius = opts.radius ?? 6;\n const arc = opts.arc ?? Math.PI * 0.9; // ~160°\n const rangeX = bounds.maxX - bounds.minX || 1;\n const rangeY = bounds.maxY - bounds.minY || 1;\n const cx = (node.position.x + (node.size?.w ?? 200) / 2 - bounds.minX) / rangeX;\n const cy = (node.position.y + (node.size?.h ?? 120) / 2 - bounds.minY) / rangeY;\n const angle = (cx - 0.5) * arc;\n const height = (0.5 - cy) * 6;\n mesh.position = new Vector3(Math.sin(angle) * radius, height, Math.cos(angle) * radius);\n // Rotate the plane around Y so its FRONT face (default plane normal: +Z)\n // points outward — toward the orbiting camera. Babylon's `lookAt` aimed\n // the back of the plane at the target, which read as mirrored text.\n mesh.rotation = new Vector3(0, angle, 0);\n}\n\nexport function sceneBounds(scene: Scene) {\n const xs = scene.nodes.map((n) => n.position.x);\n const ys = scene.nodes.map((n) => n.position.y);\n const xe = scene.nodes.map((n) => n.position.x + (n.size?.w ?? 200));\n const ye = scene.nodes.map((n) => n.position.y + (n.size?.h ?? 120));\n return {\n minX: Math.min(...xs),\n maxX: Math.max(...xe),\n minY: Math.min(...ys),\n maxY: Math.max(...ye),\n };\n}\n\n\nexport * from \"./primitives\";\n\nexport * from \"./layouts\";\n"]}
@@ -0,0 +1,323 @@
1
+ import { Scene, Mesh, Vector3, DynamicTexture } from '@babylonjs/core';
2
+ import { WidgetSpec, SceneNode, WidgetAdapter, Scene as Scene$1 } from '@particle-academy/fancy-3d';
3
+
4
+ declare const TEX_SCALE = 2;
5
+ declare function paintWidget(ctx: CanvasRenderingContext2D, spec: WidgetSpec, w: number, h: number, selected: boolean): void;
6
+
7
+ /**
8
+ * 3D shape primitives for `@particle-academy/fancy-3d`.
9
+ *
10
+ * A primitive is a Babylon mesh that can host UI content on its surface —
11
+ * either a flat color, a freeform 2D paint callback, or a `WidgetSpec`
12
+ * rendered through the same painters as the Babylon adapter.
13
+ *
14
+ * Every primitive returns a `Mesh`, ready to position in your scene.
15
+ */
16
+
17
+ type PaintFn = (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
18
+ type SurfaceContent = {
19
+ type: "color";
20
+ color: string;
21
+ } | {
22
+ type: "paint";
23
+ paint: PaintFn;
24
+ pixelWidth?: number;
25
+ pixelHeight?: number;
26
+ transparent?: boolean;
27
+ } | {
28
+ type: "widget";
29
+ widget: WidgetSpec;
30
+ pixelWidth?: number;
31
+ pixelHeight?: number;
32
+ selected?: boolean;
33
+ };
34
+ interface PanelOpts {
35
+ scene: Scene;
36
+ name?: string;
37
+ width: number;
38
+ height: number;
39
+ surface: SurfaceContent;
40
+ /** Babylon sideOrientation. Use `Mesh.DOUBLESIDE` for panels you want visible
41
+ * from both directions (e.g. self-luminous screens). Default is FRONTSIDE. */
42
+ sideOrientation?: number;
43
+ }
44
+ declare function createPanel(opts: PanelOpts): Mesh;
45
+ interface BillboardOpts extends PanelOpts {
46
+ /** When true, mesh.billboardMode = ALL — always faces the camera. */
47
+ faceCamera?: boolean;
48
+ }
49
+ declare function createBillboard(opts: BillboardOpts): Mesh;
50
+ interface BuildingOpts {
51
+ scene: Scene;
52
+ name?: string;
53
+ width: number;
54
+ height: number;
55
+ depth: number;
56
+ /** Surface applied to all 6 faces (cheap path). */
57
+ surface?: SurfaceContent;
58
+ /** Per-face surfaces; missing faces use `surface` or a default grey. */
59
+ faces?: Partial<Record<BoxFace, SurfaceContent>>;
60
+ }
61
+ /** Babylon box face indices (CreateBox): 0=front (-Z), 1=back (+Z), 2=right (+X), 3=left (-X), 4=top (+Y), 5=bottom (-Y). */
62
+ type BoxFace = "front" | "back" | "right" | "left" | "top" | "bottom";
63
+ declare function createBuilding(opts: BuildingOpts): Mesh;
64
+ interface PillarOpts {
65
+ scene: Scene;
66
+ name?: string;
67
+ thickness: number;
68
+ height: number;
69
+ surface?: SurfaceContent;
70
+ }
71
+ declare function createPillar(opts: PillarOpts): Mesh;
72
+ interface CylinderOpts {
73
+ scene: Scene;
74
+ name?: string;
75
+ radius: number;
76
+ height: number;
77
+ surface: SurfaceContent;
78
+ tessellation?: number;
79
+ }
80
+ declare function createCylinder(opts: CylinderOpts): Mesh;
81
+ interface CurvedPanelOpts {
82
+ scene: Scene;
83
+ name?: string;
84
+ width: number;
85
+ height: number;
86
+ arc: number;
87
+ surface: SurfaceContent;
88
+ tessellation?: number;
89
+ }
90
+ declare function createCurvedPanel(opts: CurvedPanelOpts): Mesh;
91
+ interface SphereOpts {
92
+ scene: Scene;
93
+ name?: string;
94
+ diameter: number;
95
+ surface: SurfaceContent;
96
+ segments?: number;
97
+ }
98
+ declare function createSphere(opts: SphereOpts): Mesh;
99
+ interface DiscOpts {
100
+ scene: Scene;
101
+ name?: string;
102
+ radius: number;
103
+ surface: SurfaceContent;
104
+ tessellation?: number;
105
+ }
106
+ declare function createDisc(opts: DiscOpts): Mesh;
107
+ interface Card3DOpts {
108
+ scene: Scene;
109
+ name?: string;
110
+ width: number;
111
+ height: number;
112
+ /** Extrusion depth. Defaults to a thin 0.06 — like real foam-board signage. */
113
+ depth?: number;
114
+ /** Surface for the front face (the visible UI). */
115
+ front: SurfaceContent;
116
+ /** Surface for the side and back faces. Defaults to a dark color. */
117
+ edge?: SurfaceContent;
118
+ }
119
+ declare function createCard3D(opts: Card3DOpts): Mesh;
120
+ interface SignOpts {
121
+ scene: Scene;
122
+ name?: string;
123
+ /** Panel dimensions. */
124
+ width: number;
125
+ height: number;
126
+ /** How tall the post is (from ground to bottom of panel). */
127
+ postHeight?: number;
128
+ /** Post thickness (square cross-section). */
129
+ postThickness?: number;
130
+ /** Panel surface (color, paint, or widget). */
131
+ surface: SurfaceContent;
132
+ /** Post color. */
133
+ postColor?: string;
134
+ }
135
+ interface SignResult {
136
+ /** Group containing the panel + post, parented at ground level. */
137
+ root: Mesh;
138
+ panel: Mesh;
139
+ post: Mesh;
140
+ }
141
+ declare function createSign(opts: SignOpts): SignResult;
142
+ interface MonitorOpts {
143
+ scene: Scene;
144
+ name?: string;
145
+ width: number;
146
+ height: number;
147
+ /** Front-to-back depth of the display chassis. Defaults to 0.18. */
148
+ depth?: number;
149
+ /** Bezel color. Defaults to near-black. */
150
+ bezel?: string;
151
+ /** Screen surface — color, paint, or widget. */
152
+ screen: SurfaceContent;
153
+ /** Optional kickstand height — when set, the monitor sits on a base. */
154
+ standHeight?: number;
155
+ }
156
+ interface MonitorResult {
157
+ root: Mesh;
158
+ body: Mesh;
159
+ screen: Mesh;
160
+ stand?: Mesh;
161
+ }
162
+ declare function createMonitor(opts: MonitorOpts): MonitorResult;
163
+ interface DecalOpts {
164
+ scene: Scene;
165
+ name?: string;
166
+ /** The mesh to project the decal onto. */
167
+ target: Mesh;
168
+ /** World-space position the projector sits at. */
169
+ position: Vector3;
170
+ /** Direction the projector points. Defaults to -Z. */
171
+ normal?: Vector3;
172
+ /** Size of the decal box. */
173
+ size: {
174
+ width: number;
175
+ height: number;
176
+ depth?: number;
177
+ };
178
+ /** Rotation around the projection axis (radians). */
179
+ angle?: number;
180
+ /** Surface to project. */
181
+ surface: SurfaceContent;
182
+ }
183
+ /**
184
+ * Projects a SurfaceContent onto `target`'s geometry. The decal conforms to
185
+ * the underlying surface — useful for signage on curved walls, logos on
186
+ * irregular terrain, graffiti on cylindrical surfaces, etc.
187
+ */
188
+ declare function createDecal(opts: DecalOpts): Mesh;
189
+ declare function createWidgetTexture(scene: Scene, name: string, widget: WidgetSpec, pixelWidth: number, pixelHeight: number, selected?: boolean): DynamicTexture;
190
+
191
+ /**
192
+ * Layout helpers — map 2D scene-node positions onto 3D arrangements.
193
+ *
194
+ * All layout functions take the same shape: a SceneNode, the Mesh that was
195
+ * built for it, the scene's bounds, and layout-specific options. They mutate
196
+ * `mesh.position` (and sometimes `mesh.rotation`) in place.
197
+ *
198
+ * Pair with `sceneBounds(scene)` from `./babylon` to compute the bounds.
199
+ */
200
+
201
+ interface Bounds {
202
+ minX: number;
203
+ maxX: number;
204
+ minY: number;
205
+ maxY: number;
206
+ }
207
+ interface GridLayoutOpts {
208
+ /** Pixel-to-world unit ratio. Defaults to 1/120. */
209
+ scale?: number;
210
+ /** World-space center of the grid. Defaults to (0, 0, 0). */
211
+ origin?: Vector3;
212
+ }
213
+ /**
214
+ * Direct 2D-to-3D mapping. DOM (x, y) becomes world (x, -y, 0) — the most
215
+ * literal layout. Useful when you want the scene to look identical to its
216
+ * DOM rendering, just rendered as floating panels.
217
+ */
218
+ declare function placeOnGrid(node: SceneNode, mesh: Mesh, bounds: Bounds, opts?: GridLayoutOpts): void;
219
+ interface WallLayoutOpts {
220
+ /** Distance from origin along the wall's normal. Defaults to 0. */
221
+ z?: number;
222
+ /** Spread along world X. Defaults to 10 world units. */
223
+ spreadX?: number;
224
+ /** Spread along world Y. Defaults to 4 world units. */
225
+ spreadY?: number;
226
+ /** Wall vertical center. Defaults to 1.5 world units. */
227
+ centerY?: number;
228
+ }
229
+ /**
230
+ * Hangs panels on a flat virtual wall, centered on the world origin and
231
+ * facing +Z.
232
+ */
233
+ declare function placeOnWall(node: SceneNode, mesh: Mesh, bounds: Bounds, opts?: WallLayoutOpts): void;
234
+ interface ArcLayoutOpts {
235
+ /** Cylinder radius. Defaults to 6. */
236
+ radius?: number;
237
+ /** Total arc spanned in radians. Defaults to π * 0.9 (~160°). */
238
+ arc?: number;
239
+ /** Vertical extent. Defaults to 6. */
240
+ height?: number;
241
+ /** Base Y of the arc. Defaults to 0. */
242
+ baseY?: number;
243
+ }
244
+ /**
245
+ * Wraps DOM x onto an angle around a vertical axis; DOM y becomes height.
246
+ * Same math as `placeOnCylinder` from `./babylon`, exposed here with a
247
+ * clearer name and consistent options shape.
248
+ */
249
+ declare function placeOnArc(node: SceneNode, mesh: Mesh, bounds: Bounds, opts?: ArcLayoutOpts): void;
250
+ interface PathLayoutOpts {
251
+ /** Waypoints along the path. */
252
+ waypoints: Vector3[];
253
+ /** Should each mesh face the next waypoint? Defaults to true. */
254
+ faceForward?: boolean;
255
+ /** Distribute by node index (0..n-1) instead of normalized x. Defaults to false. */
256
+ byIndex?: boolean;
257
+ /** Total node count when using `byIndex`. Defaults to inferred from bounds. */
258
+ nodeCount?: number;
259
+ }
260
+ /**
261
+ * Distributes nodes along a polyline. Each mesh sits on the path; if
262
+ * `faceForward` is true, each mesh's +Y rotation aligns with the path
263
+ * tangent.
264
+ */
265
+ declare function placeOnPath(node: SceneNode, mesh: Mesh, bounds: Bounds, opts: PathLayoutOpts): void;
266
+ interface SphereLayoutOpts {
267
+ /** Sphere radius. Defaults to 5. */
268
+ radius?: number;
269
+ /** World-space center. Defaults to (0, 0, 0). */
270
+ center?: Vector3;
271
+ /** Latitude span in radians (0..π). Defaults to π * 0.7 (avoids poles). */
272
+ latSpan?: number;
273
+ /** Longitude span in radians (0..2π). Defaults to 2π. */
274
+ lonSpan?: number;
275
+ }
276
+ /**
277
+ * DOM x → longitude, DOM y → latitude. Useful for "globe of widgets" or
278
+ * any kind of spherical immersive layout.
279
+ */
280
+ declare function placeOnSphere(node: SceneNode, mesh: Mesh, bounds: Bounds, opts?: SphereLayoutOpts): void;
281
+
282
+ /**
283
+ * BabylonJS adapter for `@particle-academy/fancy-3d`.
284
+ *
285
+ * Each widget kind paints onto a 2D HTMLCanvasElement that is uploaded to a
286
+ * Babylon `DynamicTexture`, which is then applied to a plane mesh sized to
287
+ * the widget's pixel rect. Edges become line meshes between node centers.
288
+ *
289
+ * `@babylonjs/core` is an OPTIONAL peer dependency — only consumers building
290
+ * 3D scenes need to install it.
291
+ */
292
+
293
+ interface BabylonAdapterDeps {
294
+ scene3D: Scene;
295
+ /** Pixel size for the widget (the scene node's `size` field). */
296
+ sizeFor(spec: WidgetSpec): {
297
+ w: number;
298
+ h: number;
299
+ };
300
+ }
301
+ declare function createBabylonAdapter(deps: BabylonAdapterDeps): WidgetAdapter<Mesh>;
302
+ /**
303
+ * "3D Desktop" layout — wraps the scene's 2D positions onto a partial
304
+ * cylinder facing the camera. DOM `x` becomes angle around the cylinder,
305
+ * DOM `y` becomes height.
306
+ */
307
+ declare function placeOnCylinder(node: SceneNode, mesh: Mesh, bounds: {
308
+ minX: number;
309
+ maxX: number;
310
+ minY: number;
311
+ maxY: number;
312
+ }, opts?: {
313
+ radius?: number;
314
+ arc?: number;
315
+ }): void;
316
+ declare function sceneBounds(scene: Scene$1): {
317
+ minX: number;
318
+ maxX: number;
319
+ minY: number;
320
+ maxY: number;
321
+ };
322
+
323
+ export { type ArcLayoutOpts, type BabylonAdapterDeps, type BillboardOpts, type BoxFace, type BuildingOpts, type Card3DOpts, type CurvedPanelOpts, type CylinderOpts, type DecalOpts, type DiscOpts, type GridLayoutOpts, type MonitorOpts, type MonitorResult, type PaintFn, type PanelOpts, type PathLayoutOpts, type PillarOpts, type SignOpts, type SignResult, type SphereLayoutOpts, type SphereOpts, type SurfaceContent, TEX_SCALE, type WallLayoutOpts, createBabylonAdapter, createBillboard, createBuilding, createCard3D, createCurvedPanel, createCylinder, createDecal, createDisc, createMonitor, createPanel, createPillar, createSign, createSphere, createWidgetTexture, paintWidget, placeOnArc, placeOnCylinder, placeOnGrid, placeOnPath, placeOnSphere, placeOnWall, sceneBounds };