@sonicjs-cms/core 2.3.14 → 2.3.15

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.
Files changed (41) hide show
  1. package/dist/{chunk-T4XRPNX2.js → chunk-4M2UOUXV.js} +8 -8
  2. package/dist/{chunk-T4XRPNX2.js.map → chunk-4M2UOUXV.js.map} +1 -1
  3. package/dist/{chunk-D4PJFFOV.cjs → chunk-5OLN5JO3.cjs} +90 -90
  4. package/dist/{chunk-D4PJFFOV.cjs.map → chunk-5OLN5JO3.cjs.map} +1 -1
  5. package/dist/{chunk-ETS5XSAG.cjs → chunk-63LV4YVI.cjs} +2 -2
  6. package/dist/{chunk-ETS5XSAG.cjs.map → chunk-63LV4YVI.cjs.map} +1 -1
  7. package/dist/{chunk-SKPETEM5.js → chunk-67SKO5RQ.js} +3 -3
  8. package/dist/{chunk-SKPETEM5.js.map → chunk-67SKO5RQ.js.map} +1 -1
  9. package/dist/{chunk-CAJOP354.js → chunk-72I2MOSH.js} +2 -2
  10. package/dist/{chunk-CAJOP354.js.map → chunk-72I2MOSH.js.map} +1 -1
  11. package/dist/{chunk-H34L445M.js → chunk-A27RBGBA.js} +3 -3
  12. package/dist/{chunk-H34L445M.js.map → chunk-A27RBGBA.js.map} +1 -1
  13. package/dist/{chunk-SZE3XVET.cjs → chunk-H2X4BFCW.cjs} +3 -3
  14. package/dist/{chunk-SZE3XVET.cjs.map → chunk-H2X4BFCW.cjs.map} +1 -1
  15. package/dist/{chunk-XWPGIFS7.cjs → chunk-QG3YQKL4.cjs} +4 -4
  16. package/dist/{chunk-XWPGIFS7.cjs.map → chunk-QG3YQKL4.cjs.map} +1 -1
  17. package/dist/index.cjs +108 -77
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +38 -7
  22. package/dist/index.js.map +1 -1
  23. package/dist/middleware.cjs +23 -23
  24. package/dist/middleware.js +2 -2
  25. package/dist/migrations-H3Q5FZGZ.js +4 -0
  26. package/dist/{migrations-WF6VIVU2.js.map → migrations-H3Q5FZGZ.js.map} +1 -1
  27. package/dist/migrations-VN5VTX3C.cjs +13 -0
  28. package/dist/{migrations-3A53GREK.cjs.map → migrations-VN5VTX3C.cjs.map} +1 -1
  29. package/dist/{plugin-manifest-BCMx9CAq.d.cts → plugin-manifest-Dpy8wxIB.d.cts} +2 -2
  30. package/dist/{plugin-manifest-BCMx9CAq.d.ts → plugin-manifest-Dpy8wxIB.d.ts} +2 -2
  31. package/dist/routes.cjs +24 -24
  32. package/dist/routes.js +4 -4
  33. package/dist/services.cjs +2 -2
  34. package/dist/services.js +1 -1
  35. package/dist/types.d.cts +1 -1
  36. package/dist/types.d.ts +1 -1
  37. package/dist/utils.cjs +11 -11
  38. package/dist/utils.js +1 -1
  39. package/package.json +1 -1
  40. package/dist/migrations-3A53GREK.cjs +0 -13
  41. package/dist/migrations-WF6VIVU2.js +0 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugins/core-plugins/database-tools-plugin/services/database-service.ts","../src/templates/pages/admin-database-table.template.ts","../src/plugins/core-plugins/database-tools-plugin/admin-routes.ts","../src/plugins/core-plugins/email-plugin/index.ts","../src/plugins/core-plugins/otp-login-plugin/otp-service.ts","../src/plugins/core-plugins/otp-login-plugin/email-templates.ts","../src/plugins/core-plugins/otp-login-plugin/index.ts","../src/plugins/available/magic-link-auth/index.ts","../src/app.ts","../src/db/index.ts","../src/index.ts"],"names":["init_admin_layout_catalyst_template","escapeHtml","renderAdminLayoutCatalyst","router","Hono","requireAuth","PluginBuilder","html","renderAdminLayout","z","adminLayoutV2","emailPlugin","AuthManager","getCoreVersion","metricsMiddleware","bootstrapMiddleware","api_default","api_media_default","api_system_default","admin_api_default","adminCollectionsRoutes","adminSettingsRoutes","admin_content_default","adminMediaRoutes","adminPluginRoutes","adminLogsRoutes","userRoutes","auth_default","test_cleanup_default","d1","drizzle","schema_exports","package_default"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyBO,IAAM,uBAAN,MAA2B;AAAA,EAChC,YAAoB,EAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA,EAAiB;AAAA;AAAA;AAAA;AAAA,EAKrC,MAAM,gBAAA,GAA2C;AAC/C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,EAAU;AACpC,IAAA,MAAM,KAAA,GAAuB;AAAA,MAC3B,QAAQ,EAAC;AAAA,MACT,SAAA,EAAW;AAAA,KACb;AAEA,IAAA,KAAA,MAAW,aAAa,MAAA,EAAQ;AAC9B,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAE,CAAA,CAAE,KAAA,EAAM;AACzF,QAAA,MAAM,QAAA,GAAY,QAAQ,KAAA,IAAoB,CAAA;AAE9C,QAAA,KAAA,CAAM,OAAO,IAAA,CAAK;AAAA,UAChB,IAAA,EAAM,SAAA;AAAA,UACN;AAAA,SACD,CAAA;AACD,QAAA,KAAA,CAAM,SAAA,IAAa,QAAA;AAAA,MACrB,SAAS,KAAA,EAAO;AAEd,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,MACnE;AAAA,IACF;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,SAAA,GAA+B;AAC3C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAKpC,EAAE,GAAA,EAAI;AAEP,IAAA,OAAO,MAAA,CAAO,SAAS,GAAA,CAAI,CAAC,QAAa,GAAA,CAAI,IAAI,KAAK,EAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,UAAA,EAA6C;AACjE,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,IAAI,kBAAA,GAAqB,KAAA;AAEzB,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA;AAAA,QAC9B;AAAA,OACF,CAAE,IAAA,CAAK,UAAA,EAAY,OAAO,EAAE,KAAA,EAAM;AAElC,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,OAAA,EAAS,uDAAA;AAAA,UACT,eAAe,EAAC;AAAA,UAChB,kBAAA,EAAoB,KAAA;AAAA,UACpB,MAAA,EAAQ,CAAC,sBAAsB;AAAA,SACjC;AAAA,MACF;AAGA,MAAA,MAAM,gBAAA,GAAmB;AAAA,QACvB,SAAA;AAAA,QACA,kBAAA;AAAA,QACA,yBAAA;AAAA,QACA,aAAA;AAAA,QACA,OAAA;AAAA,QACA,UAAA;AAAA,QACA,eAAA;AAAA,QACA,YAAA;AAAA,QACA,kBAAA;AAAA,QACA,mBAAA;AAAA,QACA,MAAA;AAAA,QACA,gBAAA;AAAA,QACA,SAAA;AAAA,QACA,iBAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,OACF;AAGA,MAAA,MAAM,cAAA,GAAiB,MAAM,IAAA,CAAK,SAAA,EAAU;AAC5C,MAAA,MAAM,gBAAgB,gBAAA,CAAiB,MAAA;AAAA,QAAO,CAAA,KAAA,KAC5C,cAAA,CAAe,QAAA,CAAS,KAAK;AAAA,OAC/B;AAGA,MAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,QAAA,IAAI;AACF,UAAA,MAAM,KAAK,EAAA,CAAG,OAAA,CAAQ,eAAe,SAAS,CAAA,CAAE,EAAE,GAAA,EAAI;AACtD,UAAA,aAAA,CAAc,KAAK,SAAS,CAAA;AAAA,QAC9B,SAAS,KAAA,EAAO;AACd,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAA;AAC1D,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QAC3D;AAAA,MACF;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,iDAAiD,EACpE,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA,CAAE,GAAA,EAAI;AAGjC,QAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA;AAAA,UAChC;AAAA,SACF,CAAE,IAAA,CAAK,UAAA,EAAY,OAAO,EAAE,KAAA,EAAM;AAElC,QAAA,kBAAA,GAAqB,CAAC,CAAC,WAAA;AACvB,QAAA,aAAA,CAAc,KAAK,mBAAmB,CAAA;AAAA,MACxC,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,iCAAA,EAAoC,KAAK,CAAA,CAAE,CAAA;AACvD,QAAA,OAAA,CAAQ,KAAA,CAAM,mCAAmC,KAAK,CAAA;AAAA,MACxD;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,6BAA6B,EAAE,GAAA,EAAI;AAAA,MAC3D,SAAS,KAAA,EAAO;AAAA,MAEhB;AAEA,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAA,GAAS,CAAA,GAC5B,CAAA,0BAAA,EAA6B,MAAA,CAAO,MAAM,CAAA,SAAA,EAAY,aAAA,CAAc,MAAM,CAAA,gBAAA,CAAA,GAC1E,CAAA,iCAAA,EAAoC,cAAc,MAAM,CAAA,gBAAA,CAAA;AAE5D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,OAAO,MAAA,KAAW,CAAA;AAAA,QAC3B,OAAA;AAAA,QACA,aAAA;AAAA,QACA,kBAAA;AAAA,QACA,MAAA,EAAQ,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,KAAA;AAAA,OACvC;AAAA,IAEF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAA,EAAS,+BAA+B,KAAK,CAAA,CAAA;AAAA,QAC7C,aAAA;AAAA,QACA,kBAAA;AAAA,QACA,MAAA,EAAQ,CAAC,MAAA,CAAO,KAAK,CAAC;AAAA,OACxB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAA,GAAkF;AACtF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,CAAA,OAAA,EAAU,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA;AACrC,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,gBAAA,EAAiB;AAI1C,MAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAU,QAAQ,CAAA,cAAA,EAAiB,KAAA,CAAM,SAAS,CAAA,WAAA,CAAa,CAAA;AAE3E,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,OAAA,EAAS,CAAA,6BAAA,EAAgC,KAAA,CAAM,SAAS,CAAA,MAAA,CAAA;AAAA,QACxD;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAA,EAAS,kBAAkB,KAAK,CAAA;AAAA,OAClC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,SAAA,EACA,KAAA,GAAgB,KAChB,MAAA,GAAiB,CAAA,EACjB,UAAA,EACA,aAAA,GAAgC,KAAA,EACZ;AACpB,IAAA,IAAI;AAEF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,EAAU;AACpC,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,EAAG;AAC/B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,SAAS,CAAA,UAAA,CAAY,CAAA;AAAA,MAChD;AAGA,MAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,kBAAA,EAAqB,SAAS,CAAA,CAAA,CAAG,CAAA,CAAE,GAAA,EAAI;AAClF,MAAA,MAAM,OAAA,GAAU,aAAa,OAAA,EAAS,GAAA,CAAI,CAAC,GAAA,KAAa,GAAA,CAAI,IAAI,CAAA,IAAK,EAAC;AAGtE,MAAA,IAAI,UAAA,IAAc,CAAC,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAA,EAAG;AAC/C,QAAA,UAAA,GAAa,KAAA,CAAA;AAAA,MACf;AAGA,MAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAE,CAAA,CAAE,KAAA,EAAM;AAC9F,MAAA,MAAM,SAAA,GAAa,aAAa,KAAA,IAAoB,CAAA;AAGpD,MAAA,IAAI,KAAA,GAAQ,iBAAiB,SAAS,CAAA,CAAA;AACtC,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,KAAA,IAAS,CAAA,UAAA,EAAa,UAAU,CAAA,CAAA,EAAI,aAAA,CAAc,aAAa,CAAA,CAAA;AAAA,MACjE;AACA,MAAA,KAAA,IAAS,CAAA,OAAA,EAAU,KAAK,CAAA,QAAA,EAAW,MAAM,CAAA,CAAA;AAGzC,MAAA,MAAM,aAAa,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,KAAK,EAAE,GAAA,EAAI;AAEpD,MAAA,OAAO;AAAA,QACL,SAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM,UAAA,CAAW,OAAA,IAAW,EAAC;AAAA,QAC7B;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,KAAK,CAAA,CAAE,CAAA;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAA,GAAkE;AACtE,IAAA,MAAM,SAAmB,EAAC;AAE1B,IAAA,IAAI;AAEF,MAAA,MAAM,cAAA,GAAiB,CAAC,OAAA,EAAS,SAAA,EAAW,aAAa,CAAA;AACzD,MAAA,MAAM,cAAA,GAAiB,MAAM,IAAA,CAAK,SAAA,EAAU;AAE5C,MAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,QAAA,IAAI,CAAC,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,EAAG;AACnC,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,wBAAA,EAA2B,KAAK,CAAA,CAAE,CAAA;AAAA,QAChD;AAAA,MACF;AAGA,MAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA;AAAA,QAC/B;AAAA,OACF,CAAE,IAAA,CAAK,OAAO,CAAA,CAAE,KAAA,EAAM;AAEtB,MAAA,IAAK,UAAA,EAAY,UAAqB,CAAA,EAAG;AACvC,QAAA,MAAA,CAAO,KAAK,sBAAsB,CAAA;AAAA,MACpC;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,kBAAkB,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,wBAAwB,EAAE,KAAA,EAAM;AAC9E,QAAA,IAAI,eAAA,IAAoB,eAAA,CAAwB,eAAA,KAAoB,IAAA,EAAM;AACxE,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,iCAAA,EAAqC,eAAA,CAAwB,eAAe,CAAA,CAAE,CAAA;AAAA,QAC5F;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,+BAAA,EAAkC,KAAK,CAAA,CAAE,CAAA;AAAA,MACvD;AAAA,IAEF,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,kBAAA,EAAqB,KAAK,CAAA,CAAE,CAAA;AAAA,IAC1C;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,MACzB;AAAA,KACF;AAAA,EACF;AACF,CAAA;;;AC5SAA,qDAAA,EAAA;AAkBO,SAAS,wBAAwB,IAAA,EAAqC;AAC3E,EAAA,MAAM,aAAa,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,SAAA,GAAY,KAAK,QAAQ,CAAA;AAC3D,EAAA,MAAM,QAAA,GAAA,CAAY,IAAA,CAAK,WAAA,GAAc,CAAA,IAAK,KAAK,QAAA,GAAW,CAAA;AAC1D,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,IAAA,CAAK,cAAc,IAAA,CAAK,QAAA,EAAU,KAAK,SAAS,CAAA;AAExE,EAAA,MAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sGAAA,EAgBkF,KAAK,SAAS,CAAA;AAAA;AAAA,oBAAA,EAEhG,QAAA,CAAS,cAAA,EAAgB,CAAA,GAAA,EAAM,MAAA,CAAO,cAAA,EAAgB,CAAA,IAAA,EAAO,IAAA,CAAK,SAAA,CAAU,cAAA,EAAgB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAAA,EAa/E,IAAA,CAAK,QAAA,KAAa,EAAA,GAAK,UAAA,GAAa,EAAE,CAAA;AAAA,iCAAA,EACtC,IAAA,CAAK,QAAA,KAAa,EAAA,GAAK,UAAA,GAAa,EAAE,CAAA;AAAA,iCAAA,EACtC,IAAA,CAAK,QAAA,KAAa,EAAA,GAAK,UAAA,GAAa,EAAE,CAAA;AAAA,kCAAA,EACrC,IAAA,CAAK,QAAA,KAAa,GAAA,GAAM,UAAA,GAAa,EAAE,CAAA;AAAA,kCAAA,EACvC,IAAA,CAAK,QAAA,KAAa,GAAA,GAAM,UAAA,GAAa,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAA,EAsBzD,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,GAAA,KAAO;AAAA;AAAA;AAAA;AAAA,wCAAA,EAIA,GAAG,CAAA;AAAA;AAAA;AAAA,4BAAA,EAGf,GAAG,CAAA;AAAA,sBAAA,EACT,IAAA,CAAK,eAAe,GAAA,GAAM;AAAA,4CAAA,EACJ,IAAA,CAAK,aAAA,KAAkB,KAAA,GAAQ,EAAA,GAAK,YAAY,CAAA;AAAA;AAAA;AAAA,sBAAA,CAAA,GAGpE;AAAA;AAAA;AAAA;AAAA,sBAAA,CAIH;AAAA;AAAA;AAAA,gBAAA,CAGN,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,cAAA,EAIX,IAAA,CAAK,KAAK,MAAA,GAAS,CAAA,GACjB,KAAK,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,GAAA,KAAQ;AAAA,6BAAA,EACf,GAAA,GAAM,CAAA,KAAM,CAAA,GAAI,2BAAA,GAA8B,gCAAgC,CAAA;AAAA,oBAAA,EACvF,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,GAAA,KAAO;AAAA,qJAAA,EACyGC,YAAW,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,CAAC,CAAC,CAAA;AAAA,wBAAA,EAC/J,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAC,CAAC;AAAA;AAAA,oBAAA,CAE9B,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC;AAAA;AAAA,gBAAA,CAEd,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,GACR;AAAA;AAAA,iCAAA,EAEiB,IAAA,CAAK,QAAQ,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAA,CAQxC;AAAA;AAAA;AAAA;;AAAA;AAAA,QAAA,EAMJ,aAAa,CAAA,GAAI;AAAA;AAAA;AAAA;AAAA,kCAAA,EAIS,IAAA,CAAK,cAAc,CAAC,CAAA;AAAA,gBAAA,EACtC,IAAA,CAAK,WAAA,KAAgB,CAAA,GAAI,UAAA,GAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAAA,EAMtB,IAAA,CAAK,cAAc,CAAC,CAAA;AAAA,gBAAA,EACtC,IAAA,CAAK,WAAA,KAAgB,UAAA,GAAa,UAAA,GAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iDAAA,EAShB,IAAA,CAAK,WAAW,CAAA,qCAAA,EAAwC,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAAA,EAM7E,IAAA,CAAK,cAAc,CAAC,CAAA;AAAA,oBAAA,EACtC,IAAA,CAAK,WAAA,KAAgB,CAAA,GAAI,UAAA,GAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA,kBAAA,EAS1C,mBAAA,CAAoB,IAAA,CAAK,WAAA,EAAa,UAAU,CAAC;;AAAA;AAAA,sCAAA,EAG7B,IAAA,CAAK,cAAc,CAAC,CAAA;AAAA,oBAAA,EACtC,IAAA,CAAK,WAAA,KAAgB,UAAA,GAAa,UAAA,GAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAAA,GAY3D,EAAE;AAAA;AAAA;;AAAA;AAAA,gCAAA,EAKoB,KAAK,SAAS,CAAA;AAAA,wBAAA,EACtB,KAAK,WAAW,CAAA;AAAA,4BAAA,EACZ,KAAK,QAAQ,CAAA;AAAA,yBAAA,EAChB,IAAA,CAAK,cAAc,EAAE,CAAA;AAAA,4BAAA,EAClB,IAAA,CAAK,iBAAiB,KAAK,CAAA;;AAAA;AAAA,+BAAA,EAGxB,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;AAsEzC,EAAA,MAAM,UAAA,GAAsC;AAAA,IAC1C,KAAA,EAAO,CAAA,OAAA,EAAU,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,IAC/B,SAAA,EAAW,CAAA,UAAA,EAAa,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,IACtC,WAAA,EAAa,CAAA,6BAAA,EAAgC,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,IAC3D,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,OAAOC,4CAA0B,UAAU,CAAA;AAC7C;AAEA,SAAS,mBAAA,CAAoB,aAAqB,UAAA,EAA4B;AAC5E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,UAAA,GAAa,CAAA;AAEnB,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,UAAA,EAAY,CAAA,EAAA,EAAK;AACpC,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd;AAAA,EACF,CAAA,MAAO;AACL,IAAA,IAAI,eAAe,CAAA,EAAG;AACpB,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AACzC,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,MAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,IACvB,CAAA,MAAA,IAAW,WAAA,IAAe,UAAA,GAAa,CAAA,EAAG;AACxC,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,MAAA,KAAA,IAAS,CAAA,GAAI,aAAa,CAAA,EAAG,CAAA,IAAK,YAAY,CAAA,EAAA,EAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACjE,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,MAAA,KAAA,IAAS,CAAA,GAAI,cAAc,CAAA,EAAG,CAAA,IAAK,cAAc,CAAA,EAAG,CAAA,EAAA,EAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA;AACrE,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,MAAA,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,IAAI,CAAA,IAAA,KAAQ;AACvB,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,OAAO;AAAA;AAAA;AAAA;AAAA,MAAA,CAAA;AAAA,IAKT;AAEA,IAAA,MAAM,WAAW,IAAA,KAAS,WAAA;AAC1B,IAAA,OAAO;AAAA;AAAA,0BAAA,EAEiB,IAAI,CAAA;AAAA,iFAAA,EAEtB,QAAA,GACI,gJACA,6HACN,CAAA;AAAA;AAAA,QAAA,EAEE,IAAI;AAAA;AAAA,IAAA,CAAA;AAAA,EAGZ,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AACZ;AAEA,SAASD,YAAW,IAAA,EAAsB;AACxC,EAAA,MAAM,GAAA,GAA8B;AAAA,IAClC,GAAA,EAAK,OAAA;AAAA,IACL,GAAA,EAAK,MAAA;AAAA,IACL,GAAA,EAAK,MAAA;AAAA,IACL,GAAA,EAAK,QAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACP;AACA,EAAA,OAAO,MAAA,CAAO,IAAI,CAAA,CAAE,OAAA,CAAQ,YAAY,CAAA,CAAA,KAAK,GAAA,CAAI,CAAC,CAAA,IAAK,CAAC,CAAA;AAC1D;AAEA,SAAS,gBAAgB,KAAA,EAAoB;AAC3C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,mEAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,OAAO,CAAA,qDAAA,EAAwD,KAAA,GAAQ,sEAAA,GAAyE,+DAA+D,KAAK,KAAK,CAAA,OAAA,CAAA;AAAA,EAC3N;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,sEAAsE,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,CAAE,UAAU,CAAA,EAAG,EAAE,CAAA,IAAK,IAAA,CAAK,UAAU,KAAK,CAAA,CAAE,MAAA,GAAS,EAAA,GAAK,QAAQ,EAAA,CAAA,GAAM,SAAA;AAAA,EAC3K;AACA,EAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,EAAA,IAAI,GAAA,CAAI,SAAS,GAAA,EAAK;AACpB,IAAA,OAAOA,YAAW,GAAA,CAAI,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,CAAA,GAAI,KAAA;AAAA,EAC7C;AACA,EAAA,OAAOA,YAAW,GAAG,CAAA;AACvB;;;AC/UO,SAAS,8BAAA,GAAiC;AAC/C,EAAA,MAAME,OAAAA,GAAS,IAAIC,SAAA,EAAmD;AAGtE,EAAAD,OAAAA,CAAO,GAAA,CAAI,GAAA,EAAKE,6BAAA,EAAa,CAAA;AAG7B,EAAAF,OAAAA,CAAO,GAAA,CAAI,YAAA,EAAc,OAAO,CAAA,KAAM;AACpC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,gBAAA,EAAiB;AAE7C,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,kCAAkC,KAAK,CAAA;AACrD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAAA,OAAAA,CAAO,IAAA,CAAK,eAAA,EAAiB,OAAO,CAAA,KAAM;AACxC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,EAAE,aAAY,GAAI,IAAA;AAGxB,MAAA,IAAI,gBAAgB,mBAAA,EAAqB;AACvC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,eAAA,CAAgB,KAAK,KAAK,CAAA;AAEvD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,IAAA,EAAM;AAAA,UACJ,eAAe,MAAA,CAAO,aAAA;AAAA,UACtB,oBAAoB,MAAA,CAAO,kBAAA;AAAA,UAC3B,QAAQ,MAAA,CAAO;AAAA;AACjB,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,8BAA8B,KAAK,CAAA;AACjD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAAA,OAAAA,CAAO,IAAA,CAAK,aAAA,EAAe,OAAO,CAAA,KAAM;AACtC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,YAAA,EAAa;AAE1C,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,IAAA,EAAM;AAAA,UACJ,UAAU,MAAA,CAAO;AAAA;AACnB,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,0BAA0B,KAAK,CAAA;AAC7C,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAAA,OAAAA,CAAO,GAAA,CAAI,eAAA,EAAiB,OAAO,CAAA,KAAM;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,UAAA,GAAa,MAAM,OAAA,CAAQ,gBAAA,EAAiB;AAElD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,8BAA8B,KAAK,CAAA;AACjD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAAA,OAAAA,CAAO,GAAA,CAAI,wBAAA,EAA0B,OAAO,CAAA,KAAM;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA;AACzC,MAAA,MAAM,QAAQ,QAAA,CAAS,CAAA,CAAE,IAAI,KAAA,CAAM,OAAO,KAAK,KAAK,CAAA;AACpD,MAAA,MAAM,SAAS,QAAA,CAAS,CAAA,CAAE,IAAI,KAAA,CAAM,QAAQ,KAAK,GAAG,CAAA;AACpD,MAAA,MAAM,UAAA,GAAa,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACrC,MAAA,MAAM,aAAA,GAAiB,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,IAAK,KAAA;AAE7C,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,YAAA,CAAa,WAAW,KAAA,EAAO,MAAA,EAAQ,YAAY,aAAa,CAAA;AAEhG,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,8BAA8B,KAAK,CAAA;AACjD,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,+BAA+B,KAAK,CAAA;AAAA,SAC1C,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAAA,OAAAA,CAAO,GAAA,CAAI,oBAAA,EAAsB,OAAO,CAAA,KAAM;AAC5C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAClC,QAAA,OAAO,CAAA,CAAE,SAAS,cAAc,CAAA;AAAA,MAClC;AAEA,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA;AACzC,MAAA,MAAM,OAAO,QAAA,CAAS,CAAA,CAAE,IAAI,KAAA,CAAM,MAAM,KAAK,GAAG,CAAA;AAChD,MAAA,MAAM,WAAW,QAAA,CAAS,CAAA,CAAE,IAAI,KAAA,CAAM,UAAU,KAAK,IAAI,CAAA;AACzD,MAAA,MAAM,UAAA,GAAa,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AACrC,MAAA,MAAM,aAAA,GAAiB,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,IAAK,KAAA;AAE7C,MAAA,MAAM,MAAA,GAAA,CAAU,OAAO,CAAA,IAAK,QAAA;AAE5B,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,OAAA,GAAU,IAAI,oBAAA,CAAqB,EAAE,CAAA;AAC3C,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,YAAA,CAAa,WAAW,QAAA,EAAU,MAAA,EAAQ,YAAY,aAAa,CAAA;AAEnG,MAAA,MAAM,QAAA,GAAkC;AAAA,QACtC,IAAA,EAAM;AAAA,UACJ,MAAM,IAAA,CAAK,KAAA,CAAM,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,SAAA;AAAA,UAClC,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,MAAM,IAAA,CAAK;AAAA,SACb;AAAA,QACA,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,SAAS,SAAA,CAAU,OAAA;AAAA,QACnB,MAAM,SAAA,CAAU,IAAA;AAAA,QAChB,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,WAAA,EAAa,IAAA;AAAA,QACb,QAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,uBAAA,CAAwB,QAAQ,CAAC,CAAA;AAAA,IACjD,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,CAAA,OAAA,EAAU,KAAK,IAAI,GAAG,CAAA;AAAA,IACtC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAOA,OAAAA;AACT;ACjOO,SAAS,iBAAA,GAA4B;AAC1C,EAAA,MAAM,OAAA,GAAUG,gCAAc,MAAA,CAAO;AAAA,IACnC,IAAA,EAAM,OAAA;AAAA,IACN,OAAA,EAAS,cAAA;AAAA,IACT,WAAA,EAAa;AAAA,GACd,CAAA;AAGD,EAAA,OAAA,CAAQ,QAAA,CAAS;AAAA,IACf,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,cAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,IACA,OAAA,EAAS,KAAA;AAAA,IACT,aAAA,EAAe;AAAA,GAChB,CAAA;AAGD,EAAA,MAAM,WAAA,GAAc,IAAIF,SAAAA,EAAK;AAE7B,EAAA,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,OAAO,CAAA,KAAW;AAC7C,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AACzB,IAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AAGjB,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA,IAAA,CAE/B,EAAE,KAAA,EAAM;AAET,IAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,GAAW,IAAA,CAAK,MAAM,MAAA,CAAO,QAAQ,IAAI,EAAC;AAEnE,IAAA,MAAM,cAAc,MAAMG,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAA,EAwBH,QAAA,CAAS,UAAU,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAA,EAmBrB,QAAA,CAAS,aAAa,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAA,EAmBxB,QAAA,CAAS,YAAY,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAA,EAgBvB,QAAA,CAAS,WAAW,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAA,EAetB,QAAA,CAAS,WAAW,EAAE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAsI7C,IAAA,MAAM,eAAe,IAAA,GAAO;AAAA,MAC1B,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAA,IAAS,OAAA;AAAA,MACjC,KAAA,EAAO,KAAK,KAAA,IAAS,mBAAA;AAAA,MACrB,IAAA,EAAM,KAAK,IAAA,IAAQ;AAAA,KACrB,GAAI,MAAA;AAEJ,IAAA,OAAO,CAAA,CAAE,IAAA;AAAA,MACPC,mCAAA,CAAkB;AAAA,QAChB,KAAA,EAAO,gBAAA;AAAA,QACP,OAAA,EAAS,WAAA;AAAA,QACT,IAAA,EAAM,YAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACd;AAAA,KACH;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,WAAA,CAAY,IAAA,CAAK,WAAA,EAAa,OAAO,CAAA,KAAW;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AAGjB,MAAA,MAAM,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,MAAA,CAKhB,EAAE,IAAA,CAAK,IAAA,CAAK,UAAU,IAAI,CAAC,EAAE,GAAA,EAAI;AAElC,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,EAAE,OAAA,EAAS,MAAM,CAAA;AAAA,IACjC,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,gCAAgC,KAAK,CAAA;AACnD,MAAA,OAAO,CAAA,CAAE,KAAK,EAAE,OAAA,EAAS,OAAO,KAAA,EAAO,yBAAA,IAA6B,GAAG,CAAA;AAAA,IACzE;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,WAAA,CAAY,IAAA,CAAK,OAAA,EAAS,OAAO,CAAA,KAAW;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAG9B,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA,MAAA,CAE/B,EAAE,KAAA,EAAM;AAET,MAAA,IAAI,CAAC,QAAQ,QAAA,EAAU;AACrB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,QAAQ,CAAA;AAG3C,MAAA,IAAI,CAAC,SAAS,MAAA,IAAU,CAAC,SAAS,SAAA,IAAa,CAAC,SAAS,QAAA,EAAU;AACjE,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,QAAA,CAAS,SAAA;AAGzC,MAAA,IAAI,CAAC,OAAA,CAAQ,KAAA,CAAM,4BAA4B,CAAA,EAAG;AAChD,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,+BAAA,EAAiC;AAAA,QAC5D,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,eAAA,EAAiB,CAAA,OAAA,EAAU,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,UAC1C,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,MAAM,CAAA,EAAG,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK,SAAS,SAAS,CAAA,CAAA,CAAA;AAAA,UACjD,EAAA,EAAI,CAAC,OAAO,CAAA;AAAA,UACZ,OAAA,EAAS,yBAAA;AAAA,UACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAA,EAMY,QAAA,CAAS,QAAQ,CAAA,KAAA,EAAQ,QAAA,CAAS,SAAS,CAAA;AAAA,8BAAA,EACvC,QAAA,CAAS,WAAW,SAAS,CAAA;AAAA,6BAAA,EAAA,iBAC9B,IAAI,IAAA,EAAK,EAAE,WAAA,EAAa,CAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAAA;AAAA,UAK7C,QAAA,EAAU,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS;AAAA,SACxC;AAAA,OACF,CAAA;AAED,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AAEjC,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,OAAA,CAAQ,KAAA,CAAM,qBAAqB,IAAI,CAAA;AACvC,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,KAAK,OAAA,IAAW;AAAA,SACzB,EAAG,SAAS,MAAM,CAAA;AAAA,MACpB;AAEA,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,IAAA;AAAA,QACT,OAAA,EAAS,mCAAmC,OAAO,CAAA,CAAA;AAAA,QACnD,SAAS,IAAA,CAAK;AAAA,OACf,CAAA;AAAA,IAEH,SAAS,KAAA,EAAY;AACnB,MAAA,OAAA,CAAQ,KAAA,CAAM,qBAAqB,KAAK,CAAA;AACxC,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,MAAM,OAAA,IAAW;AAAA,SACvB,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,OAAA,CAAQ,QAAA,CAAS,wBAAwB,WAAA,EAAa;AAAA,IACpD,WAAA,EAAa,uBAAA;AAAA,IACb,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX,CAAA;AAGD,EAAA,OAAA,CAAQ,WAAA,CAAY,SAAS,+BAAA,EAAiC;AAAA,IAC5D,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,EAAA;AAAA,IACP,WAAA,EAAa,CAAC,cAAc;AAAA,GAC7B,CAAA;AAGD,EAAA,OAAA,CAAQ,SAAA,CAAU;AAAA,IAChB,UAAU,YAAY;AACpB,MAAA,OAAA,CAAQ,KAAK,+BAA0B,CAAA;AAAA,IACzC,CAAA;AAAA,IAEA,YAAY,YAAY;AACtB,MAAA,OAAA,CAAQ,KAAK,iCAA4B,CAAA;AAAA,IAC3C;AAAA,GACD,CAAA;AAED,EAAA,OAAO,QAAQ,KAAA,EAAM;AACvB;AAGO,IAAM,cAAc,iBAAA,EAAkB;;;AChZtC,IAAM,aAAN,MAAiB;AAAA,EACtB,YAAoB,EAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA,EAAiB;AAAA;AAAA;AAAA;AAAA,EAKrC,YAAA,CAAa,SAAiB,CAAA,EAAW;AACvC,IAAA,MAAM,MAAA,GAAS,YAAA;AACf,IAAA,IAAI,IAAA,GAAO,EAAA;AAEX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,MAAA,MAAM,YAAA,GAAe,IAAI,UAAA,CAAW,CAAC,CAAA;AACrC,MAAA,MAAA,CAAO,gBAAgB,YAAY,CAAA;AACnC,MAAA,MAAM,WAAA,GAAc,YAAA,CAAa,CAAC,CAAA,IAAK,CAAA;AACvC,MAAA,IAAA,IAAQ,MAAA,CAAO,WAAA,GAAc,MAAA,CAAO,MAAM,CAAA;AAAA,IAC5C;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CACJ,KAAA,EACA,QAAA,EACA,WACA,SAAA,EACkB;AAClB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,UAAU,CAAA;AAClD,IAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,SAAA,GAAY,GAAA,GAAO,QAAA,CAAS,iBAAA,GAAoB,EAAA,GAAK,GAAA;AAE3D,IAAA,MAAM,OAAA,GAAmB;AAAA,MACvB,EAAA;AAAA,MACA,UAAA,EAAY,MAAM,WAAA,EAAY;AAAA,MAC9B,IAAA;AAAA,MACA,UAAA,EAAY,SAAA;AAAA,MACZ,IAAA,EAAM,CAAA;AAAA,MACN,OAAA,EAAS,IAAA;AAAA,MACT,YAAY,SAAA,IAAa,IAAA;AAAA,MACzB,YAAY,SAAA,IAAa,IAAA;AAAA,MACzB,QAAA,EAAU,CAAA;AAAA,MACV,UAAA,EAAY;AAAA,KACd;AAEA,IAAA,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAKrB,CAAA,CAAE,IAAA;AAAA,MACD,OAAA,CAAQ,EAAA;AAAA,MACR,OAAA,CAAQ,UAAA;AAAA,MACR,OAAA,CAAQ,IAAA;AAAA,MACR,OAAA,CAAQ,UAAA;AAAA,MACR,OAAA,CAAQ,IAAA;AAAA,MACR,OAAA,CAAQ,OAAA;AAAA,MACR,OAAA,CAAQ,UAAA;AAAA,MACR,OAAA,CAAQ,UAAA;AAAA,MACR,OAAA,CAAQ,QAAA;AAAA,MACR,OAAA,CAAQ;AAAA,MACR,GAAA,EAAI;AAEN,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,CACJ,KAAA,EACA,IAAA,EACA,QAAA,EACyE;AACzE,IAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAC1C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAKrC,CAAA,CAAE,IAAA,CAAK,eAAA,EAAiB,IAAI,EAAE,KAAA,EAAM;AAErC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,yBAAA,EAA0B;AAAA,IAC1D;AAGA,IAAA,IAAI,GAAA,GAAM,QAAQ,UAAA,EAAY;AAC5B,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,kBAAA,EAAmB;AAAA,IACnD;AAGA,IAAA,IAAI,OAAA,CAAQ,QAAA,IAAY,QAAA,CAAS,WAAA,EAAa;AAC5C,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,2BAAA,EAA4B;AAAA,IAC5D;AAGA,IAAA,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,IAAA,CAIrB,EAAE,IAAA,CAAK,GAAA,EAAK,OAAA,CAAQ,EAAE,EAAE,GAAA,EAAI;AAE7B,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAA,CAAkB,KAAA,EAAe,IAAA,EAA+B;AACpE,IAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAE1C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAKpC,CAAA,CAAE,IAAA,CAAK,eAAA,EAAiB,IAAI,EAAE,KAAA,EAAM;AAErC,IAAA,OAAO,QAAQ,QAAA,IAAY,CAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAA,CAAe,KAAA,EAAe,QAAA,EAAyC;AAC3E,IAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAC1C,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAK,KAAK,EAAA,GAAK,GAAA;AAE3C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,IAAA,CAIpC,CAAA,CAAE,IAAA,CAAK,eAAA,EAAiB,UAAU,EAAE,KAAA,EAAM;AAE3C,IAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,CAAA;AAC/B,IAAA,OAAO,QAAQ,QAAA,CAAS,gBAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAA,CAAkB,KAAA,GAAgB,EAAA,EAAwB;AAC9D,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,IAAA,CAIpC,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA,CAAE,GAAA,EAAI;AAEnB,IAAA,MAAM,IAAA,GAAQ,MAAA,CAAO,OAAA,IAAW,EAAC;AACjC,IAAA,OAAO,KAAK,GAAA,CAAI,CAAA,GAAA,KAAO,IAAA,CAAK,WAAA,CAAY,GAAG,CAAC,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAA,GAAuC;AAC3C,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA,IAAA,CAGpC,CAAA,CAAE,IAAA,CAAK,GAAA,EAAK,GAAA,GAAO,EAAA,GAAK,KAAK,EAAA,GAAK,EAAA,GAAK,GAAK,CAAA,CAAE,GAAA,EAAI;AAEnD,IAAA,OAAO,MAAA,CAAO,KAAK,OAAA,IAAW,CAAA;AAAA,EAChC;AAAA,EAEQ,YAAY,GAAA,EAAuC;AACzD,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAAA,MACjB,UAAA,EAAY,MAAA,CAAO,GAAA,CAAI,UAAU,CAAA;AAAA,MACjC,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAAA,MACrB,YAAY,MAAA,CAAO,GAAA,CAAI,UAAA,IAAc,IAAA,CAAK,KAAK,CAAA;AAAA,MAC/C,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,IAAA,IAAQ,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS,GAAA,CAAI,OAAA,KAAY,IAAA,IAAQ,GAAA,CAAI,YAAY,MAAA,GAAY,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AAAA,MACtF,YAAY,OAAO,GAAA,CAAI,UAAA,KAAe,QAAA,GAAW,IAAI,UAAA,GAAa,IAAA;AAAA,MAClE,YAAY,OAAO,GAAA,CAAI,UAAA,KAAe,QAAA,GAAW,IAAI,UAAA,GAAa,IAAA;AAAA,MAClE,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,QAAA,IAAY,CAAC,CAAA;AAAA,MAClC,YAAY,MAAA,CAAO,GAAA,CAAI,UAAA,IAAc,IAAA,CAAK,KAAK;AAAA,KACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CAAS,IAAA,GAAe,CAAA,EAK3B;AACD,IAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,KAAS,IAAA,GAAO,EAAA,GAAK,KAAK,EAAA,GAAK,GAAA;AAElD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAQnC,EAAE,IAAA,CAAK,IAAA,CAAK,KAAI,EAAG,KAAK,EAAE,KAAA,EAAM;AAEjC,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAO,KAAA,IAAS,CAAA;AAAA,MACvB,UAAA,EAAY,OAAO,UAAA,IAAc,CAAA;AAAA,MACjC,MAAA,EAAQ,OAAO,MAAA,IAAU,CAAA;AAAA,MACzB,OAAA,EAAS,OAAO,OAAA,IAAW;AAAA,KAC7B;AAAA,EACF;AACF,CAAA;;;ACnOO,SAAS,mBAAmB,IAAA,EAA4B;AAC7D,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA,IAAA,EAWH,KAAK,OAAA,GAAU;AAAA;AAAA,gBAAA,EAEH,KAAK,OAAO,CAAA;AAAA;AAAA,IAAA,CAAA,GAEtB,EAAE;;AAAA;AAAA;AAAA,0FAAA,EAIkF,KAAK,OAAO,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,UAAA,EAM5F,KAAK,IAAI;AAAA;AAAA;;AAAA;AAAA;AAAA,oDAAA,EAMuB,KAAK,aAAa,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,+CAAA,EAOb,KAAK,UAAU,CAAA;AAAA;AAAA,uBAAA,EAEvC,KAAK,WAAW,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6CAAA,EAUM,KAAK,OAAO,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,yDAAA,EAYA,KAAK,KAAK,CAAA;AAAA,QAAA,EAC3D,KAAK,SAAA,GAAY,CAAA,sCAAA,EAAyC,IAAA,CAAK,SAAS,SAAS,EAAE;AAAA,wCAAA,EACnD,KAAK,SAAS,CAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA,iCAAA,EAAA,qBAOjB,IAAA,EAAK,EAAE,aAAa,CAAA,CAAA,EAAI,KAAK,OAAO,CAAA;AAAA;;AAAA;AAAA,OAAA,CAAA;AAK3E;AAEO,SAAS,mBAAmB,IAAA,EAA4B;AAC7D,EAAA,OAAO,CAAA,oBAAA,EAAuB,KAAK,OAAO;;AAAA;;AAAA,EAI1C,KAAK,IAAI;;AAAA,qBAAA,EAEY,KAAK,aAAa,CAAA;;AAAA;AAAA,wCAAA,EAGJ,KAAK,UAAU,CAAA;AAAA;AAAA,gBAAA,EAEvC,KAAK,WAAW,CAAA;AAAA;;AAAA;AAAA,mCAAA,EAIQ,KAAK,OAAO,CAAA;;AAAA;AAAA;;AAAA;AAAA,uBAAA,EAMxB,KAAK,KAAK;AAAA,EACjC,KAAK,SAAA,GAAY,CAAA,YAAA,EAAe,IAAA,CAAK,SAAS,KAAK,EAAE;AAAA,MAAA,EAC/C,KAAK,SAAS;;AAAA,KAAA,EAAA,qBAEd,IAAA,EAAK,EAAE,aAAa,CAAA,CAAA,EAAI,KAAK,OAAO,CAAA,sBAAA,CAAA;AAC5C;AAEO,SAAS,eAAe,IAAA,EAAoD;AACjF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,mBAAmB,IAAI,CAAA;AAAA,IAC7B,IAAA,EAAM,mBAAmB,IAAI;AAAA,GAC/B;AACF;;;ACjHA,IAAM,gBAAA,GAAmBC,MAAE,MAAA,CAAO;AAAA,EAChC,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,MAAM,yBAAyB;AACnD,CAAC,CAAA;AAED,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EAC/B,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,MAAM,yBAAyB,CAAA;AAAA,EACjD,IAAA,EAAMA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,CAAC;AAC/B,CAAC,CAAA;AAGD,IAAM,gBAAA,GAAgC;AAAA,EACpC,UAAA,EAAY,CAAA;AAAA,EACZ,iBAAA,EAAmB,EAAA;AAAA,EACnB,WAAA,EAAa,CAAA;AAAA,EACb,gBAAA,EAAkB,CAAA;AAAA,EAClB,wBAAA,EAA0B,KAAA;AAAA,EAC1B,OAAA,EAAS;AACX,CAAA;AAEO,SAAS,oBAAA,GAA+B;AAC7C,EAAA,MAAM,OAAA,GAAUH,gCAAc,MAAA,CAAO;AAAA,IACnC,IAAA,EAAM,WAAA;AAAA,IACN,OAAA,EAAS,cAAA;AAAA,IACT,WAAA,EAAa;AAAA,GACd,CAAA;AAED,EAAA,OAAA,CAAQ,QAAA,CAAS;AAAA,IACf,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,cAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,IACA,OAAA,EAAS,KAAA;AAAA,IACT,aAAA,EAAe;AAAA,GAChB,CAAA;AAID,EAAA,MAAM,MAAA,GAAS,IAAIF,SAAAA,EAAK;AAGxB,EAAA,MAAA,CAAO,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA,KAAW;AACxC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,SAAA,CAAU,IAAI,CAAA;AAElD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA,EAAS,WAAW,KAAA,CAAM;AAAA,WACzB,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,UAAA,CAAW,IAAA;AAC7B,MAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAC1C,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,UAAA,GAAa,IAAI,UAAA,CAAW,EAAE,CAAA;AACpC,MAAA,MAAM,QAAA,GAAW,EAAE,GAAG,gBAAA,EAAiB;AAGvC,MAAA,MAAM,UAAA,GAAa,MAAM,UAAA,CAAW,cAAA,CAAe,iBAAiB,QAAQ,CAAA;AAC5E,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,IAAA,GAAO,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAI7B,CAAA,CAAE,IAAA,CAAK,eAAe,CAAA,CAAE,KAAA,EAAM;AAE/B,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,QAAA,CAAS,wBAAA,EAA0B;AAE/C,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS,oFAAA;AAAA,UACT,SAAA,EAAW,SAAS,iBAAA,GAAoB;AAAA,SACzC,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,SAAA,EAAW;AAC3B,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,kBAAkB,KAAK,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,iBAAiB,CAAA,IAAK,SAAA;AACzF,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,YAAY,CAAA,IAAK,SAAA;AAGhD,MAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,aAAA;AAAA,QAC/B,eAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AAGA,MAAA,IAAI;AAGF,QAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,CAAI,WAAA,KAAgB,aAAA;AAExC,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,OAAA,CAAQ,IAAI,CAAA,mBAAA,EAAsB,eAAe,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,QACtE;AAGA,QAAA,MAAM,eAAe,cAAA,CAAe;AAAA,UAClC,MAAM,OAAA,CAAQ,IAAA;AAAA,UACd,eAAe,QAAA,CAAS,iBAAA;AAAA,UACxB,YAAY,QAAA,CAAS,UAAA;AAAA,UACrB,aAAa,QAAA,CAAS,WAAA;AAAA,UACtB,KAAA,EAAO,eAAA;AAAA,UACP,SAAA;AAAA,UACA,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,UAClC,SAAS,QAAA,CAAS;AAAA,SACnB,CAAA;AAUD,QAAA,MAAM,QAAA,GAAgB;AAAA,UACpB,OAAA,EAAS,oFAAA;AAAA,UACT,SAAA,EAAW,SAAS,iBAAA,GAAoB;AAAA,SAC1C;AAGA,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,QAAA,CAAS,WAAW,OAAA,CAAQ,IAAA;AAAA,QAC9B;AAEA,QAAA,OAAO,CAAA,CAAE,KAAK,QAAQ,CAAA;AAAA,MACxB,SAAS,UAAA,EAAY;AACnB,QAAA,OAAA,CAAQ,KAAA,CAAM,4BAA4B,UAAU,CAAA;AACpD,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,sBAAsB,KAAK,CAAA;AACzC,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,OAAO,CAAA,KAAW;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAEjD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA,EAAS,WAAW,KAAA,CAAM;AAAA,WACzB,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,UAAA,CAAW,IAAA;AACnC,MAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAC1C,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AACjB,MAAA,MAAM,UAAA,GAAa,IAAI,UAAA,CAAW,EAAE,CAAA;AACpC,MAAA,MAAM,QAAA,GAAW,EAAE,GAAG,gBAAA,EAAiB;AAGvC,MAAA,MAAM,eAAe,MAAM,UAAA,CAAW,UAAA,CAAW,eAAA,EAAiB,MAAM,QAAQ,CAAA;AAEhF,MAAA,IAAI,CAAC,aAAa,KAAA,EAAO;AAEvB,QAAA,MAAM,UAAA,CAAW,iBAAA,CAAkB,eAAA,EAAiB,IAAI,CAAA;AAExD,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO,aAAa,KAAA,IAAS,cAAA;AAAA,UAC7B,mBAAmB,YAAA,CAAa;AAAA,WAC/B,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,IAAA,GAAO,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAI7B,CAAA,CAAE,IAAA,CAAK,eAAe,CAAA,CAAE,KAAA,EAAM;AAE/B,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAIA,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,UACJ,IAAI,IAAA,CAAK,EAAA;AAAA,UACT,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,MAAM,IAAA,CAAK;AAAA,SACb;AAAA,QACA,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,qBAAqB,KAAK,CAAA;AACxC,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,OAAO,CAAA,KAAW;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,SAAA,CAAU,IAAI,CAAA;AAElD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA,EAAS,WAAW,KAAA,CAAM;AAAA,WACzB,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,OAAO,MAAA,CAAO,KAAA;AAAA,QACZ,IAAI,QAAQ,CAAA,CAAE,GAAA,CAAI,IAAI,OAAA,CAAQ,SAAA,EAAW,UAAU,CAAA,EAAG;AAAA,UACpD,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,GAAA,CAAI,OAAA;AAAA,UACnB,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,OAAO,UAAA,CAAW,IAAA,CAAK,OAAO;AAAA,SACtD,CAAA;AAAA,QACD,CAAA,CAAE;AAAA,OACJ;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,qBAAqB,KAAK,CAAA;AACxC,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,KAAA,EAAO;AAAA,SACN,GAAG,CAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,OAAA,CAAQ,QAAA,CAAS,aAAa,MAAA,EAAQ;AAAA,IACpC,WAAA,EAAa,8BAAA;AAAA,IACb,YAAA,EAAc,KAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX,CAAA;AAID,EAAA,MAAM,WAAA,GAAc,IAAIA,SAAAA,EAAK;AAG7B,EAAA,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,OAAO,CAAA,KAAW;AAC7C,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAEzB,IAAA,MAAM,cAAc,MAAMG,SAAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAqK1B,IAAA,MAAM,eAAe,IAAA,GAAO;AAAA,MAC1B,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAA,IAAS,OAAA;AAAA,MACjC,KAAA,EAAO,KAAK,KAAA,IAAS,mBAAA;AAAA,MACrB,IAAA,EAAM,KAAK,IAAA,IAAQ;AAAA,KACrB,GAAI,MAAA;AAEJ,IAAA,OAAO,CAAA,CAAE,IAAA;AAAA,MACPG,+BAAA,CAAc;AAAA,QACZ,KAAA,EAAO,oBAAA;AAAA,QACP,OAAA,EAAS,WAAA;AAAA,QACT,IAAA,EAAM,YAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACd;AAAA,KACH;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,OAAA,CAAQ,QAAA,CAAS,4BAA4B,WAAA,EAAa;AAAA,IACxD,WAAA,EAAa,2BAAA;AAAA,IACb,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX,CAAA;AAGD,EAAA,OAAA,CAAQ,WAAA,CAAY,aAAa,mCAAA,EAAqC;AAAA,IACpE,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,EAAA;AAAA,IACP,WAAA,EAAa,CAAC,YAAY;AAAA,GAC3B,CAAA;AAGD,EAAA,OAAA,CAAQ,SAAA,CAAU;AAAA,IAChB,UAAU,YAAY;AACpB,MAAA,OAAA,CAAQ,KAAK,mCAA8B,CAAA;AAAA,IAC7C,CAAA;AAAA,IACA,YAAY,YAAY;AACtB,MAAA,OAAA,CAAQ,KAAK,qCAAgC,CAAA;AAAA,IAC/C;AAAA,GACD,CAAA;AAED,EAAA,OAAO,QAAQ,KAAA,EAAM;AACvB;AAEO,IAAM,iBAAiB,oBAAA,EAAqB;ACjenD,IAAM,sBAAA,GAAyBD,MAAE,MAAA,CAAO;AAAA,EACtC,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,MAAM,yBAAyB;AACnD,CAAC,CAAA;AAEM,SAAS,yBAAA,GAAoC;AAClD,EAAA,MAAM,eAAA,GAAkB,IAAIL,SAAAA,EAAK;AAGjC,EAAA,eAAA,CAAgB,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA,KAAW;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAC9B,MAAA,MAAM,UAAA,GAAa,sBAAA,CAAuB,SAAA,CAAU,IAAI,CAAA;AAExD,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA,EAAS,WAAW,KAAA,CAAM;AAAA,WACzB,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,UAAA,CAAW,IAAA;AAC7B,MAAA,MAAM,eAAA,GAAkB,MAAM,WAAA,EAAY;AAC1C,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AAGjB,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAK,KAAK,EAAA,GAAK,GAAA;AAC3C,MAAA,MAAM,WAAA,GAAc,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAIpC,CAAA,CAAE,IAAA,CAAK,eAAA,EAAiB,UAAU,EAAE,KAAA,EAAM;AAE3C,MAAA,MAAM,gBAAA,GAAmB,CAAA;AACzB,MAAA,IAAI,WAAA,IAAe,WAAA,CAAY,KAAA,IAAS,gBAAA,EAAkB;AACxD,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,IAAA,GAAO,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAI7B,CAAA,CAAE,IAAA,CAAK,eAAe,CAAA,CAAE,KAAA,EAAM;AAE/B,MAAA,MAAM,aAAA,GAAgB,KAAA;AAEtB,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,aAAA,EAAe;AAE3B,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,SAAA,EAAW;AAC3B,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAGA,MAAA,MAAM,QAAQ,MAAA,CAAO,UAAA,EAAW,GAAI,GAAA,GAAM,OAAO,UAAA,EAAW;AAC5D,MAAA,MAAM,OAAA,GAAU,OAAO,UAAA,EAAW;AAClC,MAAA,MAAM,iBAAA,GAAoB,EAAA;AAC1B,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAK,oBAAoB,EAAA,GAAK,GAAA;AAGzD,MAAA,MAAM,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAIhB,CAAA,CAAE,IAAA;AAAA,QACD,OAAA;AAAA,QACA,eAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,KAAK,GAAA,EAAI;AAAA,QACT,CAAA,CAAE,IAAI,MAAA,CAAO,kBAAkB,KAAK,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,iBAAiB,CAAA,IAAK,SAAA;AAAA,QACvE,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,YAAY,CAAA,IAAK;AAAA,QAC9B,GAAA,EAAI;AAGN,MAAA,MAAM,UAAU,IAAI,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,MAAA;AACnC,MAAA,MAAM,SAAA,GAAY,CAAA,EAAG,OAAO,CAAA,8BAAA,EAAiC,KAAK,CAAA,CAAA;AAGlE,MAAA,IAAI;AACF,QAAA,MAAMO,YAAAA,GAAc,CAAA,CAAE,GAAA,CAAI,OAAA,EAAS,IAAI,OAAO,CAAA;AAC9C,QAAA,IAAIA,YAAAA,IAAeA,aAAY,SAAA,EAAW;AACxC,UAAA,MAAMA,aAAY,SAAA,CAAU;AAAA,YAC1B,EAAA,EAAI,eAAA;AAAA,YACJ,OAAA,EAAS,4BAAA;AAAA,YACT,IAAA,EAAM,oBAAA,CAAqB,SAAA,EAAW,iBAAiB;AAAA,WACxD,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,MAAM,4BAA4B,CAAA;AAE1C,UAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,eAAA,EAAkB,eAAe,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE,CAAA;AAAA,QAC/D;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,oCAAoC,KAAK,CAAA;AACvD,QAAA,OAAO,EAAE,IAAA,CAAK;AAAA,UACZ,KAAA,EAAO;AAAA,WACN,GAAG,CAAA;AAAA,MACR;AAEA,MAAA,OAAO,EAAE,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,6EAAA;AAAA;AAAA,QAET,GAAI,CAAA,CAAE,GAAA,CAAI,gBAAgB,aAAA,IAAiB,EAAE,UAAU,SAAA;AAAU,OAClE,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,KAAK,CAAA;AAChD,MAAA,OAAO,EAAE,IAAA,CAAK,EAAE,KAAA,EAAO,2BAAA,IAA+B,GAAG,CAAA;AAAA,IAC3D;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,eAAA,CAAgB,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA,KAAW;AAC/C,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAEjC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,OAAO,CAAA,CAAE,SAAS,sCAAsC,CAAA;AAAA,MAC1D;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,GAAA,CAAI,EAAA;AAGjB,MAAA,MAAM,SAAA,GAAY,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA;AAAA,MAAA,CAGlC,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA,CAAE,KAAA,EAAM;AAErB,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO,CAAA,CAAE,SAAS,iDAAiD,CAAA;AAAA,MACrE;AAGA,MAAA,IAAI,SAAA,CAAU,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,EAAG;AACrC,QAAA,OAAO,CAAA,CAAE,SAAS,+CAA+C,CAAA;AAAA,MACnE;AAGA,MAAA,IAAI,IAAA,GAAO,MAAM,EAAA,CAAG,OAAA,CAAQ;AAAA;AAAA,MAAA,CAE3B,CAAA,CAAE,IAAA,CAAK,SAAA,CAAU,UAAU,EAAE,KAAA,EAAM;AAEpC,MAAA,MAAM,aAAA,GAAgB,KAAA;AAEtB,MAAA,IAAI,CAAC,QAAQ,aAAA,EAAe;AAE1B,QAAA,MAAM,MAAA,GAAS,OAAO,UAAA,EAAW;AACjC,QAAA,MAAM,WAAW,SAAA,CAAU,UAAA,CAAW,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAClD,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,QAAA,MAAM,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAKhB,CAAA,CAAE,IAAA;AAAA,UACD,MAAA;AAAA,UACA,SAAA,CAAU,UAAA;AAAA,UACV,QAAA;AAAA,UACA,QAAA;AAAA,UACA,EAAA;AAAA,UACA,GAAA;AAAA,UACA;AAAA,UACA,GAAA,EAAI;AAEN,QAAA,IAAA,GAAO;AAAA,UACL,EAAA,EAAI,MAAA;AAAA,UACJ,OAAO,SAAA,CAAU,UAAA;AAAA,UACjB,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACR;AAAA,MACF,CAAA,MAAA,IAAW,CAAC,IAAA,EAAM;AAChB,QAAA,OAAO,CAAA,CAAE,SAAS,mDAAmD,CAAA;AAAA,MACvE;AAGA,MAAA,MAAM,GAAG,OAAA,CAAQ;AAAA;AAAA;AAAA;AAAA,MAAA,CAIhB,CAAA,CAAE,KAAK,IAAA,CAAK,GAAA,IAAO,SAAA,CAAU,EAAE,EAAE,GAAA,EAAI;AAGtC,MAAA,MAAM,QAAA,GAAW,MAAMC,6BAAA,CAAY,aAAA;AAAA,QACjC,IAAA,CAAK,EAAA;AAAA,QACL,IAAA,CAAK,KAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AAGA,MAAAA,6BAAA,CAAY,aAAA,CAAc,GAAG,QAAQ,CAAA;AAGrC,MAAA,MAAM,GAAG,OAAA,CAAQ;AAAA;AAAA,MAAA,CAEhB,CAAA,CAAE,KAAK,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,EAAE,EAAE,GAAA,EAAI;AAGjC,MAAA,OAAO,CAAA,CAAE,SAAS,iDAAiD,CAAA;AAAA,IACrE,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,kCAAkC,KAAK,CAAA;AACrD,MAAA,OAAO,CAAA,CAAE,SAAS,yCAAyC,CAAA;AAAA,IAC7D;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,iBAAA;AAAA,IACN,OAAA,EAAS,OAAA;AAAA,IACT,WAAA,EAAa,mDAAA;AAAA,IACb,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,cAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,IACA,YAAA,EAAc,CAAC,OAAO,CAAA;AAAA,IAEtB,QAAQ,CAAC;AAAA,MACP,IAAA,EAAM,kBAAA;AAAA,MACN,OAAA,EAAS,eAAA;AAAA,MACT,WAAA,EAAa,qCAAA;AAAA,MACb,YAAA,EAAc;AAAA,KACf,CAAA;AAAA,IAED,MAAM,QAAQ,OAAA,EAAwB;AACpC,MAAA,OAAA,CAAQ,IAAI,sCAAsC,CAAA;AAAA,IAEpD,CAAA;AAAA,IAEA,MAAM,SAAS,OAAA,EAAwB;AACrC,MAAA,OAAA,CAAQ,IAAI,qCAAqC,CAAA;AACjD,MAAA,OAAA,CAAQ,IAAI,oDAAoD,CAAA;AAAA,IAClE,CAAA;AAAA,IAEA,MAAM,WAAW,OAAA,EAAwB;AACvC,MAAA,OAAA,CAAQ,IAAI,uCAAuC,CAAA;AAAA,IACrD,CAAA;AAAA,IAEA,MAAM,UAAU,OAAA,EAAwB;AACtC,MAAA,OAAA,CAAQ,IAAI,wCAAwC,CAAA;AAAA,IAGtD;AAAA,GACF;AACF;AAKA,SAAS,oBAAA,CAAqB,WAAmB,aAAA,EAA+B;AAC9E,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,qBAAA,EAkFc,SAAS,CAAA;AAAA;;AAAA,wDAAA,EAGqB,aAAa,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;AAgBlE;AAEe,yBAAA;;;ACtPR,SAAS,gBAAA,CAAiB,MAAA,GAAwB,EAAC,EAAe;AACvE,EAAA,MAAM,GAAA,GAAM,IAAIR,SAAAA,EAAmD;AAGnE,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,IAAWS,gCAAA,EAAe;AACpD,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,IAAQ,YAAA;AAG/B,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,OAAO,CAAA,EAAG,IAAA,KAAS;AAC9B,IAAA,CAAA,CAAE,GAAA,CAAI,cAAc,UAAU,CAAA;AAC9B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAKC,mCAAA,EAAmB,CAAA;AAGhC,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAKC,qCAAA,CAAoB,MAAM,CAAC,CAAA;AAGxC,EAAA,IAAI,MAAA,CAAO,YAAY,UAAA,EAAY;AACjC,IAAA,KAAA,MAAW,UAAA,IAAc,MAAA,CAAO,UAAA,CAAW,UAAA,EAAY;AACrD,MAAA,GAAA,CAAI,GAAA,CAAI,KAAK,UAAU,CAAA;AAAA,IACzB;AAAA,EACF;AAGA,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,OAAO,EAAA,EAAI,IAAA,KAAS;AAE/B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,OAAO,EAAA,EAAI,IAAA,KAAS;AAE/B,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAC,CAAA;AAGD,EAAA,IAAI,MAAA,CAAO,YAAY,SAAA,EAAW;AAChC,IAAA,KAAA,MAAW,UAAA,IAAc,MAAA,CAAO,UAAA,CAAW,SAAA,EAAW;AACpD,MAAA,GAAA,CAAI,GAAA,CAAI,KAAK,UAAU,CAAA;AAAA,IACzB;AAAA,EACF;AAKA,EAAA,GAAA,CAAI,KAAA,CAAM,QAAQC,6BAAS,CAAA;AAC3B,EAAA,GAAA,CAAI,KAAA,CAAM,cAAcC,mCAAc,CAAA;AACtC,EAAA,GAAA,CAAI,KAAA,CAAM,eAAeC,oCAAe,CAAA;AACxC,EAAA,GAAA,CAAI,KAAA,CAAM,cAAcC,mCAAc,CAAA;AACtC,EAAA,GAAA,CAAI,KAAA,CAAM,oBAAoBhB,wBAAoB,CAAA;AAClD,EAAA,GAAA,CAAI,KAAA,CAAM,sBAAsBiB,wCAAsB,CAAA;AACtD,EAAA,GAAA,CAAI,KAAA,CAAM,mBAAmBC,qCAAmB,CAAA;AAChD,EAAA,GAAA,CAAI,KAAA,CAAM,uBAAA,EAAyB,8BAAA,EAAgC,CAAA;AACnE,EAAA,GAAA,CAAI,KAAA,CAAM,kBAAkBC,uCAAkB,CAAA;AAC9C,EAAA,GAAA,CAAI,KAAA,CAAM,gBAAgBC,kCAAgB,CAAA;AAC1C,EAAA,GAAA,CAAI,KAAA,CAAM,kBAAkBC,mCAAiB,CAAA;AAC7C,EAAA,GAAA,CAAI,KAAA,CAAM,eAAeC,iCAAe,CAAA;AACxC,EAAA,GAAA,CAAI,KAAA,CAAM,UAAUC,4BAAgB,CAAA;AACpC,EAAA,GAAA,CAAI,KAAA,CAAM,SAASC,8BAAU,CAAA;AAG7B,EAAA,GAAA,CAAI,KAAA,CAAM,KAAKC,sCAAiB,CAAA;AAGhC,EAAA,IAAI,WAAA,CAAY,MAAA,IAAU,WAAA,CAAY,MAAA,CAAO,SAAS,CAAA,EAAG;AACvD,IAAA,KAAA,MAAW,KAAA,IAAS,YAAY,MAAA,EAAQ;AACtC,MAAA,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAGA,EAAA,IAAI,cAAA,CAAe,MAAA,IAAU,cAAA,CAAe,MAAA,CAAO,SAAS,CAAA,EAAG;AAC7D,IAAA,KAAA,MAAW,KAAA,IAAS,eAAe,MAAA,EAAQ;AACzC,MAAA,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAGA,EAAA,MAAM,kBAAkB,yBAAA,EAA0B;AAClD,EAAA,IAAI,eAAA,CAAgB,MAAA,IAAU,eAAA,CAAgB,MAAA,CAAO,SAAS,CAAA,EAAG;AAC/D,IAAA,KAAA,MAAW,KAAA,IAAS,gBAAgB,MAAA,EAAQ;AAC1C,MAAA,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAGA,EAAA,GAAA,CAAI,GAAA,CAAI,UAAA,EAAY,OAAO,CAAA,KAAM;AAC/B,IAAA,IAAI;AAEF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,CAAA,CAAE,IAAI,GAAG,CAAA;AAC7B,MAAA,MAAM,WAAW,GAAA,CAAI,QAAA;AAGrB,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAA;AAEnD,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO,EAAE,QAAA,EAAS;AAAA,MACpB;AAGA,MAAA,MAAM,SAAS,MAAM,CAAA,CAAE,GAAA,CAAI,YAAA,CAAa,IAAI,SAAS,CAAA;AAErD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAO,EAAE,QAAA,EAAS;AAAA,MACpB;AAGA,MAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,MAAA,MAAA,CAAO,cAAc,WAAA,IAAe,OAAA,CAAQ,IAAI,cAAA,EAAgB,MAAA,CAAO,aAAa,WAAW,CAAA;AAC/F,MAAA,MAAA,CAAO,cAAc,kBAAA,IAAsB,OAAA,CAAQ,IAAI,qBAAA,EAAuB,MAAA,CAAO,aAAa,kBAAkB,CAAA;AACpH,MAAA,OAAA,CAAQ,GAAA,CAAI,iBAAiB,0BAA0B,CAAA;AACvD,MAAA,OAAA,CAAQ,GAAA,CAAI,+BAA+B,GAAG,CAAA;AAC9C,MAAA,OAAA,CAAQ,GAAA,CAAI,gCAAgC,oBAAoB,CAAA;AAChE,MAAA,OAAA,CAAQ,GAAA,CAAI,gCAAgC,cAAc,CAAA;AAE1D,MAAA,OAAO,IAAI,QAAA,CAAS,MAAA,CAAO,IAAA,EAAa;AAAA,QACtC;AAAA,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,uBAAuB,KAAK,CAAA;AAC1C,MAAA,OAAO,EAAE,QAAA,EAAS;AAAA,IACpB;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAGA,EAAA,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,CAAC,CAAA,KAAM;AAClB,IAAA,OAAO,CAAA,CAAE,SAAS,aAAa,CAAA;AAAA,EACjC,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,CAAC,CAAA,KAAM;AACxB,IAAA,OAAO,EAAE,IAAA,CAAK;AAAA,MACZ,IAAA,EAAM,OAAA;AAAA,MACN,OAAA,EAAS,UAAA;AAAA,MACT,MAAA,EAAQ,SAAA;AAAA,MACR,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACnC,CAAA;AAAA,EACH,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,QAAA,CAAS,CAAC,CAAA,KAAM;AAClB,IAAA,OAAO,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,aAAa,MAAA,EAAQ,GAAA,IAAO,GAAG,CAAA;AAAA,EACxD,CAAC,CAAA;AAGD,EAAA,GAAA,CAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,CAAA,KAAM;AACtB,IAAA,OAAA,CAAQ,MAAM,GAAG,CAAA;AACjB,IAAA,OAAO,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,yBAAyB,MAAA,EAAQ,GAAA,IAAO,GAAG,CAAA;AAAA,EACpE,CAAC,CAAA;AAED,EAAA,OAAO,GAAA;AACT;AAQO,SAAS,oBAAoB,IAAA,EAAwB;AAC1D,EAAA,OAAA,CAAQ,KAAK,oEAAoE,CAAA;AAEnF;AAQO,SAAS,gBAAgB,IAAA,EAAwB;AACtD,EAAA,OAAA,CAAQ,KAAK,gEAAgE,CAAA;AAE/E;ACjTO,SAAS,SAASC,IAAA,EAAgB;AACvC,EAAA,OAAOC,UAAA,CAAQD,IAAA,EAAI,EAAE,MAAA,EAAAE,gCAAA,EAAQ,CAAA;AAC/B;;;AC8SO,IAAM,UAAUC,iCAAA,CAAY","file":"index.cjs","sourcesContent":["import { D1Database } from '@cloudflare/workers-types'\n\nexport interface TruncateResult {\n success: boolean\n message: string\n tablesCleared: string[]\n adminUserPreserved: boolean\n errors?: string[]\n}\n\nexport interface DatabaseStats {\n tables: Array<{\n name: string\n rowCount: number\n }>\n totalRows: number\n}\n\nexport interface TableData {\n tableName: string\n columns: string[]\n rows: any[]\n totalRows: number\n}\n\nexport class DatabaseToolsService {\n constructor(private db: D1Database) {}\n\n /**\n * Get database statistics\n */\n async getDatabaseStats(): Promise<DatabaseStats> {\n const tables = await this.getTables()\n const stats: DatabaseStats = {\n tables: [],\n totalRows: 0\n }\n\n for (const tableName of tables) {\n try {\n const result = await this.db.prepare(`SELECT COUNT(*) as count FROM ${tableName}`).first()\n const rowCount = (result?.count as number) || 0\n \n stats.tables.push({\n name: tableName,\n rowCount\n })\n stats.totalRows += rowCount\n } catch (error) {\n // Skip tables that can't be counted (might be views or system tables)\n console.warn(`Could not count rows in table ${tableName}:`, error)\n }\n }\n\n return stats\n }\n\n /**\n * Get all tables in the database\n */\n private async getTables(): Promise<string[]> {\n const result = await this.db.prepare(`\n SELECT name FROM sqlite_master \n WHERE type='table' \n AND name NOT LIKE 'sqlite_%'\n ORDER BY name\n `).all()\n\n return result.results?.map((row: any) => row.name) || []\n }\n\n /**\n * Truncate all data except admin user\n */\n async truncateAllData(adminEmail: string): Promise<TruncateResult> {\n const errors: string[] = []\n const tablesCleared: string[] = []\n let adminUserPreserved = false\n\n try {\n // First, preserve the admin user data\n const adminUser = await this.db.prepare(\n 'SELECT * FROM users WHERE email = ? AND role = ?'\n ).bind(adminEmail, 'admin').first()\n\n if (!adminUser) {\n return {\n success: false,\n message: 'Admin user not found. Operation cancelled for safety.',\n tablesCleared: [],\n adminUserPreserved: false,\n errors: ['Admin user not found']\n }\n }\n\n // Define tables to truncate (excluding system tables)\n const tablesToTruncate = [\n 'content',\n 'content_versions', \n 'content_workflow_status',\n 'collections',\n 'media',\n 'sessions',\n 'notifications',\n 'api_tokens',\n 'workflow_history',\n 'scheduled_content',\n 'faqs',\n 'faq_categories',\n 'plugins',\n 'plugin_settings',\n 'email_templates',\n 'email_themes'\n ]\n\n // Check which tables exist\n const existingTables = await this.getTables()\n const tablesToClear = tablesToTruncate.filter(table => \n existingTables.includes(table)\n )\n\n // Clear all data except users table\n for (const tableName of tablesToClear) {\n try {\n await this.db.prepare(`DELETE FROM ${tableName}`).run()\n tablesCleared.push(tableName)\n } catch (error) {\n errors.push(`Failed to clear table ${tableName}: ${error}`)\n console.error(`Error clearing table ${tableName}:`, error)\n }\n }\n\n // Clear users table but preserve admin\n try {\n await this.db.prepare('DELETE FROM users WHERE email != ? OR role != ?')\n .bind(adminEmail, 'admin').run()\n \n // Verify admin user still exists\n const verifyAdmin = await this.db.prepare(\n 'SELECT id FROM users WHERE email = ? AND role = ?'\n ).bind(adminEmail, 'admin').first()\n\n adminUserPreserved = !!verifyAdmin\n tablesCleared.push('users (non-admin)')\n } catch (error) {\n errors.push(`Failed to clear non-admin users: ${error}`)\n console.error('Error clearing non-admin users:', error)\n }\n\n // Reset auto-increment counters if supported\n try {\n await this.db.prepare('DELETE FROM sqlite_sequence').run()\n } catch (error) {\n // sqlite_sequence might not exist, ignore\n }\n\n const message = errors.length > 0 \n ? `Truncation completed with ${errors.length} errors. ${tablesCleared.length} tables cleared.`\n : `Successfully truncated database. ${tablesCleared.length} tables cleared.`\n\n return {\n success: errors.length === 0,\n message,\n tablesCleared,\n adminUserPreserved,\n errors: errors.length > 0 ? errors : undefined\n }\n\n } catch (error) {\n return {\n success: false,\n message: `Database truncation failed: ${error}`,\n tablesCleared,\n adminUserPreserved,\n errors: [String(error)]\n }\n }\n }\n\n /**\n * Create a backup of current data (simplified version)\n */\n async createBackup(): Promise<{ success: boolean; message: string; backupId?: string }> {\n try {\n const backupId = `backup_${Date.now()}`\n const stats = await this.getDatabaseStats()\n \n // In a real implementation, this would export data to a file or cloud storage\n // For now, we'll just log the stats and return success\n console.log(`Backup ${backupId} created with ${stats.totalRows} total rows`)\n \n return {\n success: true,\n message: `Backup created successfully (${stats.totalRows} rows)`,\n backupId\n }\n } catch (error) {\n return {\n success: false,\n message: `Backup failed: ${error}`\n }\n }\n }\n\n /**\n * Get table data with optional pagination and sorting\n */\n async getTableData(\n tableName: string,\n limit: number = 100,\n offset: number = 0,\n sortColumn?: string,\n sortDirection: 'asc' | 'desc' = 'asc'\n ): Promise<TableData> {\n try {\n // Validate table name to prevent SQL injection\n const tables = await this.getTables()\n if (!tables.includes(tableName)) {\n throw new Error(`Table ${tableName} not found`)\n }\n\n // Get column names\n const pragmaResult = await this.db.prepare(`PRAGMA table_info(${tableName})`).all()\n const columns = pragmaResult.results?.map((col: any) => col.name) || []\n\n // Validate sort column if provided\n if (sortColumn && !columns.includes(sortColumn)) {\n sortColumn = undefined\n }\n\n // Get total row count\n const countResult = await this.db.prepare(`SELECT COUNT(*) as count FROM ${tableName}`).first()\n const totalRows = (countResult?.count as number) || 0\n\n // Build query with optional sorting\n let query = `SELECT * FROM ${tableName}`\n if (sortColumn) {\n query += ` ORDER BY ${sortColumn} ${sortDirection.toUpperCase()}`\n }\n query += ` LIMIT ${limit} OFFSET ${offset}`\n\n // Get paginated data\n const dataResult = await this.db.prepare(query).all()\n\n return {\n tableName,\n columns,\n rows: dataResult.results || [],\n totalRows\n }\n } catch (error) {\n throw new Error(`Failed to fetch table data: ${error}`)\n }\n }\n\n /**\n * Validate database integrity\n */\n async validateDatabase(): Promise<{ valid: boolean; issues: string[] }> {\n const issues: string[] = []\n\n try {\n // Check critical tables exist\n const requiredTables = ['users', 'content', 'collections']\n const existingTables = await this.getTables()\n\n for (const table of requiredTables) {\n if (!existingTables.includes(table)) {\n issues.push(`Critical table missing: ${table}`)\n }\n }\n\n // Check admin user exists\n const adminCount = await this.db.prepare(\n 'SELECT COUNT(*) as count FROM users WHERE role = ?'\n ).bind('admin').first()\n\n if ((adminCount?.count as number) === 0) {\n issues.push('No admin users found')\n }\n\n // Run SQLite integrity check\n try {\n const integrityResult = await this.db.prepare('PRAGMA integrity_check').first()\n if (integrityResult && (integrityResult as any).integrity_check !== 'ok') {\n issues.push(`Database integrity check failed: ${(integrityResult as any).integrity_check}`)\n }\n } catch (error) {\n issues.push(`Could not run integrity check: ${error}`)\n }\n\n } catch (error) {\n issues.push(`Validation error: ${error}`)\n }\n\n return {\n valid: issues.length === 0,\n issues\n }\n }\n}","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\n\nexport interface DatabaseTablePageData {\n user?: {\n name: string\n email: string\n role: string\n }\n tableName: string\n columns: string[]\n rows: any[]\n totalRows: number\n currentPage: number\n pageSize: number\n sortColumn?: string\n sortDirection?: 'asc' | 'desc'\n}\n\nexport function renderDatabaseTablePage(data: DatabaseTablePageData): string {\n const totalPages = Math.ceil(data.totalRows / data.pageSize)\n const startRow = (data.currentPage - 1) * data.pageSize + 1\n const endRow = Math.min(data.currentPage * data.pageSize, data.totalRows)\n\n const pageContent = `\n <div class=\"space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <div class=\"flex items-center space-x-3\">\n <a\n href=\"/admin/settings/database-tools\"\n class=\"inline-flex items-center text-sm/6 text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300\"\n >\n <svg class=\"w-5 h-5 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n </svg>\n Back to Database Tools\n </a>\n </div>\n <h1 class=\"mt-2 text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Table: ${data.tableName}</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">\n Showing ${startRow.toLocaleString()} - ${endRow.toLocaleString()} of ${data.totalRows.toLocaleString()} rows\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 flex items-center space-x-3\">\n <div class=\"flex items-center space-x-2\">\n <label for=\"pageSize\" class=\"text-sm font-medium text-zinc-700 dark:text-zinc-300\">\n Rows per page:\n </label>\n <select\n id=\"pageSize\"\n onchange=\"changePageSize(this.value)\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm cursor-pointer\"\n >\n <option value=\"10\" ${data.pageSize === 10 ? 'selected' : ''}>10</option>\n <option value=\"20\" ${data.pageSize === 20 ? 'selected' : ''}>20</option>\n <option value=\"50\" ${data.pageSize === 50 ? 'selected' : ''}>50</option>\n <option value=\"100\" ${data.pageSize === 100 ? 'selected' : ''}>100</option>\n <option value=\"200\" ${data.pageSize === 200 ? 'selected' : ''}>200</option>\n </select>\n </div>\n <button\n onclick=\"refreshTableData()\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"/>\n </svg>\n Refresh\n </button>\n </div>\n </div>\n\n <!-- Table Card -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden\">\n <!-- Table -->\n <div class=\"overflow-x-auto\">\n <table class=\"min-w-full divide-y divide-zinc-950/10 dark:divide-white/10\">\n <thead class=\"bg-zinc-50 dark:bg-white/5\">\n <tr>\n ${data.columns.map(col => `\n <th\n scope=\"col\"\n class=\"px-4 py-3.5 text-left text-xs font-semibold text-zinc-950 dark:text-white uppercase tracking-wider cursor-pointer hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors\"\n onclick=\"sortTable('${col}')\"\n >\n <div class=\"flex items-center space-x-1\">\n <span>${col}</span>\n ${data.sortColumn === col ? `\n <svg class=\"w-4 h-4 ${data.sortDirection === 'asc' ? '' : 'rotate-180'}\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 15l7-7 7 7\"/>\n </svg>\n ` : `\n <svg class=\"w-4 h-4 text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\"/>\n </svg>\n `}\n </div>\n </th>\n `).join('')}\n </tr>\n </thead>\n <tbody class=\"divide-y divide-zinc-950/5 dark:divide-white/5\">\n ${data.rows.length > 0\n ? data.rows.map((row, idx) => `\n <tr class=\"${idx % 2 === 0 ? 'bg-white dark:bg-zinc-900' : 'bg-zinc-50 dark:bg-zinc-900/50'}\">\n ${data.columns.map(col => `\n <td class=\"px-4 py-3 text-sm text-zinc-700 dark:text-zinc-300 whitespace-nowrap max-w-xs overflow-hidden text-ellipsis\" title=\"${escapeHtml(String(row[col] ?? ''))}\">\n ${formatCellValue(row[col])}\n </td>\n `).join('')}\n </tr>\n `).join('')\n : `\n <tr>\n <td colspan=\"${data.columns.length}\" class=\"px-4 py-12 text-center text-sm text-zinc-500 dark:text-zinc-400\">\n <svg class=\"w-12 h-12 mx-auto mb-4 text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4\"/>\n </svg>\n <p>No data in this table</p>\n </td>\n </tr>\n `\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n ${totalPages > 1 ? `\n <div class=\"flex items-center justify-between border-t border-zinc-950/10 dark:border-white/10 bg-zinc-50 dark:bg-zinc-900/50 px-4 py-3 sm:px-6\">\n <div class=\"flex flex-1 justify-between sm:hidden\">\n <button\n onclick=\"goToPage(${data.currentPage - 1})\"\n ${data.currentPage === 1 ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-lg px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-100 dark:hover:bg-zinc-800 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Previous\n </button>\n <button\n onclick=\"goToPage(${data.currentPage + 1})\"\n ${data.currentPage === totalPages ? 'disabled' : ''}\n class=\"relative ml-3 inline-flex items-center rounded-lg px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-100 dark:hover:bg-zinc-800 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n </button>\n </div>\n <div class=\"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between\">\n <div>\n <p class=\"text-sm text-zinc-700 dark:text-zinc-300\">\n Page <span class=\"font-medium\">${data.currentPage}</span> of <span class=\"font-medium\">${totalPages}</span>\n </p>\n </div>\n <div>\n <nav class=\"isolate inline-flex -space-x-px rounded-lg shadow-sm\" aria-label=\"Pagination\">\n <button\n onclick=\"goToPage(${data.currentPage - 1})\"\n ${data.currentPage === 1 ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-l-lg px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800 focus:z-20 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <span class=\"sr-only\">Previous</span>\n <svg class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n ${generatePageNumbers(data.currentPage, totalPages)}\n\n <button\n onclick=\"goToPage(${data.currentPage + 1})\"\n ${data.currentPage === totalPages ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-r-lg px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800 focus:z-20 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <span class=\"sr-only\">Next</span>\n <svg class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </nav>\n </div>\n </div>\n </div>\n ` : ''}\n </div>\n </div>\n\n <script>\n const currentTableName = '${data.tableName}';\n let currentPage = ${data.currentPage};\n let currentPageSize = ${data.pageSize};\n let currentSort = '${data.sortColumn || ''}';\n let currentSortDir = '${data.sortDirection || 'asc'}';\n\n function goToPage(page) {\n if (page < 1 || page > ${totalPages}) return;\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('pageSize', currentPageSize);\n if (currentSort) {\n params.set('sort', currentSort);\n params.set('dir', currentSortDir);\n }\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function sortTable(column) {\n let newDir = 'asc';\n if (currentSort === column && currentSortDir === 'asc') {\n newDir = 'desc';\n }\n\n const params = new URLSearchParams();\n params.set('page', '1');\n params.set('pageSize', currentPageSize);\n params.set('sort', column);\n params.set('dir', newDir);\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function changePageSize(newSize) {\n const params = new URLSearchParams();\n params.set('page', '1');\n params.set('pageSize', newSize);\n if (currentSort) {\n params.set('sort', currentSort);\n params.set('dir', currentSortDir);\n }\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function refreshTableData() {\n window.location.reload();\n }\n\n function formatCellValue(value) {\n if (value === null || value === undefined) {\n return '<span class=\"text-zinc-400 dark:text-zinc-500 italic\">null</span>';\n }\n if (typeof value === 'boolean') {\n return \\`<span class=\"px-2 py-0.5 rounded text-xs font-medium \\${value ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-400'}\">\\${value}</span>\\`;\n }\n if (typeof value === 'object') {\n return '<span class=\"text-xs font-mono text-zinc-600 dark:text-zinc-400\">' + JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? '...' : '') + '</span>';\n }\n const str = String(value);\n if (str.length > 100) {\n return escapeHtml(str.substring(0, 100)) + '...';\n }\n return escapeHtml(str);\n }\n\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return String(text).replace(/[&<>\"']/g, m => map[m]);\n }\n </script>\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: `Table: ${data.tableName}`,\n pageTitle: `Database: ${data.tableName}`,\n currentPath: `/admin/database-tools/tables/${data.tableName}`,\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}\n\nfunction generatePageNumbers(currentPage: number, totalPages: number): string {\n const pages: number[] = []\n const maxVisible = 7\n\n if (totalPages <= maxVisible) {\n for (let i = 1; i <= totalPages; i++) {\n pages.push(i)\n }\n } else {\n if (currentPage <= 4) {\n for (let i = 1; i <= 5; i++) pages.push(i)\n pages.push(-1) // ellipsis\n pages.push(totalPages)\n } else if (currentPage >= totalPages - 3) {\n pages.push(1)\n pages.push(-1) // ellipsis\n for (let i = totalPages - 4; i <= totalPages; i++) pages.push(i)\n } else {\n pages.push(1)\n pages.push(-1) // ellipsis\n for (let i = currentPage - 1; i <= currentPage + 1; i++) pages.push(i)\n pages.push(-1) // ellipsis\n pages.push(totalPages)\n }\n }\n\n return pages.map(page => {\n if (page === -1) {\n return `\n <span class=\"relative inline-flex items-center px-4 py-2 text-sm font-semibold text-zinc-700 dark:text-zinc-300 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700\">\n ...\n </span>\n `\n }\n\n const isActive = page === currentPage\n return `\n <button\n onclick=\"goToPage(${page})\"\n class=\"relative inline-flex items-center px-4 py-2 text-sm font-semibold ${\n isActive\n ? 'z-10 bg-indigo-600 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'\n : 'text-zinc-900 dark:text-zinc-100 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800'\n }\"\n >\n ${page}\n </button>\n `\n }).join('')\n}\n\nfunction escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n }\n return String(text).replace(/[&<>\"']/g, m => map[m] || m)\n}\n\nfunction formatCellValue(value: any): string {\n if (value === null || value === undefined) {\n return '<span class=\"text-zinc-400 dark:text-zinc-500 italic\">null</span>'\n }\n if (typeof value === 'boolean') {\n return `<span class=\"px-2 py-0.5 rounded text-xs font-medium ${value ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-400'}\">${value}</span>`\n }\n if (typeof value === 'object') {\n return '<span class=\"text-xs font-mono text-zinc-600 dark:text-zinc-400\">' + JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? '...' : '') + '</span>'\n }\n const str = String(value)\n if (str.length > 100) {\n return escapeHtml(str.substring(0, 100)) + '...'\n }\n return escapeHtml(str)\n}\n","import { Hono } from 'hono'\nimport { DatabaseToolsService } from './services/database-service'\nimport { renderDatabaseTablePage, DatabaseTablePageData } from '../../../templates/pages/admin-database-table.template'\nimport { requireAuth } from '../../../middleware'\n\ntype Bindings = {\n DB: D1Database\n}\n\ntype Variables = {\n user?: {\n userId: string\n email: string\n role: string\n }\n}\n\nexport function createDatabaseToolsAdminRoutes() {\n const router = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n // Apply authentication middleware\n router.use('*', requireAuth())\n\n // Get database statistics\n router.get('/api/stats', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const stats = await service.getDatabaseStats()\n\n return c.json({\n success: true,\n data: stats\n })\n } catch (error) {\n console.error('Error fetching database stats:', error)\n return c.json({ \n success: false, \n error: 'Failed to fetch database statistics' \n }, 500)\n }\n })\n\n // Truncate all data except admin user\n router.post('/api/truncate', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const body = await c.req.json()\n const { confirmText } = body\n\n // Require confirmation text for safety\n if (confirmText !== 'TRUNCATE ALL DATA') {\n return c.json({\n success: false,\n error: 'Invalid confirmation text. Operation cancelled.'\n }, 400)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const result = await service.truncateAllData(user.email)\n\n return c.json({\n success: result.success,\n message: result.message,\n data: {\n tablesCleared: result.tablesCleared,\n adminUserPreserved: result.adminUserPreserved,\n errors: result.errors\n }\n })\n } catch (error) {\n console.error('Error truncating database:', error)\n return c.json({ \n success: false, \n error: 'Failed to truncate database' \n }, 500)\n }\n })\n\n // Create backup\n router.post('/api/backup', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const result = await service.createBackup()\n\n return c.json({\n success: result.success,\n message: result.message,\n data: {\n backupId: result.backupId\n }\n })\n } catch (error) {\n console.error('Error creating backup:', error)\n return c.json({ \n success: false, \n error: 'Failed to create backup' \n }, 500)\n }\n })\n\n // Validate database\n router.get('/api/validate', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.json({\n success: false,\n error: 'Unauthorized. Admin access required.'\n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const validation = await service.validateDatabase()\n\n return c.json({\n success: true,\n data: validation\n })\n } catch (error) {\n console.error('Error validating database:', error)\n return c.json({\n success: false,\n error: 'Failed to validate database'\n }, 500)\n }\n })\n\n // Get table data (API endpoint)\n router.get('/api/tables/:tableName', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.json({\n success: false,\n error: 'Unauthorized. Admin access required.'\n }, 403)\n }\n\n const tableName = c.req.param('tableName')\n const limit = parseInt(c.req.query('limit') || '100')\n const offset = parseInt(c.req.query('offset') || '0')\n const sortColumn = c.req.query('sort')\n const sortDirection = (c.req.query('dir') || 'asc') as 'asc' | 'desc'\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const tableData = await service.getTableData(tableName, limit, offset, sortColumn, sortDirection)\n\n return c.json({\n success: true,\n data: tableData\n })\n } catch (error) {\n console.error('Error fetching table data:', error)\n return c.json({\n success: false,\n error: `Failed to fetch table data: ${error}`\n }, 500)\n }\n })\n\n // View table data page\n router.get('/tables/:tableName', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.redirect('/admin/login')\n }\n\n const tableName = c.req.param('tableName')\n const page = parseInt(c.req.query('page') || '1')\n const pageSize = parseInt(c.req.query('pageSize') || '20')\n const sortColumn = c.req.query('sort')\n const sortDirection = (c.req.query('dir') || 'asc') as 'asc' | 'desc'\n\n const offset = (page - 1) * pageSize\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const tableData = await service.getTableData(tableName, pageSize, offset, sortColumn, sortDirection)\n\n const pageData: DatabaseTablePageData = {\n user: {\n name: user.email.split('@')[0] || 'Unknown',\n email: user.email,\n role: user.role\n },\n tableName: tableData.tableName,\n columns: tableData.columns,\n rows: tableData.rows,\n totalRows: tableData.totalRows,\n currentPage: page,\n pageSize: pageSize,\n sortColumn: sortColumn,\n sortDirection: sortDirection\n }\n\n return c.html(renderDatabaseTablePage(pageData))\n } catch (error) {\n console.error('Error rendering table page:', error)\n return c.text(`Error: ${error}`, 500)\n }\n })\n\n return router\n}","/**\n * Email Plugin\n *\n * Send transactional emails using Resend\n * Handles registration, verification, password reset, and one-time codes\n */\n\nimport { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport { PluginBuilder } from '../../sdk/plugin-builder'\nimport type { Plugin } from '@sonicjs-cms/core'\nimport { renderAdminLayout } from '../../../templates/layouts/admin-layout-v2.template'\n\nexport function createEmailPlugin(): Plugin {\n const builder = PluginBuilder.create({\n name: 'email',\n version: '1.0.0-beta.1',\n description: 'Send transactional emails using Resend'\n })\n\n // Add plugin metadata\n builder.metadata({\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n license: 'MIT',\n compatibility: '^2.0.0'\n })\n\n // Create the Email Settings route\n const emailRoutes = new Hono()\n\n emailRoutes.get('/settings', async (c: any) => {\n const user = c.get('user') as { email?: string; role?: string; name?: string } | undefined\n const db = c.env.DB\n\n // Load current settings from database\n const plugin = await db.prepare(`\n SELECT settings FROM plugins WHERE id = 'email'\n `).first() as { settings: string | null } | null\n\n const settings = plugin?.settings ? JSON.parse(plugin.settings) : {}\n\n const contentHTML = await html`\n <div class=\"p-8\">\n <!-- Header -->\n <div class=\"mb-8\">\n <h1 class=\"text-3xl font-bold text-zinc-950 dark:text-white mb-2\">Email Settings</h1>\n <p class=\"text-zinc-600 dark:text-zinc-400\">Configure Resend API for sending transactional emails</p>\n </div>\n\n <!-- Settings Form -->\n <div class=\"max-w-3xl\">\n <!-- Main Settings Card -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 mb-6\">\n <h2 class=\"text-xl font-semibold text-zinc-950 dark:text-white mb-4\">Resend Configuration</h2>\n\n <form id=\"emailSettingsForm\" class=\"space-y-6\">\n <!-- API Key -->\n <div>\n <label for=\"apiKey\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Resend API Key <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"password\"\n id=\"apiKey\"\n name=\"apiKey\"\n value=\"${settings.apiKey || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"re_...\"\n required\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Get your API key from <a href=\"https://resend.com/api-keys\" target=\"_blank\" class=\"text-indigo-600 dark:text-indigo-400 hover:underline\">resend.com/api-keys</a>\n </p>\n </div>\n\n <!-- From Email -->\n <div>\n <label for=\"fromEmail\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n From Email <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"email\"\n id=\"fromEmail\"\n name=\"fromEmail\"\n value=\"${settings.fromEmail || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"noreply@yourdomain.com\"\n required\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Must be a verified domain in Resend\n </p>\n </div>\n\n <!-- From Name -->\n <div>\n <label for=\"fromName\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n From Name <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"fromName\"\n name=\"fromName\"\n value=\"${settings.fromName || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"Your App Name\"\n required\n />\n </div>\n\n <!-- Reply To -->\n <div>\n <label for=\"replyTo\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Reply-To Email\n </label>\n <input\n type=\"email\"\n id=\"replyTo\"\n name=\"replyTo\"\n value=\"${settings.replyTo || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"support@yourdomain.com\"\n />\n </div>\n\n <!-- Logo URL -->\n <div>\n <label for=\"logoUrl\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Logo URL\n </label>\n <input\n type=\"url\"\n id=\"logoUrl\"\n name=\"logoUrl\"\n value=\"${settings.logoUrl || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"https://yourdomain.com/logo.png\"\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Logo to display in email templates\n </p>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex gap-3 pt-4\">\n <button\n type=\"submit\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n Save Settings\n </button>\n <button\n type=\"button\"\n id=\"testEmailBtn\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Send Test Email\n </button>\n <button\n type=\"button\"\n id=\"resetBtn\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Reset\n </button>\n </div>\n </form>\n </div>\n\n <!-- Status Message -->\n <div id=\"statusMessage\" class=\"hidden rounded-xl p-4 mb-6\"></div>\n\n <!-- Info Card -->\n <div class=\"rounded-xl bg-indigo-50 dark:bg-indigo-950/30 ring-1 ring-indigo-100 dark:ring-indigo-900/50 p-6\">\n <h3 class=\"font-semibold text-indigo-900 dark:text-indigo-300 mb-3\">\n 📧 Email Templates Included\n </h3>\n <ul class=\"text-sm text-indigo-800 dark:text-indigo-200 space-y-2\">\n <li>✓ Registration confirmation</li>\n <li>✓ Email verification</li>\n <li>✓ Password reset</li>\n <li>✓ One-time code (2FA)</li>\n </ul>\n <p class=\"text-xs text-indigo-700 dark:text-indigo-300 mt-4\">\n Templates are code-based and can be customized by editing the plugin files.\n </p>\n </div>\n </div>\n </div>\n\n <script>\n // Form submission handler\n document.getElementById('emailSettingsForm').addEventListener('submit', async (e) => {\n e.preventDefault()\n const formData = new FormData(e.target)\n const data = Object.fromEntries(formData.entries())\n\n const statusEl = document.getElementById('statusMessage')\n\n try {\n const response = await fetch('/admin/plugins/email/settings', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data)\n })\n\n if (response.ok) {\n statusEl.className = 'rounded-xl bg-green-50 dark:bg-green-950/30 ring-1 ring-green-100 dark:ring-green-900/50 p-4 mb-6 text-green-900 dark:text-green-200'\n statusEl.innerHTML = '✅ Settings saved successfully!'\n statusEl.classList.remove('hidden')\n setTimeout(() => statusEl.classList.add('hidden'), 3000)\n } else {\n throw new Error('Failed to save settings')\n }\n } catch (error) {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = '❌ Failed to save settings. Please try again.'\n statusEl.classList.remove('hidden')\n }\n })\n\n // Test email handler\n document.getElementById('testEmailBtn').addEventListener('click', async () => {\n // Prompt for destination email\n const toEmail = prompt('Enter destination email address for test:')\n if (!toEmail) return\n\n // Basic email validation\n if (!toEmail.match(/^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$/)) {\n alert('Please enter a valid email address')\n return\n }\n\n const statusEl = document.getElementById('statusMessage')\n\n statusEl.className = 'rounded-xl bg-indigo-50 dark:bg-indigo-950/30 ring-1 ring-indigo-100 dark:ring-indigo-900/50 p-4 mb-6 text-indigo-900 dark:text-indigo-200'\n statusEl.innerHTML = \\`📧 Sending test email to \\${toEmail}...\\`\n statusEl.classList.remove('hidden')\n\n try {\n const response = await fetch('/admin/plugins/email/test', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ toEmail })\n })\n\n const data = await response.json()\n\n if (response.ok) {\n statusEl.className = 'rounded-xl bg-green-50 dark:bg-green-950/30 ring-1 ring-green-100 dark:ring-green-900/50 p-4 mb-6 text-green-900 dark:text-green-200'\n statusEl.innerHTML = \\`✅ \\${data.message || 'Test email sent! Check your inbox.'}\\`\n } else {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = \\`❌ \\${data.error || 'Failed to send test email. Check your settings.'}\\`\n }\n } catch (error) {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = '❌ Network error. Please try again.'\n }\n })\n\n // Reset button handler\n document.getElementById('resetBtn').addEventListener('click', () => {\n document.getElementById('emailSettingsForm').reset()\n })\n </script>\n `\n\n const templateUser = user ? {\n name: user.name ?? user.email ?? 'Admin',\n email: user.email ?? 'admin@sonicjs.com',\n role: user.role ?? 'admin'\n } : undefined\n\n return c.html(\n renderAdminLayout({\n title: 'Email Settings',\n content: contentHTML,\n user: templateUser,\n currentPath: '/admin/plugins/email/settings'\n })\n )\n })\n\n // POST endpoint for saving settings\n emailRoutes.post('/settings', async (c: any) => {\n try {\n const body = await c.req.json()\n const db = c.env.DB\n\n // Update plugin settings in database\n await db.prepare(`\n UPDATE plugins\n SET settings = ?,\n updated_at = unixepoch()\n WHERE id = 'email'\n `).bind(JSON.stringify(body)).run()\n\n return c.json({ success: true })\n } catch (error) {\n console.error('Error saving email settings:', error)\n return c.json({ success: false, error: 'Failed to save settings' }, 500)\n }\n })\n\n // POST endpoint for test email\n emailRoutes.post('/test', async (c: any) => {\n try {\n const db = c.env.DB\n const body = await c.req.json()\n\n // Load settings from database\n const plugin = await db.prepare(`\n SELECT settings FROM plugins WHERE id = 'email'\n `).first() as { settings: string | null } | null\n\n if (!plugin?.settings) {\n return c.json({\n success: false,\n error: 'Email settings not configured. Please save your settings first.'\n }, 400)\n }\n\n const settings = JSON.parse(plugin.settings)\n\n // Validate required settings\n if (!settings.apiKey || !settings.fromEmail || !settings.fromName) {\n return c.json({\n success: false,\n error: 'Missing required settings. Please configure API Key, From Email, and From Name.'\n }, 400)\n }\n\n // Use provided email or fallback to fromEmail\n const toEmail = body.toEmail || settings.fromEmail\n\n // Validate email format\n if (!toEmail.match(/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/)) {\n return c.json({\n success: false,\n error: 'Invalid email address format'\n }, 400)\n }\n\n // Send test email via Resend API\n const response = await fetch('https://api.resend.com/emails', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${settings.apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n from: `${settings.fromName} <${settings.fromEmail}>`,\n to: [toEmail],\n subject: 'Test Email from SonicJS',\n html: `\n <div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n <h1 style=\"color: #667eea;\">Test Email Successful! 🎉</h1>\n <p>This is a test email from your SonicJS Email plugin.</p>\n <p><strong>Configuration:</strong></p>\n <ul>\n <li>From: ${settings.fromName} &lt;${settings.fromEmail}&gt;</li>\n <li>Reply-To: ${settings.replyTo || 'Not set'}</li>\n <li>Sent at: ${new Date().toISOString()}</li>\n </ul>\n <p>Your email settings are working correctly!</p>\n </div>\n `,\n reply_to: settings.replyTo || settings.fromEmail\n })\n })\n\n const data = await response.json() as any\n\n if (!response.ok) {\n console.error('Resend API error:', data)\n return c.json({\n success: false,\n error: data.message || 'Failed to send test email. Check your API key and domain verification.'\n }, response.status)\n }\n\n return c.json({\n success: true,\n message: `Test email sent successfully to ${toEmail}`,\n emailId: data.id\n })\n\n } catch (error: any) {\n console.error('Test email error:', error)\n return c.json({\n success: false,\n error: error.message || 'An error occurred while sending test email'\n }, 500)\n }\n })\n\n // Register the route\n builder.addRoute('/admin/plugins/email', emailRoutes, {\n description: 'Email plugin settings',\n requiresAuth: true,\n priority: 80\n })\n\n // Add menu item\n builder.addMenuItem('Email', '/admin/plugins/email/settings', {\n icon: 'envelope',\n order: 80,\n permissions: ['email:manage']\n })\n\n // Add lifecycle hooks\n builder.lifecycle({\n activate: async () => {\n console.info('✅ Email plugin activated')\n },\n\n deactivate: async () => {\n console.info('❌ Email plugin deactivated')\n }\n })\n\n return builder.build() as Plugin\n}\n\n// Export the plugin instance\nexport const emailPlugin = createEmailPlugin()\n","/**\n * OTP Service\n * Handles OTP code generation, verification, and management\n */\n\nimport type { D1Database } from '@cloudflare/workers-types'\n\nexport interface OTPSettings {\n codeLength: number\n codeExpiryMinutes: number\n maxAttempts: number\n rateLimitPerHour: number\n allowNewUserRegistration: boolean\n appName: string\n}\n\nexport interface OTPCode {\n id: string\n user_email: string\n code: string\n expires_at: number\n used: number\n used_at: number | null\n ip_address: string | null\n user_agent: string | null\n attempts: number\n created_at: number\n}\n\nexport class OTPService {\n constructor(private db: D1Database) {}\n\n /**\n * Generate a secure random OTP code\n */\n generateCode(length: number = 6): string {\n const digits = '0123456789'\n let code = ''\n\n for (let i = 0; i < length; i++) {\n const randomValues = new Uint8Array(1)\n crypto.getRandomValues(randomValues)\n const randomValue = randomValues[0] ?? 0\n code += digits[randomValue % digits.length]\n }\n\n return code\n }\n\n /**\n * Create and store a new OTP code\n */\n async createOTPCode(\n email: string,\n settings: OTPSettings,\n ipAddress?: string,\n userAgent?: string\n ): Promise<OTPCode> {\n const code = this.generateCode(settings.codeLength)\n const id = crypto.randomUUID()\n const now = Date.now()\n const expiresAt = now + (settings.codeExpiryMinutes * 60 * 1000)\n\n const otpCode: OTPCode = {\n id,\n user_email: email.toLowerCase(),\n code,\n expires_at: expiresAt,\n used: 0,\n used_at: null,\n ip_address: ipAddress || null,\n user_agent: userAgent || null,\n attempts: 0,\n created_at: now\n }\n\n await this.db.prepare(`\n INSERT INTO otp_codes (\n id, user_email, code, expires_at, used, used_at,\n ip_address, user_agent, attempts, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n otpCode.id,\n otpCode.user_email,\n otpCode.code,\n otpCode.expires_at,\n otpCode.used,\n otpCode.used_at,\n otpCode.ip_address,\n otpCode.user_agent,\n otpCode.attempts,\n otpCode.created_at\n ).run()\n\n return otpCode\n }\n\n /**\n * Verify an OTP code\n */\n async verifyCode(\n email: string,\n code: string,\n settings: OTPSettings\n ): Promise<{ valid: boolean; attemptsRemaining?: number; error?: string }> {\n const normalizedEmail = email.toLowerCase()\n const now = Date.now()\n\n // Find the most recent unused code for this email\n const otpCode = await this.db.prepare(`\n SELECT * FROM otp_codes\n WHERE user_email = ? AND code = ? AND used = 0\n ORDER BY created_at DESC\n LIMIT 1\n `).bind(normalizedEmail, code).first() as OTPCode | null\n\n if (!otpCode) {\n return { valid: false, error: 'Invalid or expired code' }\n }\n\n // Check if expired\n if (now > otpCode.expires_at) {\n return { valid: false, error: 'Code has expired' }\n }\n\n // Check attempts\n if (otpCode.attempts >= settings.maxAttempts) {\n return { valid: false, error: 'Maximum attempts exceeded' }\n }\n\n // Code is valid - mark as used\n await this.db.prepare(`\n UPDATE otp_codes\n SET used = 1, used_at = ?, attempts = attempts + 1\n WHERE id = ?\n `).bind(now, otpCode.id).run()\n\n return { valid: true }\n }\n\n /**\n * Increment failed attempt count\n */\n async incrementAttempts(email: string, code: string): Promise<number> {\n const normalizedEmail = email.toLowerCase()\n\n const result = await this.db.prepare(`\n UPDATE otp_codes\n SET attempts = attempts + 1\n WHERE user_email = ? AND code = ? AND used = 0\n RETURNING attempts\n `).bind(normalizedEmail, code).first() as { attempts: number } | null\n\n return result?.attempts || 0\n }\n\n /**\n * Check rate limiting\n */\n async checkRateLimit(email: string, settings: OTPSettings): Promise<boolean> {\n const normalizedEmail = email.toLowerCase()\n const oneHourAgo = Date.now() - (60 * 60 * 1000)\n\n const result = await this.db.prepare(`\n SELECT COUNT(*) as count\n FROM otp_codes\n WHERE user_email = ? AND created_at > ?\n `).bind(normalizedEmail, oneHourAgo).first() as { count: number } | null\n\n const count = result?.count || 0\n return count < settings.rateLimitPerHour\n }\n\n /**\n * Get recent OTP requests for activity log\n */\n async getRecentRequests(limit: number = 50): Promise<OTPCode[]> {\n const result = await this.db.prepare(`\n SELECT * FROM otp_codes\n ORDER BY created_at DESC\n LIMIT ?\n `).bind(limit).all()\n\n const rows = (result.results || []) as Record<string, unknown>[]\n return rows.map(row => this.mapRowToOTP(row))\n }\n\n /**\n * Clean up expired codes (for maintenance)\n */\n async cleanupExpiredCodes(): Promise<number> {\n const now = Date.now()\n\n const result = await this.db.prepare(`\n DELETE FROM otp_codes\n WHERE expires_at < ? OR (used = 1 AND used_at < ?)\n `).bind(now, now - (30 * 24 * 60 * 60 * 1000)).run() // Keep used codes for 30 days\n\n return result.meta.changes || 0\n }\n\n private mapRowToOTP(row: Record<string, unknown>): OTPCode {\n return {\n id: String(row.id),\n user_email: String(row.user_email),\n code: String(row.code),\n expires_at: Number(row.expires_at ?? Date.now()),\n used: Number(row.used ?? 0),\n used_at: row.used_at === null || row.used_at === undefined ? null : Number(row.used_at),\n ip_address: typeof row.ip_address === 'string' ? row.ip_address : null,\n user_agent: typeof row.user_agent === 'string' ? row.user_agent : null,\n attempts: Number(row.attempts ?? 0),\n created_at: Number(row.created_at ?? Date.now())\n }\n }\n\n /**\n * Get OTP statistics\n */\n async getStats(days: number = 7): Promise<{\n total: number\n successful: number\n failed: number\n expired: number\n }> {\n const since = Date.now() - (days * 24 * 60 * 60 * 1000)\n\n const stats = await this.db.prepare(`\n SELECT\n COUNT(*) as total,\n SUM(CASE WHEN used = 1 THEN 1 ELSE 0 END) as successful,\n SUM(CASE WHEN attempts >= 3 AND used = 0 THEN 1 ELSE 0 END) as failed,\n SUM(CASE WHEN expires_at < ? AND used = 0 THEN 1 ELSE 0 END) as expired\n FROM otp_codes\n WHERE created_at > ?\n `).bind(Date.now(), since).first() as any\n\n return {\n total: stats?.total || 0,\n successful: stats?.successful || 0,\n failed: stats?.failed || 0,\n expired: stats?.expired || 0\n }\n }\n}\n","/**\n * OTP Email Templates\n * HTML and plain text templates for OTP codes\n */\n\nexport interface OTPEmailData {\n code: string\n expiryMinutes: number\n codeLength: number\n maxAttempts: number\n email: string\n ipAddress?: string\n timestamp: string\n appName: string\n logoUrl?: string\n}\n\nexport function renderOTPEmailHTML(data: OTPEmailData): string {\n return `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Your Login Code</title>\n</head>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f5f5f5;\">\n\n <div style=\"background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);\">\n\n ${data.logoUrl ? `\n <div style=\"text-align: center; padding: 30px 20px 20px;\">\n <img src=\"${data.logoUrl}\" alt=\"Logo\" style=\"max-width: 150px; height: auto;\">\n </div>\n ` : ''}\n\n <div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px 30px; text-align: center;\">\n <h1 style=\"margin: 0 0 10px 0; font-size: 32px; font-weight: 600;\">Your Login Code</h1>\n <p style=\"margin: 0; opacity: 0.95; font-size: 16px;\">Enter this code to sign in to ${data.appName}</p>\n </div>\n\n <div style=\"padding: 40px 30px;\">\n <div style=\"background: #f8f9fa; border: 2px dashed #667eea; border-radius: 12px; padding: 30px; text-align: center; margin: 0 0 30px 0;\">\n <div style=\"font-size: 56px; font-weight: bold; letter-spacing: 12px; color: #667eea; font-family: 'Courier New', Courier, monospace; line-height: 1;\">\n ${data.code}\n </div>\n </div>\n\n <div style=\"background: #fff3cd; border-left: 4px solid #ffc107; padding: 16px 20px; margin: 0 0 30px 0; border-radius: 6px;\">\n <p style=\"margin: 0; font-size: 14px; color: #856404;\">\n <strong>⚠️ This code expires in ${data.expiryMinutes} minutes</strong>\n </p>\n </div>\n\n <div style=\"margin: 0 0 30px 0;\">\n <h3 style=\"color: #333; margin: 0 0 15px 0; font-size: 18px;\">Quick Tips:</h3>\n <ul style=\"color: #666; font-size: 14px; line-height: 1.8; margin: 0; padding-left: 20px;\">\n <li>Enter the code exactly as shown (${data.codeLength} digits)</li>\n <li>The code can only be used once</li>\n <li>You have ${data.maxAttempts} attempts to enter the correct code</li>\n <li>Request a new code if this one expires</li>\n </ul>\n </div>\n\n <div style=\"background: #e8f4ff; border-radius: 8px; padding: 20px; margin: 0 0 30px 0;\">\n <p style=\"margin: 0 0 10px 0; font-size: 14px; color: #0066cc; font-weight: 600;\">\n 🔒 Security Notice\n </p>\n <p style=\"margin: 0; font-size: 13px; color: #004080; line-height: 1.6;\">\n Never share this code with anyone. ${data.appName} will never ask you for this code via phone, email, or social media.\n </p>\n </div>\n </div>\n\n <div style=\"border-top: 1px solid #eee; padding: 30px; background: #f8f9fa;\">\n <p style=\"margin: 0 0 15px 0; font-size: 14px; color: #666; text-align: center;\">\n <strong>Didn't request this code?</strong><br>\n Someone may have entered your email by mistake. You can safely ignore this email.\n </p>\n\n <div style=\"text-align: center; color: #999; font-size: 12px; line-height: 1.6;\">\n <p style=\"margin: 5px 0;\">This email was sent to ${data.email}</p>\n ${data.ipAddress ? `<p style=\"margin: 5px 0;\">IP Address: ${data.ipAddress}</p>` : ''}\n <p style=\"margin: 5px 0;\">Time: ${data.timestamp}</p>\n </div>\n </div>\n\n </div>\n\n <div style=\"text-align: center; padding: 20px; color: #999; font-size: 12px;\">\n <p style=\"margin: 0;\">&copy; ${new Date().getFullYear()} ${data.appName}. All rights reserved.</p>\n </div>\n\n</body>\n</html>`\n}\n\nexport function renderOTPEmailText(data: OTPEmailData): string {\n return `Your Login Code for ${data.appName}\n\nYour one-time verification code is:\n\n${data.code}\n\nThis code expires in ${data.expiryMinutes} minutes.\n\nQuick Tips:\n• Enter the code exactly as shown (${data.codeLength} digits)\n• The code can only be used once\n• You have ${data.maxAttempts} attempts to enter the correct code\n• Request a new code if this one expires\n\nSecurity Notice:\nNever share this code with anyone. ${data.appName} will never ask you for this code via phone, email, or social media.\n\nDidn't request this code?\nSomeone may have entered your email by mistake. You can safely ignore this email.\n\n---\nThis email was sent to ${data.email}\n${data.ipAddress ? `IP Address: ${data.ipAddress}` : ''}\nTime: ${data.timestamp}\n\n© ${new Date().getFullYear()} ${data.appName}. All rights reserved.`\n}\n\nexport function renderOTPEmail(data: OTPEmailData): { html: string; text: string } {\n return {\n html: renderOTPEmailHTML(data),\n text: renderOTPEmailText(data)\n }\n}\n","/**\n * OTP Login Plugin\n *\n * Passwordless authentication via email one-time codes\n * Users receive a secure 6-digit code to sign in without passwords\n */\n\nimport { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport { z } from 'zod'\nimport { PluginBuilder } from '../../sdk/plugin-builder'\nimport type { Plugin } from '@sonicjs-cms/core'\nimport { OTPService, type OTPSettings } from './otp-service'\nimport { renderOTPEmail } from './email-templates'\nimport { adminLayoutV2 } from '../../../templates/layouts/admin-layout-v2.template'\n\n// Validation schemas\nconst otpRequestSchema = z.object({\n email: z.string().email('Valid email is required')\n})\n\nconst otpVerifySchema = z.object({\n email: z.string().email('Valid email is required'),\n code: z.string().min(4).max(8)\n})\n\n// Default settings\nconst DEFAULT_SETTINGS: OTPSettings = {\n codeLength: 6,\n codeExpiryMinutes: 10,\n maxAttempts: 3,\n rateLimitPerHour: 5,\n allowNewUserRegistration: false,\n appName: 'SonicJS'\n}\n\nexport function createOTPLoginPlugin(): Plugin {\n const builder = PluginBuilder.create({\n name: 'otp-login',\n version: '1.0.0-beta.1',\n description: 'Passwordless authentication via email one-time codes'\n })\n\n builder.metadata({\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n license: 'MIT',\n compatibility: '^2.0.0'\n })\n\n // ==================== API Routes ====================\n\n const otpAPI = new Hono()\n\n // POST /auth/otp/request - Request OTP code\n otpAPI.post('/request', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB\n const otpService = new OTPService(db)\n const settings = { ...DEFAULT_SETTINGS } // TODO: Load from plugin settings\n\n // Check rate limiting\n const canRequest = await otpService.checkRateLimit(normalizedEmail, settings)\n if (!canRequest) {\n return c.json({\n error: 'Too many requests. Please try again in an hour.'\n }, 429)\n }\n\n // Check if user exists\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n if (!user && !settings.allowNewUserRegistration) {\n // Don't reveal if user exists or not (security)\n return c.json({\n message: 'If an account exists for this email, you will receive a verification code shortly.',\n expiresIn: settings.codeExpiryMinutes * 60\n })\n }\n\n if (user && !user.is_active) {\n return c.json({\n error: 'This account has been deactivated.'\n }, 403)\n }\n\n // Get IP and user agent\n const ipAddress = c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for') || 'unknown'\n const userAgent = c.req.header('user-agent') || 'unknown'\n\n // Create OTP code\n const otpCode = await otpService.createOTPCode(\n normalizedEmail,\n settings,\n ipAddress,\n userAgent\n )\n\n // Send email (if email plugin is available)\n try {\n // TODO: Integrate with email plugin\n // For now, we'll just log the code in development\n const isDevMode = c.env.ENVIRONMENT === 'development'\n\n if (isDevMode) {\n console.log(`[DEV] OTP Code for ${normalizedEmail}: ${otpCode.code}`)\n }\n\n // Prepare email content\n const emailContent = renderOTPEmail({\n code: otpCode.code,\n expiryMinutes: settings.codeExpiryMinutes,\n codeLength: settings.codeLength,\n maxAttempts: settings.maxAttempts,\n email: normalizedEmail,\n ipAddress,\n timestamp: new Date().toISOString(),\n appName: settings.appName\n })\n\n // TODO: Actually send email via email plugin\n // await emailService.send({\n // to: normalizedEmail,\n // subject: `Your login code for ${settings.appName}`,\n // html: emailContent.html,\n // text: emailContent.text\n // })\n\n const response: any = {\n message: 'If an account exists for this email, you will receive a verification code shortly.',\n expiresIn: settings.codeExpiryMinutes * 60\n }\n\n // In development, include the code\n if (isDevMode) {\n response.dev_code = otpCode.code\n }\n\n return c.json(response)\n } catch (emailError) {\n console.error('Error sending OTP email:', emailError)\n return c.json({\n error: 'Failed to send verification code. Please try again.'\n }, 500)\n }\n } catch (error) {\n console.error('OTP request error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // POST /auth/otp/verify - Verify OTP code\n otpAPI.post('/verify', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpVerifySchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email, code } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB\n const otpService = new OTPService(db)\n const settings = { ...DEFAULT_SETTINGS } // TODO: Load from plugin settings\n\n // Verify the code\n const verification = await otpService.verifyCode(normalizedEmail, code, settings)\n\n if (!verification.valid) {\n // Increment attempts on failure\n await otpService.incrementAttempts(normalizedEmail, code)\n\n return c.json({\n error: verification.error || 'Invalid code',\n attemptsRemaining: verification.attemptsRemaining\n }, 401)\n }\n\n // Code is valid - get user\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n if (!user) {\n return c.json({\n error: 'User not found'\n }, 404)\n }\n\n if (!user.is_active) {\n return c.json({\n error: 'Account is deactivated'\n }, 403)\n }\n\n // TODO: Generate JWT token\n // For now, return success with user data\n return c.json({\n success: true,\n user: {\n id: user.id,\n email: user.email,\n role: user.role\n },\n message: 'Authentication successful'\n })\n } catch (error) {\n console.error('OTP verify error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // POST /auth/otp/resend - Resend OTP code\n otpAPI.post('/resend', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n // Reuse the request endpoint logic\n return otpAPI.fetch(\n new Request(c.req.url.replace('/resend', '/request'), {\n method: 'POST',\n headers: c.req.raw.headers,\n body: JSON.stringify({ email: validation.data.email })\n }),\n c.env\n )\n } catch (error) {\n console.error('OTP resend error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // Register API routes\n builder.addRoute('/auth/otp', otpAPI, {\n description: 'OTP authentication endpoints',\n requiresAuth: false,\n priority: 100\n })\n\n // ==================== Admin UI Routes ====================\n\n const adminRoutes = new Hono()\n\n // Settings page\n adminRoutes.get('/settings', async (c: any) => {\n const user = c.get('user') as { email?: string; role?: string; name?: string } | undefined\n\n const contentHTML = await html`\n <div class=\"p-8\">\n <div class=\"mb-8\">\n <h1 class=\"text-3xl font-bold mb-2\">OTP Login Settings</h1>\n <p class=\"text-zinc-600 dark:text-zinc-400\">Configure passwordless authentication via email codes</p>\n </div>\n\n <div class=\"max-w-3xl\">\n <div class=\"backdrop-blur-md bg-black/20 border border-white/10 shadow-xl rounded-xl p-6 mb-6\">\n <h2 class=\"text-xl font-semibold mb-4\">Code Settings</h2>\n\n <form id=\"otpSettingsForm\" class=\"space-y-6\">\n <div>\n <label for=\"codeLength\" class=\"block text-sm font-medium mb-2\">\n Code Length\n </label>\n <input\n type=\"number\"\n id=\"codeLength\"\n name=\"codeLength\"\n min=\"4\"\n max=\"8\"\n value=\"6\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Number of digits in OTP code (4-8)</p>\n </div>\n\n <div>\n <label for=\"codeExpiryMinutes\" class=\"block text-sm font-medium mb-2\">\n Code Expiry (minutes)\n </label>\n <input\n type=\"number\"\n id=\"codeExpiryMinutes\"\n name=\"codeExpiryMinutes\"\n min=\"5\"\n max=\"60\"\n value=\"10\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">How long codes remain valid (5-60 minutes)</p>\n </div>\n\n <div>\n <label for=\"maxAttempts\" class=\"block text-sm font-medium mb-2\">\n Maximum Attempts\n </label>\n <input\n type=\"number\"\n id=\"maxAttempts\"\n name=\"maxAttempts\"\n min=\"3\"\n max=\"10\"\n value=\"3\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Max verification attempts before invalidation</p>\n </div>\n\n <div>\n <label for=\"rateLimitPerHour\" class=\"block text-sm font-medium mb-2\">\n Rate Limit (per hour)\n </label>\n <input\n type=\"number\"\n id=\"rateLimitPerHour\"\n name=\"rateLimitPerHour\"\n min=\"3\"\n max=\"20\"\n value=\"5\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Max code requests per email per hour</p>\n </div>\n\n <div class=\"flex items-center\">\n <input\n type=\"checkbox\"\n id=\"allowNewUserRegistration\"\n name=\"allowNewUserRegistration\"\n class=\"w-4 h-4 rounded border-white/10\"\n />\n <label for=\"allowNewUserRegistration\" class=\"ml-2 text-sm\">\n Allow new user registration via OTP\n </label>\n </div>\n\n <div class=\"flex gap-3 pt-4\">\n <button\n type=\"submit\"\n class=\"px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-purple-700 transition-all\"\n >\n Save Settings\n </button>\n <button\n type=\"button\"\n id=\"testOTPBtn\"\n class=\"px-6 py-2 bg-white/10 hover:bg-white/20 text-white rounded-lg font-medium transition-all\"\n >\n Send Test Code\n </button>\n </div>\n </form>\n </div>\n\n <div id=\"statusMessage\" class=\"hidden backdrop-blur-md bg-black/20 border border-white/10 rounded-xl p-4 mb-6\"></div>\n\n <div class=\"backdrop-blur-md bg-blue-500/10 border border-blue-500/20 rounded-xl p-6\">\n <h3 class=\"font-semibold text-blue-400 mb-3\">\n 🔢 Features\n </h3>\n <ul class=\"text-sm text-blue-200 space-y-2\">\n <li>✓ Passwordless authentication</li>\n <li>✓ Secure random code generation</li>\n <li>✓ Rate limiting protection</li>\n <li>✓ Brute force prevention</li>\n <li>✓ Mobile-friendly UX</li>\n </ul>\n </div>\n </div>\n </div>\n\n <script>\n document.getElementById('otpSettingsForm').addEventListener('submit', async (e) => {\n e.preventDefault()\n const statusEl = document.getElementById('statusMessage')\n statusEl.className = 'backdrop-blur-md bg-green-500/20 border border-green-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '✅ Settings saved successfully!'\n statusEl.classList.remove('hidden')\n setTimeout(() => statusEl.classList.add('hidden'), 3000)\n })\n\n document.getElementById('testOTPBtn').addEventListener('click', async () => {\n const email = prompt('Enter email address for test:')\n if (!email) return\n\n const statusEl = document.getElementById('statusMessage')\n statusEl.className = 'backdrop-blur-md bg-blue-500/20 border border-blue-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '📧 Sending test code...'\n statusEl.classList.remove('hidden')\n\n try {\n const response = await fetch('/auth/otp/request', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email })\n })\n\n const data = await response.json()\n\n if (response.ok) {\n statusEl.className = 'backdrop-blur-md bg-green-500/20 border border-green-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '✅ Test code sent!' + (data.dev_code ? \\` Code: <strong>\\${data.dev_code}</strong>\\` : '')\n } else {\n throw new Error(data.error || 'Failed')\n }\n } catch (error) {\n statusEl.className = 'backdrop-blur-md bg-red-500/20 border border-red-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '❌ Failed to send test code'\n }\n })\n </script>\n `\n\n const templateUser = user ? {\n name: user.name ?? user.email ?? 'Admin',\n email: user.email ?? 'admin@sonicjs.com',\n role: user.role ?? 'admin'\n } : undefined\n\n return c.html(\n adminLayoutV2({\n title: 'OTP Login Settings',\n content: contentHTML,\n user: templateUser,\n currentPath: '/admin/plugins/otp-login/settings'\n })\n )\n })\n\n // Register admin routes\n builder.addRoute('/admin/plugins/otp-login', adminRoutes, {\n description: 'OTP login admin interface',\n requiresAuth: true,\n priority: 85\n })\n\n // Add menu item\n builder.addMenuItem('OTP Login', '/admin/plugins/otp-login/settings', {\n icon: 'key',\n order: 85,\n permissions: ['otp:manage']\n })\n\n // Lifecycle hooks\n builder.lifecycle({\n activate: async () => {\n console.info('✅ OTP Login plugin activated')\n },\n deactivate: async () => {\n console.info('❌ OTP Login plugin deactivated')\n }\n })\n\n return builder.build() as Plugin\n}\n\nexport const otpLoginPlugin = createOTPLoginPlugin()\n","/**\n * Magic Link Authentication Plugin\n *\n * Provides passwordless authentication via email magic links\n * Users receive a secure one-time link to sign in without passwords\n */\n\nimport { Hono } from 'hono'\nimport { z } from 'zod'\nimport type { Plugin, PluginContext } from '../../types'\nimport type { D1Database } from '@cloudflare/workers-types'\nimport { AuthManager } from '../../../middleware/auth'\n\nconst magicLinkRequestSchema = z.object({\n email: z.string().email('Valid email is required')\n})\n\nexport function createMagicLinkAuthPlugin(): Plugin {\n const magicLinkRoutes = new Hono()\n\n // Request a magic link\n magicLinkRoutes.post('/request', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = magicLinkRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB as D1Database\n\n // Check rate limiting\n const oneHourAgo = Date.now() - (60 * 60 * 1000)\n const recentLinks = await db.prepare(`\n SELECT COUNT(*) as count\n FROM magic_links\n WHERE user_email = ? AND created_at > ?\n `).bind(normalizedEmail, oneHourAgo).first() as any\n\n const rateLimitPerHour = 5 // TODO: Get from plugin settings\n if (recentLinks && recentLinks.count >= rateLimitPerHour) {\n return c.json({\n error: 'Too many requests. Please try again later.'\n }, 429)\n }\n\n // Check if user exists\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n const allowNewUsers = false // TODO: Get from plugin settings\n\n if (!user && !allowNewUsers) {\n // Don't reveal if user exists or not for security\n return c.json({\n message: 'If an account exists for this email, you will receive a magic link shortly.'\n })\n }\n\n if (user && !user.is_active) {\n return c.json({\n error: 'This account has been deactivated.'\n }, 403)\n }\n\n // Generate secure token\n const token = crypto.randomUUID() + '-' + crypto.randomUUID()\n const tokenId = crypto.randomUUID()\n const linkExpiryMinutes = 15 // TODO: Get from plugin settings\n const expiresAt = Date.now() + (linkExpiryMinutes * 60 * 1000)\n\n // Store magic link\n await db.prepare(`\n INSERT INTO magic_links (\n id, user_email, token, expires_at, used, created_at, ip_address, user_agent\n ) VALUES (?, ?, ?, ?, 0, ?, ?, ?)\n `).bind(\n tokenId,\n normalizedEmail,\n token,\n expiresAt,\n Date.now(),\n c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for') || 'unknown',\n c.req.header('user-agent') || 'unknown'\n ).run()\n\n // Generate magic link URL\n const baseUrl = new URL(c.req.url).origin\n const magicLink = `${baseUrl}/auth/magic-link/verify?token=${token}`\n\n // Send email via email plugin\n try {\n const emailPlugin = c.env.plugins?.get('email')\n if (emailPlugin && emailPlugin.sendEmail) {\n await emailPlugin.sendEmail({\n to: normalizedEmail,\n subject: 'Your Magic Link to Sign In',\n html: renderMagicLinkEmail(magicLink, linkExpiryMinutes)\n })\n } else {\n console.error('Email plugin not available')\n // In production, this should fail. For now, log the link for testing\n console.log(`Magic link for ${normalizedEmail}: ${magicLink}`)\n }\n } catch (error) {\n console.error('Failed to send magic link email:', error)\n return c.json({\n error: 'Failed to send email. Please try again later.'\n }, 500)\n }\n\n return c.json({\n message: 'If an account exists for this email, you will receive a magic link shortly.',\n // For development only - remove in production\n ...(c.env.ENVIRONMENT === 'development' && { dev_link: magicLink })\n })\n } catch (error) {\n console.error('Magic link request error:', error)\n return c.json({ error: 'Failed to process request' }, 500)\n }\n })\n\n // Verify magic link and sign in\n magicLinkRoutes.get('/verify', async (c: any) => {\n try {\n const token = c.req.query('token')\n\n if (!token) {\n return c.redirect('/auth/login?error=Invalid magic link')\n }\n\n const db = c.env.DB as D1Database\n\n // Find magic link\n const magicLink = await db.prepare(`\n SELECT * FROM magic_links\n WHERE token = ? AND used = 0\n `).bind(token).first() as any\n\n if (!magicLink) {\n return c.redirect('/auth/login?error=Invalid or expired magic link')\n }\n\n // Check expiration\n if (magicLink.expires_at < Date.now()) {\n return c.redirect('/auth/login?error=This magic link has expired')\n }\n\n // Get or create user\n let user = await db.prepare(`\n SELECT * FROM users WHERE email = ? AND is_active = 1\n `).bind(magicLink.user_email).first() as any\n\n const allowNewUsers = false // TODO: Get from plugin settings\n\n if (!user && allowNewUsers) {\n // Create new user\n const userId = crypto.randomUUID()\n const username = magicLink.user_email.split('@')[0]\n const now = Date.now()\n\n await db.prepare(`\n INSERT INTO users (\n id, email, username, first_name, last_name,\n password_hash, role, is_active, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, NULL, 'viewer', 1, ?, ?)\n `).bind(\n userId,\n magicLink.user_email,\n username,\n username,\n '',\n now,\n now\n ).run()\n\n user = {\n id: userId,\n email: magicLink.user_email,\n username,\n role: 'viewer'\n }\n } else if (!user) {\n return c.redirect('/auth/login?error=No account found for this email')\n }\n\n // Mark magic link as used\n await db.prepare(`\n UPDATE magic_links\n SET used = 1, used_at = ?\n WHERE id = ?\n `).bind(Date.now(), magicLink.id).run()\n\n // Generate JWT token\n const jwtToken = await AuthManager.generateToken(\n user.id,\n user.email,\n user.role\n )\n\n // Set auth cookie\n AuthManager.setAuthCookie(c, jwtToken)\n\n // Update last login\n await db.prepare(`\n UPDATE users SET last_login_at = ? WHERE id = ?\n `).bind(Date.now(), user.id).run()\n\n // Redirect to admin dashboard\n return c.redirect('/admin/dashboard?message=Successfully signed in')\n } catch (error) {\n console.error('Magic link verification error:', error)\n return c.redirect('/auth/login?error=Authentication failed')\n }\n })\n\n return {\n name: 'magic-link-auth',\n version: '1.0.0',\n description: 'Passwordless authentication via email magic links',\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n dependencies: ['email'],\n\n routes: [{\n path: '/auth/magic-link',\n handler: magicLinkRoutes,\n description: 'Magic link authentication endpoints',\n requiresAuth: false\n }],\n\n async install(context: PluginContext) {\n console.log('Installing magic-link-auth plugin...')\n // Migration is handled by plugin system\n },\n\n async activate(context: PluginContext) {\n console.log('Magic link authentication activated')\n console.log('Users can now sign in via /auth/magic-link/request')\n },\n\n async deactivate(context: PluginContext) {\n console.log('Magic link authentication deactivated')\n },\n\n async uninstall(context: PluginContext) {\n console.log('Uninstalling magic-link-auth plugin...')\n // Optionally clean up magic_links table\n // await context.db.prepare('DROP TABLE IF EXISTS magic_links').run()\n }\n }\n}\n\n/**\n * Render magic link email template\n */\nfunction renderMagicLinkEmail(magicLink: string, expiryMinutes: number): string {\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Your Magic Link</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n line-height: 1.6;\n color: #333;\n max-width: 600px;\n margin: 0 auto;\n padding: 20px;\n }\n .container {\n background: #ffffff;\n border-radius: 8px;\n padding: 40px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .header {\n text-align: center;\n margin-bottom: 30px;\n }\n .header h1 {\n color: #0ea5e9;\n margin: 0;\n font-size: 24px;\n }\n .content {\n margin-bottom: 30px;\n }\n .button {\n display: inline-block;\n padding: 14px 32px;\n background: linear-gradient(135deg, #0ea5e9 0%, #06b6d4 100%);\n color: #ffffff !important;\n text-decoration: none;\n border-radius: 6px;\n font-weight: 600;\n text-align: center;\n margin: 20px 0;\n }\n .button:hover {\n opacity: 0.9;\n }\n .expiry {\n color: #ef4444;\n font-size: 14px;\n margin-top: 20px;\n }\n .footer {\n margin-top: 40px;\n padding-top: 20px;\n border-top: 1px solid #e5e7eb;\n font-size: 12px;\n color: #6b7280;\n text-align: center;\n }\n .security-note {\n background: #fef3c7;\n border-left: 4px solid #f59e0b;\n padding: 12px 16px;\n margin-top: 20px;\n border-radius: 4px;\n font-size: 14px;\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>🔗 Your Magic Link</h1>\n </div>\n\n <div class=\"content\">\n <p>Hello!</p>\n <p>You requested a magic link to sign in to your account. Click the button below to continue:</p>\n\n <div style=\"text-align: center;\">\n <a href=\"${magicLink}\" class=\"button\">Sign In</a>\n </div>\n\n <p class=\"expiry\">⏰ This link expires in ${expiryMinutes} minutes</p>\n\n <div class=\"security-note\">\n <strong>Security Notice:</strong> If you didn't request this link, you can safely ignore this email.\n Someone may have entered your email address by mistake.\n </div>\n </div>\n\n <div class=\"footer\">\n <p>This is an automated email from SonicJS.</p>\n <p>For security, this link can only be used once.</p>\n </div>\n </div>\n </body>\n </html>\n `\n}\n\nexport default createMagicLinkAuthPlugin()\n","/**\n * Main Application Factory\n *\n * Creates a configured SonicJS application with all core functionality\n */\n\nimport { Hono } from 'hono'\nimport type { Context } from 'hono'\nimport type { D1Database, KVNamespace, R2Bucket } from '@cloudflare/workers-types'\nimport {\n apiRoutes,\n apiMediaRoutes,\n apiSystemRoutes,\n adminApiRoutes,\n authRoutes,\n testCleanupRoutes,\n adminContentRoutes,\n adminUsersRoutes,\n adminMediaRoutes,\n adminPluginRoutes,\n adminLogsRoutes,\n adminDashboardRoutes,\n adminCollectionsRoutes,\n adminSettingsRoutes\n} from './routes'\nimport { getCoreVersion } from './utils/version'\nimport { bootstrapMiddleware } from './middleware/bootstrap'\nimport { metricsMiddleware } from './middleware/metrics'\nimport { createDatabaseToolsAdminRoutes } from './plugins/core-plugins/database-tools-plugin/admin-routes'\nimport { emailPlugin } from './plugins/core-plugins/email-plugin'\nimport { otpLoginPlugin } from './plugins/core-plugins/otp-login-plugin'\nimport { createMagicLinkAuthPlugin } from './plugins/available/magic-link-auth'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\nexport interface Bindings {\n DB: D1Database\n CACHE_KV: KVNamespace\n MEDIA_BUCKET: R2Bucket\n ASSETS: Fetcher\n EMAIL_QUEUE?: Queue\n SENDGRID_API_KEY?: string\n DEFAULT_FROM_EMAIL?: string\n IMAGES_ACCOUNT_ID?: string\n IMAGES_API_TOKEN?: string\n ENVIRONMENT?: string\n BUCKET_NAME?: string\n}\n\nexport interface Variables {\n user?: {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n }\n requestId?: string\n startTime?: number\n appVersion?: string\n}\n\nexport interface SonicJSConfig {\n // Collections configuration\n collections?: {\n directory?: string\n autoSync?: boolean\n }\n\n // Plugins configuration\n plugins?: {\n directory?: string\n autoLoad?: boolean\n disableAll?: boolean // Disable all plugins including core plugins\n }\n\n // Custom routes\n routes?: Array<{\n path: string\n handler: Hono\n }>\n\n // Custom middleware\n middleware?: {\n beforeAuth?: Array<(c: Context, next: () => Promise<void>) => Promise<void>>\n afterAuth?: Array<(c: Context, next: () => Promise<void>) => Promise<void>>\n }\n\n // App metadata\n version?: string\n name?: string\n}\n\nexport type SonicJSApp = Hono<{ Bindings: Bindings; Variables: Variables }>\n\n// ============================================================================\n// Application Factory\n// ============================================================================\n\n/**\n * Create a SonicJS application with core functionality\n *\n * @param config - Application configuration\n * @returns Configured Hono application\n *\n * @example\n * ```typescript\n * import { createSonicJSApp } from '@sonicjs/core'\n *\n * const app = createSonicJSApp({\n * collections: {\n * directory: './src/collections',\n * autoSync: true\n * },\n * plugins: {\n * directory: './src/plugins',\n * autoLoad: true\n * }\n * })\n *\n * export default app\n * ```\n */\nexport function createSonicJSApp(config: SonicJSConfig = {}): SonicJSApp {\n const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n // Set app metadata\n const appVersion = config.version || getCoreVersion()\n const appName = config.name || 'SonicJS AI'\n\n // App version middleware\n app.use('*', async (c, next) => {\n c.set('appVersion', appVersion)\n await next()\n })\n\n // Metrics middleware - track all requests for real-time analytics\n app.use('*', metricsMiddleware())\n\n // Bootstrap middleware - runs migrations, syncs collections, and initializes plugins\n app.use('*', bootstrapMiddleware(config))\n\n // Custom middleware - before auth\n if (config.middleware?.beforeAuth) {\n for (const middleware of config.middleware.beforeAuth) {\n app.use('*', middleware)\n }\n }\n\n // Logging middleware\n app.use('*', async (_c, next) => {\n // Logging logic here\n await next()\n })\n\n // Security middleware\n app.use('*', async (_c, next) => {\n // Security headers, CORS, etc.\n await next()\n })\n\n // Custom middleware - after auth\n if (config.middleware?.afterAuth) {\n for (const middleware of config.middleware.afterAuth) {\n app.use('*', middleware)\n }\n }\n\n // Core routes\n // Routes are being imported incrementally from routes/*\n // Each route is tested and migrated one-by-one\n app.route('/api', apiRoutes)\n app.route('/api/media', apiMediaRoutes)\n app.route('/api/system', apiSystemRoutes)\n app.route('/admin/api', adminApiRoutes)\n app.route('/admin/dashboard', adminDashboardRoutes)\n app.route('/admin/collections', adminCollectionsRoutes)\n app.route('/admin/settings', adminSettingsRoutes)\n app.route('/admin/database-tools', createDatabaseToolsAdminRoutes())\n app.route('/admin/content', adminContentRoutes)\n app.route('/admin/media', adminMediaRoutes)\n app.route('/admin/plugins', adminPluginRoutes)\n app.route('/admin/logs', adminLogsRoutes)\n app.route('/admin', adminUsersRoutes)\n app.route('/auth', authRoutes)\n\n // Test cleanup routes (only for development/test environments)\n app.route('/', testCleanupRoutes)\n\n // Plugin routes - Email\n if (emailPlugin.routes && emailPlugin.routes.length > 0) {\n for (const route of emailPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Plugin routes - OTP Login (passwordless authentication via email codes)\n if (otpLoginPlugin.routes && otpLoginPlugin.routes.length > 0) {\n for (const route of otpLoginPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Plugin routes - Magic Link Auth (passwordless authentication via email links)\n const magicLinkPlugin = createMagicLinkAuthPlugin()\n if (magicLinkPlugin.routes && magicLinkPlugin.routes.length > 0) {\n for (const route of magicLinkPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Serve files from R2 storage (public file access)\n app.get('/files/*', async (c) => {\n try {\n // Extract the path from the URL pathname (everything after /files/)\n const url = new URL(c.req.url)\n const pathname = url.pathname\n\n // Remove the /files/ prefix to get the R2 object key\n const objectKey = pathname.replace(/^\\/files\\//, '')\n\n if (!objectKey) {\n return c.notFound()\n }\n\n // Get file from R2\n const object = await c.env.MEDIA_BUCKET.get(objectKey)\n\n if (!object) {\n return c.notFound()\n }\n\n // Set appropriate headers\n const headers = new Headers()\n object.httpMetadata?.contentType && headers.set('Content-Type', object.httpMetadata.contentType)\n object.httpMetadata?.contentDisposition && headers.set('Content-Disposition', object.httpMetadata.contentDisposition)\n headers.set('Cache-Control', 'public, max-age=31536000') // 1 year cache\n headers.set('Access-Control-Allow-Origin', '*') // Allow CORS for media files\n headers.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')\n headers.set('Access-Control-Allow-Headers', 'Content-Type')\n\n return new Response(object.body as any, {\n headers\n })\n } catch (error) {\n console.error('Error serving file:', error)\n return c.notFound()\n }\n })\n\n // Custom routes - User-defined routes\n if (config.routes) {\n for (const route of config.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Root redirect to login\n app.get('/', (c) => {\n return c.redirect('/auth/login')\n })\n\n // Health check\n app.get('/health', (c) => {\n return c.json({\n name: appName,\n version: appVersion,\n status: 'running',\n timestamp: new Date().toISOString()\n })\n })\n\n // 404 handler\n app.notFound((c) => {\n return c.json({ error: 'Not Found', status: 404 }, 404)\n })\n\n // Error handler\n app.onError((err, c) => {\n console.error(err)\n return c.json({ error: 'Internal Server Error', status: 500 }, 500)\n })\n\n return app\n}\n\n/**\n * Setup core middleware (backward compatibility)\n *\n * @param _app - Hono application\n * @deprecated Use createSonicJSApp() instead\n */\nexport function setupCoreMiddleware(_app: SonicJSApp): void {\n console.warn('setupCoreMiddleware is deprecated. Use createSonicJSApp() instead.')\n // Backward compatibility implementation\n}\n\n/**\n * Setup core routes (backward compatibility)\n *\n * @param _app - Hono application\n * @deprecated Use createSonicJSApp() instead\n */\nexport function setupCoreRoutes(_app: SonicJSApp): void {\n console.warn('setupCoreRoutes is deprecated. Use createSonicJSApp() instead.')\n // Backward compatibility implementation\n}\n","import { drizzle } from 'drizzle-orm/d1';\nimport * as schema from './schema';\n\nexport function createDb(d1: D1Database) {\n return drizzle(d1, { schema });\n}\n\nexport * from './schema';","/**\n * @sonicjs/core - Main Entry Point\n *\n * Core framework for SonicJS headless CMS\n * Built for Cloudflare's edge platform with TypeScript\n *\n * Phase 2 Migration Status:\n * - Week 1: Types, Utils, Database (COMPLETED ✓)\n * - Week 2: Services, Middleware, Plugins (COMPLETED ✓)\n * - Week 3: Routes, Templates (COMPLETED ✓)\n * - Week 4: Integration & Testing (COMPLETED ✓)\n *\n * Test Coverage:\n * - Utilities: 48 tests (sanitize, query-filter, metrics)\n * - Middleware: 51 tests (auth, logging, security, performance)\n * - Total: 99 tests passing\n */\n\n// ============================================================================\n// Main Application API (Phase 2 Week 1)\n// ============================================================================\n\nexport { createSonicJSApp, setupCoreMiddleware, setupCoreRoutes } from './app'\nexport type { SonicJSConfig, SonicJSApp, Bindings, Variables } from './app'\n\n// ============================================================================\n// Placeholders - To be populated in Phase 2\n// ============================================================================\n\n// Services - Week 2 (COMPLETED)\nexport {\n // Collection Management\n loadCollectionConfigs,\n loadCollectionConfig,\n getAvailableCollectionNames,\n validateCollectionConfig,\n registerCollections,\n syncCollections,\n syncCollection,\n isCollectionManaged,\n getManagedCollections,\n cleanupRemovedCollections,\n fullCollectionSync,\n // Database Migrations\n MigrationService,\n // Logging\n Logger,\n getLogger,\n initLogger,\n // Plugin Services - Class implementations\n PluginService as PluginServiceClass,\n PluginBootstrapService,\n} from './services'\n\nexport type { Migration, MigrationStatus, LogLevel, LogCategory, LogEntry, LogFilter, CorePlugin } from './services'\n\n// Middleware - Week 2 (COMPLETED)\nexport {\n // Authentication\n AuthManager,\n requireAuth,\n requireRole,\n optionalAuth,\n // Logging\n loggingMiddleware,\n detailedLoggingMiddleware,\n securityLoggingMiddleware,\n performanceLoggingMiddleware,\n // Performance\n cacheHeaders,\n compressionMiddleware,\n securityHeaders,\n // Permissions\n PermissionManager,\n requirePermission,\n requireAnyPermission,\n logActivity,\n // Plugin middleware\n requireActivePlugin,\n requireActivePlugins,\n getActivePlugins,\n isPluginActive,\n // Bootstrap\n bootstrapMiddleware,\n} from './middleware'\n\nexport type { Permission, UserPermissions } from './middleware'\n\n// Plugins - Week 2 (COMPLETED)\nexport {\n // Hook System - Class implementations\n HookSystemImpl,\n ScopedHookSystem as ScopedHookSystemClass,\n HookUtils,\n // Plugin Registry\n PluginRegistryImpl,\n // Plugin Manager - Class implementation\n PluginManager as PluginManagerClass,\n // Plugin Validator - Class implementation\n PluginValidator as PluginValidatorClass,\n} from './plugins'\n\n// Routes - Week 3 (COMPLETED)\nexport {\n ROUTES_INFO,\n apiRoutes,\n apiContentCrudRoutes,\n apiMediaRoutes,\n apiSystemRoutes,\n adminApiRoutes,\n authRoutes,\n adminContentRoutes,\n adminUsersRoutes,\n adminMediaRoutes,\n adminLogsRoutes,\n adminPluginRoutes,\n adminDesignRoutes,\n adminCheckboxRoutes,\n adminTestimonialsRoutes,\n adminCodeExamplesRoutes,\n adminDashboardRoutes,\n adminCollectionsRoutes,\n adminSettingsRoutes,\n} from './routes'\n\n// Templates - Week 3 (COMPLETED)\nexport {\n // Form templates\n renderForm,\n renderFormField,\n // Table templates\n renderTable,\n // Pagination templates\n renderPagination,\n // Alert templates\n renderAlert,\n // Confirmation dialog templates\n renderConfirmationDialog,\n getConfirmationDialogScript,\n // Filter bar templates\n renderFilterBar,\n} from './templates'\n\nexport type {\n FormField,\n FormData,\n TableColumn,\n TableData,\n PaginationData,\n AlertData,\n ConfirmationDialogOptions,\n FilterBarData,\n Filter,\n FilterOption,\n} from './templates'\n\n// Types - Week 1 (COMPLETED)\nexport type {\n // Collection types\n FieldType,\n FieldConfig,\n CollectionSchema,\n CollectionConfig,\n CollectionConfigModule,\n CollectionSyncResult,\n // Plugin types\n Plugin,\n PluginContext,\n PluginConfig,\n PluginRoutes,\n PluginMiddleware,\n PluginModel,\n PluginService,\n PluginAdminPage,\n PluginComponent,\n PluginMenuItem,\n PluginHook,\n HookHandler,\n HookContext,\n HookSystem,\n ScopedHookSystem,\n PluginRegistry,\n PluginManager,\n PluginStatus,\n AuthService,\n ContentService,\n MediaService,\n PluginLogger,\n PluginBuilderOptions,\n PluginValidator,\n PluginValidationResult,\n HookName,\n // Plugin manifest\n PluginManifest,\n} from './types'\n\nexport { HOOKS } from './types'\n\n// Utils - Week 1 (COMPLETED)\nexport {\n // Sanitization\n escapeHtml,\n sanitizeInput,\n sanitizeObject,\n // Template rendering\n TemplateRenderer,\n templateRenderer,\n renderTemplate,\n // Query filtering\n QueryFilterBuilder,\n buildQuery,\n // Metrics\n metricsTracker,\n // Version\n SONICJS_VERSION,\n getCoreVersion,\n} from './utils'\n\nexport type {\n FilterOperator,\n FilterCondition,\n FilterGroup,\n QueryFilter,\n QueryResult,\n} from './utils'\n\n// Database - Week 1 (COMPLETED)\nexport {\n createDb,\n // Schema exports\n users,\n collections,\n content,\n contentVersions,\n media,\n apiTokens,\n workflowHistory,\n plugins,\n pluginHooks,\n pluginRoutes,\n pluginAssets,\n pluginActivityLog,\n systemLogs,\n logConfig,\n // Zod validation schemas\n insertUserSchema,\n selectUserSchema,\n insertCollectionSchema,\n selectCollectionSchema,\n insertContentSchema,\n selectContentSchema,\n insertMediaSchema,\n selectMediaSchema,\n insertWorkflowHistorySchema,\n selectWorkflowHistorySchema,\n insertPluginSchema,\n selectPluginSchema,\n insertPluginHookSchema,\n selectPluginHookSchema,\n insertPluginRouteSchema,\n selectPluginRouteSchema,\n insertPluginAssetSchema,\n selectPluginAssetSchema,\n insertPluginActivityLogSchema,\n selectPluginActivityLogSchema,\n insertSystemLogSchema,\n selectSystemLogSchema,\n insertLogConfigSchema,\n selectLogConfigSchema,\n} from './db'\n\nexport type {\n User,\n NewUser,\n Collection,\n NewCollection,\n Content,\n NewContent,\n Media,\n NewMedia,\n WorkflowHistory,\n NewWorkflowHistory,\n Plugin as DbPlugin,\n NewPlugin,\n PluginHook as DbPluginHook,\n NewPluginHook,\n PluginRoute,\n NewPluginRoute,\n PluginAsset,\n NewPluginAsset,\n PluginActivityLog,\n NewPluginActivityLog,\n SystemLog,\n NewSystemLog,\n LogConfig,\n NewLogConfig,\n} from './db'\n\n// Plugins - Week 2\n// export { PluginBuilder, HookSystem } from './plugins/sdk'\n\n// ============================================================================\n// Version\n// ============================================================================\n\n// Import version from package.json\nimport packageJson from '../package.json'\nexport const VERSION = packageJson.version\n\n// ============================================================================\n// Phase 2 Migration Notes\n// ============================================================================\n\n/**\n * This is a work-in-progress package being extracted from the main SonicJS codebase.\n *\n * Current Phase: 2 (Core Module Migration)\n * Current Week: 1 (Types, Utils, Database)\n *\n * Expected completion: 4 weeks from 2025-01-17\n *\n * DO NOT USE IN PRODUCTION - Alpha release for development only\n */\n"]}
1
+ {"version":3,"sources":["../src/plugins/core-plugins/database-tools-plugin/services/database-service.ts","../src/templates/pages/admin-database-table.template.ts","../src/plugins/core-plugins/database-tools-plugin/admin-routes.ts","../src/plugins/core-plugins/email-plugin/index.ts","../src/plugins/core-plugins/otp-login-plugin/otp-service.ts","../src/plugins/core-plugins/otp-login-plugin/email-templates.ts","../src/plugins/core-plugins/otp-login-plugin/index.ts","../src/plugins/available/magic-link-auth/index.ts","../src/app.ts","../src/db/index.ts","../src/index.ts"],"names":["init_admin_layout_catalyst_template","escapeHtml","renderAdminLayoutCatalyst","router","Hono","requireAuth","PluginBuilder","html","renderAdminLayout","z","emailPlugin","adminLayoutV2","AuthManager","getCoreVersion","metricsMiddleware","bootstrapMiddleware","api_default","api_media_default","api_system_default","admin_api_default","adminCollectionsRoutes","adminSettingsRoutes","admin_content_default","adminMediaRoutes","adminPluginRoutes","adminLogsRoutes","userRoutes","auth_default","test_cleanup_default","d1","drizzle","schema_exports","package_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import { D1Database } from '@cloudflare/workers-types'\n\nexport interface TruncateResult {\n success: boolean\n message: string\n tablesCleared: string[]\n adminUserPreserved: boolean\n errors?: string[]\n}\n\nexport interface DatabaseStats {\n tables: Array<{\n name: string\n rowCount: number\n }>\n totalRows: number\n}\n\nexport interface TableData {\n tableName: string\n columns: string[]\n rows: any[]\n totalRows: number\n}\n\nexport class DatabaseToolsService {\n constructor(private db: D1Database) {}\n\n /**\n * Get database statistics\n */\n async getDatabaseStats(): Promise<DatabaseStats> {\n const tables = await this.getTables()\n const stats: DatabaseStats = {\n tables: [],\n totalRows: 0\n }\n\n for (const tableName of tables) {\n try {\n const result = await this.db.prepare(`SELECT COUNT(*) as count FROM ${tableName}`).first()\n const rowCount = (result?.count as number) || 0\n \n stats.tables.push({\n name: tableName,\n rowCount\n })\n stats.totalRows += rowCount\n } catch (error) {\n // Skip tables that can't be counted (might be views or system tables)\n console.warn(`Could not count rows in table ${tableName}:`, error)\n }\n }\n\n return stats\n }\n\n /**\n * Get all tables in the database\n */\n private async getTables(): Promise<string[]> {\n const result = await this.db.prepare(`\n SELECT name FROM sqlite_master \n WHERE type='table' \n AND name NOT LIKE 'sqlite_%'\n ORDER BY name\n `).all()\n\n return result.results?.map((row: any) => row.name) || []\n }\n\n /**\n * Truncate all data except admin user\n */\n async truncateAllData(adminEmail: string): Promise<TruncateResult> {\n const errors: string[] = []\n const tablesCleared: string[] = []\n let adminUserPreserved = false\n\n try {\n // First, preserve the admin user data\n const adminUser = await this.db.prepare(\n 'SELECT * FROM users WHERE email = ? AND role = ?'\n ).bind(adminEmail, 'admin').first()\n\n if (!adminUser) {\n return {\n success: false,\n message: 'Admin user not found. Operation cancelled for safety.',\n tablesCleared: [],\n adminUserPreserved: false,\n errors: ['Admin user not found']\n }\n }\n\n // Define tables to truncate (excluding system tables)\n const tablesToTruncate = [\n 'content',\n 'content_versions', \n 'content_workflow_status',\n 'collections',\n 'media',\n 'sessions',\n 'notifications',\n 'api_tokens',\n 'workflow_history',\n 'scheduled_content',\n 'faqs',\n 'faq_categories',\n 'plugins',\n 'plugin_settings',\n 'email_templates',\n 'email_themes'\n ]\n\n // Check which tables exist\n const existingTables = await this.getTables()\n const tablesToClear = tablesToTruncate.filter(table => \n existingTables.includes(table)\n )\n\n // Clear all data except users table\n for (const tableName of tablesToClear) {\n try {\n await this.db.prepare(`DELETE FROM ${tableName}`).run()\n tablesCleared.push(tableName)\n } catch (error) {\n errors.push(`Failed to clear table ${tableName}: ${error}`)\n console.error(`Error clearing table ${tableName}:`, error)\n }\n }\n\n // Clear users table but preserve admin\n try {\n await this.db.prepare('DELETE FROM users WHERE email != ? OR role != ?')\n .bind(adminEmail, 'admin').run()\n \n // Verify admin user still exists\n const verifyAdmin = await this.db.prepare(\n 'SELECT id FROM users WHERE email = ? AND role = ?'\n ).bind(adminEmail, 'admin').first()\n\n adminUserPreserved = !!verifyAdmin\n tablesCleared.push('users (non-admin)')\n } catch (error) {\n errors.push(`Failed to clear non-admin users: ${error}`)\n console.error('Error clearing non-admin users:', error)\n }\n\n // Reset auto-increment counters if supported\n try {\n await this.db.prepare('DELETE FROM sqlite_sequence').run()\n } catch (error) {\n // sqlite_sequence might not exist, ignore\n }\n\n const message = errors.length > 0 \n ? `Truncation completed with ${errors.length} errors. ${tablesCleared.length} tables cleared.`\n : `Successfully truncated database. ${tablesCleared.length} tables cleared.`\n\n return {\n success: errors.length === 0,\n message,\n tablesCleared,\n adminUserPreserved,\n errors: errors.length > 0 ? errors : undefined\n }\n\n } catch (error) {\n return {\n success: false,\n message: `Database truncation failed: ${error}`,\n tablesCleared,\n adminUserPreserved,\n errors: [String(error)]\n }\n }\n }\n\n /**\n * Create a backup of current data (simplified version)\n */\n async createBackup(): Promise<{ success: boolean; message: string; backupId?: string }> {\n try {\n const backupId = `backup_${Date.now()}`\n const stats = await this.getDatabaseStats()\n \n // In a real implementation, this would export data to a file or cloud storage\n // For now, we'll just log the stats and return success\n console.log(`Backup ${backupId} created with ${stats.totalRows} total rows`)\n \n return {\n success: true,\n message: `Backup created successfully (${stats.totalRows} rows)`,\n backupId\n }\n } catch (error) {\n return {\n success: false,\n message: `Backup failed: ${error}`\n }\n }\n }\n\n /**\n * Get table data with optional pagination and sorting\n */\n async getTableData(\n tableName: string,\n limit: number = 100,\n offset: number = 0,\n sortColumn?: string,\n sortDirection: 'asc' | 'desc' = 'asc'\n ): Promise<TableData> {\n try {\n // Validate table name to prevent SQL injection\n const tables = await this.getTables()\n if (!tables.includes(tableName)) {\n throw new Error(`Table ${tableName} not found`)\n }\n\n // Get column names\n const pragmaResult = await this.db.prepare(`PRAGMA table_info(${tableName})`).all()\n const columns = pragmaResult.results?.map((col: any) => col.name) || []\n\n // Validate sort column if provided\n if (sortColumn && !columns.includes(sortColumn)) {\n sortColumn = undefined\n }\n\n // Get total row count\n const countResult = await this.db.prepare(`SELECT COUNT(*) as count FROM ${tableName}`).first()\n const totalRows = (countResult?.count as number) || 0\n\n // Build query with optional sorting\n let query = `SELECT * FROM ${tableName}`\n if (sortColumn) {\n query += ` ORDER BY ${sortColumn} ${sortDirection.toUpperCase()}`\n }\n query += ` LIMIT ${limit} OFFSET ${offset}`\n\n // Get paginated data\n const dataResult = await this.db.prepare(query).all()\n\n return {\n tableName,\n columns,\n rows: dataResult.results || [],\n totalRows\n }\n } catch (error) {\n throw new Error(`Failed to fetch table data: ${error}`)\n }\n }\n\n /**\n * Validate database integrity\n */\n async validateDatabase(): Promise<{ valid: boolean; issues: string[] }> {\n const issues: string[] = []\n\n try {\n // Check critical tables exist\n const requiredTables = ['users', 'content', 'collections']\n const existingTables = await this.getTables()\n\n for (const table of requiredTables) {\n if (!existingTables.includes(table)) {\n issues.push(`Critical table missing: ${table}`)\n }\n }\n\n // Check admin user exists\n const adminCount = await this.db.prepare(\n 'SELECT COUNT(*) as count FROM users WHERE role = ?'\n ).bind('admin').first()\n\n if ((adminCount?.count as number) === 0) {\n issues.push('No admin users found')\n }\n\n // Run SQLite integrity check\n try {\n const integrityResult = await this.db.prepare('PRAGMA integrity_check').first()\n if (integrityResult && (integrityResult as any).integrity_check !== 'ok') {\n issues.push(`Database integrity check failed: ${(integrityResult as any).integrity_check}`)\n }\n } catch (error) {\n issues.push(`Could not run integrity check: ${error}`)\n }\n\n } catch (error) {\n issues.push(`Validation error: ${error}`)\n }\n\n return {\n valid: issues.length === 0,\n issues\n }\n }\n}","import { renderAdminLayoutCatalyst, AdminLayoutCatalystData } from '../layouts/admin-layout-catalyst.template'\n\nexport interface DatabaseTablePageData {\n user?: {\n name: string\n email: string\n role: string\n }\n tableName: string\n columns: string[]\n rows: any[]\n totalRows: number\n currentPage: number\n pageSize: number\n sortColumn?: string\n sortDirection?: 'asc' | 'desc'\n}\n\nexport function renderDatabaseTablePage(data: DatabaseTablePageData): string {\n const totalPages = Math.ceil(data.totalRows / data.pageSize)\n const startRow = (data.currentPage - 1) * data.pageSize + 1\n const endRow = Math.min(data.currentPage * data.pageSize, data.totalRows)\n\n const pageContent = `\n <div class=\"space-y-6\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <div class=\"flex items-center space-x-3\">\n <a\n href=\"/admin/settings/database-tools\"\n class=\"inline-flex items-center text-sm/6 text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300\"\n >\n <svg class=\"w-5 h-5 mr-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n </svg>\n Back to Database Tools\n </a>\n </div>\n <h1 class=\"mt-2 text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8\">Table: ${data.tableName}</h1>\n <p class=\"mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400\">\n Showing ${startRow.toLocaleString()} - ${endRow.toLocaleString()} of ${data.totalRows.toLocaleString()} rows\n </p>\n </div>\n <div class=\"mt-4 sm:mt-0 flex items-center space-x-3\">\n <div class=\"flex items-center space-x-2\">\n <label for=\"pageSize\" class=\"text-sm font-medium text-zinc-700 dark:text-zinc-300\">\n Rows per page:\n </label>\n <select\n id=\"pageSize\"\n onchange=\"changePageSize(this.value)\"\n class=\"rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm cursor-pointer\"\n >\n <option value=\"10\" ${data.pageSize === 10 ? 'selected' : ''}>10</option>\n <option value=\"20\" ${data.pageSize === 20 ? 'selected' : ''}>20</option>\n <option value=\"50\" ${data.pageSize === 50 ? 'selected' : ''}>50</option>\n <option value=\"100\" ${data.pageSize === 100 ? 'selected' : ''}>100</option>\n <option value=\"200\" ${data.pageSize === 200 ? 'selected' : ''}>200</option>\n </select>\n </div>\n <button\n onclick=\"refreshTableData()\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"/>\n </svg>\n Refresh\n </button>\n </div>\n </div>\n\n <!-- Table Card -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden\">\n <!-- Table -->\n <div class=\"overflow-x-auto\">\n <table class=\"min-w-full divide-y divide-zinc-950/10 dark:divide-white/10\">\n <thead class=\"bg-zinc-50 dark:bg-white/5\">\n <tr>\n ${data.columns.map(col => `\n <th\n scope=\"col\"\n class=\"px-4 py-3.5 text-left text-xs font-semibold text-zinc-950 dark:text-white uppercase tracking-wider cursor-pointer hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors\"\n onclick=\"sortTable('${col}')\"\n >\n <div class=\"flex items-center space-x-1\">\n <span>${col}</span>\n ${data.sortColumn === col ? `\n <svg class=\"w-4 h-4 ${data.sortDirection === 'asc' ? '' : 'rotate-180'}\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 15l7-7 7 7\"/>\n </svg>\n ` : `\n <svg class=\"w-4 h-4 text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\"/>\n </svg>\n `}\n </div>\n </th>\n `).join('')}\n </tr>\n </thead>\n <tbody class=\"divide-y divide-zinc-950/5 dark:divide-white/5\">\n ${data.rows.length > 0\n ? data.rows.map((row, idx) => `\n <tr class=\"${idx % 2 === 0 ? 'bg-white dark:bg-zinc-900' : 'bg-zinc-50 dark:bg-zinc-900/50'}\">\n ${data.columns.map(col => `\n <td class=\"px-4 py-3 text-sm text-zinc-700 dark:text-zinc-300 whitespace-nowrap max-w-xs overflow-hidden text-ellipsis\" title=\"${escapeHtml(String(row[col] ?? ''))}\">\n ${formatCellValue(row[col])}\n </td>\n `).join('')}\n </tr>\n `).join('')\n : `\n <tr>\n <td colspan=\"${data.columns.length}\" class=\"px-4 py-12 text-center text-sm text-zinc-500 dark:text-zinc-400\">\n <svg class=\"w-12 h-12 mx-auto mb-4 text-zinc-400 dark:text-zinc-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4\"/>\n </svg>\n <p>No data in this table</p>\n </td>\n </tr>\n `\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n ${totalPages > 1 ? `\n <div class=\"flex items-center justify-between border-t border-zinc-950/10 dark:border-white/10 bg-zinc-50 dark:bg-zinc-900/50 px-4 py-3 sm:px-6\">\n <div class=\"flex flex-1 justify-between sm:hidden\">\n <button\n onclick=\"goToPage(${data.currentPage - 1})\"\n ${data.currentPage === 1 ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-lg px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-100 dark:hover:bg-zinc-800 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Previous\n </button>\n <button\n onclick=\"goToPage(${data.currentPage + 1})\"\n ${data.currentPage === totalPages ? 'disabled' : ''}\n class=\"relative ml-3 inline-flex items-center rounded-lg px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-100 dark:hover:bg-zinc-800 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n </button>\n </div>\n <div class=\"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between\">\n <div>\n <p class=\"text-sm text-zinc-700 dark:text-zinc-300\">\n Page <span class=\"font-medium\">${data.currentPage}</span> of <span class=\"font-medium\">${totalPages}</span>\n </p>\n </div>\n <div>\n <nav class=\"isolate inline-flex -space-x-px rounded-lg shadow-sm\" aria-label=\"Pagination\">\n <button\n onclick=\"goToPage(${data.currentPage - 1})\"\n ${data.currentPage === 1 ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-l-lg px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800 focus:z-20 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <span class=\"sr-only\">Previous</span>\n <svg class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n ${generatePageNumbers(data.currentPage, totalPages)}\n\n <button\n onclick=\"goToPage(${data.currentPage + 1})\"\n ${data.currentPage === totalPages ? 'disabled' : ''}\n class=\"relative inline-flex items-center rounded-r-lg px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800 focus:z-20 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <span class=\"sr-only\">Next</span>\n <svg class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </nav>\n </div>\n </div>\n </div>\n ` : ''}\n </div>\n </div>\n\n <script>\n const currentTableName = '${data.tableName}';\n let currentPage = ${data.currentPage};\n let currentPageSize = ${data.pageSize};\n let currentSort = '${data.sortColumn || ''}';\n let currentSortDir = '${data.sortDirection || 'asc'}';\n\n function goToPage(page) {\n if (page < 1 || page > ${totalPages}) return;\n const params = new URLSearchParams();\n params.set('page', page);\n params.set('pageSize', currentPageSize);\n if (currentSort) {\n params.set('sort', currentSort);\n params.set('dir', currentSortDir);\n }\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function sortTable(column) {\n let newDir = 'asc';\n if (currentSort === column && currentSortDir === 'asc') {\n newDir = 'desc';\n }\n\n const params = new URLSearchParams();\n params.set('page', '1');\n params.set('pageSize', currentPageSize);\n params.set('sort', column);\n params.set('dir', newDir);\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function changePageSize(newSize) {\n const params = new URLSearchParams();\n params.set('page', '1');\n params.set('pageSize', newSize);\n if (currentSort) {\n params.set('sort', currentSort);\n params.set('dir', currentSortDir);\n }\n window.location.href = \\`/admin/database-tools/tables/\\${currentTableName}?\\${params}\\`;\n }\n\n function refreshTableData() {\n window.location.reload();\n }\n\n function formatCellValue(value) {\n if (value === null || value === undefined) {\n return '<span class=\"text-zinc-400 dark:text-zinc-500 italic\">null</span>';\n }\n if (typeof value === 'boolean') {\n return \\`<span class=\"px-2 py-0.5 rounded text-xs font-medium \\${value ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-400'}\">\\${value}</span>\\`;\n }\n if (typeof value === 'object') {\n return '<span class=\"text-xs font-mono text-zinc-600 dark:text-zinc-400\">' + JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? '...' : '') + '</span>';\n }\n const str = String(value);\n if (str.length > 100) {\n return escapeHtml(str.substring(0, 100)) + '...';\n }\n return escapeHtml(str);\n }\n\n function escapeHtml(text) {\n const map = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n };\n return String(text).replace(/[&<>\"']/g, m => map[m]);\n }\n </script>\n `\n\n const layoutData: AdminLayoutCatalystData = {\n title: `Table: ${data.tableName}`,\n pageTitle: `Database: ${data.tableName}`,\n currentPath: `/admin/database-tools/tables/${data.tableName}`,\n user: data.user,\n content: pageContent\n }\n\n return renderAdminLayoutCatalyst(layoutData)\n}\n\nfunction generatePageNumbers(currentPage: number, totalPages: number): string {\n const pages: number[] = []\n const maxVisible = 7\n\n if (totalPages <= maxVisible) {\n for (let i = 1; i <= totalPages; i++) {\n pages.push(i)\n }\n } else {\n if (currentPage <= 4) {\n for (let i = 1; i <= 5; i++) pages.push(i)\n pages.push(-1) // ellipsis\n pages.push(totalPages)\n } else if (currentPage >= totalPages - 3) {\n pages.push(1)\n pages.push(-1) // ellipsis\n for (let i = totalPages - 4; i <= totalPages; i++) pages.push(i)\n } else {\n pages.push(1)\n pages.push(-1) // ellipsis\n for (let i = currentPage - 1; i <= currentPage + 1; i++) pages.push(i)\n pages.push(-1) // ellipsis\n pages.push(totalPages)\n }\n }\n\n return pages.map(page => {\n if (page === -1) {\n return `\n <span class=\"relative inline-flex items-center px-4 py-2 text-sm font-semibold text-zinc-700 dark:text-zinc-300 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700\">\n ...\n </span>\n `\n }\n\n const isActive = page === currentPage\n return `\n <button\n onclick=\"goToPage(${page})\"\n class=\"relative inline-flex items-center px-4 py-2 text-sm font-semibold ${\n isActive\n ? 'z-10 bg-indigo-600 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'\n : 'text-zinc-900 dark:text-zinc-100 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800'\n }\"\n >\n ${page}\n </button>\n `\n }).join('')\n}\n\nfunction escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#039;'\n }\n return String(text).replace(/[&<>\"']/g, m => map[m] || m)\n}\n\nfunction formatCellValue(value: any): string {\n if (value === null || value === undefined) {\n return '<span class=\"text-zinc-400 dark:text-zinc-500 italic\">null</span>'\n }\n if (typeof value === 'boolean') {\n return `<span class=\"px-2 py-0.5 rounded text-xs font-medium ${value ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' : 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-400'}\">${value}</span>`\n }\n if (typeof value === 'object') {\n return '<span class=\"text-xs font-mono text-zinc-600 dark:text-zinc-400\">' + JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? '...' : '') + '</span>'\n }\n const str = String(value)\n if (str.length > 100) {\n return escapeHtml(str.substring(0, 100)) + '...'\n }\n return escapeHtml(str)\n}\n","import { Hono } from 'hono'\nimport { DatabaseToolsService } from './services/database-service'\nimport { renderDatabaseTablePage, DatabaseTablePageData } from '../../../templates/pages/admin-database-table.template'\nimport { requireAuth } from '../../../middleware'\n\ntype Bindings = {\n DB: D1Database\n}\n\ntype Variables = {\n user?: {\n userId: string\n email: string\n role: string\n }\n}\n\nexport function createDatabaseToolsAdminRoutes() {\n const router = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n // Apply authentication middleware\n router.use('*', requireAuth())\n\n // Get database statistics\n router.get('/api/stats', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const stats = await service.getDatabaseStats()\n\n return c.json({\n success: true,\n data: stats\n })\n } catch (error) {\n console.error('Error fetching database stats:', error)\n return c.json({ \n success: false, \n error: 'Failed to fetch database statistics' \n }, 500)\n }\n })\n\n // Truncate all data except admin user\n router.post('/api/truncate', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const body = await c.req.json()\n const { confirmText } = body\n\n // Require confirmation text for safety\n if (confirmText !== 'TRUNCATE ALL DATA') {\n return c.json({\n success: false,\n error: 'Invalid confirmation text. Operation cancelled.'\n }, 400)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const result = await service.truncateAllData(user.email)\n\n return c.json({\n success: result.success,\n message: result.message,\n data: {\n tablesCleared: result.tablesCleared,\n adminUserPreserved: result.adminUserPreserved,\n errors: result.errors\n }\n })\n } catch (error) {\n console.error('Error truncating database:', error)\n return c.json({ \n success: false, \n error: 'Failed to truncate database' \n }, 500)\n }\n })\n\n // Create backup\n router.post('/api/backup', async (c) => {\n try {\n const user = c.get('user')\n \n if (!user || user.role !== 'admin') {\n return c.json({ \n success: false, \n error: 'Unauthorized. Admin access required.' \n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const result = await service.createBackup()\n\n return c.json({\n success: result.success,\n message: result.message,\n data: {\n backupId: result.backupId\n }\n })\n } catch (error) {\n console.error('Error creating backup:', error)\n return c.json({ \n success: false, \n error: 'Failed to create backup' \n }, 500)\n }\n })\n\n // Validate database\n router.get('/api/validate', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.json({\n success: false,\n error: 'Unauthorized. Admin access required.'\n }, 403)\n }\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const validation = await service.validateDatabase()\n\n return c.json({\n success: true,\n data: validation\n })\n } catch (error) {\n console.error('Error validating database:', error)\n return c.json({\n success: false,\n error: 'Failed to validate database'\n }, 500)\n }\n })\n\n // Get table data (API endpoint)\n router.get('/api/tables/:tableName', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.json({\n success: false,\n error: 'Unauthorized. Admin access required.'\n }, 403)\n }\n\n const tableName = c.req.param('tableName')\n const limit = parseInt(c.req.query('limit') || '100')\n const offset = parseInt(c.req.query('offset') || '0')\n const sortColumn = c.req.query('sort')\n const sortDirection = (c.req.query('dir') || 'asc') as 'asc' | 'desc'\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const tableData = await service.getTableData(tableName, limit, offset, sortColumn, sortDirection)\n\n return c.json({\n success: true,\n data: tableData\n })\n } catch (error) {\n console.error('Error fetching table data:', error)\n return c.json({\n success: false,\n error: `Failed to fetch table data: ${error}`\n }, 500)\n }\n })\n\n // View table data page\n router.get('/tables/:tableName', async (c) => {\n try {\n const user = c.get('user')\n\n if (!user || user.role !== 'admin') {\n return c.redirect('/admin/login')\n }\n\n const tableName = c.req.param('tableName')\n const page = parseInt(c.req.query('page') || '1')\n const pageSize = parseInt(c.req.query('pageSize') || '20')\n const sortColumn = c.req.query('sort')\n const sortDirection = (c.req.query('dir') || 'asc') as 'asc' | 'desc'\n\n const offset = (page - 1) * pageSize\n\n const db = c.env.DB\n const service = new DatabaseToolsService(db)\n const tableData = await service.getTableData(tableName, pageSize, offset, sortColumn, sortDirection)\n\n const pageData: DatabaseTablePageData = {\n user: {\n name: user.email.split('@')[0] || 'Unknown',\n email: user.email,\n role: user.role\n },\n tableName: tableData.tableName,\n columns: tableData.columns,\n rows: tableData.rows,\n totalRows: tableData.totalRows,\n currentPage: page,\n pageSize: pageSize,\n sortColumn: sortColumn,\n sortDirection: sortDirection\n }\n\n return c.html(renderDatabaseTablePage(pageData))\n } catch (error) {\n console.error('Error rendering table page:', error)\n return c.text(`Error: ${error}`, 500)\n }\n })\n\n return router\n}","/**\n * Email Plugin\n *\n * Send transactional emails using Resend\n * Handles registration, verification, password reset, and one-time codes\n */\n\nimport { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport { PluginBuilder } from '../../sdk/plugin-builder'\nimport type { Plugin } from '@sonicjs-cms/core'\nimport { renderAdminLayout } from '../../../templates/layouts/admin-layout-v2.template'\n\nexport function createEmailPlugin(): Plugin {\n const builder = PluginBuilder.create({\n name: 'email',\n version: '1.0.0-beta.1',\n description: 'Send transactional emails using Resend'\n })\n\n // Add plugin metadata\n builder.metadata({\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n license: 'MIT',\n compatibility: '^2.0.0'\n })\n\n // Create the Email Settings route\n const emailRoutes = new Hono()\n\n emailRoutes.get('/settings', async (c: any) => {\n const user = c.get('user') as { email?: string; role?: string; name?: string } | undefined\n const db = c.env.DB\n\n // Load current settings from database\n const plugin = await db.prepare(`\n SELECT settings FROM plugins WHERE id = 'email'\n `).first() as { settings: string | null } | null\n\n const settings = plugin?.settings ? JSON.parse(plugin.settings) : {}\n\n const contentHTML = await html`\n <div class=\"p-8\">\n <!-- Header -->\n <div class=\"mb-8\">\n <h1 class=\"text-3xl font-bold text-zinc-950 dark:text-white mb-2\">Email Settings</h1>\n <p class=\"text-zinc-600 dark:text-zinc-400\">Configure Resend API for sending transactional emails</p>\n </div>\n\n <!-- Settings Form -->\n <div class=\"max-w-3xl\">\n <!-- Main Settings Card -->\n <div class=\"rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6 mb-6\">\n <h2 class=\"text-xl font-semibold text-zinc-950 dark:text-white mb-4\">Resend Configuration</h2>\n\n <form id=\"emailSettingsForm\" class=\"space-y-6\">\n <!-- API Key -->\n <div>\n <label for=\"apiKey\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Resend API Key <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"password\"\n id=\"apiKey\"\n name=\"apiKey\"\n value=\"${settings.apiKey || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"re_...\"\n required\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Get your API key from <a href=\"https://resend.com/api-keys\" target=\"_blank\" class=\"text-indigo-600 dark:text-indigo-400 hover:underline\">resend.com/api-keys</a>\n </p>\n </div>\n\n <!-- From Email -->\n <div>\n <label for=\"fromEmail\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n From Email <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"email\"\n id=\"fromEmail\"\n name=\"fromEmail\"\n value=\"${settings.fromEmail || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"noreply@yourdomain.com\"\n required\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Must be a verified domain in Resend\n </p>\n </div>\n\n <!-- From Name -->\n <div>\n <label for=\"fromName\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n From Name <span class=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"fromName\"\n name=\"fromName\"\n value=\"${settings.fromName || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"Your App Name\"\n required\n />\n </div>\n\n <!-- Reply To -->\n <div>\n <label for=\"replyTo\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Reply-To Email\n </label>\n <input\n type=\"email\"\n id=\"replyTo\"\n name=\"replyTo\"\n value=\"${settings.replyTo || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"support@yourdomain.com\"\n />\n </div>\n\n <!-- Logo URL -->\n <div>\n <label for=\"logoUrl\" class=\"block text-sm font-medium text-zinc-950 dark:text-white mb-2\">\n Logo URL\n </label>\n <input\n type=\"url\"\n id=\"logoUrl\"\n name=\"logoUrl\"\n value=\"${settings.logoUrl || ''}\"\n class=\"w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400\"\n placeholder=\"https://yourdomain.com/logo.png\"\n />\n <p class=\"text-xs text-zinc-500 dark:text-zinc-400 mt-1\">\n Logo to display in email templates\n </p>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex gap-3 pt-4\">\n <button\n type=\"submit\"\n class=\"inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm\"\n >\n Save Settings\n </button>\n <button\n type=\"button\"\n id=\"testEmailBtn\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Send Test Email\n </button>\n <button\n type=\"button\"\n id=\"resetBtn\"\n class=\"inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm\"\n >\n Reset\n </button>\n </div>\n </form>\n </div>\n\n <!-- Status Message -->\n <div id=\"statusMessage\" class=\"hidden rounded-xl p-4 mb-6\"></div>\n\n <!-- Info Card -->\n <div class=\"rounded-xl bg-indigo-50 dark:bg-indigo-950/30 ring-1 ring-indigo-100 dark:ring-indigo-900/50 p-6\">\n <h3 class=\"font-semibold text-indigo-900 dark:text-indigo-300 mb-3\">\n 📧 Email Templates Included\n </h3>\n <ul class=\"text-sm text-indigo-800 dark:text-indigo-200 space-y-2\">\n <li>✓ Registration confirmation</li>\n <li>✓ Email verification</li>\n <li>✓ Password reset</li>\n <li>✓ One-time code (2FA)</li>\n </ul>\n <p class=\"text-xs text-indigo-700 dark:text-indigo-300 mt-4\">\n Templates are code-based and can be customized by editing the plugin files.\n </p>\n </div>\n </div>\n </div>\n\n <script>\n // Form submission handler\n document.getElementById('emailSettingsForm').addEventListener('submit', async (e) => {\n e.preventDefault()\n const formData = new FormData(e.target)\n const data = Object.fromEntries(formData.entries())\n\n const statusEl = document.getElementById('statusMessage')\n\n try {\n const response = await fetch('/admin/plugins/email/settings', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data)\n })\n\n if (response.ok) {\n statusEl.className = 'rounded-xl bg-green-50 dark:bg-green-950/30 ring-1 ring-green-100 dark:ring-green-900/50 p-4 mb-6 text-green-900 dark:text-green-200'\n statusEl.innerHTML = '✅ Settings saved successfully!'\n statusEl.classList.remove('hidden')\n setTimeout(() => statusEl.classList.add('hidden'), 3000)\n } else {\n throw new Error('Failed to save settings')\n }\n } catch (error) {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = '❌ Failed to save settings. Please try again.'\n statusEl.classList.remove('hidden')\n }\n })\n\n // Test email handler\n document.getElementById('testEmailBtn').addEventListener('click', async () => {\n // Prompt for destination email\n const toEmail = prompt('Enter destination email address for test:')\n if (!toEmail) return\n\n // Basic email validation\n if (!toEmail.match(/^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$/)) {\n alert('Please enter a valid email address')\n return\n }\n\n const statusEl = document.getElementById('statusMessage')\n\n statusEl.className = 'rounded-xl bg-indigo-50 dark:bg-indigo-950/30 ring-1 ring-indigo-100 dark:ring-indigo-900/50 p-4 mb-6 text-indigo-900 dark:text-indigo-200'\n statusEl.innerHTML = \\`📧 Sending test email to \\${toEmail}...\\`\n statusEl.classList.remove('hidden')\n\n try {\n const response = await fetch('/admin/plugins/email/test', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ toEmail })\n })\n\n const data = await response.json()\n\n if (response.ok) {\n statusEl.className = 'rounded-xl bg-green-50 dark:bg-green-950/30 ring-1 ring-green-100 dark:ring-green-900/50 p-4 mb-6 text-green-900 dark:text-green-200'\n statusEl.innerHTML = \\`✅ \\${data.message || 'Test email sent! Check your inbox.'}\\`\n } else {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = \\`❌ \\${data.error || 'Failed to send test email. Check your settings.'}\\`\n }\n } catch (error) {\n statusEl.className = 'rounded-xl bg-red-50 dark:bg-red-950/30 ring-1 ring-red-100 dark:ring-red-900/50 p-4 mb-6 text-red-900 dark:text-red-200'\n statusEl.innerHTML = '❌ Network error. Please try again.'\n }\n })\n\n // Reset button handler\n document.getElementById('resetBtn').addEventListener('click', () => {\n document.getElementById('emailSettingsForm').reset()\n })\n </script>\n `\n\n const templateUser = user ? {\n name: user.name ?? user.email ?? 'Admin',\n email: user.email ?? 'admin@sonicjs.com',\n role: user.role ?? 'admin'\n } : undefined\n\n return c.html(\n renderAdminLayout({\n title: 'Email Settings',\n content: contentHTML,\n user: templateUser,\n currentPath: '/admin/plugins/email/settings'\n })\n )\n })\n\n // POST endpoint for saving settings\n emailRoutes.post('/settings', async (c: any) => {\n try {\n const body = await c.req.json()\n const db = c.env.DB\n\n // Update plugin settings in database\n await db.prepare(`\n UPDATE plugins\n SET settings = ?,\n updated_at = unixepoch()\n WHERE id = 'email'\n `).bind(JSON.stringify(body)).run()\n\n return c.json({ success: true })\n } catch (error) {\n console.error('Error saving email settings:', error)\n return c.json({ success: false, error: 'Failed to save settings' }, 500)\n }\n })\n\n // POST endpoint for test email\n emailRoutes.post('/test', async (c: any) => {\n try {\n const db = c.env.DB\n const body = await c.req.json()\n\n // Load settings from database\n const plugin = await db.prepare(`\n SELECT settings FROM plugins WHERE id = 'email'\n `).first() as { settings: string | null } | null\n\n if (!plugin?.settings) {\n return c.json({\n success: false,\n error: 'Email settings not configured. Please save your settings first.'\n }, 400)\n }\n\n const settings = JSON.parse(plugin.settings)\n\n // Validate required settings\n if (!settings.apiKey || !settings.fromEmail || !settings.fromName) {\n return c.json({\n success: false,\n error: 'Missing required settings. Please configure API Key, From Email, and From Name.'\n }, 400)\n }\n\n // Use provided email or fallback to fromEmail\n const toEmail = body.toEmail || settings.fromEmail\n\n // Validate email format\n if (!toEmail.match(/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/)) {\n return c.json({\n success: false,\n error: 'Invalid email address format'\n }, 400)\n }\n\n // Send test email via Resend API\n const response = await fetch('https://api.resend.com/emails', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${settings.apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n from: `${settings.fromName} <${settings.fromEmail}>`,\n to: [toEmail],\n subject: 'Test Email from SonicJS',\n html: `\n <div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n <h1 style=\"color: #667eea;\">Test Email Successful! 🎉</h1>\n <p>This is a test email from your SonicJS Email plugin.</p>\n <p><strong>Configuration:</strong></p>\n <ul>\n <li>From: ${settings.fromName} &lt;${settings.fromEmail}&gt;</li>\n <li>Reply-To: ${settings.replyTo || 'Not set'}</li>\n <li>Sent at: ${new Date().toISOString()}</li>\n </ul>\n <p>Your email settings are working correctly!</p>\n </div>\n `,\n reply_to: settings.replyTo || settings.fromEmail\n })\n })\n\n const data = await response.json() as any\n\n if (!response.ok) {\n console.error('Resend API error:', data)\n return c.json({\n success: false,\n error: data.message || 'Failed to send test email. Check your API key and domain verification.'\n }, response.status)\n }\n\n return c.json({\n success: true,\n message: `Test email sent successfully to ${toEmail}`,\n emailId: data.id\n })\n\n } catch (error: any) {\n console.error('Test email error:', error)\n return c.json({\n success: false,\n error: error.message || 'An error occurred while sending test email'\n }, 500)\n }\n })\n\n // Register the route\n builder.addRoute('/admin/plugins/email', emailRoutes, {\n description: 'Email plugin settings',\n requiresAuth: true,\n priority: 80\n })\n\n // Add menu item\n builder.addMenuItem('Email', '/admin/plugins/email/settings', {\n icon: 'envelope',\n order: 80,\n permissions: ['email:manage']\n })\n\n // Add lifecycle hooks\n builder.lifecycle({\n activate: async () => {\n console.info('✅ Email plugin activated')\n },\n\n deactivate: async () => {\n console.info('❌ Email plugin deactivated')\n }\n })\n\n return builder.build() as Plugin\n}\n\n// Export the plugin instance\nexport const emailPlugin = createEmailPlugin()\n","/**\n * OTP Service\n * Handles OTP code generation, verification, and management\n */\n\nimport type { D1Database } from '@cloudflare/workers-types'\n\nexport interface OTPSettings {\n codeLength: number\n codeExpiryMinutes: number\n maxAttempts: number\n rateLimitPerHour: number\n allowNewUserRegistration: boolean\n appName: string\n}\n\nexport interface OTPCode {\n id: string\n user_email: string\n code: string\n expires_at: number\n used: number\n used_at: number | null\n ip_address: string | null\n user_agent: string | null\n attempts: number\n created_at: number\n}\n\nexport class OTPService {\n constructor(private db: D1Database) {}\n\n /**\n * Generate a secure random OTP code\n */\n generateCode(length: number = 6): string {\n const digits = '0123456789'\n let code = ''\n\n for (let i = 0; i < length; i++) {\n const randomValues = new Uint8Array(1)\n crypto.getRandomValues(randomValues)\n const randomValue = randomValues[0] ?? 0\n code += digits[randomValue % digits.length]\n }\n\n return code\n }\n\n /**\n * Create and store a new OTP code\n */\n async createOTPCode(\n email: string,\n settings: OTPSettings,\n ipAddress?: string,\n userAgent?: string\n ): Promise<OTPCode> {\n const code = this.generateCode(settings.codeLength)\n const id = crypto.randomUUID()\n const now = Date.now()\n const expiresAt = now + (settings.codeExpiryMinutes * 60 * 1000)\n\n const otpCode: OTPCode = {\n id,\n user_email: email.toLowerCase(),\n code,\n expires_at: expiresAt,\n used: 0,\n used_at: null,\n ip_address: ipAddress || null,\n user_agent: userAgent || null,\n attempts: 0,\n created_at: now\n }\n\n await this.db.prepare(`\n INSERT INTO otp_codes (\n id, user_email, code, expires_at, used, used_at,\n ip_address, user_agent, attempts, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n otpCode.id,\n otpCode.user_email,\n otpCode.code,\n otpCode.expires_at,\n otpCode.used,\n otpCode.used_at,\n otpCode.ip_address,\n otpCode.user_agent,\n otpCode.attempts,\n otpCode.created_at\n ).run()\n\n return otpCode\n }\n\n /**\n * Verify an OTP code\n */\n async verifyCode(\n email: string,\n code: string,\n settings: OTPSettings\n ): Promise<{ valid: boolean; attemptsRemaining?: number; error?: string }> {\n const normalizedEmail = email.toLowerCase()\n const now = Date.now()\n\n // Find the most recent unused code for this email\n const otpCode = await this.db.prepare(`\n SELECT * FROM otp_codes\n WHERE user_email = ? AND code = ? AND used = 0\n ORDER BY created_at DESC\n LIMIT 1\n `).bind(normalizedEmail, code).first() as OTPCode | null\n\n if (!otpCode) {\n return { valid: false, error: 'Invalid or expired code' }\n }\n\n // Check if expired\n if (now > otpCode.expires_at) {\n return { valid: false, error: 'Code has expired' }\n }\n\n // Check attempts\n if (otpCode.attempts >= settings.maxAttempts) {\n return { valid: false, error: 'Maximum attempts exceeded' }\n }\n\n // Code is valid - mark as used\n await this.db.prepare(`\n UPDATE otp_codes\n SET used = 1, used_at = ?, attempts = attempts + 1\n WHERE id = ?\n `).bind(now, otpCode.id).run()\n\n return { valid: true }\n }\n\n /**\n * Increment failed attempt count\n */\n async incrementAttempts(email: string, code: string): Promise<number> {\n const normalizedEmail = email.toLowerCase()\n\n const result = await this.db.prepare(`\n UPDATE otp_codes\n SET attempts = attempts + 1\n WHERE user_email = ? AND code = ? AND used = 0\n RETURNING attempts\n `).bind(normalizedEmail, code).first() as { attempts: number } | null\n\n return result?.attempts || 0\n }\n\n /**\n * Check rate limiting\n */\n async checkRateLimit(email: string, settings: OTPSettings): Promise<boolean> {\n const normalizedEmail = email.toLowerCase()\n const oneHourAgo = Date.now() - (60 * 60 * 1000)\n\n const result = await this.db.prepare(`\n SELECT COUNT(*) as count\n FROM otp_codes\n WHERE user_email = ? AND created_at > ?\n `).bind(normalizedEmail, oneHourAgo).first() as { count: number } | null\n\n const count = result?.count || 0\n return count < settings.rateLimitPerHour\n }\n\n /**\n * Get recent OTP requests for activity log\n */\n async getRecentRequests(limit: number = 50): Promise<OTPCode[]> {\n const result = await this.db.prepare(`\n SELECT * FROM otp_codes\n ORDER BY created_at DESC\n LIMIT ?\n `).bind(limit).all()\n\n const rows = (result.results || []) as Record<string, unknown>[]\n return rows.map(row => this.mapRowToOTP(row))\n }\n\n /**\n * Clean up expired codes (for maintenance)\n */\n async cleanupExpiredCodes(): Promise<number> {\n const now = Date.now()\n\n const result = await this.db.prepare(`\n DELETE FROM otp_codes\n WHERE expires_at < ? OR (used = 1 AND used_at < ?)\n `).bind(now, now - (30 * 24 * 60 * 60 * 1000)).run() // Keep used codes for 30 days\n\n return result.meta.changes || 0\n }\n\n private mapRowToOTP(row: Record<string, unknown>): OTPCode {\n return {\n id: String(row.id),\n user_email: String(row.user_email),\n code: String(row.code),\n expires_at: Number(row.expires_at ?? Date.now()),\n used: Number(row.used ?? 0),\n used_at: row.used_at === null || row.used_at === undefined ? null : Number(row.used_at),\n ip_address: typeof row.ip_address === 'string' ? row.ip_address : null,\n user_agent: typeof row.user_agent === 'string' ? row.user_agent : null,\n attempts: Number(row.attempts ?? 0),\n created_at: Number(row.created_at ?? Date.now())\n }\n }\n\n /**\n * Get OTP statistics\n */\n async getStats(days: number = 7): Promise<{\n total: number\n successful: number\n failed: number\n expired: number\n }> {\n const since = Date.now() - (days * 24 * 60 * 60 * 1000)\n\n const stats = await this.db.prepare(`\n SELECT\n COUNT(*) as total,\n SUM(CASE WHEN used = 1 THEN 1 ELSE 0 END) as successful,\n SUM(CASE WHEN attempts >= 3 AND used = 0 THEN 1 ELSE 0 END) as failed,\n SUM(CASE WHEN expires_at < ? AND used = 0 THEN 1 ELSE 0 END) as expired\n FROM otp_codes\n WHERE created_at > ?\n `).bind(Date.now(), since).first() as any\n\n return {\n total: stats?.total || 0,\n successful: stats?.successful || 0,\n failed: stats?.failed || 0,\n expired: stats?.expired || 0\n }\n }\n}\n","/**\n * OTP Email Templates\n * HTML and plain text templates for OTP codes\n */\n\nexport interface OTPEmailData {\n code: string\n expiryMinutes: number\n codeLength: number\n maxAttempts: number\n email: string\n ipAddress?: string\n timestamp: string\n appName: string\n logoUrl?: string\n}\n\nexport function renderOTPEmailHTML(data: OTPEmailData): string {\n return `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Your Login Code</title>\n</head>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f5f5f5;\">\n\n <div style=\"background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);\">\n\n ${data.logoUrl ? `\n <div style=\"text-align: center; padding: 30px 20px 20px;\">\n <img src=\"${data.logoUrl}\" alt=\"Logo\" style=\"max-width: 150px; height: auto;\">\n </div>\n ` : ''}\n\n <div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px 30px; text-align: center;\">\n <h1 style=\"margin: 0 0 10px 0; font-size: 32px; font-weight: 600;\">Your Login Code</h1>\n <p style=\"margin: 0; opacity: 0.95; font-size: 16px;\">Enter this code to sign in to ${data.appName}</p>\n </div>\n\n <div style=\"padding: 40px 30px;\">\n <div style=\"background: #f8f9fa; border: 2px dashed #667eea; border-radius: 12px; padding: 30px; text-align: center; margin: 0 0 30px 0;\">\n <div style=\"font-size: 56px; font-weight: bold; letter-spacing: 12px; color: #667eea; font-family: 'Courier New', Courier, monospace; line-height: 1;\">\n ${data.code}\n </div>\n </div>\n\n <div style=\"background: #fff3cd; border-left: 4px solid #ffc107; padding: 16px 20px; margin: 0 0 30px 0; border-radius: 6px;\">\n <p style=\"margin: 0; font-size: 14px; color: #856404;\">\n <strong>⚠️ This code expires in ${data.expiryMinutes} minutes</strong>\n </p>\n </div>\n\n <div style=\"margin: 0 0 30px 0;\">\n <h3 style=\"color: #333; margin: 0 0 15px 0; font-size: 18px;\">Quick Tips:</h3>\n <ul style=\"color: #666; font-size: 14px; line-height: 1.8; margin: 0; padding-left: 20px;\">\n <li>Enter the code exactly as shown (${data.codeLength} digits)</li>\n <li>The code can only be used once</li>\n <li>You have ${data.maxAttempts} attempts to enter the correct code</li>\n <li>Request a new code if this one expires</li>\n </ul>\n </div>\n\n <div style=\"background: #e8f4ff; border-radius: 8px; padding: 20px; margin: 0 0 30px 0;\">\n <p style=\"margin: 0 0 10px 0; font-size: 14px; color: #0066cc; font-weight: 600;\">\n 🔒 Security Notice\n </p>\n <p style=\"margin: 0; font-size: 13px; color: #004080; line-height: 1.6;\">\n Never share this code with anyone. ${data.appName} will never ask you for this code via phone, email, or social media.\n </p>\n </div>\n </div>\n\n <div style=\"border-top: 1px solid #eee; padding: 30px; background: #f8f9fa;\">\n <p style=\"margin: 0 0 15px 0; font-size: 14px; color: #666; text-align: center;\">\n <strong>Didn't request this code?</strong><br>\n Someone may have entered your email by mistake. You can safely ignore this email.\n </p>\n\n <div style=\"text-align: center; color: #999; font-size: 12px; line-height: 1.6;\">\n <p style=\"margin: 5px 0;\">This email was sent to ${data.email}</p>\n ${data.ipAddress ? `<p style=\"margin: 5px 0;\">IP Address: ${data.ipAddress}</p>` : ''}\n <p style=\"margin: 5px 0;\">Time: ${data.timestamp}</p>\n </div>\n </div>\n\n </div>\n\n <div style=\"text-align: center; padding: 20px; color: #999; font-size: 12px;\">\n <p style=\"margin: 0;\">&copy; ${new Date().getFullYear()} ${data.appName}. All rights reserved.</p>\n </div>\n\n</body>\n</html>`\n}\n\nexport function renderOTPEmailText(data: OTPEmailData): string {\n return `Your Login Code for ${data.appName}\n\nYour one-time verification code is:\n\n${data.code}\n\nThis code expires in ${data.expiryMinutes} minutes.\n\nQuick Tips:\n• Enter the code exactly as shown (${data.codeLength} digits)\n• The code can only be used once\n• You have ${data.maxAttempts} attempts to enter the correct code\n• Request a new code if this one expires\n\nSecurity Notice:\nNever share this code with anyone. ${data.appName} will never ask you for this code via phone, email, or social media.\n\nDidn't request this code?\nSomeone may have entered your email by mistake. You can safely ignore this email.\n\n---\nThis email was sent to ${data.email}\n${data.ipAddress ? `IP Address: ${data.ipAddress}` : ''}\nTime: ${data.timestamp}\n\n© ${new Date().getFullYear()} ${data.appName}. All rights reserved.`\n}\n\nexport function renderOTPEmail(data: OTPEmailData): { html: string; text: string } {\n return {\n html: renderOTPEmailHTML(data),\n text: renderOTPEmailText(data)\n }\n}\n","/**\n * OTP Login Plugin\n *\n * Passwordless authentication via email one-time codes\n * Users receive a secure 6-digit code to sign in without passwords\n */\n\nimport { Hono } from 'hono'\nimport { html } from 'hono/html'\nimport { z } from 'zod'\nimport { PluginBuilder } from '../../sdk/plugin-builder'\nimport type { Plugin } from '@sonicjs-cms/core'\nimport { OTPService, type OTPSettings } from './otp-service'\nimport { renderOTPEmail } from './email-templates'\nimport { adminLayoutV2 } from '../../../templates/layouts/admin-layout-v2.template'\n\n// Validation schemas\nconst otpRequestSchema = z.object({\n email: z.string().email('Valid email is required')\n})\n\nconst otpVerifySchema = z.object({\n email: z.string().email('Valid email is required'),\n code: z.string().min(4).max(8)\n})\n\n// Default settings\nconst DEFAULT_SETTINGS: OTPSettings = {\n codeLength: 6,\n codeExpiryMinutes: 10,\n maxAttempts: 3,\n rateLimitPerHour: 5,\n allowNewUserRegistration: false,\n appName: 'SonicJS'\n}\n\nexport function createOTPLoginPlugin(): Plugin {\n const builder = PluginBuilder.create({\n name: 'otp-login',\n version: '1.0.0-beta.1',\n description: 'Passwordless authentication via email one-time codes'\n })\n\n builder.metadata({\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n license: 'MIT',\n compatibility: '^2.0.0'\n })\n\n // ==================== API Routes ====================\n\n const otpAPI = new Hono()\n\n // POST /auth/otp/request - Request OTP code\n otpAPI.post('/request', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB\n const otpService = new OTPService(db)\n const settings = { ...DEFAULT_SETTINGS } // TODO: Load from plugin settings\n\n // Check rate limiting\n const canRequest = await otpService.checkRateLimit(normalizedEmail, settings)\n if (!canRequest) {\n return c.json({\n error: 'Too many requests. Please try again in an hour.'\n }, 429)\n }\n\n // Check if user exists\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n if (!user && !settings.allowNewUserRegistration) {\n // Don't reveal if user exists or not (security)\n return c.json({\n message: 'If an account exists for this email, you will receive a verification code shortly.',\n expiresIn: settings.codeExpiryMinutes * 60\n })\n }\n\n if (user && !user.is_active) {\n return c.json({\n error: 'This account has been deactivated.'\n }, 403)\n }\n\n // Get IP and user agent\n const ipAddress = c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for') || 'unknown'\n const userAgent = c.req.header('user-agent') || 'unknown'\n\n // Create OTP code\n const otpCode = await otpService.createOTPCode(\n normalizedEmail,\n settings,\n ipAddress,\n userAgent\n )\n\n // Send email via Email plugin\n try {\n const isDevMode = c.env.ENVIRONMENT === 'development'\n\n if (isDevMode) {\n console.log(`[DEV] OTP Code for ${normalizedEmail}: ${otpCode.code}`)\n }\n\n // Prepare email content\n const emailContent = renderOTPEmail({\n code: otpCode.code,\n expiryMinutes: settings.codeExpiryMinutes,\n codeLength: settings.codeLength,\n maxAttempts: settings.maxAttempts,\n email: normalizedEmail,\n ipAddress,\n timestamp: new Date().toISOString(),\n appName: settings.appName\n })\n\n // Load email plugin settings from database\n const emailPlugin = await db.prepare(`\n SELECT settings FROM plugins WHERE id = 'email' AND status = 'active'\n `).first() as { settings: string | null } | null\n\n if (emailPlugin?.settings) {\n const emailSettings = JSON.parse(emailPlugin.settings)\n\n if (emailSettings.apiKey && emailSettings.fromEmail && emailSettings.fromName) {\n // Send email via Resend API\n const emailResponse = await fetch('https://api.resend.com/emails', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${emailSettings.apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n from: `${emailSettings.fromName} <${emailSettings.fromEmail}>`,\n to: [normalizedEmail],\n subject: `Your login code for ${settings.appName}`,\n html: emailContent.html,\n text: emailContent.text,\n reply_to: emailSettings.replyTo || emailSettings.fromEmail\n })\n })\n\n if (!emailResponse.ok) {\n const errorData = await emailResponse.json() as { message?: string }\n console.error('Failed to send OTP email via Resend:', errorData)\n // Don't expose error to user for security - just log it\n }\n } else {\n console.warn('Email plugin is not fully configured (missing apiKey, fromEmail, or fromName)')\n }\n } else {\n console.warn('Email plugin is not active or has no settings configured')\n }\n\n const response: any = {\n message: 'If an account exists for this email, you will receive a verification code shortly.',\n expiresIn: settings.codeExpiryMinutes * 60\n }\n\n // In development, include the code\n if (isDevMode) {\n response.dev_code = otpCode.code\n }\n\n return c.json(response)\n } catch (emailError) {\n console.error('Error sending OTP email:', emailError)\n return c.json({\n error: 'Failed to send verification code. Please try again.'\n }, 500)\n }\n } catch (error) {\n console.error('OTP request error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // POST /auth/otp/verify - Verify OTP code\n otpAPI.post('/verify', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpVerifySchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email, code } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB\n const otpService = new OTPService(db)\n const settings = { ...DEFAULT_SETTINGS } // TODO: Load from plugin settings\n\n // Verify the code\n const verification = await otpService.verifyCode(normalizedEmail, code, settings)\n\n if (!verification.valid) {\n // Increment attempts on failure\n await otpService.incrementAttempts(normalizedEmail, code)\n\n return c.json({\n error: verification.error || 'Invalid code',\n attemptsRemaining: verification.attemptsRemaining\n }, 401)\n }\n\n // Code is valid - get user\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n if (!user) {\n return c.json({\n error: 'User not found'\n }, 404)\n }\n\n if (!user.is_active) {\n return c.json({\n error: 'Account is deactivated'\n }, 403)\n }\n\n // TODO: Generate JWT token\n // For now, return success with user data\n return c.json({\n success: true,\n user: {\n id: user.id,\n email: user.email,\n role: user.role\n },\n message: 'Authentication successful'\n })\n } catch (error) {\n console.error('OTP verify error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // POST /auth/otp/resend - Resend OTP code\n otpAPI.post('/resend', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = otpRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n // Reuse the request endpoint logic\n return otpAPI.fetch(\n new Request(c.req.url.replace('/resend', '/request'), {\n method: 'POST',\n headers: c.req.raw.headers,\n body: JSON.stringify({ email: validation.data.email })\n }),\n c.env\n )\n } catch (error) {\n console.error('OTP resend error:', error)\n return c.json({\n error: 'An error occurred. Please try again.'\n }, 500)\n }\n })\n\n // Register API routes\n builder.addRoute('/auth/otp', otpAPI, {\n description: 'OTP authentication endpoints',\n requiresAuth: false,\n priority: 100\n })\n\n // ==================== Admin UI Routes ====================\n\n const adminRoutes = new Hono()\n\n // Settings page\n adminRoutes.get('/settings', async (c: any) => {\n const user = c.get('user') as { email?: string; role?: string; name?: string } | undefined\n\n const contentHTML = await html`\n <div class=\"p-8\">\n <div class=\"mb-8\">\n <h1 class=\"text-3xl font-bold mb-2\">OTP Login Settings</h1>\n <p class=\"text-zinc-600 dark:text-zinc-400\">Configure passwordless authentication via email codes</p>\n </div>\n\n <div class=\"max-w-3xl\">\n <div class=\"backdrop-blur-md bg-black/20 border border-white/10 shadow-xl rounded-xl p-6 mb-6\">\n <h2 class=\"text-xl font-semibold mb-4\">Code Settings</h2>\n\n <form id=\"otpSettingsForm\" class=\"space-y-6\">\n <div>\n <label for=\"codeLength\" class=\"block text-sm font-medium mb-2\">\n Code Length\n </label>\n <input\n type=\"number\"\n id=\"codeLength\"\n name=\"codeLength\"\n min=\"4\"\n max=\"8\"\n value=\"6\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Number of digits in OTP code (4-8)</p>\n </div>\n\n <div>\n <label for=\"codeExpiryMinutes\" class=\"block text-sm font-medium mb-2\">\n Code Expiry (minutes)\n </label>\n <input\n type=\"number\"\n id=\"codeExpiryMinutes\"\n name=\"codeExpiryMinutes\"\n min=\"5\"\n max=\"60\"\n value=\"10\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">How long codes remain valid (5-60 minutes)</p>\n </div>\n\n <div>\n <label for=\"maxAttempts\" class=\"block text-sm font-medium mb-2\">\n Maximum Attempts\n </label>\n <input\n type=\"number\"\n id=\"maxAttempts\"\n name=\"maxAttempts\"\n min=\"3\"\n max=\"10\"\n value=\"3\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Max verification attempts before invalidation</p>\n </div>\n\n <div>\n <label for=\"rateLimitPerHour\" class=\"block text-sm font-medium mb-2\">\n Rate Limit (per hour)\n </label>\n <input\n type=\"number\"\n id=\"rateLimitPerHour\"\n name=\"rateLimitPerHour\"\n min=\"3\"\n max=\"20\"\n value=\"5\"\n class=\"w-full px-4 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none\"\n />\n <p class=\"text-xs text-zinc-500 mt-1\">Max code requests per email per hour</p>\n </div>\n\n <div class=\"flex items-center\">\n <input\n type=\"checkbox\"\n id=\"allowNewUserRegistration\"\n name=\"allowNewUserRegistration\"\n class=\"w-4 h-4 rounded border-white/10\"\n />\n <label for=\"allowNewUserRegistration\" class=\"ml-2 text-sm\">\n Allow new user registration via OTP\n </label>\n </div>\n\n <div class=\"flex gap-3 pt-4\">\n <button\n type=\"submit\"\n class=\"px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-purple-700 transition-all\"\n >\n Save Settings\n </button>\n <button\n type=\"button\"\n id=\"testOTPBtn\"\n class=\"px-6 py-2 bg-white/10 hover:bg-white/20 text-white rounded-lg font-medium transition-all\"\n >\n Send Test Code\n </button>\n </div>\n </form>\n </div>\n\n <div id=\"statusMessage\" class=\"hidden backdrop-blur-md bg-black/20 border border-white/10 rounded-xl p-4 mb-6\"></div>\n\n <div class=\"backdrop-blur-md bg-blue-500/10 border border-blue-500/20 rounded-xl p-6\">\n <h3 class=\"font-semibold text-blue-400 mb-3\">\n 🔢 Features\n </h3>\n <ul class=\"text-sm text-blue-200 space-y-2\">\n <li>✓ Passwordless authentication</li>\n <li>✓ Secure random code generation</li>\n <li>✓ Rate limiting protection</li>\n <li>✓ Brute force prevention</li>\n <li>✓ Mobile-friendly UX</li>\n </ul>\n </div>\n </div>\n </div>\n\n <script>\n document.getElementById('otpSettingsForm').addEventListener('submit', async (e) => {\n e.preventDefault()\n const statusEl = document.getElementById('statusMessage')\n statusEl.className = 'backdrop-blur-md bg-green-500/20 border border-green-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '✅ Settings saved successfully!'\n statusEl.classList.remove('hidden')\n setTimeout(() => statusEl.classList.add('hidden'), 3000)\n })\n\n document.getElementById('testOTPBtn').addEventListener('click', async () => {\n const email = prompt('Enter email address for test:')\n if (!email) return\n\n const statusEl = document.getElementById('statusMessage')\n statusEl.className = 'backdrop-blur-md bg-blue-500/20 border border-blue-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '📧 Sending test code...'\n statusEl.classList.remove('hidden')\n\n try {\n const response = await fetch('/auth/otp/request', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email })\n })\n\n const data = await response.json()\n\n if (response.ok) {\n statusEl.className = 'backdrop-blur-md bg-green-500/20 border border-green-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '✅ Test code sent!' + (data.dev_code ? \\` Code: <strong>\\${data.dev_code}</strong>\\` : '')\n } else {\n throw new Error(data.error || 'Failed')\n }\n } catch (error) {\n statusEl.className = 'backdrop-blur-md bg-red-500/20 border border-red-500/30 rounded-xl p-4 mb-6'\n statusEl.innerHTML = '❌ Failed to send test code'\n }\n })\n </script>\n `\n\n const templateUser = user ? {\n name: user.name ?? user.email ?? 'Admin',\n email: user.email ?? 'admin@sonicjs.com',\n role: user.role ?? 'admin'\n } : undefined\n\n return c.html(\n adminLayoutV2({\n title: 'OTP Login Settings',\n content: contentHTML,\n user: templateUser,\n currentPath: '/admin/plugins/otp-login/settings'\n })\n )\n })\n\n // Register admin routes\n builder.addRoute('/admin/plugins/otp-login', adminRoutes, {\n description: 'OTP login admin interface',\n requiresAuth: true,\n priority: 85\n })\n\n // Add menu item\n builder.addMenuItem('OTP Login', '/admin/plugins/otp-login/settings', {\n icon: 'key',\n order: 85,\n permissions: ['otp:manage']\n })\n\n // Lifecycle hooks\n builder.lifecycle({\n activate: async () => {\n console.info('✅ OTP Login plugin activated')\n },\n deactivate: async () => {\n console.info('❌ OTP Login plugin deactivated')\n }\n })\n\n return builder.build() as Plugin\n}\n\nexport const otpLoginPlugin = createOTPLoginPlugin()\n","/**\n * Magic Link Authentication Plugin\n *\n * Provides passwordless authentication via email magic links\n * Users receive a secure one-time link to sign in without passwords\n */\n\nimport { Hono } from 'hono'\nimport { z } from 'zod'\nimport type { Plugin, PluginContext } from '../../types'\nimport type { D1Database } from '@cloudflare/workers-types'\nimport { AuthManager } from '../../../middleware/auth'\n\nconst magicLinkRequestSchema = z.object({\n email: z.string().email('Valid email is required')\n})\n\nexport function createMagicLinkAuthPlugin(): Plugin {\n const magicLinkRoutes = new Hono()\n\n // Request a magic link\n magicLinkRoutes.post('/request', async (c: any) => {\n try {\n const body = await c.req.json()\n const validation = magicLinkRequestSchema.safeParse(body)\n\n if (!validation.success) {\n return c.json({\n error: 'Validation failed',\n details: validation.error.issues\n }, 400)\n }\n\n const { email } = validation.data\n const normalizedEmail = email.toLowerCase()\n const db = c.env.DB as D1Database\n\n // Check rate limiting\n const oneHourAgo = Date.now() - (60 * 60 * 1000)\n const recentLinks = await db.prepare(`\n SELECT COUNT(*) as count\n FROM magic_links\n WHERE user_email = ? AND created_at > ?\n `).bind(normalizedEmail, oneHourAgo).first() as any\n\n const rateLimitPerHour = 5 // TODO: Get from plugin settings\n if (recentLinks && recentLinks.count >= rateLimitPerHour) {\n return c.json({\n error: 'Too many requests. Please try again later.'\n }, 429)\n }\n\n // Check if user exists\n const user = await db.prepare(`\n SELECT id, email, role, is_active\n FROM users\n WHERE email = ?\n `).bind(normalizedEmail).first() as any\n\n const allowNewUsers = false // TODO: Get from plugin settings\n\n if (!user && !allowNewUsers) {\n // Don't reveal if user exists or not for security\n return c.json({\n message: 'If an account exists for this email, you will receive a magic link shortly.'\n })\n }\n\n if (user && !user.is_active) {\n return c.json({\n error: 'This account has been deactivated.'\n }, 403)\n }\n\n // Generate secure token\n const token = crypto.randomUUID() + '-' + crypto.randomUUID()\n const tokenId = crypto.randomUUID()\n const linkExpiryMinutes = 15 // TODO: Get from plugin settings\n const expiresAt = Date.now() + (linkExpiryMinutes * 60 * 1000)\n\n // Store magic link\n await db.prepare(`\n INSERT INTO magic_links (\n id, user_email, token, expires_at, used, created_at, ip_address, user_agent\n ) VALUES (?, ?, ?, ?, 0, ?, ?, ?)\n `).bind(\n tokenId,\n normalizedEmail,\n token,\n expiresAt,\n Date.now(),\n c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for') || 'unknown',\n c.req.header('user-agent') || 'unknown'\n ).run()\n\n // Generate magic link URL\n const baseUrl = new URL(c.req.url).origin\n const magicLink = `${baseUrl}/auth/magic-link/verify?token=${token}`\n\n // Send email via email plugin\n try {\n const emailPlugin = c.env.plugins?.get('email')\n if (emailPlugin && emailPlugin.sendEmail) {\n await emailPlugin.sendEmail({\n to: normalizedEmail,\n subject: 'Your Magic Link to Sign In',\n html: renderMagicLinkEmail(magicLink, linkExpiryMinutes)\n })\n } else {\n console.error('Email plugin not available')\n // In production, this should fail. For now, log the link for testing\n console.log(`Magic link for ${normalizedEmail}: ${magicLink}`)\n }\n } catch (error) {\n console.error('Failed to send magic link email:', error)\n return c.json({\n error: 'Failed to send email. Please try again later.'\n }, 500)\n }\n\n return c.json({\n message: 'If an account exists for this email, you will receive a magic link shortly.',\n // For development only - remove in production\n ...(c.env.ENVIRONMENT === 'development' && { dev_link: magicLink })\n })\n } catch (error) {\n console.error('Magic link request error:', error)\n return c.json({ error: 'Failed to process request' }, 500)\n }\n })\n\n // Verify magic link and sign in\n magicLinkRoutes.get('/verify', async (c: any) => {\n try {\n const token = c.req.query('token')\n\n if (!token) {\n return c.redirect('/auth/login?error=Invalid magic link')\n }\n\n const db = c.env.DB as D1Database\n\n // Find magic link\n const magicLink = await db.prepare(`\n SELECT * FROM magic_links\n WHERE token = ? AND used = 0\n `).bind(token).first() as any\n\n if (!magicLink) {\n return c.redirect('/auth/login?error=Invalid or expired magic link')\n }\n\n // Check expiration\n if (magicLink.expires_at < Date.now()) {\n return c.redirect('/auth/login?error=This magic link has expired')\n }\n\n // Get or create user\n let user = await db.prepare(`\n SELECT * FROM users WHERE email = ? AND is_active = 1\n `).bind(magicLink.user_email).first() as any\n\n const allowNewUsers = false // TODO: Get from plugin settings\n\n if (!user && allowNewUsers) {\n // Create new user\n const userId = crypto.randomUUID()\n const username = magicLink.user_email.split('@')[0]\n const now = Date.now()\n\n await db.prepare(`\n INSERT INTO users (\n id, email, username, first_name, last_name,\n password_hash, role, is_active, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, NULL, 'viewer', 1, ?, ?)\n `).bind(\n userId,\n magicLink.user_email,\n username,\n username,\n '',\n now,\n now\n ).run()\n\n user = {\n id: userId,\n email: magicLink.user_email,\n username,\n role: 'viewer'\n }\n } else if (!user) {\n return c.redirect('/auth/login?error=No account found for this email')\n }\n\n // Mark magic link as used\n await db.prepare(`\n UPDATE magic_links\n SET used = 1, used_at = ?\n WHERE id = ?\n `).bind(Date.now(), magicLink.id).run()\n\n // Generate JWT token\n const jwtToken = await AuthManager.generateToken(\n user.id,\n user.email,\n user.role\n )\n\n // Set auth cookie\n AuthManager.setAuthCookie(c, jwtToken)\n\n // Update last login\n await db.prepare(`\n UPDATE users SET last_login_at = ? WHERE id = ?\n `).bind(Date.now(), user.id).run()\n\n // Redirect to admin dashboard\n return c.redirect('/admin/dashboard?message=Successfully signed in')\n } catch (error) {\n console.error('Magic link verification error:', error)\n return c.redirect('/auth/login?error=Authentication failed')\n }\n })\n\n return {\n name: 'magic-link-auth',\n version: '1.0.0',\n description: 'Passwordless authentication via email magic links',\n author: {\n name: 'SonicJS Team',\n email: 'team@sonicjs.com'\n },\n dependencies: ['email'],\n\n routes: [{\n path: '/auth/magic-link',\n handler: magicLinkRoutes,\n description: 'Magic link authentication endpoints',\n requiresAuth: false\n }],\n\n async install(context: PluginContext) {\n console.log('Installing magic-link-auth plugin...')\n // Migration is handled by plugin system\n },\n\n async activate(context: PluginContext) {\n console.log('Magic link authentication activated')\n console.log('Users can now sign in via /auth/magic-link/request')\n },\n\n async deactivate(context: PluginContext) {\n console.log('Magic link authentication deactivated')\n },\n\n async uninstall(context: PluginContext) {\n console.log('Uninstalling magic-link-auth plugin...')\n // Optionally clean up magic_links table\n // await context.db.prepare('DROP TABLE IF EXISTS magic_links').run()\n }\n }\n}\n\n/**\n * Render magic link email template\n */\nfunction renderMagicLinkEmail(magicLink: string, expiryMinutes: number): string {\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Your Magic Link</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n line-height: 1.6;\n color: #333;\n max-width: 600px;\n margin: 0 auto;\n padding: 20px;\n }\n .container {\n background: #ffffff;\n border-radius: 8px;\n padding: 40px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .header {\n text-align: center;\n margin-bottom: 30px;\n }\n .header h1 {\n color: #0ea5e9;\n margin: 0;\n font-size: 24px;\n }\n .content {\n margin-bottom: 30px;\n }\n .button {\n display: inline-block;\n padding: 14px 32px;\n background: linear-gradient(135deg, #0ea5e9 0%, #06b6d4 100%);\n color: #ffffff !important;\n text-decoration: none;\n border-radius: 6px;\n font-weight: 600;\n text-align: center;\n margin: 20px 0;\n }\n .button:hover {\n opacity: 0.9;\n }\n .expiry {\n color: #ef4444;\n font-size: 14px;\n margin-top: 20px;\n }\n .footer {\n margin-top: 40px;\n padding-top: 20px;\n border-top: 1px solid #e5e7eb;\n font-size: 12px;\n color: #6b7280;\n text-align: center;\n }\n .security-note {\n background: #fef3c7;\n border-left: 4px solid #f59e0b;\n padding: 12px 16px;\n margin-top: 20px;\n border-radius: 4px;\n font-size: 14px;\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>🔗 Your Magic Link</h1>\n </div>\n\n <div class=\"content\">\n <p>Hello!</p>\n <p>You requested a magic link to sign in to your account. Click the button below to continue:</p>\n\n <div style=\"text-align: center;\">\n <a href=\"${magicLink}\" class=\"button\">Sign In</a>\n </div>\n\n <p class=\"expiry\">⏰ This link expires in ${expiryMinutes} minutes</p>\n\n <div class=\"security-note\">\n <strong>Security Notice:</strong> If you didn't request this link, you can safely ignore this email.\n Someone may have entered your email address by mistake.\n </div>\n </div>\n\n <div class=\"footer\">\n <p>This is an automated email from SonicJS.</p>\n <p>For security, this link can only be used once.</p>\n </div>\n </div>\n </body>\n </html>\n `\n}\n\nexport default createMagicLinkAuthPlugin()\n","/**\n * Main Application Factory\n *\n * Creates a configured SonicJS application with all core functionality\n */\n\nimport { Hono } from 'hono'\nimport type { Context } from 'hono'\nimport type { D1Database, KVNamespace, R2Bucket } from '@cloudflare/workers-types'\nimport {\n apiRoutes,\n apiMediaRoutes,\n apiSystemRoutes,\n adminApiRoutes,\n authRoutes,\n testCleanupRoutes,\n adminContentRoutes,\n adminUsersRoutes,\n adminMediaRoutes,\n adminPluginRoutes,\n adminLogsRoutes,\n adminDashboardRoutes,\n adminCollectionsRoutes,\n adminSettingsRoutes\n} from './routes'\nimport { getCoreVersion } from './utils/version'\nimport { bootstrapMiddleware } from './middleware/bootstrap'\nimport { metricsMiddleware } from './middleware/metrics'\nimport { createDatabaseToolsAdminRoutes } from './plugins/core-plugins/database-tools-plugin/admin-routes'\nimport { emailPlugin } from './plugins/core-plugins/email-plugin'\nimport { otpLoginPlugin } from './plugins/core-plugins/otp-login-plugin'\nimport { createMagicLinkAuthPlugin } from './plugins/available/magic-link-auth'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\nexport interface Bindings {\n DB: D1Database\n CACHE_KV: KVNamespace\n MEDIA_BUCKET: R2Bucket\n ASSETS: Fetcher\n EMAIL_QUEUE?: Queue\n SENDGRID_API_KEY?: string\n DEFAULT_FROM_EMAIL?: string\n IMAGES_ACCOUNT_ID?: string\n IMAGES_API_TOKEN?: string\n ENVIRONMENT?: string\n BUCKET_NAME?: string\n}\n\nexport interface Variables {\n user?: {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n }\n requestId?: string\n startTime?: number\n appVersion?: string\n}\n\nexport interface SonicJSConfig {\n // Collections configuration\n collections?: {\n directory?: string\n autoSync?: boolean\n }\n\n // Plugins configuration\n plugins?: {\n directory?: string\n autoLoad?: boolean\n disableAll?: boolean // Disable all plugins including core plugins\n }\n\n // Custom routes\n routes?: Array<{\n path: string\n handler: Hono\n }>\n\n // Custom middleware\n middleware?: {\n beforeAuth?: Array<(c: Context, next: () => Promise<void>) => Promise<void>>\n afterAuth?: Array<(c: Context, next: () => Promise<void>) => Promise<void>>\n }\n\n // App metadata\n version?: string\n name?: string\n}\n\nexport type SonicJSApp = Hono<{ Bindings: Bindings; Variables: Variables }>\n\n// ============================================================================\n// Application Factory\n// ============================================================================\n\n/**\n * Create a SonicJS application with core functionality\n *\n * @param config - Application configuration\n * @returns Configured Hono application\n *\n * @example\n * ```typescript\n * import { createSonicJSApp } from '@sonicjs/core'\n *\n * const app = createSonicJSApp({\n * collections: {\n * directory: './src/collections',\n * autoSync: true\n * },\n * plugins: {\n * directory: './src/plugins',\n * autoLoad: true\n * }\n * })\n *\n * export default app\n * ```\n */\nexport function createSonicJSApp(config: SonicJSConfig = {}): SonicJSApp {\n const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()\n\n // Set app metadata\n const appVersion = config.version || getCoreVersion()\n const appName = config.name || 'SonicJS AI'\n\n // App version middleware\n app.use('*', async (c, next) => {\n c.set('appVersion', appVersion)\n await next()\n })\n\n // Metrics middleware - track all requests for real-time analytics\n app.use('*', metricsMiddleware())\n\n // Bootstrap middleware - runs migrations, syncs collections, and initializes plugins\n app.use('*', bootstrapMiddleware(config))\n\n // Custom middleware - before auth\n if (config.middleware?.beforeAuth) {\n for (const middleware of config.middleware.beforeAuth) {\n app.use('*', middleware)\n }\n }\n\n // Logging middleware\n app.use('*', async (_c, next) => {\n // Logging logic here\n await next()\n })\n\n // Security middleware\n app.use('*', async (_c, next) => {\n // Security headers, CORS, etc.\n await next()\n })\n\n // Custom middleware - after auth\n if (config.middleware?.afterAuth) {\n for (const middleware of config.middleware.afterAuth) {\n app.use('*', middleware)\n }\n }\n\n // Core routes\n // Routes are being imported incrementally from routes/*\n // Each route is tested and migrated one-by-one\n app.route('/api', apiRoutes)\n app.route('/api/media', apiMediaRoutes)\n app.route('/api/system', apiSystemRoutes)\n app.route('/admin/api', adminApiRoutes)\n app.route('/admin/dashboard', adminDashboardRoutes)\n app.route('/admin/collections', adminCollectionsRoutes)\n app.route('/admin/settings', adminSettingsRoutes)\n app.route('/admin/database-tools', createDatabaseToolsAdminRoutes())\n app.route('/admin/content', adminContentRoutes)\n app.route('/admin/media', adminMediaRoutes)\n app.route('/admin/plugins', adminPluginRoutes)\n app.route('/admin/logs', adminLogsRoutes)\n app.route('/admin', adminUsersRoutes)\n app.route('/auth', authRoutes)\n\n // Test cleanup routes (only for development/test environments)\n app.route('/', testCleanupRoutes)\n\n // Plugin routes - Email\n if (emailPlugin.routes && emailPlugin.routes.length > 0) {\n for (const route of emailPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Plugin routes - OTP Login (passwordless authentication via email codes)\n if (otpLoginPlugin.routes && otpLoginPlugin.routes.length > 0) {\n for (const route of otpLoginPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Plugin routes - Magic Link Auth (passwordless authentication via email links)\n const magicLinkPlugin = createMagicLinkAuthPlugin()\n if (magicLinkPlugin.routes && magicLinkPlugin.routes.length > 0) {\n for (const route of magicLinkPlugin.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Serve files from R2 storage (public file access)\n app.get('/files/*', async (c) => {\n try {\n // Extract the path from the URL pathname (everything after /files/)\n const url = new URL(c.req.url)\n const pathname = url.pathname\n\n // Remove the /files/ prefix to get the R2 object key\n const objectKey = pathname.replace(/^\\/files\\//, '')\n\n if (!objectKey) {\n return c.notFound()\n }\n\n // Get file from R2\n const object = await c.env.MEDIA_BUCKET.get(objectKey)\n\n if (!object) {\n return c.notFound()\n }\n\n // Set appropriate headers\n const headers = new Headers()\n object.httpMetadata?.contentType && headers.set('Content-Type', object.httpMetadata.contentType)\n object.httpMetadata?.contentDisposition && headers.set('Content-Disposition', object.httpMetadata.contentDisposition)\n headers.set('Cache-Control', 'public, max-age=31536000') // 1 year cache\n headers.set('Access-Control-Allow-Origin', '*') // Allow CORS for media files\n headers.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')\n headers.set('Access-Control-Allow-Headers', 'Content-Type')\n\n return new Response(object.body as any, {\n headers\n })\n } catch (error) {\n console.error('Error serving file:', error)\n return c.notFound()\n }\n })\n\n // Custom routes - User-defined routes\n if (config.routes) {\n for (const route of config.routes) {\n app.route(route.path, route.handler)\n }\n }\n\n // Root redirect to login\n app.get('/', (c) => {\n return c.redirect('/auth/login')\n })\n\n // Health check\n app.get('/health', (c) => {\n return c.json({\n name: appName,\n version: appVersion,\n status: 'running',\n timestamp: new Date().toISOString()\n })\n })\n\n // 404 handler\n app.notFound((c) => {\n return c.json({ error: 'Not Found', status: 404 }, 404)\n })\n\n // Error handler\n app.onError((err, c) => {\n console.error(err)\n return c.json({ error: 'Internal Server Error', status: 500 }, 500)\n })\n\n return app\n}\n\n/**\n * Setup core middleware (backward compatibility)\n *\n * @param _app - Hono application\n * @deprecated Use createSonicJSApp() instead\n */\nexport function setupCoreMiddleware(_app: SonicJSApp): void {\n console.warn('setupCoreMiddleware is deprecated. Use createSonicJSApp() instead.')\n // Backward compatibility implementation\n}\n\n/**\n * Setup core routes (backward compatibility)\n *\n * @param _app - Hono application\n * @deprecated Use createSonicJSApp() instead\n */\nexport function setupCoreRoutes(_app: SonicJSApp): void {\n console.warn('setupCoreRoutes is deprecated. Use createSonicJSApp() instead.')\n // Backward compatibility implementation\n}\n","import { drizzle } from 'drizzle-orm/d1';\nimport * as schema from './schema';\n\nexport function createDb(d1: D1Database) {\n return drizzle(d1, { schema });\n}\n\nexport * from './schema';","/**\n * @sonicjs/core - Main Entry Point\n *\n * Core framework for SonicJS headless CMS\n * Built for Cloudflare's edge platform with TypeScript\n *\n * Phase 2 Migration Status:\n * - Week 1: Types, Utils, Database (COMPLETED ✓)\n * - Week 2: Services, Middleware, Plugins (COMPLETED ✓)\n * - Week 3: Routes, Templates (COMPLETED ✓)\n * - Week 4: Integration & Testing (COMPLETED ✓)\n *\n * Test Coverage:\n * - Utilities: 48 tests (sanitize, query-filter, metrics)\n * - Middleware: 51 tests (auth, logging, security, performance)\n * - Total: 99 tests passing\n */\n\n// ============================================================================\n// Main Application API (Phase 2 Week 1)\n// ============================================================================\n\nexport { createSonicJSApp, setupCoreMiddleware, setupCoreRoutes } from './app'\nexport type { SonicJSConfig, SonicJSApp, Bindings, Variables } from './app'\n\n// ============================================================================\n// Placeholders - To be populated in Phase 2\n// ============================================================================\n\n// Services - Week 2 (COMPLETED)\nexport {\n // Collection Management\n loadCollectionConfigs,\n loadCollectionConfig,\n getAvailableCollectionNames,\n validateCollectionConfig,\n registerCollections,\n syncCollections,\n syncCollection,\n isCollectionManaged,\n getManagedCollections,\n cleanupRemovedCollections,\n fullCollectionSync,\n // Database Migrations\n MigrationService,\n // Logging\n Logger,\n getLogger,\n initLogger,\n // Plugin Services - Class implementations\n PluginService as PluginServiceClass,\n PluginBootstrapService,\n} from './services'\n\nexport type { Migration, MigrationStatus, LogLevel, LogCategory, LogEntry, LogFilter, CorePlugin } from './services'\n\n// Middleware - Week 2 (COMPLETED)\nexport {\n // Authentication\n AuthManager,\n requireAuth,\n requireRole,\n optionalAuth,\n // Logging\n loggingMiddleware,\n detailedLoggingMiddleware,\n securityLoggingMiddleware,\n performanceLoggingMiddleware,\n // Performance\n cacheHeaders,\n compressionMiddleware,\n securityHeaders,\n // Permissions\n PermissionManager,\n requirePermission,\n requireAnyPermission,\n logActivity,\n // Plugin middleware\n requireActivePlugin,\n requireActivePlugins,\n getActivePlugins,\n isPluginActive,\n // Bootstrap\n bootstrapMiddleware,\n} from './middleware'\n\nexport type { Permission, UserPermissions } from './middleware'\n\n// Plugins - Week 2 (COMPLETED)\nexport {\n // Hook System - Class implementations\n HookSystemImpl,\n ScopedHookSystem as ScopedHookSystemClass,\n HookUtils,\n // Plugin Registry\n PluginRegistryImpl,\n // Plugin Manager - Class implementation\n PluginManager as PluginManagerClass,\n // Plugin Validator - Class implementation\n PluginValidator as PluginValidatorClass,\n} from './plugins'\n\n// Routes - Week 3 (COMPLETED)\nexport {\n ROUTES_INFO,\n apiRoutes,\n apiContentCrudRoutes,\n apiMediaRoutes,\n apiSystemRoutes,\n adminApiRoutes,\n authRoutes,\n adminContentRoutes,\n adminUsersRoutes,\n adminMediaRoutes,\n adminLogsRoutes,\n adminPluginRoutes,\n adminDesignRoutes,\n adminCheckboxRoutes,\n adminTestimonialsRoutes,\n adminCodeExamplesRoutes,\n adminDashboardRoutes,\n adminCollectionsRoutes,\n adminSettingsRoutes,\n} from './routes'\n\n// Templates - Week 3 (COMPLETED)\nexport {\n // Form templates\n renderForm,\n renderFormField,\n // Table templates\n renderTable,\n // Pagination templates\n renderPagination,\n // Alert templates\n renderAlert,\n // Confirmation dialog templates\n renderConfirmationDialog,\n getConfirmationDialogScript,\n // Filter bar templates\n renderFilterBar,\n} from './templates'\n\nexport type {\n FormField,\n FormData,\n TableColumn,\n TableData,\n PaginationData,\n AlertData,\n ConfirmationDialogOptions,\n FilterBarData,\n Filter,\n FilterOption,\n} from './templates'\n\n// Types - Week 1 (COMPLETED)\nexport type {\n // Collection types\n FieldType,\n FieldConfig,\n CollectionSchema,\n CollectionConfig,\n CollectionConfigModule,\n CollectionSyncResult,\n // Plugin types\n Plugin,\n PluginContext,\n PluginConfig,\n PluginRoutes,\n PluginMiddleware,\n PluginModel,\n PluginService,\n PluginAdminPage,\n PluginComponent,\n PluginMenuItem,\n PluginHook,\n HookHandler,\n HookContext,\n HookSystem,\n ScopedHookSystem,\n PluginRegistry,\n PluginManager,\n PluginStatus,\n AuthService,\n ContentService,\n MediaService,\n PluginLogger,\n PluginBuilderOptions,\n PluginValidator,\n PluginValidationResult,\n HookName,\n // Plugin manifest\n PluginManifest,\n} from './types'\n\nexport { HOOKS } from './types'\n\n// Utils - Week 1 (COMPLETED)\nexport {\n // Sanitization\n escapeHtml,\n sanitizeInput,\n sanitizeObject,\n // Template rendering\n TemplateRenderer,\n templateRenderer,\n renderTemplate,\n // Query filtering\n QueryFilterBuilder,\n buildQuery,\n // Metrics\n metricsTracker,\n // Version\n SONICJS_VERSION,\n getCoreVersion,\n} from './utils'\n\nexport type {\n FilterOperator,\n FilterCondition,\n FilterGroup,\n QueryFilter,\n QueryResult,\n} from './utils'\n\n// Database - Week 1 (COMPLETED)\nexport {\n createDb,\n // Schema exports\n users,\n collections,\n content,\n contentVersions,\n media,\n apiTokens,\n workflowHistory,\n plugins,\n pluginHooks,\n pluginRoutes,\n pluginAssets,\n pluginActivityLog,\n systemLogs,\n logConfig,\n // Zod validation schemas\n insertUserSchema,\n selectUserSchema,\n insertCollectionSchema,\n selectCollectionSchema,\n insertContentSchema,\n selectContentSchema,\n insertMediaSchema,\n selectMediaSchema,\n insertWorkflowHistorySchema,\n selectWorkflowHistorySchema,\n insertPluginSchema,\n selectPluginSchema,\n insertPluginHookSchema,\n selectPluginHookSchema,\n insertPluginRouteSchema,\n selectPluginRouteSchema,\n insertPluginAssetSchema,\n selectPluginAssetSchema,\n insertPluginActivityLogSchema,\n selectPluginActivityLogSchema,\n insertSystemLogSchema,\n selectSystemLogSchema,\n insertLogConfigSchema,\n selectLogConfigSchema,\n} from './db'\n\nexport type {\n User,\n NewUser,\n Collection,\n NewCollection,\n Content,\n NewContent,\n Media,\n NewMedia,\n WorkflowHistory,\n NewWorkflowHistory,\n Plugin as DbPlugin,\n NewPlugin,\n PluginHook as DbPluginHook,\n NewPluginHook,\n PluginRoute,\n NewPluginRoute,\n PluginAsset,\n NewPluginAsset,\n PluginActivityLog,\n NewPluginActivityLog,\n SystemLog,\n NewSystemLog,\n LogConfig,\n NewLogConfig,\n} from './db'\n\n// Plugins - Week 2\n// export { PluginBuilder, HookSystem } from './plugins/sdk'\n\n// ============================================================================\n// Version\n// ============================================================================\n\n// Import version from package.json\nimport packageJson from '../package.json'\nexport const VERSION = packageJson.version\n\n// ============================================================================\n// Phase 2 Migration Notes\n// ============================================================================\n\n/**\n * This is a work-in-progress package being extracted from the main SonicJS codebase.\n *\n * Current Phase: 2 (Core Module Migration)\n * Current Week: 1 (Types, Utils, Database)\n *\n * Expected completion: 4 weeks from 2025-01-17\n *\n * DO NOT USE IN PRODUCTION - Alpha release for development only\n */\n"]}