diff --git a/psd2ui-tools/README.md b/psd2ui-tools/README.md
new file mode 100644
index 0000000..78f5474
--- /dev/null
+++ b/psd2ui-tools/README.md
@@ -0,0 +1,296 @@
+## 属性
+
+ @Btn | @btn 按钮
+
+ @ProgressBar | @progressBar 进度条
+
+ @Toggle | @toggle 选项按钮
+
+ @.9 九宫格
+
+ @ar 锚点
+
+ @size 尺寸
+
+ @full 全屏
+
+ @scale 缩放
+
+ @ignore | @ig 忽略导出图片和节点
+
+ @ignorenode | @ignode 忽略导出节点
+
+ @ignoreimg | @igimg 忽略图片
+
+ @img 图片选项
+
+ @flip 翻转图像
+
+ @flipX 翻转图像 (flip 变种)
+
+ @flipY 翻转图像 (flip 变种)
+
+
+
+### 组件
+
+
+```
+@Btn || @btn
+
+作用图层: 所有图层
+```
+
+
+```
+@ProgressBar || @progressBar
+作用图层: 组图层
+
+@bar
+
+bar 为 ProgressBar 的属性,类型为 Sprite
+作用图层: 图像图层
+```
+
+
+```
+@Toggle || @toggle
+作用图层: 组图层
+
+@check
+
+check 为 Toggle 的属性,类型为 Sprite
+作用图层: 图像图层
+
+
+```
+
+### Field
+
+
+
+```
+@.9{l:0,r:0,b:0,t:0}
+
+九宫格
+作用图层: 图像图层
+
+参数:
+ l = left
+ r = right
+ b = bottom
+ t = top
+ ps:
+ l r 只填写其中一项,则为对称
+ b t 同上
+ 不填写则默认为 0
+```
+
+```
+@ar{x:0,y:0}
+
+锚点
+作用图层: 所有图层
+
+参数:
+ 参数都为可选
+ 不填写则默认为 0.5
+
+```
+
+
+```
+@size{w:100,h:100}
+
+节点尺寸 非图片尺寸
+作用图层: 所有图层
+
+参数:
+ w?: 宽
+ h?: 高
+ 只对填写的参数生效,未填写的则为计算到的值
+ 无参数不生效
+
+```
+
+
+```
+@full
+
+节点设置为全屏尺寸
+作用图层: 组图层
+
+```
+
+
+```
+@scale{x:1,y:1}
+
+节点缩放
+作用图层: 所有图层
+
+参数:
+ x?: x 方向
+ y?: y 方向
+ 只对填写的参数生效,未填写的则为 1
+
+```
+
+
+```
+@ignore
+@ig
+
+忽略导出图像和节点
+作用图层: 所有图层
+```
+
+
+```
+@ignorenode
+@ignode
+
+忽略导出节点
+作用图层: 所有图层
+```
+
+
+```
+@ignoreimg
+@igimg
+
+忽略导出图像
+作用图层: 图像图层
+```
+
+
+```
+@img{name:string,id:number,bind:number}
+
+定制图片
+作用图层:图像图层
+
+参数:
+ id: number 可选 当前文档中图片唯一 id
+ name: string 可选 导出的图片名
+ bind: number 可选 绑定 图像 id
+```
+
+
+```
+@flip{bind: 0, x: 0, y: 0}
+
+镜像图像
+作用图层:图像图层
+
+参数:
+ bind: number 必选 被绑定的图片 需要用 @img{id:number} 做标记
+ x: 0 | 1, 可选, 1 为 进行 x 方向镜像
+ y: 0 | 1, 可选, 1 为 进行 y 方向镜像
+ x,y 都缺省时,默认 x 方向镜像
+
+注意:
+ @flip 的图层不会导出图像
+```
+
+
+```
+@flipX{bind: 0}
+
+flip 的变种 x 方向镜像图像
+作用图层:图像图层
+
+参数:
+ bind: number 必选 被绑定的图片 需要用 @img{id:number} 做标记
+
+注意:
+ @flipX 的图层不会导出图像
+```
+
+
+```
+@flipY{bind: 0}
+
+flip 的变种 y 方向镜像图像vv
+作用图层:图像图层
+
+参数:
+ bind: number 必选 被绑定的图片 需要用 @img{id:number} 做标记
+
+注意:
+ @flipY 的图层不会导出图像
+```
+
+
+
+### 说明
+ 多个字段可作用在同一个图层上,按需使用
+
+
+
+### 例如
+```
+节点名@Btn@size{w:100,h:100}
+
+节点名@ar{x:1,y:1}@full@img{name:bg}
+```
+
+
+
+### 美术
+- 智能图层 支持
+- 图层样式
+- 颜色叠加 图层图层不支持,文本图层支持
+- 描边 文本图层支持
+
+工具会把 画布外的图像也导出成图片,需要美术将 画布外 不需要导出的图像处理掉
+需要美术将多个碎图组合的图像合并成智能图层使用
+
+
+
+### 程序 配置
+json 文件,key 为组件名,val 为 预制体参数
+如下:
+```
+{
+ "cc.Label": {
+ "__type__": "e4f88adp3hERoJ48DZ2PSAl",
+ "_N$file":{
+ "__uuid__": "803c185c-9442-4b99-af1a-682f877539ab"
+ },
+ "_isSystemFontUsed": false,
+ "isFixNumber": true
+ }
+}
+```
+
+##### 特殊配置
+```
+ "textOffsetY":{
+ "default": -3,
+ "36": -3
+ }
+
+
+textOffsetY label节点 Y 偏移
+
+以字号为 key ,偏移值 为 val
+如果没有配置 某些字号,则 使用 default 默认偏移值,如果没有配置 default, 偏移为 0
+
+```
+
+### 已知bug
+使用 强制导出图片选项时,输入为多个 psd 或含有多个 psd 文件的文件夹时,如果在不同 psd 含有相同 md5 的图像,则会在各自目录下生成相同 uuid 的图片
+
+
+
+
+
+### CHANGELOG
+- 增加只导出 图片功能
+
+- 移除 @mirror 中的参数: {id}
+- 移除 @flipX & @flipY 中的参数: {id}
+- 使用 @flip 替换 @mirror
+- @img 增加 {id, bind} 参数
+- 增加 @scale
diff --git a/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v249 b/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v249
new file mode 100644
index 0000000..189fa91
--- /dev/null
+++ b/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v249
@@ -0,0 +1,9 @@
+{
+ "ver": "1.3.2",
+ "uuid": "$PREFB_UUID",
+ "importer": "prefab",
+ "optimizationPolicy": "AUTO",
+ "asyncLoadAssets": false,
+ "readonly": false,
+ "subMetas": {}
+}
\ No newline at end of file
diff --git a/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v342 b/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v342
new file mode 100644
index 0000000..1322373
--- /dev/null
+++ b/psd2ui-tools/assets/cc/meta/CCPrefab.meta.v342
@@ -0,0 +1,13 @@
+{
+ "ver": "1.1.35",
+ "importer": "prefab",
+ "imported": true,
+ "uuid": "$PREFB_UUID",
+ "files": [
+ ".json"
+ ],
+ "subMetas": {},
+ "userData": {
+ "syncNodeName": "$NODE_NAME"
+ }
+}
diff --git a/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v249 b/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v249
new file mode 100644
index 0000000..e7d0e56
--- /dev/null
+++ b/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v249
@@ -0,0 +1,38 @@
+{
+ "ver": "2.3.7",
+ "uuid": "$SPRITE_FRAME_UUID",
+ "importer": "texture",
+ "type": "sprite",
+ "wrapMode": "clamp",
+ "filterMode": "bilinear",
+ "premultiplyAlpha": false,
+ "genMipmaps": false,
+ "packable": true,
+ "width": $WIDTH,
+ "height": $HEIGHT,
+ "platformSettings": {},
+ "subMetas": {
+ "$FILE_NAME": {
+ "ver": "1.0.6",
+ "uuid": "$TEXTURE_UUID",
+ "importer": "sprite-frame",
+ "rawTextureUuid": "$SPRITE_FRAME_UUID",
+ "trimType": "auto",
+ "trimThreshold": 1,
+ "rotated": false,
+ "offsetX": 0,
+ "offsetY": 0,
+ "trimX": 0,
+ "trimY": 0,
+ "width": $WIDTH,
+ "height": $HEIGHT,
+ "rawWidth": $WIDTH,
+ "rawHeight": $HEIGHT,
+ "borderTop": $BORDER_TOP,
+ "borderBottom": $BORDER_BOTTOM,
+ "borderLeft": $BORDER_LEFT,
+ "borderRight": $BORDER_RIGHT,
+ "subMetas": {}
+ }
+ }
+ }
\ No newline at end of file
diff --git a/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v342 b/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v342
new file mode 100644
index 0000000..f045b4a
--- /dev/null
+++ b/psd2ui-tools/assets/cc/meta/CCSpriteFrame.meta.v342
@@ -0,0 +1,74 @@
+{
+ "ver": "1.0.22",
+ "importer": "image",
+ "imported": true,
+ "uuid": "$TEXTURE_UUID",
+ "files": [
+ ".png",
+ ".json"
+ ],
+ "subMetas": {
+ "6c48a": {
+ "importer": "texture",
+ "uuid": "$TEXTURE_UUID@6c48a",
+ "displayName": "$FILE_NAME",
+ "id": "6c48a",
+ "name": "texture",
+ "userData": {
+ "wrapModeS": "clamp-to-edge",
+ "wrapModeT": "clamp-to-edge",
+ "imageUuidOrDatabaseUri": "$TEXTURE_UUID",
+ "minfilter": "linear",
+ "magfilter": "linear",
+ "mipfilter": "none",
+ "anisotropy": 0,
+ "isUuid": true
+ },
+ "ver": "1.0.21",
+ "imported": true,
+ "files": [
+ ".json"
+ ],
+ "subMetas": {}
+ },
+ "f9941": {
+ "importer": "sprite-frame",
+ "uuid": "$TEXTURE_UUID@f9941",
+ "displayName": "$FILE_NAME",
+ "id": "f9941",
+ "name": "spriteFrame",
+ "userData": {
+ "trimType": "auto",
+ "trimThreshold": 1,
+ "rotated": false,
+ "offsetX": 0,
+ "offsetY": 0,
+ "trimX": 0,
+ "trimY": 0,
+ "width": $WIDTH,
+ "height": $HEIGHT,
+ "rawWidth": $WIDTH,
+ "rawHeight": $HEIGHT,
+ "borderTop": $BORDER_TOP,
+ "borderBottom": $BORDER_BOTTOM,
+ "borderLeft": $BORDER_LEFT,
+ "borderRight": $BORDER_RIGHT,
+ "packable": true,
+ "isUuid": true,
+ "imageUuidOrDatabaseUri": "$TEXTURE_UUID@6c48a",
+ "atlasUuid": ""
+ },
+ "ver": "1.0.9",
+ "imported": true,
+ "files": [
+ ".json"
+ ],
+ "subMetas": {}
+ }
+ },
+ "userData": {
+ "type": "sprite-frame",
+ "hasAlpha": true,
+ "redirect": "$TEXTURE_UUID@f9941"
+ }
+}
diff --git a/psd2ui-tools/dist/index.js b/psd2ui-tools/dist/index.js
new file mode 100644
index 0000000..a049817
--- /dev/null
+++ b/psd2ui-tools/dist/index.js
@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("minimist"),require("ag-psd/initialize-canvas"),require("ag-psd"),require("fs-extra"),require("path"),require("crypto"),require("pinyin-pro"),require("canvas")):"function"==typeof define&&define.amd?define(["minimist","ag-psd/initialize-canvas","ag-psd","fs-extra","path","crypto","pinyin-pro","canvas"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).minimist,null,t.psd,t.fs,t.path,t.crypto,t.pinyinPro,t.canvas)}(this,(function(t,e,i,o,s,r,n,a){"use strict";function l(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(i){if("default"!==i){var o=Object.getOwnPropertyDescriptor(t,i);Object.defineProperty(e,i,o.get?o:{enumerable:!0,get:function(){return t[i]}})}})),e.default=t,Object.freeze(e)}var c,p=l(i);function h(t,e,i,o){var s,r=arguments.length,n=r<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(t,e,i,o);else for(var a=t.length-1;a>=0;a--)(s=t[a])&&(n=(r<3?s(n):r>3?s(e,i,n):s(e,i))||n);return r>3&&n&&Object.defineProperty(e,i,n),n}function d(t,e,i,o){return new(i||(i=Promise))((function(s,r){function n(t){try{l(o.next(t))}catch(t){r(t)}}function a(t){try{l(o.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(n,a)}l((o=o.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError,function(t){t[t.all=0]="all",t[t.v249=1]="v249",t[t.v342=2]="v342"}(c||(c={}));let u=(t,e)=>{t.__unserialization||(t.__unserialization=[]),t.__unserialization.push(e)};function _(t){return e=>{Object.defineProperty(e.prototype,"$__type__",{value:t,enumerable:!0})}}let v={},g={},f={},y=0;function m(t){return void 0!==t.constructor.__ver_tag_id__&&f[t.constructor.__ver_tag_id__]==t||(t.constructor.__ver_tag_id__=`${y}`,f[t.constructor.__ver_tag_id__]=t,y++),t.constructor.__ver_tag_id__}function b(t,e){for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){if(i in t)continue;t[i]=e[i]}}function x(t,...e){for(let i=0;i{let o=e.constructor.name;o=m(e),!g[o]&&(g[o]={});let s=g[o];if(s[i]||(s[i]={}),c.all===t)for(const t in c)s[i][c[t]]=!0;else s[i][c[t]]=!0;var r=S(e.constructor);if(r){let t=m(r.prototype);!v[o]&&(v[o]=t);for(var n=S(r);n;){let e=m(n.prototype);!v[t]&&(v[t]=e),n=S(n)}for(;t;)t in g&&x(s,g[t]),t=v[t]}e._version||(e._version={}),e._version[o]=g[o]=s}}function S(t){var e=t.prototype,i=e&&Object.getPrototypeOf(e);return i&&i.constructor}const M="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",F=new Array(123);for(let t=0;t<123;++t)F[t]=64;for(let t=0;t<64;++t)F[M.charCodeAt(t)]=t;const P=F,I="0123456789abcdef".split(""),$=["","","",""],j=$.concat($,"-",$,"-",$,"-",$,"-",$,$,$),C=j.map(((t,e)=>"-"===t?NaN:e)).filter(isFinite);let N={};for(let t=0;t>2],j[C[i++]]=I[(3&o)<<2|s>>4],j[C[i++]]=I[15&s]}return t.replace(e,j.join(""))}compressUuid(t){const e=t.split("@")[0];if(36!==e.length)return t;let i=[];i[0]=e[0],i[1]=e[1];let o=e.replace("-","").replace("-","").replace("-","").replace("-","");for(let t=2,e=2;t<32;t+=3){const s=N[String.fromCharCode(o.charCodeAt(t))],r=N[String.fromCharCode(o.charCodeAt(t+1))],n=N[String.fromCharCode(o.charCodeAt(t+2))];i[e++]=M[(s<<2)+(r>>2)],i[e++]=M[((3&r)<<4)+n]}return t.replace(e,i.join(""))}isNumber(t){return!isNaN(parseFloat(t))&&isFinite(t)}};class O{constructor(){this.uuid="",this.idx=0,this.uuid=z.uuid()}toJSON(){var t;let e={};for(const i in this)if(Object.prototype.hasOwnProperty.call(this,i)){if(this.__unserialization&&-1!==this.__unserialization.indexOf(i))continue;let o=this.constructor.__ver_tag_id__;if(this._version&&(null===(t=this._version[o])||void 0===t?void 0:t[i])&&!this._version[o][i][c[V.editorVersion]])continue;const s=this[i];e[i]=s}return e}}h([u],O.prototype,"uuid",void 0),h([u],O.prototype,"idx",void 0);class A extends O{constructor(){super(),this._name="",this._objFlags=0,this.__type__=this.$__type__}}h([w(c.all)],A.prototype,"__type__",void 0),h([w(c.all)],A.prototype,"_name",void 0),h([w(c.all)],A.prototype,"_objFlags",void 0);class T extends A{constructor(){super(...arguments),this._enabled=!0,this.node=null,this._id="",this.__prefab=null}}h([w(c.all)],T.prototype,"_enabled",void 0),h([w(c.all)],T.prototype,"node",void 0),h([w(c.all)],T.prototype,"_id",void 0),h([w(c.v342)],T.prototype,"__prefab",void 0);let E=class extends T{constructor(){super(...arguments),this.duration=.1,this.zoomScale=1.2,this.clickEvents=[],this._N$interactable=!0,this._N$enableAutoGrayEffect=!1,this._N$transition=3,this.transition=3,this._N$target=null,this._interactable=!0,this._transition=3,this._duration=.1,this._zoomScale=1.2,this._target=null}updateWithLayer(t){}};h([w(c.v249)],E.prototype,"duration",void 0),h([w(c.v249)],E.prototype,"zoomScale",void 0),h([w(c.all)],E.prototype,"clickEvents",void 0),h([w(c.v249)],E.prototype,"_N$interactable",void 0),h([w(c.v249)],E.prototype,"_N$enableAutoGrayEffect",void 0),h([w(c.v249)],E.prototype,"_N$transition",void 0),h([w(c.v249)],E.prototype,"transition",void 0),h([w(c.v249)],E.prototype,"_N$target",void 0),h([w(c.v342)],E.prototype,"_interactable",void 0),h([w(c.v342)],E.prototype,"_transition",void 0),h([w(c.v342)],E.prototype,"_duration",void 0),h([w(c.v342)],E.prototype,"_zoomScale",void 0),h([w(c.v342)],E.prototype,"_target",void 0),E=h([_("cc.Button")],E);class k{constructor(t,e,i,o){this.r=Math.ceil(t||0),this.g=Math.ceil(e||0),this.b=Math.ceil(i||0),this.a=Math.ceil(o||0)}set(t){this.r=Math.ceil(t.r||0),this.g=Math.ceil(t.g||0),this.b=Math.ceil(t.b||0),this.a=Math.ceil(t.a||0)}toHEX(t="#rrggbb"){const e="0",i=[(this.r<16?e:"")+this.r.toString(16),(this.g<16?e:"")+this.g.toString(16),(this.b<16?e:"")+this.b.toString(16)];return"#rgb"===t?(i[0]=i[0][0],i[1]=i[1][0],i[2]=i[2][0]):"#rrggbbaa"===t&&i.push((this.a<16?e:"")+this.a.toString(16)),i.join("")}}class D extends k{constructor(){super(...arguments),this.__type__="cc.Color"}}class L{constructor(t=0,e=0){this.x=t||0,this.y=e||0}}let B=class extends L{constructor(){super(...arguments),this.__type__="cc.Vec2"}};B=h([_("cc.Vec2")],B);let R=class extends T{constructor(){super(...arguments),this._materials=[],this._srcBlendFactor=770,this._dstBlendFactor=771,this._spriteFrame=null,this._type=0,this._sizeMode=1,this._fillType=0,this._fillCenter=new B,this._fillStart=0,this._fillRange=0,this._isTrimmedMode=!0,this._atlas=null,this._visFlags=0,this._customMaterial=null,this._color=new D(255,255,255,255),this._useGrayscale=!1}use9(){this._type=1,this._sizeMode=0}updateWithLayer(t){t.s9&&this.use9(),1==Math.abs(t.scale.x)&&1==Math.abs(t.scale.y)||(this._sizeMode=0),V.editorVersion>=c.v342&&(this._srcBlendFactor=2,this._dstBlendFactor=4)}setSpriteFrame(t){V.editorVersion>=c.v342?this._spriteFrame={__uuid__:`${t}@f9941`,__expectedType__:"cc.SpriteFrame"}:this._spriteFrame={__uuid__:t}}};h([w(c.v249)],R.prototype,"_materials",void 0),h([w(c.all)],R.prototype,"_srcBlendFactor",void 0),h([w(c.all)],R.prototype,"_dstBlendFactor",void 0),h([w(c.all)],R.prototype,"_spriteFrame",void 0),h([w(c.all)],R.prototype,"_type",void 0),h([w(c.all)],R.prototype,"_sizeMode",void 0),h([w(c.all)],R.prototype,"_fillType",void 0),h([w(c.all)],R.prototype,"_fillCenter",void 0),h([w(c.all)],R.prototype,"_fillStart",void 0),h([w(c.all)],R.prototype,"_fillRange",void 0),h([w(c.all)],R.prototype,"_isTrimmedMode",void 0),h([w(c.all)],R.prototype,"_atlas",void 0),h([w(c.v342)],R.prototype,"_visFlags",void 0),h([w(c.v342)],R.prototype,"_customMaterial",void 0),h([w(c.v342)],R.prototype,"_color",void 0),h([w(c.v342)],R.prototype,"_useGrayscale",void 0),R=h([_("cc.Sprite")],R);let U=class extends T{constructor(){super(...arguments),this._N$totalLength=0,this._N$barSprite=null,this._N$mode=0,this._N$progress=1,this._N$reverse=!1,this._barSprite=null,this._mode=0,this._totalLength=0,this._progress=1,this._reverse=!1}setBar(t){this._barSprite=this._N$barSprite={__id__:t.idx}}updateWithLayer(t){if(t.children)t:for(let e=0;e 只能作用在 组图层 上")}};h([w(c.v249)],U.prototype,"_N$totalLength",void 0),h([w(c.v249)],U.prototype,"_N$barSprite",void 0),h([w(c.v249)],U.prototype,"_N$mode",void 0),h([w(c.v249)],U.prototype,"_N$progress",void 0),h([w(c.v249)],U.prototype,"_N$reverse",void 0),h([w(c.v342)],U.prototype,"_barSprite",void 0),h([w(c.v342)],U.prototype,"_mode",void 0),h([w(c.v342)],U.prototype,"_totalLength",void 0),h([w(c.v342)],U.prototype,"_progress",void 0),h([w(c.v342)],U.prototype,"_reverse",void 0),U=h([_("cc.ProgressBar")],U);let W=class extends E{constructor(){super(...arguments),this._N$isChecked=!0,this.toggleGroup=null,this.checkMark=null,this.checkEvents=[],this._isChecked=!0,this._checkMark=null}setCheckMark(t){this._checkMark=this.checkMark={__id__:t.idx}}updateWithLayer(t){if(t.children)t:for(let e=0;e 只能作用在 组图层 上")}};h([w(c.v249)],W.prototype,"_N$isChecked",void 0),h([w(c.v249)],W.prototype,"toggleGroup",void 0),h([w(c.v249)],W.prototype,"checkMark",void 0),h([w(c.all)],W.prototype,"checkEvents",void 0),h([w(c.v342)],W.prototype,"_isChecked",void 0),h([w(c.v342)],W.prototype,"_checkMark",void 0),W=h([_("cc.Toggle")],W);const V=new class{constructor(){this.help="\n--help | 帮助信息 \n--init | 初始化缓存文件 必须设置 --project-assets --cache 两项\n--force-img | 强制导出图片 即使在有缓存的情况下也要导出\n--input | 输入目录或者 psd 文件 非 init 时 必选 [dir or psd] \n--output | 输出目录 可选 缺省时为 --input [dir] \n--engine-version | 引擎版本 可选 [v249 | v342] \n--project-assets | 指定项目文件夹 可选 [dir] \n--cache-remake | 重新创建缓存文件 可选\n--cache | 缓存文件全路径 可选 [file-full-path] \n--config | 预制体配置 可选 [file-full-path] \n--pinyin | 中文转拼音 可选\n--img-only | 只导出图片 可选 \n--json | json 对象参数 插件工具使用 将所有参数用对象的形式编码成 base64 字符串 \n",this.editorVersion=c.v249,this.DEFAULT_SPRITE_FRAME_MATERIAL={[c.v249]:"eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432",[c.v342]:""},this.DEFAULT_LABEL_MATERIAL={[c.v249]:"eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432",[c.v342]:""},this.CompMappings={Btn:E,ProgressBar:U,Toggle:W},this.textOffsetY={default:0,36:0},this.textLineHeightOffset=0}get SpriteFrame_Material(){return this.DEFAULT_SPRITE_FRAME_MATERIAL[V.editorVersion]}get Label_Material(){return this.DEFAULT_LABEL_MATERIAL[V.editorVersion]}};let X=new class{DFS(t,e,i=0){if(!o.existsSync(t))return void console.log(`FileUtils-> ${t} is not exists`);let r=o.readdirSync(t),n=i;i++,r.forEach((r=>{let a=s.join(t,r),l=o.lstatSync(a).isDirectory();null==e||e({isDirectory:l,fullPath:a,fileName:r,depth:n}),l&&this.DFS(a,e,i)}))}filterFile(t,e){if(!o.existsSync(t))return void console.log(`FileUtils-> ${t} is not exists`);var i=[];return o.readdirSync(t).forEach((r=>{let n=s.join(t,r),a=o.lstatSync(n).isDirectory();if(!a){if(!e(r))return}a?i=i.concat(this.filterFile(n,e)):i.push(n)})),i}getFolderFiles(t,e){if(!o.existsSync(t))return void console.log(`FileUtils-> ${t} is not exists`);let i=[];return o.readdirSync(t).forEach((r=>{let n=s.join(t,r);o.lstatSync(n).isDirectory()?"folder"===e&&i.push({fullPath:n,basename:r}):"file"===e&&i.push({fullPath:n,basename:r})})),i}writeFile(t,e){return d(this,void 0,void 0,(function*(){if("string"!=typeof e)try{e=JSON.stringify(e,null,2)}catch(t){return void console.log("FileUtils->writeFile ",t)}console.log(`写入文件 ${t}`);let i=s.dirname(t);yield o.mkdirp(i),yield o.writeFile(t,e),console.log(`写入完成 ${t} `)}))}getMD5(t){return"string"==typeof t&&(t=o.readFileSync(t)),r.createHash("md5").update(t).digest("hex")}};class G{constructor(){this._imageMap=new Map,this._cachePath=null}initWithPath(t){if(!o.existsSync(t))return void console.log(`ImageCacheMgr-> 文件不存在: ${t}`);this._cachePath=t;let e=o.readFileSync(t,"utf-8");this.initWithFile(e)}initWithFile(t){let e=JSON.parse(t);this.initWithJson(e)}initWithJson(t){for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&this._imageMap.set(e,t[e])}set(t,e){this._imageMap.set(t,e)}has(t){return this._imageMap.has(t)}get(t){return this._imageMap.get(t)}saveImageMap(t){return d(this,void 0,void 0,(function*(){if(t||(t=this._cachePath),!t)return void console.log(`ImageCacheMgr-> 缓存路径 [${t}] 不存在,无法保存 `);let e=Object.create(null);this._imageMap.forEach(((t,i)=>{e[i]=t}));let i=JSON.stringify(e,null,2);yield X.writeFile(t,i)}))}loadImages(t){if(this._imageMap.size>0)return void console.error("ImageCacheMgr-> 暂时只能在 启动时加载");let e=X.filterFile(t,(t=>".png"==s.extname(t)));if(e)for(let t=0;t缓存 ",i);let s=this._loadImageMetaWarp(`${i}.meta`);s&&this.set(o,s)}}_loadImageMetaWarp(t){let e=o.readFileSync(t,{encoding:"utf-8"}),i=null;switch(V.editorVersion){case c.v249:i=this._loadImageMeta249(e,t);break;case c.v342:i=this._loadImageMeta34x(e,t);break;default:console.log(`ImageCacheMgr-> 暂未实现 ${c[V.editorVersion]} 版本`)}return i}_loadImageMeta249(t,e){var i;let o=s.basename(e,".png.meta"),r=s.join(s.dirname(e),`${o}.png`),n=JSON.parse(t);return(null===(i=null==n?void 0:n.subMetas)||void 0===i?void 0:i[o])?{path:r,textureUuid:n.subMetas[o].uuid,uuid:n.uuid,isOutput:!0}:null}_loadImageMeta34x(t,e){var i;let o=s.basename(e,".png.meta"),r=s.join(s.dirname(e),`${o}.png`),n=JSON.parse(t);if(!(null===(i=null==n?void 0:n.subMetas)||void 0===i?void 0:i["6c48a"]))return null;let a=n.subMetas["6c48a"].uuid.replace("@6c48a","");return{path:r,textureUuid:a,uuid:a,isOutput:!0}}static getInstance(){return this._instance||(this._instance=new G),this._instance}}G._instance=null;const Y=G.getInstance();class H{constructor(){this._imageIdKeyMap=new Map,this._imageArray=new Map}add(t){var e;if(t.isIgnore()||t.isBind()||this._imageArray.has(t.md5)||this._imageArray.set(t.md5,t),void 0!==(null===(e=t.attr.comps.img)||void 0===e?void 0:e.id)){let e=t.attr.comps.img.id;this._imageIdKeyMap.has(e)&&console.warn(`ImageMgr-> ${t.source.name} 已有相同 @img{id:${e}},请检查 psd 图层`),this._imageIdKeyMap.set(e,t)}}getAllImage(){return this._imageArray}getSerialNumberImage(t){var e,i,o;let s=null!==(i=null===(e=t.attr.comps.flip)||void 0===e?void 0:e.bind)&&void 0!==i?i:null===(o=t.attr.comps.img)||void 0===o?void 0:o.bind;if(void 0!==s){if(this._imageIdKeyMap.has(s))return this._imageIdKeyMap.get(s);console.warn(`ImageMgr-> ${t.source.name} 未找到绑定的图像 {${s}},请检查 psd 图层`)}return t}clear(){this._imageIdKeyMap.clear(),this._imageArray.clear()}static getInstance(){return this._instance||(this._instance=new H),this._instance}}H._instance=null;const J=H.getInstance();var q;!function(t){t[t.Doc=0]="Doc",t[t.Group=1]="Group",t[t.Text=2]="Text",t[t.Image=3]="Image"}(q||(q={}));class K{constructor(t=0,e=0,i=0,o=0){"object"!=typeof t?(this.left=t||0,this.right=e||0,this.top=i||0,this.bottom=o||0):this.set(t)}set(t){this.left=t.left,this.right=t.right,this.top=t.top,this.bottom=t.bottom}}class Q{constructor(t=0,e=0){this.width=t||0,this.height=e||0}}class Z{constructor(t=0,e=0,i=0){this.x=t||0,this.y=e||0,this.z=i||0}}class tt{constructor(t,e,i){var o,s,r,n;this.uuid=z.uuid(),this.source=t,this.parent=e,this.rootDoc=i,this.name=t.name,this.position=new L,this.size=new Q,this.rect=new K(t),this.anchorPoint=new L(.5,.5),this.hidden=!1,this.opacity=255,this.color=new k(255,255,255,255),console.log("PsdLayer->解析到图层 ",this.name),this.attr=this.parseNameRule(this.name),this.name=this.chineseToPinyin((null===(o=this.attr)||void 0===o?void 0:o.name)||this.name);let a=null===(s=this.attr)||void 0===s?void 0:s.comps.scale;this.scale=new Z(null!==(r=null==a?void 0:a.x)&&void 0!==r?r:1,null!==(n=null==a?void 0:a.y)&&void 0!==n?n:1,1)}parseNameRule(t){var e,i;if(!t)return;let o=(t=t.trim()).split("@");if(0===o.length)return void console.error("PsdLayer-> 名字解析错误");let s={name:null!==(i=null===(e=o[0])||void 0===e?void 0:e.replace(/\.|>|\/|\ /g,"_"))&&void 0!==i?i:"unknow",comps:{}};for(let e=1;e${t} 属性 解析错误`);continue}let o=i.substring(n+1,e);a=i.substr(0,n),o=o.trim(),o.split(",").forEach((e=>{let i=(e=e.trim()).split(":");i.length?(i.map((t=>t.trim())),r[i[0]]=z.isNumber(i[1])?parseFloat(i[1]):i[1]):console.log(`PsdLayer->${t} 属性 解析错误`)}))}a=a.trim(),a=a.replace(":",""),s.comps[a]=r}return s.comps.ignore=s.comps.ignore||s.comps.ig,s.comps.ignorenode=s.comps.ignorenode||s.comps.ignode,s.comps.ignoreimg=s.comps.ignoreimg||s.comps.igimg,s.comps.Btn=s.comps.Btn||s.comps.btn,s.comps.ProgressBar=s.comps.ProgressBar||s.comps.progressBar,s.comps.Toggle=s.comps.Toggle||s.comps.toggle,s.comps.img&&s.comps.img.name&&(s.comps.img.name=this.chineseToPinyin(s.comps.img.name)),(s.comps.flip||s.comps.flipX||s.comps.flipY)&&(s.comps.flip=Object.assign({},s.comps.flip,s.comps.flipX,s.comps.flipY),s.comps.flipX&&(s.comps.flip.x=1),s.comps.flipY&&(s.comps.flip.y=1),void 0!==s.comps.flip.bind&&(s.comps.flip.y||(s.comps.flip.x=1),s.comps.flip.x&&(s.comps.flipX=Object.assign({},s.comps.flipX,s.comps.flip)),s.comps.flip.y&&(s.comps.flipY=Object.assign({},s.comps.flipY,s.comps.flip)))),s.comps.full&&s.comps.size&&console.warn(`PsdLayer->${s.name} 同时存在 @full 和 @size`),s}parseSource(){var t,e;let i=this.source;if(!this.parent)return!1;this.hidden=i.hidden,this.opacity=Math.round(255*i.opacity);let o=this.attr.comps.ar;return o&&(this.anchorPoint.x=null!==(t=o.x)&&void 0!==t?t:this.anchorPoint.x,this.anchorPoint.y=null!==(e=o.y)&&void 0!==e?e:this.anchorPoint.y),this.computeBasePosition(),!0}parseEffects(){}chineseToPinyin(t){if(!t||!tt.isPinyin)return t;let e=n.pinyin(t,{toneType:"none",type:"array"});return e=e.map((t=>t.slice(0,1).toUpperCase()+t.slice(1).toLowerCase())),e.join("")}computeBasePosition(){if(!this.rootDoc)return;let t=this.rect,e=t.right-t.left,i=t.bottom-t.top;this.size.width=e,this.size.height=i;let o=t.left,s=this.rootDoc.size.height-t.bottom;this.position.x=o,this.position.y=s}updatePositionWithAR(){if(!this.parent)return;let t=this.parent;for(;t;)this.position.x-=t.position.x,this.position.y-=t.position.y,t=t.parent;this.position.x=this.position.x-this.rootDoc.size.width*this.rootDoc.anchorPoint.x+this.size.width*this.anchorPoint.x,this.position.y=this.position.y-this.rootDoc.size.height*this.rootDoc.anchorPoint.y+this.size.height*this.anchorPoint.y}}tt.isPinyin=!1;class et extends tt{constructor(t,e,i){super(t,e,i),this.children=[],i&&(this.rect=new K(0,i.size.width,0,i.size.height))}parseSource(){var t;return super.parseSource(),(null===(t=this.attr)||void 0===t?void 0:t.comps.full)||(this.resize(),this.computeBasePosition()),!0}resize(){let t=Number.MAX_SAFE_INTEGER,e=Number.MIN_SAFE_INTEGER,i=Number.MAX_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER;for(let s=0;si+4)return console.log("Texture9Utils-> 设置的九宫格 left, right 数据不合理,请重新设置"),t;if(e.b+e.t>o+4)return console.log("Texture9Utils-> 设置的九宫格 bottom, top 数据不合理,请重新设置"),t;let c=a.createCanvas(Math.min(i,e.l+e.r+4)||i,Math.min(o,e.b+e.t+4)||o),p=c.getContext("2d");return p.drawImage(t,0,0,s+4,n+4,0,0,s+4,n+4),p.drawImage(t,0,o-l,s+4,l,0,n+4,s+4,l),p.drawImage(t,i-s,0,r,n+4,s+4,0,r,n+4),p.drawImage(t,i-s,o-l,r,l,s+4,n+4,r,l),c}}class st extends tt{constructor(t,e,i){var o;if(super(t,e,i),this.textureUuid=z.uuid(),this.imgName=(null===(o=this.attr.comps.img)||void 0===o?void 0:o.name)||this.name,this.attr.comps[".9"]){let t=this.attr.comps[".9"];this.s9=ot.safeBorder(this.source.canvas,t);let e=ot.split(this.source.canvas,t);this.source.canvas=e}let s=this.source.canvas;this.imgBuffer=s.toBuffer("image/png"),this.md5=X.getMD5(this.imgBuffer),this.textureSize=new Q(s.width,s.height),this.scale=new Z((this.isFilpX()?-1:1)*this.scale.x,(this.isFilpY()?-1:1)*this.scale.y,1)}onCtor(){}isIgnore(){return!(!this.attr.comps.ignore&&!this.attr.comps.ignoreimg)}isBind(){var t,e;return void 0!==(null===(t=this.attr.comps.flip)||void 0===t?void 0:t.bind)||void 0!==(null===(e=this.attr.comps.img)||void 0===e?void 0:e.bind)}isFilpX(){var t;return void 0!==(null===(t=this.attr.comps.flipX)||void 0===t?void 0:t.bind)}isFilpY(){var t;return void 0!==(null===(t=this.attr.comps.flipY)||void 0===t?void 0:t.bind)}updatePositionWithAR(){if(!this.parent)return;let t=this.parent;for(;t;)this.position.x-=t.position.x,this.position.y-=t.position.y,t=t.parent;let e=this.isFilpX()?1-this.anchorPoint.x:this.anchorPoint.x,i=this.isFilpY()?1-this.anchorPoint.y:this.anchorPoint.y;this.position.x=this.position.x-this.rootDoc.size.width*this.rootDoc.anchorPoint.x+this.size.width*e,this.position.y=this.position.y-this.rootDoc.size.height*this.rootDoc.anchorPoint.y+this.size.height*i}}class rt extends tt{parseSource(){super.parseSource();let t=this.source.text,e=t.style;if(e){let t=e.fillColor;t&&(this.color=new k(t.r,t.g,t.b,255*t.a))}return this.text=t.text,this.fontSize=e.fontSize,this.offsetY=V.textOffsetY[this.fontSize]||V.textOffsetY.default||0,this.parseSolidFill(),this.parseStroke(),!0}onCtor(){}parseStroke(){var t,e;if(null===(t=this.source.effects)||void 0===t?void 0:t.stroke){let t=null===(e=this.source.effects)||void 0===e?void 0:e.stroke[0];if((null==t?void 0:t.enabled)&&"outside"===(null==t?void 0:t.position)){let e=t.color;this.outline={width:t.size.value,color:new k(e.r,e.g,e.b,255*t.opacity)}}}}parseSolidFill(){var t,e;if(null===(t=this.source.effects)||void 0===t?void 0:t.solidFill){let t=null===(e=this.source.effects)||void 0===e?void 0:e.solidFill;for(let e=0;e 空图层 ${null==t?void 0:t.name}`),null;let s=o=new st(t,e,i);J.add(s),s.isIgnore()||s.isBind()||Y.has(s.md5)||Y.set(s.md5,{uuid:s.uuid,textureUuid:s.textureUuid})}break;case q.Text:o=new rt(t,e,i)}return o.layerType=s,o.parseSource(),o.onCtor(),o}};class at extends O{constructor(){super(),this.__type__="cc.CompPrefabInfo",this.fileId="",this.fileId=z.compressUuid(this.uuid)}}let lt=class extends Q{constructor(){super(...arguments),this.__type__="cc.Size"}};lt=h([_("cc.Size")],lt);let ct=class{constructor(){this.__type__="TypedArray",this.ctor="Float64Array",this.array=[]}setPosition(t,e,i){this.array[0]=t,this.array[1]=e,this.array[2]=i}setRotation(t,e,i,o){this.array[3]=t,this.array[4]=e,this.array[5]=i,this.array[6]=o}setScale(t,e,i){this.array[7]=t,this.array[8]=e,this.array[9]=i}};ct=h([_("TypedArray")],ct);class pt extends Z{constructor(){super(...arguments),this.__type__="cc.Vec3"}}let ht=class extends A{constructor(t){super(),this._parent=null,this._children=[],this._active=!0,this._components=[],this._prefab=null,this._id="",this._opacity=255,this._color=new D(255,255,255,255),this._contentSize=new lt,this._anchorPoint=new B(0,0),this._trs=new ct,this._eulerAngles=new pt,this._skewX=0,this._skewY=0,this._is3DNode=!1,this._groupIndex=0,this.groupIndex=0,this._renderEnable=!1,this._bfsRenderFlag=!1,this._lpos=new pt,this._lrot=new pt,this._lscale=new pt,this._euler=new pt,this._layer=33554432,this.psdDoc=null,this.components=[],this.children=[],t&&(this.psdDoc=t,t.pushObject(this))}addComponent(t){t.node={__id__:this.idx};let e=this.psdDoc.pushObject(t);this._components.push({__id__:e}),this.components.push(t),V.editorVersion>=c.v342&&this.addCompPrefabInfo(t)}addCompPrefabInfo(t){let e=new at,i=this.psdDoc.pushObject(e);t.__prefab={__id__:i}}addChild(t){this._children.push({__id__:t.idx}),t._parent={__id__:this.idx},this.children.push(t)}};h([w(c.all)],ht.prototype,"_parent",void 0),h([w(c.all)],ht.prototype,"_children",void 0),h([w(c.all)],ht.prototype,"_active",void 0),h([w(c.all)],ht.prototype,"_components",void 0),h([w(c.all)],ht.prototype,"_prefab",void 0),h([w(c.all)],ht.prototype,"_id",void 0),h([w(c.v249)],ht.prototype,"_opacity",void 0),h([w(c.v249)],ht.prototype,"_color",void 0),h([w(c.v249)],ht.prototype,"_contentSize",void 0),h([w(c.v249)],ht.prototype,"_anchorPoint",void 0),h([w(c.v249)],ht.prototype,"_trs",void 0),h([w(c.v249)],ht.prototype,"_eulerAngles",void 0),h([w(c.v249)],ht.prototype,"_skewX",void 0),h([w(c.v249)],ht.prototype,"_skewY",void 0),h([w(c.v249)],ht.prototype,"_is3DNode",void 0),h([w(c.v249)],ht.prototype,"_groupIndex",void 0),h([w(c.v249)],ht.prototype,"groupIndex",void 0),h([w(c.v249)],ht.prototype,"_renderEnable",void 0),h([w(c.v249)],ht.prototype,"_bfsRenderFlag",void 0),h([w(c.v342)],ht.prototype,"_lpos",void 0),h([w(c.v342)],ht.prototype,"_lrot",void 0),h([w(c.v342)],ht.prototype,"_lscale",void 0),h([w(c.v342)],ht.prototype,"_euler",void 0),h([w(c.v342)],ht.prototype,"_layer",void 0),h([u],ht.prototype,"psdDoc",void 0),h([u],ht.prototype,"components",void 0),h([u],ht.prototype,"children",void 0),ht=h([_("cc.Node")],ht);class dt extends O{constructor(){super(),this.__type__="cc.PrefabInfo",this.root={__id__:1},this.asset={__id__:0},this.fileId="",this.sync=!1,this.fileId=z.compressUuid(this.uuid)}}h([w(c.all)],dt.prototype,"__type__",void 0),h([w(c.all)],dt.prototype,"root",void 0),h([w(c.all)],dt.prototype,"asset",void 0),h([w(c.all)],dt.prototype,"fileId",void 0),h([w(c.all)],dt.prototype,"sync",void 0);let ut=class extends A{constructor(){super(...arguments),this._native="",this.data=null,this.optimizationPolicy=0,this.asyncLoadAssets=!1,this.readonly=!1,this.persistent=!1}};h([w(c.all)],ut.prototype,"_native",void 0),h([w(c.all)],ut.prototype,"data",void 0),h([w(c.all)],ut.prototype,"optimizationPolicy",void 0),h([w(c.all)],ut.prototype,"asyncLoadAssets",void 0),h([w(c.v249)],ut.prototype,"readonly",void 0),h([w(c.v342)],ut.prototype,"persistent",void 0),ut=h([_("cc.Prefab")],ut);let _t=class extends T{constructor(){super(...arguments),this._srcBlendFactor=770,this._dstBlendFactor=771,this._string="",this._fontSize=0,this._lineHeight=0,this._enableWrapText=!0,this._isSystemFontUsed=!0,this._spacingX=0,this._underlineHeight=0,this._materials=[],this._N$string="",this._N$file=null,this._batchAsBitmap=!1,this._styleFlags=0,this._N$horizontalAlign=1,this._N$verticalAlign=1,this._N$fontFamily="Arial",this._N$overflow=0,this._N$cacheMode=0,this._visFlags=0,this._customMaterial=null,this._color=new D(255,255,255,255),this._overflow=0,this._cacheMode=0,this._horizontalAlign=1,this._verticalAlign=1,this._actualFontSize=0,this._isItalic=!1,this._isBold=!1,this._isUnderline=!1}updateWithLayer(t){this._fontSize=t.fontSize,this._string=this._N$string=t.text,this._lineHeight=this._fontSize+V.textLineHeightOffset,V.editorVersion>=c.v342&&(this._srcBlendFactor=2,this._dstBlendFactor=4)}};h([w(c.all)],_t.prototype,"_srcBlendFactor",void 0),h([w(c.all)],_t.prototype,"_dstBlendFactor",void 0),h([w(c.all)],_t.prototype,"_string",void 0),h([w(c.all)],_t.prototype,"_fontSize",void 0),h([w(c.all)],_t.prototype,"_lineHeight",void 0),h([w(c.all)],_t.prototype,"_enableWrapText",void 0),h([w(c.all)],_t.prototype,"_isSystemFontUsed",void 0),h([w(c.all)],_t.prototype,"_spacingX",void 0),h([w(c.all)],_t.prototype,"_underlineHeight",void 0),h([w(c.v249)],_t.prototype,"_materials",void 0),h([w(c.v249)],_t.prototype,"_N$string",void 0),h([w(c.v249)],_t.prototype,"_N$file",void 0),h([w(c.v249)],_t.prototype,"_batchAsBitmap",void 0),h([w(c.v249)],_t.prototype,"_styleFlags",void 0),h([w(c.v249)],_t.prototype,"_N$horizontalAlign",void 0),h([w(c.v249)],_t.prototype,"_N$verticalAlign",void 0),h([w(c.v249)],_t.prototype,"_N$fontFamily",void 0),h([w(c.v249)],_t.prototype,"_N$overflow",void 0),h([w(c.v249)],_t.prototype,"_N$cacheMode",void 0),h([w(c.v342)],_t.prototype,"_visFlags",void 0),h([w(c.v342)],_t.prototype,"_customMaterial",void 0),h([w(c.v342)],_t.prototype,"_color",void 0),h([w(c.v342)],_t.prototype,"_overflow",void 0),h([w(c.v342)],_t.prototype,"_cacheMode",void 0),h([w(c.v342)],_t.prototype,"_horizontalAlign",void 0),h([w(c.v342)],_t.prototype,"_verticalAlign",void 0),h([w(c.v342)],_t.prototype,"_actualFontSize",void 0),h([w(c.v342)],_t.prototype,"_isItalic",void 0),h([w(c.v342)],_t.prototype,"_isBold",void 0),h([w(c.v342)],_t.prototype,"_isUnderline",void 0),_t=h([_("cc.Label")],_t);let vt=class extends T{constructor(){super(...arguments),this._color=new D(255,255,255,255),this._width=1}updateWithLayer(t){this._width=t.outline.width,this._color.set(t.outline.color)}};h([w(c.all)],vt.prototype,"_color",void 0),h([w(c.all)],vt.prototype,"_width",void 0),vt=h([_("cc.LabelOutline")],vt);class gt{constructor(){this.textObjects=[]}test(){const t=s.join(__dirname,"..","out");this.parsePsd("./test-img-only/境界奖励-优化.psd",t)}exec(t){return d(this,void 0,void 0,(function*(){if(!this.checkArgs(t))return;if(o.lstatSync(t.input).isDirectory())t.output||(t.output=s.join(t.input,"psd2ui")),this.parsePsdDir(t.input,t.output);else{if(!t.output){let e=s.dirname(t.input);t.output=s.join(e,"psd2ui")}this.parsePsd(t.input,t.output)}}))}checkArgs(t){return t.input?!!o.existsSync(t.input)||(console.error(`输入路径不存在: ${t.input}`),!1):(console.error("请设置 --input"),!1)}parsePsdDir(t,e){return d(this,void 0,void 0,(function*(){o.emptyDirSync(e);let i=X.filterFile(t,(t=>".psd"==s.extname(t)));for(let t=0;t{let n=J.getSerialNumberImage(e),a=`${n.imgName}_${i}`;console.log(`保存图片 [${n.imgName}] 重命名为 [${a}] md5: ${n.md5}`);let l=s.join(t,`${a}.png`);o.writeFileSync(l,n.imgBuffer),i++}))}saveTextFile(t,e){this.scanText(t,t);let i=JSON.stringify(this.textObjects,null,2),r=s.join(e,"text.txt");o.writeFileSync(r,i,{encoding:"utf-8"})}scanText(t,e){if(t instanceof et)for(let i=0;i test")}))}loadMetaTemplete(){return d(this,void 0,void 0,(function*(){this.spriteFrameMetaContent=o.readFileSync(s.join(__dirname,`../assets/cc/meta/CCSpriteFrame.meta.${c[V.editorVersion]}`),"utf-8"),this.prefabMetaContent=o.readFileSync(s.join(__dirname,`../assets/cc/meta/CCPrefab.meta.${c[V.editorVersion]}`),"utf-8")}))}loadPsdConfig(t){return d(this,void 0,void 0,(function*(){if(!o.existsSync(t))return void console.log(`Main-> 配置 ${t} 不存在`);let e=o.readFileSync(t,"utf-8");this.psdConfig=JSON.parse(e);for(const t in this.psdConfig)t in V&&("object"==typeof this.psdConfig[t]?V[t]=Object.assign({},V[t],this.psdConfig[t]):V[t]=this.psdConfig[t]||V[t])}))}exec(t){return d(this,void 0,void 0,(function*(){if((t=function(t){if(t.json){let e=t.json;t=JSON.parse(Buffer.from(e,"base64").toString())}return t.help=t.help||t.h,t.input=t.input||t.in,t.output=t.output||t.out,t["engine-version"]=t["engine-version"]||t.ev,t["project-assets"]=t["project-assets"]||t.p,t["cache-remake"]=t["cache-remake"]||t.crm,t["force-img"]=t["force-img"]||t.fimg,t.pinyin=t.pinyin||t.py,t.cache=t.cache||t.c,t.init=t.init||t.i,t.config=t.config,t}(t)).help)return console.log("help:\n",V.help),!1;if(t["img-only"])return ft.exec(t),!0;let e=()=>d(this,void 0,void 0,(function*(){t.cache&&(o.mkdirsSync(s.dirname(t.cache)),yield Y.saveImageMap(t.cache))}));if(t["engine-version"]&&(V.editorVersion=c[t["engine-version"]]),console.log(`Main-> 数据版本 ${c[V.editorVersion]}`),!t.init||t["project-assets"]&&t.cache){if(t.cache&&!o.existsSync(t.cache)&&e(),t["project-assets"]&&(t["cache-remake"]||t.init)&&(yield Y.loadImages(t["project-assets"]),e(),t.init))console.log("psd2ui 缓存完成");else if(this.checkArgs(t)){if(t.cache&&(yield Y.initWithPath(t.cache)),yield this.loadMetaTemplete(),t.config&&(yield this.loadPsdConfig(t.config)),this.isForceImg=!!t["force-img"],tt.isPinyin=t.pinyin,o.lstatSync(t.input).isDirectory())t.output||(t.output=s.join(t.input,"psd2ui")),this.parsePsdDir(t.input,t.output);else{if(!t.output){let e=s.dirname(t.input);t.output=s.join(e,"psd2ui")}this.parsePsd(t.input,t.output)}yield e(),console.log("psd2ui 导出完成")}}else console.log("psd2ui --init 无法处理,请设置 --project-assets")}))}checkArgs(t){if(!t.input)return console.error("请设置 --input"),!1;if(!o.existsSync(t.input))return console.error(`输入路径不存在: ${t.input}`),!1;if(t["engine-version"]){switch(c[t["engine-version"]]){case c.v249:case c.v342:break;default:return console.log(`暂未实现该引擎版本 ${t["engine-version"]}`),!1}}return!0}parsePsdDir(t,e){return d(this,void 0,void 0,(function*(){let i=X.filterFile(t,(t=>".psd"==s.extname(t)));for(let t=0;t=c.v342&&255!==t.opacity){let e=new yt;e._opacity=t.opacity,e.updateWithLayer(t),r.addComponent(e)}let n=new lt(t.size.width,t.size.height);if(null===(i=t.attr)||void 0===i?void 0:i.comps.size){let e=t.attr.comps.size;n.width=null!==(o=e.w)&&void 0!==o?o:n.width,n.height=null!==(s=e.h)&&void 0!==s?s:n.height}n.width=Math.round(Math.abs(n.width/t.scale.x)),n.height=Math.round(Math.abs(n.height/t.scale.y));let a=0;if(t instanceof rt&&(a=t.offsetY),r._contentSize=n,t.updatePositionWithAR(),r._trs.setPosition(t.position.x,t.position.y+a,0),r._trs.setRotation(0,0,0,1),r._trs.setScale(t.scale.x,t.scale.y,t.scale.z),r._anchorPoint=new B(t.anchorPoint.x,t.anchorPoint.y),V.editorVersion>=c.v342){r._lpos=new pt(t.position.x,t.position.y+a,0),r._lrot=new pt(0,0,0),r._lscale=new pt(t.scale.x,t.scale.y,t.scale.z),r._euler=new pt;let e=new mt;e._contentSize=n,e._anchorPoint=r._anchorPoint,e.updateWithLayer(t),r.addComponent(e)}if(t instanceof et)for(let i=0;i{let r=J.getSerialNumberImage(e),n=Y.get(r.md5);if(!this.isForceImg&&(null==n?void 0:n.isOutput))return void console.log(`已有相同资源,不再导出 [${e.imgName}] md5: ${e.md5}`);console.log(`保存图片 [${r.imgName}] md5: ${r.md5}`),n&&(n.isOutput=!0);let a=s.join(t,`${r.imgName}.png`);o.writeFileSync(a,r.imgBuffer),this.saveImageMeta(r,a)}))}saveImageMeta(t,e){let i=J.getSerialNumberImage(t),s=Y.get(i.md5);s||(s=i);let r=this.spriteFrameMetaContent.replace(/\$SPRITE_FRAME_UUID/g,s.uuid);r=r.replace(/\$TEXTURE_UUID/g,s.textureUuid),r=r.replace(/\$FILE_NAME/g,i.imgName),r=r.replace(/\$WIDTH/g,i.textureSize.width),r=r.replace(/\$HEIGHT/g,i.textureSize.height);let n=i.s9||{b:0,t:0,l:0,r:0};r=r.replace(/\$BORDER_TOP/g,n.t),r=r.replace(/\$BORDER_BOTTOM/g,n.b),r=r.replace(/\$BORDER_LEFT/g,n.l),r=r.replace(/\$BORDER_RIGHT/g,n.r),o.writeFileSync(e+".meta",r)}savePrefab(t,e){let i=s.join(e,`${t.name}.prefab`);o.writeFileSync(i,JSON.stringify(t.objectArray,null,2)),this.savePrefabMeta(t,i)}savePrefabMeta(t,e){let i=this.prefabMetaContent.replace(/\$PREFB_UUID/g,t.uuid);o.writeFileSync(e+".meta",i)}applyConfig(t){if(this.psdConfig&&t.__type__ in this.psdConfig){let e=this.psdConfig[t.__type__];for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){const o=e[i];t[i]=o}}}};bt.length?wt.exec(xt):wt.test()}));
diff --git a/psd2ui-tools/package-lock.json b/psd2ui-tools/package-lock.json
new file mode 100644
index 0000000..29a9cea
--- /dev/null
+++ b/psd2ui-tools/package-lock.json
@@ -0,0 +1,2960 @@
+{
+ "name": "psd2ui",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "psd2ui",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "ag-psd": "^15.0.0",
+ "canvas": "^2.10.2",
+ "fs-extra": "^10.1.0",
+ "minimist": "^1.2.7",
+ "pinyin-pro": "^3.16.0"
+ },
+ "devDependencies": {
+ "@rollup/plugin-commonjs": "^25.0.3",
+ "@rollup/plugin-json": "^6.0.0",
+ "@rollup/plugin-node-resolve": "^15.1.0",
+ "@rollup/plugin-typescript": "^11.1.2",
+ "@types/fs-extra": "^9.0.13",
+ "@types/node": "^18.11.9",
+ "cross-env": "^7.0.3",
+ "rollup-plugin-terser": "^7.0.2",
+ "rollup-plugin-typescript2": "^0.35.0",
+ "ts-node": "^10.9.1",
+ "tslib": "^2.6.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.22.5.tgz",
+ "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
+ "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.22.5.tgz",
+ "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
+ "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "make-dir": "^3.1.0",
+ "node-fetch": "^2.6.7",
+ "nopt": "^5.0.0",
+ "npmlog": "^5.0.1",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "node-pre-gyp": "bin/node-pre-gyp"
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs": {
+ "version": "25.0.3",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz",
+ "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "commondir": "^1.0.1",
+ "estree-walker": "^2.0.2",
+ "glob": "^8.0.3",
+ "is-reference": "1.2.1",
+ "magic-string": "^0.27.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.68.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@rollup/plugin-json": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-json/-/plugin-json-6.0.0.tgz",
+ "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz",
+ "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-builtin-module": "^3.2.1",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-typescript": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz",
+ "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.14.0||^3.0.0",
+ "tslib": "*",
+ "typescript": ">=3.7.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ },
+ "tslib": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+ "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true
+ },
+ "node_modules/@types/base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@types/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ZmI0sZGAUNXUfMWboWwi4LcfpoVUYldyN6Oe0oJ5cCsHDU/LlRq8nQKPXhYLOx36QYSW9bNIb1vvRrD6K7Llgw=="
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
+ "dev": true
+ },
+ "node_modules/@types/fs-extra": {
+ "version": "9.0.13",
+ "resolved": "https://registry.npmmirror.com/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+ "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "18.11.9",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.9.tgz",
+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
+ "dev": true
+ },
+ "node_modules/@types/pako": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/@types/pako/-/pako-2.0.0.tgz",
+ "integrity": "sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA=="
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true
+ },
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ag-psd": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmmirror.com/ag-psd/-/ag-psd-15.0.0.tgz",
+ "integrity": "sha512-CQt1YX+NtGxbghgwbZ2vOd+9toIa3PAlexClPQWnvILM8vn72ORoEgOiTMjWdKRaNpkX2KomWZWkWaeG84idcw==",
+ "dependencies": {
+ "@types/base64-js": "^1.3.0",
+ "@types/pako": "^2.0.0",
+ "base64-js": "^1.5.1",
+ "pako": "^2.0.4"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/aproba": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz",
+ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
+ },
+ "node_modules/are-we-there-yet": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+ "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/builtin-modules": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/builtin-modules/-/builtin-modules-3.3.0.tgz",
+ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/canvas": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmmirror.com/canvas/-/canvas-2.10.2.tgz",
+ "integrity": "sha512-FSmlsip0nZ0U4Zcfht0qBJqDhlfGuevTZKE8h+dBOYrJjGvY3iqMGSzzbvkaFhvMXiVxfcMaPHS/kge++T5SKg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^1.0.0",
+ "nan": "^2.17.0",
+ "simple-get": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "dependencies": {
+ "mimic-response": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.1.tgz",
+ "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/gauge": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/gauge/-/gauge-3.0.2.tgz",
+ "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.2",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.1",
+ "object-assign": "^4.1.1",
+ "signal-exit": "^3.0.0",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/is-builtin-module": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmmirror.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+ "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+ "dev": true,
+ "dependencies": {
+ "builtin-modules": "^3.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.12.1.tgz",
+ "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true
+ },
+ "node_modules/is-reference": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-1.2.1.tgz",
+ "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.27.0.tgz",
+ "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.13"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ },
+ "node_modules/minipass": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.4.tgz",
+ "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
+ },
+ "node_modules/node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npmlog": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-5.0.1.tgz",
+ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "dependencies": {
+ "are-we-there-yet": "^2.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^3.0.0",
+ "set-blocking": "^2.0.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pako": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/pinyin-pro": {
+ "version": "3.16.0",
+ "resolved": "https://registry.npmmirror.com/pinyin-pro/-/pinyin-pro-3.16.0.tgz",
+ "integrity": "sha512-U4pMQ/KSMM5JmSb+ZcReCIbgzGl/JaglaHqWjCli0hpA0rDdjRbAO67e6fOa3ZFcJzbqfe6bJkaMMmpiWmkXgQ=="
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
+ "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.11.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.79.1",
+ "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz",
+ "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup-plugin-terser": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmmirror.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
+ "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "jest-worker": "^26.2.1",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^5.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0"
+ }
+ },
+ "node_modules/rollup-plugin-typescript2": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmmirror.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.35.0.tgz",
+ "integrity": "sha512-szcIO9hPUx3PhQl91u4pfNAH2EKbtrXaES+m163xQVE5O1CC0ea6YZV/5woiDDW3CR9jF2CszPrKN+AFiND0bg==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^4.1.2",
+ "find-cache-dir": "^3.3.2",
+ "fs-extra": "^10.0.0",
+ "semver": "^7.3.7",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "rollup": ">=1.26.3",
+ "typescript": ">=2.4.0"
+ }
+ },
+ "node_modules/rollup-plugin-typescript2/node_modules/@rollup/pluginutils": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
+ "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
+ "dev": true,
+ "dependencies": {
+ "estree-walker": "^2.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
+ },
+ "node_modules/simple-get": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz",
+ "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
+ "dependencies": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/tar": {
+ "version": "6.1.12",
+ "resolved": "https://registry.npmmirror.com/tar/-/tar-6.1.12.tgz",
+ "integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.19.1",
+ "resolved": "https://registry.npmmirror.com/terser/-/terser-5.19.1.tgz",
+ "integrity": "sha512-27hxBUVdV6GoNg1pKQ7Z5cbR6V9txPVyBA+FQw3BaZ1Wuzvztce5p156DaP0NVZNrMZZ+6iG9Syf7WgMNKDg2Q==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.0.tgz",
+ "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==",
+ "dev": true
+ },
+ "node_modules/typescript": {
+ "version": "4.9.3",
+ "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.3.tgz",
+ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ }
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.22.5.tgz",
+ "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.22.5"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
+ "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.22.5.tgz",
+ "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.22.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@mapbox/node-pre-gyp": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
+ "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
+ "requires": {
+ "detect-libc": "^2.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "make-dir": "^3.1.0",
+ "node-fetch": "^2.6.7",
+ "nopt": "^5.0.0",
+ "npmlog": "^5.0.1",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.11"
+ }
+ },
+ "@rollup/plugin-commonjs": {
+ "version": "25.0.3",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz",
+ "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1",
+ "commondir": "^1.0.1",
+ "estree-walker": "^2.0.2",
+ "glob": "^8.0.3",
+ "is-reference": "1.2.1",
+ "magic-string": "^0.27.0"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ }
+ },
+ "minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
+ }
+ },
+ "@rollup/plugin-json": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-json/-/plugin-json-6.0.0.tgz",
+ "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1"
+ }
+ },
+ "@rollup/plugin-node-resolve": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz",
+ "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-builtin-module": "^3.2.1",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ }
+ },
+ "@rollup/plugin-typescript": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmmirror.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz",
+ "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1",
+ "resolve": "^1.22.1"
+ }
+ },
+ "@rollup/pluginutils": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+ "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true
+ },
+ "@types/base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@types/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ZmI0sZGAUNXUfMWboWwi4LcfpoVUYldyN6Oe0oJ5cCsHDU/LlRq8nQKPXhYLOx36QYSW9bNIb1vvRrD6K7Llgw=="
+ },
+ "@types/estree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
+ "dev": true
+ },
+ "@types/fs-extra": {
+ "version": "9.0.13",
+ "resolved": "https://registry.npmmirror.com/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+ "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "18.11.9",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.9.tgz",
+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
+ "dev": true
+ },
+ "@types/pako": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/@types/pako/-/pako-2.0.0.tgz",
+ "integrity": "sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA=="
+ },
+ "@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ },
+ "ag-psd": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmmirror.com/ag-psd/-/ag-psd-15.0.0.tgz",
+ "integrity": "sha512-CQt1YX+NtGxbghgwbZ2vOd+9toIa3PAlexClPQWnvILM8vn72ORoEgOiTMjWdKRaNpkX2KomWZWkWaeG84idcw==",
+ "requires": {
+ "@types/base64-js": "^1.3.0",
+ "@types/pako": "^2.0.0",
+ "base64-js": "^1.5.1",
+ "pako": "^2.0.4"
+ }
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "requires": {
+ "debug": "4"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "aproba": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz",
+ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
+ },
+ "are-we-there-yet": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+ "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "builtin-modules": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/builtin-modules/-/builtin-modules-3.3.0.tgz",
+ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
+ "dev": true
+ },
+ "canvas": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmmirror.com/canvas/-/canvas-2.10.2.tgz",
+ "integrity": "sha512-FSmlsip0nZ0U4Zcfht0qBJqDhlfGuevTZKE8h+dBOYrJjGvY3iqMGSzzbvkaFhvMXiVxfcMaPHS/kge++T5SKg==",
+ "requires": {
+ "@mapbox/node-pre-gyp": "^1.0.0",
+ "nan": "^2.17.0",
+ "simple-get": "^3.0.3"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
+ },
+ "create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.1"
+ }
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
+ "deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
+ },
+ "detect-libc": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.1.tgz",
+ "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w=="
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
+ },
+ "find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true,
+ "peer": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gauge": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/gauge/-/gauge-3.0.2.tgz",
+ "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
+ "requires": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.2",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.1",
+ "object-assign": "^4.1.1",
+ "signal-exit": "^3.0.0",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.2"
+ }
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
+ },
+ "https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "is-builtin-module": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmmirror.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+ "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "^3.3.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.12.1.tgz",
+ "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+ },
+ "is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true
+ },
+ "is-reference": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-1.2.1.tgz",
+ "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "*"
+ }
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "magic-string": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.27.0.tgz",
+ "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/sourcemap-codec": "^1.4.13"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ }
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ },
+ "minipass": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.4.tgz",
+ "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
+ },
+ "node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
+ "nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "npmlog": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-5.0.1.tgz",
+ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "requires": {
+ "are-we-there-yet": "^2.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^3.0.0",
+ "set-blocking": "^2.0.0"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "pako": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pinyin-pro": {
+ "version": "3.16.0",
+ "resolved": "https://registry.npmmirror.com/pinyin-pro/-/pinyin-pro-3.16.0.tgz",
+ "integrity": "sha512-U4pMQ/KSMM5JmSb+ZcReCIbgzGl/JaglaHqWjCli0hpA0rDdjRbAO67e6fOa3ZFcJzbqfe6bJkaMMmpiWmkXgQ=="
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "resolve": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
+ "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.11.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "rollup": {
+ "version": "2.79.1",
+ "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz",
+ "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "rollup-plugin-terser": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmmirror.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
+ "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "jest-worker": "^26.2.1",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^5.0.0"
+ }
+ },
+ "rollup-plugin-typescript2": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmmirror.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.35.0.tgz",
+ "integrity": "sha512-szcIO9hPUx3PhQl91u4pfNAH2EKbtrXaES+m163xQVE5O1CC0ea6YZV/5woiDDW3CR9jF2CszPrKN+AFiND0bg==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^4.1.2",
+ "find-cache-dir": "^3.3.2",
+ "fs-extra": "^10.0.0",
+ "semver": "^7.3.7",
+ "tslib": "^2.4.0"
+ },
+ "dependencies": {
+ "@rollup/pluginutils": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
+ "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
+ "dev": true,
+ "requires": {
+ "estree-walker": "^2.0.1",
+ "picomatch": "^2.2.2"
+ }
+ }
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
+ },
+ "simple-get": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz",
+ "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "tar": {
+ "version": "6.1.12",
+ "resolved": "https://registry.npmmirror.com/tar/-/tar-6.1.12.tgz",
+ "integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==",
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ }
+ },
+ "terser": {
+ "version": "5.19.1",
+ "resolved": "https://registry.npmmirror.com/terser/-/terser-5.19.1.tgz",
+ "integrity": "sha512-27hxBUVdV6GoNg1pKQ7Z5cbR6V9txPVyBA+FQw3BaZ1Wuzvztce5p156DaP0NVZNrMZZ+6iG9Syf7WgMNKDg2Q==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ }
+ },
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "ts-node": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "dev": true,
+ "requires": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ }
+ },
+ "tslib": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.0.tgz",
+ "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.9.3",
+ "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.3.tgz",
+ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
+ "dev": true,
+ "peer": true
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "requires": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
+ }
+ }
+}
diff --git a/psd2ui-tools/package.json b/psd2ui-tools/package.json
new file mode 100644
index 0000000..6cda5e8
--- /dev/null
+++ b/psd2ui-tools/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "psd2ui",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "build": "tsc -b",
+ "watch": "tsc -w",
+ "rollup": "rollup -c",
+ "test": "node dist/index.js --input ./test/normal-test.psd --cache-remake --output ./out/",
+ "help": "node dist/index.js --h",
+ "test-dir": "node dist/index.js --input E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\test --output E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\out --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json",
+ "test-psd": "node dist/index.js --input E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\test\\normal-test.psd --output E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\out --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json",
+ "test-cache": "node dist/index.js --input E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\test\\normal-test.psd --output E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\out --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json --project-assets E:\\Demo\\CC249JSTest\\assets --cache-remake",
+ "test-dir-no-output": "node dist/index.js --input E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\test --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json",
+ "test-psd-no-output": "node dist/index.js --input E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\test\\normal-test.psd --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json",
+ "test-init": "node dist/index.js --init --project-assets E:\\Demo\\CC249JSTest\\assets --cache E:\\Git\\ccc-framework-3d\\tools\\psd2ui\\cache\\cache.json",
+ "test-png9": "ts-node src/index.ts --engine-version v342 --pinyin --input ./test/png9.psd --output ./out/",
+ "test-png9-2": "node dist/index.js --engine-version v342 --pinyin --input ./test/png9.psd --output ./out/"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "ag-psd": "^15.0.0",
+ "canvas": "^2.10.2",
+ "fs-extra": "^10.1.0",
+ "minimist": "^1.2.7",
+ "pinyin-pro": "^3.16.0"
+ },
+ "devDependencies": {
+ "@rollup/plugin-commonjs": "^25.0.3",
+ "@rollup/plugin-json": "^6.0.0",
+ "@rollup/plugin-node-resolve": "^15.1.0",
+ "@rollup/plugin-typescript": "^11.1.2",
+ "@types/fs-extra": "^9.0.13",
+ "@types/node": "^18.11.9",
+ "cross-env": "^7.0.3",
+ "rollup-plugin-terser": "^7.0.2",
+ "rollup-plugin-typescript2": "^0.35.0",
+ "ts-node": "^10.9.1",
+ "tslib": "^2.6.0"
+ }
+}
diff --git a/psd2ui-tools/rollup.config.js b/psd2ui-tools/rollup.config.js
new file mode 100644
index 0000000..6aebeea
--- /dev/null
+++ b/psd2ui-tools/rollup.config.js
@@ -0,0 +1,28 @@
+
+
+let path = require("path");
+const commonjs = require('@rollup/plugin-commonjs')
+const typescript = require('rollup-plugin-typescript2')
+let resolve = require('@rollup/plugin-node-resolve').default;
+let json = require("@rollup/plugin-json").default;
+let terser = require("rollup-plugin-terser").terser;
+
+
+const override = { compilerOptions: { module: 'ESNext' } }
+module.exports = {
+ input: "./src/export.ts",
+
+ output: {
+ file: path.resolve(__dirname, "./dist/index.js"),
+ sourcemap: false,
+ format: "umd",
+ },
+
+ plugins: [
+ typescript({ tsconfig: './tsconfig.json', tsconfigOverride: override }),
+ json(),
+ // resolve(),
+ commonjs(),
+ terser()
+ ]
+}
diff --git a/psd2ui-tools/src/EditorVersion.ts b/psd2ui-tools/src/EditorVersion.ts
new file mode 100644
index 0000000..a90ec90
--- /dev/null
+++ b/psd2ui-tools/src/EditorVersion.ts
@@ -0,0 +1,6 @@
+
+export enum EditorVersion{
+ all,
+ v249,
+ v342,
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/ExportImageMgr.ts b/psd2ui-tools/src/ExportImageMgr.ts
new file mode 100644
index 0000000..8792c14
--- /dev/null
+++ b/psd2ui-tools/src/ExportImageMgr.ts
@@ -0,0 +1,171 @@
+
+
+import 'ag-psd/initialize-canvas'; // only needed for reading image data and thumbnails
+import * as psd from 'ag-psd';
+import fs from 'fs-extra';
+import path from 'path';
+import { imageMgr } from './assets-manager/ImageMgr';
+import { fileUtils } from './utils/FileUtils';
+import { parser } from './Parser';
+import { PsdDocument } from './psd/PsdDocument';
+import { PsdLayer } from './psd/PsdLayer';
+import { PsdGroup } from './psd/PsdGroup';
+import { PsdText } from './psd/PsdText';
+import { Color } from './values/Color';
+
+interface TextObject{
+ text: string;
+ fontSize: number;
+ color: string;
+ outlineWidth?: number;
+ outlineColor?: string;
+}
+
+class ExportImageMgr{
+
+ textObjects: TextObject[] = [];
+
+ test(){
+ const outDir = path.join(__dirname, "..", "out");
+ let psdPath = "./test-img-only/境界奖励-优化.psd";
+ this.parsePsd(psdPath, outDir);
+ }
+
+ async exec(args) {
+ // 检查参数
+ if (!this.checkArgs(args)) {
+ return;
+ }
+
+ // 判断输入是文件夹还是文件
+ let stat = fs.lstatSync(args.input);
+ let isDirectory = stat.isDirectory();
+ if (isDirectory) {
+ if (!args.output) {
+ args.output = path.join(args.input, "psd2ui")
+ }
+ this.parsePsdDir(args.input, args.output);
+ } else {
+ if (!args.output) {
+ let input_dir = path.dirname(args.input);
+ args.output = path.join(input_dir, "psd2ui")
+ }
+ this.parsePsd(args.input, args.output);
+ }
+
+ }
+
+ // 检查参数
+ checkArgs(args) {
+
+ if (!args.input) {
+ console.error(`请设置 --input`);
+ return false;
+ }
+ if (!fs.existsSync(args.input)) {
+ console.error(`输入路径不存在: ${args.input}`);
+ return false;
+ }
+
+ return true;
+ }
+
+ async parsePsdDir(dir: string, outDir: string) {
+ // 清空目录
+ fs.emptyDirSync(outDir);
+
+ let psds = fileUtils.filterFile(dir, (fileName) => {
+ let extname = path.extname(fileName);
+ if (extname == ".psd") {
+ return true;
+ }
+ return false;
+ });
+
+ for (let i = 0; i < psds.length; i++) {
+ const element = psds[i];
+ await this.parsePsd(element, outDir);
+ }
+ }
+ async parsePsd(psdPath: string, outDir: string) {
+ // 每开始一个新的 psd 清理掉上一个 psd 的图
+ imageMgr.clear();
+ this.textObjects.length = 0;
+ console.log(`=========================================`);
+
+ console.log(`处理 ${psdPath} 文件`);
+
+ let psdName = path.basename(psdPath, ".psd");
+ let buffer = fs.readFileSync(psdPath);
+ const psdFile = psd.readPsd(buffer)
+ let psdRoot = parser.parseLayer(psdFile) as PsdDocument;
+ psdRoot.name = psdName;
+ let prefabDir = path.join(outDir, psdName);
+ let textureDir = path.join(prefabDir, "textures");
+ fs.mkdirsSync(prefabDir); // 创建预制体根目录
+ fs.emptyDirSync(prefabDir);
+ fs.mkdirsSync(textureDir); //创建 图片目录
+ await this.saveImage(textureDir);
+ await this.saveTextFile(psdRoot,prefabDir);
+ console.log(`psd2ui ${psdPath} 处理完成`);
+
+ }
+
+ saveImage(out: string) {
+
+ let images = imageMgr.getAllImage();
+ let idx = 0;
+ images.forEach((psdImage, k) => {
+ // 查找镜像
+ let _layer = imageMgr.getSerialNumberImage(psdImage);
+ let name = `${_layer.imgName}_${idx}`
+ console.log(`保存图片 [${_layer.imgName}] 重命名为 [${name}] md5: ${_layer.md5}`);
+ let fullpath = path.join(out, `${name}.png`);
+ fs.writeFileSync(fullpath, _layer.imgBuffer);
+ idx++;
+ });
+
+ }
+
+
+ saveTextFile(psdRoot: PsdDocument,out: string){
+ this.scanText(psdRoot,psdRoot);
+ let textContent = JSON.stringify(this.textObjects,null,2);
+ let fullpath = path.join(out, `text.txt`);
+ fs.writeFileSync(fullpath, textContent,{encoding: "utf-8"});
+ }
+
+ scanText(layer: PsdLayer, psdRoot: PsdDocument) {
+ if (layer instanceof PsdGroup) {
+ for (let i = 0; i < layer.children.length; i++) {
+ const childLayer = layer.children[i];
+ this.scanText(childLayer, psdRoot);
+ }
+ } else if (layer instanceof PsdText) {
+ let textObj: TextObject = {
+ text: layer.text,
+ fontSize: layer.fontSize,
+ color: `#${layer.color.toHEX()}`
+ };
+ // 有描边
+ if (layer.outline) {
+ textObj.outlineWidth = layer.outline.width;
+ textObj.outlineColor = `#${layer.outline.color.toHEX()}`;
+ }
+
+ this.textObjects.push(textObj);
+ }
+ }
+
+
+ private static _instance:ExportImageMgr = null
+ public static getInstance(): ExportImageMgr{
+ if(!this._instance){
+ this._instance = new ExportImageMgr();
+ }
+ return this._instance;
+ }
+}
+
+
+export let exportImageMgr = ExportImageMgr.getInstance();
\ No newline at end of file
diff --git a/psd2ui-tools/src/Main.ts b/psd2ui-tools/src/Main.ts
new file mode 100644
index 0000000..d3bf65d
--- /dev/null
+++ b/psd2ui-tools/src/Main.ts
@@ -0,0 +1,507 @@
+
+
+//ag-psd 使用 参考 https://github.com/Agamnentzar/ag-psd/blob/HEAD/README_PSD.md
+
+import 'ag-psd/initialize-canvas'; // only needed for reading image data and thumbnails
+import * as psd from 'ag-psd';
+import fs from 'fs-extra';
+import path from 'path';
+import { parser } from './Parser';
+import { PsdDocument } from './psd/PsdDocument';
+import { PsdLayer } from './psd/PsdLayer';
+import { LayerType } from './psd/LayerType';
+import { PsdGroup } from './psd/PsdGroup';
+import { CCNode } from './engine/cc/CCNode';
+import { PsdImage } from './psd/PsdImage';
+import { PsdText } from './psd/PsdText';
+import { CCSprite } from './engine/cc/CCSprite';
+import { CCPrefabInfo } from './engine/cc/CCPrefabInfo';
+import { CCPrefab } from './engine/cc/CCPrefab';
+import { CCSize } from './engine/cc/values/CCSize';
+import { CCVec2 } from './engine/cc/values/CCVec2';
+import { CCComponent } from './engine/cc/CCComponent';
+import { CCLabel } from './engine/cc/CCLabel';
+import { CCLabelOutline } from './engine/cc/CCLabelOutline';
+import { imageCacheMgr } from './assets-manager/ImageCacheMgr';
+import { EditorVersion } from './EditorVersion';
+import { Config, config } from './config';
+import { fileUtils } from './utils/FileUtils';
+import { imageMgr } from './assets-manager/ImageMgr';
+import { exportImageMgr } from './ExportImageMgr';
+import { CCUIOpacity } from './engine/cc/CCUIOpacity';
+import { CCUITransform } from './engine/cc/CCUITransform';
+import { CCVec3 } from './engine/cc/values/CCVec3';
+
+
+/***
+ * 执行流程
+ * - 首次运行,先读取项目文件夹下所有图片资源,进行 md5 缓存
+ *
+ * - 加载缓存文件
+ * - 处理 psd
+ * - 通过 md5 判断是否已经存在资源,如果存在, 则不再导出,预制体中使用已存在的资源的 uuid
+ *
+ */
+
+
+console.log(`当前目录: `, __dirname);
+
+
+export class Main {
+
+ spriteFrameMetaContent: string = "";
+ prefabMetaContent: string = "";
+ psdConfig: Config = null;
+
+ // 强制导出图片
+ isForceImg = false;
+
+ async test() {
+ console.log(`Main-> test`);
+ }
+
+ // 首先加载 meta 模板
+ async loadMetaTemplete() {
+ this.spriteFrameMetaContent = fs.readFileSync(path.join(__dirname, `../assets/cc/meta/CCSpriteFrame.meta.${EditorVersion[config.editorVersion]}`), "utf-8");
+ this.prefabMetaContent = fs.readFileSync(path.join(__dirname, `../assets/cc/meta/CCPrefab.meta.${EditorVersion[config.editorVersion]}`), "utf-8");
+ }
+
+ // 加载配置
+ async loadPsdConfig(filepath) {
+ if (!fs.existsSync(filepath)) {
+ console.log(`Main-> 配置 ${filepath} 不存在`);
+ return;
+ }
+
+ let psdConfig = fs.readFileSync(filepath, "utf-8");
+ this.psdConfig = JSON.parse(psdConfig);
+
+ // 合并配置
+ for (const key in this.psdConfig) {
+ if (key in config) {
+ if (typeof this.psdConfig[key] === 'object') {
+ config[key] = Object.assign({}, config[key], this.psdConfig[key]);
+ } else {
+ config[key] = this.psdConfig[key] || config[key];
+ }
+ }
+ }
+
+ }
+
+ async exec(args) {
+ args = mergeAlias(args);
+ if (args.help) {
+ console.log(`help:\n`, config.help);
+ return false;
+ }
+
+ // 只导出图片
+ if (args["img-only"]) {
+ exportImageMgr.exec(args);
+ return true;
+ }
+
+ let writeCache = async () => {
+ // 写入缓存
+ if (args.cache) {
+ fs.mkdirsSync(path.dirname(args.cache));
+ await imageCacheMgr.saveImageMap(args.cache);
+ }
+ }
+ // 设置引擎版本
+ if (args["engine-version"]) {
+ config.editorVersion = EditorVersion[args["engine-version"] as string];
+ }
+
+ console.log(`Main-> 数据版本 ${EditorVersion[config.editorVersion]}`);
+
+
+ if (args.init && (!args["project-assets"] || !args.cache)) {
+ console.log(`psd2ui --init 无法处理,请设置 --project-assets`);
+ return;
+ }
+
+ // 创建缓存文件
+ if (args.cache && !fs.existsSync(args.cache)) {
+ writeCache();
+ }
+
+ // 在没有缓存文件或者 指定重新缓存的时候,读取项目资源
+ if (args["project-assets"] && (args["cache-remake"] || args.init)) {
+ await imageCacheMgr.loadImages(args["project-assets"]);
+ // 先写入一次
+ writeCache();
+ if (args.init) {
+ console.log(`psd2ui 缓存完成`);
+ return;
+ }
+ }
+
+ // 检查参数
+ if (!this.checkArgs(args)) {
+ return;
+ }
+
+ if (args.cache) {
+ await imageCacheMgr.initWithPath(args.cache);
+ }
+
+ // 加载 meta 文件模板
+ await this.loadMetaTemplete();
+
+ if (args.config) {
+ await this.loadPsdConfig(args.config);
+ }
+
+ this.isForceImg = !!args["force-img"];
+
+ PsdLayer.isPinyin = args.pinyin;
+
+ // 判断输入是文件夹还是文件
+ let stat = fs.lstatSync(args.input);
+ let isDirectory = stat.isDirectory();
+ if (isDirectory) {
+ if (!args.output) {
+ args.output = path.join(args.input, "psd2ui")
+ }
+ this.parsePsdDir(args.input, args.output);
+ } else {
+ if (!args.output) {
+ let input_dir = path.dirname(args.input);
+ args.output = path.join(input_dir, "psd2ui")
+ }
+ this.parsePsd(args.input, args.output);
+ }
+
+ // 写入缓存
+ await writeCache();
+
+ console.log(`psd2ui 导出完成`);
+ }
+ // 检查参数
+ checkArgs(args) {
+
+ if (!args.input) {
+ console.error(`请设置 --input`);
+ return false;
+ }
+
+ if (!fs.existsSync(args.input)) {
+ console.error(`输入路径不存在: ${args.input}`);
+ return false;
+ }
+
+ if (args["engine-version"]) {
+ let editorVersion = EditorVersion[args["engine-version"] as string];
+ switch (editorVersion) {
+ case EditorVersion.v249:
+ case EditorVersion.v342:
+ break;
+ default:
+ console.log(`暂未实现该引擎版本 ${args["engine-version"]}`);
+ return false;
+ }
+ }
+
+
+ return true;
+ }
+
+ async parsePsdDir(dir: string, outDir: string) {
+ // 清空目录
+ // fs.emptyDirSync(outDir);
+
+ let psds = fileUtils.filterFile(dir, (fileName) => {
+ let extname = path.extname(fileName);
+ if (extname == ".psd") {
+ return true;
+ }
+ return false;
+ });
+
+ for (let i = 0; i < psds.length; i++) {
+ const element = psds[i];
+ await this.parsePsd(element, outDir);
+ }
+ }
+ async parsePsd(psdPath: string, outDir: string) {
+ // 每开始一个新的 psd 清理掉上一个 psd 的图
+ imageMgr.clear();
+ console.log(`=========================================`);
+
+ console.log(`处理 ${psdPath} 文件`);
+
+ let psdName = path.basename(psdPath, ".psd");
+ let buffer = fs.readFileSync(psdPath);
+ const psdFile = psd.readPsd(buffer)
+ let psdRoot = parser.parseLayer(psdFile) as PsdDocument;
+ psdRoot.name = psdName;
+ let prefabDir = path.join(outDir, psdName);
+ let textureDir = path.join(prefabDir, "textures");
+ fs.mkdirsSync(prefabDir); // 创建预制体根目录
+ // fs.emptyDirSync(prefabDir);
+ fs.mkdirsSync(textureDir); //创建 图片目录
+ await this.saveImage(textureDir);
+ await this.buildPrefab(psdRoot);
+ await this.savePrefab(psdRoot, prefabDir);
+ console.log(`psd2ui ${psdPath} 处理完成`);
+
+ }
+
+
+ buildPrefab(psdRoot: PsdDocument) {
+ let prefab = new CCPrefab();
+ psdRoot.pushObject(prefab);
+ let data = this.createCCNode(psdRoot, psdRoot);
+ prefab.data = { __id__: data.idx };
+ // 后期处理
+ this.postUIObject(psdRoot, psdRoot);
+
+ }
+ createCCNode(layer: PsdLayer, psdRoot: PsdDocument) {
+ let node = new CCNode(psdRoot);
+ layer.uiObject = node;
+ node._name = layer.name; //layer.attr?.name || layer.name;
+ node._active = !layer.hidden;
+ node._opacity = layer.opacity;
+
+ if (config.editorVersion >= EditorVersion.v342) {
+ // 3.4.x
+ if (layer.opacity !== 255) {
+ let uiOpacity = new CCUIOpacity();
+ uiOpacity._opacity = layer.opacity;
+ uiOpacity.updateWithLayer(layer);
+ node.addComponent(uiOpacity);
+ }
+ }
+
+ // 劫持尺寸设置,使用 psd 中配置的尺寸,这里不对原数据进行修改
+ let size = new CCSize(layer.size.width, layer.size.height);
+ if (layer.attr?.comps.size) {
+ let _attrSize = layer.attr.comps.size;
+ size.width = _attrSize.w ?? size.width;
+ size.height = _attrSize.h ?? size.height;
+
+ }
+
+ // 对缩放进行处理
+ size.width = Math.round(Math.abs(size.width / layer.scale.x));
+ size.height = Math.round(Math.abs(size.height / layer.scale.y));
+
+ // 配置的位置 Y 偏移
+ let offsetY = 0;
+ if (layer instanceof PsdText) {
+ offsetY = layer.offsetY;
+ }
+
+ node._contentSize = size;
+ // 更新一下位置 // 根据图层名字设置 锚点,位置, 因为没有对原始数据进行修改,所以这里不考虑 缩放
+ layer.updatePositionWithAR();
+
+ // 2.4.9
+ node._trs.setPosition(layer.position.x, layer.position.y + offsetY, 0);
+ node._trs.setRotation(0, 0, 0, 1);
+ node._trs.setScale(layer.scale.x, layer.scale.y, layer.scale.z);
+ node._anchorPoint = new CCVec2(layer.anchorPoint.x, layer.anchorPoint.y);
+
+
+ if (config.editorVersion >= EditorVersion.v342) {
+ // 3.4.x
+ node._lpos = new CCVec3(layer.position.x, layer.position.y + offsetY, 0);
+ node._lrot = new CCVec3(0, 0, 0);
+ node._lscale = new CCVec3(layer.scale.x, layer.scale.y, layer.scale.z);
+ node._euler = new CCVec3();
+
+ // 3.4.x
+ let uiTransform = new CCUITransform();
+ uiTransform._contentSize = size;
+ uiTransform._anchorPoint = node._anchorPoint;
+ uiTransform.updateWithLayer(layer);
+ node.addComponent(uiTransform);
+ }
+
+ //
+ if (layer instanceof PsdGroup) {
+ for (let i = 0; i < layer.children.length; i++) {
+ const childLayer = layer.children[i];
+ let childNode = this.createCCNode(childLayer, psdRoot);
+ childNode && node.addChild(childNode);
+ }
+ } else if (layer instanceof PsdImage) {
+ let sprite = new CCSprite();
+
+ node.addComponent(sprite);
+ sprite._materials.push({
+ __uuid__: config.SpriteFrame_Material
+ });
+ sprite.updateWithLayer(layer);
+
+ if (layer.isIgnore()) {
+ // 忽略图像
+ } else {
+ // 查找绑定的图像
+ let _layer = imageMgr.getSerialNumberImage(layer);
+ // 使用已缓存的 图片 的 uuid
+ let imageWarp = imageCacheMgr.get(_layer.md5);
+ sprite.setSpriteFrame(imageWarp ? imageWarp.textureUuid : _layer.textureUuid);
+ }
+
+ this.applyConfig(sprite);
+ } else if (layer instanceof PsdText) {
+ let label = new CCLabel();
+ node.addComponent(label);
+ node._color.set(layer.color);
+ label._color.set(layer.color);
+ label._materials.push({
+ __uuid__: config.Label_Material
+ });
+ label.updateWithLayer(layer);
+ this.applyConfig(label);
+ // 有描边
+ if (layer.outline) {
+ let labelOutline = new CCLabelOutline();
+ node.addComponent(labelOutline);
+ labelOutline.updateWithLayer(layer);
+ this.applyConfig(labelOutline);
+ }
+ }
+
+ // Button / Toggle / ProgressBar
+ if (layer.attr) {
+ for (const key in layer.attr.comps) {
+ if (Object.prototype.hasOwnProperty.call(layer.attr.comps, key) && layer.attr.comps[key]) {
+ let ctor = config.CompMappings[key] as any;
+ if (ctor) {
+ let comp: CCComponent = new ctor();
+ node.addComponent(comp);
+ comp.updateWithLayer(layer);
+ this.applyConfig(comp);
+ }
+ }
+ }
+ }
+
+ this.createPrefabInfo(layer, psdRoot);
+ return node;
+ }
+
+ createPrefabInfo(layer: PsdLayer, psdRoot: PsdDocument) {
+ let node = layer.uiObject as CCNode;
+ let prefabInfo = new CCPrefabInfo();
+ let idx = psdRoot.pushObject(prefabInfo);
+ node._prefab = { __id__: idx };
+ }
+
+ // 后处理
+ postUIObject(layer: PsdLayer, psdRoot: PsdDocument) {
+ }
+
+ saveImage(out: string) {
+
+ let images = imageMgr.getAllImage();
+ images.forEach((psdImage, k) => {
+ // 查找镜像
+ let _layer = imageMgr.getSerialNumberImage(psdImage);
+
+ // 查找已缓存的相同图像
+ let imageWarp = imageCacheMgr.get(_layer.md5);
+
+ // 不是强制导出的话,判断是否已经导出过
+ if (!this.isForceImg) {
+ // 判断是否已经导出过相同 md5 的资源,不再重复导出
+ if (imageWarp?.isOutput) {
+ console.log(`已有相同资源,不再导出 [${psdImage.imgName}] md5: ${psdImage.md5}`);
+ return;
+ }
+ }
+ console.log(`保存图片 [${_layer.imgName}] md5: ${_layer.md5}`);
+ imageWarp && (imageWarp.isOutput = true);
+ let fullpath = path.join(out, `${_layer.imgName}.png`);
+ fs.writeFileSync(fullpath, _layer.imgBuffer);
+ this.saveImageMeta(_layer, fullpath);
+ });
+
+ }
+
+ saveImageMeta(layer: PsdImage, fullpath: string) {
+ let _layer = imageMgr.getSerialNumberImage(layer);
+ let imageWarp = imageCacheMgr.get(_layer.md5);
+ if (!imageWarp) {
+ imageWarp = _layer;
+ }
+
+ // 2.4.9 =-> SPRITE_FRAME_UUID
+ let meta = this.spriteFrameMetaContent.replace(/\$SPRITE_FRAME_UUID/g, imageWarp.uuid)
+
+ meta = meta.replace(/\$TEXTURE_UUID/g, imageWarp.textureUuid);
+ meta = meta.replace(/\$FILE_NAME/g, _layer.imgName);
+ meta = meta.replace(/\$WIDTH/g, _layer.textureSize.width as any);
+ meta = meta.replace(/\$HEIGHT/g, _layer.textureSize.height as any);
+
+ let s9 = _layer.s9 || {
+ b: 0, t: 0, l: 0, r: 0,
+ };
+
+ meta = meta.replace(/\$BORDER_TOP/g, s9.t as any);
+ meta = meta.replace(/\$BORDER_BOTTOM/g, s9.b as any);
+ meta = meta.replace(/\$BORDER_LEFT/g, s9.l as any);
+ meta = meta.replace(/\$BORDER_RIGHT/g, s9.r as any);
+
+ fs.writeFileSync(fullpath + `.meta`, meta);
+ }
+
+
+ savePrefab(psdDoc: PsdDocument, out) {
+ let fullpath = path.join(out, `${psdDoc.name}.prefab`);
+ fs.writeFileSync(fullpath, JSON.stringify(psdDoc.objectArray, null, 2));
+ this.savePrefabMeta(psdDoc, fullpath);
+ }
+
+ savePrefabMeta(psdDoc: PsdDocument, fullpath) {
+ let meta = this.prefabMetaContent.replace(/\$PREFB_UUID/g, psdDoc.uuid)
+ fs.writeFileSync(fullpath + `.meta`, meta);
+ }
+
+ applyConfig(comp: CCComponent) {
+ if (!this.psdConfig) {
+ return;
+ }
+ if (comp.__type__ in this.psdConfig) {
+ let compConfig = this.psdConfig[comp.__type__];
+ for (const key in compConfig) {
+ if (Object.prototype.hasOwnProperty.call(compConfig, key)) {
+ const element = compConfig[key];
+ comp[key] = element;
+ }
+ }
+ }
+ }
+}
+
+/** 合并别名 */
+function mergeAlias(args) {
+ // 如果是 json 对象参数
+ if (args.json) {
+ let base64 = args.json;
+ // 解码 json
+ args = JSON.parse(Buffer.from(base64, "base64").toString());
+
+ // // 编码
+ // let jsonContent = JSON.stringify(args);
+ // let base64 = Buffer.from(jsonContent).toString("base64");
+ }
+ args.help = args.help || args.h;
+ args.input = args.input || args.in;
+ args.output = args.output || args.out;
+ args["engine-version"] = args["engine-version"] || args.ev;
+ args["project-assets"] = args["project-assets"] || args.p;
+ args["cache-remake"] = args["cache-remake"] || args.crm;
+ args["force-img"] = args["force-img"] || args.fimg;
+ args.pinyin = args.pinyin || args.py;
+ args.cache = args.cache || args.c;
+ args.init = args.init || args.i;
+ args.config = args.config;
+ return args;
+}
+
diff --git a/psd2ui-tools/src/Parser.ts b/psd2ui-tools/src/Parser.ts
new file mode 100644
index 0000000..e81f3a4
--- /dev/null
+++ b/psd2ui-tools/src/Parser.ts
@@ -0,0 +1,107 @@
+import { imageCacheMgr } from "./assets-manager/ImageCacheMgr";
+import { imageMgr } from "./assets-manager/ImageMgr";
+import { LayerType } from "./psd/LayerType";
+import { PsdDocument } from "./psd/PsdDocument";
+import { PsdGroup } from "./psd/PsdGroup";
+import { PsdImage } from "./psd/PsdImage";
+import { PsdAttr, PsdLayer } from "./psd/PsdLayer";
+import { PsdText } from "./psd/PsdText";
+import { PsdLayerSource } from "./_declare";
+
+export class Parser {
+
+ /** 解析图层类型 */
+ parseLayerType(source: PsdLayerSource) {
+ if ("children" in source) {
+ if ("width" in source && "height" in source) {
+ // Document
+ return LayerType.Doc;
+ } else {
+ // Group
+ return LayerType.Group;
+ }
+ } else if ("text" in source) {
+ // Text
+ return LayerType.Text;
+ }
+ // else if ('placedLayer' in layer) {
+ // // 智能对象
+ // }
+ return LayerType.Image;
+ }
+ parseLayer(source: any, parent?: PsdGroup, rootDoc?: PsdDocument) {
+ let layer: PsdLayer = null;
+ let layerType = this.parseLayerType(source);
+ switch (layerType) {
+ case LayerType.Doc:
+ case LayerType.Group: {
+
+ let group: PsdGroup = null
+ // Group
+ if (layerType == LayerType.Group) {
+ group = new PsdGroup(source, parent, rootDoc);
+ if(group.attr.comps.ignorenode || group.attr.comps.ignore){
+ return null;
+ }
+ } else {
+ // Document
+ group = new PsdDocument(source);
+ }
+
+ for (let i = 0; i < source.children.length; i++) {
+ const childSource = source.children[i];
+ let child = this.parseLayer(childSource, group, rootDoc || group as PsdDocument);
+ if (child) {
+ if (!child.attr.comps.ignorenode && !child.attr.comps.ignore) {
+ // 没有进行忽略节点的时候才放入列表
+ group.children.push(child);
+ }
+ } else {
+ console.error(`图层解析错误`);
+ }
+ }
+ layer = group;
+ }
+ break;
+
+ case LayerType.Image: {
+ //
+ if (!source.canvas) {
+ console.error(`Parser-> 空图层 ${source?.name}`);
+ return null;
+ }
+ // Image
+ let image = layer = new PsdImage(source, parent, rootDoc);
+ imageMgr.add(image);
+
+ // 没有设置忽略且不说镜像的情况下才进行缓存
+ if (!image.isIgnore() && ! image.isBind()) {
+ if (!imageCacheMgr.has(image.md5)) {
+ imageCacheMgr.set(image.md5, {
+ uuid: image.uuid,
+ textureUuid: image.textureUuid,
+ });
+ }
+ }
+ }
+ break;
+
+ case LayerType.Text: {
+ // Text
+ layer = new PsdText(source, parent, rootDoc);
+ }
+ break;
+
+ default:
+ break;
+ }
+ layer.layerType = layerType;
+ layer.parseSource();
+ layer.onCtor();
+ return layer;
+ }
+
+
+}
+
+export const parser = new Parser();
\ No newline at end of file
diff --git a/psd2ui-tools/src/_declare.ts b/psd2ui-tools/src/_declare.ts
new file mode 100644
index 0000000..a80833d
--- /dev/null
+++ b/psd2ui-tools/src/_declare.ts
@@ -0,0 +1,6 @@
+
+export interface PsdLayerSource {
+ [k: string]: any;
+}
+
+
diff --git a/psd2ui-tools/src/_decorator.ts b/psd2ui-tools/src/_decorator.ts
new file mode 100644
index 0000000..dfffa5c
--- /dev/null
+++ b/psd2ui-tools/src/_decorator.ts
@@ -0,0 +1,137 @@
+import { config } from "./config";
+import { EditorVersion } from "./EditorVersion";
+import { UIObject } from "./engine/UIObject";
+
+/** 禁止序列化 */
+export let nonserialization = (target: any,propertyKey: string)=>{
+ if(!target.__unserialization){
+ target.__unserialization = [];
+ }
+ target.__unserialization.push(propertyKey);
+
+ // if(!target.toJSON){
+ // // JSON.stringify 自动调用
+ // target.toJSON = function(){
+ // let data:Record = {};
+ // for (const key in this) {
+ // if (Object.prototype.hasOwnProperty.call(this, key)) {
+ // // @ts-ignore
+ // if(this.__unserialization.indexOf(key) !== -1){
+ // continue;
+ // }
+ // // 判断编辑器版本
+ // if(this._version && !this._version[key][EditorVersion[config.editorVersion]]){
+ // continue;
+ // }
+ // const value = this[key];
+ // data[key] = value;
+ // }
+ // }
+ // return data;
+ // }
+ // }
+}
+
+export function cctype(type: string){
+ return (target: Function) => {
+ Object.defineProperty(target.prototype,"$__type__",{
+ value: type,
+ enumerable: true,
+ })
+ }
+}
+
+
+let _extends = {};
+let _class_attrs = {};
+let _target_map_ = {};
+let __verIdx = 0;
+
+let _printID = -1;
+
+function checkTag(target){
+ if(target.constructor.__ver_tag_id__ === undefined || _target_map_[target.constructor.__ver_tag_id__] != target){
+ target.constructor.__ver_tag_id__ = `${__verIdx}`;
+ _target_map_[target.constructor.__ver_tag_id__] = target;
+ __verIdx ++;
+ }
+ return target.constructor.__ver_tag_id__;
+}
+
+function _assign(target,source){
+ for (const key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ if(key in target){
+ continue;
+ }
+ target[key] = source[key];
+ }
+ }
+}
+function assign(target,... sources){
+ for (let i = 0; i < sources.length; i++) {
+ _assign(target,sources[i]);
+ }
+}
+
+export function ccversion(version: number){
+
+ return (target: any,propertyKey: string)=>{
+ let _class_name_ = target.constructor.name;
+
+ _class_name_ = checkTag(target);
+
+ !_class_attrs[_class_name_] && (_class_attrs[_class_name_] = {});
+
+ let _class_obj = _class_attrs[_class_name_];
+ if(!_class_obj[propertyKey]){
+ _class_obj[propertyKey] = {};
+ }
+
+ if(EditorVersion.all === version){
+ for (const key in EditorVersion) {
+ _class_obj[propertyKey][EditorVersion[key]] = true;
+ }
+ }else{
+ _class_obj[propertyKey][EditorVersion[version]] = true;
+ }
+
+ var base = getSuper(target.constructor);
+ // (base === Object || base === UIObject) && (base = null);
+ if(base){
+ let parent = checkTag(base.prototype);
+ !_extends[_class_name_] && (_extends[_class_name_] = parent);
+
+
+ var _super = getSuper(base);
+ let superIdx = 1;
+ while (_super) {
+ // if(_super === Object || _super === UIObject) {
+ // // _super = null;
+ // break;
+ // }
+ let super_tag = checkTag(_super.prototype);
+ !_extends[parent] && (_extends[parent] = super_tag);
+ _super = getSuper(_super);
+ superIdx++;
+ }
+
+ while (parent) {
+ if(parent in _class_attrs){
+ assign(_class_obj,_class_attrs[parent]);
+ }
+ parent = _extends[parent];
+ }
+ }
+ if(!target._version){
+ target._version = {};
+ }
+ target._version[_class_name_] = _class_attrs[_class_name_] = _class_obj;
+ }
+}
+
+function getSuper (ctor) {
+ var proto = ctor.prototype; // binded function do not have prototype
+ var dunderProto = proto && Object.getPrototypeOf(proto);
+ return dunderProto && dunderProto.constructor;
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/assets-manager/ImageCacheMgr.ts b/psd2ui-tools/src/assets-manager/ImageCacheMgr.ts
new file mode 100644
index 0000000..dcd4d53
--- /dev/null
+++ b/psd2ui-tools/src/assets-manager/ImageCacheMgr.ts
@@ -0,0 +1,165 @@
+import fs from "fs-extra";
+import path from "path";
+import { config } from "../config";
+import { EditorVersion } from "../EditorVersion";
+import { fileUtils } from "../utils/FileUtils";
+
+export interface ImageWarp {
+ path?: string;
+ uuid: string;
+ textureUuid: string;
+ isOutput?: boolean
+}
+
+export class ImageCacheMgr {
+ private _imageMap: Map = new Map();
+ private _cachePath: string = null;
+
+ initWithPath(_path: string) {
+ if (!fs.existsSync(_path)) {
+ console.log(`ImageCacheMgr-> 文件不存在: ${_path}`);
+ return;
+ }
+ this._cachePath = _path;
+ let content = fs.readFileSync(_path, "utf-8");
+ this.initWithFile(content);
+ }
+ initWithFile(file: string) {
+ let json = JSON.parse(file);
+ this.initWithJson(json);
+ }
+ initWithJson(json: any) {
+ for (const key in json) {
+ if (Object.prototype.hasOwnProperty.call(json, key)) {
+ this._imageMap.set(key, json[key]);
+ }
+ }
+ }
+
+ set(md5: string, warp: ImageWarp) {
+ this._imageMap.set(md5, warp);
+ }
+
+ has(md5: string): boolean {
+ return this._imageMap.has(md5);
+ }
+
+ get(md5: string): ImageWarp {
+ return this._imageMap.get(md5);
+ }
+
+ async saveImageMap(_path?: string) {
+ if (!_path) {
+ _path = this._cachePath;
+ }
+ if (!_path) {
+ console.log(`ImageCacheMgr-> 缓存路径 [${_path}] 不存在,无法保存 `);
+ return;
+ }
+ let obj = Object.create(null);
+ this._imageMap.forEach((v, k) => {
+ obj[k] = v;
+ });
+ let content = JSON.stringify(obj, null, 2);
+ await fileUtils.writeFile(_path, content);
+ }
+
+
+ // 获取已存在的图片,生成 md5: uuid 映射,
+ loadImages(dir: string) {
+ if (this._imageMap.size > 0) {
+ console.error(`ImageCacheMgr-> 暂时只能在 启动时加载`);
+ return;
+ }
+
+ let pngs = fileUtils.filterFile(dir, (fileName) => {
+ let extname = path.extname(fileName);
+ if (extname == ".png") {
+ return true;
+ }
+ return false;
+ });
+
+ if(!pngs){
+ return;
+ }
+
+ for (let i = 0; i < pngs.length; i++) {
+ const png = pngs[i];
+ let md5 = fileUtils.getMD5(png);
+ console.log(`ImageCacheMgr->缓存 `, png);
+ let imageWarp = this._loadImageMetaWarp(`${png}.meta`);
+ if (imageWarp) {
+ this.set(md5, imageWarp);
+ }
+ }
+ }
+
+ private _loadImageMetaWarp(_path: string) {
+ let content = fs.readFileSync(_path, { encoding: "utf-8" });
+ let imageWarp: ImageWarp = null;
+ switch (config.editorVersion) {
+ case EditorVersion.v249:
+ imageWarp = this._loadImageMeta249(content, _path);
+ break;
+ case EditorVersion.v342:
+ imageWarp = this._loadImageMeta34x(content, _path);
+ break;
+
+ default:
+ console.log(`ImageCacheMgr-> 暂未实现 ${EditorVersion[config.editorVersion]} 版本`);
+
+ break;
+ }
+ return imageWarp;
+ }
+
+ private _loadImageMeta249(metaContent: any, _path: string) {
+ let filename = path.basename(_path, ".png.meta");
+ let fullpath = path.join(path.dirname(_path), `${filename}.png`);
+ let metaJson = JSON.parse(metaContent);
+
+ if (!metaJson?.subMetas?.[filename]) {
+ return null;
+ }
+ let imageWarp: ImageWarp = {
+ path: fullpath,
+ textureUuid: metaJson.subMetas[filename].uuid,
+ uuid: metaJson.uuid,
+ isOutput: true,
+ }
+
+ return imageWarp;
+ }
+ private _loadImageMeta34x(metaContent: any, _path: string) {
+ let filename = path.basename(_path, ".png.meta");
+ let fullpath = path.join(path.dirname(_path), `${filename}.png`);
+ let metaJson = JSON.parse(metaContent);
+
+ if (!metaJson?.subMetas?.["6c48a"]) {
+ return null;
+ }
+ let uuid = metaJson.subMetas["6c48a"].uuid.replace("@6c48a", "");
+ let imageWarp: ImageWarp = {
+ path: fullpath,
+ textureUuid: uuid,
+ uuid: uuid,
+ isOutput: true,
+ }
+
+ return imageWarp;
+ }
+
+
+
+
+ private static _instance: ImageCacheMgr = null
+ public static getInstance(): ImageCacheMgr {
+ if (!this._instance) {
+ this._instance = new ImageCacheMgr();
+ }
+ return this._instance;
+ }
+}
+
+export const imageCacheMgr = ImageCacheMgr.getInstance();
\ No newline at end of file
diff --git a/psd2ui-tools/src/assets-manager/ImageMgr.ts b/psd2ui-tools/src/assets-manager/ImageMgr.ts
new file mode 100644
index 0000000..d73c0ef
--- /dev/null
+++ b/psd2ui-tools/src/assets-manager/ImageMgr.ts
@@ -0,0 +1,59 @@
+import { PsdImage } from "../psd/PsdImage";
+
+class ImageMgr{
+ // 镜像图像管理
+ private _imageIdKeyMap: Map = new Map();
+
+ // 当前 psd 所有的图片
+ private _imageArray: Map = new Map();
+
+ add(psdImage: PsdImage){
+ // 不忽略导出图片
+ if(!psdImage.isIgnore() && !psdImage.isBind()){
+ if(!this._imageArray.has(psdImage.md5)){
+ this._imageArray.set(psdImage.md5,psdImage);
+ }
+ }
+
+ if(typeof psdImage.attr.comps.img?.id != "undefined"){
+ let id = psdImage.attr.comps.img.id;
+ if(this._imageIdKeyMap.has(id)){
+ console.warn(`ImageMgr-> ${psdImage.source.name} 已有相同 @img{id:${id}},请检查 psd 图层`);
+ }
+ this._imageIdKeyMap.set(id,psdImage);
+ }
+ }
+
+ getAllImage(){
+ return this._imageArray;
+ }
+
+ /** 尝试获取有编号的图像图层 */
+ getSerialNumberImage(psdImage: PsdImage){
+ let bind = psdImage.attr.comps.flip?.bind ?? psdImage.attr.comps.img?.bind;
+ if(typeof bind != 'undefined'){
+ if(this._imageIdKeyMap.has(bind)){
+ return this._imageIdKeyMap.get(bind)
+ }else{
+ console.warn(`ImageMgr-> ${psdImage.source.name} 未找到绑定的图像 {${bind}},请检查 psd 图层`);
+
+ }
+ }
+ return psdImage;
+ }
+
+ clear(){
+ this._imageIdKeyMap.clear();
+ this._imageArray.clear()
+ }
+
+ private static _instance:ImageMgr = null
+ public static getInstance(): ImageMgr{
+ if(!this._instance){
+ this._instance = new ImageMgr();
+ }
+ return this._instance;
+ }
+}
+
+export const imageMgr = ImageMgr.getInstance();
\ No newline at end of file
diff --git a/psd2ui-tools/src/config.ts b/psd2ui-tools/src/config.ts
new file mode 100644
index 0000000..2a35466
--- /dev/null
+++ b/psd2ui-tools/src/config.ts
@@ -0,0 +1,60 @@
+import { EditorVersion } from "./EditorVersion";
+import { CCButton } from "./engine/cc/CCButton";
+import { CCComponent } from "./engine/cc/CCComponent";
+import { CCProgressBar } from "./engine/cc/CCProgressBar";
+import { CCToggle } from "./engine/cc/CCToggle";
+
+export class Config {
+
+
+ readonly help = `
+--help | 帮助信息
+--init | 初始化缓存文件 必须设置 --project-assets --cache 两项
+--force-img | 强制导出图片 即使在有缓存的情况下也要导出
+--input | 输入目录或者 psd 文件 非 init 时 必选 [dir or psd]
+--output | 输出目录 可选 缺省时为 --input [dir]
+--engine-version | 引擎版本 可选 [v249 | v342]
+--project-assets | 指定项目文件夹 可选 [dir]
+--cache-remake | 重新创建缓存文件 可选
+--cache | 缓存文件全路径 可选 [file-full-path]
+--config | 预制体配置 可选 [file-full-path]
+--pinyin | 中文转拼音 可选
+--img-only | 只导出图片 可选
+--json | json 对象参数 插件工具使用 将所有参数用对象的形式编码成 base64 字符串
+`
+
+ editorVersion: EditorVersion = EditorVersion.v249;
+
+ DEFAULT_SPRITE_FRAME_MATERIAL = {
+ [EditorVersion.v249]: "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432",
+ [EditorVersion.v342]: "",
+ }
+
+ DEFAULT_LABEL_MATERIAL = {
+ [EditorVersion.v249]: "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432",
+ [EditorVersion.v342]: "",
+ }
+ get SpriteFrame_Material() {
+ return this.DEFAULT_SPRITE_FRAME_MATERIAL[config.editorVersion];
+ }
+ get Label_Material() {
+ return this.DEFAULT_LABEL_MATERIAL[config.editorVersion];
+ }
+
+ CompMappings: Record = {
+ "Btn": CCButton,
+ "ProgressBar": CCProgressBar,
+ "Toggle": CCToggle,
+ }
+
+ // text 文本 Y 偏移
+ textOffsetY = {
+ default: 0,
+ "36": 0,
+ }
+
+ // text 文本 行高偏移,默认为 0 ,行高默认为 字体大小
+ textLineHeightOffset = 0;
+}
+
+export const config = new Config();
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/UIObject.ts b/psd2ui-tools/src/engine/UIObject.ts
new file mode 100644
index 0000000..83cf514
--- /dev/null
+++ b/psd2ui-tools/src/engine/UIObject.ts
@@ -0,0 +1,44 @@
+import { config } from "../config";
+import { EditorVersion } from "../EditorVersion";
+import { utils } from "../utils/Utils";
+import { nonserialization } from "../_decorator";
+
+export class UIObject{
+
+ @nonserialization
+ uuid: string = "";
+
+ @nonserialization
+ idx: number = 0;
+
+ constructor(){
+ this.uuid = utils.uuid();
+ }
+
+ toJSON(){
+ let data:Record = {};
+ for (const key in this) {
+ if (Object.prototype.hasOwnProperty.call(this, key)) {
+ // @ts-ignore
+ if(this.__unserialization && this.__unserialization.indexOf(key) !== -1){
+ continue;
+ }
+ // @ts-ignore
+ let ver_tag = this.constructor.__ver_tag_id__;
+
+ // 判断编辑器版本
+ // @ts-ignore
+ if(this._version && this._version[ver_tag]?.[key]){
+ // @ts-ignore
+ if(!this._version[ver_tag][key][EditorVersion[config.editorVersion]]){
+ continue;
+ }
+ }
+
+ const value = this[key];
+ data[key] = value;
+ }
+ }
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCButton.ts b/psd2ui-tools/src/engine/cc/CCButton.ts
new file mode 100644
index 0000000..cb35cec
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCButton.ts
@@ -0,0 +1,54 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCIDObject } from "./CCObject";
+
+@cctype("cc.Button")
+export class CCButton extends CCComponent{
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ duration: number = 0.1;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ zoomScale: number = 1.2;
+
+ @ccversion(EditorVersion.all)
+ clickEvents = [];
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$interactable: boolean = true;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$enableAutoGrayEffect: boolean = false;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$transition: number = 3;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ transition: number = 3;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$target: CCIDObject = null;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _interactable = true;
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _transition = 3;
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _duration = 0.1;
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _zoomScale = 1.2;
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _target: CCIDObject = null;
+
+ updateWithLayer(psdLayer: PsdLayer) {
+
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCCompPrefabInfo.ts b/psd2ui-tools/src/engine/cc/CCCompPrefabInfo.ts
new file mode 100644
index 0000000..fd1bb70
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCCompPrefabInfo.ts
@@ -0,0 +1,16 @@
+import { utils } from "../../utils/Utils";
+import { cctype, nonserialization } from "../../_decorator";
+import { UIObject } from "../UIObject";
+import { CCIDObject } from "./CCObject";
+
+// @cctype("cc.CompPrefabInfo")
+export class CCCompPrefabInfo extends UIObject{
+
+ __type__: string = "cc.CompPrefabInfo";
+ fileId: string = "";
+
+ constructor(){
+ super();
+ this.fileId = utils.compressUuid(this.uuid);
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCComponent.ts b/psd2ui-tools/src/engine/cc/CCComponent.ts
new file mode 100644
index 0000000..f10f88e
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCComponent.ts
@@ -0,0 +1,22 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { ccversion, nonserialization } from "../../_decorator";
+import { CCIDObject, CCObject } from "./CCObject";
+
+export abstract class CCComponent extends CCObject{
+
+ @ccversion(EditorVersion.all)
+ _enabled: boolean = true;
+
+ @ccversion(EditorVersion.all)
+ node: CCIDObject = null;
+
+ @ccversion(EditorVersion.all)
+ _id: string = "";
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ __prefab: CCIDObject = null;
+
+ abstract updateWithLayer(psdLayer: PsdLayer);
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCLabel.ts b/psd2ui-tools/src/engine/cc/CCLabel.ts
new file mode 100644
index 0000000..cc0c9ec
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCLabel.ts
@@ -0,0 +1,112 @@
+import { config } from "../../config";
+import { EditorVersion } from "../../EditorVersion";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { PsdText } from "../../psd/PsdText";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCUUIDObject } from "./CCObject";
+import { CCColor } from "./values/CCColor";
+
+@cctype("cc.Label")
+export class CCLabel extends CCComponent{
+
+ @ccversion(EditorVersion.all)
+ _srcBlendFactor: number = 770; // 3.4.x = 2
+ @ccversion(EditorVersion.all)
+ _dstBlendFactor: number = 771; // 3.4.x = 4
+ @ccversion(EditorVersion.all)
+ _string: string = "";
+ @ccversion(EditorVersion.all)
+ _fontSize: number = 0;
+ @ccversion(EditorVersion.all)
+ _lineHeight: number = 0;
+ @ccversion(EditorVersion.all)
+ _enableWrapText: boolean = true;
+ @ccversion(EditorVersion.all)
+ _isSystemFontUsed: boolean = true;
+ @ccversion(EditorVersion.all)
+ _spacingX: number = 0;
+ @ccversion(EditorVersion.all)
+ _underlineHeight: number = 0;
+
+ @ccversion(EditorVersion.v249)
+ _materials: CCUUIDObject[] = [];
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$string: string = "";
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$file: any = null;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _batchAsBitmap: boolean = false;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _styleFlags: number = 0;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$horizontalAlign: number = 1;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$verticalAlign: number = 1;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$fontFamily: string = "Arial";
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$overflow: number = 0;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$cacheMode: number = 0;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _visFlags: number = 0;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _customMaterial: any = null;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _color: CCColor = new CCColor(255,255,255,255);
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _overflow: number = 0;
+
+ // // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _cacheMode = 0;
+
+ @ccversion(EditorVersion.v342)
+ _horizontalAlign = 1;
+
+ @ccversion(EditorVersion.v342)
+ _verticalAlign = 1;
+
+ @ccversion(EditorVersion.v342)
+ _actualFontSize = 0;
+
+ @ccversion(EditorVersion.v342)
+ _isItalic = false;
+
+ @ccversion(EditorVersion.v342)
+ _isBold = false;
+
+ @ccversion(EditorVersion.v342)
+ _isUnderline = false;
+
+ updateWithLayer(psdLayer: PsdText) {
+ this._fontSize = psdLayer.fontSize;
+ // this._actualFontSize = this._fontSize;
+ this._string = this._N$string = psdLayer.text;
+
+ this._lineHeight = this._fontSize + config.textLineHeightOffset;
+
+ if(config.editorVersion >= EditorVersion.v342){
+ this._srcBlendFactor = 2;
+ this._dstBlendFactor = 4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCLabelOutline.ts b/psd2ui-tools/src/engine/cc/CCLabelOutline.ts
new file mode 100644
index 0000000..3337acb
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCLabelOutline.ts
@@ -0,0 +1,22 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdText } from "../../psd/PsdText";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCUUIDObject } from "./CCObject";
+import { CCColor } from "./values/CCColor";
+
+@cctype("cc.LabelOutline")
+export class CCLabelOutline extends CCComponent{
+
+ @ccversion(EditorVersion.all)
+ _color: CCColor = new CCColor(255,255,255,255);
+ @ccversion(EditorVersion.all)
+ _width: number = 1;
+
+
+ updateWithLayer(psdLayer: PsdText) {
+
+ this._width = psdLayer.outline.width;
+ this._color.set(psdLayer.outline.color);
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCNode.ts b/psd2ui-tools/src/engine/cc/CCNode.ts
new file mode 100644
index 0000000..3daefdf
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCNode.ts
@@ -0,0 +1,147 @@
+import { config } from "../../config";
+import { EditorVersion } from "../../EditorVersion";
+import { PsdDocument } from "../../psd/PsdDocument";
+import { cctype, ccversion, nonserialization } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCCompPrefabInfo } from "./CCCompPrefabInfo";
+import { CCIDObject, CCObject } from "./CCObject";
+import { CCColor } from "./values/CCColor";
+import { CCSize } from "./values/CCSize";
+import { CCTypedArray } from "./values/CCTypedArray";
+import { CCVec2 } from "./values/CCVec2";
+import { CCVec3 } from "./values/CCVec3";
+
+@cctype("cc.Node")
+export class CCNode extends CCObject{
+
+ @ccversion(EditorVersion.all)
+ _parent: CCIDObject = null;
+
+ @ccversion(EditorVersion.all)
+ _children: CCIDObject[] = [];
+
+ @ccversion(EditorVersion.all)
+ _active: boolean = true;
+
+ @ccversion(EditorVersion.all)
+ _components: CCIDObject[] = [];
+
+ @ccversion(EditorVersion.all)
+ _prefab: CCIDObject = null;
+
+ @ccversion(EditorVersion.all)
+ _id: string = "";
+
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _opacity: number = 255;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _color: CCColor = new CCColor(255,255,255,255);
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _contentSize: CCSize = new CCSize();
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _anchorPoint: CCVec2 = new CCVec2(0,0);
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _trs: CCTypedArray = new CCTypedArray();
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _eulerAngles: CCVec3 = new CCVec3();
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _skewX: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _skewY: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _is3DNode: boolean = false;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _groupIndex: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ groupIndex: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _renderEnable: boolean = false;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _bfsRenderFlag: boolean = false;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _lpos: CCVec3 = new CCVec3();
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _lrot: CCVec3 = new CCVec3();
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _lscale: CCVec3 = new CCVec3();
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _euler: CCVec3 = new CCVec3();
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _layer: number = 33554432;
+
+
+ @nonserialization
+ psdDoc: PsdDocument = null;
+
+ @nonserialization
+ components: CCComponent[] = [];
+
+ @nonserialization
+ children: CCNode[] = [];
+
+ constructor(psdDoc: PsdDocument){
+ super();
+ if(psdDoc){
+ this.psdDoc = psdDoc;
+ psdDoc.pushObject(this);
+ }
+ }
+
+
+ addComponent(comp: CCComponent){
+ comp.node = {__id__: this.idx }
+ let compIdx = this.psdDoc.pushObject(comp);
+ this._components.push({ __id__: compIdx});
+ this.components.push(comp);
+
+ if(config.editorVersion >= EditorVersion.v342){
+ this.addCompPrefabInfo(comp)
+ }
+ }
+
+ addCompPrefabInfo(comp: CCComponent){
+ let compInfo = new CCCompPrefabInfo();
+ let compIdx = this.psdDoc.pushObject(compInfo);
+ comp.__prefab = {__id__: compIdx }
+ }
+
+ addChild(child: CCNode){
+ this._children.push({ __id__: child.idx});
+ child._parent = { __id__: this.idx };
+ this.children.push(child);
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCObject.ts b/psd2ui-tools/src/engine/cc/CCObject.ts
new file mode 100644
index 0000000..2c5038e
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCObject.ts
@@ -0,0 +1,29 @@
+import { EditorVersion } from "../../EditorVersion";
+import { utils } from "../../utils/Utils";
+import { ccversion, nonserialization } from "../../_decorator";
+import { UIObject } from "../UIObject";
+
+export type CCIDObject = { __id__: number };
+export type CCUUIDObject = { __uuid__: string, __expectedType__?: string};
+
+
+
+export class CCObject extends UIObject{
+
+ @ccversion(EditorVersion.all)
+ __type__: string;
+
+ @ccversion(EditorVersion.all)
+ _name: string = "";
+
+ @ccversion(EditorVersion.all)
+ _objFlags: number = 0;
+
+ constructor(){
+ super();
+
+ // @ts-ignore
+ this.__type__ = this.$__type__
+
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCPrefab.ts b/psd2ui-tools/src/engine/cc/CCPrefab.ts
new file mode 100644
index 0000000..e2a8f1c
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCPrefab.ts
@@ -0,0 +1,26 @@
+import { EditorVersion } from "../../EditorVersion";
+import { cctype, ccversion } from "../../_decorator";
+import { CCIDObject, CCObject } from "./CCObject";
+
+@cctype("cc.Prefab")
+export class CCPrefab extends CCObject{
+
+ @ccversion(EditorVersion.all)
+ _native: string = "";
+ @ccversion(EditorVersion.all)
+ data: CCIDObject = null;
+
+ @ccversion(EditorVersion.all)
+ optimizationPolicy: number = 0;
+ @ccversion(EditorVersion.all)
+ asyncLoadAssets: boolean = false;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ readonly: boolean = false;
+
+ // // 3.4.x
+ @ccversion(EditorVersion.v342)
+ persistent: boolean = false;
+
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCPrefabInfo.ts b/psd2ui-tools/src/engine/cc/CCPrefabInfo.ts
new file mode 100644
index 0000000..3ee209d
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCPrefabInfo.ts
@@ -0,0 +1,30 @@
+import { EditorVersion } from "../../EditorVersion";
+import { utils } from "../../utils/Utils";
+import { cctype, ccversion, nonserialization } from "../../_decorator";
+import { UIObject } from "../UIObject";
+import { CCIDObject } from "./CCObject";
+
+// @cctype("cc.PrefabInfo")
+export class CCPrefabInfo extends UIObject{
+
+ @ccversion(EditorVersion.all)
+ __type__: string = "cc.PrefabInfo";
+
+
+ @ccversion(EditorVersion.all)
+ root: CCIDObject = { __id__: 1 };
+
+ @ccversion(EditorVersion.all)
+ asset: CCIDObject = { __id__: 0};
+
+ @ccversion(EditorVersion.all)
+ fileId: string = "";
+
+ @ccversion(EditorVersion.all)
+ sync: boolean = false;
+
+ constructor(){
+ super();
+ this.fileId = utils.compressUuid(this.uuid);
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCProgressBar.ts b/psd2ui-tools/src/engine/cc/CCProgressBar.ts
new file mode 100644
index 0000000..ccf0ea0
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCProgressBar.ts
@@ -0,0 +1,86 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdGroup } from "../../psd/PsdGroup";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCNode } from "./CCNode";
+import { CCIDObject } from "./CCObject";
+import { CCSprite } from "./CCSprite";
+
+@cctype("cc.ProgressBar")
+export class CCProgressBar extends CCComponent{
+
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$totalLength: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$barSprite: CCIDObject = null;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$mode: number = 0;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$progress: number = 1;
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$reverse: boolean = false;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _barSprite: CCIDObject = null;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _mode = 0;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _totalLength = 0;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _progress = 1;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _reverse = false;
+
+
+ setBar(sprite: CCSprite){
+ this._barSprite = this._N$barSprite = {
+ __id__: sprite.idx
+ }
+ }
+
+ updateWithLayer(psdLayer: PsdGroup) {
+ if(!psdLayer.children){
+ console.error(`CCProgressBar-> 只能作用在 组图层 上`);
+ return;
+ }
+
+ outer: for (let i = 0; i < psdLayer.children.length; i++) {
+ const child = psdLayer.children[i];
+ if(child.attr.comps.bar){
+ let node = child.uiObject as CCNode;
+
+ // 暂时只有横向进度条
+ this._totalLength = this._N$totalLength = node._contentSize.width;
+
+ for (let j = 0; j < node.components.length; j++) {
+ const comp = node.components[j];
+ if(comp instanceof CCSprite){
+ this.setBar(comp);
+ break outer;
+ }
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCSprite.ts b/psd2ui-tools/src/engine/cc/CCSprite.ts
new file mode 100644
index 0000000..92a37f1
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCSprite.ts
@@ -0,0 +1,93 @@
+import { config } from "../../config";
+import { EditorVersion } from "../../EditorVersion";
+import { PsdImage } from "../../psd/PsdImage";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCIDObject, CCUUIDObject } from "./CCObject";
+import { CCColor } from "./values/CCColor";
+import { CCVec2 } from "./values/CCVec2";
+
+@cctype("cc.Sprite")
+export class CCSprite extends CCComponent {
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _materials: CCUUIDObject[] = [];
+
+ @ccversion(EditorVersion.all)
+ _srcBlendFactor: number = 770; // 3.4.x = 2
+
+ @ccversion(EditorVersion.all)
+ _dstBlendFactor: number = 771; // 3.4.x = 4
+
+ @ccversion(EditorVersion.all)
+ _spriteFrame: CCUUIDObject = null;
+
+ @ccversion(EditorVersion.all)
+ _type: number = 0;
+
+ @ccversion(EditorVersion.all)
+ _sizeMode: number = 1;
+
+ @ccversion(EditorVersion.all)
+ _fillType: number = 0;
+
+ @ccversion(EditorVersion.all)
+ _fillCenter: CCVec2 = new CCVec2();
+
+ @ccversion(EditorVersion.all)
+ _fillStart: number = 0;
+
+ @ccversion(EditorVersion.all)
+ _fillRange: number = 0;
+
+ @ccversion(EditorVersion.all)
+ _isTrimmedMode: boolean = true;
+
+ @ccversion(EditorVersion.all)
+ _atlas = null;
+
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _visFlags: number = 0;
+
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _customMaterial: any = null;
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _color: CCColor = new CCColor(255,255,255,255);
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _useGrayscale: boolean = false;
+
+ use9() {
+ this._type = 1;
+ this._sizeMode = 0;
+ }
+
+ updateWithLayer(psdLayer: PsdImage) {
+ if (psdLayer.s9) {
+ this.use9();
+ }
+ if (Math.abs(psdLayer.scale.x) != 1 || Math.abs(psdLayer.scale.y) != 1) {
+ this._sizeMode = 0;
+ }
+
+ if(config.editorVersion >= EditorVersion.v342){
+ this._srcBlendFactor = 2;
+ this._dstBlendFactor = 4;
+ }
+ }
+
+ setSpriteFrame(uuid: string){
+ if(config.editorVersion >= EditorVersion.v342){
+ this._spriteFrame = {__uuid__: `${uuid}@f9941`,__expectedType__ : "cc.SpriteFrame"};
+ }else{
+ this._spriteFrame = {__uuid__: uuid};
+ }
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCToggle.ts b/psd2ui-tools/src/engine/cc/CCToggle.ts
new file mode 100644
index 0000000..99cd261
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCToggle.ts
@@ -0,0 +1,62 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdGroup } from "../../psd/PsdGroup";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { cctype, ccversion } from "../../_decorator";
+import { CCButton } from "./CCButton";
+import { CCComponent } from "./CCComponent";
+import { CCNode } from "./CCNode";
+import { CCIDObject } from "./CCObject";
+import { CCSprite } from "./CCSprite";
+
+@cctype("cc.Toggle")
+export class CCToggle extends CCButton{
+
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ _N$isChecked = true;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ toggleGroup = null;
+ // 2.4.x
+ @ccversion(EditorVersion.v249)
+ checkMark: CCIDObject = null;
+ @ccversion(EditorVersion.all)
+ checkEvents = [];
+
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _isChecked = true;
+ // 3.4.x
+ @ccversion(EditorVersion.v342)
+ _checkMark: CCIDObject = null;
+
+ setCheckMark(sprite: CCSprite){
+ this._checkMark = this.checkMark = {
+ __id__: sprite.idx
+ }
+ }
+
+
+ updateWithLayer(psdLayer: PsdGroup) {
+ if(!psdLayer.children){
+ console.error(`CCToggle-> 只能作用在 组图层 上`);
+ return;
+ }
+
+ outer: for (let i = 0; i < psdLayer.children.length; i++) {
+ const child = psdLayer.children[i];
+ if(child.attr.comps.check){
+ let node = child.uiObject as CCNode;
+ for (let j = 0; j < node.components.length; j++) {
+ const comp = node.components[j];
+ if(comp instanceof CCSprite){
+
+ this.setCheckMark(comp);
+ break outer;
+ }
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCUIOpacity.ts b/psd2ui-tools/src/engine/cc/CCUIOpacity.ts
new file mode 100644
index 0000000..2487c0b
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCUIOpacity.ts
@@ -0,0 +1,15 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+
+// 3.4.x
+@cctype("cc.UIOpacity")
+export class CCUIOpacity extends CCComponent{
+
+ @ccversion(EditorVersion.v342)
+ _opacity = 255;
+
+ updateWithLayer(psdLayer: PsdLayer) {
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/CCUITransform.ts b/psd2ui-tools/src/engine/cc/CCUITransform.ts
new file mode 100644
index 0000000..d67c81a
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/CCUITransform.ts
@@ -0,0 +1,22 @@
+import { EditorVersion } from "../../EditorVersion";
+import { PsdLayer } from "../../psd/PsdLayer";
+import { cctype, ccversion } from "../../_decorator";
+import { CCComponent } from "./CCComponent";
+import { CCIDObject, CCObject } from "./CCObject";
+import { CCSize } from "./values/CCSize";
+import { CCVec2 } from "./values/CCVec2";
+
+// 3.4.x
+
+@cctype("cc.UITransform")
+export class CCUITransform extends CCComponent{
+
+ @ccversion(EditorVersion.v342)
+ _contentSize: CCSize = new CCSize();
+
+ @ccversion(EditorVersion.v342)
+ _anchorPoint: CCVec2 = new CCVec2(0,0);
+
+ updateWithLayer(psdLayer: PsdLayer) {
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/values/CCColor.ts b/psd2ui-tools/src/engine/cc/values/CCColor.ts
new file mode 100644
index 0000000..3856876
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/values/CCColor.ts
@@ -0,0 +1,7 @@
+import { Color } from "../../../values/Color";
+import { cctype } from "../../../_decorator";
+
+export class CCColor extends Color{
+
+ __type__: string = "cc.Color";
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/values/CCSize.ts b/psd2ui-tools/src/engine/cc/values/CCSize.ts
new file mode 100644
index 0000000..fd5ff8b
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/values/CCSize.ts
@@ -0,0 +1,8 @@
+import { Size } from "../../../values/Size";
+import { cctype } from "../../../_decorator";
+
+@cctype("cc.Size")
+export class CCSize extends Size{
+
+ __type__: string = "cc.Size";
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/values/CCTypedArray.ts b/psd2ui-tools/src/engine/cc/values/CCTypedArray.ts
new file mode 100644
index 0000000..bd9e220
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/values/CCTypedArray.ts
@@ -0,0 +1,28 @@
+import { cctype } from "../../../_decorator";
+import { CCVec3 } from "./CCVec3";
+
+@cctype("TypedArray")
+export class CCTypedArray{
+
+ __type__: string = "TypedArray";
+ ctor: string = "Float64Array";
+ array: number [] = [];
+
+ setPosition(x: number,y: number,z: number){
+ this.array[0] = x;
+ this.array[1] = y;
+ this.array[2] = z;
+ }
+
+ setRotation(x: number,y: number,z: number,w: number){
+ this.array[3] = x;
+ this.array[4] = y;
+ this.array[5] = z;
+ this.array[6] = w;
+ }
+ setScale(x: number,y: number,z: number){
+ this.array[7] = x;
+ this.array[8] = y;
+ this.array[9] = z;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/values/CCVec2.ts b/psd2ui-tools/src/engine/cc/values/CCVec2.ts
new file mode 100644
index 0000000..95503c6
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/values/CCVec2.ts
@@ -0,0 +1,8 @@
+import { Vec2 } from "../../../values/Vec2";
+import { cctype } from "../../../_decorator";
+
+@cctype("cc.Vec2")
+export class CCVec2 extends Vec2{
+
+ __type__: string = "cc.Vec2";
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/engine/cc/values/CCVec3.ts b/psd2ui-tools/src/engine/cc/values/CCVec3.ts
new file mode 100644
index 0000000..f8dac7e
--- /dev/null
+++ b/psd2ui-tools/src/engine/cc/values/CCVec3.ts
@@ -0,0 +1,8 @@
+import { Vec3 } from "../../../values/Vec3";
+import { cctype } from "../../../_decorator";
+
+
+
+export class CCVec3 extends Vec3{
+ __type__: string = "cc.Vec3";
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/export.ts b/psd2ui-tools/src/export.ts
new file mode 100644
index 0000000..1771a9e
--- /dev/null
+++ b/psd2ui-tools/src/export.ts
@@ -0,0 +1,2 @@
+
+export * from './index'
\ No newline at end of file
diff --git a/psd2ui-tools/src/index.ts b/psd2ui-tools/src/index.ts
new file mode 100644
index 0000000..59b6f23
--- /dev/null
+++ b/psd2ui-tools/src/index.ts
@@ -0,0 +1,20 @@
+
+import minimist from 'minimist';
+import { Main } from './Main';
+import { Texture9Utils } from './utils/Texture9Utils';
+// ##################
+
+// 输入
+
+const oldArgs = process.argv.slice(2);
+const args = minimist(oldArgs);
+
+let main = new Main();
+if (oldArgs.length) {
+ main.exec(args);
+} else {
+ // 测试
+ main.test();
+}
+
+// ##################
diff --git a/psd2ui-tools/src/psd/LayerType.ts b/psd2ui-tools/src/psd/LayerType.ts
new file mode 100644
index 0000000..d21d92a
--- /dev/null
+++ b/psd2ui-tools/src/psd/LayerType.ts
@@ -0,0 +1,6 @@
+export enum LayerType{
+ Doc,
+ Group,
+ Text,
+ Image
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/psd/PsdDocument.ts b/psd2ui-tools/src/psd/PsdDocument.ts
new file mode 100644
index 0000000..ab63e1a
--- /dev/null
+++ b/psd2ui-tools/src/psd/PsdDocument.ts
@@ -0,0 +1,46 @@
+import { UIObject } from "../engine/UIObject";
+import { Rect } from "../values/Rect";
+import { Size } from "../values/Size";
+import { PsdGroup } from "./PsdGroup";
+
+export class PsdDocument extends PsdGroup{
+
+ /** 当前文档所有的图片 */
+ images: Map = new Map();
+
+ objectMap: Map = new Map();
+
+ objectArray: UIObject[] = [];
+
+ constructor(source: any){
+ super(source,null,null);
+ this.size = new Size(source.width,source.height);
+ this.rect = new Rect(0, this.size.width, 0, this.size.height);
+ }
+
+ pushObject(uiObject: UIObject){
+ let idx = this.objectArray.length;
+ uiObject.idx = idx;
+ this.objectMap.set(uiObject.uuid,idx);
+ this.objectArray.push(uiObject);
+ return idx;
+ }
+
+ getObjectIdx(uuid: string){
+ let idx = this.objectMap.get(uuid);
+ return idx;
+ }
+ getObject(uuid: string){
+ let idx = this.objectMap.get(uuid);
+ if(idx < this.objectArray.length){
+ return this.objectArray[idx];
+ }
+ return null;
+ }
+
+ onCtor(): void {
+ super.onCtor();
+
+ }
+
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/psd/PsdGroup.ts b/psd2ui-tools/src/psd/PsdGroup.ts
new file mode 100644
index 0000000..df3ac2c
--- /dev/null
+++ b/psd2ui-tools/src/psd/PsdGroup.ts
@@ -0,0 +1,49 @@
+import { Rect } from "../values/Rect";
+import { PsdLayer } from "./PsdLayer";
+
+export class PsdGroup extends PsdLayer {
+ declare children: PsdLayer[];
+ declare parent: PsdGroup;
+
+
+ constructor(source: any, parent: PsdLayer, rootDoc: PsdLayer) {
+ super(source, parent, rootDoc);
+ this.children = [];
+ if (rootDoc) {
+ this.rect = new Rect(0, rootDoc.size.width, 0, rootDoc.size.height);
+ }
+ }
+ parseSource(): boolean {
+ super.parseSource();
+
+ if(!this.attr?.comps.full){
+ this.resize();
+ this.computeBasePosition();
+ }
+ return true;
+ }
+
+ resize() {
+ let left = Number.MAX_SAFE_INTEGER;
+ let right = Number.MIN_SAFE_INTEGER;
+ let top = Number.MAX_SAFE_INTEGER;
+ let bottom = Number.MIN_SAFE_INTEGER;
+
+ for (let i = 0; i < this.children.length; i++) {
+ const element = this.children[i];
+ let _rect = element.rect;
+ left = Math.min(_rect.left, left);
+ right = Math.max(_rect.right, right);
+ top = Math.min(_rect.top, top);
+ bottom = Math.max(_rect.bottom, bottom);
+ }
+ this.rect.left = left;
+ this.rect.right = right;
+ this.rect.top = top;
+ this.rect.bottom = bottom;
+ }
+
+ onCtor() {
+
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/psd/PsdImage.ts b/psd2ui-tools/src/psd/PsdImage.ts
new file mode 100644
index 0000000..fb910cc
--- /dev/null
+++ b/psd2ui-tools/src/psd/PsdImage.ts
@@ -0,0 +1,98 @@
+import { PsdGroup } from "./PsdGroup";
+import { PsdLayer } from "./PsdLayer";
+import { utils } from "../utils/Utils";
+import canvas from 'canvas';
+import { Border, Texture9Utils } from "../utils/Texture9Utils";
+import { Size } from "../values/Size";
+import { fileUtils } from "../utils/FileUtils";
+import { Vec3 } from "../values/Vec3";
+
+export class PsdImage extends PsdLayer {
+ declare parent: PsdGroup;
+
+ declare textureUuid: string;
+
+ declare md5: string;
+ declare imgBuffer: Buffer;
+
+ declare textureSize: Size;
+
+ declare imgName: string;
+
+
+ declare s9: Border;
+
+ constructor(source: any, parent: PsdLayer, rootDoc: PsdLayer) {
+ super(source, parent, rootDoc);
+ this.textureUuid = utils.uuid();
+
+ // img name
+ this.imgName = this.attr.comps.img?.name || this.name
+
+ // .9
+ if (this.attr.comps['.9']) {
+ let s9 = this.attr.comps['.9'];
+ this.s9 = Texture9Utils.safeBorder(this.source.canvas, s9 as any);
+ let newCanvas = Texture9Utils.split(this.source.canvas, s9 as any);
+ this.source.canvas = newCanvas;
+ }
+ let canvas: canvas.Canvas = this.source.canvas;
+
+ this.imgBuffer = canvas.toBuffer('image/png');
+ this.md5 = fileUtils.getMD5(this.imgBuffer);
+
+ this.textureSize = new Size(canvas.width, canvas.height);
+ this.scale = new Vec3((this.isFilpX() ? -1 : 1) * this.scale.x, (this.isFilpY() ? -1 : 1) * this.scale.y, 1);
+ }
+
+ onCtor() {
+
+ }
+
+ isIgnore() {
+ //
+ if (this.attr.comps.ignore || this.attr.comps.ignoreimg) {
+ return true;
+ }
+ return false;
+ }
+
+ /** 是否是镜像图片 */
+ isBind() {
+ return typeof this.attr.comps.flip?.bind !== 'undefined'
+ || typeof this.attr.comps.img?.bind !== 'undefined';
+ }
+
+ /** 是否是 x 方向镜像图片 */
+ isFilpX() {
+ return typeof this.attr.comps.flipX?.bind !== 'undefined';
+ }
+
+ /** 是否是 y 方向镜像图片 */
+ isFilpY() {
+ return typeof this.attr.comps.flipY?.bind !== 'undefined';
+ }
+
+ // 根据锚点计算坐标
+ updatePositionWithAR() {
+ if (!this.parent) {
+ return;
+ }
+
+ let parent = this.parent;
+ while (parent) {
+ this.position.x -= parent.position.x;
+ this.position.y -= parent.position.y;
+ parent = parent.parent;
+ }
+
+ // this.position.x = this.position.x - this.parent.size.width * this.parent.anchorPoint.x + this.size.width * this.anchorPoint.x;
+ // this.position.y = this.position.y - this.parent.size.height * this.parent.anchorPoint.y + this.size.height * this.anchorPoint.y;
+ // 如果是镜像图片,则特殊处理
+ let arX = (this.isFilpX() ? (1 - this.anchorPoint.x) : this.anchorPoint.x);
+ let arY = (this.isFilpY() ? (1 - this.anchorPoint.y) : this.anchorPoint.y);
+ this.position.x = this.position.x - this.rootDoc.size.width * this.rootDoc.anchorPoint.x + this.size.width * arX;
+ this.position.y = this.position.y - this.rootDoc.size.height * this.rootDoc.anchorPoint.y + this.size.height * arY;
+ }
+
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/psd/PsdLayer.ts b/psd2ui-tools/src/psd/PsdLayer.ts
new file mode 100644
index 0000000..263b4fc
--- /dev/null
+++ b/psd2ui-tools/src/psd/PsdLayer.ts
@@ -0,0 +1,298 @@
+import { PsdLayerSource } from "../_declare";
+import { LayerType } from "./LayerType";
+import { Size } from "../values/Size";
+import { Vec2 } from "../values/Vec2";
+import { utils } from "../utils/Utils";
+import { UIObject } from "../engine/UIObject";
+import { Rect } from "../values/Rect";
+import { Color } from "../values/Color";
+import { Vec3 } from "../values/Vec3";
+import { pinyin } from "pinyin-pro";
+
+/**
+ * 命名规则
+ * "name@Type{prop: 1,prop2: 2}"
+ * Type = btn | bar | (toggle @check) | .9 |
+ *
+ */
+
+export interface PsdAttr {
+ name: string,
+ comps: {
+ Btn?: {};
+ btn?: {};
+ ProgressBar?: {};
+ progressBar?: {};
+ bar?: {};
+ Toggle?: {};
+ toggle?: {};
+ check?: {};
+ ".9"?: { l?: number, r?: number, b?: number, t?: number };
+ ar?: { x?: number, y?: number };
+ // 忽略导出节点和图片
+ ignore?: {};
+ ig?: {};
+ // 忽略导出节点
+ ignorenode?: {};
+ ignode?: {};
+ // 忽略导出图片
+ ignoreimg?: {};
+ igimg?: {};
+
+ full?: {};
+ size?: { w?: number, h?: number };
+ scale?: { x?: number, y?: number };
+ img?: { id?: number, name?: string, bind?: number }
+ flip?: { bind: number, x?: number, y?: number }
+ flipX?: { bind: number }
+ flipY?: { bind: number }
+ // position?:{x?: number,y?: number};
+ // pos?:{x?: number,y?: number};
+ }
+}
+
+export abstract class PsdLayer {
+
+ static isPinyin = false;
+
+ declare uuid: string;
+ declare rootDoc: PsdLayer;
+ declare name: string;
+ declare source: PsdLayerSource;
+ declare parent: PsdLayer;
+ declare position: Vec2;
+ declare size: Size;
+ declare rect: Rect;
+ declare anchorPoint: Vec2;
+ declare hidden: boolean;
+ declare opacity: number;
+ declare layerType: LayerType;
+ declare uiObject: UIObject;
+ declare attr: PsdAttr; // 解析名字获得各项属性
+ declare color: Color;
+ declare scale: Vec3;
+
+ constructor(source: any, parent: PsdLayer, rootDoc: PsdLayer) {
+ this.uuid = utils.uuid();
+ this.source = source;
+ this.parent = parent;
+ this.rootDoc = rootDoc;
+ this.name = source.name;
+ this.position = new Vec2();
+ this.size = new Size();
+ this.rect = new Rect(source);
+ // this.anchorPoint = new Vec2();
+ this.anchorPoint = new Vec2(0.5, 0.5);
+ this.hidden = false;
+ this.opacity = 255;
+ this.color = new Color(255, 255, 255, 255);
+ console.log(`PsdLayer->解析到图层 `, this.name);
+
+ this.attr = this.parseNameRule(this.name);
+ // // 更新名字
+ this.name = this.chineseToPinyin(this.attr?.name || this.name);
+
+ // 使用配置的缩放系数
+ let _scale = this.attr?.comps.scale;
+ this.scale = new Vec3(_scale?.x ?? 1, _scale?.y ?? 1, 1);
+ }
+
+ abstract onCtor();
+
+
+ parseNameRule(name: string) {
+ if (!name) {
+ return;
+ }
+ name = name.trim();
+ let fragments = name.split("@");
+ if (fragments.length === 0) {
+ console.error(`PsdLayer-> 名字解析错误`);
+ return;
+ }
+ let obj: PsdAttr = {
+ name: fragments[0]?.replace(/\.|>|\/|\ /g, "_") ?? "unknow",
+ comps: {},
+ }
+ for (let i = 1; i < fragments.length; i++) {
+ const fragment = fragments[i].trim();
+ let attr = {};
+ let startIdx = fragment.indexOf("{");
+ let comp = fragment;
+ if (startIdx != -1) {
+
+ let endIdx = fragment.indexOf("}");
+ if (endIdx == -1) {
+ console.log(`PsdLayer->${name} 属性 解析错误`);
+ continue;
+ }
+ let attrStr = fragment.substring(startIdx + 1, endIdx);
+ comp = fragment.substr(0, startIdx);
+ attrStr = attrStr.trim();
+ let attrs = attrStr.split(",");
+ attrs.forEach((str) => {
+ str = str.trim();
+ let strs = str.split(":");
+ if (!strs.length) {
+ console.log(`PsdLayer->${name} 属性 解析错误`);
+ return;
+ }
+ strs.map((v) => {
+ return v.trim();
+ });
+ attr[strs[0]] = utils.isNumber(strs[1]) ? parseFloat(strs[1]) : strs[1];
+ });
+ }
+ comp = comp.trim();
+ comp = comp.replace(":", ""); // 防呆,删除 key 中的冒号,
+ obj.comps[comp] = attr;
+ }
+
+ // 获取别名的值
+ obj.comps.ignore = obj.comps.ignore || obj.comps.ig;
+ obj.comps.ignorenode = obj.comps.ignorenode || obj.comps.ignode;
+ obj.comps.ignoreimg = obj.comps.ignoreimg || obj.comps.igimg;
+ obj.comps.Btn = obj.comps.Btn || obj.comps.btn;
+ obj.comps.ProgressBar = obj.comps.ProgressBar || obj.comps.progressBar;
+ obj.comps.Toggle = obj.comps.Toggle || obj.comps.toggle;
+
+ // 图片名中文转拼音
+ if (obj.comps.img) {
+ if (obj.comps.img.name) {
+ obj.comps.img.name = this.chineseToPinyin(obj.comps.img.name);
+ }
+ }
+
+ // 将mirror filpX filpY 进行合并
+ if (obj.comps.flip || obj.comps.flipX || obj.comps.flipY) {
+ obj.comps.flip = Object.assign({}, obj.comps.flip, obj.comps.flipX, obj.comps.flipY);
+
+ if (obj.comps.flipX) {
+ obj.comps.flip.x = 1;
+ }
+
+ if (obj.comps.flipY) {
+ obj.comps.flip.y = 1;
+ }
+
+ // x,y 都缺省时,默认 x 方向镜像
+ if (typeof obj.comps.flip.bind !== 'undefined') {
+ if (!obj.comps.flip.y) {
+ obj.comps.flip.x = 1;
+ }
+
+ // 只有作为镜像图片使用的时候才反向赋值
+ // 反向赋值,防止使用的时候值错误
+ if (obj.comps.flip.x) {
+ obj.comps.flipX = Object.assign({}, obj.comps.flipX, obj.comps.flip);
+ }
+
+ if (obj.comps.flip.y) {
+ obj.comps.flipY = Object.assign({}, obj.comps.flipY, obj.comps.flip);
+ }
+ }
+
+ }
+
+
+ // 检查冲突
+ if (obj.comps.full && obj.comps.size) {
+ console.warn(`PsdLayer->${obj.name} 同时存在 @full 和 @size`);
+ }
+
+ return obj;
+ }
+
+ /** 解析数据 */
+ parseSource() {
+ let _source = this.source;
+
+
+ // psd文档
+ if (!this.parent) {
+ return false;
+ }
+ this.hidden = _source.hidden;
+ this.opacity = Math.round(_source.opacity * 255);
+
+ // 获取锚点
+ let ar = this.attr.comps.ar;
+ if (ar) {
+ this.anchorPoint.x = ar.x ?? this.anchorPoint.x;
+ this.anchorPoint.y = ar.y ?? this.anchorPoint.y;
+ }
+
+ this.computeBasePosition();
+ return true;
+ }
+ /** 解析 effect */
+ parseEffects() {
+ // 颜色叠加 暂时搞不定
+ // if(this.source.effects?.solidFill){
+ // let solidFills = this.source.effects?.solidFill;
+ // for (let i = 0; i < solidFills.length; i++) {
+ // const solidFill = solidFills[i];
+ // if(solidFill.enabled){
+ // let color = solidFill.color;
+ // this.color = new Color(color.r,color.g,color.b,solidFill.opacity * 255);
+ // }
+ // }
+ // }
+ }
+
+ /** 中文转拼音 */
+ chineseToPinyin(text: string) {
+ if (!text || !PsdLayer.isPinyin) {
+ return text;
+ }
+ let names = pinyin(text, {
+ toneType: "none",
+ type: "array"
+ });
+
+ names = names.map((text) => {
+ return text.slice(0, 1).toUpperCase() + text.slice(1).toLowerCase();
+ });
+ return names.join("");
+ }
+
+ // 计算初始坐标 左下角 0,0 为锚点
+ computeBasePosition() {
+ if (!this.rootDoc) {
+ return;
+ }
+ let _rect = this.rect;
+ let width = (_rect.right - _rect.left);
+ let height = (_rect.bottom - _rect.top);
+
+ this.size.width = width;
+ this.size.height = height;
+
+ // 位置 左下角为锚点
+ let x = _rect.left;
+ let y = (this.rootDoc.size.height - _rect.bottom);
+
+ this.position.x = x;
+ this.position.y = y;
+ }
+
+ // 根据锚点计算坐标
+ updatePositionWithAR() {
+ if (!this.parent) {
+ return;
+ }
+
+ let parent = this.parent;
+ while (parent) {
+ this.position.x -= parent.position.x;
+ this.position.y -= parent.position.y;
+ parent = parent.parent;
+ }
+
+ // this.position.x = this.position.x - this.parent.size.width * this.parent.anchorPoint.x + this.size.width * this.anchorPoint.x;
+ // this.position.y = this.position.y - this.parent.size.height * this.parent.anchorPoint.y + this.size.height * this.anchorPoint.y;
+ this.position.x = this.position.x - this.rootDoc.size.width * this.rootDoc.anchorPoint.x + this.size.width * this.anchorPoint.x;
+ this.position.y = this.position.y - this.rootDoc.size.height * this.rootDoc.anchorPoint.y + this.size.height * this.anchorPoint.y;
+ }
+
+}
diff --git a/psd2ui-tools/src/psd/PsdText.ts b/psd2ui-tools/src/psd/PsdText.ts
new file mode 100644
index 0000000..3d84f68
--- /dev/null
+++ b/psd2ui-tools/src/psd/PsdText.ts
@@ -0,0 +1,67 @@
+
+import { config } from "../config";
+import { Color } from "../values/Color";
+import { Vec2 } from "../values/Vec2";
+import { PsdGroup } from "./PsdGroup";
+import { PsdLayer } from "./PsdLayer";
+
+export class PsdText extends PsdLayer{
+ declare parent: PsdGroup;
+ declare text: string;
+ declare fontSize: number;
+ declare font: string;
+ declare outline: { width: number, color: Color }; // 描边
+ declare offsetY: number;
+
+
+ parseSource(): boolean {
+ super.parseSource();
+ let textSource = this.source.text;
+ let style = textSource.style;
+ if(style){
+ let fillColor = style.fillColor;
+ if(fillColor){
+ this.color = new Color(fillColor.r,fillColor.g,fillColor.b,fillColor.a * 255);
+ }
+ }
+ this.text = textSource.text;
+ this.fontSize = style.fontSize;
+
+ this.offsetY = config.textOffsetY[this.fontSize] || config.textOffsetY["default"] || 0;
+
+ this.parseSolidFill();
+ this.parseStroke();
+ return true;
+ }
+ onCtor(){
+
+ }
+
+ /** 描边 */
+ parseStroke(){
+ if(this.source.effects?.stroke){
+ let stroke = this.source.effects?.stroke[0];
+ // 外描边
+ if(stroke?.enabled && stroke?.position === "outside"){
+ let color = stroke.color;
+ this.outline = {
+ width: stroke.size.value,
+ color: new Color(color.r,color.g,color.b,stroke.opacity * 255)
+ }
+ }
+ }
+ }
+ /** 解析 颜色叠加 */
+ parseSolidFill() {
+ if(this.source.effects?.solidFill){
+ let solidFills = this.source.effects?.solidFill;
+ for (let i = 0; i < solidFills.length; i++) {
+ const solidFill = solidFills[i];
+ if(solidFill.enabled){
+ let color = solidFill.color;
+ this.color = new Color(color.r,color.g,color.b,solidFill.opacity * 255);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/utils/FileUtils.ts b/psd2ui-tools/src/utils/FileUtils.ts
new file mode 100644
index 0000000..c625ad2
--- /dev/null
+++ b/psd2ui-tools/src/utils/FileUtils.ts
@@ -0,0 +1,114 @@
+
+import fs from 'fs-extra';
+import path from 'path';
+import crypto from "crypto";
+
+
+class FileUtils {
+
+ // 深度遍历
+ DFS(root: string, callback?: (options: {isDirectory: boolean,fullPath: string, fileName: string,depth: number}) => void,depth = 0) {
+ let exists = fs.existsSync(root);
+ if (!exists) {
+ console.log(`FileUtils-> ${root} is not exists`);
+ return;
+ }
+ let files = fs.readdirSync(root);
+ let _cacheDepth = depth;
+ depth ++;
+ files.forEach((file) => {
+ let fullPath = path.join(root, file);
+ let stat = fs.lstatSync(fullPath);
+ let isDirectory = stat.isDirectory();
+ callback?.({isDirectory,fullPath,fileName: file,depth: _cacheDepth});
+ if (!isDirectory) {
+
+ } else {
+ this.DFS(fullPath,callback,depth);
+ }
+ });
+ }
+
+ filterFile(root: string, filter?: (fileName: string) => boolean) {
+ let exists = fs.existsSync(root);
+ if (!exists) {
+ console.log(`FileUtils-> ${root} is not exists`);
+ return;
+ }
+ var res: string[] = [];
+ let files = fs.readdirSync(root);
+ files.forEach((file) => {
+ let pathName = path.join(root, file);
+ let stat = fs.lstatSync(pathName);
+ let isDirectory = stat.isDirectory();
+ // 只对文件进行判断
+ if(!isDirectory){
+ let isPass = filter(file);
+ if(!isPass){
+ return;
+ }
+ }
+ if (!isDirectory) {
+ res.push(pathName);
+ } else {
+ res = res.concat(this.filterFile(pathName,filter));
+ }
+ });
+ return res
+ }
+
+ getFolderFiles(dir: string,type: "folder" | "file"){
+ let exists = fs.existsSync(dir);
+ if (!exists) {
+ console.log(`FileUtils-> ${dir} is not exists`);
+ return;
+ }
+ let res: {fullPath: string,basename: string}[] = [];
+ let files = fs.readdirSync(dir);
+ files.forEach((file) => {
+ let fullPath = path.join(dir, file);
+ let stat = fs.lstatSync(fullPath);
+ let isDirectory = stat.isDirectory();
+ if (isDirectory) {
+ if(type === 'folder'){
+ res.push({fullPath,basename: file});
+ }
+ }else{
+ if(type === 'file'){
+ res.push({fullPath,basename: file});
+ }
+ }
+ });
+ return res;
+ }
+
+
+ async writeFile(fullPath: string, data: any) {
+ if(typeof data !== 'string'){
+ try {
+ data = JSON.stringify(data,null,2);
+ } catch (error) {
+ console.log(`FileUtils->writeFile `,error);
+ return;
+ }
+ }
+ console.log(`写入文件 ${fullPath}`);
+
+ let dir = path.dirname(fullPath);
+ await fs.mkdirp(dir);
+ await fs.writeFile(fullPath, data);
+
+ console.log(`写入完成 ${fullPath} `);
+ }
+
+ /** 获取文件的 md5 */
+ getMD5(buffer: Buffer | string){
+ if(typeof buffer === 'string'){
+ buffer = fs.readFileSync(buffer);
+ }
+ let md5 = crypto.createHash("md5").update(buffer).digest("hex");
+ return md5;
+ }
+}
+
+export let fileUtils = new FileUtils();
\ No newline at end of file
diff --git a/psd2ui-tools/src/utils/Texture9Utils.ts b/psd2ui-tools/src/utils/Texture9Utils.ts
new file mode 100644
index 0000000..be2fbe9
--- /dev/null
+++ b/psd2ui-tools/src/utils/Texture9Utils.ts
@@ -0,0 +1,60 @@
+
+import canvas from 'canvas';
+
+export interface Border {
+ l?: number;
+ r?: number;
+ t?: number;
+ b?: number;
+}
+
+export class Texture9Utils {
+
+ static safeBorder(_canvas: canvas.Canvas, border: Border) {
+
+ border.l = (border.l ?? border.r) || 0;
+ border.r = (border.r ?? border.l) || 0;
+ border.t = (border.t ?? border.b) || 0;
+ border.b = (border.b ?? border.t) || 0;
+ return border;
+ }
+ static split(_canvas: canvas.Canvas, border: Border): canvas.Canvas {
+ this.safeBorder(_canvas, border);
+ let cw = _canvas.width;
+ let ch = _canvas.height;
+ let space = 4;
+ let left = border.l || cw;
+ let right = border.r || cw;
+ let top = border.t || ch;
+ let bottom = border.b || ch;
+ if (border.b == 0 && border.t == 0 && border.l == 0 && border.r == 0) {
+ return _canvas;
+ }
+
+ if (border.l + border.r > cw + space) {
+ console.log(`Texture9Utils-> 设置的九宫格 left, right 数据不合理,请重新设置`);
+ return _canvas;
+ }
+ if (border.b + border.t > ch + space) {
+ console.log(`Texture9Utils-> 设置的九宫格 bottom, top 数据不合理,请重新设置`);
+ return _canvas;
+ }
+
+ let newCanvas = canvas.createCanvas(Math.min(cw, border.l + border.r + space) || cw, Math.min(ch, border.b + border.t + space) || ch);
+ let ctx = newCanvas.getContext("2d");
+
+ // 左上
+ ctx.drawImage(_canvas, 0, 0, left + space, top + space, 0, 0, left + space, top + space);
+
+ // 左下
+ ctx.drawImage(_canvas, 0, ch - bottom, left + space, bottom, 0, top + space, left + space, bottom);
+
+ // 右上
+ ctx.drawImage(_canvas, cw - left, 0, right, top + space, left + space, 0, right, top + space);
+
+ // 右下
+ ctx.drawImage(_canvas, cw - left, ch - bottom, right, bottom, left + space, top + space, right, bottom);
+
+ return newCanvas;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/utils/Utils.ts b/psd2ui-tools/src/utils/Utils.ts
new file mode 100644
index 0000000..46481b6
--- /dev/null
+++ b/psd2ui-tools/src/utils/Utils.ts
@@ -0,0 +1,98 @@
+import canvas from 'canvas';
+import { PsdLayer } from "../psd/PsdLayer";
+import fs from 'fs-extra';
+import path from 'path';
+import { PsdDocument } from '../psd/PsdDocument';
+import { PsdImage } from '../psd/PsdImage';
+
+// ------------decode-uuid
+const BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+const values = new Array(123); // max char code in base64Keys
+for (let i = 0; i < 123; ++i) { values[i] = 64; } // fill with placeholder('=') index
+for (let i = 0; i < 64; ++i) { values[BASE64_KEYS.charCodeAt(i)] = i; }
+
+// decoded value indexed by base64 char code
+const BASE64_VALUES = values;
+
+const HexChars = '0123456789abcdef'.split('');
+
+const _t = ['', '', '', ''];
+const UuidTemplate = _t.concat(_t, '-', _t, '-', _t, '-', _t, '-', _t, _t, _t);
+const Indices = UuidTemplate.map((x, i) => x === '-' ? NaN : i).filter(isFinite);
+
+
+let HexMap = {}
+{
+ for (let i = 0; i < HexChars.length; i++) {
+ let char = HexChars[i]
+ HexMap[char] = i
+ }
+}
+
+class Utils {
+
+
+ uuid() {
+ var d = new Date().getTime();
+ if (globalThis.performance && typeof globalThis.performance.now === "function") {
+ d += performance.now(); //use high-precision timer if available
+ }
+ var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (d + Math.random() * 16) % 16 | 0;
+ d = Math.floor(d / 16);
+ return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
+ });
+ return uuid;
+ }
+
+ decodeUuid(base64) {
+ const strs = base64.split('@');
+ const uuid = strs[0];
+ if (uuid.length !== 22) {
+ return base64;
+ }
+ UuidTemplate[0] = base64[0];
+ UuidTemplate[1] = base64[1];
+ for (let i = 2, j = 2; i < 22; i += 2) {
+ const lhs = BASE64_VALUES[base64.charCodeAt(i)];
+ const rhs = BASE64_VALUES[base64.charCodeAt(i + 1)];
+ UuidTemplate[Indices[j++]] = HexChars[lhs >> 2];
+ UuidTemplate[Indices[j++]] = HexChars[((lhs & 3) << 2) | rhs >> 4];
+ UuidTemplate[Indices[j++]] = HexChars[rhs & 0xF];
+ }
+ return base64.replace(uuid, UuidTemplate.join(''));
+ }
+ // 压缩uuid
+ compressUuid(fullUuid) {
+ const strs = fullUuid.split('@');
+ const uuid: string = strs[0];
+ if (uuid.length !== 36) {
+ return fullUuid;
+ }
+
+ let zipUuid = []
+ zipUuid[0] = uuid[0];
+ zipUuid[1] = uuid[1];
+ let cleanUuid = uuid.replace('-', '').replace('-', '').replace('-', '').replace('-', '')
+
+ for (let i = 2, j = 2; i < 32; i += 3) {
+
+ const left = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i))];
+ const mid = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i + 1))];
+ const right = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i + 2))];
+
+ zipUuid[j++] = BASE64_KEYS[(left << 2) + (mid >> 2)]
+ zipUuid[j++] = BASE64_KEYS[((mid & 3) << 4) + right]
+ }
+ return fullUuid.replace(uuid, zipUuid.join(''));
+ }
+
+
+ isNumber(val){
+ return (!isNaN(parseFloat(val)) && isFinite(val));
+ }
+}
+
+
+
+export const utils = new Utils();
\ No newline at end of file
diff --git a/psd2ui-tools/src/utils/UuidUtils.ts b/psd2ui-tools/src/utils/UuidUtils.ts
new file mode 100644
index 0000000..63e15ce
--- /dev/null
+++ b/psd2ui-tools/src/utils/UuidUtils.ts
@@ -0,0 +1,98 @@
+var Uuid = require('node-uuid');
+
+var Base64KeyChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+var AsciiTo64 = new Array(128);
+for (var i = 0; i < 128; ++i) { AsciiTo64[i] = 0; }
+for (i = 0; i < 64; ++i) { AsciiTo64[Base64KeyChars.charCodeAt(i)] = i; }
+
+var Reg_Dash = /-/g;
+var Reg_Uuid = /^[0-9a-fA-F-]{36}$/;
+var Reg_NormalizedUuid = /^[0-9a-fA-F]{32}$/;
+var Reg_CompressedUuid = /^[0-9a-zA-Z+/]{22,23}$/;
+
+export class UuidUtils {
+
+ // 加了这个标记后,字符串就不可能会是 uuid 了。
+ static NonUuidMark: '.'
+
+ // 压缩后的 uuid 可以减小保存时的尺寸,但不能做为文件名(因为无法区分大小写并且包含非法字符)。
+ // 默认将 uuid 的后面 27 位压缩成 18 位,前 5 位保留下来,方便调试。
+ // fc991dd7-0033-4b80-9d41-c8a86a702e59 -> fc9913XADNLgJ1ByKhqcC5Z
+ // 如果启用 min 则将 uuid 的后面 30 位压缩成 20 位,前 2 位保留不变。
+ // fc991dd7-0033-4b80-9d41-c8a86a702e59 -> fcmR3XADNLgJ1ByKhqcC5Z
+ /*
+ * @param {Boolean} [min=false]
+ */
+ static compressUuid (uuid, min) {
+ if (Reg_Uuid.test(uuid)) {
+ uuid = uuid.replace(Reg_Dash, '');
+ }
+ else if (!Reg_NormalizedUuid.test(uuid)) {
+ return uuid;
+ }
+ var reserved = (min === true) ? 2 : 5;
+ return UuidUtils.compressHex(uuid, reserved);
+ }
+
+ static compressHex (hexString, reservedHeadLength) {
+ var length = hexString.length;
+ var i;
+ if (typeof reservedHeadLength !== 'undefined') {
+ i = reservedHeadLength;
+ }
+ else {
+ i = length % 3;
+ }
+ var head = hexString.slice(0, i);
+ var base64Chars = [];
+ while (i < length) {
+ var hexVal1 = parseInt(hexString[i], 16);
+ var hexVal2 = parseInt(hexString[i + 1], 16);
+ var hexVal3 = parseInt(hexString[i + 2], 16);
+ base64Chars.push(Base64KeyChars[(hexVal1 << 2) | (hexVal2 >> 2)]);
+ base64Chars.push(Base64KeyChars[((hexVal2 & 3) << 4) | hexVal3]);
+ i += 3;
+ }
+ return head + base64Chars.join('');
+ }
+
+ static decompressUuid (str) {
+ if (str.length === 23) {
+ // decode base64
+ var hexChars = [];
+ for (var i = 5; i < 23; i += 2) {
+ var lhs = AsciiTo64[str.charCodeAt(i)];
+ var rhs = AsciiTo64[str.charCodeAt(i + 1)];
+ hexChars.push((lhs >> 2).toString(16));
+ hexChars.push((((lhs & 3) << 2) | rhs >> 4).toString(16));
+ hexChars.push((rhs & 0xF).toString(16));
+ }
+ //
+ str = str.slice(0, 5) + hexChars.join('');
+ }
+ else if (str.length === 22) {
+ // decode base64
+ var hexChars = [];
+ for (var i = 2; i < 22; i += 2) {
+ var lhs = AsciiTo64[str.charCodeAt(i)];
+ var rhs = AsciiTo64[str.charCodeAt(i + 1)];
+ hexChars.push((lhs >> 2).toString(16));
+ hexChars.push((((lhs & 3) << 2) | rhs >> 4).toString(16));
+ hexChars.push((rhs & 0xF).toString(16));
+ }
+ //
+ str = str.slice(0, 2) + hexChars.join('');
+ }
+ return [str.slice(0, 8), str.slice(8, 12), str.slice(12, 16), str.slice(16, 20), str.slice(20)].join('-');
+ }
+
+ static isUuid (str) {
+ return Reg_CompressedUuid.test(str) || Reg_NormalizedUuid.test(str) || Reg_Uuid.test(str);
+ }
+
+ static uuid () {
+ var uuid = Uuid.v4();
+ return UuidUtils.compressUuid(uuid, true);
+ }
+};
diff --git a/psd2ui-tools/src/values/Color.ts b/psd2ui-tools/src/values/Color.ts
new file mode 100644
index 0000000..e5e8ab8
--- /dev/null
+++ b/psd2ui-tools/src/values/Color.ts
@@ -0,0 +1,40 @@
+export class Color{
+ declare r: number;
+ declare g: number;
+ declare b: number;
+ declare a: number;
+ constructor(r: number,g: number,b: number,a: number){
+ this.r = Math.ceil(r || 0);
+ this.g = Math.ceil(g || 0);
+ this.b = Math.ceil(b || 0);
+ this.a = Math.ceil(a || 0);
+ }
+
+ set(color: Color){
+ this.r = Math.ceil(color.r || 0);
+ this.g = Math.ceil(color.g || 0);
+ this.b = Math.ceil(color.b || 0);
+ this.a = Math.ceil(color.a || 0);
+ }
+
+
+ public toHEX (fmt: '#rgb' | '#rrggbb' | '#rrggbbaa' = '#rrggbb') {
+ const prefix = '0';
+ // #rrggbb
+ const hex = [
+ (this.r < 16 ? prefix : '') + (this.r).toString(16),
+ (this.g < 16 ? prefix : '') + (this.g).toString(16),
+ (this.b < 16 ? prefix : '') + (this.b).toString(16),
+ ];
+ const i = -1;
+ if (fmt === '#rgb') {
+ hex[0] = hex[0][0];
+ hex[1] = hex[1][0];
+ hex[2] = hex[2][0];
+ } else if (fmt === '#rrggbbaa') {
+ hex.push((this.a < 16 ? prefix : '') + (this.a).toString(16));
+ }
+ return hex.join('');
+ }
+
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/values/Rect.ts b/psd2ui-tools/src/values/Rect.ts
new file mode 100644
index 0000000..62a338a
--- /dev/null
+++ b/psd2ui-tools/src/values/Rect.ts
@@ -0,0 +1,23 @@
+export class Rect{
+ declare left: number;
+ declare right: number;
+ declare top: number;
+ declare bottom: number;
+ constructor(left: number | Rect = 0,right = 0,top = 0,bottom = 0) {
+ if(typeof left == 'object'){
+ this.set(left);
+ return;
+ }
+ this.left = left || 0;
+ this.right = right || 0;
+ this.top = top || 0;
+ this.bottom = bottom || 0;
+ }
+
+ set(rect: Rect){
+ this.left = rect.left;
+ this.right = rect.right;
+ this.top = rect.top;
+ this.bottom = rect.bottom;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/values/Size.ts b/psd2ui-tools/src/values/Size.ts
new file mode 100644
index 0000000..f5303cb
--- /dev/null
+++ b/psd2ui-tools/src/values/Size.ts
@@ -0,0 +1,8 @@
+export class Size{
+ declare width: number;
+ declare height: number;
+ constructor(width: number = 0,height: number = 0) {
+ this.width = width || 0;
+ this.height = height || 0;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/values/Vec2.ts b/psd2ui-tools/src/values/Vec2.ts
new file mode 100644
index 0000000..dae37b6
--- /dev/null
+++ b/psd2ui-tools/src/values/Vec2.ts
@@ -0,0 +1,8 @@
+export class Vec2{
+ declare x: number;
+ declare y: number;
+ constructor(x: number = 0,y: number = 0) {
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/src/values/Vec3.ts b/psd2ui-tools/src/values/Vec3.ts
new file mode 100644
index 0000000..b7854a6
--- /dev/null
+++ b/psd2ui-tools/src/values/Vec3.ts
@@ -0,0 +1,10 @@
+export class Vec3{
+ declare x: number;
+ declare y: number;
+ declare z: number;
+ constructor(x: number = 0,y: number = 0,z: number = 0) {
+ this.x = x || 0;
+ this.y = y || 0;
+ this.z = z || 0;
+ }
+}
\ No newline at end of file
diff --git a/psd2ui-tools/test/_test.config.json b/psd2ui-tools/test/_test.config.json
new file mode 100644
index 0000000..454e40d
--- /dev/null
+++ b/psd2ui-tools/test/_test.config.json
@@ -0,0 +1,15 @@
+{
+ "cc.Label": {
+ "__type__": "e4f88adp3hERoJ48DZ2PSAl",
+ "_N$file":{
+ "__uuid__": "803c185c-9442-4b99-af1a-682f877539ab"
+ },
+ "_isSystemFontUsed": false,
+ "isFixNumber": true
+ },
+ "textOffsetY":{
+ "default": -3,
+ "36": -3
+ },
+ "textLineHeightOffset": 4
+}
\ No newline at end of file
diff --git a/psd2ui-tools/test/demo.psd b/psd2ui-tools/test/demo.psd
new file mode 100644
index 0000000..6102aeb
Binary files /dev/null and b/psd2ui-tools/test/demo.psd differ
diff --git a/psd2ui-tools/test/png9.psd b/psd2ui-tools/test/png9.psd
new file mode 100644
index 0000000..5f94ddb
Binary files /dev/null and b/psd2ui-tools/test/png9.psd differ
diff --git a/psd2ui-tools/tsconfig.json b/psd2ui-tools/tsconfig.json
new file mode 100644
index 0000000..2e34dd3
--- /dev/null
+++ b/psd2ui-tools/tsconfig.json
@@ -0,0 +1,104 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true,
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "ES2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "commonjs", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ "resolveJsonModule": true, /* Enable importing .json files. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ "declaration": false, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": false, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ },
+}