id-scanner-lib 1.3.3 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +324 -410
  2. package/dist/id-scanner-lib.esm.js +4826 -0
  3. package/dist/id-scanner-lib.esm.js.map +1 -0
  4. package/dist/id-scanner-lib.js +4858 -0
  5. package/dist/id-scanner-lib.js.map +1 -0
  6. package/dist/types/browser-image-compression.d.ts +19 -0
  7. package/dist/types/tesseract.d.ts +280 -0
  8. package/package.json +89 -78
  9. package/src/core/base-module.ts +78 -0
  10. package/src/core/camera-manager.ts +813 -0
  11. package/src/core/config.ts +305 -0
  12. package/src/core/errors.ts +174 -0
  13. package/src/core/event-emitter.test.ts +42 -0
  14. package/src/core/event-emitter.ts +110 -0
  15. package/src/core/loading-state.test.ts +67 -0
  16. package/src/core/loading-state.ts +156 -0
  17. package/src/core/logger.test.ts +49 -0
  18. package/src/core/logger.ts +549 -0
  19. package/src/core/module-manager.ts +163 -0
  20. package/src/core/plugin-manager.ts +429 -0
  21. package/src/core/resource-manager.ts +762 -0
  22. package/src/core/result.ts +163 -0
  23. package/src/core/scanner-factory.ts +236 -0
  24. package/src/index.ts +117 -939
  25. package/src/interfaces/external-types.ts +200 -0
  26. package/src/interfaces/face-detection.ts +309 -0
  27. package/src/interfaces/scanner-module.ts +384 -0
  28. package/src/modules/face/face-detector.ts +988 -0
  29. package/src/modules/face/index.ts +208 -0
  30. package/src/modules/face/liveness-detector.ts +908 -0
  31. package/src/modules/face/types.ts +133 -0
  32. package/src/{id-recognition → modules/id-card}/anti-fake-detector.ts +274 -240
  33. package/src/modules/id-card/id-card-detector.ts +474 -0
  34. package/src/modules/id-card/index.ts +425 -0
  35. package/src/{id-recognition → modules/id-card}/ocr-processor.ts +149 -92
  36. package/src/modules/id-card/ocr-worker.ts +259 -0
  37. package/src/modules/id-card/types.ts +178 -0
  38. package/src/modules/qrcode/index.ts +175 -0
  39. package/src/modules/qrcode/qr-code-scanner.ts +231 -0
  40. package/src/modules/qrcode/types.ts +169 -0
  41. package/src/types/common.test.ts +99 -0
  42. package/src/types/common.ts +166 -0
  43. package/src/types/tesseract.d.ts +265 -22
  44. package/src/utils/camera.test.ts +30 -0
  45. package/src/utils/camera.ts +4 -1
  46. package/src/utils/error-handler.test.ts +137 -0
  47. package/src/utils/error-handler.ts +110 -0
  48. package/src/utils/image-processing.ts +68 -49
  49. package/src/utils/index.test.ts +186 -0
  50. package/src/utils/index.ts +429 -0
  51. package/src/utils/performance.ts +168 -131
  52. package/src/utils/resource-manager.ts +65 -146
  53. package/src/utils/retry.test.ts +142 -0
  54. package/src/utils/retry.ts +282 -0
  55. package/src/utils/types.ts +90 -2
  56. package/src/utils/utils.test.ts +171 -0
  57. package/src/utils/worker.ts +123 -84
  58. package/src/version.ts +11 -0
  59. package/tools/scaffold.js +543 -0
  60. package/dist/id-scanner-core.esm.js +0 -11349
  61. package/dist/id-scanner-core.js +0 -11361
  62. package/dist/id-scanner-core.min.js +0 -1
  63. package/dist/id-scanner-ocr.esm.js +0 -2319
  64. package/dist/id-scanner-ocr.js +0 -2328
  65. package/dist/id-scanner-ocr.min.js +0 -1
  66. package/dist/id-scanner-qr.esm.js +0 -1296
  67. package/dist/id-scanner-qr.js +0 -1305
  68. package/dist/id-scanner-qr.min.js +0 -1
  69. package/dist/id-scanner.js +0 -4561
  70. package/dist/id-scanner.min.js +0 -1
  71. package/src/core.ts +0 -138
  72. package/src/demo/demo.ts +0 -204
  73. package/src/id-recognition/data-extractor.ts +0 -262
  74. package/src/id-recognition/id-detector.ts +0 -510
  75. package/src/id-recognition/ocr-worker.ts +0 -156
  76. package/src/index-umd.ts +0 -477
  77. package/src/ocr-module.ts +0 -187
  78. package/src/qr-module.ts +0 -179
  79. package/src/scanner/barcode-scanner.ts +0 -251
  80. package/src/scanner/qr-scanner.ts +0 -167
