{"_id":"@aegis-framework/pandora","_rev":"20-4665d9c33b5b92423e04ccc58d2917a4","name":"@aegis-framework/pandora","dist-tags":{"latest":"0.6.3"},"versions":{"0.1.0":{"name":"@aegis-framework/pandora","version":"0.1.0","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.0","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"36ae0c1130eb2dba2f056037ba8be6a096e2e970","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.0.tgz","fileCount":11,"integrity":"sha512-o7Q87qhTp1GtgAIXicfqtfwCb11Bz8QaiHrD16EBTD8YweFkXpDp5j81YKRCP4R1G+xuCE6+Gsep2ddCNIt9cQ==","signatures":[{"sig":"MEQCIArcUwnN2Es1JtcAQ1iGh4WZLGEIQQJzcrfKKHKeB+eXAiB45Q/64wn1TLmabUA4P0QRMD1LbdF/r3mh6Modg8BV5A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95025,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc92OXCRA9TVsSAnZWagAAU5oQAI/Xz2tH+DPTCEhOdFyL\nsmLPq81latS8FAGHiyIF3ya7cQ/3mn3zeadkO7Nqjuri9aVwhjCXlVmXN2i3\n27A7kZ9lkUj8Ju7PSyc4Iv1p9Ju661jhV/u0Ypx6Tg7eBeyisv1oGzJfdEkM\nSmxL22nvuowht+yddme6UpzTM2zcj1oaFaFLS7bBCMMyctV9g9W9KcBgGwpj\nGM5yYr8BrqINiJNaLqrbCnd8PwrG6FjP9euSthcbPn3EJRKNaPP3xqtOMs7k\ntslcnjOCEfy8CpIFc2C0yG1zLVPuXDyWT1WvfCyydMGlh+uKXwgEuQi9hN2z\nvPyUv8OqbU58D/LUxmt9IPZoLYV6SVLf+yV/gVYSwVYQgysyuSpVxQrGChaY\nl9HSYQ8U8Gjj9bAsIyj0zYp4oRJaVH/d6jxkjzzL1BMVGsMoCUiIEgdI6SHx\nNW0T743622AoLuTAKd2VFCX5MLSKP3LKfsDsh8bqmmADXXcLdgr60DzPGWhI\nlvXsWgh1Z7Siu8GWh2fAJyjPyX8baFxYB6QJoDUwWq5dmaOsq62NrR+Vs6xE\nDl84n+/yWm5IUBP2L6agcboeoi68dkDxeCrIpKA7hdyWvL1K1SHXpc3ZD/sO\n1DlnxXN7nejN5T2rtETnvKc6CH2D5NHecRcm299aHdSVKQwlSnQIliqfaZy9\nh9y4\r\n=S01+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"882909498db979f66530b28e251961a29079bc31","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.9.0","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"10.16.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.5.5","eslint":"^5.16.0","parcel":"^1.12.3","@babel/core":"^7.0.0-0","jsdoc-to-markdown":"^5.0.0","@babel/plugin-proposal-class-properties":"^7.4.0","@babel/plugin-syntax-object-rest-spread":"^7.0.0","@babel/plugin-proposal-object-rest-spread":"^7.4.4"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.0_1559716756032_0.5950914353439363","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"@aegis-framework/pandora","version":"0.1.1","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.1","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"fe663b81667e320fc859928b53843d6bd76986ab","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.1.tgz","fileCount":12,"integrity":"sha512-6gbYbJn+pkKiG2NsM0766icE6CneHqwbjoFZP/cb52fOFjdovHrQ5EYOsD4En6XAqAhvxFqlHUTl5up8dEnKMQ==","signatures":[{"sig":"MEYCIQCwU244lr62T9tCNmwvfAIG1pLp08rtHz36c8TqV9ToNAIhAPknjxp6N6WQ21MXQnc0IjzhF22gQa0t+bVyJcj+nv/Z","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82512,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdALEpCRA9TVsSAnZWagAAGa8QAJ95x6zbHul4uRXfQb4U\njvFrHVoAlrT4h+abqEZQCNkZDwQe5e88I9Qf+EAzqzFsw8NZlECqjrSHtdYE\noNtXqed77z/N39tWkGJ3E2hJGVwqpZBK6Hqhy+8XaThj8GeQBIy5TdncpYNH\nU5HIPyZiYzZO39icpJVotaE/BWeXB+dYMVixYp5G2omKsry0q95F+TKtWdSz\nQFNJ0JgN4N9bg0yv03nUHtOZprkjzO3a6q+Dyx763AL9nr3keF1O/t5FGYfq\n9cFfEnDTDI+AlT02+o0Z5rcqHCXt5p4L61LvSUHDmaKLC3pP48+Ou8c9xqfR\nF3RkoYBZOCiZTGmzwaJ2o6vbWibD9/PQCernUlrQsvJ43Ct1DD5ZUULshj7q\n6a0MhhaP4L0Fo6BbOaSrHgsWg+FzmgjCJssvmjRIIhc8s5ERRfCzUKiVmtQE\nrK+dyL2WbqNL/7c8eqTJFXaBIvqTU1bMRnjYsr4J95Ea/hTgDi/8fKCR82Yw\nSrEH4YudG3UbETZqom7+MIA1rqvtBjIR72TH7AXmSUO+6o7+G9VBqOhtSU2u\n2AEfsJ5Ypu3ZWoXO36aW10T4l6kBy3QcmfZ1fbvinPyFWa/zV24gCX14ef7w\nO3tarZfLIfEtay6aGKtt5tf6U6gbXjP8D/0XGkI8iDzPR9lEYNaKOX6Mu6y6\n337u\r\n=n3t9\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"c449a547896200b803c2e7cb979f7f96beb7e579","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.9.0","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"10.16.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.5.5","eslint":"^5.16.0","parcel":"^1.12.3","@babel/core":"^7.0.0-0","jsdoc-to-markdown":"^5.0.0","@babel/plugin-proposal-class-properties":"^7.4.0","@babel/plugin-syntax-object-rest-spread":"^7.0.0","@babel/plugin-proposal-object-rest-spread":"^7.4.4"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.1_1560326440241_0.6412474429655621","host":"s3://npm-registry-packages"}},"0.1.2":{"name":"@aegis-framework/pandora","version":"0.1.2","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.2","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"6c8ab07bf0a71eab9ac56829866b88aaf5ae341c","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.2.tgz","fileCount":12,"integrity":"sha512-k1fet/0Ye5rdlaaI/OlOrID+ddWE2XW+rAB04nyCt5U/7zTBSn2Vb6HylFLY8KyTTKQQktiZncrNit3gF0nnnA==","signatures":[{"sig":"MEUCIDI80YQlGVlLcgsKw2cstHMfNAceGLNsxCuUL3nOvzjZAiEAjdkdghqV8wpTnTMfc+yXIQvvjLFay3QwG6yI4SStAIY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":92505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdCYPiCRA9TVsSAnZWagAAAY4P/iPJ489JyrxMO7yqZSmj\nGsx/z0O6xwz8tNJG+d5KhTFw4RR+JyMY2hmTA95tFBOQJ9fLXxpb2RKYycFX\nkcjQjHfsIQ7853qeqpfn33WNIC+ubx/uSTuS6Q47IrbuPt92I0A2hg85fTgw\nKYv0v++p8XJJMcRe3kd8lci/w5UpIr837k0dbNpERBgznY4vI6JkI4I+vaoD\niz3XG/JcpzbHk75FgEC0tLRoTmsSRr03wVexSQGMnN/7sdzTZgBtlgcrCDX+\nntZZDhKA8+4dysBV0VJ4FFTRrLVHc1hJnjyHoFi8IZTefQcfmbBONR6ftIzA\n4uRMnUSBOi9g2FWfZZhya7RsrvDV8erLm8FJTdv+gRsQMyY0FNwP2mYEv52+\noTUpkvML03T5xTWowlg4AeMIeGQugii7PgcuWZGu46zpP5hoP44XIPwlPQK+\n2SFMnTWHWhT6OaH0BLplU4dzDzDUf+wUcJ93oN7w0jKybUbYtU4OdEf2jB63\nTisqWzihIYPvUd6zxrF3FtegOl3y35USxDOgrUaY6GyOXSPeFyyhByfqj9rN\n7mt1RHNHGTO1pJESUDHKh2alciTJ6atSeMVznhMnKCmSRx8E5DP4RppjxwjO\npmAX5GPvCWxoJbNv94y1qE0c0DJxwXDrte9fLAqibRgc4uDo9fiEAq/t7kO0\nErYg\r\n=8Xgl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"e05b2fb570a53d5256d9f0fa91bafc629f492222","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.9.0","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"10.16.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.5.5","eslint":"^5.16.0","parcel":"^1.12.3","@babel/core":"^7.0.0-0","jsdoc-to-markdown":"^5.0.0","@babel/plugin-proposal-class-properties":"^7.4.0","@babel/plugin-syntax-object-rest-spread":"^7.0.0","@babel/plugin-proposal-object-rest-spread":"^7.4.4"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.2_1560904673328_0.8667001988433694","host":"s3://npm-registry-packages"}},"0.1.3":{"name":"@aegis-framework/pandora","version":"0.1.3","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.3","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"7eaf21e16041035ac68761e99bbd92ed105a48db","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.3.tgz","fileCount":13,"integrity":"sha512-N4Qo3H6c/EHHGm+uWl7bY6e/HRJu1g6pvFuqbuNk79Y2zbz1JNfKmsIJumipleUgnr3rxxV3EmavUEmfKv8dlA==","signatures":[{"sig":"MEUCIQDfWh0aIyJbgTRrmuPhQGgaFLEmPEoCllga2yfrjfjy9QIgSl7ezktK2tA+uBAKvDDHgW95GszTI9r3CHplvQC3A6I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":99304,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdcWDLCRA9TVsSAnZWagAA8dUQAJFxNDiuB9/Jhn7werOU\nnvUSPhiO3Qkq6/fSNouPeCUWhMM95AFnQyoCH9B0155NmybO4WyxJqVD3KEw\nMs5aZ3uQN8i1PPU80yXOJmVx32Tru0WxWAW2XGWLZVWKXSq4utibX6YsEXXv\n8w0NgQfs13hvOtY4JsVwBfIPTO1T3w7a73wrqVCyoO71tF9NdSPPcUOcBa1k\nuKwRlD0e+IB5790zbPb2mHTRZ4Im8S/Y3FBrgtEm04WVadiIH5lohwIjTzpT\nGLxfWzu1RCzPXpj7SDgE9XHquVkw9ZOaYGjNqD350StmI3zigXMQduuZHG8v\ndUYTUDg38ptuqwbB/GtAuk75gZ+aRPgPzpaySgA46sgLMVAZBnlUN+akJPsY\nN9cmo7IvF+Kswev76XnWobcfbqZHrLWKAHJKJMLsTWciCZdkkqdWGsLXhPEQ\nhxlYYQPflVH1dm+8B8HVqqOy8s0d2ehpCq4uXRqr1AgBvEzNtH3N7OF2iiNB\nVbnjjL16zjV7r89QMweV3n3xGtlkVSul239YU0hxP07rDbx3Kqyd5Y1wnkVC\nALtGkLgJlYwy63o1P9yI2rBgrd0dfCxPJ/vrYDNv05aR7zOnPqOw2rqtEt9q\nhAunHAsOn8NZP9jR/2goz4CqM+xAa/VmEilg37A4x4DRu8yRkAv+GjSsQ0Ty\njSlx\r\n=bGBN\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"3483e6e47b10aca202febd996b14a3828028874a","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.10.2","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"12.8.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.3","eslint":"^6.3.0","parcel":"^1.12.3","@babel/core":"^7.5.5","jsdoc-to-markdown":"^5.0.1","@babel/plugin-proposal-class-properties":"^7.5.5","@babel/plugin-syntax-object-rest-spread":"^7.0.0","@babel/plugin-proposal-object-rest-spread":"^7.5.5"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.3_1567711434540_0.1898798532658832","host":"s3://npm-registry-packages"}},"0.1.4":{"name":"@aegis-framework/pandora","version":"0.1.4","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.4","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"61fe8861c7fde672756251dce5d2e429e781e6e3","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.4.tgz","fileCount":12,"integrity":"sha512-K0GXCR2HVhpEoFXgNzY6OPZe3dOa4BnFjOZDhqS6aeyYYSo7qO4tdXpADqcsk8DOt/sHsn0heabK3FuVvx+0ug==","signatures":[{"sig":"MEYCIQDhVr2miF4HyIpSqRrMJStECzcaUs6rW19liq+1MWR0LQIhAJZn+pOcZvqApoBOhoOAlC4ZV/jyLWNzwflOOmhLdYEd","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":105131,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeQw/4CRA9TVsSAnZWagAA5hIP/jvlALg/ICLaZZjHvil+\nuXRvM+UjISqiX7yb4iaKufSpVRYAOWKU8QaSzRZpnEf6NVKzNA+37e8tqA70\n/razzWwuEHnBDIc5ZHsUv7oEGJBKcfe9/3s25vwAO5sGHryvngiPSqIs3l2t\nSqGuNVOrbxCkauGLNNTFxphrrz42kAkLl3Um6GYq+c5Kzuej+8veeqSvxTVM\ns0S6HOmVQlycxwVERsgOnfZnOjrlyECtS/8kCoRy1Y/kH6RK5vk+Im5F3GQV\nNcAUaC8qKiHHc/BFWa9A+QXi9WkulI85Ybk1N8EG2Ok7s1XP43cJTfYIBXxv\nxSdwoP7y5xTHvEPFOynmUlpdzLlDnoZgZI2gCxtn+Cz0r9kHuaNFoLJtYnK8\nwNKAKpzCDVfZAO+NcdKFWIc7ZqivwbjEG0A80L3krFU+M7Pjmbi2i/FQqSaC\n6ckKwlj2KOrPfy/9EZzCXxWSx2wp6tFmEosqlsQUIulvfWrT/9xxyY3d+nIu\n4wUyTtfIgB8N/o9dfym7edcX+mbzG1hZJVfOuSGfP4wLzoInPPPxiv9LxSTg\ni/9QYXyBm5zTxYnAapyWDFhCVJPP2vYmgAQf74NAf3iUoyAYrp3PaqfhOswy\nxW33DDBAAs9ZZMBkhN3MHFBtMqZWKJNgWB3LT4wm67R+qVG+gis1TxaSCg3d\nXEpm\r\n=VFbL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"0213d7ebcfc3ba8ec14fa65dafa85f8897ebc079","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.10.2","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"12.8.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.3","eslint":"^6.8.0","parcel":"^1.12.4","@babel/core":"^7.8.4","jsdoc-to-markdown":"^5.0.3","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-syntax-object-rest-spread":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.8.3"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.4_1581453304301_0.8165973015956043","host":"s3://npm-registry-packages"}},"0.1.5":{"name":"@aegis-framework/pandora","version":"0.1.5","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.5","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"b3f4c9c4f19872a8a2e4c96935136d89faf880c2","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.5.tgz","fileCount":12,"integrity":"sha512-2r53VL5ErwZUU0fPQ+dfz+oiRZ7BfRl1di15oFM5NlohefebnBiN0sCkNf5tSg4LZdUd3PTHfZcuSJC7m28otg==","signatures":[{"sig":"MEUCID0yQs86J6Wfkc9I4rFRjBU8btgyx3PRAAVj9ZxN4a5RAiEA57UeaPY9iISYMU9wdUV8OyGzlycEgp34Yp1r0ylHzs8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":105685,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUBlPCRA9TVsSAnZWagAAeagP/2orK0Skc29DtFHE+pCO\nnwPdhRZmkfH6KTfJ4U5KNMcyYPbUYUrs3+z4jCyba9N+ZeV2Npv9DIOvOBU4\n7p/JPVndW31ILt4Vmj+i08uo103vrnWkSlK5I8gFLIJtuUgZeHWo8ZKnpN1x\nQe7xBhhwWeAT+SAykzAaRUp2euzHX7HRRw/wzA5mlcRmreuHdJzaDVqkDOjk\nTNN8K/jzZe7udpqZenUTo5Jm/RvAYJHGQ9eordO4Z3UKh1O0gMadjzGNqOQ/\nHsqoq0lHoXrzJaZPYd7qAyTDquUjU5J2tot9Ch/4lvhjJrLIemcy/QC20mO5\nJwHDzBLcjfOOJ28dmRqVTLMEdOHTVADo+6aN9L1PfjIdwDR/3Z2GzP6RbsTR\nSPSMXyDMqL/JQ1iKW/au02nYWM84ZKGY2lFWa7XFpxnH/fqBOl2S1qVU3Tnp\nsox+7aKa8bGqy3Z1nyji1foIh55O4rJXasY16pN7wlD411/nA5iA1B/Kz5Qo\nzXEiFybdSjtdcNXuNfX2DFL3u7DxSbsXQ6D5zdSl4Ut84vxfAPKyB0YJIsgC\n11zwxx8/ow+dTchfcG8HMYXcRAKEYRezr6+CZ0AKoTCgOGNjgLxeRaHHAsjr\nCwmHGFdkCMFhz9gl3VOvPd1QmeSKWgSgR0yC1C/HxZh3gVFip7r/Bm5kH5o3\nTM2L\r\n=aVx7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"bde6ecc057e02e893c5ed8d7ae39de1685705039","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.10.2","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"12.8.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.3","eslint":"^6.8.0","parcel":"^1.12.4","@babel/core":"^7.8.4","jsdoc-to-markdown":"^5.0.3","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-syntax-object-rest-spread":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.8.3"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.5_1582307662537_0.6563049631409734","host":"s3://npm-registry-packages"}},"0.1.6":{"name":"@aegis-framework/pandora","version":"0.1.6","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.6","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"b40c5eea9a1c913cf2f685c4c67445beddc7a99e","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.6.tgz","fileCount":12,"integrity":"sha512-cuyhtVU38PPingobXCwZfaue5H1Rz8ONROYb298yyqroydnQjR+UYWeaEVOtqh4pe2VgSY+8R1GiyzlIecnJBg==","signatures":[{"sig":"MEUCIQCoTaTJnbVUCbZOLuOboRFODB+rbp7mEBqWxWLjPUJIsgIgOaPSQtrJVUwShi8memlP0VsxaWnGdmpZ1sb+UBLymMM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":106585,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe0SzGCRA9TVsSAnZWagAA4JgP+gJy759tU980iYef/O2h\npQrMBIFcmwhIFP/U9gawY5URUWONN80YaCPBhVpMosMhEA8BSOOxFuFIHepk\n26SfxiRHNuAYP9w5qoaJXyk3Nfg1Opnrxob38z5jU3l+ntLczceTmp/Bx6ms\n27MZu3rNNTSjlOH509+n7gVLCQdqhg66vK93wysiHoIi2OviUAWzZKRei2rb\nfUqcVLr2sMrz+n+tFNvWVrq7j7oK986ntswhkjqpuFKZOELNQ3oXxCLRJdvi\nurRXzcOL9owj/pQPvncU6VMJfMa+rhSxMpZSTDc1lGoFdVwY5Tp/DEV6KIsM\naWdC5zR21itq8lxrjR9QKwSnjldkd183B0sRMmBvVaur57253/m3hrio3xF9\nFrC8GemdtSGBQwnBEo2mWYegIs44WLrDg5sWZkVHmvIZ/YlMN1MwhZ4D+m6T\novGEAbNNq5bMBLsUxnEp34kpHkCJC1naR/JOUrQkaEFsuXQi565CfspcBjkB\nPVeqnNAlzrFtPqDWNSxKEarYxA88rXKPDyRmK4C/4rSoUIcpL+njW7fEfSxD\nzzQHbtMp4qAmTQPVh+k+0ZDh0BmA16JP0jIJkUBubrEa5bwJTv3YAdUZU3mz\n22XgGQppcg34YxFPUuriNVb8I1cUk+Rjrq5owHYEOgT1ZFJMpnZFZsGqXEe4\nfDXP\r\n=8mtV\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"95fae8275403598ddc1a922af8a4640cfd24d7a5","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.10.2","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"12.8.0","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.3","eslint":"^6.8.0","parcel":"^1.12.4","@babel/core":"^7.8.4","jsdoc-to-markdown":"^5.0.3","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-syntax-object-rest-spread":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.8.3"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.6_1590766787522_0.23480532824274958","host":"s3://npm-registry-packages"}},"0.1.7":{"name":"@aegis-framework/pandora","version":"0.1.7","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.7","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"833a78d228bb672b5d1ba851d7f9f807909ad680","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.7.tgz","fileCount":12,"integrity":"sha512-It5FL1kpQPDOqFARYr9NhCkKLx8hPzvwkGk4pfFBXTJpDr6Z1/7W6m0AWjy2odWibKAL9tpvuK10durMZgKHqA==","signatures":[{"sig":"MEUCIQDlJHSwdmvHfH2A5yVRfTJrfJ9YKYKjzuG1aFcJl/ictQIgbHzruL0OzFfINPNPBnlBttVtkeZ79FkJLRF36u8OGEk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":107890,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYr0aCRA9TVsSAnZWagAAzlIP/jH02X/0Fc6RZ9e2siFB\n/AMfJu5g5uYLdJ7ByeDrokC8mXYUOUOLEpHCyBKWgxCD+Dv2FdKnQ/FvEAdo\nRhmarQAVGoz8u7eWI8SGs084MXyYTi+JFz3bytOZr/fegZwu9gn3azuWE0w4\nhZvrv3rEGKHHJ55kWH9y+9IgILAHOiBkrY3DXzJPXXw/vqpebSQIRvBTTkPs\nRtcjwKxrwGf3toS0DSJy5/53oZeHN/Zkw1SBEwVrxlF1vHC9HK/eHkNYCyQs\nySHOVJGYNIgVhwHHcJEnemBkRU4N1Rlp/IoFuPqct8XfFjttCcF7D7m9FlWS\nUV8NASx2fPnr1Ob6hZUYP9feXT3e3t1V0MEWIyxyduXXdDgJEh8W02Kgy6ZI\ny7bo2YgVdBloYJc+3EOsTX7EY/BP5EgrDWWzrqFRWUQyFc5+HPZfW1H9M5ky\nWHA5qybmnXl8AZPBepChTvFw65MhNv9rBE3ggzsXv/n6NZN3W2K96BETllvc\nUbbNXBxJWiR3afiJIg7hTGwj0zsOoZjlRyRHIPq1mFI6Knn7ekRa8Hrc260k\nieOppMs5C07FzeH+GeIYK8Yn9tU/0GmyO583nab5LUPZcY1qC03bOuLiL0Mp\njBb043DazanOR9DGNVs6ezfFPKh401R+GsD1HU6e2DrwdzXJj0+2hWZiwzSx\nfUUu\r\n=VQWL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"66aa061c8e3b32ae8518aaebac6f07fec2167fad","scripts":{"build":"parcel build ./index.js --global Pandora --out-file pandora.js --no-minify --no-cache --public-url . && parcel build ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch ./index.js --global Pandora --out-file pandora.min.js --no-cache --public-url .","eslint":"eslint index.js src"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"6.14.6","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"12.18.3","browserslist":["> 5%"],"_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.5","eslint":"^7.9.0","parcel":"^1.12.4","@babel/core":"^7.11.6","babel-eslint":"^10.1.0","jsdoc-to-markdown":"^6.0.1","@babel/plugin-proposal-class-properties":"^7.10.4","@babel/plugin-syntax-object-rest-spread":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.11.0"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.7_1600306457724_0.11717513335428764","host":"s3://npm-registry-packages"}},"0.1.8":{"name":"@aegis-framework/pandora","version":"0.1.8","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diego Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.1.8","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"9811afcde83f64ed1d389968c109ec782c204b7d","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.1.8.tgz","fileCount":14,"integrity":"sha512-IsDEvjMafNFZQr8nYekFgLfGvERUOdJQQnwjuumdCFY98dhbK5GkLC2FeZd2+1Yv2zW9h4ZiK9niYXCxYIQ0zg==","signatures":[{"sig":"MEUCIQCgB009veDnUMtPilTd36i0gmqKl2/rYSm/qNQBcCpCEgIgXqBqOTUuFOw1PyLGVFOY4AVVCr/QOD0qsc/Af0xfVl4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":137430,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhxeKACRA9TVsSAnZWagAAHJcP/1o93nkaCAjOE2SHpaWS\ndI2BKibAo6YTZj84DsHqoa7Bt8A0WE9ugZ9Zhh1Hwcvu5aFFwR0XzbHldeJ6\n/385IS5Xcqb4+6jrtOoT42E+bX5YuOn4dfPOYSiniyqe6b1JxT7pH1wATh0J\n8G4DCtYc+YuVwlGESIAOHwpy9pd9XjtIyEGNW2f1EAKQzuu2PATWqFbI7eqm\n71Mq9hJEoZe4MRmVE9R423LUCfokrQbWd0ZgciHtMLMGviO2lwGiqhppBV5f\ngKmMmZtG1PtkKHaitIxjKU4d5OAAiI29/Wk3B0oNPAPXI75o5pgkuhQJxcCZ\nExEz5Rik/O3YYkuORHiy/CNWJzm22DykkAsRbkp2xNEMWat5ZBGtfSRgZ/Wd\nUZkH7nNEH1dcV1SAs11OyRxAP3t1qevtFp0xlM2sBz6MW7KadNcHOI32eBUU\nt2EfhPyGJM6Bu9JSZbKaRx/4xJOkMZNc15/xhGaNLB8rKOpprZVDH1zwXoM/\nFxAydUF7WryF5wOebz+FwctSnHNcNXynSaGNkW2WrBOuB3hCdaxxeCKKrXw3\nxjc+4KL52YZbqxdo/pMVmGSyCW6UgHCjOMxItWJVsJhAvgly56e10znPkiuS\nSL1ztZ2bSlVxjLuY/zvqCTRpfABTvg/OdLgqDVzpxqJ2EJzYPtxAIKMbR4i7\ngehM\r\n=i8qO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/pandora.node.js","legacy":"./dist/pandora.min.js","module":"./dist/pandora.js","gitHead":"16d0147eebd0af68a15fc9203d3f3e5e39b5c155","scripts":{"build":"yarn build:main && yarn build:module && yarn build:legacy","jsdoc":"jsdoc ./src -c ./.jsdoc.json && jsdoc2md -f ./src/* -c ./.jsdoc.json >> ./docs/README.md","watch":"parcel watch --target legacy --no-cache --public-url .","eslint":"eslint index.js src","build:main":"parcel build --target main --no-cache --public-url .","build:legacy":"parcel build --target legacy --no-cache --public-url .","build:module":"parcel build --target module --no-cache --public-url ."},"targets":{"main":{"source":"index.js","engines":{"node":">= 12"},"optimize":true,"isLibrary":true,"outputFormat":"commonjs","includeNodeModules":true},"legacy":{"source":"browser.js","context":"browser","engines":{"browsers":"> 0.5%, last 2 versions, not dead"},"optimize":true,"isLibrary":false,"outputFormat":"global","includeNodeModules":true},"module":{"source":"index.js","engines":{"browsers":"Chrome 80"},"optimize":true,"isLibrary":true,"outputFormat":"esmodule","includeNodeModules":true}},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"8.1.2","description":"Aegis Framework Web Components Library","directories":{},"_nodeVersion":"17.1.0","browserslist":"> 0.5%, last 2 versions, not dead","_hasShrinkwrap":false,"devDependencies":{"jsdoc":"^3.6.7","eslint":"^8.5.0","parcel":"^2.0.1","jsdoc-to-markdown":"^7.1.0","@babel/eslint-parser":"^7.16.5"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.1.8_1640358528407_0.0028501863449801323","host":"s3://npm-registry-packages"}},"0.3.0":{"name":"@aegis-framework/pandora","version":"0.3.0","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.3.0","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"0db513d3db58015ad1425cdbc292e4cf845a625f","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.3.0.tgz","fileCount":21,"integrity":"sha512-xI8hx5vtKcZym3G3rulZuioscGq7OU6Ya0aqLmNm1R0RxxYfRWTjXZUbHds5hVPTwJkirOm9L1cBO2nDWxu8dQ==","signatures":[{"sig":"MEUCIEmujZ9j8FAaDQOhX8SNwrKy4LRrmz8GGeulraGcJOU+AiEA/j4W1lbdHAwcBdqyXy1zZTC/rGuB11sp+i8I+EsgOF0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":228260},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"46d1cfd0f04abb646f13b75c298a8a9c2faf89fb","scripts":{"lint":"eslint ./src/**/*.ts","test":"http-server -p 3000 -c-1","build":"yarn clean && yarn lint && yarn check && yarn build:module && yarn build:legacy && yarn build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","_hasShrinkwrap":false,"packageManager":"yarn@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","http-server":"^14.1.1","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.3.0_1765040075703_0.1865956371208619","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aegis-framework/pandora","version":"0.3.1","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.3.1","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"ce4f9d4b1c52a2975f673d7d6f3e909a47bab52f","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.3.1.tgz","fileCount":21,"integrity":"sha512-pKf7pkE1yBOkbHbO22fHJQZdGdiBHt8Hnob2FrwaYXl3Q4/MYR+B8GUL4j4kFICDPwKbcH1kK/l0kC9siwcsHA==","signatures":[{"sig":"MEQCIEMx+rQmoa4a/w3/eRA6agVi1dVZiJ3Sf89M2XDGAF7jAiASOWmUyXPTpuGZWyrHmwgMZRrcT9yWxae05842LqW2Kg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":227883},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"6484c4f1037ba994509d9633ee7080cb661e3b73","scripts":{"lint":"eslint ./src/**/*.ts","test":"http-server -p 3000 -c-1","build":"yarn clean && yarn lint && yarn check && yarn build:module && yarn build:legacy && yarn build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","_hasShrinkwrap":false,"packageManager":"yarn@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","http-server":"^14.1.1","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.3.1_1765162454401_0.853631150598291","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aegis-framework/pandora","version":"0.4.0","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.4.0","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://gitlab.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"fe8288854e20118ad52758470749855dc7a79c97","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.4.0.tgz","fileCount":23,"integrity":"sha512-vmXn0AuOAgQAjAs4WYX/V5EkQXHXS9VsF5mXHQnrzyTCChPffi6YGSkmQDc2jPsQ/ryfwNyPolrzaJz2PgPi2g==","signatures":[{"sig":"MEUCIQDZfSaJ3phbM3XP5cJbkKE767UYit6PYGv6o3L0A7lKKgIgE52UQeK6Ois7qYRHnrzEGvrr2GwNP37kKouhexjXSHc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":467818},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"7b8c134dd57cf778b8cdd54004319b3c5188267a","scripts":{"lint":"eslint ./src/**/*.ts","test":"bun test/index.html","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://gitlab.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.4.0_1765332406408_0.3258543321542189","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@aegis-framework/pandora","version":"0.4.1","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.4.1","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"b75e208344de2715f43d8e318bf32f91d7639c35","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.4.1.tgz","fileCount":23,"integrity":"sha512-py8AgIWqUCzPl/VXLnQhfiN8J8tvZt3769oJGEHzD+tG6kIEL2O2yU0fzCWPV7luxSLGJqlPTqYh2ZaQ5Up4mw==","signatures":[{"sig":"MEYCIQCmiQbNhv5apLWxg1Il2CPAT9Ta5lmccfoy1OmL8phdIwIhAKDUD5pBJSxQlMyx42v1ZppRaIPMUuHWhXbZSDpCXJXp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":470923},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"bdf46fc00d0d9715418ac11d0f8ec68b323e8616","scripts":{"lint":"eslint ./src/**/*.ts","test":"bun test/index.html","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.4.1_1766116823418_0.16701735509554627","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@aegis-framework/pandora","version":"0.4.2","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.4.2","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"3d2805b05b704f93d4cb94c5960082d9dac8b2f1","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.4.2.tgz","fileCount":23,"integrity":"sha512-uNZO7Lhct+ouKbGqPz1XwFxcDGD8WCgzFpW3QVxC6WrMhN8xul+8GAjcMxj8hLHraesgCPU0oJYBy4W1U32Bvw==","signatures":[{"sig":"MEUCIQCSf6Jrp9c6vY6Y+7bss2b0zOjtfUoe+uoiWnRkHTdlEwIgb7H5BQCifNJ2L5nAr8XXX4Qk0g8hDmFEUzoLFsCkZAc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":471099},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"f91012a3473fc2be47beeeee0e484c4b8054400a","scripts":{"lint":"eslint ./src/**/*.ts","test":"bun test/index.html","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.4.2_1766336505418_0.03189197078513151","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aegis-framework/pandora","version":"0.5.0","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.5.0","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"3e91c1f34e54e1e73a183c5dee55b3c1b2ff5303","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.5.0.tgz","fileCount":23,"integrity":"sha512-hC2pQsQJB7hkfVY2JoGupSW8IekHfCDpr/UBIGzrORZ3SxH8L/qfIQHV2wd/SRlBXnA7iUH2h5PCLQJwz+qFvw==","signatures":[{"sig":"MEUCIEsChml6k+Oh8NBKSrzjtbuo5oYi6lW2HShgSpuxtTmaAiEA1IeUFlz30ZAbm+zYoyEPsgVSfW6DWQ45uS+LGZueHXM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":483237},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"bfa2a94acb4b86d62615d71d6ab91735cff75668","scripts":{"lint":"eslint ./src/**/*.ts","test":"bun test/index.html","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":["./dist/pandora.browser.js"],"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@4.12.0","devDependencies":{"bun":"^1.3.3","eslint":"^9.39.1","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.5.0_1773761413703_0.5674447896385759","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@aegis-framework/pandora","version":"0.6.0","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.6.0","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"f0d21068c571ac00a05d403fdf9c9fbbb6f00658","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.6.0.tgz","fileCount":27,"integrity":"sha512-Mz90KVTI5ZvmjGPCm4MZSlPUX2emqzGTMFpwjC27JpWIHdygYEF7Lj/AUyLXzAworwEYsKbfPo/ph3CzScS34A==","signatures":[{"sig":"MEQCIC+GeyZxV8cjq8ltZgzz8P5HCI3AN/zZZnQ9cDeDHXmEAiA+IgN5Emd7POp1lpGeVryL1AGUcAytDYFyYf0z4YZXjA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":851420},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/browser.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"6cdd850ec2e78bfce84aaaa21476af1b187c0cc9","scripts":{"lint":"eslint ./src/**/*.ts","test":"cypress run --component","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","test:e2e":"cypress run --e2e","test:open":"cypress open","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":["./dist/pandora.browser.js"],"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@4.12.0","devDependencies":{"bun":"^1.3.3","vite":"^6","eslint":"^9.39.1","cypress":"^15.12.0","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.6.0_1777042035452_0.09046471680100154","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@aegis-framework/pandora","version":"0.6.1","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.6.1","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"9685fa41039ea4f33b89ccbbbe819f2df5d79116","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.6.1.tgz","fileCount":27,"integrity":"sha512-HF70GklL8zjwi/KqB4blzIRANXNWyeH1CnduYf9Fu2YkJN6HwVt7DK9aepiNBlqve1gMQTniT3XXm8kcnfNsvQ==","signatures":[{"sig":"MEQCICat0LsMFFI6cM0GTGFAEViDPgyWKGbU6Id2CVrjkw1rAiAWPz2fpStWIApnkI8U2TjIQRug+PMwKvQwVfYP+2FvEQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":862864},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/browser.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"5dee616e65d42d2500e779514f533f1d01e2ee2a","scripts":{"lint":"eslint ./src/**/*.ts","test":"cypress run --component","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","test:e2e":"cypress run --e2e","test:open":"cypress open","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":["./dist/pandora.browser.js"],"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.12","devDependencies":{"bun":"^1.3.3","vite":"^6","eslint":"^9.39.1","cypress":"^15.12.0","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.6.1_1777060955728_0.34569082771789494","host":"s3://npm-registry-packages-npm-production"}},"0.6.2":{"name":"@aegis-framework/pandora","version":"0.6.2","keywords":["pandora","dom","web","component","shadow","javascript","library"],"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","_id":"@aegis-framework/pandora@0.6.2","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"homepage":"https://aegisframework.com/","bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"dist":{"shasum":"f8e43b3c946890317c827e5bfd94525609f10b65","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.6.2.tgz","fileCount":27,"integrity":"sha512-BhywOrmHjtAsRUsvi+QT0Zszuf0Nh3KDJWzMdogRsUiIB7DeTXDHdzNH2y2my/dm/mQn5IgeYRfvCYkcs11vLw==","signatures":[{"sig":"MEYCIQCRXrbbEmxUeci4u5WCcEHfR5U2CStqvTpcDjg2Azj/GQIhALwHd4uYqauHFTszEqetT6wtjObz/cZvscBDmNA+qmQI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1099303},"main":"./dist/pandora.js","type":"module","types":"./dist/types/index.d.ts","module":"./dist/pandora.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/browser.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"gitHead":"64395b92a2436f3c6c7ba4738db57442d48ddd1f","scripts":{"lint":"eslint ./src/**/*.ts","test":"cypress run --component","build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","check":"tsc --noEmit","clean":"rm -rf dist","test:e2e":"cypress run --e2e","test:open":"cypress open","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js"},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"repository":{"url":"git+https://github.com/AegisFramework/Pandora.git","type":"git"},"_npmVersion":"11.6.2","description":"Aegis Framework Web Components Library","directories":{},"sideEffects":["./dist/pandora.browser.js"],"_nodeVersion":"25.2.1","browserslist":"> 0.5%, last 2 versions, not dead","dependencies":{"lit-html":"^3.0.0"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.12","devDependencies":{"bun":"^1.3.3","vite":"^6","eslint":"^9.39.1","cypress":"^15.12.0","@eslint/js":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","@babel/eslint-parser":"^7.28.5","@typescript-eslint/parser":"^8.48.1","@typescript-eslint/eslint-plugin":"^8.48.1"},"_npmOperationalInternal":{"tmp":"tmp/pandora_0.6.2_1778981235071_0.4874383490951042","host":"s3://npm-registry-packages-npm-production"}},"0.6.3":{"name":"@aegis-framework/pandora","version":"0.6.3","description":"Aegis Framework Web Components Library","type":"module","main":"./dist/pandora.js","module":"./dist/pandora.js","types":"./dist/types/index.d.ts","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/pandora.js","default":"./dist/pandora.js"},"./browser":{"types":"./dist/types/browser.d.ts","import":"./dist/pandora.browser.js","default":"./dist/pandora.browser.js"}},"sideEffects":["./dist/pandora.browser.js"],"repository":{"type":"git","url":"git+https://github.com/AegisFramework/Pandora.git"},"bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"homepage":"https://aegisframework.com/","author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","keywords":["pandora","dom","web","component","shadow","javascript","library"],"scripts":{"build":"bun clean && bun lint && bun check && bun build:module && bun build:legacy && bun build:types","build:module":"bun build ./src/index.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/index.js ./dist/pandora.js && mv ./dist/index.js.map ./dist/pandora.js.map && sed -i 's/index.js.map/pandora.js.map/' ./dist/pandora.js","build:legacy":"bun build ./src/browser.ts --target browser --format esm --outdir ./dist --sourcemap=linked --minify && mv ./dist/browser.js ./dist/pandora.browser.js && mv ./dist/browser.js.map ./dist/pandora.browser.js.map && sed -i 's/browser.js.map/pandora.browser.js.map/' ./dist/pandora.browser.js","build:types":"tsc --emitDeclarationOnly --declarationDir ./dist/types","check":"tsc --noEmit","lint":"eslint ./src/**/*.ts","clean":"rm -rf dist","test":"cypress run --component","test:e2e":"cypress run --e2e","test:open":"cypress open"},"dependencies":{"lit-html":"^3.0.0"},"devDependencies":{"@babel/eslint-parser":"^7.28.5","@eslint/js":"^9.39.1","@typescript-eslint/eslint-plugin":"^8.48.1","@typescript-eslint/parser":"^8.48.1","bun":"^1.3.3","cypress":"^15.12.0","eslint":"^9.39.1","typescript":"^5.9.3","typescript-eslint":"^8.48.1","vite":"^6"},"browserslist":"> 0.5%, last 2 versions, not dead","packageManager":"bun@1.3.12","gitHead":"6f03a4afddaa87edcb826deaf581d7221791d5f9","_id":"@aegis-framework/pandora@0.6.3","_nodeVersion":"26.1.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-Y2RA/oZ7WsE4/Zsx2rWvOgJYF5kiyoJ6+fngIsunDUuIu0lVRwi1sUTcW2fAgvjsVNhhGVUJctClnmuqfhlDag==","shasum":"27badfb06cb727dd1ce68f91e48a27baa6d12e10","tarball":"https://registry.npmjs.org/@aegis-framework/pandora/-/pandora-0.6.3.tgz","fileCount":27,"unpackedSize":1129598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDbVb8F0GwejRKh5k97WCqB1RCe8BWmHJL+dSRRD0/TbAIhANM4916y1sdC7YGtxIeeNRSn+3ZLb02pz0s1IfyPmbBW"}]},"_npmUser":{"name":"hyuchia","email":"dev@hyuchia.com"},"directories":{},"maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pandora_0.6.3_1781128791422_0.4781705386918036"},"_hasShrinkwrap":false}},"time":{"created":"2019-06-05T06:39:15.987Z","modified":"2026-06-10T21:59:51.715Z","0.1.0":"2019-06-05T06:39:16.137Z","0.1.1":"2019-06-12T08:00:40.435Z","0.1.2":"2019-06-19T00:37:53.516Z","0.1.3":"2019-09-05T19:23:54.695Z","0.1.4":"2020-02-11T20:35:04.407Z","0.1.5":"2020-02-21T17:54:22.767Z","0.1.6":"2020-05-29T15:39:47.627Z","0.1.7":"2020-09-17T01:34:17.944Z","0.1.8":"2021-12-24T15:08:48.535Z","0.3.0":"2025-12-06T16:54:35.839Z","0.3.1":"2025-12-08T02:54:14.555Z","0.4.0":"2025-12-10T02:06:46.612Z","0.4.1":"2025-12-19T04:00:23.561Z","0.4.2":"2025-12-21T17:01:45.621Z","0.5.0":"2026-03-17T15:30:13.863Z","0.6.0":"2026-04-24T14:47:15.586Z","0.6.1":"2026-04-24T20:02:35.939Z","0.6.2":"2026-05-17T01:27:15.249Z","0.6.3":"2026-06-10T21:59:51.600Z"},"bugs":{"url":"https://github.com/AegisFramework/Pandora/issues"},"author":{"name":"Diana Islas Ocampo","email":"dev@hyuchia.com"},"license":"MIT","homepage":"https://aegisframework.com/","keywords":["pandora","dom","web","component","shadow","javascript","library"],"repository":{"type":"git","url":"git+https://github.com/AegisFramework/Pandora.git"},"description":"Aegis Framework Web Components Library","maintainers":[{"name":"hyuchia","email":"dev@hyuchia.com"}],"readme":"# Pandora\n\nPandora is a lightweight web components library with a decorator-first API, automatic rendering via microtask batching, and built-in [lit-html](https://lit.dev/docs/libraries/standalone-templates/) integration for efficient DOM updates.\n\n**This is a breaking API redesign from pre-0.6 versions.** The state/props bags, `setState()`, `setProps()`, and most lifecycle hooks have been removed in favor of decorator-driven reactivity. See the [Migration Guide](#migration-guide) for a complete mapping of old APIs to new ones.\n\n```typescript\nimport { Component, Register, State, Listen, html } from '@aegis-framework/pandora';\n\n@Register('my-counter')\nclass MyCounter extends Component {\n  @State() count = 0;\n\n  @Listen('click')\n  increment() {\n    this.count++; // auto-renders\n  }\n\n  render() {\n    return html`<button>Count: ${this.count}</button>`;\n  }\n}\n```\n\n## Installation\n\n```bash\n# npm\nnpm install @aegis-framework/pandora\n\n# yarn\nyarn add @aegis-framework/pandora\n\n# bun\nbun add @aegis-framework/pandora\n```\n\n## Quick Start\n\nThe simplest component you can build: a prop that auto-renders on change.\n\n```typescript\nimport { Component, Register, Attribute, html } from '@aegis-framework/pandora';\n\n@Register('my-greeting')\nclass MyGreeting extends Component {\n  @Attribute() name = 'World';\n\n  render() {\n    return html`<h1>Hello, ${this.name}!</h1>`;\n  }\n}\n```\n\n```html\n<my-greeting name=\"Alice\"></my-greeting>\n```\n\nThat's all you need. No constructor, no `forceRender()`, no lifecycle boilerplate. When `name` changes -- whether from an attribute update or a direct property assignment -- the component re-renders automatically.\n\n## Decorators Reference\n\nPandora uses [TC39 Stage 3 decorators](https://github.com/tc39/proposal-decorators), supported in TypeScript 5.0+ and modern build tools (Vite, esbuild, Bun). For environments without decorator support, see [Non-Decorator Usage](#non-decorator-usage).\n\n### @Register(tagName)\n\nClass decorator. Registers the component with the custom elements registry under the given tag name. Same thing as calling `Registry.register(tagName, MyClass)` by hand.\n\n```typescript\n@Register('my-button')\nclass MyButton extends Component {\n  render() {\n    return html`<button>${this.slotContent}</button>`;\n  }\n}\n```\n\n### @State(options?)\n\nField decorator. Declares a reactive instance field. Any assignment queues a re-render on the next microtask, and multiple changes within the same synchronous block coalesce into a single render.\n\n```typescript\n@Register('my-toggle')\nclass MyToggle extends Component {\n  @State() open = false;\n\n  render() {\n    return html`\n      <button @click=${() => { this.open = !this.open; }}>Toggle</button>\n      ${this.open ? html`<div class=\"panel\">Content</div>` : nothing}\n    `;\n  }\n}\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `render` | `boolean` | `true` | Whether changes queue a re-render |\n\n**`@State({ render: false })`** keeps the field reactive (`@Watch` callbacks and `didChange` still fire) but skips the render queue. Reach for it when a field updates at high frequency, or when you'd rather handle DOM updates imperatively via `@Watch`:\n\n```typescript\n@Register('media-player')\nclass MediaPlayer extends Component {\n  @State() track = 'Song A';\n  @State({ render: false }) currentTime = 0; // updates 60x/sec\n\n  @Query('.time-display') timeDisplay!: HTMLSpanElement;\n\n  @Watch('currentTime')\n  onTimeUpdate(newVal: number) {\n    if (this.isReady) {\n      this.timeDisplay.textContent = `${newVal.toFixed(1)}s`;\n    }\n  }\n\n  render() {\n    return html`\n      <div>Now playing: ${this.track}</div>\n      <span class=\"time-display\">0.0s</span>\n    `;\n  }\n}\n```\n\nWhen to use `render: false`:\n\n- The field updates at animation-frame frequency (media time, scroll position, WebGL uniforms)\n- The render function is expensive and you want surgical DOM updates instead\n- You need to call imperative third-party APIs (canvas, WebGL, widget libraries)\n\nMost of the time the default auto-render is what you want -- lit-html's DOM diffing means only changed bindings update, not the whole tree. Reach for `render: false` when profiling shows a real bottleneck, not before.\n\n### @Property(options?)\n\nField decorator. Declares a reactive field that **never triggers a render**. Designed for **container components** -- ones whose children are defined in HTML or managed from outside. `@Watch` callbacks and `didChange()` still fire; `_queueRender()` never does.\n\n```typescript\n@Register('game-screen')\nclass GameScreen extends Component {\n  @Property() open = false;\n\n  @Watch('open')\n  onOpenChange() {\n    this.classList.toggle('active', this.open);\n  }\n\n  render(): void {\n    // void = preserve HTML children\n  }\n}\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `attribute` | `string \\| false` | `false` | Attribute name to sync, or `false` for property-only |\n| `equals` | `(a, b) => boolean` | `===` | Custom equality check |\n\n**When to use @Property vs @State:**\n\n| Scenario | Decorator | Why |\n|----------|-----------|-----|\n| Leaf component with rendered content | `@State()` | Needs auto-render |\n| Container with HTML children | `@Property()` | Re-render would destroy children |\n| High-frequency value (animation, scroll) | `@State({ render: false })` | Same behavior, but field lives on a rendering component |\n| Property set from outside that shouldn't re-render | `@Property()` | Intent is clear |\n\n`@Property()` is functionally equivalent to `@State({ render: false })`, but the intent is clearer at a glance: this component doesn't re-render, its children are its content.\n\n### @Attribute(attributeNameOrOptions?)\n\nField decorator. Declares a property that syncs with a DOM attribute. `@Attribute` registers the attribute as observed for you -- no need to set `static observedAttributes` by hand. Assignments sync back to the DOM attribute, and external attribute changes sync back to the property. Either direction queues a re-render.\n\n**String shorthand** -- custom attribute name:\n\n```typescript\n@Register('my-input')\nclass MyInput extends Component {\n  @Attribute() placeholder = '';\n  @Attribute('max-length') maxLength = 100; // maps to attribute \"max-length\"\n  @Attribute() disabled = false;\n\n  render() {\n    return html`\n      <input\n        placeholder=${this.placeholder}\n        maxlength=${this.maxLength}\n        ?disabled=${this.disabled}\n      >\n    `;\n  }\n}\n```\n\n```html\n<my-input placeholder=\"Enter text\" max-length=\"50\" disabled></my-input>\n```\n\nAttribute values are coerced for you: `''` and `'true'` become `true`, `'false'` becomes `false`, numeric strings become numbers, and everything else stays a string.\n\n**Property-only mode** -- use `@Property()`:\n\nFor inputs that hold complex values (objects, arrays, functions), use `@Property()` instead of `@Attribute()`. The field stays reactive but skips attribute sync entirely. See [Attribute Value Types](#attribute-value-types) for when to reach for each.\n\n```typescript\n@Register('data-table')\nclass DataTable extends Component {\n  @Attribute() title = '';\n  @Property() columns: string[] = [];\n  @Property() rows: Record<string, unknown>[] = [];\n  @Property() onRowClick?: (row: Record<string, unknown>) => void;\n\n  render() {\n    return html`\n      <h2>${this.title}</h2>\n      <table>\n        <thead><tr>${this.columns.map(c => html`<th>${c}</th>`)}</tr></thead>\n        <tbody>\n          ${this.rows.map(row => html`\n            <tr @click=${() => this.onRowClick?.(row)}>\n              ${this.columns.map(c => html`<td>${row[c]}</td>`)}\n            </tr>\n          `)}\n        </tbody>\n      </table>\n    `;\n  }\n}\n```\n\n```javascript\nconst table = document.querySelector('data-table');\ntable.columns = ['name', 'email'];\ntable.rows = [{ name: 'Alice', email: 'alice@example.com' }];\ntable.onRowClick = (row) => console.log('Clicked:', row);\n```\n\n### @Watch(property)\n\nMethod decorator. Runs the decorated method synchronously when a `@State` or `@Attribute` field changes, before the queued render. The method receives `(newValue, oldValue)`.\n\n```typescript\n@Register('search-box')\nclass SearchBox extends Component {\n  @Attribute() query = '';\n\n  @Watch('query')\n  onQueryChange(newVal: string, oldVal: string) {\n    console.log(`Query changed: \"${oldVal}\" -> \"${newVal}\"`);\n    this.fetchResults(newVal);\n  }\n\n  render() {\n    return html`<input .value=${this.query}>`;\n  }\n}\n```\n\nWatch callbacks fire synchronously inside the setter, before the microtask render. Any state you modify from a watcher gets batched into the same render.\n\nMultiple methods can watch the same property, and one method can watch multiple properties by stacking decorators:\n\n```typescript\n@Watch('width')\n@Watch('height')\nonDimensionChange(newVal: number) {\n  this.recalculateLayout();\n}\n```\n\n### @Computed(...dependencies)\n\nGetter decorator. Caches the return value and only recalculates when one of its dependencies (`@State`, `@Attribute`, `@Property`) changes. List dependencies by property name.\n\n```typescript\n@Register('task-list')\nclass TaskList extends Component {\n  @State() tasks: Array<{ text: string; done: boolean }> = [];\n  @State() filter: 'all' | 'active' | 'done' = 'all';\n\n  @Computed('tasks', 'filter')\n  get filteredTasks() {\n    if (this.filter === 'all') return this.tasks;\n    return this.tasks.filter(t => this.filter === 'done' ? t.done : !t.done);\n  }\n\n  @Computed('tasks')\n  get completedCount() {\n    return this.tasks.filter(t => t.done).length;\n  }\n\n  render() {\n    return html`\n      <p>${this.completedCount}/${this.tasks.length} done</p>\n      ${this.filteredTasks.map(t => html`<div>${t.text}</div>`)}\n    `;\n  }\n}\n```\n\nWithout `@Computed`, the getters would re-evaluate on every access -- every render, every template binding. With `@Computed`, the value is cached after the first calculation and only recomputed when `tasks` or `filter` actually changes.\n\n### @Subscribe(stateKey)\n\nField decorator. Binds a property to a global Registry state key. The component subscribes on connect and unsubscribes on disconnect, all for you. When the global value changes, the property updates and a render is queued.\n\n```typescript\nRegistry.setState('app.theme', 'light');\n\n@Register('themed-card')\nclass ThemedCard extends Component {\n  @Subscribe('app.theme') theme!: string;\n\n  render() {\n    return html`<div class=\"card theme-${this.theme}\">...</div>`;\n  }\n}\n\n// All ThemedCard instances re-render automatically\nRegistry.setState('app.theme', 'dark');\n```\n\nSetting the property from inside the component also updates the global state, so every other consumer sees the change too.\n\n### @Query(selector) / @QueryAll(selector)\n\nField decorators. Give you lazy DOM references. Each access calls `query()` or `queryAll()` on the component (or the shadow root for `ShadowComponent`), so references are always current after a render.\n\n```typescript\n@Register('my-form')\nclass MyForm extends Component {\n  @Query('.submit-btn') submitButton!: HTMLButtonElement;\n  @QueryAll('.field') fields!: NodeListOf<HTMLInputElement>;\n\n  async didMount() {\n    this.submitButton.focus();\n  }\n\n  render() {\n    return html`\n      <input class=\"field\" name=\"email\">\n      <input class=\"field\" name=\"name\">\n      <button class=\"submit-btn\">Submit</button>\n    `;\n  }\n}\n```\n\n### @Slot(name?)\n\nField decorator for `ShadowComponent`. Gives you a lazy reference to a `<slot>` element inside the shadow root. Re-queried on every access, so the reference is always current.\n\n```typescript\n@Register('card-layout')\nclass CardLayout extends ShadowComponent {\n  @Slot() defaultSlot!: HTMLSlotElement;\n  @Slot('header') headerSlot!: HTMLSlotElement;\n\n  async didMount() {\n    this.headerSlot?.addEventListener('slotchange', () => {\n      console.log('Header slot changed');\n    });\n  }\n\n  render() {\n    return html`\n      <div class=\"header\"><slot name=\"header\"></slot></div>\n      <div class=\"body\"><slot></slot></div>\n    `;\n  }\n}\n```\n\n`@Slot()` with no argument targets the default slot (`slot:not([name])`). `@Slot('name')` targets a named slot (`slot[name=\"name\"]`). Returns `null` when no matching slot exists in the shadow root.\n\n### @Listen(event, options?)\n\nMethod decorator. Attaches an event listener on mount and removes it on unmount, automatically. The method is auto-bound to the instance. Saves you from wiring up `this.on(...)` in `didMount` and `this.off(...)` in `willUnmount` by hand.\n\n```typescript\n@Register('modal-dialog')\nclass ModalDialog extends Component {\n  @Listen('click')\n  handleClick(e: MouseEvent) {\n    if ((e.target as Element).matches('.close-btn')) {\n      this.close();\n    }\n  }\n\n  @Listen('resize', { target: 'window' })\n  handleResize() {\n    this.recalculatePosition();\n  }\n\n  @Listen('keydown', { target: 'document', capture: true })\n  handleKeydown(e: KeyboardEvent) {\n    if (e.key === 'Escape') this.close();\n  }\n\n  // Delegated: fires only when a descendant matching the selector is clicked\n  @Listen('click', { delegate: '[data-action=\"save\"]' })\n  onSaveClick(e: Event) {\n    this.save();\n  }\n}\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `target` | `'self' \\| 'window' \\| 'document' \\| string` | `'self'` | Where to attach the listener. A CSS selector string queries within the component. |\n| `delegate` | `string` | -- | CSS selector for event delegation. The handler only fires when `event.target.closest(delegate)` matches. |\n| `capture` | `boolean` | `false` | Use capture phase |\n| `passive` | `boolean` | `false` | Mark as passive |\n| `once` | `boolean` | `false` | Remove after first fire |\n\n**Event delegation:** With `delegate` set, the listener attaches to the component (or `target`), but the handler only fires when the event originates from a descendant matching the selector. This is the same delegation pattern you'd recognize from jQuery, Backbone, and most UI frameworks -- handy for dynamic children without re-attaching listeners every render.\n\n### @Emitter(eventName)\n\nField decorator. Creates a typed function that dispatches a `CustomEvent` with `bubbles: true`, `cancelable: true`, and `composed: true`. Returns the result of `dispatchEvent` -- `false` if a listener cancelled the event.\n\n```typescript\n@Register('file-input')\nclass FileInput extends Component {\n  @Emitter('file-select') emitFileSelect!: (detail: { file: File }) => boolean;\n  @Emitter('file-error') emitFileError!: (detail: { message: string }) => boolean;\n\n  handleChange(e: Event) {\n    const file = (e.target as HTMLInputElement).files?.[0];\n    if (file) {\n      this.emitFileSelect({ file });\n    } else {\n      this.emitFileError({ message: 'No file selected' });\n    }\n  }\n\n  render() {\n    return html`<input type=\"file\" @change=${this.handleChange.bind(this)}>`;\n  }\n}\n```\n\n```javascript\n// Parent listens with standard DOM events\ndocument.querySelector('file-input').addEventListener('file-select', (e) => {\n  console.log(e.detail.file.name);\n});\n```\n\n### @Style(css)\n\nClass decorator. Declaratively applies styles at component definition time. Accepts a CSS object or a raw CSS string. Styles go through Constructable Stylesheets, shared across every instance of the class, and are applied once on first mount.\n\n**Object form:**\n\n```typescript\n@Register('my-card')\n@Style({\n  ':host': { display: 'block', padding: '16px' },\n  h3: { color: '#333', fontSize: '18px' },\n  '.body': { marginTop: '8px' }\n})\nclass MyCard extends Component {\n  @Attribute() title = '';\n\n  render() {\n    return html`\n      <h3>${this.title}</h3>\n      <div class=\"body\">${this.slotContent}</div>\n    `;\n  }\n}\n```\n\n**String form:**\n\n```typescript\n@Register('my-card')\n@Style(`\n  :host { display: block; }\n  h3 { color: #333; }\n`)\nclass MyCard extends Component { /* ... */ }\n```\n\nFor `ShadowComponent`, `:host` and normal selectors are naturally scoped by Shadow DOM. For regular `Component`, selectors are prefixed with the component tag name for you.\n\n### @ClassList(map)\n\nClass decorator. Toggles CSS classes on the host element based on reactive field values. Takes a map of class names to conditions, in one of two forms:\n\n- **Property name string** -- the class tracks the truthiness of that field. Uses `@Watch` internally, so it only re-evaluates when that specific field changes.\n- **Function condition** -- `(self) => boolean`, re-evaluated on every `didChange` (whenever any reactive field changes).\n\n```typescript\n@Register('game-screen')\n@ClassList({\n  active: 'open',                              // 'active' when this.open is truthy\n  'mode-nvl': (self) => self.mode === 'nvl'   // function condition\n})\nclass GameScreen extends Component {\n  @Property() open = false;\n  @Property() mode = 'adv';\n\n  render(): void {}\n}\n```\n\nInitial classes are applied on `connectedCallback`, and subsequent updates react to field changes automatically. You can mix both forms in the same map.\n\n## Component API\n\n### Status Getters\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `isConnected` | `boolean` | True when in the DOM |\n| `isReady` | `boolean` | True after first render + `didMount` complete |\n| `isFirstMount` | `boolean` | True until first mount completes |\n| `slotContent` | `string` | Original `innerHTML` captured before first render |\n\n### Rendering\n\n| Method / Property | Signature | Description |\n|-------------------|-----------|-------------|\n| `render()` | `() => string \\| TemplateResult \\| void \\| Promise<...>` | Override to provide template. `void` = preserve children. `''` = clear. |\n| `forceRender()` | `() => Promise<void>` | Immediate render (escape hatch -- prefer reactive fields) |\n| `batch(fn)` | `(() => void) => void` | Group state changes; `@Watch`/`didChange` deferred until batch completes, one render queued |\n| `ready(callback)` | `(() => void) => void` | Call after component is mounted. Fires immediately (via microtask) if already mounted. |\n| `static template` | `string \\| ((self) => TemplateValue)` | External template; setting it auto-re-renders mounted instances |\n\n### Styles\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `setStyle(style, reset?)` | `(Style \\| string, boolean?) => Style` | Apply styles; `reset=true` replaces instead of merging |\n\n### Events\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `on(event, callback, options?)` | Returns `this` | Add event listener (chainable) |\n| `off(event, callback, options?)` | Returns `this` | Remove event listener (chainable) |\n| `once(event, callback, options?)` | Returns `this` | One-time listener (chainable) |\n| `emit(event, detail?, options?)` | Returns `boolean` | Dispatch `CustomEvent` (bubbles, composed, cancelable) |\n\n### DOM Helpers\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `query<E>(selector)` | `(string) => E \\| null` | `querySelector` within the component |\n| `queryAll<E>(selector)` | `(string) => NodeListOf<E>` | `querySelectorAll` within the component |\n\nFor `ShadowComponent`, `query` and `queryAll` search within the shadow root.\n\n### Registration\n\n| Method / Property | Description |\n|-------------------|-------------|\n| `static register()` | Manual registration (equivalent to `@Register`) |\n| `static tag` | Tag name (auto-derived from class name, or set by `@Register`) |\n\n## Lifecycle\n\n```\nMount:   willMount -> render -> didMount (first time) / didReconnect (subsequent)\nUnmount: willUnmount -> didUnmount\nChanges: @Watch callbacks -> didChange -> queued microtask render\n```\n\nAll lifecycle hooks are async. Override only the hooks you need.\n\n| Hook | When it runs | Common use |\n|------|-------------|------------|\n| `willMount()` | Before every render on connect | Setup that must run before the DOM is ready |\n| `didMount()` | After the first render only | One-time subscriptions, timers, third-party init |\n| `didReconnect()` | After re-insertion (not first mount) | Refresh data, re-sync state |\n| `willUnmount()` | Before removal | Save state, cancel pending requests |\n| `didUnmount()` | After removal | Final cleanup |\n\n### Lifecycle Events\n\nComponents dispatch DOM events after mount completes and before teardown, which bubble up through the tree and cross shadow DOM boundaries (`bubbles: true, composed: true`). That lets outside code react to component lifecycle without subclassing.\n\n| Event | When | `event.detail` |\n|-------|------|----------------|\n| `pandora:ready` | After `didMount` completes (first mount) | `{ firstMount: boolean, tag: string }` |\n| `pandora:unmount` | Before `willUnmount` runs | `{ tag: string }` |\n\n```javascript\n// Listen on an ancestor or the document\ndocument.addEventListener('pandora:ready', (e) => {\n  console.log(`<${e.detail.tag}> is ready`);\n});\n\ndocument.addEventListener('pandora:unmount', (e) => {\n  console.log(`<${e.detail.tag}> is unmounting`);\n});\n```\n\nIn lit-html templates or HTML event binding:\n\n```html\n<game-screen @pandora:ready=\"onScreenReady\"></game-screen>\n```\n\nThese events complement `Registry.onMount` / `Registry.onUnmount`. Reach for the DOM events when you want to listen to a specific subtree or respond from a parent component's template; reach for `Registry.onMount` when you need a global observer across every tag.\n\n### didChange(property, oldValue, newValue, source?)\n\nA generic change observer that fires whenever any `@State`, `@Attribute`, `@Property`, or `@Subscribe` field changes value. Override it when you want a single interception point across every reactive field, instead of writing individual `@Watch` methods.\n\n**Timing:** fires synchronously in the setter, after `@Watch` callbacks, before the queued render.\n\n**Source values:**\n\n| Source | Meaning |\n|--------|---------|\n| `'state'` | `@State` field setter |\n| `'prop'` | `@Attribute` field setter (property assignment) |\n| `'prop-attribute'` | `@Attribute` attribute change (external HTML attribute modification) |\n| `'property'` | `@Property` field setter |\n| `'consumer'` | `@Subscribe` global state update |\n| `'reactive'` | `reactive()` primitive |\n\n```typescript\n@Register('audit-form')\nclass AuditForm extends Component {\n  @State() name = '';\n  @State() email = '';\n  @Attribute() role = 'user';\n\n  didChange(property: string, oldValue: unknown, newValue: unknown, source?: string) {\n    console.log(`[${source}:${property}] ${oldValue} -> ${newValue}`);\n    analytics.track('field_change', { property, newValue, source });\n  }\n\n  render() {\n    return html`\n      <input .value=${this.name} @input=${(e: Event) => { this.name = (e.target as HTMLInputElement).value; }}>\n      <input .value=${this.email} @input=${(e: Event) => { this.email = (e.target as HTMLInputElement).value; }}>\n    `;\n  }\n}\n```\n\nReach for `didChange` when you want to observe every field change uniformly (logging, analytics, dirty tracking). Reach for `@Watch` when you need targeted reactions to specific fields.\n\n### Lifecycle Example\n\n```typescript\n@Register('data-list')\nclass DataList extends Component {\n  @State() items: string[] = [];\n  private _pollInterval: number | undefined;\n\n  async willMount() {\n    // Runs on every connect -- safe for synchronous setup\n  }\n\n  async didMount() {\n    // Runs once -- safe for subscriptions and timers\n    this._pollInterval = setInterval(() => this.refresh(), 5000);\n    await this.refresh();\n  }\n\n  async didReconnect() {\n    // Component was re-inserted (e.g., moved in the DOM)\n    await this.refresh();\n  }\n\n  async willUnmount() {\n    clearInterval(this._pollInterval);\n  }\n\n  async refresh() {\n    this.items = await fetchItems();\n  }\n\n  render() {\n    return html`<ul>${this.items.map(i => html`<li>${i}</li>`)}</ul>`;\n  }\n}\n```\n\n## Decorator Inheritance\n\nWhen you subclass a decorated component, it helps to know how decorators interact with inheritance:\n\n### @Watch and Method Overrides\n\n`@Watch` metadata inherits from parent classes via `Symbol.metadata`. When a child overrides a watched method, what happens next depends on whether the child re-declares `@Watch`:\n\n```typescript\nclass ScreenComponent extends Component {\n  @Property() open = false;\n\n  @Watch('open')\n  onOpenChange() {\n    this.classList.toggle('active', this.open);\n  }\n}\n\n// Case 1: Override method WITH @Watch — child's version runs (normal JS override)\nclass MainScreen extends ScreenComponent {\n  @Watch('open')\n  override onOpenChange() {\n    super.onOpenChange(); // call parent's logic\n    if (this.open) this.playAmbient();\n  }\n}\n\n// Case 2: Override method WITHOUT @Watch — parent's @Watch entry still\n// points to 'onOpenChange', but the instance resolves to the child's\n// override. Same result: child's version runs.\nclass GameScreen extends ScreenComponent {\n  override onOpenChange() {\n    super.onOpenChange();\n    if (this.open) this.startGame();\n  }\n}\n\n// Case 3: Add a NEW watcher with a DIFFERENT name — BOTH fire\nclass DialogScreen extends ScreenComponent {\n  @Watch('open')\n  onOpenAnimation() {\n    this.animate(); // fires in addition to parent's onOpenChange\n  }\n}\n```\n\n**Rules:**\n\n1. `@Watch` entries are stored in class metadata, which inherits via the prototype chain.\n2. `getWatchersForProperty` looks up methods by name on the **instance**. If the child overrides the method, the child's version runs (standard JavaScript).\n3. Adding a new `@Watch` with a **different method name** on the same property creates an additional watcher -- both the parent's and child's fire.\n4. `super.method()` works normally inside overridden watchers.\n\n### @State and @Attribute Inheritance\n\nDecorated fields on parent classes are inherited. A child can add new decorated fields without touching the parent's:\n\n```typescript\nclass BaseComponent extends Component {\n  @State() loading = false;\n}\n\nclass UserCard extends BaseComponent {\n  @State() name = ''; // adds a new field; loading is inherited\n}\n```\n\nTo override a parent's field default, re-declare the field in the child:\n\n```typescript\nclass DarkCard extends BaseComponent {\n  @State() loading = true; // overrides default\n}\n```\n\n## Render Timing and Batching\n\nKnowing when renders actually happen saves surprises later. Here's the exact sequence when a reactive field changes:\n\n```\nthis.count = 5\n  |\n  +--> setter fires\n  |      |\n  |      +--> @Watch callbacks fire (synchronous)\n  |      |\n  |      +--> didChange() fires (synchronous)\n  |      |\n  |      +--> _queueRender() called -- sets a flag, schedules a microtask\n  |\nthis.name = 'Alice'     <-- same synchronous block\n  |\n  +--> setter fires\n  |      |\n  |      +--> @Watch / didChange fire (synchronous)\n  |      |\n  |      +--> _queueRender() called -- flag already set, no-op\n  |\n  ... synchronous code finishes ...\n  |\n  +--> microtask fires: ONE render with count=5, name='Alice'\n```\n\nKey points:\n\n- **`@Watch` and `didChange` fire synchronously** in the setter, so you can read the new value right away and modify other state in response. Those follow-up modifications are batched into the same render.\n- **Multiple synchronous changes produce exactly one render.** The first change schedules a microtask; later changes in the same synchronous block see the flag is already set and skip scheduling.\n- **`forceRender()` bypasses batching.** It triggers an immediate render. Reach for it when you need the DOM updated before the next line of code runs (rare), or when you're updating plain non-decorated fields.\n- **Renders are skipped while disconnected.** If the component isn't in the DOM (`isConnected` is `false`), `_queueRender()` is a no-op.\n- **Renders are skipped during initialization.** Field defaults set during construction don't trigger a re-render -- only changes after the first mount cycle do.\n\n### render() Return Value Semantics\n\n| Return value | Behavior |\n|---|---|\n| `void` / `undefined` | **No-op** -- preserve existing DOM. For container components whose HTML-defined children ARE the content. |\n| `''` (empty string) | **Clear** -- explicitly empties the component's innerHTML. |\n| `nothing` (lit-html) | **Clear** -- explicitly renders nothing via lit-html. |\n| `'<div>...'` | **Render** -- string template applied to DOM. |\n| `` html`...` `` | **Render** -- lit-html template diffed against DOM. |\n\nThe default `render()` returns `void`, so components that don't override it (container / structural components) keep their HTML-defined children intact. That matters for components like `<visual-novel>` or `<main-screen>`, where the children are set in HTML and managed from outside.\n\n### batch()\n\nWhen you want to update multiple fields and only fire `@Watch` / `didChange` once per field, after every change lands:\n\n```typescript\nthis.batch(() => {\n  this.x = 1;\n  this.y = 2;\n  this.z = 3;\n});\n// @Watch fires once per changed field, in order\n// One render is queued for the entire batch\n```\n\nWithout `batch()`, each assignment fires `@Watch` / `didChange` synchronously -- the render is already batched by microtask, but the watchers fire three times. With `batch()`, watchers are deferred and run after every assignment is done.\n\n### Deferred Registration\n\nFor engines and frameworks that need to control exactly when `customElements.define()` runs:\n\n```typescript\n@Register('game-screen', { defer: true })\nclass GameScreen extends Component {\n  // Class is set up but NOT registered with the browser\n}\n\n// Later, when ready:\nRegistry.define('game-screen', GameScreen);\n```\n\n`{ defer: true }` sets the static `tag` property but skips both `customElements.define()` and Registry registration. Call `Registry.define(tag, ComponentClass)` once your setup is ready.\n\n## Plain Fields vs @State\n\nNot every piece of instance data needs to be a `@State` field. Here's how to decide:\n\n| Scenario | Use | Why |\n|----------|-----|-----|\n| Value is shown in the template | `@State() count = 0` | Changes must trigger a re-render |\n| Value is internal bookkeeping (timer IDs, references) | `private _timer = 0` | No render needed -- plain field is simpler |\n| Value updates at high frequency but drives targeted DOM updates | `@State({ render: false }) time = 0` | Reactive (fires `@Watch`) but skips the render queue |\n| Value is passed in from a parent element | `@Attribute() label = ''` | Syncs with DOM attributes automatically |\n| Value is passed in but is a complex object | `@Property() data = []` | Reactive but no attribute sync |\n\n```typescript\n@Register('stopwatch-element')\nclass StopwatchElement extends Component {\n  @State() elapsed = 0;                     // shown in template\n  @State({ render: false }) isRunning = false; // drives @Watch, not template\n  private _intervalId: number | undefined;  // internal bookkeeping\n\n  @Watch('isRunning')\n  onRunningChange(running: boolean) {\n    if (running) {\n      this._intervalId = setInterval(() => { this.elapsed++; }, 1000);\n    } else {\n      clearInterval(this._intervalId);\n    }\n  }\n\n  @Listen('click')\n  toggle() {\n    this.isRunning = !this.isRunning;\n  }\n\n  render() {\n    return html`<button>${this.elapsed}s -- ${this.isRunning ? 'Stop' : 'Start'}</button>`;\n  }\n}\n```\n\n## Attribute Value Types\n\n`@Attribute()` syncs values with DOM attributes by default. That works well for strings, numbers, and booleans, which all serialize cleanly to attribute strings. Complex values -- arrays, objects, functions -- can't round-trip through attributes.\n\n| Value type | Decorator | Behavior |\n|------------|-----------|----------|\n| `string` | `@Attribute()` | Syncs to/from attribute as a string |\n| `number` | `@Attribute()` | Syncs to/from attribute; numeric strings auto-coerced |\n| `boolean` | `@Attribute()` | Present attribute = `true`, absent = `false` |\n| `object` / `array` | `@Property()` | Property-only -- no attribute sync, no render |\n| `function` | `@Property()` | Property-only -- no attribute sync, no render |\n\nNumeric coercion covers ordinary decimal spellings, including a leading sign and trailing zeroes -- so `42`, `+1`, `-3.14`, and `1.0` all arrive as numbers. Strings with leading zeros (`007`), scientific or hex notation (`1e3`, `0xFF`), or non-finite words (`Infinity`) are preserved as strings, so significant values like ids and zip codes survive the round trip intact.\n\n**Setting attribute-friendly props from HTML:**\n\n```html\n<my-input placeholder=\"Type here\" max-length=\"50\" disabled></my-input>\n```\n\n**Setting complex props from JavaScript:**\n\n```javascript\nconst table = document.createElement('data-table');\ntable.title = 'Users';                   // attribute-backed @Attribute\ntable.columns = ['name', 'email'];       // property-only via @Property()\ntable.rows = [{ name: 'Alice' }];        // property-only\ntable.onRowClick = (row) => alert(row);  // property-only\ndocument.body.appendChild(table);\n```\n\nIf you use `@Attribute()` (the default, attribute-backed one) with an object or array value, the property still works reactively, but the value won't reflect to a DOM attribute. Reach for `@Property()` instead -- the intent is clearer and there's nothing to be surprised by later.\n\n## ShadowComponent\n\n`ShadowComponent` extends `Component` with an open shadow root. The API is identical -- every decorator works the same way. The differences:\n\n- `query()` and `queryAll()` search within the shadow root\n- `setStyle()` adopts the stylesheet into the shadow root (scoped by Shadow DOM, not by tag prefix)\n- Use native `<slot>` elements for content projection instead of `slotContent`\n- `@Style` styles are naturally encapsulated\n\n```typescript\nimport { ShadowComponent, Register, Attribute, Style, html } from '@aegis-framework/pandora';\n\n@Register('fancy-button')\n@Style({\n  ':host': { display: 'inline-block' },\n  'button': { padding: '8px 16px', borderRadius: '4px' }\n})\nclass FancyButton extends ShadowComponent {\n  @Attribute() variant = 'primary';\n\n  render() {\n    return html`\n      <button class=\"btn-${this.variant}\">\n        <slot></slot>\n      </button>\n    `;\n  }\n}\n```\n\n```html\n<fancy-button variant=\"secondary\">Click me</fancy-button>\n```\n\nAccess the shadow root via `element.shadowRoot`.\n\n## Registry\n\nThe Registry is Pandora's central hub for component management, global state, and cross-cutting concerns.\n\n### Component Management\n\n```typescript\nimport { Registry } from '@aegis-framework/pandora';\n\n// Register (usually handled by @Register decorator)\nRegistry.register('my-tag', MyComponent);\n\n// Check / retrieve\nRegistry.has('my-tag')      // boolean\nRegistry.get('my-tag')      // ComponentClass | undefined\nRegistry.list()             // string[] -- all registered tags\n\n// Evolve: swap the implementation for a registered tag\n// Useful for hot module replacement and plugin patterns\nRegistry.evolve('my-tag', UpdatedComponent)         // swap, no re-render\nRegistry.evolve('my-tag', UpdatedComponent, true)   // swap + re-render all instances\n// Note: `observedAttributes` is captured by the browser at register() time and\n// cannot be changed afterward. If the evolved class adds NEW @Attribute fields\n// whose names weren't observed originally, DOM-driven changes to those new\n// attributes won't fire attributeChangedCallback. Property access still works.\n\n// Instances\nRegistry.instances('my-tag')                // NodeListOf<Element>\nRegistry.instances('my-tag', (el) => { })  // iterate\n\n// Programmatic instantiation\nconst el = Registry.instantiate('my-tag', { title: 'Hello' });\ndocument.body.appendChild(el);\n\n// Stats\nRegistry.stats('my-tag')  // { tag, instanceCount, isRegistered, isLazy }\nRegistry.stats()           // ComponentStats[] for all tags\n```\n\n### Lazy Loading\n\nRegister a component to be code-split and only loaded when it first appears in the DOM:\n\n```typescript\nRegistry.lazy('heavy-chart', () => import('./components/HeavyChart.js'));\n\n// Check status\nRegistry.isLazy('heavy-chart')  // true before loaded\n\n// Preload eagerly (e.g., on route anticipation)\nawait Registry.preload('heavy-chart');\n```\n\n### Aliases\n\nCreate alternative tag names for an existing component:\n\n```typescript\nRegistry.register('my-button', MyButton);\nRegistry.alias('app-button', 'my-button');\nRegistry.alias('ui-button', 'my-button');\n\nRegistry.isAlias('app-button')          // true\nRegistry.getOriginalTag('app-button')   // 'my-button'\n```\n\n```html\n<!-- All render the same component -->\n<my-button>Save</my-button>\n<app-button>Save</app-button>\n<ui-button>Save</ui-button>\n```\n\n### Lifecycle Hooks\n\nListen to mount and unmount events across all registered components:\n\n```typescript\nconst off = Registry.onMount((component, tag) => {\n  console.log(`<${tag}> mounted`);\n});\n\nconst off2 = Registry.onUnmount((component, tag) => {\n  console.log(`<${tag}> unmounted`);\n});\n\n// Clean up\noff();\noff2();\n```\n\n### Error Handling\n\nRegister a global error handler. Once it's in place, errors thrown from component lifecycle hooks flow through here instead of going uncaught:\n\n```typescript\nconst off = Registry.onError((error, component, tag, lifecycle) => {\n  console.error(`Error in <${tag}> during ${lifecycle}:`, error);\n  reportToErrorTracker(error, { tag, lifecycle });\n});\n```\n\n### Middleware\n\nIntercept and transform render output across all components:\n\n```typescript\n// Render middleware -- receives (component, value, renderType)\n// renderType is 'string' for string templates, 'lit' for lit-html TemplateResults\nconst off = Registry.use('render', (component, value, renderType) => {\n  if (renderType === 'string') {\n    return value.replace(/{{version}}/g, '1.0.0');\n  }\n  return value; // pass lit-html results through unchanged\n});\n\n// Remove middleware\noff();\n```\n\n### Debug Mode\n\n```typescript\nRegistry.debug = true;  // enables [Pandora] console logs for all lifecycle events\n\nRegistry.log('custom message', { extra: 'data' }); // only logs when debug is true\n```\n\n## Global State\n\nThe Registry ships a simple key-value state system for sharing data across components. Inside a component, the main way to consume global state is `@Subscribe`. The methods below are for setting and observing state from outside components.\n\n```typescript\n// Set / get\nRegistry.setState('app.user', { name: 'Alice', id: 1 });\nRegistry.getState('app.user')   // { name: 'Alice', id: 1 }\nRegistry.hasState('app.user')   // true\n\n// Subscribe\nconst unsubscribe = Registry.subscribe('app.user', (newVal, oldVal) => {\n  console.log('User changed:', newVal);\n});\n\nRegistry.setState('app.user', { name: 'Bob', id: 2 }); // fires subscriber\n\nunsubscribe();\n\n// Delete and clear\nRegistry.deleteState('app.user')  // notifies subscribers with undefined\nRegistry.getAllState()             // { 'app.user': ..., ... }\nRegistry.clearState()             // deletes all keys, notifies each subscriber\n```\n\n### Using @Subscribe\n\n```typescript\nRegistry.setState('app.locale', 'en');\n\n@Register('date-display')\nclass DateDisplay extends Component {\n  @Subscribe('app.locale') locale!: string;\n\n  render() {\n    return html`<time>${new Date().toLocaleDateString(this.locale)}</time>`;\n  }\n}\n\n// All DateDisplay instances re-render automatically\nRegistry.setState('app.locale', 'fr');\n```\n\n### Typed State\n\n`createState` wraps a Registry key with full TypeScript type safety. Reach for it when you want compile-time checking on `get`, `set`, and `subscribe` instead of untyped `Registry.setState` / `Registry.getState` calls.\n\n```typescript\nimport { createState } from '@aegis-framework/pandora';\n\nconst theme = createState<'light' | 'dark'>('app.theme', 'light');\n\ntheme.get();              // returns 'light' | 'dark'\ntheme.set('dark');        // type-checked -- 'midnight' would be a TS error\ntheme.subscribe((val) => {\n  document.documentElement.setAttribute('data-theme', val);\n});\ntheme.has();              // boolean\ntheme.delete();           // removes the key and notifies subscribers\n```\n\nThe optional second argument to `createState` sets a default value when the key doesn't already exist in the Registry. The returned object is a plain value, not a decorator -- stash it in a module-level variable and import it wherever you need it.\n\n`@Subscribe(key)` binds a component field to the same key:\n\n```typescript\nimport { theme } from './state';\n\n@Register('theme-toggle')\nclass ThemeToggle extends Component {\n  @Subscribe(theme.key) currentTheme!: 'light' | 'dark';\n\n  render() {\n    return html`\n      <button @click=${() => theme.set(this.currentTheme === 'light' ? 'dark' : 'light')}>\n        ${this.currentTheme}\n      </button>\n    `;\n  }\n}\n```\n\n## Extending Pandora\n\nPandora exposes its reactive primitives as a public API, so you can build your own decorators that plug into the render cycle, lifecycle, and hot-reload system alongside the built-ins. This is a stable, intentional extension surface -- not internal hacks you have to guard against.\n\n### Public Extension API\n\n```typescript\nimport { reactive, addDecoratorEffect, addTeardown } from '@aegis-framework/pandora';\n```\n\n| Export | Purpose |\n|--------|---------|\n| `reactive(instance, propertyKey, options?)` | Make a field reactive: installs getter/setter, auto-renders on change, fires `onChange` callback |\n| `addDecoratorEffect(metadata, effectFn)` | Register a function to replay when `Registry.evolve()` or `Registry.lazy()` upgrades a live instance |\n| `addTeardown(instance, cleanupFn)` | Register a cleanup function that runs before decorator effects are replayed (unsubscribe, remove listeners, etc.) |\n\nAdditionally, the `Util` namespace export gives access to metadata symbols if you need to read or extend decorator metadata directly:\n\n```typescript\nimport { Util } from '@aegis-framework/pandora';\n\n// Available symbols:\nUtil.PROP_ATTRIBUTES    // string[] of observed attribute names\nUtil.WATCH_HANDLERS     // @Watch registrations: { property, methodName }[]\nUtil.LISTEN_HANDLERS    // @Listen registrations: { event, methodName, options }[]\nUtil.STYLE_METADATA     // @Style CSS data (object or string)\nUtil.DECORATOR_EFFECTS  // effect functions for evolve/lazy replay\nUtil.DECORATOR_TEARDOWNS // cleanup functions on instances\n```\n\n### reactive(instance, propertyKey, options?)\n\nThe core reactive primitive. Installs a getter/setter on `instance` backed by a Symbol-keyed storage slot. The setter skips no-op assignments, fires `onChange`, and calls `_queueRender()` on the instance for you.\n\n```typescript\nreactive(instance, propertyKey, options?);\n```\n\n**Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `initialValue` | `unknown` | `undefined` | Initial value for the field |\n| `render` | `boolean` | `true` | Whether changes call `_queueRender()` automatically |\n| `onChange` | `(newValue, oldValue) => void` | -- | Callback fired on every change, before render is queued |\n| `equals` | `(a, b) => boolean` | `===` | Custom equality check to skip no-op assignments |\n\nThe `render: false` option is the escape hatch for custom decorators that want their own render strategy -- debouncing, throttling, conditional rendering.\n\n### addDecoratorEffect / addTeardown\n\nThese two functions handle **hot-reload compatibility**. When `Registry.evolve()` upgrades a live component, or `Registry.lazy()` loads a real implementation for a placeholder, Pandora needs to replay decorator behavior on instances that are already in the DOM. Without these, custom decorators would silently stop working after an evolve.\n\n**`addDecoratorEffect(metadata, effectFn)`** -- Call this inside your decorator function (not inside `addInitializer`). The effect receives the instance and should install whatever behavior your decorator provides.\n\n**`addTeardown(instance, cleanupFn)`** -- Call this inside `addInitializer`, or inside an effect. The cleanup runs before effects are replayed during evolve, so you don't end up with duplicate subscriptions or leaked listeners.\n\n**Pattern:**\n\n```typescript\nfunction MyDecorator(config: string) {\n  return function (_target: undefined, context: ClassFieldDecoratorContext) {\n    const propertyKey = String(context.name);\n\n    const meta = context.metadata as Record<symbol, unknown>;\n\n    // 1. Register the effect for evolve/lazy replay\n    addDecoratorEffect(meta, (instance) => {\n      applyMyEffect(instance as Component, propertyKey, config);\n    });\n\n    // 2. Apply the effect on first construction\n    context.addInitializer(function (this: unknown) {\n      applyMyEffect(this as Component, propertyKey, config);\n    });\n  };\n}\n\nfunction applyMyEffect(instance: Component, propertyKey: string, config: string) {\n  // Set up the behavior (subscriptions, property descriptors, etc.)\n  const subscription = someService.subscribe(config, (value) => {\n    (instance as any)[propertyKey] = value;\n  });\n\n  // Register cleanup for evolve teardown\n  addTeardown(instance as any, () => {\n    subscription.unsubscribe();\n  });\n}\n```\n\n### didChange Hook\n\nComponents can override `didChange(property, oldValue, newValue, source?)` as a single interception point for every `@State`, `@Attribute`, `@Property`, and `@Subscribe` change. The `source` parameter tells you where the change came from (`'state'`, `'prop'`, `'prop-attribute'`, `'property'`, `'consumer'`, `'reactive'`):\n\n```typescript\nclass TrackedComponent extends Component {\n  @State() count = 0;\n  @State() name = '';\n  @Attribute() title = '';\n  @Property() open = false;\n\n  didChange(property: string, oldValue: unknown, newValue: unknown, source?: string) {\n    analytics.track('field_change', { property, oldValue, newValue, source });\n  }\n}\n```\n\n`didChange` fires synchronously after `@Watch` callbacks and before the render is queued.\n\n### Example: @LocalStorage\n\nPersists a reactive field to `localStorage` and restores it on page load:\n\n```typescript\nimport { reactive, addDecoratorEffect, addTeardown, Component } from '@aegis-framework/pandora';\n\nfunction LocalStorage(storageKey: string) {\n  return function (_target: undefined, context: ClassFieldDecoratorContext) {\n    const propertyKey = String(context.name);\n    const meta = context.metadata as Record<symbol, unknown>;\n\n    addDecoratorEffect(meta, (instance) => {\n      applyLocalStorage(instance as Component, propertyKey, storageKey);\n    });\n\n    context.addInitializer(function (this: unknown) {\n      applyLocalStorage(this as Component, propertyKey, storageKey);\n    });\n  };\n}\n\nfunction applyLocalStorage(instance: Component, propertyKey: string, storageKey: string) {\n  const stored = localStorage.getItem(storageKey);\n  const initial = stored !== null ? JSON.parse(stored) : undefined;\n\n  reactive(instance as any, propertyKey, {\n    initialValue: initial,\n    onChange(newVal) {\n      localStorage.setItem(storageKey, JSON.stringify(newVal));\n    }\n  });\n\n  // Listen for changes from other tabs\n  const handler = (e: StorageEvent) => {\n    if (e.key === storageKey && e.newValue !== null) {\n      (instance as any)[propertyKey] = JSON.parse(e.newValue);\n    }\n  };\n  window.addEventListener('storage', handler);\n  addTeardown(instance as any, () => window.removeEventListener('storage', handler));\n}\n```\n\n```typescript\n@Register('settings-panel')\nclass SettingsPanel extends Component {\n  @LocalStorage('app.theme') theme = 'light';\n\n  render() {\n    return html`\n      <button @click=${() => { this.theme = this.theme === 'light' ? 'dark' : 'light'; }}>\n        Current theme: ${this.theme}\n      </button>\n    `;\n  }\n}\n```\n\nThe decorator is reactive (auto-renders), persists across page loads, syncs across tabs, and survives `Registry.evolve()` -- all from a few dozen lines.\n\n### Example: @DebouncedState\n\nA reactive field that debounces its render trigger, useful for search inputs:\n\n```typescript\nimport { reactive, Component } from '@aegis-framework/pandora';\n\nfunction DebouncedState(ms: number = 300) {\n  return function (_target: undefined, context: ClassFieldDecoratorContext) {\n    const propertyKey = String(context.name);\n    context.addInitializer(function (this: unknown) {\n      const instance = this as Component;\n      let timer: ReturnType<typeof setTimeout>;\n      reactive(instance as any, propertyKey, {\n        render: false,\n        onChange() {\n          clearTimeout(timer);\n          timer = setTimeout(() => {\n            (instance as any)._queueRender();\n          }, ms);\n        }\n      });\n    });\n  };\n}\n```\n\n```typescript\n@Register('search-bar')\nclass SearchBar extends Component {\n  @DebouncedState(250) query = '';\n\n  @Listen('input', { target: '.search-input' })\n  onInput(e: Event) {\n    this.query = (e.target as HTMLInputElement).value;\n  }\n\n  render() {\n    return html`\n      <input class=\"search-input\" placeholder=\"Search...\">\n      <div class=\"results\">Searching for: ${this.query}</div>\n    `;\n  }\n}\n```\n\nThe field itself updates immediately (so `@Watch` and `didChange` fire synchronously), but the template only re-renders after 250ms of inactivity.\n\n### Example: @MediaQuery\n\nA reactive boolean that tracks a CSS media query:\n\n```typescript\nimport { reactive, addDecoratorEffect, addTeardown, Component } from '@aegis-framework/pandora';\n\nfunction MediaQuery(query: string) {\n  return function (_target: undefined, context: ClassFieldDecoratorContext) {\n    const propertyKey = String(context.name);\n    const meta = context.metadata as Record<symbol, unknown>;\n\n    addDecoratorEffect(meta, (instance) => {\n      applyMediaQuery(instance as Component, propertyKey, query);\n    });\n\n    context.addInitializer(function (this: unknown) {\n      applyMediaQuery(this as Component, propertyKey, query);\n    });\n  };\n}\n\nfunction applyMediaQuery(instance: Component, propertyKey: string, query: string) {\n  const mql = window.matchMedia(query);\n  reactive(instance as any, propertyKey, { initialValue: mql.matches });\n\n  const handler = (e: MediaQueryListEvent) => {\n    (instance as any)[propertyKey] = e.matches;\n  };\n  mql.addEventListener('change', handler);\n  addTeardown(instance as any, () => mql.removeEventListener('change', handler));\n}\n```\n\n```typescript\n@Register('responsive-layout')\nclass ResponsiveLayout extends Component {\n  @MediaQuery('(min-width: 768px)') isDesktop = false;\n  @MediaQuery('(prefers-color-scheme: dark)') prefersDark = false;\n\n  render() {\n    return html`\n      <div class=${this.prefersDark ? 'dark' : 'light'}>\n        ${this.isDesktop\n          ? html`<div class=\"sidebar\">...</div><div class=\"main\">...</div>`\n          : html`<div class=\"mobile-stack\">...</div>`\n        }\n      </div>\n    `;\n  }\n}\n```\n\n### Example: @FetchData\n\nA reactive field that fetches data from a URL and auto-renders when the response arrives:\n\n```typescript\nimport { reactive, addDecoratorEffect, addTeardown, Component } from '@aegis-framework/pandora';\n\nfunction FetchData(url: string) {\n  return function (_target: undefined, context: ClassFieldDecoratorContext) {\n    const propertyKey = String(context.name);\n    const meta = context.metadata as Record<symbol, unknown>;\n\n    addDecoratorEffect(meta, (instance) => {\n      applyFetchData(instance as Component, propertyKey, url);\n    });\n\n    context.addInitializer(function (this: unknown) {\n      applyFetchData(this as Component, propertyKey, url);\n    });\n  };\n}\n\nfunction applyFetchData(instance: Component, propertyKey: string, url: string) {\n  reactive(instance as any, propertyKey, { initialValue: null });\n\n  const controller = new AbortController();\n  fetch(url, { signal: controller.signal })\n    .then(r => r.json())\n    .then(data => { (instance as any)[propertyKey] = data; })\n    .catch(() => {});\n\n  addTeardown(instance as any, () => controller.abort());\n}\n```\n\n```typescript\n@Register('user-profile')\nclass UserProfile extends Component {\n  @FetchData('/api/user') userData: any = null;\n\n  render() {\n    if (!this.userData) return html`<p>Loading...</p>`;\n    return html`<h2>${this.userData.name}</h2><p>${this.userData.email}</p>`;\n  }\n}\n```\n\n### What You Can Build\n\nThe extension API is meant to let you create decorators for any external data source or side effect:\n\n| Pattern | Built with |\n|---------|-----------|\n| Persistent state (localStorage, IndexedDB) | `reactive()` + `onChange` |\n| Debounced/throttled fields | `reactive({ render: false })` + custom timer |\n| Media queries, resize observers | `reactive()` + `addTeardown()` for cleanup |\n| Data fetching | `reactive()` + `addTeardown()` for abort |\n| WebSocket bindings | `reactive()` + `addTeardown()` for disconnect |\n| Intersection observers | `reactive()` + `addTeardown()` for unobserve |\n| Animation state | `reactive({ render: false })` + requestAnimationFrame |\n| Form validation | `reactive()` + `onChange` for validation logic |\n| Feature flags | `reactive()` + external service subscription |\n| Analytics/telemetry | `didChange()` hook or `onChange` callback |\n| Type-safe shared state | `createState<T>()` + `@Subscribe` |\n| Class-based visual state | `@ClassList` decorator |\n\nAll of these plug straight into Pandora's render cycle, `@Watch`, `didChange()`, and `Registry.evolve()` -- no extra wiring needed.\n\n## Styling\n\n### setStyle()\n\n`setStyle()` uses [Constructable Stylesheets](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) -- one stylesheet per component class, shared across every instance. Updates go through `replaceSync()`, so nothing adds `<style>` elements to the DOM.\n\n```typescript\n// CSS object (keys are selectors, values are property objects)\nthis.setStyle({\n  h2: { color: 'blue', fontSize: '24px' },\n  '.active': { fontWeight: 'bold' },\n  '&:hover': { opacity: '0.9' }   // & is replaced with the tag name\n});\n\n// CSS string\nthis.setStyle('h2 { color: blue; }');\n\n// Second argument true = replace instead of merge\nthis.setStyle({ h2: { color: 'red' } }, true);\n```\n\nFor `Component` (light DOM), selectors are prefixed with the component's tag name for you. For `ShadowComponent`, Shadow DOM provides natural encapsulation on its own.\n\n### @Style Decorator\n\n`@Style` is the declarative equivalent -- styles are applied once on first mount:\n\n```typescript\n@Register('stat-card')\n@Style({\n  ':host': { display: 'block', borderRadius: '8px', padding: '16px' },\n  'h4': { margin: '0 0 8px', fontSize: '14px', color: '#666' },\n  '.value': { fontSize: '32px', fontWeight: 'bold' }\n})\nclass StatCard extends Component { /* ... */ }\n```\n\n## lit-html Integration\n\nPandora bundles and re-exports lit-html, so you don't need to install it separately.\n\n```typescript\nimport {\n  html,            // HTML template tag\n  svg,             // SVG template tag\n  nothing,         // renders nothing (replaces previous content)\n  noChange,        // skip updating a binding\n  render,          // manual render (rarely needed)\n  type TemplateResult,\n  type SVGTemplateResult,\n  type RenderOptions\n} from '@aegis-framework/pandora';\n```\n\n### String vs lit-html Templates\n\nBoth rendering modes work inside the same component. Reach for whichever fits the situation:\n\n```typescript\n// String template -- simple, no build-time processing needed\nrender() {\n  return `<p>Hello, ${this.name}</p>`;\n}\n\n// lit-html -- efficient updates, event binding, property binding\nrender() {\n  return html`\n    <p>Hello, ${this.name}</p>\n    <button @click=${() => this.handleClick()}>Go</button>\n    <input .value=${this.query} ?disabled=${this.loading}>\n    ${this.items.map(item => html`<li>${item}</li>`)}\n    ${this.error ? html`<p class=\"error\">${this.error}</p>` : nothing}\n  `;\n}\n\n// Async render -- component awaits the promise before updating the DOM\nasync render() {\n  const data = await fetchUserProfile(this.userId);\n  return html`<div>${data.name}</div>`;\n}\n```\n\n### Static Template\n\nSet a template on the class directly -- handy for external templates or programmatic overrides. Every mounted instance re-renders automatically when the template changes:\n\n```typescript\n// Function template (self is the component instance)\nMyComponent.template = (self) => html`<div>${self.title}</div>`;\n\n// Defined in the class body\nclass MyComponent extends Component {\n  static template = (self: MyComponent) => html`<h1>${self.title}</h1>`;\n}\n```\n\nAn HTML `<template>` element with a matching `id` is also picked up on first mount:\n\n```html\n<template id=\"my-component\">\n  <div class=\"wrapper\">Static HTML content</div>\n</template>\n```\n\n## Non-Decorator Usage\n\n**Best experience: modern TypeScript with decorators.** The decorator path gives you auto-rendering, attribute sync, event binding, and lifecycle management with no boilerplate.\n\n**Fallback: plain JavaScript with manual `forceRender()`.** For environments without build tools or decorator support, you can write components as plain classes. It works, but expect a bit more manual wiring.\n\n```javascript\nimport { Component, Registry, html } from '@aegis-framework/pandora';\n\nclass CounterElement extends Component {\n  count = 0;\n\n  didMount() {\n    this.on('click', () => {\n      this.count++;\n      this.forceRender(); // plain fields are not reactive -- call forceRender() manually\n    });\n  }\n\n  render() {\n    return html`<button>Count: ${this.count}</button>`;\n  }\n}\n\nRegistry.register('counter-element', CounterElement);\n```\n\nPlain class fields are not reactive. Without `@State` or `@Attribute`, changes don't trigger renders on their own -- you have to call `forceRender()` after every mutation. Lifecycle hooks (`willMount`, `didMount`, `willUnmount`, `didUnmount`, `didReconnect`) work the same way in both paths.\n\n## Test Utilities\n\nPandora ships a `testing` namespace with helpers for unit and component tests. Import it straight from the main package:\n\n```typescript\nimport { testing } from '@aegis-framework/pandora';\n```\n\n| Function | Signature | Description |\n|----------|-----------|-------------|\n| `testing.flush()` | `() => Promise<void>` | Resolve all pending microtask renders. Call after state changes before asserting DOM state. |\n| `testing.whenReady(element, timeout?)` | `(Element, number?) => Promise<void>` | Wait until `element.isReady` is true. Resolves immediately if already ready. Rejects after `timeout` ms (default 5000). |\n| `testing.resetRegistry()` | `() => void` | Clear all global state, subscriptions, and middleware. Call in `beforeEach` / `afterEach` to isolate tests. |\n| `testing.mount(tagName, container?, innerHTML?)` | `(string, Element?, string?) => Promise<Component>` | Create the element, append it to `container` (default `document.body`), wait until ready, and return it. |\n\n```typescript\nimport { testing } from '@aegis-framework/pandora';\nimport { MyCounter } from './MyCounter';\n\nbeforeEach(() => {\n  testing.resetRegistry();\n});\n\nit('increments on click', async () => {\n  const el = await testing.mount('my-counter') as MyCounter;\n\n  el.dispatchEvent(new MouseEvent('click', { bubbles: true }));\n  await testing.flush();\n\n  expect(el.shadowRoot?.textContent).toContain('1');\n});\n\nit('accepts initial innerHTML', async () => {\n  const el = await testing.mount('my-counter', document.body, '<span slot=\"label\">Clicks</span>');\n  expect(el.isReady).toBe(true);\n});\n```\n\n`testing.flush()` performs two microtask yields: the first drains any `_queueRender` microtasks, and the second drains any microtasks queued during the render itself. That's enough for all standard reactive updates.\n\n## Browser Usage\n\nPandora ships a pre-bundled browser file you can drop in without a bundler:\n\n```html\n<script src=\"node_modules/@aegis-framework/pandora/dist/pandora.browser.js\"></script>\n<script>\n  const { Component, Registry, html } = Pandora;\n\n  class CounterElement extends Component {\n    count = 0;\n\n    didMount() {\n      this.on('click', () => {\n        this.count++;\n        this.forceRender();\n      });\n    }\n\n    render() {\n      return html`<button>Count: ${this.count}</button>`;\n    }\n  }\n\n  Registry.register('counter-element', CounterElement);\n</script>\n\n<counter-element></counter-element>\n```\n\nDecorators aren't available in no-build browser usage. Use `Registry.register()` and `forceRender()` as shown above.\n\n## Migration Guide\n\nMigrating from pre-0.6 Pandora to the new decorator-first API:\n\n| Before (pre-0.6) | After (0.6) |\n|-------------------|-------------|\n| `this.state = { count: 0 }` | `@State() count = 0` |\n| `this.setState({ count: 1 })` | `this.count = 1` |\n| `this.props = { title: '' }` | `@Attribute() title = ''` |\n| `this.setProps({ title: 'Hi' })` | `this.title = 'Hi'` |\n| `onStateUpdate() { this.forceRender(); }` | Automatic -- `@State` fields queue renders on change |\n| `onPropsUpdate() { this.forceRender(); }` | Automatic -- `@Attribute` fields queue renders on change |\n| `willUpdate()` / `didUpdate()` | `@Watch('field')` or `didChange()` |\n| `update()` | `@Watch('field')` |\n| `unmount()` | `willUnmount()` / `didUnmount()` |\n| `MyComponent.template(fn)` | `MyComponent.template = fn` |\n| `this.dom` | `this` (Component is itself an `HTMLElement`) |\n| `this.static.tag` | Removed -- use `(this.constructor as typeof Component).tag` |\n| `this.width` / `this.height` | Use `getComputedStyle(this)` directly |\n| `this.ready(callback)` | Use `didMount()` |\n| `Component<Props, State>` generics | Typed class fields with decorators |\n| Untyped `Registry.setState` / `Registry.getState` for shared values | `createState<T>(key, default)` for type-safe global state |\n\n**Key behavioral changes:**\n\n- **Auto-rendering is the default.** You no longer need `onStateUpdate() { this.forceRender(); }`. Any assignment to a `@State` or `@Attribute` field queues a render for you.\n- **No more state / props bags.** Each piece of state is its own decorated class field, which gives you TypeScript types for free and makes the intent of each field explicit.\n- **`forceRender()` is the escape hatch now, not the norm.** You only need it when you're working with plain (non-decorated) fields, or when you need an immediate synchronous render.\n- **Lifecycle hooks are simpler.** The old update lifecycle (`willUpdate`, `update`, `didUpdate`, `onStateUpdate`, `onPropsUpdate`, `updateCallback`) is entirely replaced by `@Watch` and `didChange`.\n\n## License\n\nReleased under the [MIT License](./LICENSE).\n","readmeFilename":"README.md"}