[FEAT] Multi select, flip, rotate, multi remove
This commit is contained in:
354
package-lock.json
generated
354
package-lock.json
generated
@@ -1390,9 +1390,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz",
|
||||||
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
|
"integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -1403,9 +1403,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz",
|
||||||
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
|
"integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1416,9 +1416,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz",
|
||||||
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
|
"integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1429,9 +1429,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz",
|
||||||
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
|
"integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1442,9 +1442,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz",
|
||||||
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
|
"integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1455,9 +1455,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz",
|
||||||
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
|
"integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1468,9 +1468,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz",
|
||||||
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
|
"integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -1481,9 +1481,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz",
|
||||||
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
|
"integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -1494,9 +1494,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
|
"integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1507,9 +1507,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz",
|
||||||
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
|
"integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1520,9 +1520,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
|
"integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@@ -1533,9 +1533,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
|
"integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -1546,9 +1546,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
|
"integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -1559,9 +1559,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz",
|
||||||
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
|
"integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -1572,9 +1572,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
|
"integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -1585,9 +1585,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
|
"integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1598,9 +1598,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz",
|
||||||
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
|
"integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1611,9 +1611,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz",
|
||||||
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
|
"integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1624,9 +1624,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz",
|
||||||
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
|
"integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1637,9 +1637,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz",
|
||||||
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
|
"integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -1650,9 +1650,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz",
|
||||||
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
|
"integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1663,9 +1663,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz",
|
||||||
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
|
"integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2505,9 +2505,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.9.7",
|
"version": "2.9.9",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.9.tgz",
|
||||||
"integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==",
|
"integrity": "sha512-V8fbOCSeOFvlDj7LLChUcqbZrdKD9RU/VR260piF1790vT0mfLSwGc/Qzxv3IqiTukOpNtItePa0HBpMAj7MDg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4181,9 +4181,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.53.3",
|
"version": "4.53.5",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz",
|
||||||
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
|
"integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.8"
|
"@types/estree": "1.0.8"
|
||||||
@@ -4196,28 +4196,28 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.53.3",
|
"@rollup/rollup-android-arm-eabi": "4.53.5",
|
||||||
"@rollup/rollup-android-arm64": "4.53.3",
|
"@rollup/rollup-android-arm64": "4.53.5",
|
||||||
"@rollup/rollup-darwin-arm64": "4.53.3",
|
"@rollup/rollup-darwin-arm64": "4.53.5",
|
||||||
"@rollup/rollup-darwin-x64": "4.53.3",
|
"@rollup/rollup-darwin-x64": "4.53.5",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.53.3",
|
"@rollup/rollup-freebsd-arm64": "4.53.5",
|
||||||
"@rollup/rollup-freebsd-x64": "4.53.3",
|
"@rollup/rollup-freebsd-x64": "4.53.5",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.53.5",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.3",
|
"@rollup/rollup-linux-arm-musleabihf": "4.53.5",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.53.3",
|
"@rollup/rollup-linux-arm64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.53.3",
|
"@rollup/rollup-linux-arm64-musl": "4.53.5",
|
||||||
"@rollup/rollup-linux-loong64-gnu": "4.53.3",
|
"@rollup/rollup-linux-loong64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.3",
|
"@rollup/rollup-linux-ppc64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.3",
|
"@rollup/rollup-linux-riscv64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.53.3",
|
"@rollup/rollup-linux-riscv64-musl": "4.53.5",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.53.3",
|
"@rollup/rollup-linux-s390x-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.53.3",
|
"@rollup/rollup-linux-x64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.53.3",
|
"@rollup/rollup-linux-x64-musl": "4.53.5",
|
||||||
"@rollup/rollup-openharmony-arm64": "4.53.3",
|
"@rollup/rollup-openharmony-arm64": "4.53.5",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.53.3",
|
"@rollup/rollup-win32-arm64-msvc": "4.53.5",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.53.3",
|
"@rollup/rollup-win32-ia32-msvc": "4.53.5",
|
||||||
"@rollup/rollup-win32-x64-gnu": "4.53.3",
|
"@rollup/rollup-win32-x64-gnu": "4.53.5",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.53.3",
|
"@rollup/rollup-win32-x64-msvc": "4.53.5",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4251,9 +4251,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.0.tgz",
|
||||||
"integrity": "sha512-8u4xqqUeugGNCYwr9ARNtQKTOj4KmYiJAVKXf2CTIivTCR51j96htbMKWDru8H5SaQWpyVgTfOF8Ylyf5pun1Q==",
|
"integrity": "sha512-KR0igP1z4avUJetEuIeOdDlwaUDvkH8wSx7FdSjyYBS3dpyX3TzHfAMO0G1Q4/3cdjcmi3r7idh+KCmKqS+KeQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4272,9 +4272,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded": {
|
"node_modules/sass-embedded": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.97.0.tgz",
|
||||||
"integrity": "sha512-z9PQ7owvdhn7UuZGrpPccdkcH9xJd9iCv+UQhcPqppBslYEp0R9LRQVyyPTZg7jfA77bGxz/I8V48LXJR5LjXQ==",
|
"integrity": "sha512-Unwu0MtlAt9hQGHutB2NJhwhPcxiJX99AI7PSz7W4lkikQg9S/HYFtgxtIjpTB4DW7sOYX2xnxvtU/nep9HXTA==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4294,30 +4294,30 @@
|
|||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sass-embedded-all-unknown": "1.96.0",
|
"sass-embedded-all-unknown": "1.97.0",
|
||||||
"sass-embedded-android-arm": "1.96.0",
|
"sass-embedded-android-arm": "1.97.0",
|
||||||
"sass-embedded-android-arm64": "1.96.0",
|
"sass-embedded-android-arm64": "1.97.0",
|
||||||
"sass-embedded-android-riscv64": "1.96.0",
|
"sass-embedded-android-riscv64": "1.97.0",
|
||||||
"sass-embedded-android-x64": "1.96.0",
|
"sass-embedded-android-x64": "1.97.0",
|
||||||
"sass-embedded-darwin-arm64": "1.96.0",
|
"sass-embedded-darwin-arm64": "1.97.0",
|
||||||
"sass-embedded-darwin-x64": "1.96.0",
|
"sass-embedded-darwin-x64": "1.97.0",
|
||||||
"sass-embedded-linux-arm": "1.96.0",
|
"sass-embedded-linux-arm": "1.97.0",
|
||||||
"sass-embedded-linux-arm64": "1.96.0",
|
"sass-embedded-linux-arm64": "1.97.0",
|
||||||
"sass-embedded-linux-musl-arm": "1.96.0",
|
"sass-embedded-linux-musl-arm": "1.97.0",
|
||||||
"sass-embedded-linux-musl-arm64": "1.96.0",
|
"sass-embedded-linux-musl-arm64": "1.97.0",
|
||||||
"sass-embedded-linux-musl-riscv64": "1.96.0",
|
"sass-embedded-linux-musl-riscv64": "1.97.0",
|
||||||
"sass-embedded-linux-musl-x64": "1.96.0",
|
"sass-embedded-linux-musl-x64": "1.97.0",
|
||||||
"sass-embedded-linux-riscv64": "1.96.0",
|
"sass-embedded-linux-riscv64": "1.97.0",
|
||||||
"sass-embedded-linux-x64": "1.96.0",
|
"sass-embedded-linux-x64": "1.97.0",
|
||||||
"sass-embedded-unknown-all": "1.96.0",
|
"sass-embedded-unknown-all": "1.97.0",
|
||||||
"sass-embedded-win32-arm64": "1.96.0",
|
"sass-embedded-win32-arm64": "1.97.0",
|
||||||
"sass-embedded-win32-x64": "1.96.0"
|
"sass-embedded-win32-x64": "1.97.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-all-unknown": {
|
"node_modules/sass-embedded-all-unknown": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.97.0.tgz",
|
||||||
"integrity": "sha512-UfUHoWZtxmsDjDfK+fKCy0aJe6zThu7oaIQx0c/vnHgvprcddEPIay01qTXhiUa3cFcsMmvlBvPTVw0gjKVtVQ==",
|
"integrity": "sha512-9F6MyQcwp3YiuGMk5bC7g9jL+D1KkW/ONQgrkoTQ7ALcmoPKmsauZg5WgRhLYW9UhpnGTgANrWrZdiREAR1YkA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"!arm",
|
"!arm",
|
||||||
"!arm64",
|
"!arm64",
|
||||||
@@ -4327,13 +4327,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sass": "1.96.0"
|
"sass": "1.97.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-android-arm": {
|
"node_modules/sass-embedded-android-arm": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.97.0.tgz",
|
||||||
"integrity": "sha512-0mwVRBFig9hH8vFcRExBuBoR+CfUOcWdwarZwbxIFGI1IyH4BLBGiX85vVn6ssSCVNydpE6lFGm45CN8O0tQig==",
|
"integrity": "sha512-VLxeVR5FMwSZoOliBY8Qy2trZCWYz3w4ILf0QZ68eep3mIQjtykY3BSKC2R/w9DkPQDNJXdgbgnxeOubC8k5xw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -4347,9 +4347,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-android-arm64": {
|
"node_modules/sass-embedded-android-arm64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.97.0.tgz",
|
||||||
"integrity": "sha512-TJiebTo4TBF5Wrn+lFkUfSN3wazvl8kkFm9a1nA9ZtRdaE0nsJLGnMM6KLQLP2Vl+IOf6ovetZseISkClRoGXw==",
|
"integrity": "sha512-uDG/0DS6A+KRiOYUV1UNHBq67DHvO+/54Ja+dg8S5fl5uvPwZGHpJFheemA9R6vvddwyjGmzVacvCQxdmECcfQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4363,9 +4363,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-android-riscv64": {
|
"node_modules/sass-embedded-android-riscv64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.97.0.tgz",
|
||||||
"integrity": "sha512-7AVu/EeJqKN3BGNhm+tc1XzmoqbOtCwHG2VgN6j6Lyqh1JZlx0dglRtyQuKDZ7odTKiWmotEIuYZ6OxLmr2Ejg==",
|
"integrity": "sha512-yrwsyPR08CXW5Ggr0kI1jTUcKkBOtjODbDj11nRrBwyrXRqhf1obqfchQxTW0HlYT8VZmZGfnHvPNNDwOSdfZg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -4379,9 +4379,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-android-x64": {
|
"node_modules/sass-embedded-android-x64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.97.0.tgz",
|
||||||
"integrity": "sha512-ei/UsT0q8rF5JzWhn1A7B0M1y/IiWVY3l4zibQrXk5MGaOXHlCM6ffZD+2j7C613Jm9/KAQ7yX1NIIu72LPgDQ==",
|
"integrity": "sha512-a1QW1pFykLCtV8J3AZ+wtrwOx0ORZsW4orF6fOrBYL2sLhlzhB3iK+QzWezFvH5+FMgLQBC4xgYYk4NV9WCO9g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4395,9 +4395,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-darwin-arm64": {
|
"node_modules/sass-embedded-darwin-arm64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.97.0.tgz",
|
||||||
"integrity": "sha512-OMvN5NWcrrisC24ZR3GyaWJ1uFxw25qLnUkpEso9TSlaMWiomjU82/uQ/AkQvIMl+EMlJqeYLxZWvq/byLH5Xg==",
|
"integrity": "sha512-5XV42FEqhQEGFQ/w8HUk///k0XMHLyBt1j2alxTr9ZI77HqiAIl6kVZp0kxJ++gt/y3E6hKoMLngHHC6zIBR5A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4411,9 +4411,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-darwin-x64": {
|
"node_modules/sass-embedded-darwin-x64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.97.0.tgz",
|
||||||
"integrity": "sha512-J/R5sv0eW+/DU98rccHPO1f3lsTFjVTpdkU9d3P1yB7BFmQjw5PYde9BVRlXeOawPwfgT3p/hvY4RELScICdww==",
|
"integrity": "sha512-Kc0aKFfKPd/kz8mSGtRKTEN7FKnqs30iZf6APb0ZHMuvMVfOfdD+fZ/85htT+j5k2F+UUSFBpbx04W0gZW020A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4427,9 +4427,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-arm": {
|
"node_modules/sass-embedded-linux-arm": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.97.0.tgz",
|
||||||
"integrity": "sha512-XuQvV6gNld5Bz3rX0SFLtKPGMu4UQdXNp//9A+bDmtVGZ6yu8REIqphQBxOMpgkAKsA4JZLKKk1N97woeVsIlA==",
|
"integrity": "sha512-pwM5A1+w3l1T/FXwJNqZD0WukCENeRkgxPSpZmsO4/QNLdTpGCz16D5spYPQ7f7GZo9aNaHt1EaDLHCjlEA8LQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -4443,9 +4443,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-arm64": {
|
"node_modules/sass-embedded-linux-arm64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.97.0.tgz",
|
||||||
"integrity": "sha512-VcbVjK0/O/mru0h0FC1WSUWIzMqRrzuJ8eZNMXTs4vApfkh28pxNaUodwU81f1L1nngJ3vpFDBniUKpW6NwJhw==",
|
"integrity": "sha512-ofm9esPA9P0sB6wJPcDhQYjSDfa7RoVKD0IHvFPMrK9OLTKg8lw80/afH49a9URYeYiE4wFP76Fr9t+s7A6E1Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4459,9 +4459,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-musl-arm": {
|
"node_modules/sass-embedded-linux-musl-arm": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.97.0.tgz",
|
||||||
"integrity": "sha512-qK7FrnczCVECZXtyYOoI3azFlMDZn70GI1yJPPuZLpWvwIPYoZOLv3u6JSec5o3wT6KeKyWG3ZpGIpigLUjPig==",
|
"integrity": "sha512-+rsW0OreW4sPtdXDewDESxJLJdxW3B0EL7ICajkRFs3KbeNdgOVnP5DJQ39hquAoZH0AcEEGcd6236ZMMzEbwQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -4475,9 +4475,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-musl-arm64": {
|
"node_modules/sass-embedded-linux-musl-arm64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.97.0.tgz",
|
||||||
"integrity": "sha512-lVyLObEeu8Wgw8riC6dSMlkF7jVNAjdZ1jIBhvX1yDsrQwwaI60pM21YXmnZSFyCE6KVFkKAgwRQNO/IkoCwMA==",
|
"integrity": "sha512-8VF4nc7oUklhUGGAY0T6Ktd9T9ZFwoOsWje7ocOV57tjbocFp/eeAPqX1v2BpiZtMVURyYwaZsRSAL79DT7oRw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4491,9 +4491,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-musl-riscv64": {
|
"node_modules/sass-embedded-linux-musl-riscv64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.97.0.tgz",
|
||||||
"integrity": "sha512-Y+DuGVRsM2zGl268QN5aF/Y6OFYTILb3f+6huEXKlGL6FK2MXadsmeoVbmKVrTamQHzyA2bWWMU1C0jhVFtlzg==",
|
"integrity": "sha512-nlaeeZ5P7tde/c/aMiIl5UduQZPA9ftEyWJxdmWcs3pASFSykslVJR5D4L161EUHzB5z+MxSnbbzcrck0F1slA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -4507,9 +4507,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-musl-x64": {
|
"node_modules/sass-embedded-linux-musl-x64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.97.0.tgz",
|
||||||
"integrity": "sha512-sAQtUQ8fFNxnxSf3fncOh892Hfxa4PW4e5qrnSE0Y1IGV/wsTzk7m5Z6IeT7sa3BsvXh5TFN6+JGbUoOJ5RigA==",
|
"integrity": "sha512-QB6JLr2p1UuEXhiTXEYNypf+w2x/SCMY17vcnXKM47CeaJ88v2C9fJ9oVne6eZntlCylSow/vZCov0JMhklknA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4523,9 +4523,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-riscv64": {
|
"node_modules/sass-embedded-linux-riscv64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.97.0.tgz",
|
||||||
"integrity": "sha512-Bf6bAjuUm6sfGHo0XoZEstjVkEWwmmtOSomGoPuAwXFS9GQnFcqDz9EXKNkZEOsQi2D+aDeDxs8HcU9/OLMT9g==",
|
"integrity": "sha512-m7QaK4M+YhQ6FZWMI9O8g4tqmM4JrvzJl/YC/eEJXpfgwxMeXsDsPVQWFiBdWOuxqMSH8WhFksw/Bg0J+kK6VQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -4539,9 +4539,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-linux-x64": {
|
"node_modules/sass-embedded-linux-x64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.97.0.tgz",
|
||||||
"integrity": "sha512-U4GROkS0XM6ekqs/ubroWwFAGY9N35wqrt5q6Y+MJCpTK5bHPHlgFo7J75ZUSaEObL+UrDqvMDQkCdYEFiiQbg==",
|
"integrity": "sha512-yc7yLWJrAtTBCjEAoNxvE040EGYdsgmaWMSyI9LSIOFlSwrOc4x+W/8IMhLWCygTAgorNPuNlRfPDgkQm1sJmw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4555,9 +4555,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-unknown-all": {
|
"node_modules/sass-embedded-unknown-all": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.97.0.tgz",
|
||||||
"integrity": "sha512-OHzGEr2VElK2SaQdkkTX0O0KwTbiv1N/EhnHgzXYaZWOTvv0gxEfR7q7x/oScCBIZc2x8dSfvThfBnohIClo/w==",
|
"integrity": "sha512-dDky3ETKeOo543myScL4sp3pj2cANLNKea5aR6v8ZCpDSCDTRxqv4Sj/goTmkVqnp/HOVF88qB3GHtQ8rFtULQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -4567,13 +4567,13 @@
|
|||||||
"!win32"
|
"!win32"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sass": "1.96.0"
|
"sass": "1.97.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-win32-arm64": {
|
"node_modules/sass-embedded-win32-arm64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.97.0.tgz",
|
||||||
"integrity": "sha512-KKz1h5pr45fwrKcxrxHsujo3f/HgVkX64YNJ9PRPuOuX7lU8g18IEgDxoTGQ64PPBQ5RXOt6jxpT+x2OLPVnCw==",
|
"integrity": "sha512-JMU2SKIgUJDw4oaKBcVbuobWRU6f2XmFuYqJdkxJhlITAGimwjZ860gttlzjNtZcVI4+p4ovT14HwpsEcIzfnw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4587,9 +4587,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass-embedded-win32-x64": {
|
"node_modules/sass-embedded-win32-x64": {
|
||||||
"version": "1.96.0",
|
"version": "1.97.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.96.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.97.0.tgz",
|
||||||
"integrity": "sha512-MDreKaWcgiyKD5YPShaRvUBoe5dC2y8IPJK49G7iQjoMfw9INDCBkDdLcz00Mn0eJq4nJJp5UEE98M6ljIrBRg==",
|
"integrity": "sha512-mKIJGXxEl6OoWEoT4ee5OsBOfExla2ilY5J8tupVwSCxf/i3aOJNLm7ZzRWG9er2K3bC8aovgMisMIVGlBM5hw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4958,9 +4958,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
||||||
"integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
|
"integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [2.0.0] - 2025-12-17
|
||||||
|
- Add rotate sprite to context menu
|
||||||
|
- Add flip sprite to context menu
|
||||||
|
- Add multi select for sprite removal
|
||||||
|
|
||||||
## [1.9.0] - 2025-12-14
|
## [1.9.0] - 2025-12-14
|
||||||
- You can now share spritesheets to edit them later or share them with others
|
- You can now share spritesheets to edit them later or share them with others
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,18 @@
|
|||||||
<i class="fas fa-plus text-blue-600 dark:text-blue-400"></i>
|
<i class="fas fa-plus text-blue-600 dark:text-blue-400"></i>
|
||||||
<span>Add Sprite</span>
|
<span>Add Sprite</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="contextMenuSpriteId" @click="rotateSpriteInMenu(90)" class="w-full px-5 py-3 text-left hover:bg-green-50 dark:hover:bg-green-900/30 text-gray-700 dark:text-gray-200 flex items-center gap-3 transition-colors font-medium">
|
||||||
|
<i class="fas fa-redo text-green-600 dark:text-green-400"></i>
|
||||||
|
<span>Rotate +90°</span>
|
||||||
|
</button>
|
||||||
|
<button v-if="contextMenuSpriteId" @click="flipSpriteInMenu('horizontal')" class="w-full px-5 py-3 text-left hover:bg-orange-50 dark:hover:bg-orange-900/30 text-gray-700 dark:text-gray-200 flex items-center gap-3 transition-colors font-medium">
|
||||||
|
<i class="fas fa-arrows-alt-h text-orange-600 dark:text-orange-400"></i>
|
||||||
|
<span>Flip Horizontal</span>
|
||||||
|
</button>
|
||||||
|
<button v-if="contextMenuSpriteId" @click="flipSpriteInMenu('vertical')" class="w-full px-5 py-3 text-left hover:bg-orange-50 dark:hover:bg-orange-900/30 text-gray-700 dark:text-gray-200 flex items-center gap-3 transition-colors font-medium">
|
||||||
|
<i class="fas fa-arrows-alt-v text-orange-600 dark:text-orange-400"></i>
|
||||||
|
<span>Flip Vertical</span>
|
||||||
|
</button>
|
||||||
<button v-if="contextMenuSpriteId" @click="replaceSprite" class="w-full px-5 py-3 text-left hover:bg-purple-50 dark:hover:bg-purple-900/30 text-gray-700 dark:text-gray-200 flex items-center gap-3 transition-colors font-medium">
|
<button v-if="contextMenuSpriteId" @click="replaceSprite" class="w-full px-5 py-3 text-left hover:bg-purple-50 dark:hover:bg-purple-900/30 text-gray-700 dark:text-gray-200 flex items-center gap-3 transition-colors font-medium">
|
||||||
<i class="fas fa-exchange-alt text-purple-600 dark:text-purple-400"></i>
|
<i class="fas fa-exchange-alt text-purple-600 dark:text-purple-400"></i>
|
||||||
<span>Replace Sprite</span>
|
<span>Replace Sprite</span>
|
||||||
@@ -12,7 +24,7 @@
|
|||||||
<div v-if="contextMenuSpriteId" class="h-px bg-gray-200 dark:bg-gray-600 my-1"></div>
|
<div v-if="contextMenuSpriteId" class="h-px bg-gray-200 dark:bg-gray-600 my-1"></div>
|
||||||
<button v-if="contextMenuSpriteId" @click="removeSprite" class="w-full px-5 py-3 text-left hover:bg-red-50 dark:hover:bg-red-900/30 text-red-600 dark:text-red-400 flex items-center gap-3 transition-colors font-medium">
|
<button v-if="contextMenuSpriteId" @click="removeSprite" class="w-full px-5 py-3 text-left hover:bg-red-50 dark:hover:bg-red-900/30 text-red-600 dark:text-red-400 flex items-center gap-3 transition-colors font-medium">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
<span>Remove Sprite</span>
|
<span>{{ selectedSpriteIds.size > 1 ? `Remove ${selectedSpriteIds.size} Sprites` : 'Remove Sprite' }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
@@ -27,6 +39,15 @@
|
|||||||
<div class="flex flex-wrap items-center gap-1">
|
<div class="flex flex-wrap items-center gap-1">
|
||||||
<!-- Toggles Group -->
|
<!-- Toggles Group -->
|
||||||
<div class="flex items-center gap-1 p-1">
|
<div class="flex items-center gap-1 p-1">
|
||||||
|
<label class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer transition-colors" title="Toggle Multi-Select Mode">
|
||||||
|
<input id="multi-select-mode" type="checkbox" v-model="isMultiSelectMode" class="w-4 h-4 rounded text-blue-600 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600" />
|
||||||
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Multi-Select</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer transition-colors" title="Show Selection Borders">
|
||||||
|
<input id="show-active-border" type="checkbox" v-model="showActiveBorder" class="w-4 h-4 rounded text-blue-600 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600" />
|
||||||
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Borders</span>
|
||||||
|
</label>
|
||||||
|
<div class="w-px h-4 bg-gray-200 dark:bg-gray-700 mx-1"></div>
|
||||||
<label class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer transition-colors" title="Pixel Perfect">
|
<label class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer transition-colors" title="Pixel Perfect">
|
||||||
<input id="pixel-perfect" type="checkbox" v-model="settingsStore.pixelPerfect" class="w-4 h-4 rounded text-blue-600 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600" />
|
<input id="pixel-perfect" type="checkbox" v-model="settingsStore.pixelPerfect" class="w-4 h-4 rounded text-blue-600 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600" />
|
||||||
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Pixel Perfect</span>
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Pixel Perfect</span>
|
||||||
@@ -181,7 +202,8 @@
|
|||||||
<img
|
<img
|
||||||
v-if="!(activeSpriteId === sprite.id && ghostSprite)"
|
v-if="!(activeSpriteId === sprite.id && ghostSprite)"
|
||||||
:src="sprite.url"
|
:src="sprite.url"
|
||||||
class="absolute cursor-move"
|
class="absolute cursor-move transition-transform duration-200"
|
||||||
|
:class="{ 'ring-2 ring-blue-500 ring-offset-1 dark:ring-offset-gray-900': showActiveBorder && selectedSpriteIds.has(sprite.id) }"
|
||||||
:style="{
|
:style="{
|
||||||
left: `${getCellPosition(index).x + gridMetrics.negativeSpacing + sprite.x}px`,
|
left: `${getCellPosition(index).x + gridMetrics.negativeSpacing + sprite.x}px`,
|
||||||
top: `${getCellPosition(index).y + gridMetrics.negativeSpacing + sprite.y}px`,
|
top: `${getCellPosition(index).y + gridMetrics.negativeSpacing + sprite.y}px`,
|
||||||
@@ -189,6 +211,7 @@
|
|||||||
height: `${sprite.height}px`,
|
height: `${sprite.height}px`,
|
||||||
opacity: layer.id === activeLayerId ? '1' : '0.85',
|
opacity: layer.id === activeLayerId ? '1' : '0.85',
|
||||||
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
||||||
|
transform: `rotate(${sprite.rotation}deg) scale(${sprite.flipX ? -1 : 1}, ${sprite.flipY ? -1 : 1})`,
|
||||||
}"
|
}"
|
||||||
:data-sprite-id="sprite.id"
|
:data-sprite-id="sprite.id"
|
||||||
:data-layer-id="layer.id"
|
:data-layer-id="layer.id"
|
||||||
@@ -210,6 +233,7 @@
|
|||||||
height: `${activeSpriteSprite?.height}px`,
|
height: `${activeSpriteSprite?.height}px`,
|
||||||
opacity: '0.6',
|
opacity: '0.6',
|
||||||
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
||||||
|
transform: `rotate(${activeSpriteSprite?.rotation || 0}deg) scale(${activeSpriteSprite?.flipX ? -1 : 1}, ${activeSpriteSprite?.flipY ? -1 : 1})`,
|
||||||
}"
|
}"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
/>
|
/>
|
||||||
@@ -256,9 +280,12 @@
|
|||||||
(e: 'updateSprite', id: string, x: number, y: number): void;
|
(e: 'updateSprite', id: string, x: number, y: number): void;
|
||||||
(e: 'updateSpriteCell', id: string, newIndex: number): void;
|
(e: 'updateSpriteCell', id: string, newIndex: number): void;
|
||||||
(e: 'removeSprite', id: string): void;
|
(e: 'removeSprite', id: string): void;
|
||||||
|
(e: 'removeSprites', ids: string[]): void;
|
||||||
(e: 'replaceSprite', id: string, file: File): void;
|
(e: 'replaceSprite', id: string, file: File): void;
|
||||||
(e: 'addSprite', file: File): void;
|
(e: 'addSprite', file: File): void;
|
||||||
(e: 'addSpriteWithResize', file: File): void;
|
(e: 'addSpriteWithResize', file: File): void;
|
||||||
|
(e: 'rotateSprite', id: string, angle: number): void;
|
||||||
|
(e: 'flipSprite', id: string, direction: 'horizontal' | 'vertical'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// Get settings from store
|
// Get settings from store
|
||||||
@@ -337,9 +364,17 @@
|
|||||||
const contextMenuX = ref(0);
|
const contextMenuX = ref(0);
|
||||||
const contextMenuY = ref(0);
|
const contextMenuY = ref(0);
|
||||||
const contextMenuSpriteId = ref<string | null>(null);
|
const contextMenuSpriteId = ref<string | null>(null);
|
||||||
|
const selectedSpriteIds = ref<Set<string>>(new Set());
|
||||||
const replacingSpriteId = ref<string | null>(null);
|
const replacingSpriteId = ref<string | null>(null);
|
||||||
const fileInput = ref<HTMLInputElement | null>(null);
|
const fileInput = ref<HTMLInputElement | null>(null);
|
||||||
const customColor = ref('#ffffff');
|
const customColor = ref('#ffffff');
|
||||||
|
const isMultiSelectMode = ref(false);
|
||||||
|
const showActiveBorder = ref(true);
|
||||||
|
|
||||||
|
// Clear selection when toggling multi-select mode
|
||||||
|
watch(isMultiSelectMode, () => {
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
});
|
||||||
|
|
||||||
// Grid metrics
|
// Grid metrics
|
||||||
const gridMetrics = computed(() => calculateMaxDimensions());
|
const gridMetrics = computed(() => calculateMaxDimensions());
|
||||||
@@ -467,6 +502,18 @@
|
|||||||
const clickedSprite = findSpriteAtPosition(pos.x, pos.y);
|
const clickedSprite = findSpriteAtPosition(pos.x, pos.y);
|
||||||
contextMenuSpriteId.value = clickedSprite?.id || null;
|
contextMenuSpriteId.value = clickedSprite?.id || null;
|
||||||
|
|
||||||
|
if (clickedSprite) {
|
||||||
|
// If the right-clicked sprite is not in the selection, clear selection and select just this one
|
||||||
|
if (!selectedSpriteIds.value.has(clickedSprite.id)) {
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
selectedSpriteIds.value.add(clickedSprite.id);
|
||||||
|
}
|
||||||
|
// If it IS in the selection, keep the current selection (so we can apply action to all)
|
||||||
|
} else {
|
||||||
|
// Right click on empty space
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
}
|
||||||
|
|
||||||
contextMenuX.value = event.clientX;
|
contextMenuX.value = event.clientX;
|
||||||
contextMenuY.value = event.clientY;
|
contextMenuY.value = event.clientY;
|
||||||
|
|
||||||
@@ -477,6 +524,34 @@
|
|||||||
// Ignore non-left mouse buttons
|
// Ignore non-left mouse buttons
|
||||||
if ('button' in event && (event as MouseEvent).button !== 0) return;
|
if ('button' in event && (event as MouseEvent).button !== 0) return;
|
||||||
|
|
||||||
|
// Handle selection logic for left click
|
||||||
|
const pos = getMousePosition(event, zoom.value);
|
||||||
|
if (pos) {
|
||||||
|
const clickedSprite = findSpriteAtPosition(pos.x, pos.y);
|
||||||
|
if (clickedSprite) {
|
||||||
|
// Selection logic with multi-select mode check
|
||||||
|
if (event.ctrlKey || event.metaKey || isMultiSelectMode.value) {
|
||||||
|
// Toggle selection
|
||||||
|
if (selectedSpriteIds.value.has(clickedSprite.id)) {
|
||||||
|
selectedSpriteIds.value.delete(clickedSprite.id);
|
||||||
|
} else {
|
||||||
|
selectedSpriteIds.value.add(clickedSprite.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Single select (but don't clear if dragging starts immediately?
|
||||||
|
// Usually standard behavior is to clear others unless shift/ctrl held)
|
||||||
|
if (!selectedSpriteIds.value.has(clickedSprite.id)) {
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
selectedSpriteIds.value.add(clickedSprite.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Clicked on empty space
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delegate to composable for actual drag handling
|
// Delegate to composable for actual drag handling
|
||||||
dragStart(event);
|
dragStart(event);
|
||||||
};
|
};
|
||||||
@@ -500,13 +575,52 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const removeSprite = () => {
|
const removeSprite = () => {
|
||||||
if (contextMenuSpriteId.value) {
|
if (selectedSpriteIds.value.size > 0) {
|
||||||
|
emit('removeSprites', Array.from(selectedSpriteIds.value));
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
showContextMenu.value = false;
|
||||||
|
contextMenuSpriteId.value = null;
|
||||||
|
} else if (contextMenuSpriteId.value) {
|
||||||
emit('removeSprite', contextMenuSpriteId.value);
|
emit('removeSprite', contextMenuSpriteId.value);
|
||||||
showContextMenu.value = false;
|
showContextMenu.value = false;
|
||||||
contextMenuSpriteId.value = null;
|
contextMenuSpriteId.value = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rotateSpriteInMenu = (angle: number) => {
|
||||||
|
if (selectedSpriteIds.value.size > 0) {
|
||||||
|
selectedSpriteIds.value.forEach(id => {
|
||||||
|
emit('rotateSprite', id, angle);
|
||||||
|
});
|
||||||
|
} else if (contextMenuSpriteId.value) {
|
||||||
|
emit('rotateSprite', contextMenuSpriteId.value, angle);
|
||||||
|
}
|
||||||
|
showContextMenu.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const flipSpriteInMenu = (direction: 'horizontal' | 'vertical') => {
|
||||||
|
if (selectedSpriteIds.value.size > 0) {
|
||||||
|
selectedSpriteIds.value.forEach(id => {
|
||||||
|
emit('flipSprite', id, direction);
|
||||||
|
});
|
||||||
|
} else if (contextMenuSpriteId.value) {
|
||||||
|
emit('flipSprite', contextMenuSpriteId.value, direction);
|
||||||
|
}
|
||||||
|
showContextMenu.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === 'Delete' || event.key === 'Backspace') {
|
||||||
|
// Don't delete if editing text/input
|
||||||
|
if (document.activeElement?.tagName === 'INPUT' || document.activeElement?.tagName === 'TEXTAREA') return;
|
||||||
|
|
||||||
|
if (selectedSpriteIds.value.size > 0) {
|
||||||
|
emit('removeSprites', Array.from(selectedSpriteIds.value));
|
||||||
|
selectedSpriteIds.value.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const replaceSprite = () => {
|
const replaceSprite = () => {
|
||||||
if (contextMenuSpriteId.value && fileInput.value) {
|
if (contextMenuSpriteId.value && fileInput.value) {
|
||||||
replacingSpriteId.value = contextMenuSpriteId.value;
|
replacingSpriteId.value = contextMenuSpriteId.value;
|
||||||
@@ -554,10 +668,12 @@
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('mouseup', stopDrag);
|
document.addEventListener('mouseup', stopDrag);
|
||||||
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
document.removeEventListener('mouseup', stopDrag);
|
document.removeEventListener('mouseup', stopDrag);
|
||||||
|
document.removeEventListener('keydown', handleKeyDown);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch for background color changes
|
// Watch for background color changes
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
height: `${layer.sprites[i - 1].height}px`,
|
height: `${layer.sprites[i - 1].height}px`,
|
||||||
opacity: '0.3',
|
opacity: '0.3',
|
||||||
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
||||||
|
transform: `rotate(${layer.sprites[i - 1].rotation || 0}deg) scale(${layer.sprites[i - 1].flipX ? -1 : 1}, ${layer.sprites[i - 1].flipY ? -1 : 1})`,
|
||||||
}"
|
}"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
/>
|
/>
|
||||||
@@ -62,6 +63,7 @@
|
|||||||
width: `${layer.sprites[currentFrameIndex].width}px`,
|
width: `${layer.sprites[currentFrameIndex].width}px`,
|
||||||
height: `${layer.sprites[currentFrameIndex].height}px`,
|
height: `${layer.sprites[currentFrameIndex].height}px`,
|
||||||
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
imageRendering: settingsStore.pixelPerfect ? 'pixelated' : 'auto',
|
||||||
|
transform: `rotate(${layer.sprites[currentFrameIndex].rotation || 0}deg) scale(${layer.sprites[currentFrameIndex].flipX ? -1 : 1}, ${layer.sprites[currentFrameIndex].flipY ? -1 : 1})`,
|
||||||
}"
|
}"
|
||||||
@mousedown="startDrag($event, layer.sprites[currentFrameIndex], layer.id)"
|
@mousedown="startDrag($event, layer.sprites[currentFrameIndex], layer.id)"
|
||||||
@touchstart="handleTouchStart($event, layer.sprites[currentFrameIndex], layer.id)"
|
@touchstart="handleTouchStart($event, layer.sprites[currentFrameIndex], layer.id)"
|
||||||
@@ -213,7 +215,7 @@
|
|||||||
@change="toggleHiddenFrame(index)"
|
@change="toggleHiddenFrame(index)"
|
||||||
/>
|
/>
|
||||||
<div class="w-8 h-8 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded flex items-center justify-center overflow-hidden flex-shrink-0 shadow-sm">
|
<div class="w-8 h-8 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded flex items-center justify-center overflow-hidden flex-shrink-0 shadow-sm">
|
||||||
<img :src="sprite.url" class="max-w-full max-h-full object-contain" :style="settingsStore.pixelPerfect ? { 'image-rendering': 'pixelated' } : {}" />
|
<img :src="sprite.url" class="max-w-full max-h-full object-contain" :style="{ ...(settingsStore.pixelPerfect ? { 'image-rendering': 'pixelated' } : {}), transform: `rotate(${sprite.rotation || 0}deg) scale(${sprite.flipX ? -1 : 1}, ${sprite.flipY ? -1 : 1})` }" />
|
||||||
</div>
|
</div>
|
||||||
<span class="text-xs font-mono text-gray-600 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Frame {{ index + 1 }}</span>
|
<span class="text-xs font-mono text-gray-600 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Frame {{ index + 1 }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -55,7 +55,18 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
const row = Math.floor(index / columns.value);
|
const row = Math.floor(index / columns.value);
|
||||||
const cellX = Math.floor(col * cellWidth);
|
const cellX = Math.floor(col * cellWidth);
|
||||||
const cellY = Math.floor(row * cellHeight);
|
const cellY = Math.floor(row * cellHeight);
|
||||||
ctx.drawImage(sprite.img, Math.floor(cellX + negativeSpacing + sprite.x), Math.floor(cellY + negativeSpacing + sprite.y));
|
if (sprite.rotation || sprite.flipX || sprite.flipY) {
|
||||||
|
ctx.save();
|
||||||
|
const centerX = Math.floor(cellX + negativeSpacing + sprite.x + sprite.width / 2);
|
||||||
|
const centerY = Math.floor(cellY + negativeSpacing + sprite.y + sprite.height / 2);
|
||||||
|
ctx.translate(centerX, centerY);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.scale(sprite.flipX ? -1 : 1, sprite.flipY ? -1 : 1);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, Math.floor(cellX + negativeSpacing + sprite.x), Math.floor(cellY + negativeSpacing + sprite.y));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
@@ -77,7 +88,15 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
if (!ctx) return null;
|
if (!ctx) return null;
|
||||||
canvas.width = sprite.width;
|
canvas.width = sprite.width;
|
||||||
canvas.height = sprite.height;
|
canvas.height = sprite.height;
|
||||||
ctx.drawImage(sprite.img, 0, 0);
|
if (sprite.rotation) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(sprite.width / 2, sprite.height / 2);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, 0, 0);
|
||||||
|
}
|
||||||
const base64Data = canvas.toDataURL('image/png');
|
const base64Data = canvas.toDataURL('image/png');
|
||||||
return {
|
return {
|
||||||
id: sprite.id,
|
id: sprite.id,
|
||||||
@@ -85,6 +104,9 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
height: sprite.height,
|
height: sprite.height,
|
||||||
x: sprite.x,
|
x: sprite.x,
|
||||||
y: sprite.y,
|
y: sprite.y,
|
||||||
|
rotation: sprite.rotation || 0,
|
||||||
|
flipX: sprite.flipX || false,
|
||||||
|
flipY: sprite.flipY || false,
|
||||||
base64: base64Data,
|
base64: base64Data,
|
||||||
name: sprite.file.name,
|
name: sprite.file.name,
|
||||||
};
|
};
|
||||||
@@ -156,6 +178,9 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
height: spriteData.height,
|
height: spriteData.height,
|
||||||
x: spriteData.x || 0,
|
x: spriteData.x || 0,
|
||||||
y: spriteData.y || 0,
|
y: spriteData.y || 0,
|
||||||
|
rotation: spriteData.rotation || 0,
|
||||||
|
flipX: spriteData.flipX || false,
|
||||||
|
flipY: spriteData.flipY || false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
img.src = spriteData.base64;
|
img.src = spriteData.base64;
|
||||||
@@ -189,7 +214,17 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
ctx.fillStyle = backgroundColor.value;
|
ctx.fillStyle = backgroundColor.value;
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
if (sprite.rotation) {
|
||||||
|
ctx.save();
|
||||||
|
const centerX = Math.floor(negativeSpacing + sprite.x + sprite.width / 2);
|
||||||
|
const centerY = Math.floor(negativeSpacing + sprite.y + sprite.height / 2);
|
||||||
|
ctx.translate(centerX, centerY);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
||||||
|
}
|
||||||
gif.addFrame(ctx, { copy: true, delay: 1000 / fps });
|
gif.addFrame(ctx, { copy: true, delay: 1000 / fps });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -227,7 +262,17 @@ export const useExport = (sprites: Ref<Sprite[]>, columns: Ref<number>, negative
|
|||||||
ctx.fillStyle = backgroundColor.value;
|
ctx.fillStyle = backgroundColor.value;
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
if (sprite.rotation) {
|
||||||
|
ctx.save();
|
||||||
|
const centerX = Math.floor(negativeSpacing + sprite.x + sprite.width / 2);
|
||||||
|
const centerY = Math.floor(negativeSpacing + sprite.y + sprite.height / 2);
|
||||||
|
ctx.translate(centerX, centerY);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
||||||
|
}
|
||||||
const dataURL = canvas.toDataURL('image/png');
|
const dataURL = canvas.toDataURL('image/png');
|
||||||
const binary = atob(dataURL.split(',')[1]);
|
const binary = atob(dataURL.split(',')[1]);
|
||||||
const buf = new ArrayBuffer(binary.length);
|
const buf = new ArrayBuffer(binary.length);
|
||||||
|
|||||||
@@ -42,7 +42,19 @@ export const useExportLayers = (layersRef: Ref<Layer[]>, columns: Ref<number>, n
|
|||||||
vLayers.forEach(layer => {
|
vLayers.forEach(layer => {
|
||||||
const sprite = layer.sprites[cellIndex];
|
const sprite = layer.sprites[cellIndex];
|
||||||
if (!sprite) return;
|
if (!sprite) return;
|
||||||
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
|
||||||
|
if (sprite.rotation || sprite.flipX || sprite.flipY) {
|
||||||
|
ctx.save();
|
||||||
|
const centerX = Math.floor(negativeSpacing + sprite.x + sprite.width / 2);
|
||||||
|
const centerY = Math.floor(negativeSpacing + sprite.y + sprite.height / 2);
|
||||||
|
ctx.translate(centerX, centerY);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.scale(sprite.flipX ? -1 : 1, sprite.flipY ? -1 : 1);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, Math.floor(negativeSpacing + sprite.x), Math.floor(negativeSpacing + sprite.y));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,7 +122,7 @@ export const useExportLayers = (layersRef: Ref<Layer[]>, columns: Ref<number>, n
|
|||||||
canvas.height = sprite.height;
|
canvas.height = sprite.height;
|
||||||
ctx.drawImage(sprite.img, 0, 0);
|
ctx.drawImage(sprite.img, 0, 0);
|
||||||
const base64 = canvas.toDataURL('image/png');
|
const base64 = canvas.toDataURL('image/png');
|
||||||
return { id: sprite.id, width: sprite.width, height: sprite.height, x: sprite.x, y: sprite.y, base64, name: sprite.file.name };
|
return { id: sprite.id, width: sprite.width, height: sprite.height, x: sprite.x, y: sprite.y, rotation: sprite.rotation, flipX: sprite.flipX, flipY: sprite.flipY, base64, name: sprite.file.name };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
return { id: layer.id, name: layer.name, visible: layer.visible, locked: layer.locked, sprites: sprites.filter(Boolean) };
|
return { id: layer.id, name: layer.name, visible: layer.visible, locked: layer.locked, sprites: sprites.filter(Boolean) };
|
||||||
@@ -153,7 +165,7 @@ export const useExportLayers = (layersRef: Ref<Layer[]>, columns: Ref<number>, n
|
|||||||
const blob = new Blob([ab], { type: mimeType });
|
const blob = new Blob([ab], { type: mimeType });
|
||||||
const fileName = spriteData.name || `sprite-${spriteData.id}.png`;
|
const fileName = spriteData.name || `sprite-${spriteData.id}.png`;
|
||||||
const file = new File([blob], fileName, { type: mimeType });
|
const file = new File([blob], fileName, { type: mimeType });
|
||||||
resolve({ id: spriteData.id || crypto.randomUUID(), file, img, url: spriteData.base64, width: spriteData.width, height: spriteData.height, x: spriteData.x || 0, y: spriteData.y || 0 });
|
resolve({ id: spriteData.id || crypto.randomUUID(), file, img, url: spriteData.base64, width: spriteData.width, height: spriteData.height, x: spriteData.x || 0, y: spriteData.y || 0, rotation: spriteData.rotation || 0, flipX: spriteData.flipX || false, flipY: spriteData.flipY || false });
|
||||||
};
|
};
|
||||||
img.src = spriteData.base64;
|
img.src = spriteData.base64;
|
||||||
});
|
});
|
||||||
@@ -273,7 +285,7 @@ export const useExportLayers = (layersRef: Ref<Layer[]>, columns: Ref<number>, n
|
|||||||
name: layer.name,
|
name: layer.name,
|
||||||
visible: layer.visible,
|
visible: layer.visible,
|
||||||
locked: layer.locked,
|
locked: layer.locked,
|
||||||
sprites: await Promise.all(layer.sprites.map(async s => ({ id: s.id, width: s.width, height: s.height, x: s.x, y: s.y, name: s.file.name }))),
|
sprites: await Promise.all(layer.sprites.map(async s => ({ id: s.id, width: s.width, height: s.height, x: s.x, y: s.y, rotation: s.rotation, flipX: s.flipX, flipY: s.flipY, name: s.file.name }))),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
const meta = {
|
const meta = {
|
||||||
|
|||||||
@@ -130,6 +130,49 @@ export const useLayers = () => {
|
|||||||
l.sprites.splice(i, 1);
|
l.sprites.splice(i, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeSprites = (ids: string[]) => {
|
||||||
|
const l = activeLayer.value;
|
||||||
|
if (!l) return;
|
||||||
|
|
||||||
|
// Sort indices in descending order to avoid shift issues when splicing
|
||||||
|
const indicesToRemove: number[] = [];
|
||||||
|
ids.forEach(id => {
|
||||||
|
const i = l.sprites.findIndex(s => s.id === id);
|
||||||
|
if (i !== -1) indicesToRemove.push(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
indicesToRemove.sort((a, b) => b - a);
|
||||||
|
|
||||||
|
indicesToRemove.forEach(i => {
|
||||||
|
const s = l.sprites[i];
|
||||||
|
if (s.url && s.url.startsWith('blob:')) {
|
||||||
|
try {
|
||||||
|
URL.revokeObjectURL(s.url);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
l.sprites.splice(i, 1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const rotateSprite = (id: string, angle: number) => {
|
||||||
|
const l = activeLayer.value;
|
||||||
|
if (!l) return;
|
||||||
|
const s = l.sprites.find(s => s.id === id);
|
||||||
|
if (s) {
|
||||||
|
s.rotation = (s.rotation + angle) % 360;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const flipSprite = (id: string, direction: 'horizontal' | 'vertical') => {
|
||||||
|
const l = activeLayer.value;
|
||||||
|
if (!l) return;
|
||||||
|
const s = l.sprites.find(s => s.id === id);
|
||||||
|
if (s) {
|
||||||
|
if (direction === 'horizontal') s.flipX = !s.flipX;
|
||||||
|
if (direction === 'vertical') s.flipY = !s.flipY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const replaceSprite = (id: string, file: File) => {
|
const replaceSprite = (id: string, file: File) => {
|
||||||
const l = activeLayer.value;
|
const l = activeLayer.value;
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
@@ -147,7 +190,7 @@ export const useLayers = () => {
|
|||||||
const url = e.target?.result as string;
|
const url = e.target?.result as string;
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
l.sprites[i] = { id: old.id, file, img, url, width: img.width, height: img.height, x: old.x, y: old.y };
|
l.sprites[i] = { id: old.id, file, img, url, width: img.width, height: img.height, x: old.x, y: old.y, rotation: old.rotation, flipX: old.flipX || false, flipY: old.flipY || false };
|
||||||
};
|
};
|
||||||
img.onerror = () => {
|
img.onerror = () => {
|
||||||
console.error('Failed to load replacement image:', file.name);
|
console.error('Failed to load replacement image:', file.name);
|
||||||
@@ -177,6 +220,9 @@ export const useLayers = () => {
|
|||||||
height: img.height,
|
height: img.height,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
rotation: 0,
|
||||||
|
flipX: false,
|
||||||
|
flipY: false,
|
||||||
};
|
};
|
||||||
l.sprites = [...l.sprites, next];
|
l.sprites = [...l.sprites, next];
|
||||||
};
|
};
|
||||||
@@ -233,6 +279,9 @@ export const useLayers = () => {
|
|||||||
updateSpriteInLayer,
|
updateSpriteInLayer,
|
||||||
updateSpriteCell,
|
updateSpriteCell,
|
||||||
removeSprite,
|
removeSprite,
|
||||||
|
removeSprites,
|
||||||
|
rotateSprite,
|
||||||
|
flipSprite,
|
||||||
replaceSprite,
|
replaceSprite,
|
||||||
addSprite,
|
addSprite,
|
||||||
processImageFiles,
|
processImageFiles,
|
||||||
|
|||||||
@@ -48,7 +48,16 @@ export const shareSpritesheet = async (layersRef: Ref<Layer[]>, columns: Ref<num
|
|||||||
if (!ctx) return null;
|
if (!ctx) return null;
|
||||||
canvas.width = sprite.width;
|
canvas.width = sprite.width;
|
||||||
canvas.height = sprite.height;
|
canvas.height = sprite.height;
|
||||||
ctx.drawImage(sprite.img, 0, 0);
|
if (sprite.rotation || sprite.flipX || sprite.flipY) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(sprite.width / 2, sprite.height / 2);
|
||||||
|
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
||||||
|
ctx.scale(sprite.flipX ? -1 : 1, sprite.flipY ? -1 : 1);
|
||||||
|
ctx.drawImage(sprite.img, -sprite.width / 2, -sprite.height / 2);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(sprite.img, 0, 0);
|
||||||
|
}
|
||||||
const base64 = canvas.toDataURL('image/png');
|
const base64 = canvas.toDataURL('image/png');
|
||||||
return {
|
return {
|
||||||
id: sprite.id,
|
id: sprite.id,
|
||||||
@@ -56,6 +65,9 @@ export const shareSpritesheet = async (layersRef: Ref<Layer[]>, columns: Ref<num
|
|||||||
height: sprite.height,
|
height: sprite.height,
|
||||||
x: sprite.x,
|
x: sprite.x,
|
||||||
y: sprite.y,
|
y: sprite.y,
|
||||||
|
rotation: sprite.rotation || 0,
|
||||||
|
flipX: sprite.flipX || false,
|
||||||
|
flipY: sprite.flipY || false,
|
||||||
base64,
|
base64,
|
||||||
name: sprite.file.name,
|
name: sprite.file.name,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ export interface Sprite {
|
|||||||
height: number;
|
height: number;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
rotation: number;
|
||||||
|
flipX: boolean;
|
||||||
|
flipY: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SpriteFile {
|
export interface SpriteFile {
|
||||||
|
|||||||
@@ -252,7 +252,19 @@
|
|||||||
<!-- Tab Content -->
|
<!-- Tab Content -->
|
||||||
<div class="p-6 lg:flex-1 lg:overflow-auto lg:min-h-0">
|
<div class="p-6 lg:flex-1 lg:overflow-auto lg:min-h-0">
|
||||||
<div v-if="activeTab === 'canvas'" class="h-full">
|
<div v-if="activeTab === 'canvas'" class="h-full">
|
||||||
<sprite-canvas :layers="layers" :active-layer-id="activeLayerId" :columns="columns" @update-sprite="updateSpritePosition" @update-sprite-cell="updateSpriteCell" @remove-sprite="removeSprite" @replace-sprite="replaceSprite" @add-sprite="addSprite" />
|
<sprite-canvas
|
||||||
|
:layers="layers"
|
||||||
|
:active-layer-id="activeLayerId"
|
||||||
|
:columns="columns"
|
||||||
|
@update-sprite="updateSpritePosition"
|
||||||
|
@update-sprite-cell="updateSpriteCell"
|
||||||
|
@remove-sprite="removeSprite"
|
||||||
|
@remove-sprites="removeSprites"
|
||||||
|
@replace-sprite="replaceSprite"
|
||||||
|
@add-sprite="addSprite"
|
||||||
|
@rotate-sprite="rotateSprite"
|
||||||
|
@flip-sprite="flipSprite"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="activeTab === 'preview'" class="h-full">
|
<div v-if="activeTab === 'preview'" class="h-full">
|
||||||
<sprite-preview :layers="layers" :active-layer-id="activeLayerId" :columns="columns" @update-sprite="updateSpritePosition" @update-sprite-in-layer="updateSpriteInLayer" />
|
<sprite-preview :layers="layers" :active-layer-id="activeLayerId" :columns="columns" @update-sprite="updateSpritePosition" @update-sprite-in-layer="updateSpriteInLayer" />
|
||||||
@@ -288,7 +300,7 @@
|
|||||||
useHomeViewSEO();
|
useHomeViewSEO();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const { layers, visibleLayers, activeLayer, activeLayerId, columns, updateSpritePosition, updateSpriteInLayer, updateSpriteCell, removeSprite, replaceSprite, addSprite, processImageFiles, alignSprites, addLayer, removeLayer, moveLayer } = useLayers();
|
const { layers, visibleLayers, activeLayer, activeLayerId, columns, updateSpritePosition, updateSpriteInLayer, updateSpriteCell, removeSprite, removeSprites, replaceSprite, addSprite, processImageFiles, alignSprites, addLayer, removeLayer, moveLayer, rotateSprite, flipSprite } = useLayers();
|
||||||
|
|
||||||
const { downloadSpritesheet, exportSpritesheetJSON, importSpritesheetJSON, downloadAsGif, downloadAsZip } = useExportLayers(
|
const { downloadSpritesheet, exportSpritesheetJSON, importSpritesheetJSON, downloadAsGif, downloadAsZip } = useExportLayers(
|
||||||
layers,
|
layers,
|
||||||
|
|||||||
Reference in New Issue
Block a user