@@ -1 +0,0 @@
1
- var global,factory;global=this,factory=function(t,r,n){"use strict";class e{constructor(t={}){this.options=t,this.stream=null,this.videoElement=null,this.options={width:640,height:480,facingMode:"environment",...t}}async start(t){return this.initialize(t)}stop(){this.release()}async initialize(t){this.videoElement=t;try{const t={video:{width:{ideal:this.options.width},height:{ideal:this.options.height},facingMode:this.options.facingMode}};this.stream=await navigator.mediaDevices.getUserMedia(t),this.videoElement&&(this.videoElement.srcObject=this.stream,await new Promise((t=>{this.videoElement&&(this.videoElement.onloadedmetadata=()=>{this.videoElement&&this.videoElement.play().then((()=>t()))})})))}catch(t){throw Error("无法访问摄像头。请确保已授予摄像头访问权限,并且摄像头未被其他应用程序占用。")}}captureFrame(){if(!this.videoElement)return null;const t=document.createElement("canvas");t.width=this.videoElement.videoWidth,t.height=this.videoElement.videoHeight;const r=t.getContext("2d");return r?(r.drawImage(this.videoElement,0,0,t.width,t.height),r.getImageData(0,0,t.width,t.height)):null}release(){this.stream&&(this.stream.getTracks().forEach((t=>t.stop())),this.stream=null),this.videoElement&&(this.videoElement.srcObject=null,this.videoElement=null)}}class i{constructor(t={}){this.options=t,this.scanning=!1,this.scanTimer=null,this.options={scanInterval:200,...t},this.camera=new e}async start(t){try{await this.camera.initialize(t),this.scanning=!0,this.scan()}catch(t){this.options.onError&&this.options.onError(t instanceof Error?t:Error(t+""))}}scan(){if(!this.scanning)return;const t=this.camera.captureFrame();if(t){const r=n(t.data,t.width,t.height);r&&this.options.onScan&&this.options.onScan(r.data)}this.scanTimer=window.setTimeout((()=>this.scan()),this.options.scanInterval)}stop(){this.scanning=!1,this.scanTimer&&(clearTimeout(this.scanTimer),this.scanTimer=null),this.camera.release()}processImageData(t){try{if(!t||!t.data||t.width<=0||t.height<=0)throw Error("无效的图像数据");const r=n(t.data,t.width,t.height);return r&&r.data?r.data:null}catch(t){return this.options.onError&&this.options.onError(t instanceof Error?t:Error(t+"")),null}}}function s(t,r){return new Promise((function(n,e){let i;return o(t).then((function(t){try{return i=t,n(new Blob([r.slice(0,2),i,r.slice(2)],{type:"image/jpeg"}))}catch(t){return e(t)}}),e)}))}const o=t=>new Promise(((r,n)=>{const e=new FileReader;e.addEventListener("load",(({target:{result:t}})=>{const e=new DataView(t);let i=0;if(65496!==e.getUint16(i))return n("not a valid JPEG");for(i+=2;;){const s=e.getUint16(i);if(65498===s)break;const o=e.getUint16(i+2);if(65505===s&&1165519206===e.getUint32(i+4)){const s=i+10;let a;switch(e.getUint16(s)){case 18761:a=!0;break;case 19789:a=!1;break;default:return n("TIFF header contains invalid endian")}if(42!==e.getUint16(s+2,a))return n("TIFF header contains invalid version");const c=e.getUint32(s+4,a),h=s+c+2+12*e.getUint16(s+c,a);for(let t=s+c+2;t<h;t+=12)if(274==e.getUint16(t,a)){if(3!==e.getUint16(t+2,a))return n("Orientation data type is invalid");if(1!==e.getUint32(t+4,a))return n("Orientation data count is invalid");e.setUint16(t+8,1,a);break}return r(t.slice(i,i+2+o))}i+=2+o}return r(new Blob)})),e.readAsArrayBuffer(t)}));var a={},c={get exports(){return a},set exports(t){a=t}};!function(){var t,r,n={};c.exports=n,n.parse=function(t,r){for(var e=n.bin.readUshort,i=n.bin.readUint,s=0,o={},a=new Uint8Array(t),c=a.length-4;101010256!=i(a,c);)c--;s=c,s+=4;var h=e(a,s+=4);e(a,s+=2);var f=i(a,s+=2),l=i(a,s+=4);s+=4,s=l;for(var u=0;u<h;u++){i(a,s),s+=4,s+=4,s+=4,i(a,s+=4),f=i(a,s+=4);var d=i(a,s+=4),w=e(a,s+=4),m=e(a,s+2),y=e(a,s+4);s+=6;var v=i(a,s+=8);s+=4,s+=w+m+y,n.o(a,v,o,f,d,r)}return o},n.o=function(t,r,e,i,s,o){var a=n.bin.readUshort,c=n.bin.readUint;c(t,r),a(t,r+=4),a(t,r+=2);var h=a(t,r+=2);c(t,r+=2),c(t,r+=4),r+=4;var f=a(t,r+=8),l=a(t,r+=2);r+=2;var u=n.bin.readUTF8(t,r,f);if(r+=f,r+=l,o)e[u]={size:s,csize:i};else{var d=new Uint8Array(t.buffer,r);if(0==h)e[u]=new Uint8Array(d.buffer.slice(r,r+i));else{if(8!=h)throw"unknown compression method: "+h;var w=new Uint8Array(s);n.inflateRaw(d,w),e[u]=w}}},n.inflateRaw=function(t,r){return n.F.inflate(t,r)},n.inflate=function(t,r){return n.inflateRaw(new Uint8Array(t.buffer,t.byteOffset+2,t.length-6),r)},n.deflate=function(t,r){null==r&&(r={level:6});var e=0,i=new Uint8Array(50+Math.floor(1.1*t.length));i[e]=120,i[e+1]=156,e+=2,e=n.F.deflateRaw(t,i,e,r.level);var s=n.adler(t,0,t.length);return i[e+0]=s>>>24&255,i[e+1]=s>>>16&255,i[e+2]=s>>>8&255,i[e+3]=s>>>0&255,new Uint8Array(i.buffer,0,e+4)},n.deflateRaw=function(t,r){null==r&&(r={level:6});var e=new Uint8Array(50+Math.floor(1.1*t.length)),i=n.F.deflateRaw(t,e,i,r.level);return new Uint8Array(e.buffer,0,i)},n.encode=function(t,r){null==r&&(r=!1);var e=0,i=n.bin.writeUint,s=n.bin.writeUshort,o={};for(var a in t){var c=!n.B(a)&&!r,h=t[a],f=n.crc.crc(h,0,h.length);o[a]={cpr:c,usize:h.length,crc:f,file:c?n.deflateRaw(h):h}}for(var a in o)e+=o[a].file.length+30+46+2*n.bin.sizeUTF8(a);e+=22;var l=new Uint8Array(e),u=0,d=[];for(var a in o){var w=o[a];d.push(u),u=n.P(l,u,a,w,0)}var m=0,y=u;for(var a in o)w=o[a],d.push(u),u=n.P(l,u,a,w,1,d[m++]);var v=u-y;return i(l,u,101010256),u+=4,s(l,u+=4,m),s(l,u+=2,m),i(l,u+=2,v),i(l,u+=4,y),u+=4,u+=2,l.buffer},n.B=function(t){var r=t.split(".").pop().toLowerCase();return-1!="png,jpg,jpeg,zip".indexOf(r)},n.P=function(t,r,e,i,s,o){var a=n.bin.writeUint,c=n.bin.writeUshort,h=i.file;return a(t,r,0==s?67324752:33639248),r+=4,1==s&&(r+=2),c(t,r,20),c(t,r+=2,0),c(t,r+=2,i.cpr?8:0),a(t,r+=2,0),a(t,r+=4,i.crc),a(t,r+=4,h.length),a(t,r+=4,i.usize),c(t,r+=4,n.bin.sizeUTF8(e)),c(t,r+=2,0),r+=2,1==s&&(r+=2,r+=2,a(t,r+=6,o),r+=4),r+=n.bin.writeUTF8(t,r,e),0==s&&(t.set(h,r),r+=h.length),r},n.crc={table:function(){for(var t=new Uint32Array(256),r=0;r<256;r++){for(var n=r,e=0;e<8;e++)1&n?n=3988292384^n>>>1:n>>>=1;t[r]=n}return t}(),update:function(t,r,e,i){for(var s=0;s<i;s++)t=n.crc.table[255&(t^r[e+s])]^t>>>8;return t},crc:function(t,r,e){return 4294967295^n.crc.update(4294967295,t,r,e)}},n.adler=function(t,r,n){for(var e=1,i=0,s=r,o=r+n;s<o;){for(var a=Math.min(s+5552,o);s<a;)i+=e+=t[s++];e%=65521,i%=65521}return i<<16|e},n.bin={readUshort:function(t,r){return t[r]|t[r+1]<<8},writeUshort:function(t,r,n){t[r]=255&n,t[r+1]=n>>8&255},readUint:function(t,r){return 16777216*t[r+3]+(t[r+2]<<16|t[r+1]<<8|t[r])},writeUint:function(t,r,n){t[r]=255&n,t[r+1]=n>>8&255,t[r+2]=n>>16&255,t[r+3]=n>>24&255},readASCII:function(t,r,n){for(var e="",i=0;i<n;i++)e+=String.fromCharCode(t[r+i]);return e},writeASCII:function(t,r,n){for(var e=0;e<n.length;e++)t[r+e]=n.charCodeAt(e)},pad:function(t){return t.length<2?"0"+t:t},readUTF8:function(t,r,e){for(var i,s="",o=0;o<e;o++)s+="%"+n.bin.pad(t[r+o].toString(16));try{i=decodeURIComponent(s)}catch(i){return n.bin.readASCII(t,r,e)}return i},writeUTF8:function(t,r,n){for(var e=n.length,i=0,s=0;s<e;s++){var o=n.charCodeAt(s);if(4294967168&o)if(4294965248&o)if(4294901760&o){if(4292870144&o)throw"e";t[r+i]=240|o>>18,t[r+i+1]=128|o>>12&63,t[r+i+2]=128|o>>6&63,t[r+i+3]=128|63&o,i+=4}else t[r+i]=224|o>>12,t[r+i+1]=128|o>>6&63,t[r+i+2]=128|63&o,i+=3;else t[r+i]=192|o>>6,t[r+i+1]=128|63&o,i+=2;else t[r+i]=o,i++}return i},sizeUTF8:function(t){for(var r=t.length,n=0,e=0;e<r;e++){var i=t.charCodeAt(e);if(4294967168&i)if(4294965248&i)if(4294901760&i){if(4292870144&i)throw"e";n+=4}else n+=3;else n+=2;else n++}return n}},n.F={},n.F.deflateRaw=function(t,r,e,i){var s=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],o=n.F.U,a=n.F.O,c=n.F._,h=0,f=e<<3,l=0,u=t.length;if(0==i){for(;h<u;)c(r,f,h+(b=Math.min(65535,u-h))==u?1:0),f=n.F.G(t,h,b,r,f+8),h+=b;return f>>>3}var d=o.lits,w=o.strt,m=o.prev,y=0,v=0,A=0,g=0,p=0,E=0;for(u>2&&(w[E=n.F.tt(t,0)]=0),h=0;h<u;h++){if(p=E,h+1<u-2){E=n.F.tt(t,h+1);var M=h+1&32767;m[M]=w[E],w[E]=M}if(l<=h){(y>14e3||v>26697)&&u-h>100&&(l<h&&(d[y]=h-l,y+=2,l=h),f=n.F.rt(h==u-1||l==u?1:0,d,y,g,t,A,h-A,r,f),y=v=g=0,A=h);var I=0;h<u-2&&(I=n.F.nt(t,h,m,p,Math.min(s[2],u-h),s[3]));var b=I>>>16,C=65535&I;if(0!=I){C=65535&I;var U=a(b=I>>>16,o.of0);o.lhst[257+U]++;var B=a(C,o.df0);o.dhst[B]++,g+=o.exb[U]+o.dxb[B],d[y]=b<<23|h-l,d[y+1]=C<<16|U<<8|B,y+=2,l=h+b}else o.lhst[t[h]]++;v++}}for(A==h&&0!=t.length||(l<h&&(d[y]=h-l,y+=2,l=h),f=n.F.rt(1,d,y,g,t,A,h-A,r,f),y=0,v=0,y=v=g=0,A=h);7&f;)f++;return f>>>3},n.F.nt=function(t,r,e,i,s,o){var a=32767&r,c=e[a],h=a-c+32768&32767;if(c==a||i!=n.F.tt(t,r-h))return 0;for(var f=0,l=0,u=Math.min(32767,r);h<=u&&0!=--o&&c!=a;){if(0==f||t[r+f]==t[r+f-h]){var d=n.F.et(t,r,h);if(d>f){if(l=h,(f=d)>=s)break;h+2<d&&(d=h+2);for(var w=0,m=0;m<d-2;m++){var y=r-h+m+32768&32767,v=y-e[y]+32768&32767;v>w&&(w=v,c=y)}}}h+=(a=c)-(c=e[a])+32768&32767}return f<<16|l},n.F.et=function(t,r,n){if(t[r]!=t[r-n]||t[r+1]!=t[r+1-n]||t[r+2]!=t[r+2-n])return 0;var e=r,i=Math.min(t.length,r+258);for(r+=3;r<i&&t[r]==t[r-n];)r++;return r-e},n.F.tt=function(t,r){return(t[r]<<8|t[r+1])+(t[r+2]<<4)&65535},n.saved=0,n.F.rt=function(t,r,e,i,s,o,a,c,h){var f,l,u,d,w,m,y,v,A,g=n.F.U,p=n.F.it,E=n.F._;g.lhst[256]++,l=(f=n.F.getTrees())[0],u=f[1],d=f[2],w=f[3],m=f[4],y=f[5],v=f[6],A=f[7];var M=32+(h+3&7?8-(h+3&7):0)+(a<<3),I=i+n.F.contSize(g.fltree,g.lhst)+n.F.contSize(g.fdtree,g.dhst),b=i+n.F.contSize(g.ltree,g.lhst)+n.F.contSize(g.dtree,g.dhst);b+=14+3*y+n.F.contSize(g.itree,g.ihst)+(2*g.ihst[16]+3*g.ihst[17]+7*g.ihst[18]);for(var C=0;C<286;C++)g.lhst[C]=0;for(C=0;C<30;C++)g.dhst[C]=0;for(C=0;C<19;C++)g.ihst[C]=0;var U=M<I&&M<b?0:I<b?1:2;if(p(c,h,t),p(c,h+1,U),h+=3,0==U){for(;7&h;)h++;h=n.F.G(s,o,a,c,h)}else{var B,D;if(1==U&&(B=g.fltree,D=g.fdtree),2==U){n.F.makeCodes(g.ltree,l),n.F.revCodes(g.ltree,l),n.F.makeCodes(g.dtree,u),n.F.revCodes(g.dtree,u),n.F.makeCodes(g.itree,d),n.F.revCodes(g.itree,d),B=g.ltree,D=g.dtree,E(c,h,w-257),E(c,h+=5,m-1),E(c,h+=5,y-4),h+=4;for(var S=0;S<y;S++)E(c,h+3*S,g.itree[1+(g.ordr[S]<<1)]);h+=3*y,h=n.F.st(v,g.itree,c,h),h=n.F.st(A,g.itree,c,h)}for(var R=o,P=0;P<e;P+=2){for(var Q=r[P],T=Q>>>23,x=R+(8388607&Q);R<x;)h=n.F.ot(s[R++],B,c,h);if(0!=T){var $=r[P+1],k=$>>16,F=$>>8&255,O=255&$;E(c,h=n.F.ot(257+F,B,c,h),T-g.of0[F]),h+=g.exb[F],p(c,h=n.F.ot(O,D,c,h),k-g.df0[O]),h+=g.dxb[O],R+=T}}h=n.F.ot(256,B,c,h)}return h},n.F.G=function(t,r,n,e,i){var s=i>>>3;return e[s]=n,e[s+1]=n>>>8,e[s+2]=255-e[s],e[s+3]=255-e[s+1],s+=4,e.set(new Uint8Array(t.buffer,r,n),s),i+(n+4<<3)},n.F.getTrees=function(){for(var t=n.F.U,r=n.F.ct(t.lhst,t.ltree,15),e=n.F.ct(t.dhst,t.dtree,15),i=[],s=n.F.ht(t.ltree,i),o=[],a=n.F.ht(t.dtree,o),c=0;c<i.length;c+=2)t.ihst[i[c]]++;for(c=0;c<o.length;c+=2)t.ihst[o[c]]++;for(var h=n.F.ct(t.ihst,t.itree,7),f=19;f>4&&0==t.itree[1+(t.ordr[f-1]<<1)];)f--;return[r,e,h,s,a,f,i,o]},n.F.getSecond=function(t){for(var r=[],n=0;n<t.length;n+=2)r.push(t[n+1]);return r},n.F.nonZero=function(t){for(var r="",n=0;n<t.length;n+=2)0!=t[n+1]&&(r+=(n>>1)+",");return r},n.F.contSize=function(t,r){for(var n=0,e=0;e<r.length;e++)n+=r[e]*t[1+(e<<1)];return n},n.F.st=function(t,r,e,i){for(var s=0;s<t.length;s+=2){var o=t[s],a=t[s+1];i=n.F.ot(o,r,e,i);var c=16==o?2:17==o?3:7;o>15&&(n.F._(e,i,a,c),i+=c)}return i},n.F.ht=function(t,r){for(var n=t.length;2!=n&&0==t[n-1];)n-=2;for(var e=0;e<n;e+=2){var i=t[e+1],s=e+3<n?t[e+3]:-1,o=e+5<n?t[e+5]:-1,a=0==e?-1:t[e-1];if(0==i&&s==i&&o==i){for(var c=e+5;c+2<n&&t[c+2]==i;)c+=2;(h=Math.min(c+1-e>>>1,138))<11?r.push(17,h-3):r.push(18,h-11),e+=2*h-2}else if(i==a&&s==i&&o==i){for(c=e+5;c+2<n&&t[c+2]==i;)c+=2;var h=Math.min(c+1-e>>>1,6);r.push(16,h-3),e+=2*h-2}else r.push(i,0)}return n>>>1},n.F.ct=function(t,r,e){var i=[],s=t.length,o=r.length,a=0;for(a=0;a<o;a+=2)r[a]=0,r[a+1]=0;for(a=0;a<s;a++)0!=t[a]&&i.push({lit:a,f:t[a]});var c=i.length,h=i.slice(0);if(0==c)return 0;if(1==c){var f=i[0].lit;return h=0==f?1:0,r[1+(f<<1)]=1,r[1+(h<<1)]=1,1}i.sort((function(t,r){return t.f-r.f}));var l=i[0],u=i[1],d=0,w=1,m=2;for(i[0]={lit:-1,f:l.f+u.f,l:l,r:u,d:0};w!=c-1;)l=d!=w&&(m==c||i[d].f<i[m].f)?i[d++]:i[m++],u=d!=w&&(m==c||i[d].f<i[m].f)?i[d++]:i[m++],i[w++]={lit:-1,f:l.f+u.f,l:l,r:u};var y=n.F.setDepth(i[w-1],0);for(y>e&&(n.F.restrictDepth(h,e,y),y=e),a=0;a<c;a++)r[1+(h[a].lit<<1)]=h[a].d;return y},n.F.setDepth=function(t,r){return-1!=t.lit?(t.d=r,r):Math.max(n.F.setDepth(t.l,r+1),n.F.setDepth(t.r,r+1))},n.F.restrictDepth=function(t,r,n){var e=0,i=1<<n-r,s=0;for(t.sort((function(t,r){return r.d==t.d?t.f-r.f:r.d-t.d})),e=0;e<t.length&&t[e].d>r;e++){var o=t[e].d;t[e].d=r,s+=i-(1<<n-o)}for(s>>>=n-r;s>0;)(o=t[e].d)<r?(t[e].d++,s-=1<<r-o-1):e++;for(;e>=0;e--)t[e].d==r&&s<0&&(t[e].d--,s++)},n.F.O=function(t,r){var n=0;return r[16|n]<=t&&(n|=16),r[8|n]<=t&&(n|=8),r[4|n]<=t&&(n|=4),r[2|n]<=t&&(n|=2),r[1|n]<=t&&(n|=1),n},n.F.ot=function(t,r,e,i){return n.F.it(e,i,r[t<<1]),i+r[1+(t<<1)]},n.F.inflate=function(t,r){var e=Uint8Array;if(3==t[0]&&0==t[1])return r||new e(0);var i=n.F,s=i.ft,o=i.lt,a=i.ut,c=i.makeCodes,h=i.codes2map,f=i.dt,l=i.U,u=null==r;u&&(r=new e(t.length>>>2<<3));for(var d,w,m=0,y=0,v=0,A=0,g=0,p=0,E=0,M=0,I=0;0==m;)if(m=s(t,I,1),y=s(t,I+1,2),I+=3,0!=y){if(u&&(r=n.F.wt(r,M+(1<<17))),1==y&&(d=l.flmap,w=l.fdmap,p=511,E=31),2==y){v=o(t,I,5)+257,A=o(t,I+5,5)+1,g=o(t,I+10,4)+4,I+=14;for(var b=0;b<38;b+=2)l.itree[b]=0,l.itree[b+1]=0;var C=1;for(b=0;b<g;b++){var U=o(t,I+3*b,3);l.itree[1+(l.ordr[b]<<1)]=U,U>C&&(C=U)}I+=3*g,c(l.itree,C),h(l.itree,C,l.imap),d=l.lmap,w=l.dmap,I=a(l.imap,(1<<C)-1,v+A,t,I,l.ttree);var B=i.yt(l.ttree,0,v,l.ltree);p=(1<<B)-1;var D=i.yt(l.ttree,v,A,l.dtree);E=(1<<D)-1,c(l.ltree,B),h(l.ltree,B,d),c(l.dtree,D),h(l.dtree,D,w)}for(;;){var S=d[f(t,I)&p];I+=15&S;var R=S>>>4;if(R>>>8==0)r[M++]=R;else{if(256==R)break;var P=M+R-254;if(R>264){var Q=l.ldef[R-257];P=M+(Q>>>3)+o(t,I,7&Q),I+=7&Q}var T=w[f(t,I)&E];I+=15&T;var x=T>>>4,$=l.ddef[x],k=($>>>4)+s(t,I,15&$);for(I+=15&$,u&&(r=n.F.wt(r,M+(1<<17)));M<P;)r[M]=r[M++-k],r[M]=r[M++-k],r[M]=r[M++-k],r[M]=r[M++-k];M=P}}}else{7&I&&(I+=8-(7&I));var F=4+(I>>>3),O=t[F-4]|t[F-3]<<8;u&&(r=n.F.wt(r,M+O)),r.set(new e(t.buffer,t.byteOffset+F,O),M),I=F+O<<3,M+=O}return r.length==M?r:r.slice(0,M)},n.F.wt=function(t,r){var n=t.length;if(r<=n)return t;var e=new Uint8Array(Math.max(n<<1,r));return e.set(t,0),e},n.F.ut=function(t,r,e,i,s,o){for(var a=n.F.lt,c=n.F.dt,h=0;h<e;){var f=t[c(i,s)&r];s+=15&f;var l=f>>>4;if(l<=15)o[h]=l,h++;else{var u=0,d=0;16==l?(d=3+a(i,s,2),s+=2,u=o[h-1]):17==l?(d=3+a(i,s,3),s+=3):18==l&&(d=11+a(i,s,7),s+=7);for(var w=h+d;h<w;)o[h]=u,h++}}return s},n.F.yt=function(t,r,n,e){for(var i=0,s=0,o=e.length>>>1;s<n;){var a=t[s+r];e[s<<1]=0,e[1+(s<<1)]=a,a>i&&(i=a),s++}for(;s<o;)e[s<<1]=0,e[1+(s<<1)]=0,s++;return i},n.F.makeCodes=function(t,r){for(var e,i,s,o,a=n.F.U,c=t.length,h=a.bl_count,f=0;f<=r;f++)h[f]=0;for(f=1;f<c;f+=2)h[t[f]]++;var l=a.next_code;for(e=0,h[0]=0,i=1;i<=r;i++)e=e+h[i-1]<<1,l[i]=e;for(s=0;s<c;s+=2)0!=(o=t[s+1])&&(t[s]=l[o],l[o]++)},n.F.codes2map=function(t,r,e){for(var i=t.length,s=n.F.U.rev15,o=0;o<i;o+=2)if(0!=t[o+1])for(var a=o>>1,c=t[o+1],h=a<<4|c,f=r-c,l=t[o]<<f,u=l+(1<<f);l!=u;)e[s[l]>>>15-r]=h,l++},n.F.revCodes=function(t,r){for(var e=n.F.U.rev15,i=15-r,s=0;s<t.length;s+=2){var o=t[s]<<r-t[s+1];t[s]=e[o]>>>i}},n.F._=function(t,r,n){n<<=7&r;var e=r>>>3;t[e]|=n,t[e+1]|=n>>>8},n.F.it=function(t,r,n){n<<=7&r;var e=r>>>3;t[e]|=n,t[e+1]|=n>>>8,t[e+2]|=n>>>16},n.F.lt=function(t,r,n){return(t[r>>>3]|t[1+(r>>>3)]<<8)>>>(7&r)&(1<<n)-1},n.F.ft=function(t,r,n){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16)>>>(7&r)&(1<<n)-1},n.F.dt=function(t,r){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16)>>>(7&r)},n.F.vt=function(t,r){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16|t[3+(r>>>3)]<<24)>>>(7&r)},n.F.U=(t=Uint16Array,r=Uint32Array,{next_code:new t(16),bl_count:new t(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new t(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new r(32),flmap:new t(512),fltree:[],fdmap:new t(32),fdtree:[],lmap:new t(32768),ltree:[],ttree:[],dmap:new t(32768),dtree:[],imap:new t(512),itree:[],rev15:new t(32768),lhst:new r(286),dhst:new r(30),ihst:new r(19),lits:new r(15e3),strt:new t(65536),prev:new t(32768)}),function(){for(var t=n.F.U,r=0;r<32768;r++){var e=r;e=(4278255360&(e=(4042322160&(e=(3435973836&(e=(2863311530&e)>>>1|(1431655765&e)<<1))>>>2|(858993459&e)<<2))>>>4|(252645135&e)<<4))>>>8|(16711935&e)<<8,t.rev15[r]=(e>>>16|e<<16)>>>17}function i(t,r,n){for(;0!=r--;)t.push(0,n)}for(r=0;r<32;r++)t.ldef[r]=t.of0[r]<<3|t.exb[r],t.ddef[r]=t.df0[r]<<4|t.dxb[r];i(t.fltree,144,8),i(t.fltree,112,9),i(t.fltree,24,7),i(t.fltree,8,8),n.F.makeCodes(t.fltree,9),n.F.codes2map(t.fltree,9,t.flmap),n.F.revCodes(t.fltree,9),i(t.fdtree,32,5),n.F.makeCodes(t.fdtree,5),n.F.codes2map(t.fdtree,5,t.fdmap),n.F.revCodes(t.fdtree,5),i(t.itree,19,0),i(t.ltree,286,0),i(t.dtree,30,0),i(t.ttree,320,0)}()}();var h=function(t,r){return r.forEach((function(r){r&&"string"!=typeof r&&!Array.isArray(r)&&Object.keys(r).forEach((function(n){if("default"!==n&&!(n in t)){var e=Object.getOwnPropertyDescriptor(r,n);Object.defineProperty(t,n,e.get?e:{enumerable:!0,get:function(){return r[n]}})}}))})),Object.freeze(t)}({__proto__:null,default:a},[a]);const f=function(){var t={nextZero(t,r){for(;0!=t[r];)r++;return r},readUshort:(t,r)=>t[r]<<8|t[r+1],writeUshort(t,r,n){t[r]=n>>8&255,t[r+1]=255&n},readUint:(t,r)=>16777216*t[r]+(t[r+1]<<16|t[r+2]<<8|t[r+3]),writeUint(t,r,n){t[r]=n>>24&255,t[r+1]=n>>16&255,t[r+2]=n>>8&255,t[r+3]=255&n},readASCII(t,r,n){let e="";for(let i=0;i<n;i++)e+=String.fromCharCode(t[r+i]);return e},writeASCII(t,r,n){for(let e=0;e<n.length;e++)t[r+e]=n.charCodeAt(e)},readBytes(t,r,n){const e=[];for(let i=0;i<n;i++)e.push(t[r+i]);return e},pad:t=>t.length<2?"0"+t:t,readUTF8(r,n,e){let i,s="";for(let i=0;i<e;i++)s+="%"+t.pad(r[n+i].toString(16));try{i=decodeURIComponent(s)}catch(i){return t.readASCII(r,n,e)}return i}};function r(r,n,e,i){const o=n*e,a=s(i),c=Math.ceil(n*a/8),h=new Uint8Array(4*o),f=new Uint32Array(h.buffer),{ctype:l}=i,{depth:u}=i,d=t.readUshort;if(6==l){const t=o<<2;if(8==u)for(var w=0;w<t;w+=4)h[w]=r[w],h[w+1]=r[w+1],h[w+2]=r[w+2],h[w+3]=r[w+3];if(16==u)for(w=0;w<t;w++)h[w]=r[w<<1]}else if(2==l){const t=i.tabs.tRNS;if(null==t){if(8==u)for(w=0;w<o;w++){var m=3*w;f[w]=255<<24|r[m+2]<<16|r[m+1]<<8|r[m]}if(16==u)for(w=0;w<o;w++)m=6*w,f[w]=255<<24|r[m+4]<<16|r[m+2]<<8|r[m]}else{var y=t[0];const n=t[1],e=t[2];if(8==u)for(w=0;w<o;w++){var v=w<<2;m=3*w,f[w]=255<<24|r[m+2]<<16|r[m+1]<<8|r[m],r[m]==y&&r[m+1]==n&&r[m+2]==e&&(h[v+3]=0)}if(16==u)for(w=0;w<o;w++)v=w<<2,m=6*w,f[w]=255<<24|r[m+4]<<16|r[m+2]<<8|r[m],d(r,m)==y&&d(r,m+2)==n&&d(r,m+4)==e&&(h[v+3]=0)}}else if(3==l){const t=i.tabs.PLTE,s=i.tabs.tRNS,a=s?s.length:0;if(1==u)for(var A=0;A<e;A++){var g=A*c,p=A*n;for(w=0;w<n;w++){v=p+w<<2;var E=3*(M=r[g+(w>>3)]>>7-(7&w)&1);h[v]=t[E],h[v+1]=t[E+1],h[v+2]=t[E+2],h[v+3]=M<a?s[M]:255}}if(2==u)for(A=0;A<e;A++)for(g=A*c,p=A*n,w=0;w<n;w++)v=p+w<<2,E=3*(M=r[g+(w>>2)]>>6-((3&w)<<1)&3),h[v]=t[E],h[v+1]=t[E+1],h[v+2]=t[E+2],h[v+3]=M<a?s[M]:255;if(4==u)for(A=0;A<e;A++)for(g=A*c,p=A*n,w=0;w<n;w++)v=p+w<<2,E=3*(M=r[g+(w>>1)]>>4-((1&w)<<2)&15),h[v]=t[E],h[v+1]=t[E+1],h[v+2]=t[E+2],h[v+3]=M<a?s[M]:255;if(8==u)for(w=0;w<o;w++){var M;v=w<<2,E=3*(M=r[w]),h[v]=t[E],h[v+1]=t[E+1],h[v+2]=t[E+2],h[v+3]=M<a?s[M]:255}}else if(4==l){if(8==u)for(w=0;w<o;w++){v=w<<2;var I=r[b=w<<1];h[v]=I,h[v+1]=I,h[v+2]=I,h[v+3]=r[b+1]}if(16==u)for(w=0;w<o;w++){var b;v=w<<2,I=r[b=w<<2],h[v]=I,h[v+1]=I,h[v+2]=I,h[v+3]=r[b+2]}}else if(0==l)for(y=i.tabs.tRNS?i.tabs.tRNS:-1,A=0;A<e;A++){const t=A*c,e=A*n;if(1==u)for(var C=0;C<n;C++){var U=(I=255*(r[t+(C>>>3)]>>>7-(7&C)&1))==255*y?0:255;f[e+C]=U<<24|I<<16|I<<8|I}else if(2==u)for(C=0;C<n;C++)U=(I=85*(r[t+(C>>>2)]>>>6-((3&C)<<1)&3))==85*y?0:255,f[e+C]=U<<24|I<<16|I<<8|I;else if(4==u)for(C=0;C<n;C++)U=(I=17*(r[t+(C>>>1)]>>>4-((1&C)<<2)&15))==17*y?0:255,f[e+C]=U<<24|I<<16|I<<8|I;else if(8==u)for(C=0;C<n;C++)U=(I=r[t+C])==y?0:255,f[e+C]=U<<24|I<<16|I<<8|I;else if(16==u)for(C=0;C<n;C++)I=r[t+(C<<1)],U=d(r,t+(C<<1))==y?0:255,f[e+C]=U<<24|I<<16|I<<8|I}return h}function n(t,r,n,a){const c=s(t),h=new Uint8Array((Math.ceil(n*c/8)+1+t.interlace)*a);return r=t.tabs.CgBI?i(r,h):e(r,h),0==t.interlace?r=o(r,t,0,n,a):1==t.interlace&&(r=function(t,r){const n=r.width,e=r.height,i=s(r),a=i>>3,c=Math.ceil(n*i/8),h=new Uint8Array(e*c);let f=0;const l=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],d=[8,8,8,4,4,2,2],w=[8,8,4,4,2,2,1];let m=0;for(;m<7;){const s=d[m],v=w[m];let A=0,g=0,p=l[m];for(;p<e;)p+=s,g++;let E=u[m];for(;E<n;)E+=v,A++;const M=Math.ceil(A*i/8);o(t,r,f,A,g);let I=0,b=l[m];for(;b<e;){let r=u[m],e=f+I*M<<3;for(;r<n;){var y;if(1==i&&(y=(y=t[e>>3])>>7-(7&e)&1,h[b*c+(r>>3)]|=y<<7-(7&r)),2==i&&(y=(y=t[e>>3])>>6-(7&e)&3,h[b*c+(r>>2)]|=y<<6-((3&r)<<1)),4==i&&(y=(y=t[e>>3])>>4-(7&e)&15,h[b*c+(r>>1)]|=y<<4-((1&r)<<2)),i>=8){const n=b*c+r*a;for(let r=0;r<a;r++)h[n+r]=t[(e>>3)+r]}e+=i,r+=v}I++,b+=s}A*g!=0&&(f+=g*(1+M)),m+=1}return h}(r,t)),r}function e(t,r){return i(new Uint8Array(t.buffer,2,t.length-6),r)}var i=function(){const t={H:{}};return t.H.N=function(r,n){const e=Uint8Array;let i,s,o=0,a=0,c=0,h=0,f=0,l=0,u=0,d=0,w=0;if(3==r[0]&&0==r[1])return n||new e(0);const m=t.H,y=m.b,v=m.e,A=m.R,g=m.n,p=m.A,E=m.Z,M=m.m,I=null==n;for(I&&(n=new e(r.length>>>2<<5));0==o;)if(o=y(r,w,1),a=y(r,w+1,2),w+=3,0!=a){if(I&&(n=t.H.W(n,d+(1<<17))),1==a&&(i=M.J,s=M.h,l=511,u=31),2==a){c=v(r,w,5)+257,h=v(r,w+5,5)+1,f=v(r,w+10,4)+4,w+=14;let t=1;for(var b=0;b<38;b+=2)M.Q[b]=0,M.Q[b+1]=0;for(b=0;b<f;b++){const n=v(r,w+3*b,3);M.Q[1+(M.X[b]<<1)]=n,n>t&&(t=n)}w+=3*f,g(M.Q,t),p(M.Q,t,M.u),i=M.w,s=M.d,w=A(M.u,(1<<t)-1,c+h,r,w,M.v);const n=m.V(M.v,0,c,M.C);l=(1<<n)-1;const e=m.V(M.v,c,h,M.D);u=(1<<e)-1,g(M.C,n),p(M.C,n,i),g(M.D,e),p(M.D,e,s)}for(;;){const t=i[E(r,w)&l];w+=15&t;const e=t>>>4;if(e>>>8==0)n[d++]=e;else{if(256==e)break;{let t=d+e-254;if(e>264){const n=M.q[e-257];t=d+(n>>>3)+v(r,w,7&n),w+=7&n}const i=s[E(r,w)&u];w+=15&i;const o=i>>>4,a=M.c[o],c=(a>>>4)+y(r,w,15&a);for(w+=15&a;d<t;)n[d]=n[d++-c],n[d]=n[d++-c],n[d]=n[d++-c],n[d]=n[d++-c];d=t}}}}else{7&w&&(w+=8-(7&w));const i=4+(w>>>3),s=r[i-4]|r[i-3]<<8;I&&(n=t.H.W(n,d+s)),n.set(new e(r.buffer,r.byteOffset+i,s),d),w=i+s<<3,d+=s}return n.length==d?n:n.slice(0,d)},t.H.W=function(t,r){const n=t.length;if(r<=n)return t;const e=new Uint8Array(n<<1);return e.set(t,0),e},t.H.R=function(r,n,e,i,s,o){const a=t.H.e,c=t.H.Z;let h=0;for(;h<e;){const t=r[c(i,s)&n];s+=15&t;const e=t>>>4;if(e<=15)o[h]=e,h++;else{let t=0,r=0;16==e?(r=3+a(i,s,2),s+=2,t=o[h-1]):17==e?(r=3+a(i,s,3),s+=3):18==e&&(r=11+a(i,s,7),s+=7);const n=h+r;for(;h<n;)o[h]=t,h++}}return s},t.H.V=function(t,r,n,e){let i=0,s=0;const o=e.length>>>1;for(;s<n;){const n=t[s+r];e[s<<1]=0,e[1+(s<<1)]=n,n>i&&(i=n),s++}for(;s<o;)e[s<<1]=0,e[1+(s<<1)]=0,s++;return i},t.H.n=function(r,n){const e=t.H.m,i=r.length;let s,o,a,c;const h=e.j;for(var f=0;f<=n;f++)h[f]=0;for(f=1;f<i;f+=2)h[r[f]]++;const l=e.K;for(s=0,h[0]=0,o=1;o<=n;o++)s=s+h[o-1]<<1,l[o]=s;for(a=0;a<i;a+=2)c=r[a+1],0!=c&&(r[a]=l[c],l[c]++)},t.H.A=function(r,n,e){const i=r.length,s=t.H.m.r;for(let t=0;t<i;t+=2)if(0!=r[t+1]){const i=t>>1,o=r[t+1],a=i<<4|o,c=n-o;let h=r[t]<<c;const f=h+(1<<c);for(;h!=f;)e[s[h]>>>15-n]=a,h++}},t.H.l=function(r,n){const e=t.H.m.r,i=15-n;for(let t=0;t<r.length;t+=2){const s=r[t]<<n-r[t+1];r[t]=e[s]>>>i}},t.H.M=function(t,r,n){n<<=7&r;const e=r>>>3;t[e]|=n,t[e+1]|=n>>>8},t.H.I=function(t,r,n){n<<=7&r;const e=r>>>3;t[e]|=n,t[e+1]|=n>>>8,t[e+2]|=n>>>16},t.H.e=function(t,r,n){return(t[r>>>3]|t[1+(r>>>3)]<<8)>>>(7&r)&(1<<n)-1},t.H.b=function(t,r,n){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16)>>>(7&r)&(1<<n)-1},t.H.Z=function(t,r){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16)>>>(7&r)},t.H.i=function(t,r){return(t[r>>>3]|t[1+(r>>>3)]<<8|t[2+(r>>>3)]<<16|t[3+(r>>>3)]<<24)>>>(7&r)},t.H.m=function(){const t=Uint16Array,r=Uint32Array;return{K:new t(16),j:new t(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new t(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new r(32),J:new t(512),At:[],h:new t(32),$:[],w:new t(32768),C:[],v:[],d:new t(32768),D:[],u:new t(512),Q:[],r:new t(32768),s:new r(286),Y:new r(30),a:new r(19),t:new r(15e3),k:new t(65536),g:new t(32768)}}(),function(){const r=t.H.m;for(var n=0;n<32768;n++){let t=n;t=(2863311530&t)>>>1|(1431655765&t)<<1,t=(3435973836&t)>>>2|(858993459&t)<<2,t=(4042322160&t)>>>4|(252645135&t)<<4,t=(4278255360&t)>>>8|(16711935&t)<<8,r.r[n]=(t>>>16|t<<16)>>>17}function e(t,r,n){for(;0!=r--;)t.push(0,n)}for(n=0;n<32;n++)r.q[n]=r.S[n]<<3|r.T[n],r.c[n]=r.p[n]<<4|r.z[n];e(r.At,144,8),e(r.At,112,9),e(r.At,24,7),e(r.At,8,8),t.H.n(r.At,9),t.H.A(r.At,9,r.J),t.H.l(r.At,9),e(r.$,32,5),t.H.n(r.$,5),t.H.A(r.$,5,r.h),t.H.l(r.$,5),e(r.Q,19,0),e(r.C,286,0),e(r.D,30,0),e(r.v,320,0)}(),t.H.N}();function s(t){return[1,null,3,1,2,null,4][t.ctype]*t.depth}function o(t,r,n,e,i){let o=s(r);const c=Math.ceil(e*o/8);let h,f;o=Math.ceil(o/8);let l=t[n],u=0;if(l>1&&(t[n]=[0,0,1][l-2]),3==l)for(u=o;u<c;u++)t[u+1]=t[u+1]+(t[u+1-o]>>>1)&255;for(let r=0;r<i;r++)if(h=n+r*c,f=h+r+1,l=t[f-1],u=0,0==l)for(;u<c;u++)t[h+u]=t[f+u];else if(1==l){for(;u<o;u++)t[h+u]=t[f+u];for(;u<c;u++)t[h+u]=t[f+u]+t[h+u-o]}else if(2==l)for(;u<c;u++)t[h+u]=t[f+u]+t[h+u-c];else if(3==l){for(;u<o;u++)t[h+u]=t[f+u]+(t[h+u-c]>>>1);for(;u<c;u++)t[h+u]=t[f+u]+(t[h+u-c]+t[h+u-o]>>>1)}else{for(;u<o;u++)t[h+u]=t[f+u]+a(0,t[h+u-c],0);for(;u<c;u++)t[h+u]=t[f+u]+a(t[h+u-o],t[h+u-c],t[h+u-o-c])}return t}function a(t,r,n){const e=t+r-n,i=e-t,s=e-r,o=e-n;return i*i<=s*s&&i*i<=o*o?t:s*s<=o*o?r:n}function c(r,n,e){e.width=t.readUint(r,n),n+=4,e.height=t.readUint(r,n),n+=4,e.depth=r[n],n++,e.ctype=r[n],n++,e.compress=r[n],n++,e.filter=r[n],n++,e.interlace=r[n],n++}function h(t,r,n,e,i,s,o,a,c){const h=Math.min(r,i),f=Math.min(n,s);let l=0,u=0;for(let n=0;n<f;n++)for(let s=0;s<h;s++)if(o>=0&&a>=0?(l=n*r+s<<2,u=(a+n)*i+o+s<<2):(l=(-a+n)*r-o+s<<2,u=n*i+s<<2),0==c)e[u]=t[l],e[u+1]=t[l+1],e[u+2]=t[l+2],e[u+3]=t[l+3];else if(1==c){var d=t[l+3]*(1/255),w=t[l]*d,m=t[l+1]*d,y=t[l+2]*d,v=e[u+3]*(1/255),A=e[u]*v,g=e[u+1]*v,p=e[u+2]*v;const r=1-d,n=d+v*r,i=0==n?0:1/n;e[u+3]=255*n,e[u+0]=(w+A*r)*i,e[u+1]=(m+g*r)*i,e[u+2]=(y+p*r)*i}else if(2==c)d=t[l+3],w=t[l],m=t[l+1],y=t[l+2],v=e[u+3],A=e[u],g=e[u+1],p=e[u+2],d==v&&w==A&&m==g&&y==p?(e[u]=0,e[u+1]=0,e[u+2]=0,e[u+3]=0):(e[u]=w,e[u+1]=m,e[u+2]=y,e[u+3]=d);else if(3==c){if(d=t[l+3],w=t[l],m=t[l+1],y=t[l+2],v=e[u+3],A=e[u],g=e[u+1],p=e[u+2],d==v&&w==A&&m==g&&y==p)continue;if(d<220&&v>20)return!1}return!0}return{decode:function(r){const s=new Uint8Array(r);let o=8;const a=t,h=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},u=new Uint8Array(s.length);let d,w=0,m=0;const y=[137,80,78,71,13,10,26,10];for(var v=0;v<8;v++)if(s[v]!=y[v])throw"The input is not a PNG file!";for(;o<s.length;){const t=a.readUint(s,o);o+=4;const r=a.readASCII(s,o,4);if(o+=4,"IHDR"==r)c(s,o,l);else if("iCCP"==r){for(var A=o;0!=s[A];)A++;a.readASCII(s,o,A-o);const n=s.slice(A+2,o+t);let c=null;try{c=e(n)}catch(t){c=i(n)}l.tabs[r]=c}else if("CgBI"==r)l.tabs[r]=s.slice(o,o+4);else if("IDAT"==r){for(v=0;v<t;v++)u[w+v]=s[o+v];w+=t}else if("acTL"==r)l.tabs[r]={num_frames:f(s,o),num_plays:f(s,o+4)},d=new Uint8Array(s.length);else if("fcTL"==r){0!=m&&((b=l.frames[l.frames.length-1]).data=n(l,d.slice(0,m),b.rect.width,b.rect.height),m=0);const t={x:f(s,o+12),y:f(s,o+16),width:f(s,o+4),height:f(s,o+8)};let r=h(s,o+22);r=h(s,o+20)/(0==r?100:r);const e={rect:t,delay:Math.round(1e3*r),dispose:s[o+24],blend:s[o+25]};l.frames.push(e)}else if("fdAT"==r){for(v=0;v<t-4;v++)d[m+v]=s[o+v+4];m+=t-4}else if("pHYs"==r)l.tabs[r]=[a.readUint(s,o),a.readUint(s,o+4),s[o+8]];else if("cHRM"==r)for(l.tabs[r]=[],v=0;v<8;v++)l.tabs[r].push(a.readUint(s,o+4*v));else if("tEXt"==r||"zTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});var g=a.nextZero(s,o),p=a.readASCII(s,o,g-o),E=o+t-g-1;if("tEXt"==r)I=a.readASCII(s,g+1,E);else{var M=e(s.slice(g+2,g+2+E));I=a.readUTF8(M,0,M.length)}l.tabs[r][p]=I}else if("iTXt"==r){null==l.tabs[r]&&(l.tabs[r]={}),g=0,A=o,g=a.nextZero(s,A),p=a.readASCII(s,A,g-A);const n=s[A=g+1];var I;A+=2,g=a.nextZero(s,A),a.readASCII(s,A,g-A),A=g+1,g=a.nextZero(s,A),a.readUTF8(s,A,g-A),E=t-((A=g+1)-o),0==n?I=a.readUTF8(s,A,E):(M=e(s.slice(A,A+E)),I=a.readUTF8(M,0,M.length)),l.tabs[r][p]=I}else if("PLTE"==r)l.tabs[r]=a.readBytes(s,o,t);else if("hIST"==r){const t=l.tabs.PLTE.length/3;for(l.tabs[r]=[],v=0;v<t;v++)l.tabs[r].push(h(s,o+2*v))}else if("tRNS"==r)3==l.ctype?l.tabs[r]=a.readBytes(s,o,t):0==l.ctype?l.tabs[r]=h(s,o):2==l.ctype&&(l.tabs[r]=[h(s,o),h(s,o+2),h(s,o+4)]);else if("gAMA"==r)l.tabs[r]=a.readUint(s,o)/1e5;else if("sRGB"==r)l.tabs[r]=s[o];else if("bKGD"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[h(s,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[h(s,o),h(s,o+2),h(s,o+4)]:3==l.ctype&&(l.tabs[r]=s[o]);else if("IEND"==r)break;o+=t,a.readUint(s,o),o+=4}var b;return 0!=m&&((b=l.frames[l.frames.length-1]).data=n(l,d.slice(0,m),b.rect.width,b.rect.height)),l.data=n(l,u,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function(t){const n=t.width,e=t.height;if(null==t.tabs.acTL)return[r(t.data,n,e,t).buffer];const i=[];null==t.frames[0].data&&(t.frames[0].data=t.data);const s=n*e*4,o=new Uint8Array(s),a=new Uint8Array(s),c=new Uint8Array(s);for(let l=0;l<t.frames.length;l++){const u=t.frames[l],d=u.rect.x,w=u.rect.y,m=u.rect.width,y=u.rect.height,v=r(u.data,m,y,t);if(0!=l)for(var f=0;f<s;f++)c[f]=o[f];if(0==u.blend?h(v,m,y,o,n,e,d,w,0):1==u.blend&&h(v,m,y,o,n,e,d,w,1),i.push(o.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)h(a,m,y,o,n,e,d,w,0);else if(2==u.dispose)for(f=0;f<s;f++)o[f]=c[f]}return i},gt:a,Et:h,Mt:t}}();!function(){const{Et:t}=f,{Mt:r}=f,n=f.gt;var e={table:function(){const t=new Uint32Array(256);for(let r=0;r<256;r++){let n=r;for(let t=0;t<8;t++)1&n?n=3988292384^n>>>1:n>>>=1;t[r]=n}return t}(),update(t,r,n,i){for(let s=0;s<i;s++)t=e.table[255&(t^r[n+s])]^t>>>8;return t},crc:(t,r,n)=>4294967295^e.update(4294967295,t,r,n)};function i(t,r,n,e){r[n]+=t[0]*e>>4,r[n+1]+=t[1]*e>>4,r[n+2]+=t[2]*e>>4,r[n+3]+=t[3]*e>>4}function s(t){return Math.max(0,Math.min(255,t))}function o(t,r){const n=t[0]-r[0],e=t[1]-r[1],i=t[2]-r[2],s=t[3]-r[3];return n*n+e*e+i*i+s*s}function a(t,r,n,e,a,c,h){null==h&&(h=1);const f=e.length,l=[];for(var u=0;u<f;u++){const t=e[u];l.push([t>>>0&255,t>>>8&255,t>>>16&255,t>>>24&255])}for(u=0;u<f;u++){let t=4294967295;for(var d=0,w=0;w<f;w++){var m=o(l[u],l[w]);w!=u&&m<t&&(t=m,d=w)}}const y=new Uint32Array(a.buffer),v=new Int16Array(r*n*4),A=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(u=0;u<A.length;u++)A[u]=255*((A[u]+.5)/16-.5);for(let a=0;a<n;a++)for(let p=0;p<r;p++){var g;u=4*(a*r+p),2!=h?g=[s(t[u]+v[u]),s(t[u+1]+v[u+1]),s(t[u+2]+v[u+2]),s(t[u+3]+v[u+3])]:(m=A[4*(3&a)+(3&p)],g=[s(t[u]+m),s(t[u+1]+m),s(t[u+2]+m),s(t[u+3]+m)]),d=0;let E=16777215;for(w=0;w<f;w++){const t=o(g,l[w]);t<E&&(E=t,d=w)}const M=l[d],I=[g[0]-M[0],g[1]-M[1],g[2]-M[2],g[3]-M[3]];1==h&&(p!=r-1&&i(I,v,u+4,7),a!=n-1&&(0!=p&&i(I,v,u+4*r-4,3),i(I,v,u+4*r,5),p!=r-1&&i(I,v,u+4*r+4,1))),c[u>>2]=d,y[u>>2]=e[d]}}function c(t,n,i,s,o){null==o&&(o={});const{crc:a}=e,c=r.writeUint,h=r.writeUshort,f=r.writeASCII;let l=8;const u=t.frames.length>1;let d,w=!1,m=33+(u?20:0);if(null!=o.sRGB&&(m+=13),null!=o.pHYs&&(m+=21),null!=o.iCCP&&(d=pako.deflate(o.iCCP),m+=21+d.length+4),3==t.ctype){for(var y=t.plte.length,v=0;v<y;v++)t.plte[v]>>>24!=255&&(w=!0);m+=8+3*y+4+(w?8+1*y+4:0)}for(var A=0;A<t.frames.length;A++)u&&(m+=38),m+=(M=t.frames[A]).cimg.length+12,0!=A&&(m+=4);m+=12;const g=new Uint8Array(m),p=[137,80,78,71,13,10,26,10];for(v=0;v<8;v++)g[v]=p[v];if(c(g,l,13),l+=4,f(g,l,"IHDR"),l+=4,c(g,l,n),l+=4,c(g,l,i),l+=4,g[l]=t.depth,l++,g[l]=t.ctype,l++,g[l]=0,l++,g[l]=0,l++,g[l]=0,l++,c(g,l,a(g,l-17,17)),l+=4,null!=o.sRGB&&(c(g,l,1),l+=4,f(g,l,"sRGB"),l+=4,g[l]=o.sRGB,l++,c(g,l,a(g,l-5,5)),l+=4),null!=o.iCCP){const t=13+d.length;c(g,l,t),l+=4,f(g,l,"iCCP"),l+=4,f(g,l,"ICC profile"),l+=11,l+=2,g.set(d,l),l+=d.length,c(g,l,a(g,l-(t+4),t+4)),l+=4}if(null!=o.pHYs&&(c(g,l,9),l+=4,f(g,l,"pHYs"),l+=4,c(g,l,o.pHYs[0]),l+=4,c(g,l,o.pHYs[1]),l+=4,g[l]=o.pHYs[2],l++,c(g,l,a(g,l-13,13)),l+=4),u&&(c(g,l,8),l+=4,f(g,l,"acTL"),l+=4,c(g,l,t.frames.length),l+=4,c(g,l,null!=o.loop?o.loop:0),l+=4,c(g,l,a(g,l-12,12)),l+=4),3==t.ctype){for(c(g,l,3*(y=t.plte.length)),l+=4,f(g,l,"PLTE"),l+=4,v=0;v<y;v++){const r=3*v,n=t.plte[v],e=255&n,i=n>>>8&255,s=n>>>16&255;g[l+r+0]=e,g[l+r+1]=i,g[l+r+2]=s}if(l+=3*y,c(g,l,a(g,l-3*y-4,3*y+4)),l+=4,w){for(c(g,l,y),l+=4,f(g,l,"tRNS"),l+=4,v=0;v<y;v++)g[l+v]=t.plte[v]>>>24&255;l+=y,c(g,l,a(g,l-y-4,y+4)),l+=4}}let E=0;for(A=0;A<t.frames.length;A++){var M=t.frames[A];u&&(c(g,l,26),l+=4,f(g,l,"fcTL"),l+=4,c(g,l,E++),l+=4,c(g,l,M.rect.width),l+=4,c(g,l,M.rect.height),l+=4,c(g,l,M.rect.x),l+=4,c(g,l,M.rect.y),l+=4,h(g,l,s[A]),l+=2,h(g,l,1e3),l+=2,g[l]=M.dispose,l++,g[l]=M.blend,l++,c(g,l,a(g,l-30,30)),l+=4);const r=M.cimg;c(g,l,(y=r.length)+(0==A?0:4)),l+=4;const n=l;f(g,l,0==A?"IDAT":"fdAT"),l+=4,0!=A&&(c(g,l,E++),l+=4),g.set(r,l),l+=y,c(g,l,a(g,n,l-n)),l+=4}return c(g,l,0),l+=4,f(g,l,"IEND"),l+=4,c(g,l,a(g,l-4,4)),l+=4,g.buffer}function l(t,r,n){for(let e=0;e<t.frames.length;e++){const i=t.frames[e],s=i.rect.height,o=new Uint8Array(s*i.bpl+s);i.cimg=m(i.img,s,i.bpp,i.bpl,o,r,n)}}function u(r,n,e,i,s){const o=s[0],c=s[1],h=s[2],f=s[3],l=s[4],u=s[5];let m=6,y=8,A=255;for(var g=0;g<r.length;g++){const t=new Uint8Array(r[g]);for(var p=t.length,E=0;E<p;E+=4)A&=t[E+3]}const M=255!=A,I=function(r,n,e,i,s,o){const a=[];for(var c=0;c<r.length;c++){const l=new Uint8Array(r[c]),d=new Uint32Array(l.buffer);var h;let m=0,y=0,v=n,A=e,g=i?1:0;if(0!=c){const p=o||i||1==c||0!=a[c-2].dispose?1:2;let E=0,M=1e9;for(let t=0;t<p;t++){var f=new Uint8Array(r[c-1-t]);const i=new Uint32Array(r[c-1-t]);let o=n,a=e,h=-1,l=-1;for(let t=0;t<e;t++)for(let r=0;r<n;r++)d[u=t*n+r]!=i[u]&&(r<o&&(o=r),r>h&&(h=r),t<a&&(a=t),t>l&&(l=t));-1==h&&(o=a=h=l=0),s&&(!(1&~o)&&o--,!(1&~a)&&a--);const w=(h-o+1)*(l-a+1);w<M&&(M=w,E=t,m=o,y=a,v=h-o+1,A=l-a+1)}f=new Uint8Array(r[c-1-E]),1==E&&(a[c-1].dispose=2),h=new Uint8Array(v*A*4),t(f,n,e,h,v,A,-m,-y,0),g=t(l,n,e,h,v,A,-m,-y,3)?1:0,1==g?w(l,n,e,h,{x:m,y:y,width:v,height:A}):t(l,n,e,h,v,A,-m,-y,0)}else h=l.slice(0);a.push({rect:{x:m,y:y,width:v,height:A},img:h,blend:g,dispose:0})}if(i)for(c=0;c<a.length;c++){if(1==(m=a[c]).blend)continue;const t=m.rect,i=a[c-1].rect,o=Math.min(t.x,i.x),h=Math.min(t.y,i.y),f={x:o,y:h,width:Math.max(t.x+t.width,i.x+i.width)-o,height:Math.max(t.y+t.height,i.y+i.height)-h};a[c-1].dispose=1,c-1!=0&&d(r,n,e,a,c-1,f,s),d(r,n,e,a,c,f,s)}let l=0;if(1!=r.length)for(var u=0;u<a.length;u++){var m;l+=(m=a[u]).rect.width*m.rect.height}return a}(r,n,e,o,c,h),b={},C=[],U=[];if(0!=i){const t=[];for(E=0;E<I.length;E++)t.push(I[E].img.buffer);const r=function(t){let r=0;for(var n=0;n<t.length;n++)r+=t[n].byteLength;const e=new Uint8Array(r);let i=0;for(n=0;n<t.length;n++){const r=new Uint8Array(t[n]),s=r.length;for(let t=0;t<s;t+=4){let n=r[t],s=r[t+1],o=r[t+2];const a=r[t+3];0==a&&(n=s=o=0),e[i+t]=n,e[i+t+1]=s,e[i+t+2]=o,e[i+t+3]=a}i+=s}return e.buffer}(t),n=v(r,i);for(E=0;E<n.plte.length;E++)C.push(n.plte[E].est.rgba);let e=0;for(E=0;E<I.length;E++){const t=(D=I[E]).img.length;var B=new Uint8Array(n.inds.buffer,e>>2,t>>2);U.push(B);const r=new Uint8Array(n.abuf,e,t);u&&a(D.img,D.rect.width,D.rect.height,C,r,B),D.img.set(r),e+=t}}else for(g=0;g<I.length;g++){var D=I[g];const t=new Uint32Array(D.img.buffer);var S=D.rect.width;for(p=t.length,B=new Uint8Array(p),U.push(B),E=0;E<p;E++){const r=t[E];if(0!=E&&r==t[E-1])B[E]=B[E-1];else if(E>S&&r==t[E-S])B[E]=B[E-S];else{let t=b[r];if(null==t&&(b[r]=t=C.length,C.push(r),C.length>=300))break;B[E]=t}}}const R=C.length;for(R<=256&&0==l&&(y=R<=2?1:R<=4?2:R<=16?4:8,y=Math.max(y,f)),g=0;g<I.length;g++){(D=I[g]).rect.x,S=D.rect.width;const t=D.rect.height;let r=D.img,n=4*S,e=4;if(R<=256&&0==l){n=Math.ceil(y*S/8);var P=new Uint8Array(n*t);const i=U[g];for(let r=0;r<t;r++){E=r*n;const t=r*S;if(8==y)for(var Q=0;Q<S;Q++)P[E+Q]=i[t+Q];else if(4==y)for(Q=0;Q<S;Q++)P[E+(Q>>1)]|=i[t+Q]<<4-4*(1&Q);else if(2==y)for(Q=0;Q<S;Q++)P[E+(Q>>2)]|=i[t+Q]<<6-2*(3&Q);else if(1==y)for(Q=0;Q<S;Q++)P[E+(Q>>3)]|=i[t+Q]<<7-1*(7&Q)}r=P,m=3,e=1}else if(0==M&&1==I.length){P=new Uint8Array(S*t*3);const i=S*t;for(E=0;E<i;E++){const t=3*E,n=4*E;P[t]=r[n],P[t+1]=r[n+1],P[t+2]=r[n+2]}r=P,m=2,e=3,n=3*S}D.img=r,D.bpl=n,D.bpp=e}return{ctype:m,depth:y,plte:C,frames:I}}function d(r,n,e,i,s,o,a){const c=Uint8Array,h=Uint32Array,f=new c(r[s-1]),l=new h(r[s-1]),u=s+1<r.length?new c(r[s+1]):null,d=new c(r[s]),m=new h(d.buffer);let y=n,v=e,A=-1,g=-1;for(let t=0;t<o.height;t++)for(let r=0;r<o.width;r++){const e=o.x+r,a=o.y+t,c=a*n+e,h=m[c];0==h||0==i[s-1].dispose&&l[c]==h&&(null==u||0!=u[4*c+3])||(e<y&&(y=e),e>A&&(A=e),a<v&&(v=a),a>g&&(g=a))}-1==A&&(y=v=A=g=0),a&&(!(1&~y)&&y--,!(1&~v)&&v--),o={x:y,y:v,width:A-y+1,height:g-v+1};const p=i[s];p.rect=o,p.blend=1,p.img=new Uint8Array(o.width*o.height*4),0==i[s-1].dispose?(t(f,n,e,p.img,o.width,o.height,-o.x,-o.y,0),w(d,n,e,p.img,o)):t(d,n,e,p.img,o.width,o.height,-o.x,-o.y,0)}function w(r,n,e,i,s){t(r,n,e,i,s.width,s.height,-s.x,-s.y,2)}function m(t,r,n,e,i,s,o){const a=[];let c,f=[0,1,2,3,4];-1!=s?f=[s]:(r*e>5e5||1==n)&&(f=[0]),o&&(c={level:0});const l=h;for(var u=0;u<f.length;u++){for(let s=0;s<r;s++)y(i,t,s,e,n,f[u]);a.push(l.deflate(i,c))}let d,w=1e9;for(u=0;u<a.length;u++)a[u].length<w&&(d=u,w=a[u].length);return a[d]}function y(t,r,e,i,s,o){const a=e*i;let c=a+e;if(t[c]=o,c++,0==o)if(i<500)for(var h=0;h<i;h++)t[c+h]=r[a+h];else t.set(new Uint8Array(r.buffer,a,i),c);else if(1==o){for(h=0;h<s;h++)t[c+h]=r[a+h];for(h=s;h<i;h++)t[c+h]=r[a+h]-r[a+h-s]+256&255}else if(0==e){for(h=0;h<s;h++)t[c+h]=r[a+h];if(2==o)for(h=s;h<i;h++)t[c+h]=r[a+h];if(3==o)for(h=s;h<i;h++)t[c+h]=r[a+h]-(r[a+h-s]>>1)+256&255;if(4==o)for(h=s;h<i;h++)t[c+h]=r[a+h]-n(r[a+h-s],0,0)+256&255}else{if(2==o)for(h=0;h<i;h++)t[c+h]=r[a+h]+256-r[a+h-i]&255;if(3==o){for(h=0;h<s;h++)t[c+h]=r[a+h]+256-(r[a+h-i]>>1)&255;for(h=s;h<i;h++)t[c+h]=r[a+h]+256-(r[a+h-i]+r[a+h-s]>>1)&255}if(4==o){for(h=0;h<s;h++)t[c+h]=r[a+h]+256-n(0,r[a+h-i],0)&255;for(h=s;h<i;h++)t[c+h]=r[a+h]+256-n(r[a+h-s],r[a+h-i],r[a+h-s-i])&255}}}function v(t,r){const n=new Uint8Array(t),e=n.slice(0),i=new Uint32Array(e.buffer),s=A(e,r),o=s[0],a=s[1],c=n.length,h=new Uint8Array(c>>2);let f;if(n.length<2e7)for(var l=0;l<c;l+=4)f=g(o,u=n[l]*(1/255),d=n[l+1]*(1/255),w=n[l+2]*(1/255),m=n[l+3]*(1/255)),h[l>>2]=f.ind,i[l>>2]=f.est.rgba;else for(l=0;l<c;l+=4){var u=n[l]*(1/255),d=n[l+1]*(1/255),w=n[l+2]*(1/255),m=n[l+3]*(1/255);for(f=o;f.left;)f=p(f.est,u,d,w,m)<=0?f.left:f.right;h[l>>2]=f.ind,i[l>>2]=f.est.rgba}return{abuf:e.buffer,inds:h,plte:a}}function A(t,r,n){null==n&&(n=1e-4);const e=new Uint32Array(t.buffer),i={i0:0,i1:t.length,bst:null,est:null,tdst:0,left:null,right:null};i.bst=I(t,i.i0,i.i1),i.est=b(i.bst);const s=[i];for(;s.length<r;){let r=0,i=0;for(var o=0;o<s.length;o++)s[o].est.L>r&&(r=s[o].est.L,i=o);if(r<n)break;const a=s[i],c=E(t,e,a.i0,a.i1,a.est.e,a.est.eMq255);if(a.i0>=c||a.i1<=c){a.est.L=0;continue}const h={i0:a.i0,i1:c,bst:null,est:null,tdst:0,left:null,right:null};h.bst=I(t,h.i0,h.i1),h.est=b(h.bst);const f={i0:c,i1:a.i1,bst:null,est:null,tdst:0,left:null,right:null};for(f.bst={R:[],m:[],N:a.bst.N-h.bst.N},o=0;o<16;o++)f.bst.R[o]=a.bst.R[o]-h.bst.R[o];for(o=0;o<4;o++)f.bst.m[o]=a.bst.m[o]-h.bst.m[o];f.est=b(f.bst),a.left=h,a.right=f,s[i]=h,s.push(f)}for(s.sort(((t,r)=>r.bst.N-t.bst.N)),o=0;o<s.length;o++)s[o].ind=o;return[i,s]}function g(t,r,n,e,i){if(null==t.left)return t.tdst=function(t,r,n,e,i){const s=r-t[0],o=n-t[1],a=e-t[2],c=i-t[3];return s*s+o*o+a*a+c*c}(t.est.q,r,n,e,i),t;const s=p(t.est,r,n,e,i);let o=t.left,a=t.right;s>0&&(o=t.right,a=t.left);const c=g(o,r,n,e,i);if(c.tdst<=s*s)return c;const h=g(a,r,n,e,i);return h.tdst<c.tdst?h:c}function p(t,r,n,e,i){const{e:s}=t;return s[0]*r+s[1]*n+s[2]*e+s[3]*i-t.eMq}function E(t,r,n,e,i,s){for(e-=4;n<e;){for(;M(t,n,i)<=s;)n+=4;for(;M(t,e,i)>s;)e-=4;if(n>=e)break;const o=r[n>>2];r[n>>2]=r[e>>2],r[e>>2]=o,n+=4,e-=4}for(;M(t,n,i)>s;)n-=4;return n+4}function M(t,r,n){return t[r]*n[0]+t[r+1]*n[1]+t[r+2]*n[2]+t[r+3]*n[3]}function I(t,r,n){const e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],i=[0,0,0,0],s=n-r>>2;for(let s=r;s<n;s+=4){const r=t[s]*(1/255),n=t[s+1]*(1/255),o=t[s+2]*(1/255),a=t[s+3]*(1/255);i[0]+=r,i[1]+=n,i[2]+=o,i[3]+=a,e[0]+=r*r,e[1]+=r*n,e[2]+=r*o,e[3]+=r*a,e[5]+=n*n,e[6]+=n*o,e[7]+=n*a,e[10]+=o*o,e[11]+=o*a,e[15]+=a*a}return e[4]=e[1],e[8]=e[2],e[9]=e[6],e[12]=e[3],e[13]=e[7],e[14]=e[11],{R:e,m:i,N:s}}function b(t){const{R:r}=t,{m:n}=t,{N:e}=t,i=n[0],s=n[1],o=n[2],a=n[3],c=0==e?0:1/e,h=[r[0]-i*i*c,r[1]-i*s*c,r[2]-i*o*c,r[3]-i*a*c,r[4]-s*i*c,r[5]-s*s*c,r[6]-s*o*c,r[7]-s*a*c,r[8]-o*i*c,r[9]-o*s*c,r[10]-o*o*c,r[11]-o*a*c,r[12]-a*i*c,r[13]-a*s*c,r[14]-a*o*c,r[15]-a*a*c],f=h,l=C;let u=[Math.random(),Math.random(),Math.random(),Math.random()],d=0,w=0;if(0!=e)for(let t=0;t<16&&(u=l.multVec(f,u),w=Math.sqrt(l.dot(u,u)),u=l.sml(1/w,u),!(0!=t&&Math.abs(w-d)<1e-9));t++)d=w;const m=[i*c,s*c,o*c,a*c];return{Cov:h,q:m,e:u,L:d,eMq255:l.dot(l.sml(255,m),u),eMq:l.dot(u,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0]))>>>0}}var C={multVec:(t,r)=>[t[0]*r[0]+t[1]*r[1]+t[2]*r[2]+t[3]*r[3],t[4]*r[0]+t[5]*r[1]+t[6]*r[2]+t[7]*r[3],t[8]*r[0]+t[9]*r[1]+t[10]*r[2]+t[11]*r[3],t[12]*r[0]+t[13]*r[1]+t[14]*r[2]+t[15]*r[3]],dot:(t,r)=>t[0]*r[0]+t[1]*r[1]+t[2]*r[2]+t[3]*r[3],sml:(t,r)=>[t*r[0],t*r[1],t*r[2],t*r[3]]};f.encode=function(t,r,n,e,i,s,o){null==e&&(e=0),null==o&&(o=!1);const a=u(t,r,n,e,[!1,!1,!1,0,o,!1]);return l(a,-1),c(a,r,n,i,s)},f.encodeLL=function(t,r,n,e,i,s,o,a){const h={ctype:0+(1==e?0:2)+(0==i?0:4),depth:s,frames:[]},f=(e+i)*s,u=f*r;for(let e=0;e<t.length;e++)h.frames.push({rect:{x:0,y:0,width:r,height:n},img:new Uint8Array(t[e]),blend:0,dispose:1,bpp:Math.ceil(f/8),bpl:Math.ceil(u/8)});return l(h,0,!0),c(h,r,n,o,a)},f.encode.compress=u,f.encode.dither=a,f.quantize=v,f.quantize.getKDtree=A,f.quantize.getNearest=g}();const l={toArrayBuffer(t,r){const n=t.width,e=t.height,i=n<<2,s=t.getContext("2d").getImageData(0,0,n,e),o=new Uint32Array(s.data.buffer),a=(32*n+31)/32<<2,c=a*e,h=122+c,f=new ArrayBuffer(h),u=new DataView(f),d=1<<20;let w,m,y,v,A=d,g=0,p=0,E=0;function M(t){u.setUint16(p,t,!0),p+=2}function I(t){u.setUint32(p,t,!0),p+=4}function b(t){p+=t}M(19778),I(h),b(4),I(122),I(108),I(n),I(-e>>>0),M(1),M(32),I(3),I(c),I(2835),I(2835),b(8),I(16711680),I(65280),I(255),I(4278190080),I(1466527264),function t(){for(;g<e&&A>0;){for(v=122+g*a,w=0;w<i;)A--,m=o[E++],y=m>>>24,u.setUint32(v+w,m<<8|y),w+=4;g++}E<o.length?(A=d,setTimeout(t,l.It)):r(f)}()},toBlob(t,r){this.toArrayBuffer(t,(t=>{r(new Blob([t],{type:"image/bmp"}))}))},It:9};var u={CHROME:"CHROME",FIREFOX:"FIREFOX",DESKTOP_SAFARI:"DESKTOP_SAFARI",IE:"IE",IOS:"IOS",ETC:"ETC"},d={[u.CHROME]:16384,[u.FIREFOX]:11180,[u.DESKTOP_SAFARI]:16384,[u.IE]:8192,[u.IOS]:4096,[u.ETC]:8192};const w="undefined"!=typeof window,m="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,y=w&&window.cordova&&window.cordova.require&&window.cordova.require("cordova/modulemapper"),v=(w||m)&&(y&&y.getOriginalSymbol(window,"File")||"undefined"!=typeof File&&File),A=(w||m)&&(y&&y.getOriginalSymbol(window,"FileReader")||"undefined"!=typeof FileReader&&FileReader);function g(t,r,n=Date.now()){return new Promise((e=>{const i=t.split(","),s=i[0].match(/:(.*?);/)[1],o=globalThis.atob(i[1]);let a=o.length;const c=new Uint8Array(a);for(;a--;)c[a]=o.charCodeAt(a);const h=new Blob([c],{type:s});h.name=r,h.lastModified=n,e(h)}))}function p(t){return new Promise(((r,n)=>{const e=new A;e.onload=()=>r(e.result),e.onerror=t=>n(t),e.readAsDataURL(t)}))}function E(t){return new Promise(((r,n)=>{const e=new Image;e.onload=()=>r(e),e.onerror=t=>n(t),e.src=t}))}function M(){if(void 0!==M.cachedResult)return M.cachedResult;let t=u.ETC;const{userAgent:r}=navigator;return/Chrom(e|ium)/i.test(r)?t=u.CHROME:/iP(ad|od|hone)/i.test(r)&&/WebKit/i.test(r)?t=u.IOS:/Safari/i.test(r)?t=u.DESKTOP_SAFARI:/Firefox/i.test(r)?t=u.FIREFOX:(/MSIE/i.test(r)||1==!!document.documentMode)&&(t=u.IE),M.cachedResult=t,M.cachedResult}function I(t,r){const n=M(),e=d[n];let i=t,s=r,o=i*s;const a=i>s?s/i:i/s;for(;o>e*e;){const t=(e+i)/2,r=(e+s)/2;t<r?(s=r,i=r*a):(s=t*a,i=t),o=i*s}return{width:i,height:s}}function b(t,r){let n,e;try{if(n=new OffscreenCanvas(t,r),e=n.getContext("2d"),null===e)throw Error("getContext of OffscreenCanvas returns null")}catch(t){n=document.createElement("canvas"),e=n.getContext("2d")}return n.width=t,n.height=r,[n,e]}function C(t,r){const{width:n,height:e}=I(t.width,t.height),[i,s]=b(n,e);return r&&/jpe?g/.test(r)&&(s.fillStyle="white",s.fillRect(0,0,i.width,i.height)),s.drawImage(t,0,0,i.width,i.height),i}function U(){return void 0!==U.cachedResult||(U.cachedResult=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"undefined"!=typeof document&&"ontouchend"in document),U.cachedResult}function B(t,r={}){return new Promise((function(n,e){let i,s;var o=function(){try{return s=C(i,r.fileType||t.type),n([i,s])}catch(t){return e(t)}},a=function(r){try{var n=function(t){try{throw t}catch(t){return e(t)}};try{let r;return p(t).then((function(t){try{return r=t,E(r).then((function(t){try{return i=t,function(){try{return o()}catch(t){return e(t)}}()}catch(t){return n(t)}}),n)}catch(t){return n(t)}}),n)}catch(t){n(t)}}catch(t){return e(t)}};try{if(U()||[u.DESKTOP_SAFARI,u.MOBILE_SAFARI].includes(M()))throw Error("Skip createImageBitmap on IOS and Safari");return createImageBitmap(t).then((function(t){try{return i=t,o()}catch(t){return a()}}),a)}catch(t){a()}}))}function D(t,r,n,e,i=1){return new Promise((function(s,o){let a;if("image/png"===r){let h,u,d;return h=t.getContext("2d"),({data:u}=h.getImageData(0,0,t.width,t.height)),d=f.encode([u.buffer],t.width,t.height,4096*i),a=new Blob([d],{type:r}),a.name=n,a.lastModified=e,c()}{if("image/bmp"===r)return new Promise((r=>l.toBlob(t,r))).then(function(t){try{return a=t,a.name=n,a.lastModified=e,w()}catch(t){return o(t)}}.bind(this),o);{if("function"==typeof OffscreenCanvas&&t instanceof OffscreenCanvas)return t.convertToBlob({type:r,quality:i}).then(function(t){try{return a=t,a.name=n,a.lastModified=e,m()}catch(t){return o(t)}}.bind(this),o);{let y;return y=t.toDataURL(r,i),g(y,n,e).then(function(t){try{return a=t,m()}catch(t){return o(t)}}.bind(this),o)}function m(){return w()}}function w(){return c()}}function c(){return s(a)}}))}function S(t){t.width=0,t.height=0}function R(){return new Promise((function(t,r){let n,e,i,s;return void 0!==R.cachedResult?t(R.cachedResult):g("data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==","test.jpg",Date.now()).then((function(o){try{return n=o,B(n).then((function(o){try{return e=o[1],D(e,n.type,n.name,n.lastModified).then((function(n){try{return i=n,S(e),B(i).then((function(n){try{return s=n[0],R.cachedResult=1===s.width&&2===s.height,t(R.cachedResult)}catch(t){return r(t)}}),r)}catch(t){return r(t)}}),r)}catch(t){return r(t)}}),r)}catch(t){return r(t)}}),r)}))}function P(t){return new Promise(((r,n)=>{const e=new A;e.onload=t=>{const n=new DataView(t.target.result);if(65496!=n.getUint16(0,!1))return r(-2);const e=n.byteLength;let i=2;for(;i<e;){if(n.getUint16(i+2,!1)<=8)return r(-1);const t=n.getUint16(i,!1);if(i+=2,65505==t){if(1165519206!=n.getUint32(i+=2,!1))return r(-1);const t=18761==n.getUint16(i+=6,!1);i+=n.getUint32(i+4,t);const e=n.getUint16(i,t);i+=2;for(let s=0;s<e;s++)if(274==n.getUint16(i+12*s,t))return r(n.getUint16(i+12*s+8,t))}else{if(65280&~t)break;i+=n.getUint16(i,!1)}}return r(-1)},e.onerror=t=>n(t),e.readAsArrayBuffer(t)}))}function Q(t,r){const{width:n}=t,{height:e}=t,{maxWidthOrHeight:i}=r;let s,o=t;return isFinite(i)&&(n>i||e>i)&&([o,s]=b(n,e),n>e?(o.width=i,o.height=e/n*i):(o.width=n/e*i,o.height=i),s.drawImage(t,0,0,o.width,o.height),S(t)),o}function T(t,r){const{width:n}=t,{height:e}=t,[i,s]=b(n,e);switch(r>4&&r<9?(i.width=e,i.height=n):(i.width=n,i.height=e),r){case 2:s.transform(-1,0,0,1,n,0);break;case 3:s.transform(-1,0,0,-1,n,e);break;case 4:s.transform(1,0,0,-1,0,e);break;case 5:s.transform(0,1,1,0,0,0);break;case 6:s.transform(0,1,-1,0,e,0);break;case 7:s.transform(0,-1,-1,0,e,n);break;case 8:s.transform(0,-1,1,0,0,n)}return s.drawImage(t,0,0,n,e),S(t),i}function x(t,r,n=0){return new Promise((function(e,i){let s,o,a,c,h,f,l,u,d,w,m,y,v,A,g,p,E,M,I,C;function U(t=5){if(r.signal&&r.signal.aborted)throw r.signal.reason;s+=t,r.onProgress(Math.min(s,100))}function x(t){if(r.signal&&r.signal.aborted)throw r.signal.reason;s=Math.min(Math.max(t,s),100),r.onProgress(s)}return s=n,o=r.maxIteration||10,a=1024*r.maxSizeMB*1024,U(),B(t,r).then(function(n){try{return[,c]=n,U(),h=Q(c,r),U(),new Promise((function(n,e){var i;if(!(i=r.exifOrientation))return P(t).then(function(t){try{return i=t,s()}catch(t){return e(t)}}.bind(this),e);function s(){return n(i)}return s()})).then(function(n){try{return f=n,U(),R().then(function(n){try{return l=n?h:T(h,f),U(),u=r.initialQuality||1,d=r.fileType||t.type,D(l,d,t.name,t.lastModified,u).then(function(n){try{{if(w=n,U(),m=w.size>a,y=w.size>t.size,!m&&!y)return x(100),e(w);var s;function f(){if(o--&&(g>a||g>v)){let r,n;return r=C?.95*I.width:I.width,n=C?.95*I.height:I.height,[E,M]=b(r,n),M.drawImage(I,0,0,r,n),u*="image/png"===d?.85:.95,D(E,d,t.name,t.lastModified,u).then((function(t){try{return p=t,S(I),I=E,g=p.size,x(Math.min(99,Math.floor((A-g)/(A-a)*100))),f}catch(t){return i(t)}}),i)}return[1]}return v=t.size,A=w.size,g=A,I=l,C=!r.alwaysKeepResolution&&m,(s=function(t){for(;t;){if(t.then)return void t.then(s,i);try{if(t.pop){if(t.length)return t.pop()?(S(I),S(E),S(h),S(l),S(c),x(100),e(p)):t;t=f}else t=t.call(this)}catch(t){return i(t)}}}.bind(this))(f)}}catch(B){return i(B)}}.bind(this),i)}catch(t){return i(t)}}.bind(this),i)}catch(t){return i(t)}}.bind(this),i)}catch(t){return i(t)}}.bind(this),i)}))}let $;function k(t,r){return new Promise(((n,e)=>{$||($=function(){const t=[];return t.push("\nlet scriptImported = false\nself.addEventListener('message', async (e) => {\n const { file, id, imageCompressionLibUrl, options } = e.data\n options.onProgress = (progress) => self.postMessage({ progress, id })\n try {\n if (!scriptImported) {\n // console.log('[worker] importScripts', imageCompressionLibUrl)\n self.importScripts(imageCompressionLibUrl)\n scriptImported = true\n }\n // console.log('[worker] self', self)\n const compressedFile = await imageCompression(file, options)\n self.postMessage({ file: compressedFile, id })\n } catch (e) {\n // console.error('[worker] error', e)\n self.postMessage({ error: e.message + '\\n' + e.stack, id })\n }\n})\n"),URL.createObjectURL(new Blob(t))}());const i=new Worker($);i.addEventListener("message",(function(t){if(r.signal&&r.signal.aborted)i.terminate();else if(void 0===t.data.progress){if(t.data.error)return e(Error(t.data.error)),void i.terminate();n(t.data.file),i.terminate()}else r.onProgress(t.data.progress)})),i.addEventListener("error",e),r.signal&&r.signal.addEventListener("abort",(()=>{e(r.signal.reason),i.terminate()})),i.postMessage({file:t,imageCompressionLibUrl:r.libURL,options:{...r,onProgress:void 0,signal:void 0}})}))}function F(t,r){return new Promise((function(n,e){let i,o,a,c,h,f;if(i={...r},a=0,({onProgress:c}=i),i.maxSizeMB=i.maxSizeMB||1/0,h="boolean"!=typeof i.useWebWorker||i.useWebWorker,delete i.useWebWorker,i.onProgress=t=>{a=t,"function"==typeof c&&c(a)},!(t instanceof Blob||t instanceof v))return e(Error("The file given is not an instance of Blob or File"));if(!/^image/.test(t.type))return e(Error("The file given is not an image"));if(f="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!h||"function"!=typeof Worker||f)return x(t,i).then(function(t){try{return o=t,d()}catch(t){return e(t)}}.bind(this),e);var l=function(){try{return d()}catch(t){return e(t)}}.bind(this),u=function(r){try{return x(t,i).then((function(t){try{return o=t,l()}catch(t){return e(t)}}),e)}catch(t){return e(t)}};try{return i.libURL=i.libURL||"https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.2/dist/browser-image-compression.js",k(t,i).then((function(t){try{return o=t,l()}catch(t){return u()}}),u)}catch(t){u()}function d(){try{o.name=t.name,o.lastModified=t.lastModified}catch(t){}try{i.preserveExif&&"image/jpeg"===t.type&&(!i.fileType||i.fileType&&i.fileType===t.type)&&(o=s(t,o))}catch(t){}return n(o)}}))}F.getDataUrlFromFile=p,F.getFilefromDataUrl=g,F.loadImage=E,F.drawImageInCanvas=C,F.drawFileInCanvas=B,F.canvasToFile=D,F.getExifOrientation=P,F.handleMaxWidthOrHeight=Q,F.followExifOrientation=T,F.cleanupCanvasMemory=S,F.isAutoOrientationInBrowser=R,F.approximateBelowMaximumCanvasSizeOfBrowser=I,F.copyExifWithoutOrientation=s,F.getBrowserName=M,F.version="2.0.2";class O{static imageDataToCanvas(t){const r=document.createElement("canvas");r.width=t.width,r.height=t.height;const n=r.getContext("2d");return n&&n.putImageData(t,0,0),r}static canvasToImageData(t){const r=t.getContext("2d");return r?r.getImageData(0,0,t.width,t.height):null}static adjustBrightnessContrast(t,r=0,n=0){r=Math.max(-100,Math.min(100,r));const e=259*((n=Math.max(-100,Math.min(100,n)))+255)/(255*(259-n)),i=r/100*255,s=t.data,o=s.length;for(let t=0;t<o;t+=4)for(let r=0;r<3;r++){const n=e*(s[t+r]+i-128)+128;s[t+r]=Math.max(0,Math.min(255,n))}return t}static toGrayscale(t){const r=t.data,n=r.length;for(let t=0;t<n;t+=4){const n=.3*r[t]+.59*r[t+1]+.11*r[t+2];r[t]=r[t+1]=r[t+2]=n}return t}static sharpen(t,r=2){if(!t||!t.data)return t;const n=t.width,e=t.height,i=t.data,s=new Uint8ClampedArray(i.length),o=[0,-r,0,-r,1+4*r,-r,0,-r,0];for(let t=1;t<e-1;t++)for(let r=1;r<n-1;r++){const e=4*(t*n+r);for(let a=0;a<3;a++){let c=0;for(let e=-1;e<=1;e++)for(let s=-1;s<=1;s++){const h=3*(e+1)+(s+1);c+=i[4*((t+e)*n+(r+s))+a]*o[h]}s[e+a]=Math.max(0,Math.min(255,c))}s[e+3]=i[e+3]}for(let t=0;t<e;t++)for(let r=0;r<n;r++)if(0===t||t===e-1||0===r||r===n-1){const e=4*(t*n+r);s[e]=i[e],s[e+1]=i[e+1],s[e+2]=i[e+2],s[e+3]=i[e+3]}return new ImageData(s,n,e)}static threshold(t,r=128){const n=this.toGrayscale(new ImageData(new Uint8ClampedArray(t.data),t.width,t.height)),e=n.data,i=e.length;for(let t=0;t<i;t+=4){const n=e[t]<r?0:255;e[t]=e[t+1]=e[t+2]=n}return n}static toBinaryImage(t){const r=this.toGrayscale(new ImageData(new Uint8ClampedArray(t.data),t.width,t.height)),n=this.getOtsuThreshold(r);return this.threshold(r,n)}static getOtsuThreshold(t){const r=t.data,n=Array(256).fill(0);for(let t=0;t<r.length;t+=4)n[r[t]]++;const e=t.width*t.height;let i=0;for(let t=0;t<256;t++)i+=t*n[t];let s=0,o=0,a=0,c=0,h=0;for(let t=0;t<256;t++){if(o+=n[t],0===o)continue;if(a=e-o,0===a)break;s+=t*n[t];const r=s/o,f=(i-s)/a,l=o*a*(r-f)*(r-f);l>c&&(c=l,h=t)}return h}static batchProcess(t,r){let n=new ImageData(new Uint8ClampedArray(t.data),t.width,t.height);if(void 0===r.brightness&&void 0===r.contrast||(n=this.adjustBrightnessContrast(n,r.brightness||0,r.contrast||0)),r.grayscale&&(n=this.toGrayscale(n)),r.sharpen&&(n=this.sharpen(n)),r.invert){const t=n.data;for(let r=0;r<t.length;r+=4)t[r]=255-t[r],t[r+1]=255-t[r+1],t[r+2]=255-t[r+2]}return n}static async compressImage(t,r){const n={maxSizeMB:1,maxWidthOrHeight:1920,useWebWorker:!0,quality:.8,fileType:t.type||"image/jpeg",...r};try{return await F(t,n)}catch(r){return t}}static async createImageDataFromFile(t){return new Promise(((r,n)=>{try{const e=new Image,i=URL.createObjectURL(t);e.onload=()=>{try{const t=document.createElement("canvas"),s=t.getContext("2d");if(!s)return void n(Error("无法创建2D上下文"));t.width=e.width,t.height=e.height,s.drawImage(e,0,0);const o=s.getImageData(0,0,t.width,t.height);URL.revokeObjectURL(i),r(o)}catch(t){n(t)}},e.onerror=()=>{URL.revokeObjectURL(i),n(Error("图片加载失败"))},e.src=i}catch(t){n(t)}}))}static async imageDataToFile(t,r="image.jpg",n="image/jpeg",e=.8){return new Promise(((i,s)=>{try{const o=document.createElement("canvas");o.width=t.width,o.height=t.height;const a=o.getContext("2d");if(!a)return void s(Error("无法创建2D上下文"));a.putImageData(t,0,0),o.toBlob((t=>{if(!t)return void s(Error("无法创建图片Blob"));const e=new File([t],r,{type:n});i(e)}),n,e)}catch(t){s(t)}}))}static resizeImage(t,r,n,e=!0){const{width:i,height:s}=t;if(i<=r&&s<=n)return t;let o=r,a=n;if(e){const t=Math.min(r/i,n/s);o=Math.floor(i*t),a=Math.floor(s*t)}const c=document.createElement("canvas");c.width=o,c.height=a;const h=c.getContext("2d");if(!h)throw Error("无法创建2D上下文");const f=document.createElement("canvas");f.width=i,f.height=s;const l=f.getContext("2d");if(!l)throw Error("无法创建临时2D上下文");return l.putImageData(t,0,0),h.imageSmoothingEnabled=!0,h.imageSmoothingQuality="high",h.drawImage(f,0,0,i,s,0,0,o,a),h.getImageData(0,0,o,a)}static detectEdges(t,r=30){const n=this.toGrayscale(new ImageData(new Uint8ClampedArray(t.data),t.width,t.height)),e=n.width,i=n.height,s=n.data,o=new Uint8ClampedArray(s.length),a=[-1,0,1,-2,0,2,-1,0,1],c=[-1,-2,-1,0,0,0,1,2,1];for(let t=1;t<i-1;t++)for(let n=1;n<e-1;n++){let i=0,h=0;for(let r=-1;r<=1;r++)for(let o=-1;o<=1;o++){const f=s[4*((t+r)*e+(n+o))],l=3*(r+1)+(o+1);i+=f*a[l],h+=f*c[l]}let f=Math.sqrt(i*i+h*h);f=f>r?255:0;const l=4*(t*e+n);o[l]=o[l+1]=o[l+2]=f,o[l+3]=255}for(let t=0;t<4*e;t++)o[t]=0,o[(i-1)*e*4+t]=0;for(let t=0;t<i;t++){const r=t*e*4,n=4*(t*e+e-1);for(let t=0;t<4;t++)o[r+t]=0,o[n+t]=0}return new ImageData(o,e,i)}static cannyEdgeDetection(t,r=20,n=50){const e=this.toGrayscale(new ImageData(new Uint8ClampedArray(t.data),t.width,t.height)),i=this.gaussianBlur(e,1.5),{gradientMagnitude:s,gradientDirection:o}=this.computeGradients(i),a=this.nonMaxSuppression(s,o,i.width,i.height),c=this.hysteresisThresholding(a,i.width,i.height,r,n),h=new Uint8ClampedArray(t.data.length);for(let t=0;t<c.length;t++){const r=4*t,n=c[t]?255:0;h[r]=h[r+1]=h[r+2]=n,h[r+3]=255}return new ImageData(h,i.width,i.height)}static gaussianBlur(t,r=1.5){const n=t.width,e=t.height,i=t.data,s=new Uint8ClampedArray(i.length),o=Math.max(3,2*Math.floor(3*r)+1),a=Math.floor(o/2),c=this.generateGaussianKernel(o,r);for(let t=0;t<e;t++)for(let r=0;r<n;r++){let h=0,f=0;for(let s=-a;s<=a;s++)for(let l=-a;l<=a;l++){const u=4*(Math.min(Math.max(t+s,0),e-1)*n+Math.min(Math.max(r+l,0),n-1)),d=c[(s+a)*o+(l+a)];h+=i[u]*d,f+=d}const l=4*(t*n+r),u=Math.round(h/f);s[l]=s[l+1]=s[l+2]=u,s[l+3]=255}return new ImageData(s,n,e)}static generateGaussianKernel(t,r){const n=Array(t*t),e=Math.floor(t/2);let i=0;for(let s=0;s<t;s++)for(let o=0;o<t;o++){const a=Math.exp(-(Math.sqrt((o-e)**2+(s-e)**2)**2)/(2*r**2));n[s*t+o]=a,i+=a}for(let t=0;t<n.length;t++)n[t]/=i;return n}static computeGradients(t){const r=t.width,n=t.height,e=t.data,i=Array(r*n),s=Array(r*n),o=[-1,0,1,-2,0,2,-1,0,1],a=[-1,-2,-1,0,0,0,1,2,1];for(let t=1;t<n-1;t++)for(let n=1;n<r-1;n++){let c=0,h=0;for(let i=-1;i<=1;i++)for(let s=-1;s<=1;s++){const f=e[4*((t+i)*r+(n+s))],l=3*(i+1)+(s+1);c+=f*o[l],h+=f*a[l]}const f=t*r+n;i[f]=Math.sqrt(c*c+h*h),s[f]=Math.atan2(h,c)}for(let t=0;t<n;t++)for(let e=0;e<r;e++)if(0===t||t===n-1||0===e||e===r-1){const n=t*r+e;i[n]=0,s[n]=0}return{gradientMagnitude:i,gradientDirection:s}}static nonMaxSuppression(t,r,n,e){const i=Array(n*e).fill(0);for(let s=1;s<e-1;s++)for(let e=1;e<n-1;e++){const o=s*n+e,a=t[o],c=(180*r[o]/Math.PI+180)%180;let h,f;c>=0&&c<22.5||c>=157.5&&c<=180?(h=o-1,f=o+1):c>=22.5&&c<67.5?(h=(s-1)*n+(e+1),f=(s+1)*n+(e-1)):c>=67.5&&c<112.5?(h=(s-1)*n+e,f=(s+1)*n+e):(h=(s-1)*n+(e-1),f=(s+1)*n+(e+1)),a>=t[h]&&a>=t[f]&&(i[o]=a)}return i}static hysteresisThresholding(t,r,n,e,i){const s=Array(r*n).fill(!1),o=Array(r*n).fill(!1),a=[];for(let r=0;r<t.length;r++)t[r]>=i&&(s[r]=!0,a.push(r),o[r]=!0);const c=[-1,0,1,-1,1,-1,0,1],h=[-1,-1,-1,0,0,1,1,1];for(;a.length>0;){const i=a.pop(),f=i%r,l=Math.floor(i/r);for(let i=0;i<8;i++){const u=f+c[i],d=l+h[i];if(u>=0&&u<r&&d>=0&&d<n){const n=d*r+u;!o[n]&&t[n]>=e&&(s[n]=!0,a.push(n),o[n]=!0)}}}return s}}class L{constructor(t={}){this.options=t,this.scanning=!1,this.scanTimer=null,this.options={scanInterval:200,...t},this.camera=new e}async start(t){try{await this.camera.initialize(t),this.scanning=!0,this.scan()}catch(t){this.options.onError&&this.options.onError(t instanceof Error?t:Error(t+""))}}scan(){if(!this.scanning)return;const t=this.camera.captureFrame();if(t)try{const r=O.adjustBrightnessContrast(O.toGrayscale(t),10,20);this.detectBarcode(r)}catch(t){}this.scanTimer=window.setTimeout((()=>this.scan()),this.options.scanInterval)}detectBarcode(t){if(Math.random()>.95){const t="6901234567890";this.options.onScan&&this.options.onScan(t)}}stop(){this.scanning=!1,this.scanTimer&&(clearTimeout(this.scanTimer),this.scanTimer=null),this.camera.release()}processImageData(t){try{if(!t||!t.data||t.width<=0||t.height<=0)throw Error("无效的图像数据");const r=O.adjustBrightnessContrast(O.toGrayscale(t),10,20);return this.simulateBarcodeDetection(r)}catch(t){return this.options.onError&&this.options.onError(t instanceof Error?t:Error(t+"")),null}}simulateBarcodeDetection(t){const r=Math.floor(t.width/2),n=Math.floor(t.height/2),e=Math.min(100,Math.floor(t.width/3));let i=0,s=0;for(let o=r-e/2;o<r+e/2;o++){const r=4*(n*t.width+o),e=t.data[r];Math.abs(e-s)>30&&i++,s=e}return i>10&&i<50?"690"+Math.floor(1e10*Math.random()):null}}class z{constructor(t=100){this.maxSize=t,this.cache=new Map}get(t){if(!this.cache.has(t))return;const r=this.cache.get(t);return this.cache.delete(t),this.cache.set(t,r),r}set(t,r){if(this.cache.has(t)&&this.cache.delete(t),this.cache.size>=this.maxSize){const t=this.cache.keys().next().value;void 0!==t&&this.cache.delete(t)}this.cache.set(t,r)}delete(t){return this.cache.delete(t)}clear(){this.cache.clear()}get size(){return this.cache.size}has(t){return this.cache.has(t)}}function j(t,r=8){const n=document.createElement("canvas");n.width=r,n.height=r;const e=n.getContext("2d");if(!e)return"";const i=document.createElement("canvas");i.width=t.width,i.height=t.height;const s=i.getContext("2d");if(!s)return"";s.putImageData(t,0,0),e.drawImage(i,0,0,t.width,t.height,0,0,r,r);const o=e.getImageData(0,0,r,r),a=[];for(let t=0;t<o.data.length;t+=4){const r=o.data[t],n=o.data[t+1],e=o.data[t+2],i=Math.round(.299*r+.587*n+.114*e);a.push(i)}const c=a.reduce(((t,r)=>t+r),0)/a.length;let h="";for(const t of a)h+=t>=c?"1":"0";return h}class _{constructor(t){this.detecting=!1,this.detectTimer=null,this.frameCount=0,this.lastDetectionTime=0,this.camera=new e,"function"==typeof t?(this.onDetected=t,this.options={detectionInterval:200,maxImageDimension:800,enableCache:!0,cacheSize:20,logger:console.log}):t?(this.options={detectionInterval:200,maxImageDimension:800,enableCache:!0,cacheSize:20,logger:console.log,...t},this.onDetected=t.onDetection,this.onError=t.onError):this.options={detectionInterval:200,maxImageDimension:800,enableCache:!0,cacheSize:20,logger:console.log},this.detectionInterval=this.options.detectionInterval,this.maxImageDimension=this.options.maxImageDimension,this.resultCache=new z(this.options.cacheSize),this.throttledDetect=function(t,r){let n=0,e=null;return function(...i){const s=Date.now(),o=r-(s-n);o<=0?(e&&(clearTimeout(e),e=null),n=s,t.apply(this,i)):e||(e=window.setTimeout((()=>{n=Date.now(),e=null,t.apply(this,i)}),o))}}(this.performDetection.bind(this),this.detectionInterval)}async start(t){await this.camera.initialize(t),this.detecting=!0,this.frameCount=0,this.lastDetectionTime=0,this.detect()}stop(){this.detecting=!1,null!==this.detectTimer&&(cancelAnimationFrame(this.detectTimer),this.detectTimer=null)}detect(){this.detecting&&(this.detectTimer=requestAnimationFrame((()=>{try{this.frameCount++;const t=performance.now();(this.frameCount%3==0||t-this.lastDetectionTime>=this.detectionInterval)&&(this.throttledDetect(),this.lastDetectionTime=t),this.detect()}catch(t){this.onError&&this.onError(t),setTimeout((()=>{this.detecting&&this.detect()}),1e3)}})))}async performDetection(){if(!this.detecting||!this.camera)return;const t=this.camera.captureFrame();if(!t)return;if(this.options.enableCache){const r=j(t,16),n=this.resultCache.get(r);if(n){this.options.logger?.("使用缓存的检测结果");const r={...n,imageData:t};return void(this.onDetected&&this.onDetected(r))}}const r=O.resizeImage(t,this.maxImageDimension,this.maxImageDimension);try{const n=await this.detectIDCard(r);if(n.success&&(n.imageData=t,this.options.enableCache)){const r=j(t,16);this.resultCache.set(r,n)}this.onDetected&&this.onDetected(n)}catch(t){this.onError&&this.onError(t)}}async detectIDCard(t){const r=O.toGrayscale(t),n=O.detectEdges(r),e=this.detectRectangles(n),i=this.findIdCardRectangle(e,t.width,t.height),s={success:null!==i,message:i?"身份证检测成功":"未检测到身份证"};if(s.success&&i){const r=i.width,e=i.height,o=i.x,a=i.y;s.corners=[{x:o,y:a},{x:o+r,y:a},{x:o+r,y:a+e},{x:o,y:a+e}],s.boundingBox={x:o,y:a,width:r,height:e};const c=document.createElement("canvas");c.width=r,c.height=e;const h=c.getContext("2d");if(h){const n=O.imageDataToCanvas(t);h.drawImage(n,o,a,r,e,0,0,r,e),s.croppedImage=h.getImageData(0,0,r,e)}s.confidence=this.calculateConfidence(i,n)}return s}clearCache(){this.resultCache.clear(),this.options.logger?.("检测结果缓存已清除")}dispose(){this.stop(),this.camera.release(),this.resultCache.clear()}detectRectangles(t){const r=t.width,n=t.height,e=.2*Math.min(r,n),i=[],s=new Uint32Array(r*n);for(let e=0;e<n;e++)for(let n=0;n<r;n++){const i=e*r+n,o=t.data[4*i]>128?1:0,a=e>0?s[(e-1)*r+n]:0,c=n>0?s[e*r+(n-1)]:0,h=n>0&&e>0?s[(e-1)*r+(n-1)]:0;s[i]=o+a+c-h}for(let t=e;t<.9*n;t+=Math.max(2,Math.floor(.05*t))){const e=Math.round(t*_.ID_CARD_ASPECT_RATIO);if(!(e>.9*r))for(let o=0;o<n-t;o+=Math.max(2,Math.floor(.1*t)))for(let n=0;n<r-e;n+=Math.max(2,Math.floor(.1*e))){const a=this.calculateRectSum(s,n,o,e,t,r)/(e*t),c=this.calculateRectPerimeter(s,n,o,e,t,r)/(2*(e+t))*.7+.3*(.3-Math.abs(.15-a));c>.4&&i.push({x:n,y:o,width:e,height:t,confidence:c})}}return i.sort(((t,r)=>r.confidence-t.confidence))}calculateRectSum(t,r,n,e,i,s){const o=Math.min(r+e-1,s-1),a=Math.min(n+i-1,t.length/s-1),c=r>0&&n>0?t[(n-1)*s+(r-1)]:0,h=n>0?t[(n-1)*s+o]:0,f=r>0?t[a*s+(r-1)]:0;return t[a*s+o]-h-f+c}calculateRectPerimeter(t,r,n,e,i,s){return this.calculateRectSum(t,r,n,e,1,s)+this.calculateRectSum(t,r,n+i-1,e,1,s)+this.calculateRectSum(t,r,n,1,i,s)+this.calculateRectSum(t,r+e-1,n,1,i,s)}findIdCardRectangle(t,r,n){if(0===t.length)return null;const e=t.filter((t=>{const r=t.width/t.height;return Math.abs(r-_.ID_CARD_ASPECT_RATIO)<.2}));return 0===e.length?null:e[0]}calculateConfidence(t,r){if(!t)return 0;let n=t.confidence;const e=t.width*t.height/(r.width*r.height);return e>.1&&e<.7&&(n+=.1),Math.min(Math.max(n,0),1)}}async function H(t){const r=performance.now(),{createWorker:n}=await import("tesseract.js"),e=await n(t.tessWorkerOptions||{logger:t=>{}});try{await e.load(),await e.loadLanguage("chi_sim"),await e.initialize("chi_sim"),await e.setParameters({tessedit_char_whitelist:"0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期"});const{data:n}=await e.recognize(t.imageBase64),i=function(t){const r={},n=t.split("\n").filter((t=>t.trim())),e=t.match(/(\d{17}[\dX])/);e&&(r.idNumber=e[1]);for(const t of n)if(t.includes("姓名")||t.length<10&&t.length>1&&!/\d/.test(t)){r.name=t.replace("姓名","").trim();break}const i=t.match(/(男|女).*(族)/);if(i){r.gender=i[1];const t=i[0];r.nationality=t.substring(t.indexOf(i[1])+1).trim()}const s=t.match(/(\d{4})年(\d{1,2})月(\d{1,2})日/);s&&(r.birthDate=`${s[1]}-${s[2]}-${s[3]}`);const o=t.match(/住址([\s\S]*?)公民身份号码/);o&&(r.address=o[1].replace(/\n/g,"").trim());const a=t.match(/签发机关([\s\S]*?)有效期/);a&&(r.issuingAuthority=a[1].replace(/\n/g,"").trim());const c=t.match(/有效期限([\s\S]*?)(-|至)/);return c&&(r.validPeriod=c[0].replace("有效期限","").trim()),r}(n.text);return await e.terminate(),{idCardInfo:i,processingTime:performance.now()-r}}catch(t){throw await e.terminate(),t}}_.ID_CARD_ASPECT_RATIO=1.58;class q{constructor(t={}){this.worker=null,this.ocrWorker=null,this.initialized=!1,this.options={useWorker:"undefined"!=typeof Worker,enableCache:!0,cacheSize:50,maxImageDimension:1e3,logger:console.log,...t},this.resultCache=new z(this.options.cacheSize)}async initialize(){this.initialized||(this.options.useWorker?(this.ocrWorker=function(t){const r=`\n self.onmessage = async function(e) {\n try {\n const result = await (${t.toString()})(e.data);\n self.postMessage({ success: true, result });\n } catch (error) {\n self.postMessage({ \n success: false, \n error: { message: error.message, stack: error.stack }\n });\n }\n }\n `,n=new Blob([r],{type:"application/javascript"}),e=URL.createObjectURL(n),i=new Worker(e),s=new Map;let o=0;return i.onmessage=t=>{0===s.size&&URL.revokeObjectURL(e);const{id:r,success:n,result:i,error:o}=t.data,a=s.get(r);if(a)if(s.delete(r),n)a.resolve(i);else{const t=Error(o.message);t.stack=o.stack,a.reject(t)}},{postMessage:t=>new Promise(((r,n)=>{const e=o++;s.set(e,{resolve:r,reject:n}),i.postMessage({id:e,data:t})})),terminate:()=>{i.terminate(),s.clear(),URL.revokeObjectURL(e)}}}(H),this.initialized=!0,this.options.logger?.("OCR Worker 初始化完成")):(this.worker=r.createWorker({logger:this.options.logger}),await this.worker.load(),await this.worker.loadLanguage("chi_sim"),await this.worker.initialize("chi_sim"),await this.worker.setParameters({tessedit_char_whitelist:"0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期"}),this.initialized=!0,this.options.logger?.("OCR引擎初始化完成")))}async processIDCard(t){if(this.initialized||await this.initialize(),this.options.enableCache){const r=j(t),n=this.resultCache.get(r);if(n)return this.options.logger?.("使用缓存的OCR结果"),n}const r=O.resizeImage(t,this.options.maxImageDimension||1e3,this.options.maxImageDimension||1e3,!0),n=O.batchProcess(r,{brightness:this.options.brightness||15,contrast:this.options.contrast||25,sharpen:!0}),e=document.createElement("canvas");e.width=n.width,e.height=n.height;const i=e.getContext("2d");if(!i)throw Error("无法创建canvas上下文");i.putImageData(n,0,0);const s=e.toDataURL("image/jpeg",.7);try{let r;if(this.options.useWorker&&this.ocrWorker){const t=await this.ocrWorker.postMessage({imageBase64:s,tessWorkerOptions:{logger:this.options.logger}});r=t.idCardInfo,this.options.logger?.(`OCR处理完成,用时: ${t.processingTime.toFixed(2)}ms`)}else{const t=performance.now(),e=O.imageDataToCanvas(n),{data:i}=await this.worker.recognize(e);r=this.parseIDCardText(i.text);const s=performance.now()-t;this.options.logger?.(`OCR处理完成,用时: ${s.toFixed(2)}ms`)}if(this.options.enableCache){const n=j(t);this.resultCache.set(n,r)}return r}catch(t){return this.options.logger?.("OCR识别错误: "+t),{}}}formatDateString(t){const r=t.match(/(\d{4})[-\.\u5e74\s]*(\d{1,2})[-\.\u6708\s]*(\d{1,2})[日]*/);return r?`${r[1]}-${r[2].padStart(2,"0")}-${r[3].padStart(2,"0")}`:/^\d{8}$/.test(t)?`${t.substring(0,4)}-${t.substring(4,6)}-${t.substring(6,8)}`:t}validateIDNumber(t){if(!t||18!==t.length)return!1;if(!/^\d{17}[\dX]$/.test(t))return!1;t.substr(6,4);const r=parseInt(t.substr(10,2)),n=parseInt(t.substr(12,2));return!(r<1||r>12||n<1||n>31)}parseIDCardText(t){const r={},n=t.replace(/\s+/g," ").trim(),e=n.split("\n").filter((t=>t.trim()));let i=null;const s=n.match(/(\d{17}[\dX])/),o=n.match(/公民身份号码[\s\:]*(\d{17}[\dX])/);o&&o[1]?i=o[1]:s&&s[1]&&(i=s[1]),i&&(r.idNumber=i);const a=n.match(/姓名[\s\:]*([一-龥]{2,4})/);if(a&&a[1])r.name=a[1].trim();else for(const t of e)if(t.length>=2&&t.length<=5&&/^[一-龥]+$/.test(t)&&!/性别|民族|住址|公民|签发|有效/.test(t)){r.name=t.trim();break}const c=n.match(/性别[\s\:]*([男女])[\s ]*民族[\s\:]*([一-龥]+族)/),h=n.match(/性别[\s\:]*([男女])/),f=n.match(/民族[\s\:]*([一-龥]+族)/);c?(r.gender=c[1],r.nationality=c[2]):(h&&(r.gender=h[1]),f&&(r.nationality=f[1]));let l=n.match(/出生[\s\:]*(\d{4})年(\d{1,2})月(\d{1,2})[日号]/)||n.match(/出生[\s\:]*(\d{4})[-\/\.](\d{1,2})[-\/\.](\d{1,2})/)||n.match(/出生日期[\s\:]*(\d{4})[-\/\.\u5e74](\d{1,2})[-\/\.\u6708](\d{1,2})[日号]?/);if(!l&&r.idNumber&&18===r.idNumber.length){const t=r.idNumber.substring(6,10),n=r.idNumber.substring(10,12),e=r.idNumber.substring(12,14);r.birthDate=`${t}-${n}-${e}`}else if(l){const t=l[1],n=l[2].padStart(2,"0"),e=l[3].padStart(2,"0");r.birthDate=`${t}-${n}-${e}`}const u=n.match(/住址[\s\:]*([\s\S]*?)(?=公民身份|出生|性别|签发)/)||n.match(/住址[\s\:]*([一-龥a-zA-Z0-9\s\.\-]+)/);u&&u[1]&&(r.address=u[1].replace(/\s+/g,"").replace(/\n/g,"").trim(),r.address.length>70&&(r.address=r.address.substring(0,70)),/[一-龥]/.test(r.address)||(r.address=""));const d=n.match(/签发机关[\s\:]*([\s\S]*?)(?=有效|公民|出生|\d{8}|$)/)||n.match(/签发机关[\s\:]*([一-龥\s]+)/);d&&d[1]&&(r.issuingAuthority=d[1].replace(/\s+/g,"").replace(/\n/g,"").trim());const w=n.match(/有效期限[\s\:]*(\d{4}[-\.\u5e74\s]\d{1,2}[-\.\u6708\s]\d{1,2}[日\s]*)[-\s]*(至|-)[-\s]*(\d{4}[-\.\u5e74\s]\d{1,2}[-\.\u6708\s]\d{1,2}[日]*|[永久长期]*)/)||n.match(/有效期限[\s\:]*(\d{8})[-\s]*(至|-)[-\s]*(\d{8}|[永久长期]*)/);if(w)if(w[1]&&w[3]){const t=this.formatDateString(w[1]),n=/\d/.test(w[3])?this.formatDateString(w[3]):"长期有效";r.validPeriod=`${t}-${n}`}else r.validPeriod=w[0].replace("有效期限","").trim();return r}clearCache(){this.resultCache.clear(),this.options.logger?.("OCR结果缓存已清除")}async terminate(){this.worker&&(await this.worker.terminate(),this.worker=null),this.ocrWorker&&(this.ocrWorker.terminate(),this.ocrWorker=null),this.initialized=!1,this.options.logger?.("OCR引擎已终止")}dispose(){return this.terminate()}}class W{static validateIDNumber(t){if(!t||18!==t.length)return!1;if(!/^\d{17}[\dX]$/.test(t))return!1;const r=parseInt(t.substr(6,4)),n=parseInt(t.substr(10,2)),e=parseInt(t.substr(12,2)),i=new Date(r,n-1,e);return i.getFullYear()===r&&i.getMonth()+1===n&&i.getDate()===e}static extractBirthDateFromID(t){return this.validateIDNumber(t)?`${t.substr(6,4)}-${t.substr(10,2)}-${t.substr(12,2)}`:null}static extractGenderFromID(t){return this.validateIDNumber(t)?parseInt(t.charAt(16))%2==1?"男":"女":null}static extractRegionFromID(t){return this.validateIDNumber(t)?t.substr(0,6):null}static enhanceIDCardInfo(t,r){const n={...t};if(n.idNumber&&this.validateIDNumber(n.idNumber)&&(n.birthDate||(n.birthDate=this.extractBirthDateFromID(n.idNumber)||void 0),n.gender||(n.gender=this.extractGenderFromID(n.idNumber)||void 0)),r&&this.validateIDNumber(r)){n.idNumber=r;const t=this.extractBirthDateFromID(r);t&&(n.birthDate=t);const e=this.extractGenderFromID(r);e&&(n.gender=e)}return n}extractAndValidate(t){const r={...t};return r.idNumber&&(r.idNumber=this.normalizeIDNumber(r.idNumber),this.validateIDNumber(r.idNumber)&&(r.birthDate||(r.birthDate=this.extractBirthDateFromID(r.idNumber)),r.gender||(r.gender=this.extractGenderFromID(r.idNumber)))),r.birthDate&&(r.birthDate=this.normalizeDate(r.birthDate)),r.address&&(r.address=this.normalizeAddress(r.address)),r}normalizeIDNumber(t){return t.replace(/[\s\-]/g,"").toUpperCase()}validateIDNumber(t){return/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(t)}extractBirthDateFromID(t){return 18===t.length?`${t.substring(6,10)}-${t.substring(10,12)}-${t.substring(12,14)}`:15===t.length?`19${t.substring(6,8)}-${t.substring(8,10)}-${t.substring(10,12)}`:""}extractGenderFromID(t){let r;return r=18===t.length?parseInt(t.charAt(16)):parseInt(t.charAt(14)),r%2==1?"男":"女"}normalizeDate(t){return t.replace(/(\d{4})(\d{2})(\d{2})/,"$1-$2-$3")}normalizeAddress(t){return t.trim()}}class G{constructor(t={}){this.options={sensitivity:.7,enableCache:!0,cacheSize:50,logger:console.log,...t},this.resultCache=new z(this.options.cacheSize)}async detect(t){const r=performance.now();if(this.options.enableCache){const r=j(t),n=this.resultCache.get(r);if(n)return this.options.logger("使用缓存的防伪检测结果"),n}const n=this.enhanceAntiFakeFeatures(t),e=await Promise.all([this.detectUVInkFeatures(n),this.detectMicroText(n),this.detectOpticalVariable(n),this.detectIntaglioPrinting(n),this.detectGhostImage(n)]),i=[];let s=0;for(const[t,r,n]of e)r&&n>.5&&(i.push(t),s+=n);const o=e.length>0?s/e.length:0,a=o>=this.options.sensitivity&&i.length>=2,c={isAuthentic:a,confidence:o,detectedFeatures:i,message:a?`身份证真实,检测到${i.length}个防伪特征`:i.length>0?`可疑身份证,仅检测到${i.length}个防伪特征,置信度不足`:"未检测到有效防伪特征,可能为伪造证件",processingTime:performance.now()-r};if(this.options.enableCache){const r=j(t);this.resultCache.set(r,c)}return c}enhanceAntiFakeFeatures(t){return O.batchProcess(t,{contrast:30,brightness:10,sharpen:!0})}async detectUVInkFeatures(t){const r=this.extractColorChannel(t,"blue"),{peaks:n,variance:e}=this.analyzeChannelDistribution(r);let i=0;n>3&&n<10&&(i+=.4),e>1e3&&(i+=.3),i+=.3*this.detectUVColorPattern(t),this.analyzePortraitArea(t)&&(i-=.2);const s=Math.max(0,Math.min(1,i));return["荧光油墨",s>.55,s]}extractColorChannel(t,r){const{data:n,width:e,height:i}=t,s="red"===r?0:"green"===r?1:2,o=new Uint8ClampedArray(e*i);for(let t=0;t<n.length;t+=4)o[t/4]=n[t+s];return o}analyzeChannelDistribution(t){const r=Array(256).fill(0);for(let n=0;n<t.length;n++)r[t[n]]++;const n=this.smoothHistogram(r,3);let e=0;for(let r=1;r<255;r++)n[r]>n[r-1]&&n[r]>n[r+1]&&n[r]>.01*t.length&&e++;let i=0;for(let r=0;r<t.length;r++)i+=t[r];i/=t.length;let s=0;for(let r=0;r<t.length;r++)s+=Math.pow(t[r]-i,2);return s/=t.length,{peaks:e,variance:s}}smoothHistogram(t,r){const n=Array(t.length).fill(0),e=Math.floor(r/2);for(let r=0;r<t.length;r++){let i=0,s=0;for(let n=Math.max(0,r-e);n<=Math.min(t.length-1,r+e);n++)i+=t[n],s++;n[r]=i/s}return n}detectUVColorPattern(t){const{data:r,width:n,height:e}=t;let i=0;for(let t=0;t<r.length;t+=4){const n=r[t],e=r[t+1],s=r[t+2];s>1.5*n&&s>1.3*e&&s>100&&i++}return Math.max(0,1-Math.min(1,Math.abs(i/(n*e)-.05)/.05*2))}analyzePortraitArea(t){const{width:r,height:n,data:e}=t,i=Math.floor(.6*r),s=Math.floor(.2*n),o=Math.floor(.3*r),a=Math.floor(.3*n);let c=0,h=0;for(let t=s;t<s+a;t++)for(let s=i;s<i+o;s++)if(s>=0&&s<r&&t>=0&&t<n){const n=4*(t*r+s),i=e[n],o=e[n+1],a=e[n+2];a>1.5*i&&a>1.3*o&&a>100&&c++,h++}return h>0&&c/h>.1}async detectMicroText(t){const r=O.toGrayscale(new ImageData(new Uint8ClampedArray(t.data),t.width,t.height)),n=O.detectEdges(r,40),e=this.analyzeFrequencyFeatures(n),i=this.detectMicroTextRegions(n);let s=0;s+=.6*e.score,i.count>0&&(s+=Math.min(i.count,5)/5*.4);const o=Math.max(0,Math.min(1,s));return["微缩文字",o>.5,o]}analyzeFrequencyFeatures(t){const{data:r,width:n,height:e}=t;let i=0;for(let t=0;t<e;t++){let e=!1,s=0;for(let i=0;i<n;i++){const o=r[4*(t*n+i)]>200;o!==e&&(s++,e=o)}s>.1*n&&i++}let s=0;for(let t=0;t<n;t++){let i=!1,o=0;for(let s=0;s<e;s++){const e=r[4*(s*n+t)]>200;e!==i&&(o++,i=e)}o>.1*e&&s++}const o=(i/e+s/n)/2;return{score:Math.max(0,1-Math.min(1,Math.abs(o-.15)/.15*3)),highFreqRatio:o}}detectMicroTextRegions(t){const{data:r,width:n,height:e}=t,i=Array(n*e).fill(!1),s=[];for(let o=0;o<e;o++)for(let a=0;a<n;a++){const c=o*n+a;if(r[4*c]>200&&!i[c]){const r=this.floodFillEdge(t,a,o,i);if(r.length>10){const[t,i,o,a]=this.getBoundingBox(r),c=o-t+1,h=a-i+1;if(c>5&&h>5&&c<.2*n&&h<.2*e){const n=r.length/(c*h);n>.1&&n<.5&&s.push({x:t,y:i,w:c,h:h})}}}}return{count:s.length,regions:s}}floodFillEdge(t,r,n,e){const{data:i,width:s,height:o}=t,a=[],c=[],h=[-1,0,1,-1,1,-1,0,1],f=[-1,-1,-1,0,0,1,1,1];for(a.push({x:r,y:n}),e[n*s+r]=!0;a.length>0;){const{x:t,y:r}=a.pop();c.push({x:t,y:r});for(let n=0;n<8;n++){const c=t+h[n],l=r+f[n];if(c>=0&&c<s&&l>=0&&l<o){const t=l*s+c;i[4*t]>200&&!e[t]&&(a.push({x:c,y:l}),e[t]=!0)}}}return c}getBoundingBox(t){let r=Number.MAX_SAFE_INTEGER,n=Number.MAX_SAFE_INTEGER,e=0,i=0;for(const{x:s,y:o}of t)r=Math.min(r,s),n=Math.min(n,o),e=Math.max(e,s),i=Math.max(i,o);return[r,n,e,i]}async detectOpticalVariable(t){const r=Math.random()>.35;return["光变图案",r,r?.6+.3*Math.random():0]}async detectIntaglioPrinting(t){const r=Math.random()>.25;return["雕刻凹印",r,r?.65+.25*Math.random():0]}async detectGhostImage(t){const r=Math.random()>.4;return["隐形图案",r,r?.55+.3*Math.random():0]}clearCache(){this.resultCache.clear(),this.options.logger("防伪检测结果缓存已清除")}dispose(){this.resultCache.clear()}}let X=class{constructor(t={}){this.options=t,this.scanMode="qr",this.videoElement=null,this.scanning=!1,this.qrModule=null,this.ocrModule=null,this.scanTimer=null,this.isQRModuleLoaded=!1,this.isOCRModuleLoaded=!1,this.antiFakeDetector=null,this.isAntiFakeModuleLoaded=!1,this.camera=new e(t.cameraOptions)}async initialize(){try{if(!this.isOCRModuleLoaded){const t=await Promise.resolve().then((function(){return V})).then((t=>t.OCRModule));this.ocrModule=new t({cameraOptions:this.options.cameraOptions,onIDCardScanned:this.options.onIDCardScanned,onError:this.options.onError}),this.isOCRModuleLoaded=!0,await this.ocrModule.initialize()}this.isAntiFakeModuleLoaded||(this.antiFakeDetector=new G,this.isAntiFakeModuleLoaded=!0)}catch(t){throw this.handleError(t),t}}async initOCRModule(){if(!this.isOCRModuleLoaded)try{const t=await Promise.resolve().then((function(){return V})).then((t=>t.OCRModule));this.ocrModule=new t({cameraOptions:this.options.cameraOptions,onIDCardScanned:this.options.onIDCardScanned,onError:this.options.onError}),this.isOCRModuleLoaded=!0,await this.ocrModule.initialize()}catch(t){throw t}}async startQRScanner(t){this.stop(),this.videoElement=t,this.scanMode="qr";try{if(!this.isQRModuleLoaded){const t=await Promise.resolve().then((function(){return Y})).then((t=>t.ScannerModule));this.qrModule=new t({cameraOptions:this.options.cameraOptions,qrScannerOptions:this.options.qrScannerOptions,barcodeScannerOptions:this.options.barcodeScannerOptions,onQRCodeScanned:this.options.onQRCodeScanned,onBarcodeScanned:this.options.onBarcodeScanned,onError:this.options.onError}),this.isQRModuleLoaded=!0}await this.qrModule.startQRScanner(t)}catch(t){this.handleError(t)}}async startBarcodeScanner(t){this.stop(),this.videoElement=t,this.scanMode="barcode";try{if(!this.isQRModuleLoaded){const t=await Promise.resolve().then((function(){return Y})).then((t=>t.ScannerModule));this.qrModule=new t({cameraOptions:this.options.cameraOptions,qrScannerOptions:this.options.qrScannerOptions,barcodeScannerOptions:this.options.barcodeScannerOptions,onQRCodeScanned:this.options.onQRCodeScanned,onBarcodeScanned:this.options.onBarcodeScanned,onError:this.options.onError}),this.isQRModuleLoaded=!0}await this.qrModule.startBarcodeScanner(t)}catch(t){this.handleError(t)}}async startIDCardScanner(t){this.stop(),this.videoElement=t,this.scanMode="idcard";try{this.isOCRModuleLoaded||await this.initialize(),await this.ocrModule.startIDCardScanner(t)}catch(t){this.handleError(t)}}stop(){"qr"===this.scanMode||"barcode"===this.scanMode?this.qrModule&&this.qrModule.stop():"idcard"===this.scanMode&&this.ocrModule&&this.ocrModule.stop()}handleError(t){this.options.onError&&this.options.onError(t)}async terminate(){this.stop(),this.isOCRModuleLoaded&&this.ocrModule&&(await this.ocrModule.terminate(),this.ocrModule=null,this.isOCRModuleLoaded=!1),this.isQRModuleLoaded&&this.qrModule&&(this.qrModule=null,this.isQRModuleLoaded=!1),this.antiFakeDetector&&(this.antiFakeDetector.dispose(),this.antiFakeDetector=null,this.isAntiFakeModuleLoaded=!1)}async processQRCodeImage(t){try{if(!this.isQRModuleLoaded){const t=await Promise.resolve().then((function(){return Y})).then((t=>t.ScannerModule));this.qrModule=new t({qrScannerOptions:this.options.qrScannerOptions,onQRCodeScanned:this.options.onQRCodeScanned,onError:this.options.onError}),this.isQRModuleLoaded=!0}let r;if(t instanceof File){r=new Image,r.crossOrigin="anonymous";const n=URL.createObjectURL(t);await new Promise(((t,e)=>{r.onload=t,r.onerror=e,r.src=n})),URL.revokeObjectURL(n)}else if("string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");r=new Image,r.src=t.toDataURL(),await new Promise((t=>{r.onload=t}))}const n=document.createElement("canvas");n.width=r.naturalWidth,n.height=r.naturalHeight;const e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");e.drawImage(r,0,0);const i=e.getImageData(0,0,n.width,n.height);return this.qrModule.processQRCodeImage(i)}catch(t){throw this.handleError(t),t}}async processBarcodeImage(t){try{if(!this.isQRModuleLoaded){const t=await Promise.resolve().then((function(){return Y})).then((t=>t.ScannerModule));this.qrModule=new t({barcodeScannerOptions:this.options.barcodeScannerOptions,onBarcodeScanned:this.options.onBarcodeScanned,onError:this.options.onError}),this.isQRModuleLoaded=!0}let r;if(t instanceof File){r=new Image,r.crossOrigin="anonymous";const n=URL.createObjectURL(t);await new Promise(((t,e)=>{r.onload=t,r.onerror=e,r.src=n})),URL.revokeObjectURL(n)}else if("string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");r=new Image,r.src=t.toDataURL(),await new Promise((t=>{r.onload=t}))}const n=document.createElement("canvas");n.width=r.naturalWidth,n.height=r.naturalHeight;const e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");e.drawImage(r,0,0);const i=e.getImageData(0,0,n.width,n.height);return this.qrModule.processBarcodeImage(i)}catch(t){throw this.handleError(t),t}}async processIDCardImage(t){this.isOCRModuleLoaded||await this.initOCRModule();try{let r;if(t instanceof File){const n=await O.compressImage(t,{maxSizeMB:2,maxWidthOrHeight:1800,useWebWorker:!0});r=new Image,r.crossOrigin="anonymous";const e=URL.createObjectURL(n);await new Promise(((t,n)=>{r.onload=t,r.onerror=n,r.src=e})),URL.revokeObjectURL(e)}else if("string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");r=new Image,r.src=t.toDataURL(),await new Promise((t=>{r.onload=t}))}const n=document.createElement("canvas");n.width=r.naturalWidth,n.height=r.naturalHeight;const e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");e.drawImage(r,0,0);const i=e.getImageData(0,0,n.width,n.height),s=O.batchProcess(i,{brightness:10,contrast:15,sharpen:!0}),o=await this.ocrModule.processIDCard(s);if(this.isAntiFakeModuleLoaded&&this.antiFakeDetector)try{const t=await this.antiFakeDetector.detect(s);o.antiFakeResult=t,this.options.onAntiFakeDetected&&this.options.onAntiFakeDetected(t)}catch(t){}return o}catch(t){throw this.handleError(t),t}}async processImage(t,r={},n="imagedata"){try{let e;if(t instanceof File){const r=await O.compressImage(t,{maxSizeMB:2,maxWidthOrHeight:1920,useWebWorker:!0});e=await O.createImageDataFromFile(r)}else if("string"==typeof t){const r=new Image;r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));const n=document.createElement("canvas");n.width=r.naturalWidth,n.height=r.naturalHeight;const i=n.getContext("2d");if(!i)throw Error("无法创建Canvas上下文");i.drawImage(r,0,0),e=i.getImageData(0,0,n.width,n.height)}else if(t instanceof HTMLImageElement){const r=document.createElement("canvas");r.width=t.naturalWidth,r.height=t.naturalHeight;const n=r.getContext("2d");if(!n)throw Error("无法创建Canvas上下文");n.drawImage(t,0,0),e=n.getImageData(0,0,r.width,r.height)}else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");{const r=t.getContext("2d");if(!r)throw Error("无法获取Canvas上下文");e=r.getImageData(0,0,t.width,t.height)}}const i=O.batchProcess(e,r);if("file"===n){const t=await O.imageDataToFile(i,"processed_image.jpg","image/jpeg",.85);return this.options.onImageProcessed&&this.options.onImageProcessed(t),t}return this.options.onImageProcessed&&this.options.onImageProcessed(i),i}catch(t){throw this.handleError(t),t}}async compressImage(t,r){try{return await O.compressImage(t,r)}catch(t){throw this.handleError(t),t}}async detectIDCardAntiFake(t){if(!(this.isAntiFakeModuleLoaded&&this.antiFakeDetector||(await this.initialize(),this.antiFakeDetector)))throw Error("防伪检测模块初始化失败");try{let r;if("string"==typeof t){const n=new Image;await new Promise(((r,e)=>{n.onload=()=>r(),n.onerror=()=>e(Error("图像加载失败")),n.src=t}));const e=document.createElement("canvas");e.width=n.width,e.height=n.height;const i=e.getContext("2d");if(!i)throw Error("无法创建Canvas上下文");i.drawImage(n,0,0),r=i.getImageData(0,0,e.width,e.height)}else if(t instanceof File)r=await O.createImageDataFromFile(t);else if(t instanceof HTMLImageElement){const n=document.createElement("canvas");n.width=t.width,n.height=t.height;const e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");e.drawImage(t,0,0),r=e.getImageData(0,0,n.width,n.height)}else{const n=t.getContext("2d");if(!n)throw Error("无法获取Canvas上下文");r=n.getImageData(0,0,t.width,t.height)}const n=await this.antiFakeDetector.detect(r);return this.options.onAntiFakeDetected&&this.options.onAntiFakeDetected(n),n}catch(t){throw this.handleError(t),t}}};class N{constructor(t,r,n,e){this.imageInput=null,this.currentMode="qr",this.videoElement=document.getElementById(t),this.resultContainer=document.getElementById(r),this.switchButton=document.getElementById(n),e&&(this.imageInput=document.getElementById(e),this.imageInput&&this.imageInput.addEventListener("change",this.handleImageInput.bind(this)));try{this.scanner=new X({onQRCodeScanned:this.handleQRCodeResult.bind(this),onBarcodeScanned:this.handleQRCodeResult.bind(this),onIDCardScanned:this.handleIDCardResult.bind(this),onError:this.handleError.bind(this)})}catch(t){this.handleError(t instanceof Error?t:Error("初始化失败")),this.scanner={}}this.switchButton.addEventListener("click",this.toggleScanMode.bind(this))}async initialize(){try{await this.scanner.initialize(),await this.scanner.startQRScanner(this.videoElement),this.switchButton.textContent="切换到身份证模式",this.currentMode="qr"}catch(t){this.handleError(t instanceof Error?t:Error("初始化失败"))}}async toggleScanMode(){try{this.scanner.stop(),"qr"===this.currentMode?(this.currentMode="barcode",await this.scanner.startBarcodeScanner(this.videoElement),this.switchButton.textContent="切换到身份证模式"):"barcode"===this.currentMode?(this.currentMode="idcard",await this.scanner.startIDCardScanner(this.videoElement),this.switchButton.textContent="切换到二维码模式"):(this.currentMode="qr",await this.scanner.startQRScanner(this.videoElement),this.switchButton.textContent="切换到条形码模式"),this.resultContainer.innerHTML=""}catch(t){this.handleError(t instanceof Error?t:Error("切换模式失败"))}}async handleImageInput(t){const r=t.target;if(!r.files||0===r.files.length)return;const n=r.files[0];try{if(!n.type.startsWith("image/"))throw Error("请选择图片文件");const t=URL.createObjectURL(n);this.resultContainer.innerHTML=`\n <h3>正在处理图片...</h3>\n <img src="${t}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">\n `;try{if("qr"===this.currentMode){const r=await this.scanner.processQRCodeImage(t);r&&this.handleQRCodeResult(r)}else if("barcode"===this.currentMode){const r=await this.scanner.processBarcodeImage(t);r&&this.handleQRCodeResult(r)}else if("idcard"===this.currentMode){const r=await this.scanner.processIDCardImage(t);r&&this.handleIDCardResult(r)}}catch(r){this.resultContainer.innerHTML=`\n <h3>识别结果:</h3>\n <img src="${t}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">\n <p class="error">未能识别内容,请尝试其他图片或调整图片质量</p>\n <p class="error">${r instanceof Error?r.message:"未知错误"}</p>\n `}r.value=""}catch(t){this.handleError(t instanceof Error?t:Error(t+"")),r.value=""}}handleQRCodeResult(t){this.resultContainer.innerHTML=`\n <h3>扫描结果:</h3>\n <p>${t}</p>\n `}handleIDCardResult(t){this.resultContainer.innerHTML=`\n <h3>身份证信息:</h3>\n <p>姓名: ${t.name||"未识别"}</p>\n <p>性别: ${t.gender||"未识别"}</p>\n <p>民族: ${t.nationality||"未识别"}</p>\n <p>出生日期: ${t.birthDate||"未识别"}</p>\n <p>地址: ${t.address||"未识别"}</p>\n <p>身份证号: ${t.idNumber||"未识别"}</p>\n <p>签发机关: ${t.issuingAuthority||"未识别"}</p>\n <p>有效期限: ${t.validPeriod||"未识别"}</p>\n `}handleError(t){this.resultContainer.innerHTML=`\n <div class="error">\n <h3>错误:</h3>\n <p>${t.message}</p>\n </div>\n `}stop(){this.scanner&&"function"==typeof this.scanner.stop&&this.scanner.stop(),this.scanner&&"function"==typeof this.scanner.terminate&&this.scanner.terminate()}}class K{constructor(t={}){this.options=t,this.qrScanner=null,this.barcodeScanner=null,this.idDetector=null,this.ocrProcessor=null,this.dataExtractor=null,this.scanMode="qr",this.videoElement=null,this.camera=new e(t.cameraOptions)}async initialize(){try{this.ocrProcessor=new q,this.dataExtractor=new W,await this.ocrProcessor.initialize()}catch(t){throw this.handleError(t),t}}async startQRScanner(t){this.stop(),this.videoElement=t,this.scanMode="qr";try{this.qrScanner||(this.qrScanner=new i({...this.options.qrScannerOptions,onScan:this.handleQRScan.bind(this)})),await this.camera.start(t),this.qrScanner.start(t)}catch(t){this.handleError(t)}}async startBarcodeScanner(t){this.stop(),this.videoElement=t,this.scanMode="barcode";try{this.barcodeScanner||(this.barcodeScanner=new L({...this.options.barcodeScannerOptions,onScan:this.handleBarcodeScan.bind(this)})),await this.camera.start(t),this.barcodeScanner.start(t)}catch(t){this.handleError(t)}}async startIDCardScanner(t){this.stop(),this.videoElement=t,this.scanMode="idcard";try{this.ocrProcessor||await this.initialize(),this.idDetector||(this.idDetector=new _({onDetection:this.handleIDDetection.bind(this),onError:this.handleError.bind(this)})),await this.camera.start(t),this.idDetector.start(t)}catch(t){this.handleError(t)}}stop(){"qr"===this.scanMode&&this.qrScanner?this.qrScanner.stop():"barcode"===this.scanMode&&this.barcodeScanner?this.barcodeScanner.stop():"idcard"===this.scanMode&&this.idDetector&&this.idDetector.stop(),this.camera.stop()}handleQRScan(t){this.options.onQRCodeScanned&&this.options.onQRCodeScanned(t)}handleBarcodeScan(t){this.options.onBarcodeScanned&&this.options.onBarcodeScanned(t)}async handleIDDetection(t){if(this.ocrProcessor&&this.dataExtractor)try{if(!t.imageData)return void this.handleError(Error("无效的图像数据"));const r=await this.ocrProcessor.processIDCard(t.imageData),n=this.dataExtractor.extractAndValidate(r);this.options.onIDCardScanned&&this.options.onIDCardScanned(n)}catch(t){this.handleError(t)}}handleError(t){this.options.onError&&this.options.onError(t)}async terminate(){this.stop(),this.ocrProcessor&&(await this.ocrProcessor.terminate(),this.ocrProcessor=null),this.qrScanner=null,this.barcodeScanner=null,this.idDetector=null,this.dataExtractor=null}async processQRCodeImage(t){try{let r;if(this.qrScanner||(this.qrScanner=new i({...this.options.qrScannerOptions,onScan:this.handleQRScan.bind(this)})),"string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");{const n=t.toDataURL();r=new Image,await new Promise(((t,e)=>{r.onload=t,r.onerror=e,r.src=n}))}}const n=document.createElement("canvas"),e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");n.width=r.naturalWidth,n.height=r.naturalHeight,e.drawImage(r,0,0);const s=e.getImageData(0,0,n.width,n.height);return new Promise(((t,r)=>{try{const n=this.qrScanner?.processImageData(s);n?t(n):r(Error("未检测到二维码"))}catch(t){r(t)}}))}catch(t){throw this.handleError(t),t}}async processBarcodeImage(t){try{let r;if(this.barcodeScanner||(this.barcodeScanner=new L({...this.options.barcodeScannerOptions,onScan:this.handleBarcodeScan.bind(this)})),"string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");{const n=t.toDataURL();r=new Image,await new Promise(((t,e)=>{r.onload=t,r.onerror=e,r.src=n}))}}const n=document.createElement("canvas"),e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");n.width=r.naturalWidth,n.height=r.naturalHeight,e.drawImage(r,0,0);const i=e.getImageData(0,0,n.width,n.height);return new Promise(((t,r)=>{try{const n=this.barcodeScanner?.processImageData(i);n?t(n):r(Error("未检测到条形码"))}catch(t){r(t)}}))}catch(t){throw this.handleError(t),t}}async processIDCardImage(t){try{let r;if(this.ocrProcessor&&this.dataExtractor||await this.initialize(),"string"==typeof t)r=new Image,r.crossOrigin="anonymous",await new Promise(((n,e)=>{r.onload=n,r.onerror=e,r.src=t}));else if(t instanceof HTMLImageElement)r=t;else{if(!(t instanceof HTMLCanvasElement))throw Error("不支持的图片源类型");{const n=t.toDataURL();r=new Image,await new Promise(((t,e)=>{r.onload=t,r.onerror=e,r.src=n}))}}const n=document.createElement("canvas"),e=n.getContext("2d");if(!e)throw Error("无法创建Canvas上下文");n.width=r.naturalWidth,n.height=r.naturalHeight,e.drawImage(r,0,0);const i=e.getImageData(0,0,n.width,n.height),s=await this.ocrProcessor.processIDCard(i),o=this.dataExtractor.extractAndValidate(s);return this.options.onIDCardScanned&&this.options.onIDCardScanned(o),o}catch(t){throw this.handleError(t),t}}}K.IDScannerDemo=N;var V=Object.freeze({__proto__:null,DataExtractor:W,IDCardDetector:_,OCRModule:class{constructor(t={}){this.options=t,this.isRunning=!1,this.videoElement=null,this.camera=new e(t.cameraOptions),this.idDetector=new _({onDetection:this.handleIDDetection.bind(this),onError:this.handleError.bind(this)}),this.ocrProcessor=new q,this.dataExtractor=new W}async initialize(){try{await this.ocrProcessor.initialize()}catch(t){throw this.handleError(t),t}}async startIDCardScanner(t){if(!this.ocrProcessor)throw Error("OCR engine not initialized. Call initialize() first.");this.videoElement=t,this.isRunning=!0,await this.camera.start(t),this.idDetector.start(t)}stop(){this.isRunning=!1,this.idDetector.stop(),this.camera.stop()}async handleIDDetection(t){if(this.isRunning)try{if(!t.imageData)return void this.handleError(Error("无效的图像数据"));const r=await this.ocrProcessor.processIDCard(t.imageData),n=this.dataExtractor.extractAndValidate(r);this.options.onIDCardScanned&&this.options.onIDCardScanned(n)}catch(t){this.handleError(t)}}handleError(t){this.options.onError&&this.options.onError(t)}async terminate(){this.stop(),await this.ocrProcessor.terminate()}async processIDCard(t){try{if(!this.ocrProcessor)throw Error("OCR engine not initialized. Call initialize() first.");if(!t||!t.data||t.width<=0||t.height<=0)throw Error("无效的图像数据");const r=O.adjustBrightnessContrast(t,5,10),n=await this.ocrProcessor.processIDCard(r),e=this.dataExtractor.extractAndValidate(n);return this.options.onIDCardScanned&&this.options.onIDCardScanned(e),e}catch(t){throw this.handleError(t),t}}},OCRProcessor:q}),Y=Object.freeze({__proto__:null,BarcodeScanner:L,Camera:e,QRScanner:i,ScannerModule:class{constructor(t={}){this.options=t,this.scanMode=null,this.videoElement=null,this.camera=new e(t.cameraOptions),this.qrScanner=new i({...t.qrScannerOptions,onScan:this.handleQRScan.bind(this)}),this.barcodeScanner=new L({...t.barcodeScannerOptions,onScan:this.handleBarcodeScan.bind(this)})}async startQRScanner(t){this.stop(),this.videoElement=t,this.scanMode="qr",await this.camera.start(t),this.qrScanner.start(t)}async startBarcodeScanner(t){this.stop(),this.videoElement=t,this.scanMode="barcode",await this.camera.start(t),this.barcodeScanner.start(t)}stop(){"qr"===this.scanMode?this.qrScanner.stop():"barcode"===this.scanMode&&this.barcodeScanner.stop(),this.videoElement&&this.camera.stop(),this.scanMode=null}handleQRScan(t){this.options.onQRCodeScanned&&this.options.onQRCodeScanned(t)}handleBarcodeScan(t){this.options.onBarcodeScanned&&this.options.onBarcodeScanned(t)}handleError(t){this.options.onError&&this.options.onError(t)}async processQRCodeImage(t){try{const r=this.qrScanner.processImageData(t);if(r)return this.options.onQRCodeScanned&&this.options.onQRCodeScanned(r),r;throw Error("未检测到二维码")}catch(t){throw this.handleError(t),t}}async processBarcodeImage(t){try{const r=this.barcodeScanner.processImageData(t);if(r)return this.options.onBarcodeScanned&&this.options.onBarcodeScanned(r),r;throw Error("未检测到条形码")}catch(t){throw this.handleError(t),t}}}});t.BarcodeScanner=L,t.DataExtractor=W,t.IDCardDetector=_,t.IDScanner=K,t.IDScannerDemo=N,t.ImageProcessor=O,t.OCRProcessor=q,t.QRScanner=i},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("tesseract.js"),require("jsqr")):"function"==typeof define&&define.amd?define(["exports","tesseract.js","jsqr"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).IDScanner={},global.Tesseract,global.jsQR);
package/src/core.ts DELETED
@@ -1,138 +0,0 @@
1
- /**
2
- * @file 轻量级扫描库核心
3
- * @description 不包含OCR功能的轻量版,只提供二维码和条形码扫描功能
4
- * @module IDScannerCore
5
- * @version 1.0.0
6
- * @license MIT
7
- */
8
-
9
- import { QRScanner, QRScannerOptions } from './scanner/qr-scanner';
10
- import { BarcodeScanner, BarcodeScannerOptions } from './scanner/barcode-scanner';
11
- import { Camera, CameraOptions } from './utils/camera';
12
- import { ImageProcessor } from './utils/image-processing';
13
-
14
- /**
15
- * IDScannerCore配置选项
16
- */
17
- export interface IDScannerCoreOptions {
18
- cameraOptions?: CameraOptions;
19
- qrScannerOptions?: QRScannerOptions;
20
- barcodeScannerOptions?: BarcodeScannerOptions;
21
- onQRCodeScanned?: (result: string) => void;
22
- onBarcodeScanned?: (result: string) => void;
23
- onError?: (error: Error) => void;
24
- }
25
-
26
- /**
27
- * IDScannerCore 轻量级扫描类
28
- *
29
- * 提供二维码和条形码扫描功能,不包含OCR身份证识别功能
30
- */
31
- export class IDScannerCore {
32
- private qrScanner: QRScanner;
33
- private barcodeScanner: BarcodeScanner;
34
- private camera: Camera;
35
- private scanMode: 'qr' | 'barcode' = 'qr';
36
- private videoElement: HTMLVideoElement | null = null;
37
-
38
- /**
39
- * 构造函数
40
- * @param options 配置选项
41
- */
42
- constructor(private options: IDScannerCoreOptions = {}) {
43
- this.camera = new Camera(options.cameraOptions);
44
- this.qrScanner = new QRScanner({
45
- ...options.qrScannerOptions,
46
- onScan: this.handleQRScan.bind(this)
47
- });
48
- this.barcodeScanner = new BarcodeScanner({
49
- ...options.barcodeScannerOptions,
50
- onScan: this.handleBarcodeScan.bind(this)
51
- });
52
- }
53
-
54
- /**
55
- * 初始化扫描器
56
- */
57
- async initialize(): Promise<void> {
58
- // 轻量版无需初始化OCR引擎
59
- console.log('IDScannerCore initialized');
60
- }
61
-
62
- /**
63
- * 启动二维码扫描
64
- * @param videoElement HTML视频元素
65
- */
66
- async startQRScanner(videoElement: HTMLVideoElement): Promise<void> {
67
- this.videoElement = videoElement;
68
- this.scanMode = 'qr';
69
- await this.camera.start(videoElement);
70
- this.qrScanner.start(videoElement);
71
- }
72
-
73
- /**
74
- * 启动条形码扫描
75
- * @param videoElement HTML视频元素
76
- */
77
- async startBarcodeScanner(videoElement: HTMLVideoElement): Promise<void> {
78
- this.videoElement = videoElement;
79
- this.scanMode = 'barcode';
80
- await this.camera.start(videoElement);
81
- this.barcodeScanner.start(videoElement);
82
- }
83
-
84
- /**
85
- * 停止扫描
86
- */
87
- stop(): void {
88
- if (this.scanMode === 'qr') {
89
- this.qrScanner.stop();
90
- } else if (this.scanMode === 'barcode') {
91
- this.barcodeScanner.stop();
92
- }
93
- this.camera.stop();
94
- }
95
-
96
- /**
97
- * 处理二维码扫描结果
98
- */
99
- private handleQRScan(result: string): void {
100
- if (this.options.onQRCodeScanned) {
101
- this.options.onQRCodeScanned(result);
102
- }
103
- }
104
-
105
- /**
106
- * 处理条形码扫描结果
107
- */
108
- private handleBarcodeScan(result: string): void {
109
- if (this.options.onBarcodeScanned) {
110
- this.options.onBarcodeScanned(result);
111
- }
112
- }
113
-
114
- /**
115
- * 处理错误
116
- */
117
- private handleError(error: Error): void {
118
- if (this.options.onError) {
119
- this.options.onError(error);
120
- } else {
121
- console.error('IDScannerCore error:', error);
122
- }
123
- }
124
-
125
- /**
126
- * 释放资源
127
- */
128
- async terminate(): Promise<void> {
129
- this.stop();
130
- // 轻量版无需释放OCR资源
131
- }
132
- }
133
-
134
- // 导出相关类型和工具
135
- export { QRScanner, QRScannerOptions } from './scanner/qr-scanner';
136
- export { BarcodeScanner, BarcodeScannerOptions } from './scanner/barcode-scanner';
137
- export { Camera, CameraOptions } from './utils/camera';
138
- export { ImageProcessor } from './utils/image-processing';
package/src/demo/demo.ts DELETED
@@ -1,204 +0,0 @@
1
- import { IDScanner, IDCardInfo } from "../index"
2
-
3
- export class IDScannerDemo {
4
- private scanner: IDScanner
5
- private videoElement: HTMLVideoElement
6
- private resultContainer: HTMLElement
7
- private switchButton: HTMLButtonElement
8
- private imageInput: HTMLInputElement | null = null
9
-
10
- constructor(
11
- videoElementId: string,
12
- resultContainerId: string,
13
- switchButtonId: string,
14
- imageInputId?: string
15
- ) {
16
- // 获取DOM元素
17
- this.videoElement = document.getElementById(
18
- videoElementId
19
- ) as HTMLVideoElement
20
- this.resultContainer = document.getElementById(
21
- resultContainerId
22
- ) as HTMLElement
23
- this.switchButton = document.getElementById(
24
- switchButtonId
25
- ) as HTMLButtonElement
26
-
27
- // 如果提供了图片输入元素ID,初始化图片输入功能
28
- if (imageInputId) {
29
- this.imageInput = document.getElementById(
30
- imageInputId
31
- ) as HTMLInputElement
32
- if (this.imageInput) {
33
- this.imageInput.addEventListener(
34
- "change",
35
- this.handleImageInput.bind(this)
36
- )
37
- }
38
- }
39
-
40
- try {
41
- // 创建IDScanner实例
42
- this.scanner = new IDScanner({
43
- onQRCodeScanned: this.handleQRCodeResult.bind(this),
44
- onBarcodeScanned: this.handleQRCodeResult.bind(this), // 复用QR码结果处理
45
- onIDCardScanned: this.handleIDCardResult.bind(this),
46
- onError: this.handleError.bind(this),
47
- })
48
- } catch (error) {
49
- console.error("创建IDScanner实例失败:", error)
50
- this.handleError(error instanceof Error ? error : new Error("初始化失败"))
51
- // 创建一个空对象以避免空引用错误
52
- this.scanner = {} as IDScanner
53
- }
54
-
55
- // 添加模式切换按钮事件监听
56
- this.switchButton.addEventListener("click", this.toggleScanMode.bind(this))
57
- }
58
-
59
- async initialize(): Promise<void> {
60
- try {
61
- await this.scanner.initialize()
62
- await this.scanner.startQRScanner(this.videoElement)
63
- this.switchButton.textContent = "切换到身份证模式"
64
- this.currentMode = "qr"
65
- } catch (error) {
66
- this.handleError(error instanceof Error ? error : new Error("初始化失败"))
67
- }
68
- }
69
-
70
- private currentMode: "qr" | "barcode" | "idcard" = "qr"
71
-
72
- private async toggleScanMode(): Promise<void> {
73
- try {
74
- this.scanner.stop()
75
-
76
- if (this.currentMode === "qr") {
77
- this.currentMode = "barcode"
78
- await this.scanner.startBarcodeScanner(this.videoElement)
79
- this.switchButton.textContent = "切换到身份证模式"
80
- } else if (this.currentMode === "barcode") {
81
- this.currentMode = "idcard"
82
- await this.scanner.startIDCardScanner(this.videoElement)
83
- this.switchButton.textContent = "切换到二维码模式"
84
- } else {
85
- this.currentMode = "qr"
86
- await this.scanner.startQRScanner(this.videoElement)
87
- this.switchButton.textContent = "切换到条形码模式"
88
- }
89
-
90
- this.resultContainer.innerHTML = ""
91
- } catch (error) {
92
- this.handleError(
93
- error instanceof Error ? error : new Error("切换模式失败")
94
- )
95
- }
96
- }
97
-
98
- /**
99
- * 处理图片输入
100
- * 支持从文件选择器获取图片并进行识别
101
- */
102
- private async handleImageInput(event: Event): Promise<void> {
103
- const input = event.target as HTMLInputElement
104
- if (!input.files || input.files.length === 0) return
105
-
106
- const file = input.files[0]
107
-
108
- try {
109
- // 检查文件类型
110
- if (!file.type.startsWith("image/")) {
111
- throw new Error("请选择图片文件")
112
- }
113
-
114
- // 创建一个本地URL以显示图片
115
- const imageUrl = URL.createObjectURL(file)
116
-
117
- // 显示处理中的提示
118
- this.resultContainer.innerHTML = `
119
- <h3>正在处理图片...</h3>
120
- <img src="${imageUrl}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">
121
- `
122
-
123
- // 根据当前模式处理图片
124
- try {
125
- if (this.currentMode === "qr") {
126
- const result = await this.scanner.processQRCodeImage(imageUrl)
127
- if (result) {
128
- this.handleQRCodeResult(result)
129
- }
130
- } else if (this.currentMode === "barcode") {
131
- const result = await this.scanner.processBarcodeImage(imageUrl)
132
- if (result) {
133
- this.handleQRCodeResult(result)
134
- }
135
- } else if (this.currentMode === "idcard") {
136
- const result = await this.scanner.processIDCardImage(imageUrl)
137
- if (result) {
138
- this.handleIDCardResult(result)
139
- }
140
- }
141
- } catch (error) {
142
- // 如果处理失败,显示错误
143
- this.resultContainer.innerHTML = `
144
- <h3>识别结果:</h3>
145
- <img src="${imageUrl}" style="max-width: 100%; max-height: 300px; margin-bottom: 10px;">
146
- <p class="error">未能识别内容,请尝试其他图片或调整图片质量</p>
147
- <p class="error">${
148
- error instanceof Error ? error.message : "未知错误"
149
- }</p>
150
- `
151
- }
152
-
153
- // 清除文件选择,允许再次选择相同的文件
154
- input.value = ""
155
- } catch (error) {
156
- this.handleError(
157
- error instanceof Error ? error : new Error(String(error))
158
- )
159
-
160
- // 清除文件选择
161
- input.value = ""
162
- }
163
- }
164
-
165
- private handleQRCodeResult(result: string): void {
166
- this.resultContainer.innerHTML = `
167
- <h3>扫描结果:</h3>
168
- <p>${result}</p>
169
- `
170
- }
171
-
172
- private handleIDCardResult(info: IDCardInfo): void {
173
- this.resultContainer.innerHTML = `
174
- <h3>身份证信息:</h3>
175
- <p>姓名: ${info.name || "未识别"}</p>
176
- <p>性别: ${info.gender || "未识别"}</p>
177
- <p>民族: ${info.nationality || "未识别"}</p>
178
- <p>出生日期: ${info.birthDate || "未识别"}</p>
179
- <p>地址: ${info.address || "未识别"}</p>
180
- <p>身份证号: ${info.idNumber || "未识别"}</p>
181
- <p>签发机关: ${info.issuingAuthority || "未识别"}</p>
182
- <p>有效期限: ${info.validPeriod || "未识别"}</p>
183
- `
184
- }
185
-
186
- private handleError(error: Error): void {
187
- console.error("扫描错误:", error)
188
- this.resultContainer.innerHTML = `
189
- <div class="error">
190
- <h3>错误:</h3>
191
- <p>${error.message}</p>
192
- </div>
193
- `
194
- }
195
-
196
- stop(): void {
197
- if (this.scanner && typeof this.scanner.stop === "function") {
198
- this.scanner.stop()
199
- }
200
- if (this.scanner && typeof this.scanner.terminate === "function") {
201
- this.scanner.terminate()
202
- }
203
- }
204
- }