watch-tail 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/build/client/_app/immutable/assets/0.BQQ1YLPc.css +2 -0
- package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BQQ1YLPc.css.gz +0 -0
- package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css +1 -0
- package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.br +0 -0
- package/build/client/_app/immutable/assets/BrushContext.2tkUc39H.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css +1 -0
- package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.br +0 -0
- package/build/client/_app/immutable/assets/ChartAnnotations.Bw8CGteN.css.gz +0 -0
- package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css +1 -0
- package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.br +1 -0
- package/build/client/_app/immutable/assets/Circle.C5MKzgk2.css.gz +0 -0
- package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css +1 -0
- package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.br +0 -0
- package/build/client/_app/immutable/assets/DefaultTooltip.CGOVIm3D.css.gz +0 -0
- package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css +1 -0
- package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css.br +0 -0
- package/build/client/_app/immutable/assets/EventScatter.DA5sZ1c0.css.gz +0 -0
- package/build/client/_app/immutable/assets/Labels.sEaJtb97.css +1 -0
- package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.br +0 -0
- package/build/client/_app/immutable/assets/Labels.sEaJtb97.css.gz +0 -0
- package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css +1 -0
- package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.br +0 -0
- package/build/client/_app/immutable/assets/Legend.DnhxhJ2I.css.gz +0 -0
- package/build/client/_app/immutable/assets/Path.B0wDzTrn.css +1 -0
- package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.br +0 -0
- package/build/client/_app/immutable/assets/Path.B0wDzTrn.css.gz +0 -0
- package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css +1 -0
- package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.br +0 -0
- package/build/client/_app/immutable/assets/TransformContext.1cjyViIk.css.gz +0 -0
- package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css +1 -0
- package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.br +0 -0
- package/build/client/_app/immutable/assets/Voronoi.ce7atosu.css.gz +0 -0
- package/build/client/_app/immutable/chunks/AUlz4-kZ.js +1 -0
- package/build/client/_app/immutable/chunks/AUlz4-kZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/AUlz4-kZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B1t8v2wP.js +1 -0
- package/build/client/_app/immutable/chunks/B1t8v2wP.js.br +0 -0
- package/build/client/_app/immutable/chunks/B1t8v2wP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B6nyufJR.js +1 -0
- package/build/client/_app/immutable/chunks/B6nyufJR.js.br +0 -0
- package/build/client/_app/immutable/chunks/B6nyufJR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BR2LaRms.js +1 -0
- package/build/client/_app/immutable/chunks/BR2LaRms.js.br +1 -0
- package/build/client/_app/immutable/chunks/BR2LaRms.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BR7qH0F5.js +1 -0
- package/build/client/_app/immutable/chunks/BR7qH0F5.js.br +0 -0
- package/build/client/_app/immutable/chunks/BR7qH0F5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BkXArOra.js +1 -0
- package/build/client/_app/immutable/chunks/BkXArOra.js.br +0 -0
- package/build/client/_app/immutable/chunks/BkXArOra.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bl052uUt.js +1 -0
- package/build/client/_app/immutable/chunks/Bl052uUt.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bl052uUt.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bmk_Voz6.js +1 -0
- package/build/client/_app/immutable/chunks/Bmk_Voz6.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bmk_Voz6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bp63j1zN.js +1 -0
- package/build/client/_app/immutable/chunks/Bp63j1zN.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bp63j1zN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BwntJtbK.js +1 -0
- package/build/client/_app/immutable/chunks/BwntJtbK.js.br +0 -0
- package/build/client/_app/immutable/chunks/BwntJtbK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C20WvNRq.js +1 -0
- package/build/client/_app/immutable/chunks/C20WvNRq.js.br +0 -0
- package/build/client/_app/immutable/chunks/C20WvNRq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C58PZtCD.js +4 -0
- package/build/client/_app/immutable/chunks/C58PZtCD.js.br +0 -0
- package/build/client/_app/immutable/chunks/C58PZtCD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CCch3uox.js +1 -0
- package/build/client/_app/immutable/chunks/CCch3uox.js.br +0 -0
- package/build/client/_app/immutable/chunks/CCch3uox.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CDbeYGlD.js +1 -0
- package/build/client/_app/immutable/chunks/CDbeYGlD.js.br +0 -0
- package/build/client/_app/immutable/chunks/CDbeYGlD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CJFHBop_.js +1 -0
- package/build/client/_app/immutable/chunks/CJFHBop_.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJFHBop_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CYw9ugj1.js +1 -0
- package/build/client/_app/immutable/chunks/CYw9ugj1.js.br +0 -0
- package/build/client/_app/immutable/chunks/CYw9ugj1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CjJd0uRB.js +1 -0
- package/build/client/_app/immutable/chunks/CjJd0uRB.js.br +1 -0
- package/build/client/_app/immutable/chunks/CjJd0uRB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CoEFQJcr.js +1 -0
- package/build/client/_app/immutable/chunks/CoEFQJcr.js.br +0 -0
- package/build/client/_app/immutable/chunks/CoEFQJcr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D-JtVVAo.js +1 -0
- package/build/client/_app/immutable/chunks/D-JtVVAo.js.br +0 -0
- package/build/client/_app/immutable/chunks/D-JtVVAo.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DJDlf6lC.js +1 -0
- package/build/client/_app/immutable/chunks/DJDlf6lC.js.br +0 -0
- package/build/client/_app/immutable/chunks/DJDlf6lC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DJLYkl5w.js +1 -0
- package/build/client/_app/immutable/chunks/DJLYkl5w.js.br +0 -0
- package/build/client/_app/immutable/chunks/DJLYkl5w.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DPKdNiYi.js +1 -0
- package/build/client/_app/immutable/chunks/DPKdNiYi.js.br +0 -0
- package/build/client/_app/immutable/chunks/DPKdNiYi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DQi7bc16.js +1 -0
- package/build/client/_app/immutable/chunks/DQi7bc16.js.br +0 -0
- package/build/client/_app/immutable/chunks/DQi7bc16.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DVTgeA2y.js +2 -0
- package/build/client/_app/immutable/chunks/DVTgeA2y.js.br +0 -0
- package/build/client/_app/immutable/chunks/DVTgeA2y.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Db0q5_zr.js +1 -0
- package/build/client/_app/immutable/chunks/Db0q5_zr.js.br +0 -0
- package/build/client/_app/immutable/chunks/Db0q5_zr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dfvzj6n2.js +1 -0
- package/build/client/_app/immutable/chunks/Dfvzj6n2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dfvzj6n2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Di37PX72.js +1 -0
- package/build/client/_app/immutable/chunks/Di37PX72.js.br +0 -0
- package/build/client/_app/immutable/chunks/Di37PX72.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Bw_9uNRP.js → DkyYNO4U.js} +1 -1
- package/build/client/_app/immutable/chunks/DkyYNO4U.js.br +0 -0
- package/build/client/_app/immutable/chunks/DkyYNO4U.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DmRhEzIa.js +1 -0
- package/build/client/_app/immutable/chunks/DmRhEzIa.js.br +0 -0
- package/build/client/_app/immutable/chunks/DmRhEzIa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dp8S9ymS.js +1 -0
- package/build/client/_app/immutable/chunks/Dp8S9ymS.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dp8S9ymS.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DslUcEd-.js +1 -0
- package/build/client/_app/immutable/chunks/DslUcEd-.js.br +0 -0
- package/build/client/_app/immutable/chunks/DslUcEd-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dt_Zd6U2.js +1 -0
- package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dt_Zd6U2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DwezeuNE.js +5 -0
- package/build/client/_app/immutable/chunks/DwezeuNE.js.br +0 -0
- package/build/client/_app/immutable/chunks/DwezeuNE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js +1 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js.br +0 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/PYzEcuyd.js +10 -0
- package/build/client/_app/immutable/chunks/PYzEcuyd.js.br +0 -0
- package/build/client/_app/immutable/chunks/PYzEcuyd.js.gz +0 -0
- package/build/client/_app/immutable/chunks/RobXhXPM.js +1 -0
- package/build/client/_app/immutable/chunks/RobXhXPM.js.br +1 -0
- package/build/client/_app/immutable/chunks/RobXhXPM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UySfXNq7.js +1 -0
- package/build/client/_app/immutable/chunks/UySfXNq7.js.br +0 -0
- package/build/client/_app/immutable/chunks/UySfXNq7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Y5urAfNy.js +1 -0
- package/build/client/_app/immutable/chunks/Y5urAfNy.js.br +0 -0
- package/build/client/_app/immutable/chunks/Y5urAfNy.js.gz +0 -0
- package/build/client/_app/immutable/chunks/_Zq76xnA.js +15 -0
- package/build/client/_app/immutable/chunks/_Zq76xnA.js.br +0 -0
- package/build/client/_app/immutable/chunks/_Zq76xnA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/dbhDrJmm.js +1 -0
- package/build/client/_app/immutable/chunks/dbhDrJmm.js.br +0 -0
- package/build/client/_app/immutable/chunks/dbhDrJmm.js.gz +0 -0
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js +3 -0
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js.br +0 -0
- package/build/client/_app/immutable/chunks/pqiPC7Y8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/yCfI4PCa.js +1 -0
- package/build/client/_app/immutable/chunks/yCfI4PCa.js.br +0 -0
- package/build/client/_app/immutable/chunks/yCfI4PCa.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.vMZB8_Zr.js +2 -0
- package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.br +0 -0
- package/build/client/_app/immutable/entry/app.vMZB8_Zr.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.pM5lNk_5.js +1 -0
- package/build/client/_app/immutable/entry/start.pM5lNk_5.js.br +0 -0
- package/build/client/_app/immutable/entry/start.pM5lNk_5.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CZO0sIxX.js +1 -0
- package/build/client/_app/immutable/nodes/0.CZO0sIxX.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CZO0sIxX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.zcN3R_zF.js +1 -0
- package/build/client/_app/immutable/nodes/1.zcN3R_zF.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.zcN3R_zF.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DxevVqut.js +2 -0
- package/build/client/_app/immutable/nodes/2.DxevVqut.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DxevVqut.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +9 -7
- package/build/handler.js.map +1 -1
- package/build/index.js +9 -7
- package/build/index.js.map +1 -1
- package/build/server/chunks/chunks/Arc.canvas.js-D6g58nSp.js +701 -0
- package/build/server/chunks/chunks/Arc.canvas.js-D6g58nSp.js.map +1 -0
- package/build/server/chunks/chunks/Arc.js-D78Cf_4M.js +31 -0
- package/build/server/chunks/chunks/Arc.js-D78Cf_4M.js.map +1 -0
- package/build/server/chunks/chunks/Bar.js-Cv73T8_D.js +448 -0
- package/build/server/chunks/chunks/Bar.js-Cv73T8_D.js.map +1 -0
- package/build/server/chunks/chunks/ChartAnnotations.js-Ci22VB_6.js +983 -0
- package/build/server/chunks/chunks/ChartAnnotations.js-Ci22VB_6.js.map +1 -0
- package/build/server/chunks/chunks/Circle.html.js-BjwyNRG3.js +355 -0
- package/build/server/chunks/chunks/Circle.html.js-BjwyNRG3.js.map +1 -0
- package/build/server/chunks/chunks/ClipPath.canvas.js-CFTBDWVU.js +170 -0
- package/build/server/chunks/chunks/ClipPath.canvas.js-CFTBDWVU.js.map +1 -0
- package/build/server/chunks/chunks/DefaultTooltip.js-0r5rbE-1.js +352 -0
- package/build/server/chunks/chunks/DefaultTooltip.js-0r5rbE-1.js.map +1 -0
- package/build/server/chunks/chunks/EventScatter.js-DqCMPeHG.js +7304 -0
- package/build/server/chunks/chunks/EventScatter.js-DqCMPeHG.js.map +1 -0
- package/build/server/chunks/chunks/Labels.js-DpagpV6d.js +497 -0
- package/build/server/chunks/chunks/Labels.js-DpagpV6d.js.map +1 -0
- package/build/server/chunks/chunks/Legend.js-BOpwpe5s.js +343 -0
- package/build/server/chunks/chunks/Legend.js-BOpwpe5s.js.map +1 -0
- package/build/server/chunks/chunks/Line.html.js-BM5tR11G.js +423 -0
- package/build/server/chunks/chunks/Line.html.js-BM5tR11G.js.map +1 -0
- package/build/server/chunks/chunks/Link.canvas.js-P8ySzEAw.js +756 -0
- package/build/server/chunks/chunks/Link.canvas.js-P8ySzEAw.js.map +1 -0
- package/build/server/chunks/chunks/Path.canvas.js-DNAtnEBt.js +1259 -0
- package/build/server/chunks/chunks/Path.canvas.js-DNAtnEBt.js.map +1 -0
- package/build/server/chunks/chunks/Points.html.js-CLbHD6OP.js +228 -0
- package/build/server/chunks/chunks/Points.html.js-CLbHD6OP.js.map +1 -0
- package/build/server/chunks/chunks/Points.js-e6g0Re6H.js +14 -0
- package/build/server/chunks/chunks/Points.js-e6g0Re6H.js.map +1 -0
- package/build/server/chunks/chunks/Points2.js-BMGdkzTE.js +25 -0
- package/build/server/chunks/chunks/Points2.js-BMGdkzTE.js.map +1 -0
- package/build/server/chunks/chunks/Rect.html.js-Q3UvRwNn.js +547 -0
- package/build/server/chunks/chunks/Rect.html.js-Q3UvRwNn.js.map +1 -0
- package/build/server/chunks/chunks/Spline.js-BuZPz2PJ.js +516 -0
- package/build/server/chunks/chunks/Spline.js-BuZPz2PJ.js.map +1 -0
- package/build/server/chunks/chunks/Text.html.js-C8xO5Nz6.js +847 -0
- package/build/server/chunks/chunks/Text.html.js-C8xO5Nz6.js.map +1 -0
- package/build/server/chunks/chunks/TooltipItem.js-T0cKLjLu.js +314 -0
- package/build/server/chunks/chunks/TooltipItem.js-T0cKLjLu.js.map +1 -0
- package/build/server/chunks/chunks/Voronoi.js-DevTsXQE.js +2052 -0
- package/build/server/chunks/chunks/Voronoi.js-DevTsXQE.js.map +1 -0
- package/build/server/chunks/chunks/archive.js-C6rz09rJ.js +584 -0
- package/build/server/chunks/chunks/archive.js-C6rz09rJ.js.map +1 -0
- package/build/server/chunks/chunks/array.js-CBp0H4t3.js +8 -0
- package/build/server/chunks/chunks/array.js-CBp0H4t3.js.map +1 -0
- package/build/server/chunks/chunks/attributes.js-BVWo7wbg.js +25 -0
- package/build/server/chunks/chunks/attributes.js-BVWo7wbg.js.map +1 -0
- package/build/server/chunks/chunks/{env2.js-DXveJt1Y.js → aws.js-DkPqAybc.js} +2 -59
- package/build/server/chunks/chunks/aws.js-DkPqAybc.js.map +1 -0
- package/build/server/chunks/chunks/band.js-C7izXphE.js +155 -0
- package/build/server/chunks/chunks/band.js-C7izXphE.js.map +1 -0
- package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js +1356 -0
- package/build/server/chunks/chunks/centroid.js-BnGN3LH0.js.map +1 -0
- package/build/server/chunks/chunks/common.js-BWQB8Die.js +5760 -0
- package/build/server/chunks/chunks/common.js-BWQB8Die.js.map +1 -0
- package/build/server/chunks/chunks/env2.js-CcIskxOZ.js +60 -0
- package/build/server/chunks/chunks/env2.js-CcIskxOZ.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-CvFPPbaH.js → exports.js-ClPPfcHj.js} +6 -1
- package/build/server/chunks/chunks/exports.js-ClPPfcHj.js.map +1 -0
- package/build/server/chunks/chunks/group.js-DBFzWAox.js +30 -0
- package/build/server/chunks/chunks/group.js-DBFzWAox.js.map +1 -0
- package/build/server/chunks/chunks/index-server.js-DNLOKvM0.js +248 -0
- package/build/server/chunks/chunks/index-server.js-DNLOKvM0.js.map +1 -0
- package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js +2 -0
- package/build/server/chunks/chunks/index-server2.js-l0sNRNKZ.js.map +1 -0
- package/build/server/chunks/chunks/{internal2.js-DZ8ZzzjN.js → internal.js-DZ8ZzzjN.js} +1 -1
- package/build/server/chunks/chunks/internal.js-DZ8ZzzjN.js.map +1 -0
- package/build/server/chunks/chunks/internal2.js-DDcktblR.js +188 -0
- package/build/server/chunks/chunks/internal2.js-DDcktblR.js.map +1 -0
- package/build/server/chunks/chunks/key.svelte.js-CWIvXc6L.js +695 -0
- package/build/server/chunks/chunks/key.svelte.js-CWIvXc6L.js.map +1 -0
- package/build/server/chunks/chunks/{internal.js-Cc3oBhL-.js → legacy-client.js-DJmDw3Zx.js} +13 -439
- package/build/server/chunks/chunks/legacy-client.js-DJmDw3Zx.js.map +1 -0
- package/build/server/chunks/chunks/level-filter.js-H_AdNbCw.js +297 -0
- package/build/server/chunks/chunks/level-filter.js-H_AdNbCw.js.map +1 -0
- package/build/server/chunks/chunks/lineRadial.js-Dm0GMqo3.js +126 -0
- package/build/server/chunks/chunks/lineRadial.js-Dm0GMqo3.js.map +1 -0
- package/build/server/chunks/chunks/linear.js-CTOKrHn9.js +1046 -0
- package/build/server/chunks/chunks/linear.js-CTOKrHn9.js.map +1 -0
- package/build/server/chunks/chunks/log-buffer.js-CpI7gyom.js +471 -0
- package/build/server/chunks/chunks/log-buffer.js-CpI7gyom.js.map +1 -0
- package/build/server/chunks/chunks/math.js-BqujbaBs.js +50 -0
- package/build/server/chunks/chunks/math.js-BqujbaBs.js.map +1 -0
- package/build/server/chunks/chunks/max.js-CuS0BpRI.js +11 -0
- package/build/server/chunks/chunks/max.js-CuS0BpRI.js.map +1 -0
- package/build/server/chunks/chunks/min.js-DZWt5tPl.js +11 -0
- package/build/server/chunks/chunks/min.js-DZWt5tPl.js.map +1 -0
- package/build/server/chunks/chunks/motion.svelte.js-DCHSFMu-.js +677 -0
- package/build/server/chunks/chunks/motion.svelte.js-DCHSFMu-.js.map +1 -0
- package/build/server/chunks/chunks/occlusion.js-DJ-AdK9u.js +33 -0
- package/build/server/chunks/chunks/occlusion.js-DJ-AdK9u.js.map +1 -0
- package/build/server/chunks/chunks/path.js-BizMrlzb.js +488 -0
- package/build/server/chunks/chunks/path.js-BizMrlzb.js.map +1 -0
- package/build/server/chunks/chunks/path2.js-pquT2Kg6.js +27 -0
- package/build/server/chunks/chunks/path2.js-pquT2Kg6.js.map +1 -0
- package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js +7 -0
- package/build/server/chunks/chunks/pointRadial.js-Deeu1LXx.js.map +1 -0
- package/build/server/chunks/chunks/rect.svelte.js-zeS7FWjB.js +187 -0
- package/build/server/chunks/chunks/rect.svelte.js-zeS7FWjB.js.map +1 -0
- package/build/server/chunks/chunks/scales.svelte.js-D_1popPi.js +276 -0
- package/build/server/chunks/chunks/scales.svelte.js-D_1popPi.js.map +1 -0
- package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js +123 -0
- package/build/server/chunks/chunks/series-buckets.js-CX_rWCeH.js.map +1 -0
- package/build/server/chunks/chunks/{server.js-ByNB8uti.js → server.js-CAEBuMIH.js} +167 -2
- package/build/server/chunks/chunks/server.js-CAEBuMIH.js.map +1 -0
- package/build/server/chunks/chunks/source.js-DZEVvuho.js +21 -0
- package/build/server/chunks/chunks/source.js-DZEVvuho.js.map +1 -0
- package/build/server/chunks/chunks/{state.js-9DxsWxU-.js → state.js-Dves8H8h.js} +5 -4
- package/build/server/chunks/chunks/state.js-Dves8H8h.js.map +1 -0
- package/build/server/chunks/chunks/types.js-x3GyGPOz.js +11 -0
- package/build/server/chunks/chunks/types.js-x3GyGPOz.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-sNd3lS0y.js +39 -0
- package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-sNd3lS0y.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/health/{_server.ts.js-BOjix7GN.js → _server.ts.js-VctnBhIJ.js} +5 -4
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-VctnBhIJ.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/identity/{_server.ts.js-g13uvmrX.js → _server.ts.js-Dt540Sio.js} +4 -3
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-Dt540Sio.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-CmHRxdZK.js → _server.ts.js-BGyWbj78.js} +57 -8
- package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-BGyWbj78.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/regions/{_server.ts.js-BgUwioxp.js → _server.ts.js-CBqfN6Pg.js} +5 -4
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-CBqfN6Pg.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DjGMqXKo.js +194 -0
- package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DjGMqXKo.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-CIYo4C-0.js → _server.ts.js-C-XDemlx.js} +324 -223
- package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-C-XDemlx.js.map +1 -0
- package/build/server/chunks/entries/fallbacks/{error.svelte.js-CFonuZkV.js → error.svelte.js-DdUYlUJV.js} +7 -5
- package/build/server/chunks/entries/fallbacks/{error.svelte.js-CFonuZkV.js.map → error.svelte.js-DdUYlUJV.js.map} +1 -1
- package/build/server/chunks/entries/pages/{_layout.svelte.js-Dzluuq12.js → _layout.svelte.js-CBQpEToy.js} +2 -2
- package/build/server/chunks/entries/pages/{_layout.svelte.js-Dzluuq12.js.map → _layout.svelte.js-CBQpEToy.js.map} +1 -1
- package/build/server/chunks/entries/pages/{_page.svelte.js-CpwYbxbM.js → _page.svelte.js-B-kVwiNh.js} +538 -351
- package/build/server/chunks/entries/pages/_page.svelte.js-B-kVwiNh.js.map +1 -0
- package/build/server/chunks/{handler-DS32NMsJ.js → handler-BHf-eLnl.js} +3 -3
- package/build/server/chunks/{handler-DS32NMsJ.js.map → handler-BHf-eLnl.js.map} +1 -1
- package/build/server/chunks/{index.js-HHu-yOEK.js → index.js-D6Auup1Z.js} +6 -5
- package/build/server/chunks/index.js-D6Auup1Z.js.map +1 -0
- package/build/server/chunks/{manifest.js-BUrA7Zyr.js → manifest.js-B3Q7n9I6.js} +24 -10
- package/build/server/chunks/manifest.js-B3Q7n9I6.js.map +1 -0
- package/build/server/chunks/nodes/0.js-BMP_Yttt.js +9 -0
- package/build/server/chunks/nodes/{0.js-gSRmrAt_.js.map → 0.js-BMP_Yttt.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-2HQHUOse.js +9 -0
- package/build/server/chunks/nodes/{1.js-D68K7Ad_.js.map → 1.js-2HQHUOse.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-7RtHpiHN.js +9 -0
- package/build/server/chunks/nodes/2.js-7RtHpiHN.js.map +1 -0
- package/dist/cli/completions.js +6 -0
- package/dist/cli/index.js +21 -1
- package/dist/cli/options.js +28 -2
- package/dist/cli/preflight.js +30 -0
- package/dist/lib/cli/aws.js +12 -4
- package/dist/lib/log-buffer.js +314 -0
- package/dist/lib/log-format.js +185 -0
- package/dist/lib/types.js +0 -4
- package/package.json +6 -2
- package/build/client/_app/immutable/assets/0.BPmQoXaO.css +0 -2
- package/build/client/_app/immutable/assets/0.BPmQoXaO.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BPmQoXaO.css.gz +0 -0
- package/build/client/_app/immutable/chunks/Bw_9uNRP.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bw_9uNRP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/De_x7GQi.js +0 -1
- package/build/client/_app/immutable/chunks/De_x7GQi.js.br +0 -0
- package/build/client/_app/immutable/chunks/De_x7GQi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ZAD2y5xJ.js +0 -3
- package/build/client/_app/immutable/chunks/ZAD2y5xJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/ZAD2y5xJ.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Be166AxG.js +0 -2
- package/build/client/_app/immutable/entry/app.Be166AxG.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Be166AxG.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.clEDpQL9.js +0 -1
- package/build/client/_app/immutable/entry/start.clEDpQL9.js.br +0 -0
- package/build/client/_app/immutable/entry/start.clEDpQL9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js +0 -1
- package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js.br +0 -4
- package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.xMNWuLLz.js +0 -1
- package/build/client/_app/immutable/nodes/1.xMNWuLLz.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.xMNWuLLz.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CaxDXwmh.js +0 -5
- package/build/client/_app/immutable/nodes/2.CaxDXwmh.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CaxDXwmh.js.gz +0 -0
- package/build/server/chunks/chunks/env2.js-DXveJt1Y.js.map +0 -1
- package/build/server/chunks/chunks/exports.js-CvFPPbaH.js.map +0 -1
- package/build/server/chunks/chunks/internal.js-Cc3oBhL-.js.map +0 -1
- package/build/server/chunks/chunks/internal2.js-DZ8ZzzjN.js.map +0 -1
- package/build/server/chunks/chunks/server.js-ByNB8uti.js.map +0 -1
- package/build/server/chunks/chunks/state.js-9DxsWxU-.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-BOjix7GN.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-g13uvmrX.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-CmHRxdZK.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-BgUwioxp.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-CIYo4C-0.js.map +0 -1
- package/build/server/chunks/entries/pages/_page.svelte.js-CpwYbxbM.js.map +0 -1
- package/build/server/chunks/index.js-HHu-yOEK.js.map +0 -1
- package/build/server/chunks/manifest.js-BUrA7Zyr.js.map +0 -1
- package/build/server/chunks/nodes/0.js-gSRmrAt_.js +0 -9
- package/build/server/chunks/nodes/1.js-D68K7Ad_.js +0 -9
- package/build/server/chunks/nodes/2.js-ChYsaaoC.js +0 -9
- package/build/server/chunks/nodes/2.js-ChYsaaoC.js.map +0 -1
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import { d as detectLevelWithSource, i as isLogLevel } from './log-buffer.js-CpI7gyom.js';
|
|
2
|
+
import { mkdirSync, statSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { setTimeout } from 'node:timers/promises';
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
|
|
8
|
+
//#region src/lib/server/archive-sql.ts
|
|
9
|
+
/**
|
|
10
|
+
* SQL and row mapping for the local DuckDB archive.
|
|
11
|
+
*
|
|
12
|
+
* DuckDB is a native dependency and is loaded lazily by `archive.ts`; everything
|
|
13
|
+
* in this file is plain text and pure functions so the archive can be unit
|
|
14
|
+
* tested without the driver. Column order matters: {@link ARCHIVE_INSERT_COLUMNS}
|
|
15
|
+
* is the contract with {@link toArchiveParams}, and the `SELECT` in
|
|
16
|
+
* {@link buildPageQuery} uses the same names as {@link rowsToPage}.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Statements that bring a database file up to the current schema.
|
|
20
|
+
*
|
|
21
|
+
* Every statement is idempotent so an existing archive can be opened by a newer
|
|
22
|
+
* build without a migration step. `seq` orders events by arrival, which keeps
|
|
23
|
+
* paging stable when many events share a millisecond timestamp.
|
|
24
|
+
*/
|
|
25
|
+
var ARCHIVE_SCHEMA = [
|
|
26
|
+
`CREATE SEQUENCE IF NOT EXISTS log_events_seq`,
|
|
27
|
+
`CREATE TABLE IF NOT EXISTS log_events (
|
|
28
|
+
region VARCHAR NOT NULL,
|
|
29
|
+
log_group VARCHAR NOT NULL,
|
|
30
|
+
log_stream VARCHAR,
|
|
31
|
+
event_key VARCHAR NOT NULL,
|
|
32
|
+
event_id VARCHAR,
|
|
33
|
+
timestamp_ms BIGINT NOT NULL,
|
|
34
|
+
ingestion_time_ms BIGINT,
|
|
35
|
+
message VARCHAR NOT NULL,
|
|
36
|
+
level VARCHAR,
|
|
37
|
+
level_source VARCHAR,
|
|
38
|
+
seq BIGINT NOT NULL DEFAULT nextval('log_events_seq'),
|
|
39
|
+
archived_at TIMESTAMP NOT NULL DEFAULT now()
|
|
40
|
+
)`,
|
|
41
|
+
`ALTER TABLE log_events ADD COLUMN IF NOT EXISTS level VARCHAR`,
|
|
42
|
+
`ALTER TABLE log_events ADD COLUMN IF NOT EXISTS level_source VARCHAR`,
|
|
43
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS log_events_unique ON log_events (region, log_group, event_key)`,
|
|
44
|
+
`CREATE INDEX IF NOT EXISTS log_events_time ON log_events (region, log_group, timestamp_ms)`
|
|
45
|
+
];
|
|
46
|
+
/** Columns written by {@link buildInsertSql}, in binding order. */
|
|
47
|
+
var ARCHIVE_INSERT_COLUMNS = [
|
|
48
|
+
"region",
|
|
49
|
+
"log_group",
|
|
50
|
+
"log_stream",
|
|
51
|
+
"event_key",
|
|
52
|
+
"event_id",
|
|
53
|
+
"timestamp_ms",
|
|
54
|
+
"ingestion_time_ms",
|
|
55
|
+
"message",
|
|
56
|
+
"level",
|
|
57
|
+
"level_source"
|
|
58
|
+
];
|
|
59
|
+
/** Escape character used with `LIKE`/`ILIKE` so user input cannot inject wildcards. */
|
|
60
|
+
var LIKE_ESCAPE = "\\";
|
|
61
|
+
/**
|
|
62
|
+
* Stable identity of an event inside one log group.
|
|
63
|
+
*
|
|
64
|
+
* CloudWatch event ids are unique per log group and are reused as the key;
|
|
65
|
+
* events without an id (floci and LocalStack omit them) get a deterministic
|
|
66
|
+
* hash of timestamp, stream and message, so re-scanning the same window is
|
|
67
|
+
* idempotent instead of duplicating rows.
|
|
68
|
+
*/
|
|
69
|
+
function archiveEventKey(event) {
|
|
70
|
+
if (event.id !== null && event.id.length > 0) return event.id;
|
|
71
|
+
return `h:${createHash("sha256").update(`${event.timestamp}\u0000${event.streamName ?? ""}\u0000${event.message}`).digest("hex").slice(0, 32)}`;
|
|
72
|
+
}
|
|
73
|
+
/** Renders `count` placeholder rows of ten columns each. */
|
|
74
|
+
function placeholderRows(count) {
|
|
75
|
+
const row = `(${ARCHIVE_INSERT_COLUMNS.map(() => "?").join(", ")})`;
|
|
76
|
+
return Array.from({ length: count }, () => row).join(", ");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Builds a multi-row `INSERT OR IGNORE`, so events already archived are skipped
|
|
80
|
+
* by the unique index instead of raising.
|
|
81
|
+
*/
|
|
82
|
+
function buildInsertSql(rowCount) {
|
|
83
|
+
if (!Number.isInteger(rowCount) || rowCount < 1) throw new RangeError(`rowCount must be a positive integer, received ${String(rowCount)}`);
|
|
84
|
+
return `INSERT OR IGNORE INTO log_events (${ARCHIVE_INSERT_COLUMNS.join(", ")}) VALUES ${placeholderRows(rowCount)}`;
|
|
85
|
+
}
|
|
86
|
+
/** Flattens events into the parameter list {@link buildInsertSql} expects. */
|
|
87
|
+
function toArchiveParams(region, logGroup, events) {
|
|
88
|
+
const params = [];
|
|
89
|
+
for (const event of events) {
|
|
90
|
+
const detected = detectLevelWithSource(event.message);
|
|
91
|
+
params.push(region, logGroup, event.streamName ?? null, archiveEventKey(event), event.id ?? null, BigInt(Math.round(event.timestamp)), event.ingestionTime === void 0 ? null : BigInt(Math.round(event.ingestionTime)), event.message, detected.level, detected.source);
|
|
92
|
+
}
|
|
93
|
+
return params;
|
|
94
|
+
}
|
|
95
|
+
/** Column list shared by {@link buildPageQuery} and {@link rowsToPage}. */
|
|
96
|
+
var PAGE_COLUMNS = `region, log_group, log_stream, event_key, event_id, timestamp_ms, ingestion_time_ms, message, level, level_source, seq`;
|
|
97
|
+
/** Escapes `LIKE` metacharacters so a search term is matched literally. */
|
|
98
|
+
function escapeLike(value) {
|
|
99
|
+
return value.replace(/[\\%_]/g, (match) => `${LIKE_ESCAPE}${match}`);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Builds one keyset page of archived events.
|
|
103
|
+
*
|
|
104
|
+
* Ordering is `(timestamp_ms, seq)`, and the cursor compares the same tuple, so
|
|
105
|
+
* pages never repeat or skip a row even when thousands of events share a
|
|
106
|
+
* timestamp.
|
|
107
|
+
*/
|
|
108
|
+
function buildPageQuery(request) {
|
|
109
|
+
const limit = Math.max(1, Math.round(request.limit));
|
|
110
|
+
const groups = request.logGroups.length > 0 ? request.logGroups : [""];
|
|
111
|
+
const where = [
|
|
112
|
+
"region = ?",
|
|
113
|
+
`log_group IN (${groups.map(() => "?").join(", ")})`,
|
|
114
|
+
"timestamp_ms >= ?",
|
|
115
|
+
"timestamp_ms <= ?"
|
|
116
|
+
];
|
|
117
|
+
const params = [
|
|
118
|
+
request.region,
|
|
119
|
+
...groups,
|
|
120
|
+
BigInt(Math.round(request.startTime)),
|
|
121
|
+
BigInt(Math.round(request.endTime))
|
|
122
|
+
];
|
|
123
|
+
const search = request.search?.trim() ?? "";
|
|
124
|
+
if (search.length > 0) {
|
|
125
|
+
where.push(`message ILIKE ? ESCAPE '${LIKE_ESCAPE}'`);
|
|
126
|
+
params.push(`%${escapeLike(search)}%`);
|
|
127
|
+
}
|
|
128
|
+
const prefix = request.streamPrefix?.trim() ?? "";
|
|
129
|
+
if (prefix.length > 0) {
|
|
130
|
+
where.push(`log_stream LIKE ? ESCAPE '${LIKE_ESCAPE}'`);
|
|
131
|
+
params.push(`${escapeLike(prefix)}%`);
|
|
132
|
+
}
|
|
133
|
+
const levels = request.levels ?? [];
|
|
134
|
+
if (levels.length > 0) {
|
|
135
|
+
where.push(`level IN (${levels.map(() => "?").join(", ")})`);
|
|
136
|
+
params.push(...levels);
|
|
137
|
+
}
|
|
138
|
+
const after = request.after ?? null;
|
|
139
|
+
if (after !== null) {
|
|
140
|
+
where.push("(timestamp_ms > ? OR (timestamp_ms = ? AND seq > ?))");
|
|
141
|
+
params.push(BigInt(Math.round(after.timestamp)), BigInt(Math.round(after.timestamp)), BigInt(Math.round(after.seq)));
|
|
142
|
+
}
|
|
143
|
+
params.push(BigInt(limit));
|
|
144
|
+
return {
|
|
145
|
+
sql: `SELECT ${PAGE_COLUMNS} FROM log_events WHERE ${where.join(" AND ")} ORDER BY timestamp_ms, seq LIMIT ?`,
|
|
146
|
+
params
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** Converts a DuckDB value (which may be a bigint) into a JS number. */
|
|
150
|
+
function toNumber(value) {
|
|
151
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
152
|
+
if (typeof value === "bigint") return Number(value);
|
|
153
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
154
|
+
const parsed = Number(value);
|
|
155
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/** Converts a nullable DuckDB string column into `string` or `null`. */
|
|
160
|
+
function toNullableString(value) {
|
|
161
|
+
if (typeof value === "string") return value.length > 0 ? value : null;
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
/** Reads one column from a row object, tolerating case differences. */
|
|
165
|
+
function pick(row, column) {
|
|
166
|
+
if (column in row) return row[column];
|
|
167
|
+
const upper = column.toUpperCase();
|
|
168
|
+
if (upper in row) return row[upper];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Maps query rows onto wire events plus the cursor of the last row.
|
|
172
|
+
*
|
|
173
|
+
* Rows without a usable timestamp are dropped rather than rendered as 1970.
|
|
174
|
+
*/
|
|
175
|
+
function rowsToPage(rows) {
|
|
176
|
+
const events = [];
|
|
177
|
+
let last = null;
|
|
178
|
+
for (const row of rows) {
|
|
179
|
+
const timestamp = toNumber(pick(row, "timestamp_ms"));
|
|
180
|
+
const seq = toNumber(pick(row, "seq"));
|
|
181
|
+
if (timestamp === null || seq === null) continue;
|
|
182
|
+
const rawLevel = pick(row, "level");
|
|
183
|
+
const group = toNullableString(pick(row, "log_group"));
|
|
184
|
+
const event = {
|
|
185
|
+
id: toNullableString(pick(row, "event_key")),
|
|
186
|
+
timestamp,
|
|
187
|
+
message: typeof pick(row, "message") === "string" ? pick(row, "message") : "",
|
|
188
|
+
level: isLogLevel(rawLevel) ? rawLevel : null
|
|
189
|
+
};
|
|
190
|
+
if (group !== null) event.group = group;
|
|
191
|
+
const streamName = toNullableString(pick(row, "log_stream"));
|
|
192
|
+
if (streamName !== null) event.streamName = streamName;
|
|
193
|
+
const ingestionTime = toNumber(pick(row, "ingestion_time_ms"));
|
|
194
|
+
if (ingestionTime !== null) event.ingestionTime = ingestionTime;
|
|
195
|
+
events.push(event);
|
|
196
|
+
last = {
|
|
197
|
+
timestamp,
|
|
198
|
+
seq
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
events,
|
|
203
|
+
last
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/** Aggregate query behind {@link ArchiveTotals}. */
|
|
207
|
+
var ARCHIVE_TOTALS_SQL = `SELECT count(*) AS rows, count(DISTINCT log_group) AS groups, count(DISTINCT region) AS regions, min(timestamp_ms) AS oldest, max(timestamp_ms) AS newest FROM log_events`;
|
|
208
|
+
/** Log groups held by the archive, optionally limited to one region. */
|
|
209
|
+
function buildGroupsQuery(region) {
|
|
210
|
+
const where = region === null || region.length === 0 ? "" : "WHERE region = ?";
|
|
211
|
+
return {
|
|
212
|
+
sql: `SELECT region, log_group, count(*) AS events, min(timestamp_ms) AS oldest, max(timestamp_ms) AS newest FROM log_events ${where} GROUP BY region, log_group ORDER BY region, log_group`,
|
|
213
|
+
params: where === "" ? [] : [region]
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/** Maps the single row of {@link ARCHIVE_TOTALS_SQL}. */
|
|
217
|
+
function rowToTotals(row) {
|
|
218
|
+
if (row === void 0) return {
|
|
219
|
+
rows: 0,
|
|
220
|
+
groups: 0,
|
|
221
|
+
regions: 0,
|
|
222
|
+
oldest: null,
|
|
223
|
+
newest: null
|
|
224
|
+
};
|
|
225
|
+
return {
|
|
226
|
+
rows: toNumber(pick(row, "rows")) ?? 0,
|
|
227
|
+
groups: toNumber(pick(row, "groups")) ?? 0,
|
|
228
|
+
regions: toNumber(pick(row, "regions")) ?? 0,
|
|
229
|
+
oldest: toNumber(pick(row, "oldest")),
|
|
230
|
+
newest: toNumber(pick(row, "newest"))
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/** Maps the rows of {@link buildGroupsQuery}. */
|
|
234
|
+
function rowsToGroups(rows) {
|
|
235
|
+
const groups = [];
|
|
236
|
+
for (const row of rows) {
|
|
237
|
+
const region = pick(row, "region");
|
|
238
|
+
const logGroup = pick(row, "log_group");
|
|
239
|
+
if (typeof region !== "string" || typeof logGroup !== "string") continue;
|
|
240
|
+
groups.push({
|
|
241
|
+
region,
|
|
242
|
+
logGroup,
|
|
243
|
+
events: toNumber(pick(row, "events")) ?? 0,
|
|
244
|
+
oldest: toNumber(pick(row, "oldest")),
|
|
245
|
+
newest: toNumber(pick(row, "newest"))
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return groups;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Builds the bucketed counts behind the chart.
|
|
252
|
+
*
|
|
253
|
+
* One statement returns every series. The bucket is plain integer arithmetic on
|
|
254
|
+
* `timestamp_ms`, so it cannot drift with a time zone; NULL levels are reported
|
|
255
|
+
* as `unknown` rather than dropped; and a level filter matches only rows that
|
|
256
|
+
* carry one of the requested levels.
|
|
257
|
+
*/
|
|
258
|
+
function buildSeriesQuery(request) {
|
|
259
|
+
const bucketMs = Math.max(1, Math.round(request.bucketMs));
|
|
260
|
+
const groups = request.logGroups.length > 0 ? request.logGroups : [""];
|
|
261
|
+
const where = [
|
|
262
|
+
"region = ?",
|
|
263
|
+
`log_group IN (${groups.map(() => "?").join(", ")})`,
|
|
264
|
+
"timestamp_ms >= ?",
|
|
265
|
+
"timestamp_ms <= ?"
|
|
266
|
+
];
|
|
267
|
+
const params = [
|
|
268
|
+
BigInt(bucketMs),
|
|
269
|
+
BigInt(bucketMs),
|
|
270
|
+
request.region,
|
|
271
|
+
...groups,
|
|
272
|
+
BigInt(Math.round(request.startTime)),
|
|
273
|
+
BigInt(Math.round(request.endTime))
|
|
274
|
+
];
|
|
275
|
+
const levels = request.levels ?? [];
|
|
276
|
+
if (levels.length > 0) {
|
|
277
|
+
where.push(`level IN (${levels.map(() => "?").join(", ")})`);
|
|
278
|
+
params.push(...levels);
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
sql: `SELECT CAST(floor(timestamp_ms / ?) * ? AS BIGINT) AS bucket, log_group, coalesce(level, 'unknown') AS level, count(*) AS events FROM log_events WHERE ${where.join(" AND ")} GROUP BY bucket, log_group, level ORDER BY bucket, log_group, level`,
|
|
282
|
+
params
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/** Maps the rows of {@link buildSeriesQuery} onto chart points. */
|
|
286
|
+
function rowsToSeries(rows) {
|
|
287
|
+
const points = [];
|
|
288
|
+
for (const row of rows) {
|
|
289
|
+
const t = toNumber(pick(row, "bucket"));
|
|
290
|
+
const group = pick(row, "log_group");
|
|
291
|
+
const level = pick(row, "level");
|
|
292
|
+
if (t === null || typeof group !== "string") continue;
|
|
293
|
+
points.push({
|
|
294
|
+
t,
|
|
295
|
+
group,
|
|
296
|
+
level: typeof level === "string" && level.length > 0 ? level : "unknown",
|
|
297
|
+
events: toNumber(pick(row, "events")) ?? 0
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
return points;
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
303
|
+
//#region src/lib/server/archive.ts
|
|
304
|
+
/**
|
|
305
|
+
* Local DuckDB archive of the events the app has streamed.
|
|
306
|
+
*
|
|
307
|
+
* The driver (`@duckdb/node-api` plus its per-platform native binding) is an
|
|
308
|
+
* optional dependency: it is imported lazily, on the first request that needs
|
|
309
|
+
* it, and every failure is turned into an unavailable archive instead of an
|
|
310
|
+
* error. The rest of the app therefore works unchanged on platforms where the
|
|
311
|
+
* binding is missing.
|
|
312
|
+
*
|
|
313
|
+
* One process owns the file: DuckDB allows a single writer, and the SvelteKit
|
|
314
|
+
* server is that writer. Statements are serialised through an internal queue so
|
|
315
|
+
* a stream writing while another request reads cannot interleave on the
|
|
316
|
+
* connection.
|
|
317
|
+
*/
|
|
318
|
+
/** Package name of the optional DuckDB driver. */
|
|
319
|
+
var DUCKDB_MODULE = "@duckdb/node-api";
|
|
320
|
+
/** Directory name used under the platform data directory. */
|
|
321
|
+
var ARCHIVE_DIR_NAME = "watch-tail";
|
|
322
|
+
/** File name of the archive inside {@link ARCHIVE_DIR_NAME}. */
|
|
323
|
+
var ARCHIVE_FILE_NAME = "archive.duckdb";
|
|
324
|
+
/**
|
|
325
|
+
* Imports the optional DuckDB driver.
|
|
326
|
+
*
|
|
327
|
+
* The specifier is held in a variable on purpose: bundlers must leave the
|
|
328
|
+
* import alone so Node resolves it at run time, where a missing binding can be
|
|
329
|
+
* reported as an unavailable archive rather than a build error.
|
|
330
|
+
*/
|
|
331
|
+
async function loadDuckDbDriver() {
|
|
332
|
+
const loaded = await import(DUCKDB_MODULE);
|
|
333
|
+
if (typeof loaded.DuckDBInstance?.create !== "function") throw new Error(`${DUCKDB_MODULE} did not expose DuckDBInstance.create`);
|
|
334
|
+
return loaded;
|
|
335
|
+
}
|
|
336
|
+
var DISABLED_VALUES = /* @__PURE__ */ new Set([
|
|
337
|
+
"0",
|
|
338
|
+
"false",
|
|
339
|
+
"no",
|
|
340
|
+
"off"
|
|
341
|
+
]);
|
|
342
|
+
/** True when an environment value means "off". */
|
|
343
|
+
function isDisabled(value) {
|
|
344
|
+
return value !== void 0 && DISABLED_VALUES.has(value.trim().toLowerCase());
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* True when this process is a test runner.
|
|
348
|
+
*
|
|
349
|
+
* Vitest sets `VITEST`, and `NODE_ENV=test` covers other harnesses. Tests must
|
|
350
|
+
* not append to the archive of the machine they run on, so the archive is off
|
|
351
|
+
* unless a test asks for it through `WATCH_STREAM_ARCHIVE_DB` or
|
|
352
|
+
* `WATCH_STREAM_ARCHIVE=on`.
|
|
353
|
+
*/
|
|
354
|
+
function isTestProcess(env) {
|
|
355
|
+
return env.VITEST !== void 0 || env.NODE_ENV === "test";
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Resolves the archive file path.
|
|
359
|
+
*
|
|
360
|
+
* `WATCH_STREAM_ARCHIVE_DB` wins; otherwise the file lives in the platform's
|
|
361
|
+
* data directory (`XDG_DATA_HOME`, `%LOCALAPPDATA%` or
|
|
362
|
+
* `~/Library/Application Support`), never in the current directory, so history
|
|
363
|
+
* survives running the CLI from a different folder.
|
|
364
|
+
*/
|
|
365
|
+
function resolveArchiveConfig(env, platform = process.platform, home = homedir()) {
|
|
366
|
+
const path = env.WATCH_STREAM_ARCHIVE_DB?.trim() ?? "";
|
|
367
|
+
const dataDir = env.XDG_DATA_HOME?.trim() ?? (platform === "darwin" ? join(home, "Library", "Application Support") : platform === "win32" ? env.LOCALAPPDATA?.trim() ?? join(home, "AppData", "Local") : join(home, ".local", "share"));
|
|
368
|
+
const requested = env.WATCH_STREAM_ARCHIVE?.trim() ?? "";
|
|
369
|
+
return {
|
|
370
|
+
enabled: isDisabled(requested) ? false : path.length > 0 || requested.length > 0 ? true : !isTestProcess(env),
|
|
371
|
+
path: path.length > 0 ? path : join(dataDir, ARCHIVE_DIR_NAME, ARCHIVE_FILE_NAME)
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* A short, non-throwing description of an unknown failure.
|
|
376
|
+
*
|
|
377
|
+
* A conflicting lock is the one failure a user can act on, and DuckDB's own
|
|
378
|
+
* message buries the reason in a pid and a documentation link, so it is
|
|
379
|
+
* reported as what it means for this app.
|
|
380
|
+
*/
|
|
381
|
+
function describeOpenError(error, path) {
|
|
382
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
383
|
+
if (/Could not set lock|Conflicting lock/i.test(message)) return `the archive file ${path} is locked by another process (another watch-tail is using it); use --db to keep a separate file`;
|
|
384
|
+
return message;
|
|
385
|
+
}
|
|
386
|
+
/** True when the failure is the exclusive file lock. */
|
|
387
|
+
function isLockError(error) {
|
|
388
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
389
|
+
return /Could not set lock|Conflicting lock/i.test(message);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* One DuckDB file holding every event the app has streamed.
|
|
393
|
+
*
|
|
394
|
+
* `open` never throws: a missing driver, a locked file or a corrupt database all
|
|
395
|
+
* produce an instance with `available === false` and the reason on `error`. The
|
|
396
|
+
* read and write methods then behave as no-ops, so callers never have to guard
|
|
397
|
+
* their happy path.
|
|
398
|
+
*/
|
|
399
|
+
var LogArchive = class LogArchive {
|
|
400
|
+
/** Database file this archive uses. */
|
|
401
|
+
path;
|
|
402
|
+
#connection = null;
|
|
403
|
+
#available = false;
|
|
404
|
+
#error = null;
|
|
405
|
+
#queue = Promise.resolve();
|
|
406
|
+
constructor(path) {
|
|
407
|
+
this.path = path;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Opens (and creates) the archive.
|
|
411
|
+
*
|
|
412
|
+
* Statements are executed in order: the sequence first, then the table, then
|
|
413
|
+
* the indexes, so an existing file from an older build is upgraded in place.
|
|
414
|
+
*/
|
|
415
|
+
static async open(options) {
|
|
416
|
+
const archive = new LogArchive(options.path);
|
|
417
|
+
const load = options.load ?? loadDuckDbDriver;
|
|
418
|
+
const ensureDir = options.ensureDir ?? ((dir) => mkdirSync(dir, { recursive: true }));
|
|
419
|
+
try {
|
|
420
|
+
ensureDir(dirname(options.path));
|
|
421
|
+
const driver = await load();
|
|
422
|
+
for (let attempt = 1;; attempt += 1) try {
|
|
423
|
+
const connection = await (await driver.DuckDBInstance.create(options.path)).connect();
|
|
424
|
+
for (const statement of ARCHIVE_SCHEMA) await connection.run(statement);
|
|
425
|
+
archive.#connection = connection;
|
|
426
|
+
archive.#available = true;
|
|
427
|
+
break;
|
|
428
|
+
} catch (error) {
|
|
429
|
+
if (attempt >= 3 || !isLockError(error)) throw error;
|
|
430
|
+
await setTimeout(150);
|
|
431
|
+
}
|
|
432
|
+
} catch (error) {
|
|
433
|
+
archive.#available = false;
|
|
434
|
+
archive.#error = describeOpenError(error, options.path);
|
|
435
|
+
}
|
|
436
|
+
return archive;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* An archive that is off by configuration or could not be opened.
|
|
440
|
+
*
|
|
441
|
+
* Every method degrades to a no-op, so callers can use one code path for
|
|
442
|
+
* "no DuckDB on this machine" and "the user asked for no archive".
|
|
443
|
+
*/
|
|
444
|
+
static unavailable(path, error = null) {
|
|
445
|
+
const archive = new LogArchive(path);
|
|
446
|
+
archive.#available = false;
|
|
447
|
+
archive.#error = error;
|
|
448
|
+
return archive;
|
|
449
|
+
}
|
|
450
|
+
/** True when the archive can be read and written. */
|
|
451
|
+
get available() {
|
|
452
|
+
return this.#available;
|
|
453
|
+
}
|
|
454
|
+
/** Why the archive is unavailable, or the last failure, or `null`. */
|
|
455
|
+
get error() {
|
|
456
|
+
return this.#error;
|
|
457
|
+
}
|
|
458
|
+
/** Runs one task after every task queued before it. */
|
|
459
|
+
#enqueue(task) {
|
|
460
|
+
const next = this.#queue.then(task, task);
|
|
461
|
+
this.#queue = next.then(() => void 0, () => void 0);
|
|
462
|
+
return next;
|
|
463
|
+
}
|
|
464
|
+
/** Runs a statement, returning the failure instead of throwing. */
|
|
465
|
+
async #guard(fallback, task) {
|
|
466
|
+
if (this.#connection === null) return fallback;
|
|
467
|
+
return this.#enqueue(async () => {
|
|
468
|
+
try {
|
|
469
|
+
return await task();
|
|
470
|
+
} catch (error) {
|
|
471
|
+
this.#error = error instanceof Error ? error.message : String(error);
|
|
472
|
+
return fallback;
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Writes one batch of streamed events.
|
|
478
|
+
*
|
|
479
|
+
* Batches are split into chunks of {@link ARCHIVE_INSERT_CHUNK} rows, and
|
|
480
|
+
* `INSERT OR IGNORE` plus the unique index make a repeated scan idempotent.
|
|
481
|
+
* Failures never propagate: a full disk must not interrupt a log stream.
|
|
482
|
+
*/
|
|
483
|
+
async record(region, logGroup, events) {
|
|
484
|
+
if (events.length === 0) return 0;
|
|
485
|
+
return this.#guard(0, async () => {
|
|
486
|
+
const connection = this.#connection;
|
|
487
|
+
if (connection === null) return 0;
|
|
488
|
+
let written = 0;
|
|
489
|
+
for (let start = 0; start < events.length; start += 500) {
|
|
490
|
+
const chunk = events.slice(start, start + 500);
|
|
491
|
+
await connection.run(buildInsertSql(chunk.length), toArchiveParams(region, logGroup, chunk));
|
|
492
|
+
written += chunk.length;
|
|
493
|
+
}
|
|
494
|
+
return written;
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
/** Reads one page of archived events. */
|
|
498
|
+
async page(request) {
|
|
499
|
+
const empty = {
|
|
500
|
+
events: [],
|
|
501
|
+
last: null
|
|
502
|
+
};
|
|
503
|
+
return this.#guard(empty, async () => {
|
|
504
|
+
const connection = this.#connection;
|
|
505
|
+
if (connection === null) return empty;
|
|
506
|
+
const { sql, params } = buildPageQuery(request);
|
|
507
|
+
return rowsToPage((await connection.runAndReadAll(sql, params)).getRowObjects());
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
/** Bucketed event counts for the chart, per group and level. */
|
|
511
|
+
async seriesQuery(request) {
|
|
512
|
+
return this.#guard([], async () => {
|
|
513
|
+
const connection = this.#connection;
|
|
514
|
+
if (connection === null) return [];
|
|
515
|
+
const { sql, params } = buildSeriesQuery(request);
|
|
516
|
+
return rowsToSeries((await connection.runAndReadAll(sql, params)).getRowObjects());
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
/** Aggregate row count and time bounds. */
|
|
520
|
+
async totals() {
|
|
521
|
+
return this.#guard(rowToTotals(void 0), async () => {
|
|
522
|
+
const connection = this.#connection;
|
|
523
|
+
if (connection === null) return rowToTotals(void 0);
|
|
524
|
+
return rowToTotals((await connection.runAndReadAll(ARCHIVE_TOTALS_SQL)).getRowObjects()[0]);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
/** Log groups held by the archive, optionally limited to one region. */
|
|
528
|
+
async groups(region = null) {
|
|
529
|
+
return this.#guard([], async () => {
|
|
530
|
+
const connection = this.#connection;
|
|
531
|
+
if (connection === null) return [];
|
|
532
|
+
const { sql, params } = buildGroupsQuery(region);
|
|
533
|
+
return rowsToGroups((await connection.runAndReadAll(sql, params)).getRowObjects());
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
/** Status for `GET /api/archive`, including the file size on disk. */
|
|
537
|
+
async status() {
|
|
538
|
+
const totals = await this.totals();
|
|
539
|
+
let bytes = null;
|
|
540
|
+
if (this.#available) try {
|
|
541
|
+
bytes = statSync(this.path).size;
|
|
542
|
+
} catch {
|
|
543
|
+
bytes = null;
|
|
544
|
+
}
|
|
545
|
+
return {
|
|
546
|
+
path: this.path,
|
|
547
|
+
available: this.#available,
|
|
548
|
+
error: this.#error,
|
|
549
|
+
bytes,
|
|
550
|
+
totals
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
/** Closes the connection. Safe to call twice. */
|
|
554
|
+
async close() {
|
|
555
|
+
const connection = this.#connection;
|
|
556
|
+
this.#connection = null;
|
|
557
|
+
this.#available = false;
|
|
558
|
+
if (connection?.closeSync === void 0) return;
|
|
559
|
+
await this.#enqueue(async () => {
|
|
560
|
+
connection.closeSync?.();
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
/** The archive for the running server, opened once per process. */
|
|
565
|
+
var sharedArchive = null;
|
|
566
|
+
/**
|
|
567
|
+
* Returns the process-wide archive for `env`, opening it on first use.
|
|
568
|
+
*
|
|
569
|
+
* The same file is never opened twice per process; a disabled archive
|
|
570
|
+
* (`WATCH_STREAM_ARCHIVE=off`) is remembered so no driver import is attempted.
|
|
571
|
+
*/
|
|
572
|
+
function getArchive(env, load) {
|
|
573
|
+
if (sharedArchive === null) {
|
|
574
|
+
const config = resolveArchiveConfig(env);
|
|
575
|
+
sharedArchive = config.enabled ? LogArchive.open({
|
|
576
|
+
path: config.path,
|
|
577
|
+
...{}
|
|
578
|
+
}) : Promise.resolve(LogArchive.unavailable(config.path));
|
|
579
|
+
}
|
|
580
|
+
return sharedArchive;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export { getArchive as g };
|
|
584
|
+
//# sourceMappingURL=archive.js-C6rz09rJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js-C6rz09rJ.js","sources":["../../../../.svelte-kit/output/server/chunks/archive.js"],"sourcesContent":["import { i as detectLevelWithSource, l as isLogLevel } from \"./log-buffer.js\";\nimport { mkdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { setTimeout } from \"node:timers/promises\";\nimport { createHash } from \"node:crypto\";\n//#region src/lib/server/archive-sql.ts\n/**\n* SQL and row mapping for the local DuckDB archive.\n*\n* DuckDB is a native dependency and is loaded lazily by `archive.ts`; everything\n* in this file is plain text and pure functions so the archive can be unit\n* tested without the driver. Column order matters: {@link ARCHIVE_INSERT_COLUMNS}\n* is the contract with {@link toArchiveParams}, and the `SELECT` in\n* {@link buildPageQuery} uses the same names as {@link rowsToPage}.\n*/\n/**\n* Statements that bring a database file up to the current schema.\n*\n* Every statement is idempotent so an existing archive can be opened by a newer\n* build without a migration step. `seq` orders events by arrival, which keeps\n* paging stable when many events share a millisecond timestamp.\n*/\nvar ARCHIVE_SCHEMA = [\n\t`CREATE SEQUENCE IF NOT EXISTS log_events_seq`,\n\t`CREATE TABLE IF NOT EXISTS log_events (\n\t\tregion VARCHAR NOT NULL,\n\t\tlog_group VARCHAR NOT NULL,\n\t\tlog_stream VARCHAR,\n\t\tevent_key VARCHAR NOT NULL,\n\t\tevent_id VARCHAR,\n\t\ttimestamp_ms BIGINT NOT NULL,\n\t\tingestion_time_ms BIGINT,\n\t\tmessage VARCHAR NOT NULL,\n\t\tlevel VARCHAR,\n\t\tlevel_source VARCHAR,\n\t\tseq BIGINT NOT NULL DEFAULT nextval('log_events_seq'),\n\t\tarchived_at TIMESTAMP NOT NULL DEFAULT now()\n\t)`,\n\t`ALTER TABLE log_events ADD COLUMN IF NOT EXISTS level VARCHAR`,\n\t`ALTER TABLE log_events ADD COLUMN IF NOT EXISTS level_source VARCHAR`,\n\t`CREATE UNIQUE INDEX IF NOT EXISTS log_events_unique ON log_events (region, log_group, event_key)`,\n\t`CREATE INDEX IF NOT EXISTS log_events_time ON log_events (region, log_group, timestamp_ms)`\n];\n/** Columns written by {@link buildInsertSql}, in binding order. */\nvar ARCHIVE_INSERT_COLUMNS = [\n\t\"region\",\n\t\"log_group\",\n\t\"log_stream\",\n\t\"event_key\",\n\t\"event_id\",\n\t\"timestamp_ms\",\n\t\"ingestion_time_ms\",\n\t\"message\",\n\t\"level\",\n\t\"level_source\"\n];\n/** Escape character used with `LIKE`/`ILIKE` so user input cannot inject wildcards. */\nvar LIKE_ESCAPE = \"\\\\\";\n/**\n* Stable identity of an event inside one log group.\n*\n* CloudWatch event ids are unique per log group and are reused as the key;\n* events without an id (floci and LocalStack omit them) get a deterministic\n* hash of timestamp, stream and message, so re-scanning the same window is\n* idempotent instead of duplicating rows.\n*/\nfunction archiveEventKey(event) {\n\tif (event.id !== null && event.id.length > 0) return event.id;\n\treturn `h:${createHash(\"sha256\").update(`${event.timestamp}\\u0000${event.streamName ?? \"\"}\\u0000${event.message}`).digest(\"hex\").slice(0, 32)}`;\n}\n/** Renders `count` placeholder rows of ten columns each. */\nfunction placeholderRows(count) {\n\tconst row = `(${ARCHIVE_INSERT_COLUMNS.map(() => \"?\").join(\", \")})`;\n\treturn Array.from({ length: count }, () => row).join(\", \");\n}\n/**\n* Builds a multi-row `INSERT OR IGNORE`, so events already archived are skipped\n* by the unique index instead of raising.\n*/\nfunction buildInsertSql(rowCount) {\n\tif (!Number.isInteger(rowCount) || rowCount < 1) throw new RangeError(`rowCount must be a positive integer, received ${String(rowCount)}`);\n\treturn `INSERT OR IGNORE INTO log_events (${ARCHIVE_INSERT_COLUMNS.join(\", \")}) VALUES ${placeholderRows(rowCount)}`;\n}\n/** Flattens events into the parameter list {@link buildInsertSql} expects. */\nfunction toArchiveParams(region, logGroup, events) {\n\tconst params = [];\n\tfor (const event of events) {\n\t\tconst detected = detectLevelWithSource(event.message);\n\t\tparams.push(region, logGroup, event.streamName ?? null, archiveEventKey(event), event.id ?? null, BigInt(Math.round(event.timestamp)), event.ingestionTime === void 0 ? null : BigInt(Math.round(event.ingestionTime)), event.message, detected.level, detected.source);\n\t}\n\treturn params;\n}\n/** Column list shared by {@link buildPageQuery} and {@link rowsToPage}. */\nvar PAGE_COLUMNS = `region, log_group, log_stream, event_key, event_id, timestamp_ms, ingestion_time_ms, message, level, level_source, seq`;\n/** Escapes `LIKE` metacharacters so a search term is matched literally. */\nfunction escapeLike(value) {\n\treturn value.replace(/[\\\\%_]/g, (match) => `${LIKE_ESCAPE}${match}`);\n}\n/**\n* Builds one keyset page of archived events.\n*\n* Ordering is `(timestamp_ms, seq)`, and the cursor compares the same tuple, so\n* pages never repeat or skip a row even when thousands of events share a\n* timestamp.\n*/\nfunction buildPageQuery(request) {\n\tconst limit = Math.max(1, Math.round(request.limit));\n\tconst groups = request.logGroups.length > 0 ? request.logGroups : [\"\"];\n\tconst where = [\n\t\t\"region = ?\",\n\t\t`log_group IN (${groups.map(() => \"?\").join(\", \")})`,\n\t\t\"timestamp_ms >= ?\",\n\t\t\"timestamp_ms <= ?\"\n\t];\n\tconst params = [\n\t\trequest.region,\n\t\t...groups,\n\t\tBigInt(Math.round(request.startTime)),\n\t\tBigInt(Math.round(request.endTime))\n\t];\n\tconst search = request.search?.trim() ?? \"\";\n\tif (search.length > 0) {\n\t\twhere.push(`message ILIKE ? ESCAPE '${LIKE_ESCAPE}'`);\n\t\tparams.push(`%${escapeLike(search)}%`);\n\t}\n\tconst prefix = request.streamPrefix?.trim() ?? \"\";\n\tif (prefix.length > 0) {\n\t\twhere.push(`log_stream LIKE ? ESCAPE '${LIKE_ESCAPE}'`);\n\t\tparams.push(`${escapeLike(prefix)}%`);\n\t}\n\tconst levels = request.levels ?? [];\n\tif (levels.length > 0) {\n\t\twhere.push(`level IN (${levels.map(() => \"?\").join(\", \")})`);\n\t\tparams.push(...levels);\n\t}\n\tconst after = request.after ?? null;\n\tif (after !== null) {\n\t\twhere.push(\"(timestamp_ms > ? OR (timestamp_ms = ? AND seq > ?))\");\n\t\tparams.push(BigInt(Math.round(after.timestamp)), BigInt(Math.round(after.timestamp)), BigInt(Math.round(after.seq)));\n\t}\n\tparams.push(BigInt(limit));\n\treturn {\n\t\tsql: `SELECT ${PAGE_COLUMNS} FROM log_events WHERE ${where.join(\" AND \")} ORDER BY timestamp_ms, seq LIMIT ?`,\n\t\tparams\n\t};\n}\n/** Converts a DuckDB value (which may be a bigint) into a JS number. */\nfunction toNumber(value) {\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (typeof value === \"bigint\") return Number(value);\n\tif (typeof value === \"string\" && value.trim().length > 0) {\n\t\tconst parsed = Number(value);\n\t\treturn Number.isFinite(parsed) ? parsed : null;\n\t}\n\treturn null;\n}\n/** Converts a nullable DuckDB string column into `string` or `null`. */\nfunction toNullableString(value) {\n\tif (typeof value === \"string\") return value.length > 0 ? value : null;\n\treturn null;\n}\n/** Reads one column from a row object, tolerating case differences. */\nfunction pick(row, column) {\n\tif (column in row) return row[column];\n\tconst upper = column.toUpperCase();\n\tif (upper in row) return row[upper];\n}\n/**\n* Maps query rows onto wire events plus the cursor of the last row.\n*\n* Rows without a usable timestamp are dropped rather than rendered as 1970.\n*/\nfunction rowsToPage(rows) {\n\tconst events = [];\n\tlet last = null;\n\tfor (const row of rows) {\n\t\tconst timestamp = toNumber(pick(row, \"timestamp_ms\"));\n\t\tconst seq = toNumber(pick(row, \"seq\"));\n\t\tif (timestamp === null || seq === null) continue;\n\t\tconst rawLevel = pick(row, \"level\");\n\t\tconst group = toNullableString(pick(row, \"log_group\"));\n\t\tconst event = {\n\t\t\tid: toNullableString(pick(row, \"event_key\")),\n\t\t\ttimestamp,\n\t\t\tmessage: typeof pick(row, \"message\") === \"string\" ? pick(row, \"message\") : \"\",\n\t\t\tlevel: isLogLevel(rawLevel) ? rawLevel : null\n\t\t};\n\t\tif (group !== null) event.group = group;\n\t\tconst streamName = toNullableString(pick(row, \"log_stream\"));\n\t\tif (streamName !== null) event.streamName = streamName;\n\t\tconst ingestionTime = toNumber(pick(row, \"ingestion_time_ms\"));\n\t\tif (ingestionTime !== null) event.ingestionTime = ingestionTime;\n\t\tevents.push(event);\n\t\tlast = {\n\t\t\ttimestamp,\n\t\t\tseq\n\t\t};\n\t}\n\treturn {\n\t\tevents,\n\t\tlast\n\t};\n}\n/** Aggregate query behind {@link ArchiveTotals}. */\nvar ARCHIVE_TOTALS_SQL = `SELECT count(*) AS rows, count(DISTINCT log_group) AS groups, count(DISTINCT region) AS regions, min(timestamp_ms) AS oldest, max(timestamp_ms) AS newest FROM log_events`;\n/** Log groups held by the archive, optionally limited to one region. */\nfunction buildGroupsQuery(region) {\n\tconst where = region === null || region.length === 0 ? \"\" : \"WHERE region = ?\";\n\treturn {\n\t\tsql: `SELECT region, log_group, count(*) AS events, min(timestamp_ms) AS oldest, max(timestamp_ms) AS newest FROM log_events ${where} GROUP BY region, log_group ORDER BY region, log_group`,\n\t\tparams: where === \"\" ? [] : [region]\n\t};\n}\n/** Maps the single row of {@link ARCHIVE_TOTALS_SQL}. */\nfunction rowToTotals(row) {\n\tif (row === void 0) return {\n\t\trows: 0,\n\t\tgroups: 0,\n\t\tregions: 0,\n\t\toldest: null,\n\t\tnewest: null\n\t};\n\treturn {\n\t\trows: toNumber(pick(row, \"rows\")) ?? 0,\n\t\tgroups: toNumber(pick(row, \"groups\")) ?? 0,\n\t\tregions: toNumber(pick(row, \"regions\")) ?? 0,\n\t\toldest: toNumber(pick(row, \"oldest\")),\n\t\tnewest: toNumber(pick(row, \"newest\"))\n\t};\n}\n/** Maps the rows of {@link buildGroupsQuery}. */\nfunction rowsToGroups(rows) {\n\tconst groups = [];\n\tfor (const row of rows) {\n\t\tconst region = pick(row, \"region\");\n\t\tconst logGroup = pick(row, \"log_group\");\n\t\tif (typeof region !== \"string\" || typeof logGroup !== \"string\") continue;\n\t\tgroups.push({\n\t\t\tregion,\n\t\t\tlogGroup,\n\t\t\tevents: toNumber(pick(row, \"events\")) ?? 0,\n\t\t\toldest: toNumber(pick(row, \"oldest\")),\n\t\t\tnewest: toNumber(pick(row, \"newest\"))\n\t\t});\n\t}\n\treturn groups;\n}\n/**\n* Builds the bucketed counts behind the chart.\n*\n* One statement returns every series. The bucket is plain integer arithmetic on\n* `timestamp_ms`, so it cannot drift with a time zone; NULL levels are reported\n* as `unknown` rather than dropped; and a level filter matches only rows that\n* carry one of the requested levels.\n*/\nfunction buildSeriesQuery(request) {\n\tconst bucketMs = Math.max(1, Math.round(request.bucketMs));\n\tconst groups = request.logGroups.length > 0 ? request.logGroups : [\"\"];\n\tconst where = [\n\t\t\"region = ?\",\n\t\t`log_group IN (${groups.map(() => \"?\").join(\", \")})`,\n\t\t\"timestamp_ms >= ?\",\n\t\t\"timestamp_ms <= ?\"\n\t];\n\tconst params = [\n\t\tBigInt(bucketMs),\n\t\tBigInt(bucketMs),\n\t\trequest.region,\n\t\t...groups,\n\t\tBigInt(Math.round(request.startTime)),\n\t\tBigInt(Math.round(request.endTime))\n\t];\n\tconst levels = request.levels ?? [];\n\tif (levels.length > 0) {\n\t\twhere.push(`level IN (${levels.map(() => \"?\").join(\", \")})`);\n\t\tparams.push(...levels);\n\t}\n\treturn {\n\t\tsql: `SELECT CAST(floor(timestamp_ms / ?) * ? AS BIGINT) AS bucket, log_group, coalesce(level, 'unknown') AS level, count(*) AS events FROM log_events WHERE ${where.join(\" AND \")} GROUP BY bucket, log_group, level ORDER BY bucket, log_group, level`,\n\t\tparams\n\t};\n}\n/** Maps the rows of {@link buildSeriesQuery} onto chart points. */\nfunction rowsToSeries(rows) {\n\tconst points = [];\n\tfor (const row of rows) {\n\t\tconst t = toNumber(pick(row, \"bucket\"));\n\t\tconst group = pick(row, \"log_group\");\n\t\tconst level = pick(row, \"level\");\n\t\tif (t === null || typeof group !== \"string\") continue;\n\t\tpoints.push({\n\t\t\tt,\n\t\t\tgroup,\n\t\t\tlevel: typeof level === \"string\" && level.length > 0 ? level : \"unknown\",\n\t\t\tevents: toNumber(pick(row, \"events\")) ?? 0\n\t\t});\n\t}\n\treturn points;\n}\n//#endregion\n//#region src/lib/server/archive.ts\n/**\n* Local DuckDB archive of the events the app has streamed.\n*\n* The driver (`@duckdb/node-api` plus its per-platform native binding) is an\n* optional dependency: it is imported lazily, on the first request that needs\n* it, and every failure is turned into an unavailable archive instead of an\n* error. The rest of the app therefore works unchanged on platforms where the\n* binding is missing.\n*\n* One process owns the file: DuckDB allows a single writer, and the SvelteKit\n* server is that writer. Statements are serialised through an internal queue so\n* a stream writing while another request reads cannot interleave on the\n* connection.\n*/\n/** Package name of the optional DuckDB driver. */\nvar DUCKDB_MODULE = \"@duckdb/node-api\";\n/** Directory name used under the platform data directory. */\nvar ARCHIVE_DIR_NAME = \"watch-tail\";\n/** File name of the archive inside {@link ARCHIVE_DIR_NAME}. */\nvar ARCHIVE_FILE_NAME = \"archive.duckdb\";\n/**\n* Imports the optional DuckDB driver.\n*\n* The specifier is held in a variable on purpose: bundlers must leave the\n* import alone so Node resolves it at run time, where a missing binding can be\n* reported as an unavailable archive rather than a build error.\n*/\nasync function loadDuckDbDriver() {\n\tconst loaded = await import(DUCKDB_MODULE);\n\tif (typeof loaded.DuckDBInstance?.create !== \"function\") throw new Error(`${DUCKDB_MODULE} did not expose DuckDBInstance.create`);\n\treturn loaded;\n}\nvar DISABLED_VALUES = /* @__PURE__ */ new Set([\n\t\"0\",\n\t\"false\",\n\t\"no\",\n\t\"off\"\n]);\n/** True when an environment value means \"off\". */\nfunction isDisabled(value) {\n\treturn value !== void 0 && DISABLED_VALUES.has(value.trim().toLowerCase());\n}\n/**\n* True when this process is a test runner.\n*\n* Vitest sets `VITEST`, and `NODE_ENV=test` covers other harnesses. Tests must\n* not append to the archive of the machine they run on, so the archive is off\n* unless a test asks for it through `WATCH_STREAM_ARCHIVE_DB` or\n* `WATCH_STREAM_ARCHIVE=on`.\n*/\nfunction isTestProcess(env) {\n\treturn env.VITEST !== void 0 || env.NODE_ENV === \"test\";\n}\n/**\n* Resolves the archive file path.\n*\n* `WATCH_STREAM_ARCHIVE_DB` wins; otherwise the file lives in the platform's\n* data directory (`XDG_DATA_HOME`, `%LOCALAPPDATA%` or\n* `~/Library/Application Support`), never in the current directory, so history\n* survives running the CLI from a different folder.\n*/\nfunction resolveArchiveConfig(env, platform = process.platform, home = homedir()) {\n\tconst path = env.WATCH_STREAM_ARCHIVE_DB?.trim() ?? \"\";\n\tconst dataDir = env.XDG_DATA_HOME?.trim() ?? (platform === \"darwin\" ? join(home, \"Library\", \"Application Support\") : platform === \"win32\" ? env.LOCALAPPDATA?.trim() ?? join(home, \"AppData\", \"Local\") : join(home, \".local\", \"share\"));\n\tconst requested = env.WATCH_STREAM_ARCHIVE?.trim() ?? \"\";\n\treturn {\n\t\tenabled: isDisabled(requested) ? false : path.length > 0 || requested.length > 0 ? true : !isTestProcess(env),\n\t\tpath: path.length > 0 ? path : join(dataDir, ARCHIVE_DIR_NAME, ARCHIVE_FILE_NAME)\n\t};\n}\n/**\n* A short, non-throwing description of an unknown failure.\n*\n* A conflicting lock is the one failure a user can act on, and DuckDB's own\n* message buries the reason in a pid and a documentation link, so it is\n* reported as what it means for this app.\n*/\nfunction describeOpenError(error, path) {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tif (/Could not set lock|Conflicting lock/i.test(message)) return `the archive file ${path} is locked by another process (another watch-tail is using it); use --db to keep a separate file`;\n\treturn message;\n}\n/** True when the failure is the exclusive file lock. */\nfunction isLockError(error) {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn /Could not set lock|Conflicting lock/i.test(message);\n}\n/**\n* One DuckDB file holding every event the app has streamed.\n*\n* `open` never throws: a missing driver, a locked file or a corrupt database all\n* produce an instance with `available === false` and the reason on `error`. The\n* read and write methods then behave as no-ops, so callers never have to guard\n* their happy path.\n*/\nvar LogArchive = class LogArchive {\n\t/** Database file this archive uses. */\n\tpath;\n\t#connection = null;\n\t#available = false;\n\t#error = null;\n\t#queue = Promise.resolve();\n\tconstructor(path) {\n\t\tthis.path = path;\n\t}\n\t/**\n\t* Opens (and creates) the archive.\n\t*\n\t* Statements are executed in order: the sequence first, then the table, then\n\t* the indexes, so an existing file from an older build is upgraded in place.\n\t*/\n\tstatic async open(options) {\n\t\tconst archive = new LogArchive(options.path);\n\t\tconst load = options.load ?? loadDuckDbDriver;\n\t\tconst ensureDir = options.ensureDir ?? ((dir) => mkdirSync(dir, { recursive: true }));\n\t\ttry {\n\t\t\tensureDir(dirname(options.path));\n\t\t\tconst driver = await load();\n\t\t\tfor (let attempt = 1;; attempt += 1) try {\n\t\t\t\tconst connection = await (await driver.DuckDBInstance.create(options.path)).connect();\n\t\t\t\tfor (const statement of ARCHIVE_SCHEMA) await connection.run(statement);\n\t\t\t\tarchive.#connection = connection;\n\t\t\t\tarchive.#available = true;\n\t\t\t\tbreak;\n\t\t\t} catch (error) {\n\t\t\t\tif (attempt >= 3 || !isLockError(error)) throw error;\n\t\t\t\tawait setTimeout(150);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tarchive.#available = false;\n\t\t\tarchive.#error = describeOpenError(error, options.path);\n\t\t}\n\t\treturn archive;\n\t}\n\t/**\n\t* An archive that is off by configuration or could not be opened.\n\t*\n\t* Every method degrades to a no-op, so callers can use one code path for\n\t* \"no DuckDB on this machine\" and \"the user asked for no archive\".\n\t*/\n\tstatic unavailable(path, error = null) {\n\t\tconst archive = new LogArchive(path);\n\t\tarchive.#available = false;\n\t\tarchive.#error = error;\n\t\treturn archive;\n\t}\n\t/** True when the archive can be read and written. */\n\tget available() {\n\t\treturn this.#available;\n\t}\n\t/** Why the archive is unavailable, or the last failure, or `null`. */\n\tget error() {\n\t\treturn this.#error;\n\t}\n\t/** Runs one task after every task queued before it. */\n\t#enqueue(task) {\n\t\tconst next = this.#queue.then(task, task);\n\t\tthis.#queue = next.then(() => void 0, () => void 0);\n\t\treturn next;\n\t}\n\t/** Runs a statement, returning the failure instead of throwing. */\n\tasync #guard(fallback, task) {\n\t\tif (this.#connection === null) return fallback;\n\t\treturn this.#enqueue(async () => {\n\t\t\ttry {\n\t\t\t\treturn await task();\n\t\t\t} catch (error) {\n\t\t\t\tthis.#error = error instanceof Error ? error.message : String(error);\n\t\t\t\treturn fallback;\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t* Writes one batch of streamed events.\n\t*\n\t* Batches are split into chunks of {@link ARCHIVE_INSERT_CHUNK} rows, and\n\t* `INSERT OR IGNORE` plus the unique index make a repeated scan idempotent.\n\t* Failures never propagate: a full disk must not interrupt a log stream.\n\t*/\n\tasync record(region, logGroup, events) {\n\t\tif (events.length === 0) return 0;\n\t\treturn this.#guard(0, async () => {\n\t\t\tconst connection = this.#connection;\n\t\t\tif (connection === null) return 0;\n\t\t\tlet written = 0;\n\t\t\tfor (let start = 0; start < events.length; start += 500) {\n\t\t\t\tconst chunk = events.slice(start, start + 500);\n\t\t\t\tawait connection.run(buildInsertSql(chunk.length), toArchiveParams(region, logGroup, chunk));\n\t\t\t\twritten += chunk.length;\n\t\t\t}\n\t\t\treturn written;\n\t\t});\n\t}\n\t/** Reads one page of archived events. */\n\tasync page(request) {\n\t\tconst empty = {\n\t\t\tevents: [],\n\t\t\tlast: null\n\t\t};\n\t\treturn this.#guard(empty, async () => {\n\t\t\tconst connection = this.#connection;\n\t\t\tif (connection === null) return empty;\n\t\t\tconst { sql, params } = buildPageQuery(request);\n\t\t\treturn rowsToPage((await connection.runAndReadAll(sql, params)).getRowObjects());\n\t\t});\n\t}\n\t/** Bucketed event counts for the chart, per group and level. */\n\tasync seriesQuery(request) {\n\t\treturn this.#guard([], async () => {\n\t\t\tconst connection = this.#connection;\n\t\t\tif (connection === null) return [];\n\t\t\tconst { sql, params } = buildSeriesQuery(request);\n\t\t\treturn rowsToSeries((await connection.runAndReadAll(sql, params)).getRowObjects());\n\t\t});\n\t}\n\t/** Aggregate row count and time bounds. */\n\tasync totals() {\n\t\treturn this.#guard(rowToTotals(void 0), async () => {\n\t\t\tconst connection = this.#connection;\n\t\t\tif (connection === null) return rowToTotals(void 0);\n\t\t\treturn rowToTotals((await connection.runAndReadAll(ARCHIVE_TOTALS_SQL)).getRowObjects()[0]);\n\t\t});\n\t}\n\t/** Log groups held by the archive, optionally limited to one region. */\n\tasync groups(region = null) {\n\t\treturn this.#guard([], async () => {\n\t\t\tconst connection = this.#connection;\n\t\t\tif (connection === null) return [];\n\t\t\tconst { sql, params } = buildGroupsQuery(region);\n\t\t\treturn rowsToGroups((await connection.runAndReadAll(sql, params)).getRowObjects());\n\t\t});\n\t}\n\t/** Status for `GET /api/archive`, including the file size on disk. */\n\tasync status() {\n\t\tconst totals = await this.totals();\n\t\tlet bytes = null;\n\t\tif (this.#available) try {\n\t\t\tbytes = statSync(this.path).size;\n\t\t} catch {\n\t\t\tbytes = null;\n\t\t}\n\t\treturn {\n\t\t\tpath: this.path,\n\t\t\tavailable: this.#available,\n\t\t\terror: this.#error,\n\t\t\tbytes,\n\t\t\ttotals\n\t\t};\n\t}\n\t/** Closes the connection. Safe to call twice. */\n\tasync close() {\n\t\tconst connection = this.#connection;\n\t\tthis.#connection = null;\n\t\tthis.#available = false;\n\t\tif (connection?.closeSync === void 0) return;\n\t\tawait this.#enqueue(async () => {\n\t\t\tconnection.closeSync?.();\n\t\t});\n\t}\n};\n/** The archive for the running server, opened once per process. */\nvar sharedArchive = null;\n/**\n* Returns the process-wide archive for `env`, opening it on first use.\n*\n* The same file is never opened twice per process; a disabled archive\n* (`WATCH_STREAM_ARCHIVE=off`) is remembered so no driver import is attempted.\n*/\nfunction getArchive(env, load) {\n\tif (sharedArchive === null) {\n\t\tconst config = resolveArchiveConfig(env);\n\t\tsharedArchive = config.enabled ? LogArchive.open({\n\t\t\tpath: config.path,\n\t\t\t...load === void 0 ? {} : { load }\n\t\t}) : Promise.resolve(LogArchive.unavailable(config.path));\n\t}\n\treturn sharedArchive;\n}\n//#endregion\nexport { getArchive as t };\n"],"names":[],"mappings":";;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,cAAc,GAAG;AACrB,CAAC,CAAC,4CAA4C,CAAC;AAC/C,CAAC,CAAC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,CAAC;AACH,CAAC,CAAC,6DAA6D,CAAC;AAChE,CAAC,CAAC,oEAAoE,CAAC;AACvE,CAAC,CAAC,gGAAgG,CAAC;AACnG,CAAC,CAAC,0FAA0F;AAC5F,CAAC;AACD;AACA,IAAI,sBAAsB,GAAG;AAC7B,CAAC,QAAQ;AACT,CAAC,WAAW;AACZ,CAAC,YAAY;AACb,CAAC,WAAW;AACZ,CAAC,UAAU;AACX,CAAC,cAAc;AACf,CAAC,mBAAmB;AACpB,CAAC,SAAS;AACV,CAAC,OAAO;AACR,CAAC;AACD,CAAC;AACD;AACA,IAAI,WAAW,GAAG,IAAI;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,KAAK,EAAE;AAChC,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,KAAK,CAAC,EAAE;AAC9D,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAChJ;AACA;AACA,SAAS,eAAe,CAAC,KAAK,EAAE;AAChC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AAC3D;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,QAAQ,EAAE;AAClC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,MAAM,IAAI,UAAU,CAAC,CAAC,8CAA8C,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3I,CAAC,OAAO,CAAC,kCAAkC,EAAE,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;AACrH;AACA;AACA,SAAS,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;AACnD,CAAC,MAAM,MAAM,GAAG,EAAE;AAClB,CAAC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC7B,EAAE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC;AACvD,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;AACzQ,CAAC;AACD,CAAC,OAAO,MAAM;AACd;AACA;AACA,IAAI,YAAY,GAAG,CAAC,sHAAsH,CAAC;AAC3I;AACA,SAAS,UAAU,CAAC,KAAK,EAAE;AAC3B,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,KAAK,CAAC,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,OAAO,EAAE;AACjC,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;AACvE,CAAC,MAAM,KAAK,GAAG;AACf,EAAE,YAAY;AACd,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,EAAE,mBAAmB;AACrB,EAAE;AACF,EAAE;AACF,CAAC,MAAM,MAAM,GAAG;AAChB,EAAE,OAAO,CAAC,MAAM;AAChB,EAAE,GAAG,MAAM;AACX,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACvC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;AACpC,EAAE;AACF,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;AAC5C,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,wBAAwB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC;AACD,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE;AAClD,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,0BAA0B,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AACzD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AACD,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE;AACpC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACxB,CAAC;AACD,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI;AACpC,CAAC,IAAI,KAAK,KAAK,IAAI,EAAE;AACrB,EAAE,KAAK,CAAC,IAAI,CAAC,sDAAsD,CAAC;AACpE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACtH,CAAC;AACD,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC,OAAO;AACR,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,uBAAuB,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,mCAAmC,CAAC;AAC/G,EAAE;AACF,EAAE;AACF;AACA;AACA,SAAS,QAAQ,CAAC,KAAK,EAAE;AACzB,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI;AAC5E,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,MAAM,CAAC,KAAK,CAAC;AACpD,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;AAC3D,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AAC9B,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI;AAChD,CAAC;AACD,CAAC,OAAO,IAAI;AACZ;AACA;AACA,SAAS,gBAAgB,CAAC,KAAK,EAAE;AACjC,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI;AACtE,CAAC,OAAO,IAAI;AACZ;AACA;AACA,SAAS,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE;AAC3B,CAAC,IAAI,MAAM,IAAI,GAAG,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC;AACtC,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE;AACnC,CAAC,IAAI,KAAK,IAAI,GAAG,EAAE,OAAO,GAAG,CAAC,KAAK,CAAC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,IAAI,EAAE;AAC1B,CAAC,MAAM,MAAM,GAAG,EAAE;AAClB,CAAC,IAAI,IAAI,GAAG,IAAI;AAChB,CAAC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACzB,EAAE,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AACvD,EAAE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACxC,EAAE,IAAI,SAAS,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;AAC1C,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;AACrC,EAAE,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AACxD,EAAE,MAAM,KAAK,GAAG;AAChB,GAAG,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AAC/C,GAAG,SAAS;AACZ,GAAG,OAAO,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE;AAChF,GAAG,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG;AAC5C,GAAG;AACH,EAAE,IAAI,KAAK,KAAK,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK;AACzC,EAAE,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC9D,EAAE,IAAI,UAAU,KAAK,IAAI,EAAE,KAAK,CAAC,UAAU,GAAG,UAAU;AACxD,EAAE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;AAChE,EAAE,IAAI,aAAa,KAAK,IAAI,EAAE,KAAK,CAAC,aAAa,GAAG,aAAa;AACjE,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACpB,EAAE,IAAI,GAAG;AACT,GAAG,SAAS;AACZ,GAAG;AACH,GAAG;AACH,CAAC;AACD,CAAC,OAAO;AACR,EAAE,MAAM;AACR,EAAE;AACF,EAAE;AACF;AACA;AACA,IAAI,kBAAkB,GAAG,CAAC,yKAAyK,CAAC;AACpM;AACA,SAAS,gBAAgB,CAAC,MAAM,EAAE;AAClC,CAAC,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,GAAG,kBAAkB;AAC/E,CAAC,OAAO;AACR,EAAE,GAAG,EAAE,CAAC,uHAAuH,EAAE,KAAK,CAAC,sDAAsD,CAAC;AAC9L,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM;AACrC,EAAE;AACF;AACA;AACA,SAAS,WAAW,CAAC,GAAG,EAAE;AAC1B,CAAC,IAAI,GAAG,KAAK,MAAM,EAAE,OAAO;AAC5B,EAAE,IAAI,EAAE,CAAC;AACT,EAAE,MAAM,EAAE,CAAC;AACX,EAAE,OAAO,EAAE,CAAC;AACZ,EAAE,MAAM,EAAE,IAAI;AACd,EAAE,MAAM,EAAE;AACV,EAAE;AACF,CAAC,OAAO;AACR,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;AACxC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC;AAC5C,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC;AAC9C,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACvC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC;AACtC,EAAE;AACF;AACA;AACA,SAAS,YAAY,CAAC,IAAI,EAAE;AAC5B,CAAC,MAAM,MAAM,GAAG,EAAE;AAClB,CAAC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACzB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC;AACpC,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC;AACzC,EAAE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;AAClE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,GAAG,MAAM;AACT,GAAG,QAAQ;AACX,GAAG,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC;AAC7C,GAAG,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACxC,GAAG,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC;AACvC,GAAG,CAAC;AACJ,CAAC;AACD,CAAC,OAAO,MAAM;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,OAAO,EAAE;AACnC,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC3D,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;AACvE,CAAC,MAAM,KAAK,GAAG;AACf,EAAE,YAAY;AACd,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,EAAE,mBAAmB;AACrB,EAAE;AACF,EAAE;AACF,CAAC,MAAM,MAAM,GAAG;AAChB,EAAE,MAAM,CAAC,QAAQ,CAAC;AAClB,EAAE,MAAM,CAAC,QAAQ,CAAC;AAClB,EAAE,OAAO,CAAC,MAAM;AAChB,EAAE,GAAG,MAAM;AACX,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACvC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;AACpC,EAAE;AACF,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE;AACpC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AACxB,CAAC;AACD,CAAC,OAAO;AACR,EAAE,GAAG,EAAE,CAAC,uJAAuJ,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,oEAAoE,CAAC;AAC1P,EAAE;AACF,EAAE;AACF;AACA;AACA,SAAS,YAAY,CAAC,IAAI,EAAE;AAC5B,CAAC,MAAM,MAAM,GAAG,EAAE;AAClB,CAAC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACzB,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACzC,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC;AACtC,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;AAClC,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC/C,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,GAAG,CAAC;AACJ,GAAG,KAAK;AACR,GAAG,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS;AAC3E,GAAG,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI;AAC5C,GAAG,CAAC;AACJ,CAAC;AACD,CAAC,OAAO,MAAM;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,aAAa,GAAG,kBAAkB;AACtC;AACA,IAAI,gBAAgB,GAAG,YAAY;AACnC;AACA,IAAI,iBAAiB,GAAG,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB,GAAG;AAClC,CAAC,MAAM,MAAM,GAAG,MAAM,OAAO,aAAa,CAAC;AAC3C,CAAC,IAAI,OAAO,MAAM,CAAC,cAAc,EAAE,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,qCAAqC,CAAC,CAAC;AAClI,CAAC,OAAO,MAAM;AACd;AACA,IAAI,eAAe,mBAAmB,IAAI,GAAG,CAAC;AAC9C,CAAC,GAAG;AACJ,CAAC,OAAO;AACR,CAAC,IAAI;AACL,CAAC;AACD,CAAC,CAAC;AACF;AACA,SAAS,UAAU,CAAC,KAAK,EAAE;AAC3B,CAAC,OAAO,KAAK,KAAK,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,aAAa,CAAC,GAAG,EAAE;AAC5B,CAAC,OAAO,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,EAAE,EAAE;AAClF,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE;AACvD,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,QAAQ,KAAK,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,CAAC,GAAG,QAAQ,KAAK,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACxO,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,IAAI,EAAE;AACzD,CAAC,OAAO;AACR,EAAE,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC;AAC/G,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB;AAClF,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE;AACxC,CAAC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AACvE,CAAC,IAAI,sCAAsC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,gGAAgG,CAAC;AAC5L,CAAC,OAAO,OAAO;AACf;AACA;AACA,SAAS,WAAW,CAAC,KAAK,EAAE;AAC5B,CAAC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AACvE,CAAC,OAAO,sCAAsC,CAAC,IAAI,CAAC,OAAO,CAAC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,UAAU,GAAG,MAAM,UAAU,CAAC;AAClC;AACA,CAAC,IAAI;AACL,CAAC,WAAW,GAAG,IAAI;AACnB,CAAC,UAAU,GAAG,KAAK;AACnB,CAAC,MAAM,GAAG,IAAI;AACd,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE;AAC3B,CAAC,WAAW,CAAC,IAAI,EAAE;AACnB,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI;AAClB,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,aAAa,IAAI,CAAC,OAAO,EAAE;AAC5B,EAAE,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;AAC9C,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,gBAAgB;AAC/C,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACvF,EAAE,IAAI;AACN,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACnC,GAAG,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE;AAC9B,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC,GAAG,OAAO,IAAI,CAAC,EAAE,IAAI;AAC5C,IAAI,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE;AACzF,IAAI,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;AAC3E,IAAI,OAAO,CAAC,WAAW,GAAG,UAAU;AACpC,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI;AAC7B,IAAI;AACJ,GAAG,CAAC,CAAC,OAAO,KAAK,EAAE;AACnB,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK;AACxD,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC;AACzB,GAAG;AACH,EAAE,CAAC,CAAC,OAAO,KAAK,EAAE;AAClB,GAAG,OAAO,CAAC,UAAU,GAAG,KAAK;AAC7B,GAAG,OAAO,CAAC,MAAM,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC;AAC1D,EAAE;AACF,EAAE,OAAO,OAAO;AAChB,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE;AACxC,EAAE,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC;AACtC,EAAE,OAAO,CAAC,UAAU,GAAG,KAAK;AAC5B,EAAE,OAAO,CAAC,MAAM,GAAG,KAAK;AACxB,EAAE,OAAO,OAAO;AAChB,CAAC;AACD;AACA,CAAC,IAAI,SAAS,GAAG;AACjB,EAAE,OAAO,IAAI,CAAC,UAAU;AACxB,CAAC;AACD;AACA,CAAC,IAAI,KAAK,GAAG;AACb,EAAE,OAAO,IAAI,CAAC,MAAM;AACpB,CAAC;AACD;AACA,CAAC,QAAQ,CAAC,IAAI,EAAE;AAChB,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAC3C,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,MAAM,EAAE,MAAM,MAAM,CAAC;AACrD,EAAE,OAAO,IAAI;AACb,CAAC;AACD;AACA,CAAC,MAAM,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE;AAC9B,EAAE,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,OAAO,QAAQ;AAChD,EAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY;AACnC,GAAG,IAAI;AACP,IAAI,OAAO,MAAM,IAAI,EAAE;AACvB,GAAG,CAAC,CAAC,OAAO,KAAK,EAAE;AACnB,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;AACxE,IAAI,OAAO,QAAQ;AACnB,GAAG;AACH,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;AACxC,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC;AACnC,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY;AACpC,GAAG,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACtC,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,OAAO,CAAC;AACpC,GAAG,IAAI,OAAO,GAAG,CAAC;AAClB,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,GAAG,EAAE;AAC5D,IAAI,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC;AAClD,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAChG,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM;AAC3B,GAAG;AACH,GAAG,OAAO,OAAO;AACjB,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE;AACrB,EAAE,MAAM,KAAK,GAAG;AAChB,GAAG,MAAM,EAAE,EAAE;AACb,GAAG,IAAI,EAAE;AACT,GAAG;AACH,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY;AACxC,GAAG,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACtC,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,OAAO,KAAK;AACxC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC;AAClD,GAAG,OAAO,UAAU,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;AACnF,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA,CAAC,MAAM,WAAW,CAAC,OAAO,EAAE;AAC5B,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,YAAY;AACrC,GAAG,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACtC,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,OAAO,EAAE;AACrC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC;AACpD,GAAG,OAAO,YAAY,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;AACrF,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA,CAAC,MAAM,MAAM,GAAG;AAChB,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY;AACtD,GAAG,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACtC,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,OAAO,WAAW,CAAC,MAAM,CAAC;AACtD,GAAG,OAAO,WAAW,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9F,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA,CAAC,MAAM,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE;AAC7B,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,YAAY;AACrC,GAAG,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACtC,GAAG,IAAI,UAAU,KAAK,IAAI,EAAE,OAAO,EAAE;AACrC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC;AACnD,GAAG,OAAO,YAAY,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;AACrF,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA,CAAC,MAAM,MAAM,GAAG;AAChB,EAAE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;AACpC,EAAE,IAAI,KAAK,GAAG,IAAI;AAClB,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,IAAI;AAC3B,GAAG,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI;AACnC,EAAE,CAAC,CAAC,MAAM;AACV,GAAG,KAAK,GAAG,IAAI;AACf,EAAE;AACF,EAAE,OAAO;AACT,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI;AAClB,GAAG,SAAS,EAAE,IAAI,CAAC,UAAU;AAC7B,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM;AACrB,GAAG,KAAK;AACR,GAAG;AACH,GAAG;AACH,CAAC;AACD;AACA,CAAC,MAAM,KAAK,GAAG;AACf,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;AACrC,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI;AACzB,EAAE,IAAI,CAAC,UAAU,GAAG,KAAK;AACzB,EAAE,IAAI,UAAU,EAAE,SAAS,KAAK,MAAM,EAAE;AACxC,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY;AAClC,GAAG,UAAU,CAAC,SAAS,IAAI;AAC3B,EAAE,CAAC,CAAC;AACJ,CAAC;AACD,CAAC;AACD;AACA,IAAI,aAAa,GAAG,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE;AAC/B,CAAC,IAAI,aAAa,KAAK,IAAI,EAAE;AAC7B,EAAE,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC;AAC1C,EAAE,aAAa,GAAG,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC;AACnD,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI;AACpB,GAAG,GAAqB,EAAE;AAC1B,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC;AACD,CAAC,OAAO,aAAa;AACrB;;"}
|