{"_id":"@dcg-overseas/graphic-transform","_rev":"19-d2250f89f90430e0d16513798d784557","name":"@dcg-overseas/graphic-transform","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.1":{"name":"@dcg-overseas/graphic-transform","version":"0.1.1","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.1","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"4cad7249b132f694a9f53a71ffb883b293c0ce69","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.1.tgz","fileCount":5,"integrity":"sha512-3gTMLCbVZMkN5NBRomav+jLzRdtnavdmyEbPLpfao05Yac7LE2allvTkeHJL4n8Umut23tojJ4HpUXlXgyYbMA==","signatures":[{"sig":"MEYCIQCpnZ7+oMYa6Z+95TL2LwUrgds0mJJxgwJ11jhXLZILtwIhAIf3Q1wpDbmbMCZK1IeGH3r00RsSo8I3FYl9P/atsII1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58611},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\874e570a40e02ac243797556deb53627\\dcg-overseas-graphic-transform-0.1.1.tgz","_integrity":"sha512-3gTMLCbVZMkN5NBRomav+jLzRdtnavdmyEbPLpfao05Yac7LE2allvTkeHJL4n8Umut23tojJ4HpUXlXgyYbMA==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.1_1777528809439_0.6342529616506571","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@dcg-overseas/graphic-transform","version":"0.1.2","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.2","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"5d002430e6adfce77d3a3ef4b3ac886095332187","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.2.tgz","fileCount":5,"integrity":"sha512-vQyeS5cEViPA08HU4ITAdvYPJjVxiEEIX2Aug3HQTYaRIYFIlvf7oPImiunCWPLyXrGXFQVSAv+97uMCJ5LD/A==","signatures":[{"sig":"MEUCIHuaYbPLbxYXrddcrLebntbYAFrEbP0MQuxhgnpD0li+AiEA4BKlvtkmOVqntsn/MU8B3t79qyOHYhjQM9cbQnAiE2Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66186},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.2.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\a9c1020c92dbb5d67408048c5ff1c0bd\\dcg-overseas-graphic-transform-0.1.2.tgz","_integrity":"sha512-vQyeS5cEViPA08HU4ITAdvYPJjVxiEEIX2Aug3HQTYaRIYFIlvf7oPImiunCWPLyXrGXFQVSAv+97uMCJ5LD/A==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.2_1778034866710_0.7153214617597736","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@dcg-overseas/graphic-transform","version":"0.1.3","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.3","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"5ecb30ebadc5edbfff22baaee597a858c66094d8","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.3.tgz","fileCount":5,"integrity":"sha512-jwnV7AxiSZQmuG/iCPop7MnssJpNfhlA3BpKDRZee1LTo6K38VmBhShDae5YcGxX/Uwpa9O7S7xwfhm+QJAR6g==","signatures":[{"sig":"MEUCIQDQtaZ6KX7fHiVnkti1z+ACVZpOFVVp4sraK4LDokhh8AIgX+lClsheorLDCxKqTLtH10LrTCJNUYLI/dOe9ktdQL8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73398},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.3.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\de6fd896c96cedc7e4eb472a84c1863d\\dcg-overseas-graphic-transform-0.1.3.tgz","_integrity":"sha512-jwnV7AxiSZQmuG/iCPop7MnssJpNfhlA3BpKDRZee1LTo6K38VmBhShDae5YcGxX/Uwpa9O7S7xwfhm+QJAR6g==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.3_1778057561975_0.39210694153343795","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@dcg-overseas/graphic-transform","version":"0.1.4","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.4","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"70cf7366fc3e7bdeeebc6bcc43b275982ccf4695","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.4.tgz","fileCount":5,"integrity":"sha512-W+7B1soq0HxqIJJQgXsnvZBolMtth/U5O/mFzmerXntcJzdtLx8WmkZVjxegaOejBnRd4aNoa9u1/P2z3uMBSA==","signatures":[{"sig":"MEQCIFCGZ1w7+2Ek1hZSRSDO9w2jqHaZq/lPQEfaBRgXOCZkAiAo+iFHP2n/IFHSCQYXk//Rt5K9DYsQ+/7hoxgKzLleLw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73538},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.4.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\ef19ea09b4928470413dc1fdfd1e57c4\\dcg-overseas-graphic-transform-0.1.4.tgz","_integrity":"sha512-W+7B1soq0HxqIJJQgXsnvZBolMtth/U5O/mFzmerXntcJzdtLx8WmkZVjxegaOejBnRd4aNoa9u1/P2z3uMBSA==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.4_1778068465336_0.47678203496518234","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@dcg-overseas/graphic-transform","version":"0.1.5","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.5","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"0c2bc9ffab452504befea38be0c498f7a234467f","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.5.tgz","fileCount":5,"integrity":"sha512-2yTeMWJdPbdqM7nEBJvPqyUwPkQy8g346AKAjvbfj30Lsve8bdhEXTRMU6N85XW6GmKG94KHVEtBkbQZhG1XBg==","signatures":[{"sig":"MEQCIACNqZsH15I9RvrLa0Mj9nnClONMVYup8uFOy7GRdmTgAiBfsD0eCXsWr4rl4U8Zwk+PCNQdHIpeCFQ0ZO8TeAUQEQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74248},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.5.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\4bc5913171ea25214f2dc736fa3fa045\\dcg-overseas-graphic-transform-0.1.5.tgz","_integrity":"sha512-2yTeMWJdPbdqM7nEBJvPqyUwPkQy8g346AKAjvbfj30Lsve8bdhEXTRMU6N85XW6GmKG94KHVEtBkbQZhG1XBg==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.5_1778117330524_0.5071677099541625","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@dcg-overseas/graphic-transform","version":"0.1.6","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.6","maintainers":[{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"}],"dist":{"shasum":"a9cbfe8d76e4390dbfc58081b7136cb70266da18","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.6.tgz","fileCount":5,"integrity":"sha512-6x5zvNLW2TF9aND5zaRDU/4OFNlJ/1PA98nThzPtrAMdCRl3HYM0LLkU2DTVwE729B39vzYqsaYTU/SHJFy1uQ==","signatures":[{"sig":"MEUCIQC7yAhlrX2Me15TZ75VoEJRc9BpghpyanbS7DbefSJ5AwIgAz3qW5BUnBVih3QFuim8Jr2OeazTXW5eRb5iVYZuWP0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75687},"main":"./dist/index.cjs","type":"module","_from":"file:dcg-overseas-graphic-transform-0.1.6.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"w88i817x902","email":"w88i817x90l@163.com"},"_resolved":"C:\\Users\\ADMINI~1.000\\AppData\\Local\\Temp\\3d8152f5a090e3dfa4e9fd56bbc79072\\dcg-overseas-graphic-transform-0.1.6.tgz","_integrity":"sha512-6x5zvNLW2TF9aND5zaRDU/4OFNlJ/1PA98nThzPtrAMdCRl3HYM0LLkU2DTVwE729B39vzYqsaYTU/SHJFy1uQ==","_npmVersion":"11.6.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.12.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.6_1778131367767_0.20925530870538167","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@dcg-overseas/graphic-transform","version":"0.1.7","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.7","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"6478539482d7850e5738d829704f9c52b72ed798","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.7.tgz","fileCount":5,"integrity":"sha512-xW8XGD86MCJl4ue02lVY7BImhmGMkKrDOzSsgb/+j3szKCJZim6kp/wRkjMue3s7qSddgNtte8BfHnhqDGQwbw==","signatures":[{"sig":"MEQCIEBVMLPLgVSQC4o/M3CdqmwMGIqhIadQxFvK2ry4O7FPAiBFlcj4noxzaG2HeJeTsrIF1/kjvzesEsSD2SVLMkM0mw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77022},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"21a5a508c40bf7b775ec828a0436df0ce8dc60ac","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.7_1780044825505_0.6194018517171351","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@dcg-overseas/graphic-transform","version":"0.1.8","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.8","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"ec238cf34033d8d68387bfe3e65fddb964fd973d","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.8.tgz","fileCount":5,"integrity":"sha512-nAh9elde3duTZhepFAWBRdEVQF1tdWFTNfYWa7TsX1D4ZdhK68NQ5sSfYL7a6lvOtwQbMLuVZueTZSTcr+Sn2A==","signatures":[{"sig":"MEQCIAzLDm4mR3skoQVmzmvYirStTCYYfVwMffbulyErheS/AiBN60cDm3Qc9g4nPrMcoIAn/Fgvo31hBG41pevvzXyAMg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77022},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"5ade5ec52eb76493cce9116ff8a480d288787772","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.8_1780049213604_0.8945741035436019","host":"s3://npm-registry-packages-npm-production"}},"0.1.9":{"name":"@dcg-overseas/graphic-transform","version":"0.1.9","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.9","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"28744b7d3e23f0148c414912bb50b071370a52de","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.9.tgz","fileCount":5,"integrity":"sha512-zMvnLh/sx5wIoS7GaVANnDoDiOin6sDffQ/hRt1b1YyAGeN2M0CDNegXj7rr0nnJBtWG/Pg06rYpmiz057kdoQ==","signatures":[{"sig":"MEQCIEdZAJOKJANJjpwcAcmuiseBtKEh5aLpmXF7yk+jTSDnAiA1CdByWFJUcSPwH+EhAJDkvygK8YAMlIZo5LZVw84Yrg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77022},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"e600c96aa3e9076f21819eeb9cc0eeba2dcc757a","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.9_1780051342115_0.2913838221975209","host":"s3://npm-registry-packages-npm-production"}},"0.1.10":{"name":"@dcg-overseas/graphic-transform","version":"0.1.10","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.10","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"27114b904a08d2b64624db84a6c1f0abab4cced0","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.10.tgz","fileCount":5,"integrity":"sha512-8m9EJu9CipmdfBUWr0khX2b3RfMlgbMK/LY8ItyTgfEKZgwKei+XPWpjkPB4fVs8H/gRQtmNN3OGz7UKjYy8Nw==","signatures":[{"sig":"MEYCIQCmXVMk53htbl/wIuc+rLEfsEPsBUa5xsgd6I8gZZc3GgIhAMWLcWd18CcmfTP4UPiU7cXcWwYRjJ6L6s02DV6GGcgC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76739},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"4450ea3d3b61e06f37de1e3aac59388afbb88295","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"smileniuma001","email":"1124990187@qq.com"},"_npmVersion":"10.8.2","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"20.19.6","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.10_1780307225250_0.4413556982601947","host":"s3://npm-registry-packages-npm-production"}},"0.1.11":{"name":"@dcg-overseas/graphic-transform","version":"0.1.11","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.11","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"b8502f83d501b07c44c6170de6751b27130e0a66","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.11.tgz","fileCount":5,"integrity":"sha512-Spmb13Mo3bqoekZxU1Vu6U5axhshAy/FTZmWmUml4tzr6Mp4cKEfxjpae4/XI0DCOAkVPs0Wcy8YIdJIiFA3Lw==","signatures":[{"sig":"MEYCIQDGiyU6McwbfhvomSaisHIR/XBuEivkWJn16lvitNcE7gIhAK7MoFCllIL8tDczNb6458Ztp08QNF/b9aVgK7YuvZgJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82519},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"2caccbc359f87d3db0c1bc9bf842433ae94aecfc","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.11_1783142604578_0.8969037621213491","host":"s3://npm-registry-packages-npm-production"}},"0.1.12":{"name":"@dcg-overseas/graphic-transform","version":"0.1.12","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.12","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"465d3053372929fd0fd359fbde1149fd7d430da6","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.12.tgz","fileCount":5,"integrity":"sha512-fDNDrgwtyG3ScZKeal2BTKYVYpwEhhmNvD9x5cekvIYH93WWLg8kPLEY+97iG+hXx/e7WRsbUu8jWGyiaS1nOQ==","signatures":[{"sig":"MEUCIGL3VotAs96lK+nPxrUTCNKIZ9lOQdACwzuTynAGiI2eAiEA7mqM9QPO5heiBQGUscY/AMyfa10l/Ggcdc5tYo8VJ00=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82579},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"ea427459bfb488de6909f3684a7756cebf4468d9","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.12_1783160943733_0.5426353852522925","host":"s3://npm-registry-packages-npm-production"}},"0.1.13":{"name":"@dcg-overseas/graphic-transform","version":"0.1.13","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.1.13","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"bec2302595c351de0324291784a4ba31bc9d84a7","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.1.13.tgz","fileCount":5,"integrity":"sha512-iQDUhjGfw1xKKkES7HkQ80NyC6gfhd5cANhy1A2UquyGAZR3wImtJBDHVgXNBkq9rsUlAvMiUxKKqqfL6nOQSw==","signatures":[{"sig":"MEUCIQCy07WvIVvuH0jKONMhHp4rh+KeIEuJsaUwj4QZm/juNQIgBPdjU+TOGPQ0OlLHZf9s5c6N5zRaPaPj1bbbBn1GwkI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82579},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"ea427459bfb488de6909f3684a7756cebf4468d9","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.1.13_1783161707855_0.48417434527528846","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@dcg-overseas/graphic-transform","version":"0.2.0","license":"MIT","_id":"@dcg-overseas/graphic-transform@0.2.0","maintainers":[{"name":"thiszhangjin","email":"thiszhangjin@gmail.com"},{"name":"smileniuma001","email":"1124990187@qq.com"},{"name":"haoyouzhe","email":"1617629831@qq.com"},{"name":"w88i817x902","email":"w88i817x90l@163.com"},{"name":"hanqin","email":"lif605013@gmail.com"}],"dist":{"shasum":"92d6abc99e7a786eebac839d5d332a68e13dad76","tarball":"https://registry.npmjs.org/@dcg-overseas/graphic-transform/-/graphic-transform-0.2.0.tgz","fileCount":5,"integrity":"sha512-47qkDlwV74zhxUiRWeSRa1YYGGRmw8Xbv7WkZaaLOkajFWd3w4hlFFP8o6gbhbgUJf6w5WskzuaLx1nWxy/kyw==","signatures":[{"sig":"MEUCIBbRVn3cgpogk9cZiNDnmIgJNBzNu3TBSpXkzT1c1oUCAiEAvf+ElzVQWzMioGl4UlBYLwXZYCDDre9a0kjqzM5uoXY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95959},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"d8f68de7bcad41ff4121e3d6bde67b8d647b9380","scripts":{"lint":"eslint src --ext .ts,.tsx","build":"vite build","clean":"rm -rf dist *.tsbuildinfo","typecheck":"tsc --noEmit","build:watch":"vite build --watch"},"_npmUser":{"name":"haoyouzhe","email":"1617629831@qq.com"},"_npmVersion":"11.6.0","description":"Graphic transform tool","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.1","@types/react":"^18.3.3","lucide-react":"^0.400.0","vite-plugin-dts":"^3.9.1","@types/react-dom":"^18.3.0","@vitejs/plugin-react":"^4.3.1","vite-plugin-css-injected-by-js":"^4.0.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.400.0"},"_npmOperationalInternal":{"tmp":"tmp/graphic-transform_0.2.0_1783169978954_0.248076538059385","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-04-30T06:00:09.347Z","modified":"2026-09-01T11:25:09.718Z","0.1.1":"2026-04-30T06:00:09.588Z","0.1.2":"2026-05-06T02:34:26.839Z","0.1.3":"2026-05-06T08:52:42.097Z","0.1.4":"2026-05-06T11:54:25.469Z","0.1.5":"2026-05-07T01:28:50.677Z","0.1.6":"2026-05-07T05:22:47.910Z","0.1.7":"2026-05-29T08:53:45.627Z","0.1.8":"2026-05-29T10:06:53.747Z","0.1.9":"2026-05-29T10:42:22.250Z","0.1.10":"2026-06-01T09:47:05.403Z","0.1.11":"2026-07-04T05:23:24.752Z","0.1.12":"2026-07-04T10:29:03.858Z","0.1.13":"2026-07-04T10:41:48.008Z","0.2.0":"2026-07-04T12:59:39.125Z"},"license":"MIT","description":"Graphic transform tool","maintainers":[{"email":"thiszhangjin@gmail.com","name":"thiszhangjin"},{"email":"1124990187@qq.com","name":"smileniuma001"},{"email":"1617629831@qq.com","name":"haoyouzhe"},{"email":"w88i817x90l@163.com","name":"w88i817x902"},{"email":"zxy1833324628@163.com","name":"zhaoxiuyu"},{"email":"heyuqing@dcrays.cn","name":"heyuqing"},{"email":"lif605013@gmail.com","name":"hanqin"}],"readme":"# @dcg-overseas/graphic-transform\r\n\r\n为小学数学教学场景提供的**图形变换**工具：在 14×14 网格上对图形执行 **平移 / 反射 / 旋转**，配套受控状态、内部历史栈、画布拖拽和 palette → canvas 拖放。\r\n\r\n包提供 **画布 + 操作逻辑**；消费者负责 **变换类型选择器、参数面板、形状选择器、撤销/重置工具栏**。所有 UI 由应用层组合，包不携带 CSS。\r\n\r\n---\r\n\r\n## 安装\r\n\r\n```bash\r\npnpm add @dcg-overseas/graphic-transform\r\n```\r\n\r\n`react`、`react-dom`（`>=18`）作为 peer 依赖。\r\n\r\n---\r\n\r\n## 快速开始\r\n\r\n```tsx\r\nimport { useState } from 'react'\r\nimport {\r\n  GraphicTransformProvider,\r\n  GraphicTransformBoard,\r\n  useGraphicTransformContext,\r\n} from '@dcg-overseas/graphic-transform'\r\nimport type { TransformType } from '@dcg-overseas/graphic-transform'\r\n\r\nexport default function Demo() {\r\n  const [transformType, setTransformType] = useState<TransformType | null>(null)\r\n\r\n  return (\r\n    <GraphicTransformProvider transformType={transformType}>\r\n      <ModeSelect value={transformType} onChange={setTransformType} />\r\n\r\n      {/* Board fills its parent — wrap it in a sized container */}\r\n      <div style={{ width: 480, height: 480 }}>\r\n        <GraphicTransformBoard />\r\n      </div>\r\n\r\n      <Toolbar />\r\n    </GraphicTransformProvider>\r\n  )\r\n}\r\n\r\nfunction ModeSelect({ value, onChange }: {\r\n  value: TransformType | null\r\n  onChange: (t: TransformType | null) => void\r\n}) {\r\n  return (\r\n    <select value={value ?? ''} onChange={(e) => onChange((e.target.value || null) as TransformType | null)}>\r\n      <option value=\"\">请选择</option>\r\n      <option value=\"translation\">平移</option>\r\n      <option value=\"reflection\">反射</option>\r\n      <option value=\"rotation\">旋转</option>\r\n    </select>\r\n  )\r\n}\r\n\r\nfunction Toolbar() {\r\n  const { canUndo, undo, reset } = useGraphicTransformContext()\r\n  return (\r\n    <div>\r\n      <button onClick={undo} disabled={!canUndo}>撤销</button>\r\n      <button onClick={reset}>重置</button>\r\n    </div>\r\n  )\r\n}\r\n```\r\n\r\n完整可运行示例见 [`apps/web/src/pages/graphic-transform/`](../../apps/web/src/pages/graphic-transform/)。\r\n\r\n---\r\n\r\n## 设计\r\n\r\n```\r\nGraphicTransformProvider ─── 历史栈 (DrawingState[])\r\n       │                     变换数学\r\n       │                     拖拽/落点 client→math 换算\r\n       │                     theme + classNames 默认值\r\n       │\r\n       ├── GraphicTransformBoard         ← 渲染 SVG 画布\r\n       │\r\n       └── useGraphicTransformContext()  ← 任意后代读取状态、调操作\r\n```\r\n\r\n- **`transformType`** 由消费者受控（`useState` + select）—— 包不会单独存它，所以切换变换类型不会污染 history 栈。\r\n- **绘图状态**（`shapeId` / `shapeOffset` / `translation` / `reflection` / `rotation`）**由包内拥有**，每次变更都进 history。撤销永远只回退“一次有意义的绘制操作”。\r\n- **画布拖拽**期间使用 `tempOffset` 临时显示，松手时一次性 push 到 history。\r\n- **palette → canvas 拖放**由消费者实现（自定义预览/ghost），调用 `ctx.dropShapeAtClientPoint(shapeId, clientX, clientY)` 即可完成落点换算并入 history。\r\n\r\n---\r\n\r\n## API 参考\r\n\r\n### `<GraphicTransformProvider>` props\r\n\r\n| Prop | 类型 | 必填 | 说明 |\r\n|---|---|---|---|\r\n| `transformType` | `TransformType \\| null` | ✓ | 当前变换类型，**消费者受控**。`null` 表示“请选择”空态。 |\r\n| `shapes` | `Record<ShapeId, ShapeDef>` | ✓ | 形状注册表。可用 `makeShape()` 构建，或直接传字面量；`DEFAULT_SHAPES` 提供内置 6 图形。 |\r\n| `shapeIds` | `ShapeId[]` | | palette 下拉的稳定顺序；缺省用 `Object.keys(shapes)`。 |\r\n| `initialDrawingState` | `Partial<DrawingState>` | | 仅在首次挂载时使用的初始绘图状态。 |\r\n| `theme` | `GraphicTransformTheme` | | inline-style fallback 颜色/线宽，见 [主题](#主题-graphictransformtheme)。 |\r\n| `classNames` | `GraphicTransformClassNames` | | SVG 元素的 className 覆盖，见 [classNames 定制](#classnames-定制)。 |\r\n| `children` | `ReactNode` | ✓ | 任意放在 context 内的组件（Board + 你的工具栏 / 面板）。 |\r\n\r\n> Provider **没有** `width` / `height`。`<GraphicTransformBoard>` 自动填满父容器，父容器 CSS 决定画布尺寸。\r\n\r\n### `<GraphicTransformBoard>` props\r\n\r\n无。组件从 context 读取所有状态，**填满最近的父容器**：\r\n\r\n```tsx\r\n<div style={{ width: 480, height: 480 }}>\r\n  <GraphicTransformBoard />\r\n</div>\r\n```\r\n\r\nSVG 内已设置 `touch-action: none`，移动端拖拽不会被浏览器误判为滚动。\r\n\r\n### `useGraphicTransformContext()` 返回值\r\n\r\n```ts\r\n{\r\n  // 受控配置（来自 props）\r\n  transformType: TransformType | null,\r\n\r\n  // 形状注册表\r\n  shapes:   Record<ShapeId, ShapeDef>,\r\n  shapeIds: ShapeId[],\r\n\r\n  // 当前绘图状态（来自 history 栈顶；拖拽中是 tempOffset）\r\n  shapeId:     ShapeId | null,\r\n  shapeOffset: Point,\r\n  translation: TranslationState,\r\n  reflection:  ReflectionState,\r\n  rotation:    RotationState,\r\n\r\n  // 派生（memo）\r\n  currentShape:       ShapeDef | null,\r\n  originalPoints:     Point[],       // 原始多边形（已加 offset）\r\n  transformedPoints:  Point[],       // 变换后多边形（参数不全时为 []）\r\n  maxTranslation:     { up, down, left, right },\r\n  isReflectionActive: boolean,\r\n  isDragging:         boolean,\r\n  rotationCenterCanvas: Point | null, // 生效旋转中心（canvas 坐标交叉点；未选完为 null）\r\n\r\n  // 写入（自动入 history）\r\n  setShapeId:     (id: ShapeId | null) => void,\r\n  setTranslation: (t: TranslationState) => void,\r\n  setReflection:  (r: ReflectionState)  => void,\r\n  setRotation:    (r: RotationState)    => void,\r\n  /** 切换旋转中心模式（'grid-center' | 'custom' | null）；会清空方向/角度/已选交叉点 */\r\n  setRotationCenterMode:   (mode: RotationCenterMode | null) => void,\r\n  /** 选定 canvas 交叉点为旋转中心（custom 模式下 Board 内部调用；会清空方向/角度） */\r\n  setRotationCustomCenter: (p: Point) => void,\r\n\r\n  // 历史\r\n  canUndo: boolean,\r\n  undo:    () => void,\r\n  reset:   () => void,\r\n\r\n  // 拖放（应用层 palette 调用）\r\n  /** 把图形落到屏幕坐标点；命中画布返回 true 并入 history，否则返回 false */\r\n  dropShapeAtClientPoint: (shapeId: ShapeId, clientX: number, clientY: number) => boolean,\r\n\r\n  // theme / classNames（已填默认值）\r\n  theme:      Required<GraphicTransformTheme>,\r\n  classNames: Required<GraphicTransformClassNames>,\r\n\r\n  // 内部 — Board 使用，消费者通常不需要\r\n  beginCanvasDrag, updateCanvasDrag, endCanvasDrag, registerSvgRef,\r\n}\r\n```\r\n\r\n---\r\n\r\n## 数据模型\r\n\r\n```ts\r\ntype TransformType      = 'translation' | 'reflection' | 'rotation'\r\ntype ShapeId            = string                 // 开放 id，消费者自建注册表\r\ntype ReflectionAxis     = 'vertical' | 'horizontal'\r\ntype RotationDirection  = 'clockwise' | 'counter-clockwise'\r\ntype RotationAngle      = '90' | '180' | '270' | '360'\r\ntype RotationCenterMode = 'grid-center' | 'custom'\r\n\r\ninterface Point { x: number; y: number }\r\n\r\ninterface TranslationState {\r\n  upDownVal:    number\r\n  upDownDir:    'up' | 'down'\r\n  leftRightVal: number\r\n  leftRightDir: 'left' | 'right'\r\n}\r\n\r\ninterface ReflectionState { axis: ReflectionAxis | null }\r\ninterface RotationState   {\r\n  direction:    RotationDirection | null\r\n  angle:        RotationAngle | null\r\n  /** 旋转中心模式；null = 未选择（不产生旋转结果） */\r\n  centerMode:   RotationCenterMode | null\r\n  /** 用户点选的网格交叉点（canvas 坐标整数）；仅 centerMode === 'custom' 时有意义 */\r\n  customCenter: Point | null\r\n}\r\n\r\ninterface DrawingState {\r\n  shapeId:     ShapeId | null\r\n  shapeOffset: Point\r\n  translation: TranslationState\r\n  reflection:  ReflectionState\r\n  rotation:    RotationState\r\n}\r\n```\r\n\r\n所有坐标都是**网格单位**（整数）。grid 范围固定 `[-7, 7]`，即 14×14 格。\r\n\r\n---\r\n\r\n## 内置图形\r\n\r\n```ts\r\nimport { DEFAULT_SHAPES } from '@dcg-overseas/graphic-transform'\r\n```\r\n\r\n| ID | 图形 | 顶点数 |\r\n|---|---|---|\r\n| `shape1` | 直角三角形 | 3 |\r\n| `shape2` | 凹五边形（M 形） | 5 |\r\n| `shape3` | 箭头六边形 | 6 |\r\n| `shape4` | 五边形房屋 | 5 |\r\n| `shape5` | 蝴蝶结 | 6 |\r\n| `shape6` | 等腰三角形 | 3 |\r\n\r\n`DEFAULT_SHAPES[id].label` 提供中文显示名，可直接用于 `<select>`。`ShapeDef.rotationCenter` 字段已 **@deprecated**（旋转中心现锚定在画布上，见下节），运行时不再读取。\r\n\r\n---\r\n\r\n## 变换数学\r\n\r\n### 平移\r\n`(x, y) → (x + dx, y + dy)`，其中 `dx = leftRightDir==='right' ? +val : -val`，`dy` 同理（“上”为正）。\r\n\r\n### 反射\r\n- 垂直对称（纵轴 y 轴）：`(x, y) → (-x, y)`\r\n- 水平对称（横轴 x 轴）：`(x, y) → (x, -y)`\r\n\r\n### 旋转\r\n绕**画布锚定**的旋转中心旋转 `angle` 度，顺时针为视觉负向（SVG y 轴在显示前已通过 `<g transform=\"scale(1,-1)\">` 翻转）。90°/180°/270°/360° 走精确整数路径（坐标交换，无 cos/sin 浮点误差）；`360°` 即恒等变换，`270°` 等同反方向 `90°`。\r\n\r\n**旋转中心两种模式**（`rotation.centerMode`）：\r\n\r\n- **`'grid-center'`（居中）**：中心 = 画布原点 `(0, 0)`。正方形画布绕自身中心旋转 90° 倍数不变，所以此模式下 8 种方向×角度组合恒合法。\r\n- **`'custom'`（自行选择）**：中心 = 用户在画布上点选的任意网格交叉点（15×15 个，可在图形内/外/顶点上）。Board 内置交互：鼠标悬停时最近交叉点显示**浅橙**预览点（触屏为按下即预览），点击（按下→抬起位移 < 5px，与拖图消歧）后确定，**橙色**圆点落在该点并调用 `setRotationCustomCenter`。\r\n\r\n未选模式（或 custom 模式未点选交叉点）时 `rotationCenterCanvas` 为 `null`，不产生旋转结果，消费者应禁用方向/角度选项。切换模式或换点会**清空方向/角度**（旧结果绕另一点算出）并入历史。\r\n\r\n**拖图钳制**：中心锚在画布上，拖动图形时中心不动，图形移动 `Δo` 时旋转像移动 `R(Δo)`。包内用盒交集精确钳制——合法 offset 区域 = `B_base ∩ R⁻¹(B_image)`（90° 倍数旋转下轴对齐盒保持轴对齐），保证拖到任何位置原图与像都不出界。`rotationLegality` 随中心/位置自动重算。\r\n\r\n---\r\n\r\n## 主题 (`GraphicTransformTheme`)\r\n\r\ninline-style fallback，**仅在对应 className 为空时生效**。如果你给 `classNames` 全填了，theme 颜色不会有任何效果（因为 className 模式完全交给 CSS）。\r\n\r\n```ts\r\n{\r\n  axisStrokeWidth?:     number  // 默认 0.02\r\n  gridStrokeWidth?:     number  // 默认 0.02\r\n  axisColor?:           string  // 默认 '#e2e8f0'\r\n  gridColor?:           string  // 默认 '#e2e8f0'\r\n  originalFill?:        string  // 默认 '#bfdbfe'   原始图形\r\n  originalStroke?:      string  // 默认 '#2563eb'\r\n  transformedFill?:     string  // 默认 '#fecaca'   变换后（平移/旋转）\r\n  transformedStroke?:   string  // 默认 '#dc2626'\r\n  reflectionFill?:      string  // 默认 '#fed7aa'   反射时覆盖 transformed*\r\n  reflectionStroke?:    string  // 默认 '#ea580c'\r\n  mirrorLineColor?:     string  // 默认 '#ef4444'\r\n  rotationCenterColor?:        string  // 默认 '#f97316'  生效旋转中心（橙）\r\n  rotationCenterPreviewColor?: string  // 默认 '#fdba74'  悬停预览点（浅橙）\r\n  boundaryColor?:       string  // 默认 '#e2e8f0'   画布内边界\r\n  boundaryStrokeWidth?: number  // 默认 0.05\r\n}\r\n```\r\n\r\n适合“零 CSS 即可使用”的场景。下一节是更灵活的 className 定制。\r\n\r\n---\r\n\r\n## classNames 定制\r\n\r\n包不携带 CSS。如果你需要伪类（`:hover`、`.dragging`）、媒体查询、CSS 变量，请走 className 路径：\r\n\r\n```tsx\r\nimport type { GraphicTransformClassNames } from '@dcg-overseas/graphic-transform'\r\n\r\nconst BOARD_CLASS_NAMES: GraphicTransformClassNames = {\r\n  svg:                          'gt-board-svg',\r\n  boundary:                     'gt-boundary',\r\n  gridLine:                     'gt-grid-line',\r\n  axis:                         'gt-axis',\r\n  mirrorLine:                   'gt-mirror-line',\r\n  shapeOriginal:                'gt-shape-original',\r\n  shapeOriginalDragging:        'dragging',           // 拖拽时附加在 shapeOriginal 上\r\n  shapeTransformed:             'gt-shape-transformed',\r\n  shapeTransformedReflection:   'reflection',         // 反射时附加在 shapeTransformed 上\r\n  rotationCenter:               'gt-rotation-center',\r\n  rotationCenterPreview:        'gt-rotation-center-preview',\r\n}\r\n\r\n<GraphicTransformProvider transformType={transformType} classNames={BOARD_CLASS_NAMES}>\r\n  …\r\n</GraphicTransformProvider>\r\n```\r\n\r\n对应 CSS 示例：\r\n\r\n```css\r\n.gt-board-svg            { width: 100%; height: 100%; touch-action: none; }\r\n.gt-boundary             { fill: none; stroke: #e2e8f0; stroke-width: 0.05; }\r\n.gt-grid-line            { stroke: #e2e8f0; }\r\n.gt-axis                 { stroke: #94a3b8; }\r\n.gt-mirror-line          { stroke: #ef4444; }\r\n.gt-rotation-center      { fill: #f97316; }\r\n.gt-rotation-center-preview { fill: #fdba74; }\r\n.gt-shape-original       { fill: #bfdbfe; stroke: #2563eb; cursor: grab; stroke-width: 0.1; }\r\n.gt-shape-original.dragging       { cursor: grabbing; }\r\n.gt-shape-transformed    { fill: #fecaca; stroke: #dc2626; fill-opacity: 0.7; pointer-events: none; }\r\n.gt-shape-transformed.reflection  { fill: #fed7aa; stroke: #ea580c; }\r\n```\r\n\r\n**取舍**：对每个 SVG 元素，如果你给了 className，Board 不再写 inline `style`（`fill`/`stroke` 都靠你的 CSS）；如果某个 className 是空字符串，则使用 theme 的 inline-style fallback。**可以混用** —— 比如只给 `shapeOriginal` 一个 className（为了 `:hover`），其它元素继续吃 theme。\r\n\r\n---\r\n\r\n## palette → canvas 拖放\r\n\r\n包不渲染 palette，但提供了“落点换算”原语：\r\n\r\n```tsx\r\nfunction MyShapePalette() {\r\n  const { dropShapeAtClientPoint } = useGraphicTransformContext()\r\n  const [drag, setDrag] = useState<{ shapeId: ShapeId; x: number; y: number } | null>(null)\r\n\r\n  return (\r\n    <div\r\n      style={{ touchAction: 'none', cursor: 'grab' }}\r\n      onPointerDown={(e) => {\r\n        e.currentTarget.setPointerCapture(e.pointerId)\r\n        setDrag({ shapeId: 'shape1', x: e.clientX, y: e.clientY })\r\n      }}\r\n      onPointerMove={(e) => drag && setDrag({ ...drag, x: e.clientX, y: e.clientY })}\r\n      onPointerUp={(e) => {\r\n        if (!drag) return\r\n        e.currentTarget.releasePointerCapture(e.pointerId)\r\n        dropShapeAtClientPoint(drag.shapeId, e.clientX, e.clientY)\r\n        setDrag(null)\r\n      }}\r\n      onPointerCancel={() => setDrag(null)}\r\n    >\r\n      {/* 你的预览 + 跟随手指的 ghost */}\r\n    </div>\r\n  )\r\n}\r\n```\r\n\r\n`dropShapeAtClientPoint` 会：\r\n1. 检查屏幕坐标是否落在 SVG 边界内，否则返回 `false` 不入 history\r\n2. 通过 `getScreenCTM()` 把 `clientX/Y` 转为 SVG 网格坐标\r\n3. `Math.round` 吸附到整数格\r\n4. 用形状的多边形顶点裁剪到 ±7 边界\r\n5. 一次性 push 到 history\r\n\r\n完整 palette 示例（含 ghost）：[`apps/web/src/pages/graphic-transform/components.tsx`](../../apps/web/src/pages/graphic-transform/components.tsx)。\r\n\r\n---\r\n\r\n## 撤销策略\r\n\r\n每次以下操作进 history，可单步撤销：\r\n\r\n- `setShapeId` —— 选 / 换 / 清图形（保留画布锚定的旋转中心，清空方向/角度）\r\n- `setTranslation` / `setReflection` / `setRotation` —— 改任意参数\r\n- `setRotationCenterMode` —— 切换旋转中心模式（同时清空方向/角度/已选交叉点，一步可撤销）\r\n- `setRotationCustomCenter` —— 点选 / 换选交叉点（同时清空方向/角度，一步可撤销）\r\n- 画布上拖拽图形（松手时一次）\r\n- palette → canvas 落点（命中时一次）\r\n\r\n**不进** history：\r\n\r\n- 切换 `transformType`（消费者状态，与 history 解耦）\r\n- 拖拽过程中的中间帧\r\n- 选点模式的悬停预览点（Board 内部瞬态 UI）\r\n\r\n`reset()` 清空整个 history。\r\n\r\n---\r\n\r\n## 网格约定\r\n\r\n- 14×14 格，坐标范围 `[-7, 7]`，`HALF_GRID = 7`\r\n- SVG `viewBox=\"-7 -7 14 14\"`，通过 CSS `transform: scale(1, -1)` 把 y 轴翻转为数学习惯（向上为正）\r\n- 1 格 = `画布像素 / 14`，响应父容器宽度\r\n\r\n---\r\n\r\n## 移动端\r\n\r\n- 默认 `touch-action: none`，单指拖拽不会触发页面滚动\r\n- 使用 Pointer Events（统一鼠标 / 触摸 / 笔），`setPointerCapture` 保证手指移出元素后事件继续触发\r\n- 已处理 `pointercancel`：系统中断手势时会清理拖拽状态\r\n\r\n---\r\n\r\n## 导出\r\n\r\n```ts\r\n// 组件 + Hook\r\nexport { GraphicTransformProvider, GraphicTransformBoard }\r\nexport { useGraphicTransformContext, GraphicTransformContext }\r\n\r\n// 常量\r\nexport { DEFAULT_SHAPES, GRID_SIZE, HALF_GRID, INITIAL_STATE }\r\n\r\n// 几何工具（纯函数）\r\nexport {\r\n  applyTransform, clampDragOffset, clampOffsetToGrid, clientToSvgPoint,\r\n  computeMaxTranslation, computeRotationLegalityMap, EMPTY_ROTATION_LEGALITY,\r\n  isClientPointInsideSvg, makeShape, pointsInBounds, snapToGridIntersection,\r\n}\r\n\r\n// 类型\r\nexport type {\r\n  AppState, DrawingState, Point, ShapeDef, ShapeId,\r\n  TransformType, TranslationState, ReflectionState, RotationState,\r\n  ReflectionAxis, RotationAngle, RotationCenterMode, RotationDirection,\r\n  RotationLegalityMap,\r\n  GraphicTransformTheme, GraphicTransformClassNames,\r\n  GraphicTransformProviderProps, GraphicTransformContextValue,\r\n}\r\n```\r\n","readmeFilename":"README.md"}