svger-cli 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +399 -0
- package/README.md +448 -37
- package/SECURITY.md +3 -3
- package/assets/svges/500px.svg +3 -0
- package/assets/svges/adobe.svg +3 -0
- package/assets/svges/adonis.svg +3 -0
- package/assets/svges/aeroplane-1.svg +3 -0
- package/assets/svges/agenda.svg +3 -0
- package/assets/svges/airbnb.svg +3 -0
- package/assets/svges/airtable.svg +3 -0
- package/assets/svges/alarm-1.svg +7 -0
- package/assets/svges/align-text-center.svg +6 -0
- package/assets/svges/align-text-left.svg +6 -0
- package/assets/svges/align-text-right.svg +6 -0
- package/assets/svges/alpinejs.svg +4 -0
- package/assets/svges/amazon-original.svg +5 -0
- package/assets/svges/amazon-pay.svg +7 -0
- package/assets/svges/amazon.svg +10 -0
- package/assets/svges/ambulance-1.svg +4 -0
- package/assets/svges/amd.svg +3 -0
- package/assets/svges/amex.svg +4 -0
- package/assets/svges/anchor.svg +3 -0
- package/assets/svges/android-old.svg +3 -0
- package/assets/svges/android.svg +3 -0
- package/assets/svges/angellist.svg +3 -0
- package/assets/svges/angle-double-down.svg +4 -0
- package/assets/svges/angle-double-left.svg +4 -0
- package/assets/svges/angle-double-right.svg +4 -0
- package/assets/svges/angle-double-up.svg +4 -0
- package/assets/svges/angular.svg +3 -0
- package/assets/svges/app-store.svg +3 -0
- package/assets/svges/apple-brand.svg +3 -0
- package/assets/svges/apple-music-alt.svg +3 -0
- package/assets/svges/apple-music.svg +3 -0
- package/assets/svges/apple-pay.svg +3 -0
- package/assets/svges/arc-browser.svg +6 -0
- package/assets/svges/arrow-all-direction.svg +6 -0
- package/assets/svges/arrow-angular-top-left.svg +3 -0
- package/assets/svges/arrow-angular-top-right.svg +3 -0
- package/assets/svges/arrow-both-direction-horizontal-1.svg +3 -0
- package/assets/svges/arrow-both-direction-vertical-1.svg +3 -0
- package/assets/svges/arrow-downward.svg +3 -0
- package/assets/svges/arrow-left-circle.svg +4 -0
- package/assets/svges/arrow-left.svg +3 -0
- package/assets/svges/arrow-right-circle.svg +4 -0
- package/assets/svges/arrow-right.svg +3 -0
- package/assets/svges/arrow-upward.svg +3 -0
- package/assets/svges/asana.svg +3 -0
- package/assets/svges/astro.svg +4 -0
- package/assets/svges/atlassian.svg +3 -0
- package/assets/svges/audi-alt.svg +3 -0
- package/assets/svges/audi.svg +3 -0
- package/assets/svges/aws.svg +3 -0
- package/assets/svges/azure.svg +3 -0
- package/assets/svges/badge-decagram-percent.svg +6 -0
- package/assets/svges/balloons.svg +3 -0
- package/assets/svges/ban-2.svg +3 -0
- package/assets/svges/bar-chart-4.svg +6 -0
- package/assets/svges/bar-chart-dollar.svg +6 -0
- package/assets/svges/basket-shopping-3.svg +5 -0
- package/assets/svges/beat.svg +3 -0
- package/assets/svges/behance.svg +5 -0
- package/assets/svges/bell-1.svg +3 -0
- package/assets/svges/bike.svg +6 -0
- package/assets/svges/bing.svg +5 -0
- package/assets/svges/bitbucket.svg +5 -0
- package/assets/svges/bitcoin.svg +5 -0
- package/assets/svges/bittorrent.svg +6 -0
- package/assets/svges/blogger-alt.svg +3 -0
- package/assets/svges/blogger.svg +3 -0
- package/assets/svges/bluetooth-logo.svg +3 -0
- package/assets/svges/bluetooth.svg +3 -0
- package/assets/svges/bmw.svg +7 -0
- package/assets/svges/board-writing-3.svg +3 -0
- package/assets/svges/bold.svg +3 -0
- package/assets/svges/bolt-2.svg +3 -0
- package/assets/svges/bolt-3.svg +3 -0
- package/assets/svges/book-1.svg +4 -0
- package/assets/svges/bookmark-1.svg +3 -0
- package/assets/svges/bookmark-circle.svg +4 -0
- package/assets/svges/books-2.svg +3 -0
- package/assets/svges/bootstrap-5-square.svg +3 -0
- package/assets/svges/bootstrap-5.svg +3 -0
- package/assets/svges/box-archive-1.svg +4 -0
- package/assets/svges/box-closed.svg +3 -0
- package/assets/svges/box-gift-1.svg +3 -0
- package/assets/svges/brave.svg +3 -0
- package/assets/svges/bricks.svg +3 -0
- package/assets/svges/bridge-3.svg +3 -0
- package/assets/svges/briefcase-1.svg +3 -0
- package/assets/svges/briefcase-2.svg +3 -0
- package/assets/svges/briefcase-plus-1.svg +4 -0
- package/assets/svges/brush-1-rotated.svg +3 -0
- package/assets/svges/brush-2.svg +3 -0
- package/assets/svges/btc.svg +3 -0
- package/assets/svges/bug-1.svg +3 -0
- package/assets/svges/buildings-1.svg +5 -0
- package/assets/svges/bulb-2.svg +3 -0
- package/assets/svges/bulb-4.svg +9 -0
- package/assets/svges/burger-1.svg +3 -0
- package/assets/svges/burger-drink.svg +4 -0
- package/assets/svges/bus-1.svg +5 -0
- package/assets/svges/busket-ball.svg +3 -0
- package/assets/svges/cake-1.svg +3 -0
- package/assets/svges/calculator-1.svg +8 -0
- package/assets/svges/calculator-2.svg +13 -0
- package/assets/svges/calendar-days.svg +9 -0
- package/assets/svges/camera-1.svg +4 -0
- package/assets/svges/camera-movie-1.svg +3 -0
- package/assets/svges/candy-cane-2.svg +3 -0
- package/assets/svges/candy-round-1.svg +3 -0
- package/assets/svges/canva.svg +3 -0
- package/assets/svges/capsule-1.svg +3 -0
- package/assets/svges/car-2.svg +5 -0
- package/assets/svges/car-4.svg +3 -0
- package/assets/svges/car-6.svg +5 -0
- package/assets/svges/caravan-1.svg +3 -0
- package/assets/svges/cart-1.svg +5 -0
- package/assets/svges/cart-2.svg +5 -0
- package/assets/svges/cash-app.svg +3 -0
- package/assets/svges/certificate-badge-1.svg +6 -0
- package/assets/svges/chat-bubble-2.svg +5 -0
- package/assets/svges/check-circle-1.svg +4 -0
- package/assets/svges/check-square-2.svg +4 -0
- package/assets/svges/check.svg +3 -0
- package/assets/svges/chevron-down-circle.svg +4 -0
- package/assets/svges/chevron-down.svg +3 -0
- package/assets/svges/chevron-left-circle.svg +4 -0
- package/assets/svges/chevron-left.svg +3 -0
- package/assets/svges/chevron-right-circle.svg +4 -0
- package/assets/svges/chevron-up-circle.svg +4 -0
- package/assets/svges/chevron-up.svg +3 -0
- package/assets/svges/chrome.svg +6 -0
- package/assets/svges/chromecast.svg +3 -0
- package/assets/svges/cisco.svg +3 -0
- package/assets/svges/claude.svg +3 -0
- package/assets/svges/clickup.svg +4 -0
- package/assets/svges/clipboard.svg +3 -0
- package/assets/svges/cloud-2.svg +3 -0
- package/assets/svges/cloud-bolt-1.svg +4 -0
- package/assets/svges/cloud-bolt-2.svg +4 -0
- package/assets/svges/cloud-check-circle.svg +5 -0
- package/assets/svges/cloud-download.svg +5 -0
- package/assets/svges/cloud-iot-2.svg +3 -0
- package/assets/svges/cloud-rain.svg +6 -0
- package/assets/svges/cloud-refresh-clockwise.svg +5 -0
- package/assets/svges/cloud-sun.svg +9 -0
- package/assets/svges/cloud-upload.svg +5 -0
- package/assets/svges/cloudflare.svg +3 -0
- package/assets/svges/code-1.svg +5 -0
- package/assets/svges/code-s.svg +5 -0
- package/assets/svges/codepen.svg +3 -0
- package/assets/svges/coffee-cup-2.svg +6 -0
- package/assets/svges/coinbase.svg +10 -0
- package/assets/svges/colour-palette-3.svg +7 -0
- package/assets/svges/comment-1-share.svg +4 -0
- package/assets/svges/comment-1-text.svg +5 -0
- package/assets/svges/comment-1.svg +3 -0
- package/assets/svges/compass-drafting-2.svg +3 -0
- package/assets/svges/connectdevelop.svg +3 -0
- package/assets/svges/copilot.svg +8 -0
- package/assets/svges/coral.svg +3 -0
- package/assets/svges/cpanel.svg +3 -0
- package/assets/svges/crane-4.svg +3 -0
- package/assets/svges/creative-commons.svg +4 -0
- package/assets/svges/credit-card-multiple.svg +3 -0
- package/assets/svges/crop-2.svg +3 -0
- package/assets/svges/crown-3.svg +3 -0
- package/assets/svges/css3.svg +3 -0
- package/assets/svges/dashboard-square-1.svg +6 -0
- package/assets/svges/database-2.svg +3 -0
- package/assets/svges/deno.svg +4 -0
- package/assets/svges/dev.svg +3 -0
- package/assets/svges/dialogflow.svg +4 -0
- package/assets/svges/diamonds-1.svg +3 -0
- package/assets/svges/diamonds-2.svg +3 -0
- package/assets/svges/digitalocean.svg +3 -0
- package/assets/svges/diners-club.svg +38 -0
- package/assets/svges/direction-ltr.svg +4 -0
- package/assets/svges/direction-rtl.svg +4 -0
- package/assets/svges/discord-chat.svg +5 -0
- package/assets/svges/discord.svg +3 -0
- package/assets/svges/discover.svg +3 -0
- package/assets/svges/docker.svg +3 -0
- package/assets/svges/dollar-circle.svg +4 -0
- package/assets/svges/dollar.svg +3 -0
- package/assets/svges/double-quotes-end-1.svg +4 -0
- package/assets/svges/download-1.svg +4 -0
- package/assets/svges/download-circle-1.svg +4 -0
- package/assets/svges/dribbble-symbol.svg +3 -0
- package/assets/svges/dribbble.svg +3 -0
- package/assets/svges/drizzle.svg +6 -0
- package/assets/svges/dropbox.svg +7 -0
- package/assets/svges/drupal.svg +3 -0
- package/assets/svges/dumbbell-1.svg +3 -0
- package/assets/svges/edge.svg +3 -0
- package/assets/svges/emoji-expressionless-flat-eyes.svg +6 -0
- package/assets/svges/emoji-expressionless.svg +6 -0
- package/assets/svges/emoji-grin.svg +6 -0
- package/assets/svges/emoji-sad.svg +6 -0
- package/assets/svges/emoji-smile-side.svg +6 -0
- package/assets/svges/emoji-smile-sunglass.svg +5 -0
- package/assets/svges/emoji-smile-tongue.svg +3 -0
- package/assets/svges/emoji-smile.svg +6 -0
- package/assets/svges/enter-down.svg +4 -0
- package/assets/svges/enter.svg +4 -0
- package/assets/svges/envato.svg +4 -0
- package/assets/svges/envelope-1.svg +3 -0
- package/assets/svges/eraser-1.svg +4 -0
- package/assets/svges/ethereum-logo.svg +4 -0
- package/assets/svges/euro.svg +3 -0
- package/assets/svges/exit-up.svg +4 -0
- package/assets/svges/exit.svg +4 -0
- package/assets/svges/expand-arrow-1.svg +3 -0
- package/assets/svges/expand-square-4.svg +6 -0
- package/assets/svges/expressjs.svg +4 -0
- package/assets/svges/eye.svg +4 -0
- package/assets/svges/facebook-messenger.svg +3 -0
- package/assets/svges/facebook-rounded.svg +4 -0
- package/assets/svges/facebook-square.svg +3 -0
- package/assets/svges/facebook.svg +3 -0
- package/assets/svges/facetime.svg +3 -0
- package/assets/svges/figma.svg +3 -0
- package/assets/svges/file-format-zip.svg +4 -0
- package/assets/svges/file-multiple.svg +4 -0
- package/assets/svges/file-pencil.svg +4 -0
- package/assets/svges/file-plus-circle.svg +5 -0
- package/assets/svges/file-question.svg +5 -0
- package/assets/svges/file-xmark.svg +4 -0
- package/assets/svges/firebase.svg +3 -0
- package/assets/svges/firefox.svg +3 -0
- package/assets/svges/firework-rocket-4.svg +3 -0
- package/assets/svges/fitbit.svg +3 -0
- package/assets/svges/flag-1.svg +3 -0
- package/assets/svges/flag-2.svg +3 -0
- package/assets/svges/flickr.svg +4 -0
- package/assets/svges/floppy-disk-1.svg +3 -0
- package/assets/svges/flower-2.svg +3 -0
- package/assets/svges/flutter.svg +3 -0
- package/assets/svges/folder-1.svg +3 -0
- package/assets/svges/ford.svg +3 -0
- package/assets/svges/framer.svg +3 -0
- package/assets/svges/funnel-1.svg +3 -0
- package/assets/svges/gallery.svg +4 -0
- package/assets/svges/game-pad-modern-1.svg +6 -0
- package/assets/svges/gatsby.svg +3 -0
- package/assets/svges/gauge-1.svg +5 -0
- package/assets/svges/gear-1.svg +4 -0
- package/assets/svges/gears-3.svg +6 -0
- package/assets/svges/gemini.svg +3 -0
- package/assets/svges/git.svg +3 -0
- package/assets/svges/github.svg +3 -0
- package/assets/svges/glass-juice-1.svg +3 -0
- package/assets/svges/globe-1.svg +3 -0
- package/assets/svges/globe-stand.svg +4 -0
- package/assets/svges/go.svg +7 -0
- package/assets/svges/goodreads.svg +3 -0
- package/assets/svges/google-cloud.svg +3 -0
- package/assets/svges/google-drive.svg +3 -0
- package/assets/svges/google-meet.svg +3 -0
- package/assets/svges/google-pay.svg +3 -0
- package/assets/svges/google-wallet.svg +3 -0
- package/assets/svges/google.svg +3 -0
- package/assets/svges/graduation-cap-1.svg +3 -0
- package/assets/svges/grammarly.svg +3 -0
- package/assets/svges/hacker-news.svg +3 -0
- package/assets/svges/hammer-1.svg +3 -0
- package/assets/svges/hammer-2.svg +3 -0
- package/assets/svges/hand-mic.svg +3 -0
- package/assets/svges/hand-shake.svg +3 -0
- package/assets/svges/hand-stop.svg +3 -0
- package/assets/svges/hand-taking-dollar.svg +4 -0
- package/assets/svges/hand-taking-leaf-1.svg +5 -0
- package/assets/svges/hand-taking-user.svg +5 -0
- package/assets/svges/hashnode.svg +3 -0
- package/assets/svges/hat-chef-3.svg +3 -0
- package/assets/svges/headphone-1.svg +3 -0
- package/assets/svges/heart.svg +3 -0
- package/assets/svges/helicopter-2.svg +4 -0
- package/assets/svges/helmet-safety-1.svg +3 -0
- package/assets/svges/hierarchy-1.svg +9 -0
- package/assets/svges/highlighter-1.svg +3 -0
- package/assets/svges/highlighter-2.svg +3 -0
- package/assets/svges/home-2.svg +3 -0
- package/assets/svges/hospital-2.svg +4 -0
- package/assets/svges/hourglass.svg +3 -0
- package/assets/svges/html5.svg +4 -0
- package/assets/svges/ibm.svg +3 -0
- package/assets/svges/id-card.svg +7 -0
- package/assets/svges/imdb.svg +7 -0
- package/assets/svges/indent.svg +8 -0
- package/assets/svges/info.svg +4 -0
- package/assets/svges/injection-1.svg +3 -0
- package/assets/svges/instagram-logotype.svg +3 -0
- package/assets/svges/instagram.svg +4 -0
- package/assets/svges/intel.svg +4 -0
- package/assets/svges/ios.svg +3 -0
- package/assets/svges/island-2.svg +4 -0
- package/assets/svges/jaguar.svg +3 -0
- package/assets/svges/jamstack.svg +3 -0
- package/assets/svges/java.svg +3 -0
- package/assets/svges/javascript.svg +3 -0
- package/assets/svges/jcb.svg +3 -0
- package/assets/svges/joomla.svg +6 -0
- package/assets/svges/jsfiddle.svg +4 -0
- package/assets/svges/key-1.svg +3 -0
- package/assets/svges/keyboard.svg +12 -0
- package/assets/svges/knife-fork-1.svg +5 -0
- package/assets/svges/kubernetes.svg +11 -0
- package/assets/svges/label-dollar-2.svg +4 -0
- package/assets/svges/laptop-2.svg +3 -0
- package/assets/svges/laptop-phone.svg +5 -0
- package/assets/svges/laravel.svg +3 -0
- package/assets/svges/layers-1.svg +4 -0
- package/assets/svges/layout-26.svg +3 -0
- package/assets/svges/layout-9.svg +3 -0
- package/assets/svges/leaf-1.svg +3 -0
- package/assets/svges/leaf-6.svg +4 -0
- package/assets/svges/lemon-squeezy.svg +6 -0
- package/assets/svges/life-guard-tube-1.svg +3 -0
- package/assets/svges/line-dashed.svg +5 -0
- package/assets/svges/line-dotted.svg +8 -0
- package/assets/svges/line-height.svg +7 -0
- package/assets/svges/line.svg +3 -0
- package/assets/svges/lineicons.svg +6 -0
- package/assets/svges/link-2-angular-right.svg +3 -0
- package/assets/svges/linkedin.svg +3 -0
- package/assets/svges/location-arrow-right.svg +3 -0
- package/assets/svges/locked-1.svg +4 -0
- package/assets/svges/locked-2.svg +4 -0
- package/assets/svges/loom.svg +3 -0
- package/assets/svges/magento.svg +4 -0
- package/assets/svges/magnet.svg +3 -0
- package/assets/svges/mailchimp.svg +3 -0
- package/assets/svges/map-marker-1.svg +6 -0
- package/assets/svges/map-marker-5.svg +4 -0
- package/assets/svges/map-pin-5.svg +3 -0
- package/assets/svges/markdown.svg +5 -0
- package/assets/svges/mastercard.svg +7 -0
- package/assets/svges/medium-alt.svg +3 -0
- package/assets/svges/medium.svg +3 -0
- package/assets/svges/megaphone-1.svg +3 -0
- package/assets/svges/menu-cheesburger.svg +8 -0
- package/assets/svges/menu-hamburger-1.svg +5 -0
- package/assets/svges/menu-meatballs-1.svg +5 -0
- package/assets/svges/menu-meatballs-2.svg +5 -0
- package/assets/svges/mercedes.svg +3 -0
- package/assets/svges/message-2-question.svg +5 -0
- package/assets/svges/message-2.svg +3 -0
- package/assets/svges/message-3-text.svg +5 -0
- package/assets/svges/meta-alt.svg +3 -0
- package/assets/svges/meta.svg +7 -0
- package/assets/svges/microphone-1.svg +4 -0
- package/assets/svges/microscope.svg +3 -0
- package/assets/svges/microsoft-edge.svg +5 -0
- package/assets/svges/microsoft-teams.svg +6 -0
- package/assets/svges/microsoft.svg +6 -0
- package/assets/svges/minus-circle.svg +4 -0
- package/assets/svges/minus.svg +3 -0
- package/assets/svges/mongodb.svg +3 -0
- package/assets/svges/monitor-code.svg +5 -0
- package/assets/svges/monitor-mac.svg +3 -0
- package/assets/svges/monitor.svg +3 -0
- package/assets/svges/moon-half-right-5.svg +3 -0
- package/assets/svges/mountains-2.svg +3 -0
- package/assets/svges/mouse-2.svg +3 -0
- package/assets/svges/mushroom-1.svg +3 -0
- package/assets/svges/mushroom-5.svg +6 -0
- package/assets/svges/music.svg +3 -0
- package/assets/svges/mysql.svg +3 -0
- package/assets/svges/nasa.svg +3 -0
- package/assets/svges/netflix.svg +3 -0
- package/assets/svges/netlify.svg +3 -0
- package/assets/svges/next-step-2.svg +3 -0
- package/assets/svges/nextjs.svg +3 -0
- package/assets/svges/nike.svg +3 -0
- package/assets/svges/nissan.svg +3 -0
- package/assets/svges/nodejs-alt.svg +3 -0
- package/assets/svges/nodejs.svg +3 -0
- package/assets/svges/notebook-1.svg +3 -0
- package/assets/svges/notion.svg +3 -0
- package/assets/svges/npm.svg +3 -0
- package/assets/svges/nuxt.svg +3 -0
- package/assets/svges/nvidia.svg +3 -0
- package/assets/svges/oculus.svg +4 -0
- package/assets/svges/open-ai.svg +3 -0
- package/assets/svges/opera-mini.svg +3 -0
- package/assets/svges/oracle.svg +3 -0
- package/assets/svges/outdent.svg +8 -0
- package/assets/svges/paddle.svg +3 -0
- package/assets/svges/page-break-1.svg +7 -0
- package/assets/svges/pagination.svg +7 -0
- package/assets/svges/paint-bucket.svg +3 -0
- package/assets/svges/paint-roller-1.svg +3 -0
- package/assets/svges/paperclip-1.svg +3 -0
- package/assets/svges/party-flags.svg +3 -0
- package/assets/svges/party-spray.svg +3 -0
- package/assets/svges/patreon.svg +3 -0
- package/assets/svges/pause.svg +4 -0
- package/assets/svges/payoneer.svg +4 -0
- package/assets/svges/paypal.svg +4 -0
- package/assets/svges/pen-to-square.svg +4 -0
- package/assets/svges/pencil-1.svg +3 -0
- package/assets/svges/pepsi.svg +4 -0
- package/assets/svges/phone.svg +4 -0
- package/assets/svges/photos.svg +4 -0
- package/assets/svges/php.svg +3 -0
- package/assets/svges/pie-chart-2.svg +3 -0
- package/assets/svges/pilcrow.svg +3 -0
- package/assets/svges/pimjo-logo.svg +9 -0
- package/assets/svges/pimjo-symbol.svg +3 -0
- package/assets/svges/pinterest.svg +3 -0
- package/assets/svges/pizza-2.svg +6 -0
- package/assets/svges/placeholder-dollar.svg +4 -0
- package/assets/svges/plantscale.svg +3 -0
- package/assets/svges/play-store.svg +3 -0
- package/assets/svges/play.svg +3 -0
- package/assets/svges/playstation.svg +5 -0
- package/assets/svges/plug-1.svg +3 -0
- package/assets/svges/plus-circle.svg +4 -0
- package/assets/svges/plus.svg +3 -0
- package/assets/svges/pnpm.svg +10 -0
- package/assets/svges/postgresql.svg +3 -0
- package/assets/svges/postman.svg +3 -0
- package/assets/svges/pound.svg +3 -0
- package/assets/svges/power-button.svg +4 -0
- package/assets/svges/previous-step-2.svg +3 -0
- package/assets/svges/printer.svg +3 -0
- package/assets/svges/prisma.svg +3 -0
- package/assets/svges/producthunt.svg +4 -0
- package/assets/svges/proton-mail-logo.svg +3 -0
- package/assets/svges/proton-mail-symbol.svg +3 -0
- package/assets/svges/python.svg +3 -0
- package/assets/svges/question-mark-circle.svg +5 -0
- package/assets/svges/question-mark.svg +4 -0
- package/assets/svges/quora.svg +4 -0
- package/assets/svges/radis.svg +3 -0
- package/assets/svges/react.svg +3 -0
- package/assets/svges/reddit.svg +6 -0
- package/assets/svges/refresh-circle-1-clockwise.svg +4 -0
- package/assets/svges/refresh-dollar-1.svg +5 -0
- package/assets/svges/refresh-user-1.svg +6 -0
- package/assets/svges/remix-js.svg +4 -0
- package/assets/svges/road-1.svg +6 -0
- package/assets/svges/rocket-5.svg +5 -0
- package/assets/svges/route-1.svg +7 -0
- package/assets/svges/rss-right.svg +6 -0
- package/assets/svges/ruler-1.svg +3 -0
- package/assets/svges/ruler-pen.svg +4 -0
- package/assets/svges/rupee.svg +3 -0
- package/assets/svges/safari.svg +35 -0
- package/assets/svges/sanity.svg +20 -0
- package/assets/svges/school-bench-1.svg +4 -0
- package/assets/svges/school-bench-2.svg +4 -0
- package/assets/svges/scissors-1-vertical.svg +4 -0
- package/assets/svges/scoter.svg +8 -0
- package/assets/svges/scroll-down-2.svg +6 -0
- package/assets/svges/search-1.svg +3 -0
- package/assets/svges/search-2.svg +4 -0
- package/assets/svges/search-minus.svg +4 -0
- package/assets/svges/search-plus.svg +4 -0
- package/assets/svges/search-text.svg +5 -0
- package/assets/svges/select-cursor-1.svg +10 -0
- package/assets/svges/seo-monitor.svg +6 -0
- package/assets/svges/service-bell-1.svg +3 -0
- package/assets/svges/share-1-circle.svg +4 -0
- package/assets/svges/share-1.svg +3 -0
- package/assets/svges/share-2.svg +4 -0
- package/assets/svges/shield-2-check.svg +4 -0
- package/assets/svges/shield-2.svg +3 -0
- package/assets/svges/shield-dollar.svg +4 -0
- package/assets/svges/shift-left.svg +4 -0
- package/assets/svges/shift-right.svg +4 -0
- package/assets/svges/ship-1.svg +5 -0
- package/assets/svges/shirt-1.svg +3 -0
- package/assets/svges/shopify.svg +3 -0
- package/assets/svges/shovel.svg +3 -0
- package/assets/svges/shuffle.svg +3 -0
- package/assets/svges/sign-post-left.svg +3 -0
- package/assets/svges/signal-app.svg +3 -0
- package/assets/svges/signs-post-2.svg +3 -0
- package/assets/svges/sketch.svg +3 -0
- package/assets/svges/skype.svg +3 -0
- package/assets/svges/slack.svg +10 -0
- package/assets/svges/slice-2.svg +3 -0
- package/assets/svges/sliders-horizontal-square-2.svg +7 -0
- package/assets/svges/slideshare.svg +5 -0
- package/assets/svges/snapchat.svg +3 -0
- package/assets/svges/sort-alphabetical.svg +5 -0
- package/assets/svges/sort-high-to-low.svg +7 -0
- package/assets/svges/soundcloud.svg +3 -0
- package/assets/svges/spacex.svg +4 -0
- package/assets/svges/spellcheck.svg +4 -0
- package/assets/svges/spinner-2-sacle.svg +10 -0
- package/assets/svges/spinner-3.svg +3 -0
- package/assets/svges/sports.svg +3 -0
- package/assets/svges/spotify-alt.svg +6 -0
- package/assets/svges/spotify.svg +3 -0
- package/assets/svges/squarespace.svg +3 -0
- package/assets/svges/stackoverflow.svg +8 -0
- package/assets/svges/stamp.svg +3 -0
- package/assets/svges/star-fat-half-2.svg +4 -0
- package/assets/svges/star-fat.svg +3 -0
- package/assets/svges/star-sharp-disabled.svg +4 -0
- package/assets/svges/statista.svg +3 -0
- package/assets/svges/steam.svg +5 -0
- package/assets/svges/stethoscope-1.svg +3 -0
- package/assets/svges/stopwatch.svg +5 -0
- package/assets/svges/storage-hdd-2.svg +4 -0
- package/assets/svges/strikethrough-1.svg +5 -0
- package/assets/svges/stripe.svg +9 -0
- package/assets/svges/stumbleupon.svg +3 -0
- package/assets/svges/sun-1.svg +11 -0
- package/assets/svges/supabase.svg +5 -0
- package/assets/svges/surfboard-2.svg +3 -0
- package/assets/svges/svelte.svg +3 -0
- package/assets/svges/swift.svg +3 -0
- package/assets/svges/tab.svg +4 -0
- package/assets/svges/tailwindcss.svg +3 -0
- package/assets/svges/target-user.svg +5 -0
- package/assets/svges/telegram.svg +3 -0
- package/assets/svges/telephone-1.svg +4 -0
- package/assets/svges/telephone-3.svg +5 -0
- package/assets/svges/tesla.svg +3 -0
- package/assets/svges/text-format-remove.svg +5 -0
- package/assets/svges/text-format.svg +5 -0
- package/assets/svges/text-paragraph.svg +6 -0
- package/assets/svges/thumbs-down-3.svg +3 -0
- package/assets/svges/thumbs-up-3.svg +3 -0
- package/assets/svges/ticket-1.svg +3 -0
- package/assets/svges/tickets-3.svg +7 -0
- package/assets/svges/tiktok-alt.svg +3 -0
- package/assets/svges/tiktok.svg +3 -0
- package/assets/svges/tower-broadcast-1.svg +7 -0
- package/assets/svges/toyota.svg +4 -0
- package/assets/svges/train-1.svg +4 -0
- package/assets/svges/train-3.svg +5 -0
- package/assets/svges/trash-3.svg +5 -0
- package/assets/svges/tree-2.svg +3 -0
- package/assets/svges/trees-3.svg +3 -0
- package/assets/svges/trello.svg +3 -0
- package/assets/svges/trend-down-1.svg +3 -0
- package/assets/svges/trend-up-1.svg +3 -0
- package/assets/svges/trophy-1.svg +3 -0
- package/assets/svges/trowel-1.svg +3 -0
- package/assets/svges/truck-delivery-1.svg +3 -0
- package/assets/svges/tumblr.svg +3 -0
- package/assets/svges/turborepo.svg +4 -0
- package/assets/svges/twitch.svg +3 -0
- package/assets/svges/twitter-old.svg +3 -0
- package/assets/svges/typescript.svg +3 -0
- package/assets/svges/uber-symbol.svg +3 -0
- package/assets/svges/uber.svg +3 -0
- package/assets/svges/ubuntu.svg +3 -0
- package/assets/svges/underline.svg +4 -0
- package/assets/svges/unlink-2-angular-eft.svg +8 -0
- package/assets/svges/unlocked-2.svg +4 -0
- package/assets/svges/unsplash.svg +4 -0
- package/assets/svges/upload-1.svg +4 -0
- package/assets/svges/upload-circle-1.svg +4 -0
- package/assets/svges/user-4.svg +4 -0
- package/assets/svges/user-multiple-4.svg +6 -0
- package/assets/svges/vector-nodes-6.svg +3 -0
- package/assets/svges/vector-nodes-7.svg +3 -0
- package/assets/svges/vercel.svg +3 -0
- package/assets/svges/vimeo.svg +3 -0
- package/assets/svges/visa.svg +3 -0
- package/assets/svges/vite.svg +6 -0
- package/assets/svges/vk.svg +3 -0
- package/assets/svges/vmware.svg +4 -0
- package/assets/svges/volkswagen.svg +8 -0
- package/assets/svges/volume-1.svg +5 -0
- package/assets/svges/volume-high.svg +6 -0
- package/assets/svges/volume-low.svg +4 -0
- package/assets/svges/volume-mute.svg +6 -0
- package/assets/svges/volume-off.svg +3 -0
- package/assets/svges/vs-code.svg +3 -0
- package/assets/svges/vuejs.svg +3 -0
- package/assets/svges/wallet-1.svg +3 -0
- package/assets/svges/watch-beat-1.svg +4 -0
- package/assets/svges/water-drop-1.svg +4 -0
- package/assets/svges/webflow.svg +3 -0
- package/assets/svges/webhooks.svg +3 -0
- package/assets/svges/wechat.svg +4 -0
- package/assets/svges/weight-machine-1.svg +4 -0
- package/assets/svges/whatsapp.svg +3 -0
- package/assets/svges/wheelbarrow-empty.svg +3 -0
- package/assets/svges/wheelchair-1.svg +3 -0
- package/assets/svges/windows.svg +6 -0
- package/assets/svges/wise.svg +3 -0
- package/assets/svges/wordpress.svg +3 -0
- package/assets/svges/www-cursor.svg +5 -0
- package/assets/svges/www.svg +4 -0
- package/assets/svges/x.svg +3 -0
- package/assets/svges/xampp.svg +5 -0
- package/assets/svges/xbox.svg +6 -0
- package/assets/svges/xmark-circle.svg +4 -0
- package/assets/svges/xmark.svg +3 -0
- package/assets/svges/xrp.svg +3 -0
- package/assets/svges/yahoo.svg +3 -0
- package/assets/svges/yarn.svg +4 -0
- package/assets/svges/ycombinator.svg +3 -0
- package/assets/svges/yen.svg +3 -0
- package/assets/svges/youtube-kids.svg +3 -0
- package/assets/svges/youtube-music.svg +4 -0
- package/assets/svges/youtube.svg +3 -0
- package/assets/svges/zapier.svg +3 -0
- package/assets/svges/zero-size.svg +6 -0
- package/assets/svges/zoom.svg +4 -0
- package/bin/test-svger.js +163 -0
- package/dist/__tests__/__mocks__/visual-diff.d.ts +7 -0
- package/dist/__tests__/__mocks__/visual-diff.js +13 -0
- package/dist/__tests__/fixtures.js +18 -18
- package/dist/cli.js +148 -2
- package/dist/config.js +4 -1
- package/dist/core/enhanced-plugin-manager.d.ts +107 -0
- package/dist/core/enhanced-plugin-manager.js +315 -0
- package/dist/core/error-handler.d.ts +1 -1
- package/dist/core/error-handler.js +14 -17
- package/dist/core/framework-templates.js +37 -47
- package/dist/core/logger.js +0 -1
- package/dist/core/performance-engine.js +10 -15
- package/dist/core/plugin-manager.js +4 -4
- package/dist/core/style-compiler.d.ts +0 -1
- package/dist/core/style-compiler.js +3 -6
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/integrations/babel.d.ts +1 -1
- package/dist/integrations/babel.js +31 -12
- package/dist/integrations/jest-preset.js +1 -1
- package/dist/integrations/rollup.js +29 -10
- package/dist/integrations/vite.js +29 -14
- package/dist/integrations/webpack.d.ts +1 -0
- package/dist/integrations/webpack.js +29 -10
- package/dist/optimizers/advanced-stages.d.ts +40 -0
- package/dist/optimizers/advanced-stages.js +297 -0
- package/dist/optimizers/basic-cleaner.d.ts +68 -0
- package/dist/optimizers/basic-cleaner.js +198 -0
- package/dist/optimizers/collapse-useless-groups.d.ts +26 -0
- package/dist/optimizers/collapse-useless-groups.js +104 -0
- package/dist/optimizers/command-optimizer.d.ts +48 -0
- package/dist/optimizers/command-optimizer.js +299 -0
- package/dist/optimizers/index.d.ts +14 -0
- package/dist/optimizers/index.js +15 -0
- package/dist/optimizers/move-attrs-to-parent.d.ts +31 -0
- package/dist/optimizers/move-attrs-to-parent.js +115 -0
- package/dist/optimizers/numeric-optimizer.d.ts +43 -0
- package/dist/optimizers/numeric-optimizer.js +383 -0
- package/dist/optimizers/optimizer-pipeline.d.ts +39 -0
- package/dist/optimizers/optimizer-pipeline.js +81 -0
- package/dist/optimizers/path-deduplicator.d.ts +37 -0
- package/dist/optimizers/path-deduplicator.js +406 -0
- package/dist/optimizers/path-parser.d.ts +60 -0
- package/dist/optimizers/path-parser.js +428 -0
- package/dist/optimizers/path-shortener.d.ts +41 -0
- package/dist/optimizers/path-shortener.js +274 -0
- package/dist/optimizers/path-simplifier.d.ts +30 -0
- package/dist/optimizers/path-simplifier.js +326 -0
- package/dist/optimizers/remove-hidden-empty.d.ts +29 -0
- package/dist/optimizers/remove-hidden-empty.js +130 -0
- package/dist/optimizers/remove-unused-defs.d.ts +24 -0
- package/dist/optimizers/remove-unused-defs.js +132 -0
- package/dist/optimizers/shape-conversion.d.ts +74 -0
- package/dist/optimizers/shape-conversion.js +277 -0
- package/dist/optimizers/style-optimizer.d.ts +30 -0
- package/dist/optimizers/style-optimizer.js +324 -0
- package/dist/optimizers/svg-tree-parser.d.ts +55 -0
- package/dist/optimizers/svg-tree-parser.js +352 -0
- package/dist/optimizers/transform-collapsing.d.ts +38 -0
- package/dist/optimizers/transform-collapsing.js +444 -0
- package/dist/optimizers/transform-optimizer.d.ts +65 -0
- package/dist/optimizers/transform-optimizer.js +320 -0
- package/dist/optimizers/tree-serializer.d.ts +46 -0
- package/dist/optimizers/tree-serializer.js +190 -0
- package/dist/optimizers/tree-stages.d.ts +27 -0
- package/dist/optimizers/tree-stages.js +141 -0
- package/dist/optimizers/types.d.ts +207 -0
- package/dist/optimizers/types.js +122 -0
- package/dist/plugins/color-replacer.d.ts +39 -0
- package/dist/plugins/color-replacer.js +126 -0
- package/dist/plugins/gradient-optimizer.d.ts +33 -0
- package/dist/plugins/gradient-optimizer.js +197 -0
- package/dist/plugins/stroke-normalizer.d.ts +33 -0
- package/dist/plugins/stroke-normalizer.js +166 -0
- package/dist/plugins/watermark-remover.d.ts +32 -0
- package/dist/plugins/watermark-remover.js +133 -0
- package/dist/processors/svg-processor.d.ts +17 -2
- package/dist/processors/svg-processor.js +108 -32
- package/dist/services/config.d.ts +4 -0
- package/dist/services/config.js +62 -1
- package/dist/services/file-watcher.d.ts +1 -1
- package/dist/services/file-watcher.js +1 -1
- package/dist/services/svg-service.d.ts +6 -0
- package/dist/services/svg-service.js +66 -16
- package/dist/types/index.d.ts +1 -0
- package/dist/types/plugin-system.d.ts +153 -0
- package/dist/types/plugin-system.js +5 -0
- package/dist/utils/visual-diff.d.ts +150 -0
- package/dist/utils/visual-diff.js +247 -0
- package/dist/watch.js +0 -2
- package/docs/COMPLETE-ACHIEVEMENT-SUMMARY.md +401 -0
- package/docs/MIGRATION-4.0.0.md +271 -0
- package/docs/PIPELINE-INTEGRATION.md +406 -0
- package/docs/PLUGIN-DEVELOPMENT-GUIDE.md +807 -0
- package/docs/QUICK-REFERENCE.md +176 -0
- package/docs/SAMPLE-SVGS-TESTING.md +276 -0
- package/docs/archive/PHASE-1-ARCHITECTURE.md +345 -0
- package/docs/archive/PHASE-1-IMPLEMENTATION.md +307 -0
- package/docs/archive/PHASE-1-SUMMARY.md +298 -0
- package/docs/archive/PHASE-2-COMPLETE.md +207 -0
- package/docs/archive/PHASE-3-SUMMARY.md +149 -0
- package/docs/archive/PHASE-4.3-COMMAND-OPTIMIZER.md +323 -0
- package/docs/archive/PHASE-4.4-PATH-SIMPLIFICATION.md +81 -0
- package/docs/archive/PHASE-4.5-PATH-DEDUPLICATION.md +449 -0
- package/docs/archive/PHASE-5.1-SUCCESS-REPORT.md +207 -0
- package/docs/archive/PHASE-5.1-TRANSFORM-COLLAPSING.md +362 -0
- package/docs/archive/PHASE-6.1-SHAPE-CONVERSION-DESIGN.md +518 -0
- package/docs/archive/PHASE-6.2-PLUGIN-SYSTEM-STATUS.md +403 -0
- package/docs/archive/PHASE-6.3-FINAL-STATUS.md +193 -0
- package/docs/archive/PHASE-6.3-VALIDATION-PROGRESS.md +345 -0
- package/docs/archive/PHASE-6.3-VISUAL-DIFF-DESIGN.md +553 -0
- package/docs/archive/PHASE-6.3-VISUAL-DIFF-SUMMARY.md +367 -0
- package/docs/archive/PHASE-6.3-XML-SERIALIZATION-FIX.md +210 -0
- package/docs/archive/RELEASE-NOTES-3.2.0.md +344 -0
- package/docs/archive/RELEASE-PREP-3.2.0.md +376 -0
- package/docs/performance/PERFORMANCE-RESULTS.md +31 -0
- package/docs/performance/REAL-WORLD-BENCHMARKS.md +159 -0
- package/package.json +16 -6
- package/DEVELOPMENT.md +0 -353
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 3: Transform Optimizer
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Parse transform attribute lists (translate, rotate, scale, skew, matrix)
|
|
6
|
+
* 2. Consolidate multiple transforms into single matrix
|
|
7
|
+
* 3. Decompose matrix back to simpler transforms only if shorter
|
|
8
|
+
* 4. Round matrix/transform values to configured precision
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Identity matrix
|
|
12
|
+
*/
|
|
13
|
+
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
|
14
|
+
/**
|
|
15
|
+
* Parse a single transform command
|
|
16
|
+
*/
|
|
17
|
+
function parseTransformCommand(command) {
|
|
18
|
+
const match = command.match(/^(\w+)\s*\(([^)]+)\)/);
|
|
19
|
+
if (!match)
|
|
20
|
+
return null;
|
|
21
|
+
const type = match[1];
|
|
22
|
+
const valueStr = match[2].trim();
|
|
23
|
+
const values = valueStr
|
|
24
|
+
.split(/[\s,]+/)
|
|
25
|
+
.map(v => parseFloat(v))
|
|
26
|
+
.filter(v => !isNaN(v));
|
|
27
|
+
if (values.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
return { type, values };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse transform attribute into list of commands
|
|
33
|
+
*/
|
|
34
|
+
export function parseTransformList(transformStr) {
|
|
35
|
+
const transforms = [];
|
|
36
|
+
const regex = /(\w+)\s*\([^)]+\)/g;
|
|
37
|
+
let match;
|
|
38
|
+
while ((match = regex.exec(transformStr)) !== null) {
|
|
39
|
+
const cmd = parseTransformCommand(match[0]);
|
|
40
|
+
if (cmd) {
|
|
41
|
+
transforms.push(cmd);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return transforms;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Multiply two matrices: result = m1 × m2
|
|
48
|
+
*/
|
|
49
|
+
function multiplyMatrices(m1, m2) {
|
|
50
|
+
const [a1, b1, c1, d1, e1, f1] = m1;
|
|
51
|
+
const [a2, b2, c2, d2, e2, f2] = m2;
|
|
52
|
+
return [
|
|
53
|
+
a1 * a2 + c1 * b2,
|
|
54
|
+
b1 * a2 + d1 * b2,
|
|
55
|
+
a1 * c2 + c1 * d2,
|
|
56
|
+
b1 * c2 + d1 * d2,
|
|
57
|
+
a1 * e2 + c1 * f2 + e1,
|
|
58
|
+
b1 * e2 + d1 * f2 + f1,
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Convert transform command to matrix
|
|
63
|
+
*/
|
|
64
|
+
function transformToMatrix(transform) {
|
|
65
|
+
const { type, values } = transform;
|
|
66
|
+
switch (type) {
|
|
67
|
+
case 'matrix':
|
|
68
|
+
if (values.length === 6) {
|
|
69
|
+
return values;
|
|
70
|
+
}
|
|
71
|
+
return IDENTITY_MATRIX;
|
|
72
|
+
case 'translate': {
|
|
73
|
+
const tx = values[0] || 0;
|
|
74
|
+
const ty = values[1] || 0;
|
|
75
|
+
return [1, 0, 0, 1, tx, ty];
|
|
76
|
+
}
|
|
77
|
+
case 'scale': {
|
|
78
|
+
const sx = values[0] || 1;
|
|
79
|
+
const sy = values[1] !== undefined ? values[1] : sx;
|
|
80
|
+
return [sx, 0, 0, sy, 0, 0];
|
|
81
|
+
}
|
|
82
|
+
case 'rotate': {
|
|
83
|
+
const angle = values[0] || 0;
|
|
84
|
+
const rad = (angle * Math.PI) / 180;
|
|
85
|
+
const cos = Math.cos(rad);
|
|
86
|
+
const sin = Math.sin(rad);
|
|
87
|
+
// Rotate around point (cx, cy) if provided
|
|
88
|
+
if (values.length === 3) {
|
|
89
|
+
const cx = values[1];
|
|
90
|
+
const cy = values[2];
|
|
91
|
+
// translate(-cx, -cy) × rotate(angle) × translate(cx, cy)
|
|
92
|
+
return [
|
|
93
|
+
cos,
|
|
94
|
+
sin,
|
|
95
|
+
-sin,
|
|
96
|
+
cos,
|
|
97
|
+
-cx * cos + cy * sin + cx,
|
|
98
|
+
-cx * sin - cy * cos + cy,
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
return [cos, sin, -sin, cos, 0, 0];
|
|
102
|
+
}
|
|
103
|
+
case 'skewX': {
|
|
104
|
+
const angle = values[0] || 0;
|
|
105
|
+
const rad = (angle * Math.PI) / 180;
|
|
106
|
+
const tan = Math.tan(rad);
|
|
107
|
+
return [1, 0, tan, 1, 0, 0];
|
|
108
|
+
}
|
|
109
|
+
case 'skewY': {
|
|
110
|
+
const angle = values[0] || 0;
|
|
111
|
+
const rad = (angle * Math.PI) / 180;
|
|
112
|
+
const tan = Math.tan(rad);
|
|
113
|
+
return [1, tan, 0, 1, 0, 0];
|
|
114
|
+
}
|
|
115
|
+
default:
|
|
116
|
+
return IDENTITY_MATRIX;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Consolidate transform list into single matrix
|
|
121
|
+
*/
|
|
122
|
+
export function consolidateTransforms(transforms) {
|
|
123
|
+
let result = IDENTITY_MATRIX;
|
|
124
|
+
for (const transform of transforms) {
|
|
125
|
+
const matrix = transformToMatrix(transform);
|
|
126
|
+
result = multiplyMatrices(result, matrix);
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Round number with precision
|
|
132
|
+
*/
|
|
133
|
+
function roundNum(value, precision) {
|
|
134
|
+
if (Math.abs(value) < 1e-10)
|
|
135
|
+
return 0;
|
|
136
|
+
const multiplier = Math.pow(10, precision);
|
|
137
|
+
const rounded = Math.round(value * multiplier) / multiplier;
|
|
138
|
+
return Object.is(rounded, -0) ? 0 : rounded;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if matrix is identity
|
|
142
|
+
*/
|
|
143
|
+
export function isIdentityMatrix(m) {
|
|
144
|
+
const [a, b, c, d, e, f] = m;
|
|
145
|
+
return (Math.abs(a - 1) < 1e-10 &&
|
|
146
|
+
Math.abs(b) < 1e-10 &&
|
|
147
|
+
Math.abs(c) < 1e-10 &&
|
|
148
|
+
Math.abs(d - 1) < 1e-10 &&
|
|
149
|
+
Math.abs(e) < 1e-10 &&
|
|
150
|
+
Math.abs(f) < 1e-10);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Decompose matrix to simpler transforms if possible
|
|
154
|
+
* Returns shortest representation between:
|
|
155
|
+
* - matrix(a, b, c, d, e, f)
|
|
156
|
+
* - translate(tx, ty)
|
|
157
|
+
* - scale(sx, sy)
|
|
158
|
+
* - rotate(angle)
|
|
159
|
+
* - combinations
|
|
160
|
+
*/
|
|
161
|
+
export function decomposeMatrix(m, precision = 3) {
|
|
162
|
+
const [a, b, c, d, e, f] = m.map(v => roundNum(v, precision));
|
|
163
|
+
// Identity: remove transform entirely
|
|
164
|
+
if (isIdentityMatrix([a, b, c, d, e, f])) {
|
|
165
|
+
return '';
|
|
166
|
+
}
|
|
167
|
+
// Pure translate: translate(tx, ty) or translate(tx)
|
|
168
|
+
if (Math.abs(a - 1) < 1e-10 &&
|
|
169
|
+
Math.abs(b) < 1e-10 &&
|
|
170
|
+
Math.abs(c) < 1e-10 &&
|
|
171
|
+
Math.abs(d - 1) < 1e-10) {
|
|
172
|
+
if (Math.abs(f) < 1e-10) {
|
|
173
|
+
return `translate(${e})`;
|
|
174
|
+
}
|
|
175
|
+
return `translate(${e} ${f})`;
|
|
176
|
+
}
|
|
177
|
+
// Pure scale: scale(sx, sy) or scale(sx)
|
|
178
|
+
if (Math.abs(b) < 1e-10 &&
|
|
179
|
+
Math.abs(c) < 1e-10 &&
|
|
180
|
+
Math.abs(e) < 1e-10 &&
|
|
181
|
+
Math.abs(f) < 1e-10 &&
|
|
182
|
+
Math.abs(a - d) < 1e-10) {
|
|
183
|
+
return `scale(${a})`;
|
|
184
|
+
}
|
|
185
|
+
if (Math.abs(b) < 1e-10 &&
|
|
186
|
+
Math.abs(c) < 1e-10 &&
|
|
187
|
+
Math.abs(e) < 1e-10 &&
|
|
188
|
+
Math.abs(f) < 1e-10) {
|
|
189
|
+
return `scale(${a} ${d})`;
|
|
190
|
+
}
|
|
191
|
+
// Pure rotate (no translation): rotate(angle)
|
|
192
|
+
if (Math.abs(e) < 1e-10 &&
|
|
193
|
+
Math.abs(f) < 1e-10 &&
|
|
194
|
+
Math.abs(Math.sqrt(a * a + b * b) - 1) < 1e-10 &&
|
|
195
|
+
Math.abs(a - d) < 1e-10 &&
|
|
196
|
+
Math.abs(b + c) < 1e-10) {
|
|
197
|
+
const angle = roundNum((Math.atan2(b, a) * 180) / Math.PI, precision);
|
|
198
|
+
return `rotate(${angle})`;
|
|
199
|
+
}
|
|
200
|
+
// Matrix form as fallback
|
|
201
|
+
const matrixStr = `matrix(${a} ${b} ${c} ${d} ${e} ${f})`;
|
|
202
|
+
// Try to decompose into translate + rotate/scale if shorter
|
|
203
|
+
// translate(tx, ty) + rotate(angle)
|
|
204
|
+
if (Math.abs(Math.sqrt(a * a + b * b) - 1) < 1e-10 &&
|
|
205
|
+
Math.abs(a - d) < 1e-10 &&
|
|
206
|
+
Math.abs(b + c) < 1e-10) {
|
|
207
|
+
const angle = roundNum((Math.atan2(b, a) * 180) / Math.PI, precision);
|
|
208
|
+
const translateStr = Math.abs(f) < 1e-10 ? `translate(${e})` : `translate(${e} ${f})`;
|
|
209
|
+
const combined = `${translateStr} rotate(${angle})`;
|
|
210
|
+
if (combined.length < matrixStr.length) {
|
|
211
|
+
return combined;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return matrixStr;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Optimize transform attribute on a node
|
|
218
|
+
*/
|
|
219
|
+
function optimizeTransform(node, precision) {
|
|
220
|
+
const transformAttr = node.attrs.get('transform');
|
|
221
|
+
if (!transformAttr)
|
|
222
|
+
return false;
|
|
223
|
+
const transforms = parseTransformList(transformAttr);
|
|
224
|
+
if (transforms.length === 0) {
|
|
225
|
+
node.attrs.delete('transform');
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
// If only one transform, check for identity and round values
|
|
229
|
+
if (transforms.length === 1) {
|
|
230
|
+
const t = transforms[0];
|
|
231
|
+
const roundedValues = t.values.map(v => roundNum(v, precision));
|
|
232
|
+
// Convert to matrix to check for identity
|
|
233
|
+
const matrix = transformToMatrix({ type: t.type, values: roundedValues });
|
|
234
|
+
// Check if identity
|
|
235
|
+
if (isIdentityMatrix(matrix)) {
|
|
236
|
+
node.attrs.delete('transform');
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
// For matrix type, try to decompose to simpler form
|
|
240
|
+
if (t.type === 'matrix') {
|
|
241
|
+
const optimized = decomposeMatrix(matrix, precision);
|
|
242
|
+
if (optimized === '') {
|
|
243
|
+
node.attrs.delete('transform');
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
if (optimized.length < transformAttr.length) {
|
|
247
|
+
node.attrs.set('transform', optimized);
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
// Reconstruct single transform with rounded values
|
|
253
|
+
const valueStr = roundedValues.join(' ');
|
|
254
|
+
const newTransform = `${t.type}(${valueStr})`;
|
|
255
|
+
if (newTransform !== transformAttr) {
|
|
256
|
+
node.attrs.set('transform', newTransform);
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
// Multiple transforms: consolidate
|
|
262
|
+
const matrix = consolidateTransforms(transforms);
|
|
263
|
+
const optimized = decomposeMatrix(matrix, precision);
|
|
264
|
+
if (optimized === '') {
|
|
265
|
+
// Identity matrix - remove transform
|
|
266
|
+
node.attrs.delete('transform');
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
// Use optimized if shorter
|
|
270
|
+
if (optimized.length < transformAttr.length) {
|
|
271
|
+
node.attrs.set('transform', optimized);
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Optimize transforms in the tree
|
|
278
|
+
*/
|
|
279
|
+
export function optimizeTransforms(root, config) {
|
|
280
|
+
let optimizedTransforms = 0;
|
|
281
|
+
let removedIdentity = 0;
|
|
282
|
+
const precision = config.floatPrecision || 3;
|
|
283
|
+
const traverse = (node) => {
|
|
284
|
+
if (!node)
|
|
285
|
+
return;
|
|
286
|
+
if (node.type === 'element' && node.attrs.has('transform')) {
|
|
287
|
+
const hadTransform = node.attrs.has('transform');
|
|
288
|
+
const wasOptimized = optimizeTransform(node, precision);
|
|
289
|
+
if (wasOptimized) {
|
|
290
|
+
if (!node.attrs.has('transform') && hadTransform) {
|
|
291
|
+
removedIdentity++;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
optimizedTransforms++;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Recurse
|
|
299
|
+
for (const child of node.children) {
|
|
300
|
+
if (child.type === 'element') {
|
|
301
|
+
traverse(child);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
traverse(root);
|
|
306
|
+
return {
|
|
307
|
+
optimizedTransforms,
|
|
308
|
+
removedIdentity,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Transform optimization stage for pipeline
|
|
313
|
+
*/
|
|
314
|
+
export function transformOptimizationStage(root, config) {
|
|
315
|
+
const stats = optimizeTransforms(root, config);
|
|
316
|
+
return {
|
|
317
|
+
modified: stats.optimizedTransforms > 0 || stats.removedIdentity > 0,
|
|
318
|
+
stats,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG Tree Serializer
|
|
3
|
+
* Convert tree structure back to minified string
|
|
4
|
+
* Optimized for small output size
|
|
5
|
+
*/
|
|
6
|
+
import type { SVGNode } from './svg-tree-parser.js';
|
|
7
|
+
/**
|
|
8
|
+
* Serializer options
|
|
9
|
+
*/
|
|
10
|
+
export interface SerializerOptions {
|
|
11
|
+
/** Minify output (remove whitespace, newlines) */
|
|
12
|
+
minify: boolean;
|
|
13
|
+
/** Sort attributes alphabetically */
|
|
14
|
+
sortAttributes: boolean;
|
|
15
|
+
/** Use self-closing tags for void elements */
|
|
16
|
+
selfClosing: boolean;
|
|
17
|
+
/** Pretty print with indentation (for debugging) */
|
|
18
|
+
prettyPrint: boolean;
|
|
19
|
+
/** Indentation string (only used if prettyPrint is true) */
|
|
20
|
+
indent: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Serialize SVG node to string
|
|
24
|
+
*/
|
|
25
|
+
export declare function serializeNode(node: SVGNode, options?: Partial<SerializerOptions>, depth?: number): string;
|
|
26
|
+
/**
|
|
27
|
+
* Serialize SVG tree to string (minified by default)
|
|
28
|
+
*/
|
|
29
|
+
export declare function serializeSVG(node: SVGNode | null, options?: Partial<SerializerOptions>): string;
|
|
30
|
+
/**
|
|
31
|
+
* Serialize SVG tree to pretty-printed string (for debugging)
|
|
32
|
+
*/
|
|
33
|
+
export declare function serializeSVGPretty(node: SVGNode | null): string;
|
|
34
|
+
/**
|
|
35
|
+
* Serialize SVG tree to minified string (for production)
|
|
36
|
+
*/
|
|
37
|
+
export declare function serializeSVGMinified(node: SVGNode | null): string;
|
|
38
|
+
/**
|
|
39
|
+
* Calculate size reduction from serialization
|
|
40
|
+
*/
|
|
41
|
+
export declare function calculateReduction(original: string, serialized: string): {
|
|
42
|
+
originalSize: number;
|
|
43
|
+
serializedSize: number;
|
|
44
|
+
reduction: number;
|
|
45
|
+
reductionPercent: number;
|
|
46
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG Tree Serializer
|
|
3
|
+
* Convert tree structure back to minified string
|
|
4
|
+
* Optimized for small output size
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Default serializer options
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_OPTIONS = {
|
|
10
|
+
minify: true,
|
|
11
|
+
sortAttributes: false,
|
|
12
|
+
selfClosing: true,
|
|
13
|
+
prettyPrint: false,
|
|
14
|
+
indent: ' ',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Self-closing elements
|
|
18
|
+
*/
|
|
19
|
+
const SELF_CLOSING_ELEMENTS = new Set([
|
|
20
|
+
'path',
|
|
21
|
+
'rect',
|
|
22
|
+
'circle',
|
|
23
|
+
'ellipse',
|
|
24
|
+
'line',
|
|
25
|
+
'polyline',
|
|
26
|
+
'polygon',
|
|
27
|
+
'use',
|
|
28
|
+
'stop',
|
|
29
|
+
'image',
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* Elements that should preserve content as-is
|
|
33
|
+
*/
|
|
34
|
+
const PRESERVE_CONTENT_ELEMENTS = new Set(['style', 'script']);
|
|
35
|
+
/**
|
|
36
|
+
* Escape attribute value for HTML
|
|
37
|
+
*/
|
|
38
|
+
function escapeAttributeValue(value) {
|
|
39
|
+
return value
|
|
40
|
+
.replace(/&/g, '&')
|
|
41
|
+
.replace(/"/g, '"')
|
|
42
|
+
.replace(/</g, '<')
|
|
43
|
+
.replace(/>/g, '>');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Escape text content for HTML
|
|
47
|
+
*/
|
|
48
|
+
function escapeTextContent(text) {
|
|
49
|
+
return text
|
|
50
|
+
.replace(/&/g, '&')
|
|
51
|
+
.replace(/</g, '<')
|
|
52
|
+
.replace(/>/g, '>');
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Serialize attributes to string
|
|
56
|
+
*/
|
|
57
|
+
function serializeAttributes(attrs, options) {
|
|
58
|
+
if (attrs.size === 0) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
let entries = Array.from(attrs.entries());
|
|
62
|
+
// Sort attributes if requested
|
|
63
|
+
if (options.sortAttributes) {
|
|
64
|
+
entries = entries.sort((a, b) => a[0].localeCompare(b[0]));
|
|
65
|
+
}
|
|
66
|
+
// Build attribute string
|
|
67
|
+
const attrStrings = entries.map(([name, value]) => `${name}="${escapeAttributeValue(value)}"`);
|
|
68
|
+
return ' ' + attrStrings.join(' ');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Serialize SVG node to string
|
|
72
|
+
*/
|
|
73
|
+
export function serializeNode(node, options = {}, depth = 0) {
|
|
74
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
75
|
+
// Handle root container
|
|
76
|
+
if (node.tag === 'root') {
|
|
77
|
+
return node.children
|
|
78
|
+
.map(child => serializeNode(child, opts, depth))
|
|
79
|
+
.join('');
|
|
80
|
+
}
|
|
81
|
+
// Handle comments
|
|
82
|
+
if (node.type === 'comment') {
|
|
83
|
+
if (opts.minify) {
|
|
84
|
+
return ''; // Skip comments in minified output
|
|
85
|
+
}
|
|
86
|
+
return `<!--${node.content || ''}-->`;
|
|
87
|
+
}
|
|
88
|
+
// Handle text nodes
|
|
89
|
+
if (node.type === 'text') {
|
|
90
|
+
const text = node.content || '';
|
|
91
|
+
if (opts.minify) {
|
|
92
|
+
return text.trim();
|
|
93
|
+
}
|
|
94
|
+
return escapeTextContent(text);
|
|
95
|
+
}
|
|
96
|
+
// Build opening tag
|
|
97
|
+
const indent = opts.prettyPrint ? opts.indent.repeat(depth) : '';
|
|
98
|
+
const newline = opts.prettyPrint ? '\n' : '';
|
|
99
|
+
let result = indent + '<' + node.tag;
|
|
100
|
+
// Add attributes
|
|
101
|
+
result += serializeAttributes(node.attrs, opts);
|
|
102
|
+
// Handle self-closing tags
|
|
103
|
+
const isSelfClosing = opts.selfClosing &&
|
|
104
|
+
(SELF_CLOSING_ELEMENTS.has(node.tag) ||
|
|
105
|
+
(node.children.length === 0 && !node.content));
|
|
106
|
+
if (isSelfClosing) {
|
|
107
|
+
result += '/>';
|
|
108
|
+
if (opts.prettyPrint) {
|
|
109
|
+
result += newline;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
result += '>';
|
|
114
|
+
// Handle content
|
|
115
|
+
if (node.content) {
|
|
116
|
+
if (PRESERVE_CONTENT_ELEMENTS.has(node.tag)) {
|
|
117
|
+
// Preserve content as-is for style/script
|
|
118
|
+
result += node.content;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Escape and optionally trim content
|
|
122
|
+
const content = opts.minify ? node.content.trim() : node.content;
|
|
123
|
+
result += opts.minify ? content : escapeTextContent(content);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Handle children
|
|
127
|
+
if (node.children.length > 0) {
|
|
128
|
+
if (opts.prettyPrint) {
|
|
129
|
+
result += newline;
|
|
130
|
+
}
|
|
131
|
+
for (const child of node.children) {
|
|
132
|
+
result += serializeNode(child, opts, depth + 1);
|
|
133
|
+
}
|
|
134
|
+
if (opts.prettyPrint) {
|
|
135
|
+
result += indent;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Closing tag
|
|
139
|
+
result += '</' + node.tag + '>';
|
|
140
|
+
if (opts.prettyPrint) {
|
|
141
|
+
result += newline;
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Serialize SVG tree to string (minified by default)
|
|
147
|
+
*/
|
|
148
|
+
export function serializeSVG(node, options = {}) {
|
|
149
|
+
if (!node) {
|
|
150
|
+
return '';
|
|
151
|
+
}
|
|
152
|
+
return serializeNode(node, options, 0);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Serialize SVG tree to pretty-printed string (for debugging)
|
|
156
|
+
*/
|
|
157
|
+
export function serializeSVGPretty(node) {
|
|
158
|
+
return serializeSVG(node, {
|
|
159
|
+
minify: false,
|
|
160
|
+
prettyPrint: true,
|
|
161
|
+
sortAttributes: false,
|
|
162
|
+
selfClosing: true,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Serialize SVG tree to minified string (for production)
|
|
167
|
+
*/
|
|
168
|
+
export function serializeSVGMinified(node) {
|
|
169
|
+
return serializeSVG(node, {
|
|
170
|
+
minify: true,
|
|
171
|
+
prettyPrint: false,
|
|
172
|
+
sortAttributes: false,
|
|
173
|
+
selfClosing: true,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Calculate size reduction from serialization
|
|
178
|
+
*/
|
|
179
|
+
export function calculateReduction(original, serialized) {
|
|
180
|
+
const originalSize = Buffer.byteLength(original, 'utf8');
|
|
181
|
+
const serializedSize = Buffer.byteLength(serialized, 'utf8');
|
|
182
|
+
const reduction = originalSize - serializedSize;
|
|
183
|
+
const reductionPercent = (reduction / originalSize) * 100;
|
|
184
|
+
return {
|
|
185
|
+
originalSize,
|
|
186
|
+
serializedSize,
|
|
187
|
+
reduction,
|
|
188
|
+
reductionPercent,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-Based Optimization Stages
|
|
3
|
+
* Wrapper for tree-based optimizations in the optimizer pipeline
|
|
4
|
+
* Handles parse → optimize → serialize cycle
|
|
5
|
+
*/
|
|
6
|
+
import type { OptConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Tree-based optimization stage: Remove unused defs
|
|
9
|
+
*/
|
|
10
|
+
export declare function treeRemoveUnusedDefsStage(svg: string, config: OptConfig): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Tree-based optimization stage: Collapse useless groups
|
|
13
|
+
*/
|
|
14
|
+
export declare function treeCollapseGroupsStage(svg: string, config: OptConfig): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Tree-based optimization stage: Move attributes to parent
|
|
17
|
+
*/
|
|
18
|
+
export declare function treeMoveAttributesToParentStage(svg: string, config: OptConfig): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Tree-based optimization stage: Remove hidden and empty elements
|
|
21
|
+
*/
|
|
22
|
+
export declare function treeRemoveHiddenEmptyStage(svg: string, config: OptConfig): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Combined tree-based optimization stage
|
|
25
|
+
* Applies all tree optimizations in one pass for efficiency
|
|
26
|
+
*/
|
|
27
|
+
export declare function treeOptimizationStage(svg: string, config: OptConfig): Promise<string>;
|