


--[[

  GO TO THE BOTTOM OF THIS FILE TO SEE WHAT IT ACTUALLY DOES

]]










--[[--
LibDeflate 1.0.2-release <br>
Pure Lua compressor and decompressor with high compression ratio using
DEFLATE/zlib format.

@file LibDeflate.lua
@author Haoqian He (Github: SafeteeWoW; World of Warcraft: Safetyy-Illidan(US))
@copyright LibDeflate <2018-2021> Haoqian He
@license zlib License

This library is implemented according to the following specifications. <br>
Report a bug if LibDeflate is not fully compliant with those specs. <br>
Both compressors and decompressors have been implemented in the library.<br>
1. RFC1950: DEFLATE Compressed Data Format Specification version 1.3 <br>
https://tools.ietf.org/html/rfc1951 <br>
2. RFC1951: ZLIB Compressed Data Format Specification version 3.3 <br>
https://tools.ietf.org/html/rfc1950 <br>

This library requires Lua 5.1/5.2/5.3/5.4 interpreter or LuaJIT v2.0+. <br>
This library does not have any dependencies. <br>
<br>
This file "LibDeflate.lua" is the only source file of
the library. <br>
Submit suggestions or report bugs to
https://github.com/safeteeWow/LibDeflate/issues
]] --[[
zlib License

(C) 2018-2021 Haoqian He

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

License History:
1. GNU General Public License Version 3 in v1.0.0 and earlier versions.
2. GNU Lesser General Public License Version 3 in v1.0.1
3. the zlib License since v1.0.2

Credits and Disclaimer:
This library rewrites the code from the algorithm
and the ideas of the following projects,
and uses their code to help to test the correctness of this library,
but their code is not included directly in the library itself.
Their original licenses shall be comply when used.

1. zlib, by Jean-loup Gailly (compression) and Mark Adler (decompression).
  http://www.zlib.net/
  Licensed under zlib License. http://www.zlib.net/zlib_license.html
  For the compression algorithm.
2. puff, by Mark Adler. https://github.com/madler/zlib/tree/master/contrib/puff
  Licensed under zlib License. http://www.zlib.net/zlib_license.html
  For the decompression algorithm.
3. LibCompress, by jjsheets and Galmok of European Stormrage (Horde)
  https://www.wowace.com/projects/libcompress
  Licensed under GPLv2.
  https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  For the code to create customized codec.
4. WeakAuras2,
  https://github.com/WeakAuras/WeakAuras2
  Licensed under GPLv2.
  For the 6bit encoding and decoding.
]] --[[
  Curseforge auto-packaging replacements:

  Project Date: @project-date-iso@
  Project Hash: @project-hash@
  Project Version: @project-version@
--]] local LibDeflate

do local a="1.0.2-release"local b="LibDeflate"local c=3;local d="LibDeflate "..a.." Copyright (C) 2018-2021 Haoqian He.".." Licensed under the zlib License"if LibStub then local e,f=LibStub:GetLibrary(b,true)if e and f and f>=c then return e else LibDeflate=LibStub:NewLibrary(b,c)end else LibDeflate={}end;LibDeflate._VERSION=a;LibDeflate._MAJOR=b;LibDeflate._MINOR=c;LibDeflate._COPYRIGHT=d end;local assert=assert;local error=error;local pairs=pairs;local g=string.byte;local h=string.char;local i=string.find;local j=string.gsub;local k=string.sub;local l=table.concat;local m=table.sort;local tostring=tostring;local type=type;local n={}local o={}local p={}local q={}local r={}local s={}local t={}local u={}local v={}local w={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}local x={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}local y={[0]=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}local z={[0]=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}local A={16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}local B;local C;local D;local E;local F;local G;local H;local I;for J=0,255 do o[J]=h(J)end;do local K=1;for J=0,32 do n[J]=K;K=K*2 end end;for J=1,9 do p[J]={}for L=0,n[J+1]-1 do local M=0;local N=L;for O=1,J do M=M-M%2+((M%2==1 or N%2==1)and 1 or 0)N=(N-N%2)/2;M=M*2 end;p[J][L]=(M-M%2)/2 end end;do local P=18;local Q=16;local R=265;local S=1;for T=3,258 do if T<=10 then q[T]=T+254;s[T]=0 elseif T==258 then q[T]=285;s[T]=0 else if T>P then P=P+Q;Q=Q*2;R=R+4;S=S+1 end;local U=T-P-1+Q/2;q[T]=(U-U%(Q/8))/(Q/8)+R;s[T]=S;r[T]=U%(Q/8)end end end;do t[1]=0;t[2]=1;v[1]=0;v[2]=0;local P=3;local Q=4;local V=2;local S=0;for W=3,256 do if W>Q then P=P*2;Q=Q*2;V=V+2;S=S+1 end;t[W]=W<=P and V or V+1;v[W]=S<0 and 0 or S;if Q>=8 then u[W]=(W-Q/2-1)%(Q/4)end end end;function LibDeflate:Adler32(X)if type(X)~="string"then error(("Usage: LibDeflate:Adler32(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;local Y=#X;local J=1;local P=1;local Q=0;while J<=Y-15 do local Z,_,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad=g(X,J,J+15)Q=(Q+16*P+16*Z+15*_+14*a0+13*a1+12*a2+11*a3+10*a4+9*a5+8*a6+7*a7+6*a8+5*a9+4*aa+3*ab+2*ac+ad)%65521;P=(P+Z+_+a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+aa+ab+ac+ad)%65521;J=J+16 end;while J<=Y do local ae=g(X,J,J)P=(P+ae)%65521;Q=(Q+P)%65521;J=J+1 end;return(Q*65536+P)%4294967296 end;local function af(ag,ah)return ag%4294967296==ah%4294967296 end;function LibDeflate:CreateDictionary(X,Y,ai)if type(X)~="string"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if type(Y)~="number"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'strlen' - number expected got '%s'."):format(type(Y)),2)end;if type(ai)~="number"then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'adler32' - number expected got '%s'."):format(type(ai)),2)end;if Y~=#X then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'strlen' does not match the actual length of 'str'.".." 'strlen': %u, '#str': %u .".." Please check if 'str' is modified unintentionally."):format(Y,#X))end;if Y==0 then error("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - Empty string is not allowed.",2)end;if Y>32768 then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'str' - string longer than 32768 bytes is not allowed.".." Got %d bytes."):format(Y),2)end;local aj=self:Adler32(X)if not af(ai,aj)then error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):".." 'adler32' does not match the actual adler32 of 'str'.".." 'adler32': %u, 'Adler32(str)': %u .".." Please check if 'str' is modified unintentionally."):format(ai,aj))end;local ak={}ak.adler32=ai;ak.hash_tables={}ak.string_table={}ak.strlen=Y;local al=ak.string_table;local am=ak.hash_tables;al[1]=g(X,1,1)al[2]=g(X,2,2)if Y>=3 then local J=1;local an=al[1]*256+al[2]while J<=Y-2-3 do local Z,_,a0,a1=g(X,J+2,J+5)al[J+2]=Z;al[J+3]=_;al[J+4]=a0;al[J+5]=a1;an=(an*256+Z)%16777216;local U=am[an]if not U then U={}am[an]=U end;U[#U+1]=J-Y;J=J+1;an=(an*256+_)%16777216;U=am[an]if not U then U={}am[an]=U end;U[#U+1]=J-Y;J=J+1;an=(an*256+a0)%16777216;U=am[an]if not U then U={}am[an]=U end;U[#U+1]=J-Y;J=J+1;an=(an*256+a1)%16777216;U=am[an]if not U then U={}am[an]=U end;U[#U+1]=J-Y;J=J+1 end;while J<=Y-2 do local ae=g(X,J+2)al[J+2]=ae;an=(an*256+ae)%16777216;local U=am[an]if not U then U={}am[an]=U end;U[#U+1]=J-Y;J=J+1 end end;return ak end;local function ao(ak)if type(ak)~="table"then return false,("'dictionary' - table expected got '%s'."):format(type(ak))end;if type(ak.adler32)~="number"or type(ak.string_table)~="table"or type(ak.strlen)~="number"or ak.strlen<=0 or ak.strlen>32768 or ak.strlen~=#ak.string_table or type(ak.hash_tables)~="table"then return false,("'dictionary' - corrupted dictionary."):format(type(ak))end;return true,""end;local ap={[0]={false,nil,0,0,0},[1]={false,nil,4,8,4},[2]={false,nil,5,18,8},[3]={false,nil,6,32,32},[4]={true,4,4,16,16},[5]={true,8,16,32,32},[6]={true,8,16,128,128},[7]={true,8,32,128,256},[8]={true,32,128,258,1024},[9]={true,32,258,258,4096}}local function aq(X,ar,ak,as,at)if type(X)~="string"then return false,("'str' - string expected got '%s'."):format(type(X))end;if ar then local au,av=ao(ak)if not au then return false,av end end;if as then local aw=type(at)if aw~="nil"and aw~="table"then return false,("'configs' - nil or table expected got '%s'."):format(type(at))end;if aw=="table"then for ax,ay in pairs(at)do if ax~="level"and ax~="strategy"then return false,("'configs' - unsupported table key in the configs: '%s'."):format(ax)elseif ax=="level"and not ap[ay]then return false,("'configs' - unsupported 'level': %s."):format(tostring(ay))elseif ax=="strategy"and ay~="fixed"and ay~="huffman_only"and ay~="dynamic"then return false,("'configs' - unsupported 'strategy': '%s'."):format(tostring(ay))end end end end;return true,""end;local az=0;local aA=1;local aB=2;local aC=3;local function aD()local aE=0;local aF=0;local aG=0;local aH=0;local aI={}local aJ={}local function aK(N,S)aF=aF+N*n[aG]aG=aG+S;aH=aH+S;if aG>=32 then aE=aE+1;aI[aE]=o[aF%256]..o[(aF-aF%256)/256%256]..o[(aF-aF%65536)/65536%256]..o[(aF-aF%16777216)/16777216%256]local aL=n[32-aG+S]aF=(N-N%aL)/aL;aG=aG-32 end end;local function aM(X)for O=1,aG,8 do aE=aE+1;aI[aE]=h(aF%256)aF=(aF-aF%256)/256 end;aG=0;aE=aE+1;aI[aE]=X;aH=aH+#X*8 end;local function aN(aO)if aO==aC then return aH end;if aO==aA or aO==aB then local aP=(8-aG%8)%8;if aG>0 then aF=aF-n[aG]+n[aG+aP]for O=1,aG,8 do aE=aE+1;aI[aE]=o[aF%256]aF=(aF-aF%256)/256 end;aF=0;aG=0 end;if aO==aB then aH=aH+aP;return aH end end;local aQ=l(aI)aI={}aE=0;aJ[#aJ+1]=aQ;if aO==az then return aH else return aH,l(aJ)end end;return aK,aM,aN end;local function aR(aS,aT,aU)aU=aU+1;aS[aU]=aT;local N=aT[1]local aV=aU;local aW=(aV-aV%2)/2;while aW>=1 and aS[aW][1]>N do local U=aS[aW]aS[aW]=aT;aS[aV]=U;aV=aW;aW=(aW-aW%2)/2 end end;local function aX(aS,aU)local aY=aS[1]local aT=aS[aU]local N=aT[1]aS[1]=aT;aS[aU]=aY;aU=aU-1;local aV=1;local aZ=aV*2;local a_=aZ+1;while aZ<=aU do local b0=aS[aZ]if a_<=aU and aS[a_][1]<b0[1]then local b1=aS[a_]if b1[1]<N then aS[a_]=aT;aS[aV]=b1;aV=a_;aZ=aV*2;a_=aZ+1 else break end else if b0[1]<N then aS[aZ]=aT;aS[aV]=b0;aV=aZ;aZ=aV*2;a_=aZ+1 else break end end end;return aY end;local function b2(b3,b4,b5,b6)local b7=0;local b8={}local b9={}for S=1,b6 do b7=(b7+(b3[S-1]or 0))*2;b8[S]=b7 end;for ba=0,b5 do local S=b4[ba]if S then b7=b8[S]b8[S]=b7+1;if S<=9 then b9[ba]=p[S][b7]else local M=0;for O=1,S do M=M-M%2+((M%2==1 or b7%2==1)and 1 or 0)b7=(b7-b7%2)/2;M=M*2 end;b9[ba]=(M-M%2)/2 end end end;return b9 end;local function bb(P,Q)return P[1]<Q[1]or P[1]==Q[1]and P[2]<Q[2]end;local function bc(bd,b6,b5)local aU;local be=-1;local bf={}local aS={}local b4={}local bg={}local b3={}local bh=0;for ba,bi in pairs(bd)do bh=bh+1;bf[bh]={bi,ba}end;if bh==0 then return{},{},-1 elseif bh==1 then local ba=bf[1][2]b4[ba]=1;bg[ba]=0;return b4,bg,ba else m(bf,bb)aU=bh;for J=1,aU do aS[J]=bf[J]end;while aU>1 do local bj=aX(aS,aU)aU=aU-1;local bk=aX(aS,aU)aU=aU-1;local bl={bj[1]+bk[1],-1,bj,bk}aR(aS,bl,aU)aU=aU+1 end;local bm=0;local bn={aS[1],0,0,0}local bo=1;local bp=1;aS[1][1]=0;while bp<=bo do local aT=bn[bp]local S=aT[1]local ba=aT[2]local b0=aT[3]local b1=aT[4]if b0 then bo=bo+1;bn[bo]=b0;b0[1]=S+1 end;if b1 then bo=bo+1;bn[bo]=b1;b1[1]=S+1 end;bp=bp+1;if S>b6 then bm=bm+1;S=b6 end;if ba>=0 then b4[ba]=S;be=ba>be and ba or be;b3[S]=(b3[S]or 0)+1 end end;if bm>0 then repeat local S=b6-1;while(b3[S]or 0)==0 do S=S-1 end;b3[S]=b3[S]-1;b3[S+1]=(b3[S+1]or 0)+2;b3[b6]=b3[b6]-1;bm=bm-2 until bm<=0;bp=1;for S=b6,1,-1 do local bq=b3[S]or 0;while bq>0 do local ba=bf[bp][2]b4[ba]=S;bq=bq-1;bp=bp+1 end end end;bg=b2(b3,b4,b5,b6)return b4,bg,be end end;local function br(bs,bt,bu,bv)local bw=0;local bx={}local by={}local bz=0;local bA={}local bB=nil;local bi=0;bv=bv<0 and 0 or bv;local bC=bt+bv+1;for V=0,bC+1 do local T=V<=bt and(bs[V]or 0)or(V<=bC and(bu[V-bt-1]or 0)or nil)if T==bB then bi=bi+1;if T~=0 and bi==6 then bw=bw+1;bx[bw]=16;bz=bz+1;bA[bz]=3;by[16]=(by[16]or 0)+1;bi=0 elseif T==0 and bi==138 then bw=bw+1;bx[bw]=18;bz=bz+1;bA[bz]=127;by[18]=(by[18]or 0)+1;bi=0 end else if bi==1 then bw=bw+1;bx[bw]=bB;by[bB]=(by[bB]or 0)+1 elseif bi==2 then bw=bw+1;bx[bw]=bB;bw=bw+1;bx[bw]=bB;by[bB]=(by[bB]or 0)+2 elseif bi>=3 then bw=bw+1;local bD=bB~=0 and 16 or(bi<=10 and 17 or 18)bx[bw]=bD;by[bD]=(by[bD]or 0)+1;bz=bz+1;bA[bz]=bi<=10 and bi-3 or bi-11 end;bB=T;if T and T~=0 then bw=bw+1;bx[bw]=T;by[T]=(by[T]or 0)+1;bi=0 else bi=1 end end end;return bx,bA,by end;local function bE(X,U,bF,bG,bH)local J=bF-bH;while J<=bG-15-bH do U[J],U[J+1],U[J+2],U[J+3],U[J+4],U[J+5],U[J+6],U[J+7],U[J+8],U[J+9],U[J+10],U[J+11],U[J+12],U[J+13],U[J+14],U[J+15]=g(X,J+bH,J+15+bH)J=J+16 end;while J<=bG-bH do U[J]=g(X,J+bH,J+bH)J=J+1 end;return U end;local function bI(bJ,al,am,bK,bL,bH,ak)local bM=ap[bJ]local bN,bO,bP,bQ,bR=bM[1],bM[2],bM[3],bM[4],bM[5]local bS=not bN and bP or 2147483646;local bT=bR-bR%4/4;local an;local bU;local bV;local bW=0;if ak then bU=ak.hash_tables;bV=ak.string_table;bW=ak.strlen;assert(bK==1)if bL>=bK and bW>=2 then an=bV[bW-1]*65536+bV[bW]*256+al[1]local U=am[an]if not U then U={}am[an]=U end;U[#U+1]=-1 end;if bL>=bK+1 and bW>=1 then an=bV[bW]*65536+al[1]*256+al[2]local U=am[an]if not U then U={}am[an]=U end;U[#U+1]=0 end end;local bX=bW+3;an=(al[bK-bH]or 0)*256+(al[bK+1-bH]or 0)local bY={}local bZ=0;local b_={}local c0={}local c1=0;local c2={}local c3={}local c4=0;local c5={}local c6=0;local c7=false;local c8;local c9;local ca=0;local cb=0;local bp=bK;local cc=bL+(bN and 1 or 0)while bp<=cc do local cd=bp-bH;local ce=bH-3;c8=ca;c9=cb;ca=0;an=(an*256+(al[cd+2]or 0))%16777216;local cf;local cg;local ch=am[an]local ci;if not ch then ci=0;ch={}am[an]=ch;if bU then cg=bU[an]cf=cg and#cg or 0 else cf=0 end else ci=#ch;cg=ch;cf=ci end;if bp<=bL then ch[ci+1]=bp end;if cf>0 and bp+2<=bL and(not bN or c8<bP)then local cj=bN and c8>=bO and bT or bR;local ck=bL-bp;ck=ck>=257 and 257 or ck;ck=ck+cd;local cl=cd+3;while cf>=1 and cj>0 do local bB=cg[cf]if bp-bB>32768 then break end;if bB<bp then local cm=cl;if bB>=-257 then local cn=bB-ce;while cm<=ck and al[cn]==al[cm]do cm=cm+1;cn=cn+1 end else local cn=bX+bB;while cm<=ck and bV[cn]==al[cm]do cm=cm+1;cn=cn+1 end end;local L=cm-cd;if L>ca then ca=L;cb=bp-bB end;if ca>=bQ then break end end;cf=cf-1;cj=cj-1;if cf==0 and bB>0 and bU then cg=bU[an]cf=cg and#cg or 0 end end end;if not bN then c8,c9=ca,cb end;if(not bN or c7)and(c8>3 or c8==3 and c9<4096)and ca<=c8 then local V=q[c8]local co=s[c8]local cp,cq,cr;if c9<=256 then cp=t[c9]cr=u[c9]cq=v[c9]else cp=16;cq=7;local P=384;local Q=512;while true do if c9<=P then cr=(c9-Q/2-1)%(Q/4)break elseif c9<=Q then cr=(c9-Q/2-1)%(Q/4)cp=cp+1;break else cp=cp+2;cq=cq+1;P=P*2;Q=Q*2 end end end;bZ=bZ+1;bY[bZ]=V;b_[V]=(b_[V]or 0)+1;c1=c1+1;c0[c1]=cp;c2[cp]=(c2[cp]or 0)+1;if co>0 then local cs=r[c8]c4=c4+1;c3[c4]=cs end;if cq>0 then c6=c6+1;c5[c6]=cr end;for J=bp+1,bp+c8-(bN and 2 or 1)do an=(an*256+(al[J-bH+2]or 0))%16777216;if c8<=bS then ch=am[an]if not ch then ch={}am[an]=ch end;ch[#ch+1]=J end end;bp=bp+c8-(bN and 1 or 0)c7=false elseif not bN or c7 then local V=al[bN and cd-1 or cd]bZ=bZ+1;bY[bZ]=V;b_[V]=(b_[V]or 0)+1;bp=bp+1 else c7=true;bp=bp+1 end end;bZ=bZ+1;bY[bZ]=256;b_[256]=(b_[256]or 0)+1;return bY,c3,b_,c0,c5,c2 end;local function ct(b_,c2)local cu,cv,bt=bc(b_,15,285)local cw,cx,bv=bc(c2,15,29)local cy,bA,cz=br(cu,bt,cw,bv)local cA,cB=bc(cz,7,18)local cC=0;for J=1,19 do local ba=A[J]local cD=cA[ba]or 0;if cD~=0 then cC=J end end;cC=cC-4;local cE=bt+1-257;local cF=bv+1-1;if cF<0 then cF=0 end;return cE,cF,cC,cA,cB,cy,bA,cu,cv,cw,cx end;local function cG(bY,c0,cC,cA,cy,cu,cw)local cH=17;cH=cH+(cC+4)*3;for J=1,#cy do local V=cy[J]cH=cH+cA[V]if V>=16 then cH=cH+(V==16 and 2 or(V==17 and 3 or 7))end end;local cI=0;for J=1,#bY do local V=bY[J]local cJ=cu[V]cH=cH+cJ;if V>256 then cI=cI+1;if V>264 and V<285 then local cK=x[V-256]cH=cH+cK end;local cp=c0[cI]local cL=cw[cp]cH=cH+cL;if cp>3 then local cq=(cp-cp%2)/2-1;cH=cH+cq end end end;return cH end;local function cM(aK,cN,bY,c3,c0,c5,cE,cF,cC,cA,cB,cy,bA,cu,cv,cw,cx)aK(cN and 1 or 0,1)aK(2,2)aK(cE,5)aK(cF,5)aK(cC,4)for J=1,cC+4 do local ba=A[J]local cD=cA[ba]or 0;aK(cD,3)end;local cO=1;for J=1,#cy do local V=cy[J]aK(cB[V],cA[V])if V>=16 then local cP=bA[cO]aK(cP,V==16 and 2 or(V==17 and 3 or 7))cO=cO+1 end end;local cI=0;local cQ=0;local cR=0;for J=1,#bY do local cS=bY[J]local b7=cv[cS]local cJ=cu[cS]aK(b7,cJ)if cS>256 then cI=cI+1;if cS>264 and cS<285 then cQ=cQ+1;local cT=c3[cQ]local cK=x[cS-256]aK(cT,cK)end;local cU=c0[cI]local cV=cx[cU]local cL=cw[cU]aK(cV,cL)if cU>3 then cR=cR+1;local cr=c5[cR]local cq=(cU-cU%2)/2-1;aK(cr,cq)end end end end;local function cW(bY,c0)local cH=3;local cI=0;for J=1,#bY do local V=bY[J]local cJ=D[V]cH=cH+cJ;if V>256 then cI=cI+1;if V>264 and V<285 then local cK=x[V-256]cH=cH+cK end;local cp=c0[cI]cH=cH+5;if cp>3 then local cq=(cp-cp%2)/2-1;cH=cH+cq end end end;return cH end;local function cX(aK,cN,bY,c3,c0,c5)aK(cN and 1 or 0,1)aK(1,2)local cI=0;local cQ=0;local cR=0;for J=1,#bY do local cY=bY[J]local b7=B[cY]local cJ=D[cY]aK(b7,cJ)if cY>256 then cI=cI+1;if cY>264 and cY<285 then cQ=cQ+1;local cT=c3[cQ]local cK=x[cY-256]aK(cT,cK)end;local cp=c0[cI]local cV=F[cp]aK(cV,5)if cp>3 then cR=cR+1;local cr=c5[cR]local cq=(cp-cp%2)/2-1;aK(cr,cq)end end end end;local function cZ(bK,bL,aH)assert(bL-bK+1<=65535)local cH=3;aH=aH+3;local aP=(8-aH%8)%8;cH=cH+aP;cH=cH+32;cH=cH+(bL-bK+1)*8;return cH end;local function c_(aK,aM,cN,X,bK,bL,aH)assert(bL-bK+1<=65535)aK(cN and 1 or 0,1)aK(0,2)aH=aH+3;local aP=(8-aH%8)%8;if aP>0 then aK(n[aP]-1,aP)end;local d0=bL-bK+1;aK(d0,16)local d1=255-d0%256+(255-(d0-d0%256)/256)*256;aK(d1,16)aM(X:sub(bK,bL))end;local function d2(at,aK,aM,aN,X,ak)local al={}local am={}local cN=nil;local bK;local bL;local d3;local aH=aN(aC)local Y=#X;local bH;local bJ;local d4;if at then if at.level then bJ=at.level end;if at.strategy then d4=at.strategy end end;if not bJ then if Y<2048 then bJ=7 elseif Y>65536 then bJ=3 else bJ=5 end end;while not cN do if not bK then bK=1;bL=64*1024-1;bH=0 else bK=bL+1;bL=bL+32*1024;bH=bK-32*1024-1 end;if bL>=Y then bL=Y;cN=true else cN=false end;local bY,c3,b_,c0,c5,c2;local cE,cF,cC,cA,cB,cy,bA,cu,cv,cw,cx;local d5;local d6;local d7;if bJ~=0 then bE(X,al,bK,bL+3,bH)if bK==1 and ak then local bV=ak.string_table;local d8=ak.strlen;for J=0,-d8+1<-257 and-257 or-d8+1,-1 do al[J]=bV[d8+J]end end;if d4=="huffman_only"then bY={}bE(X,bY,bK,bL,bK-1)c3={}b_={}bY[bL-bK+2]=256;for J=1,bL-bK+2 do local V=bY[J]b_[V]=(b_[V]or 0)+1 end;c0={}c5={}c2={}else bY,c3,b_,c0,c5,c2=bI(bJ,al,am,bK,bL,bH,ak)end;cE,cF,cC,cA,cB,cy,bA,cu,cv,cw,cx=ct(b_,c2)d5=cG(bY,c0,cC,cA,cy,cu,cw)d6=cW(bY,c0)end;d7=cZ(bK,bL,aH)local d9=d7;d9=d6 and d6<d9 and d6 or d9;d9=d5 and d5<d9 and d5 or d9;if bJ==0 or d4~="fixed"and d4~="dynamic"and d7==d9 then c_(aK,aM,cN,X,bK,bL,aH)aH=aH+d7 elseif d4~="dynamic"and(d4=="fixed"or d6==d9)then cX(aK,cN,bY,c3,c0,c5)aH=aH+d6 elseif d4=="dynamic"or d5==d9 then cM(aK,cN,bY,c3,c0,c5,cE,cF,cC,cA,cB,cy,bA,cu,cv,cw,cx)aH=aH+d5 end;if cN then d3=aN(aC)else d3=aN(az)end;assert(d3==aH)if not cN then local L;if ak and bK==1 then L=0;while al[L]do al[L]=nil;L=L-1 end end;ak=nil;L=1;for J=bL-32767,bL do al[L]=al[J-bH]L=L+1 end;for ax,U in pairs(am)do local da=#U;if da>0 and bL+1-U[1]>32768 then if da==1 then am[ax]=nil else local db={}local dc=0;for J=2,da do L=U[J]if bL+1-L<=32768 then dc=dc+1;db[dc]=L end end;am[ax]=db end end end end end end;local function dd(X,ak,at)local aK,aM,aN=aD()d2(at,aK,aM,aN,X,ak)local aH,de=aN(aA)local aP=(8-aH%8)%8;return de,aP end;local function df(X,ak,at)local aK,aM,aN=aD()local dg=8;local dh=7;local di=dh*16+dg;aK(di,8)local dj=ak and 1 or 0;local dk=2;local dl=dk*64+dj*32;local dm=31-(di*256+dl)%31;dl=dl+dm;aK(dl,8)if dj==1 then local ai=ak.adler32;local dn=ai%256;ai=(ai-dn)/256;local dp=ai%256;ai=(ai-dp)/256;local dq=ai%256;ai=(ai-dq)/256;local dr=ai%256;aK(dr,8)aK(dq,8)aK(dp,8)aK(dn,8)end;d2(at,aK,aM,aN,X,ak)aN(aB)local ai=LibDeflate:Adler32(X)local dr=ai%256;ai=(ai-dr)/256;local dq=ai%256;ai=(ai-dq)/256;local dp=ai%256;ai=(ai-dp)/256;local dn=ai%256;aK(dn,8)aK(dp,8)aK(dq,8)aK(dr,8)local aH,de=aN(aA)local aP=(8-aH%8)%8;return de,aP end;function LibDeflate:CompressDeflate(X,at)local ds,dt=aq(X,false,nil,true,at)if not ds then error("Usage: LibDeflate:CompressDeflate(str, configs): "..dt,2)end;return dd(X,nil,at)end;function LibDeflate:CompressDeflateWithDict(X,ak,at)local ds,dt=aq(X,true,ak,true,at)if not ds then error("Usage: LibDeflate:CompressDeflateWithDict".."(str, dictionary, configs): "..dt,2)end;return dd(X,ak,at)end;function LibDeflate:CompressZlib(X,at)local ds,dt=aq(X,false,nil,true,at)if not ds then error("Usage: LibDeflate:CompressZlib(str, configs): "..dt,2)end;return df(X,nil,at)end;function LibDeflate:CompressZlibWithDict(X,ak,at)local ds,dt=aq(X,true,ak,true,at)if not ds then error("Usage: LibDeflate:CompressZlibWithDict".."(str, dictionary, configs): "..dt,2)end;return df(X,ak,at)end;local function du(dv)local dw=dv;local dx=#dv;local dy=1;local aG=0;local aF=0;local function dz(S)local aL=n[S]local V;if S<=aG then V=aF%aL;aF=(aF-V)/aL;aG=aG-S else local dA=n[aG]local dp,dq,dr,dB=g(dw,dy,dy+3)aF=aF+((dp or 0)+(dq or 0)*256+(dr or 0)*65536+(dB or 0)*16777216)*dA;dy=dy+4;aG=aG+32-S;V=aF%aL;aF=(aF-V)/aL end;return V end;local function dC(dD,aI,aE)assert(aG%8==0)local dE=aG/8<dD and aG/8 or dD;for O=1,dE do local dF=aF%256;aE=aE+1;aI[aE]=h(dF)aF=(aF-dF)/256 end;aG=aG-dE*8;dD=dD-dE;if(dx-dy-dD+1)*8+aG<0 then return-1 end;for J=dy,dy+dD-1 do aE=aE+1;aI[aE]=k(dw,J,J)end;dy=dy+dD;return aE end;local function dG(dH,dI,d9)local V=0;local dJ=0;local bp=0;local bi;if d9>0 then if aG<15 and dw then local dA=n[aG]local dp,dq,dr,dB=g(dw,dy,dy+3)aF=aF+((dp or 0)+(dq or 0)*256+(dr or 0)*65536+(dB or 0)*16777216)*dA;dy=dy+4;aG=aG+32 end;local aL=n[d9]aG=aG-d9;V=aF%aL;aF=(aF-V)/aL;V=p[d9][V]bi=dH[d9]if V<bi then return dI[V]end;bp=bi;dJ=bi*2;V=V*2 end;for S=d9+1,15 do local dK;dK=aF%2;aF=(aF-dK)/2;aG=aG-1;V=dK==1 and V+1-V%2 or V;bi=dH[S]or 0;local dL=V-dJ;if dL<bi then return dI[bp+dL]end;bp=bp+bi;dJ=dJ+bi;dJ=dJ*2;V=V*2 end;return-10 end;local function dM()return(dx-dy+1)*8+aG end;local function dN()local dO=aG%8;local aL=n[dO]aG=aG-dO;aF=(aF-aF%aL)/aL end;return dz,dC,dG,dM,dN end;local function dP(X,ak)local dz,dC,dG,dM,dN=du(X)local dQ={ReadBits=dz,ReadBytes=dC,Decode=dG,ReaderBitlenLeft=dM,SkipToByteBoundary=dN,buffer_size=0,buffer={},result_buffer={},dictionary=ak}return dQ end;local function dR(dS,b5,b6)local dH={}local d9=b6;for ba=0,b5 do local S=dS[ba]or 0;d9=S>0 and S<d9 and S or d9;dH[S]=(dH[S]or 0)+1 end;if dH[0]==b5+1 then return 0,dH,{},0 end;local dT=1;for T=1,b6 do dT=dT*2;dT=dT-(dH[T]or 0)if dT<0 then return dT end end;local dU={}dU[1]=0;for T=1,b6-1 do dU[T+1]=dU[T]+(dH[T]or 0)end;local dI={}for ba=0,b5 do local S=dS[ba]or 0;if S~=0 then local bH=dU[S]dI[bH]=ba;dU[S]=dU[S]+1 end end;return dT,dH,dI,d9 end;local function dV(dQ,cu,dW,dX,cw,dY,dZ)local aI,aE,dz,dG,dM,aJ=dQ.buffer,dQ.buffer_size,dQ.ReadBits,dQ.Decode,dQ.ReaderBitlenLeft,dQ.result_buffer;local ak=dQ.dictionary;local bV;local d8;local d_=1;if ak and not aI[0]then bV=ak.string_table;d8=ak.strlen;d_=-d8+1;for J=0,-d8+1<-257 and-257 or-d8+1,-1 do aI[J]=o[bV[d8+J]]end end;repeat local ba=dG(cu,dW,dX)if ba<0 or ba>285 then return-10 elseif ba<256 then aE=aE+1;aI[aE]=o[ba]elseif ba>256 then ba=ba-256;local S=w[ba]S=ba>=8 and S+dz(x[ba])or S;ba=dG(cw,dY,dZ)if ba<0 or ba>29 then return-10 end;local W=y[ba]W=W>4 and W+dz(z[ba])or W;local e0=aE-W+1;if e0<d_ then return-11 end;if e0>=-257 then for O=1,S do aE=aE+1;aI[aE]=aI[e0]e0=e0+1 end else e0=d8+e0;for O=1,S do aE=aE+1;aI[aE]=o[bV[e0]]e0=e0+1 end end end;if dM()<0 then return 2 end;if aE>=65536 then aJ[#aJ+1]=l(aI,"",1,32768)for J=32769,aE do aI[J-32768]=aI[J]end;aE=aE-32768;aI[aE+1]=nil end until ba==256;dQ.buffer_size=aE;return 0 end;local function e1(dQ)local aI,aE,dz,dC,dM,dN,aJ=dQ.buffer,dQ.buffer_size,dQ.ReadBits,dQ.ReadBytes,dQ.ReaderBitlenLeft,dQ.SkipToByteBoundary,dQ.result_buffer;dN()local dD=dz(16)if dM()<0 then return 2 end;local e2=dz(16)if dM()<0 then return 2 end;if dD%256+e2%256~=255 then return-2 end;if(dD-dD%256)/256+(e2-e2%256)/256~=255 then return-2 end;aE=dC(dD,aI,aE)if aE<0 then return 2 end;if aE>=65536 then aJ[#aJ+1]=l(aI,"",1,32768)for J=32769,aE do aI[J-32768]=aI[J]end;aE=aE-32768;aI[aE+1]=nil end;dQ.buffer_size=aE;return 0 end;local function e3(dQ)return dV(dQ,E,C,7,I,G,5)end;local function e4(dQ)local dz,dG=dQ.ReadBits,dQ.Decode;local e5=dz(5)+257;local e6=dz(5)+1;local e7=dz(4)+4;if e5>286 or e6>30 then return-3 end;local cA={}for J=1,e7 do cA[A[J]]=dz(3)end;local e8,e9,ea,eb=dR(cA,18,7)if e8~=0 then return-4 end;local cu={}local cw={}local bp=0;while bp<e5+e6 do local ba;local S;ba=dG(e9,ea,eb)if ba<0 then return ba elseif ba<16 then if bp<e5 then cu[bp]=ba else cw[bp-e5]=ba end;bp=bp+1 else S=0;if ba==16 then if bp==0 then return-5 end;if bp-1<e5 then S=cu[bp-1]else S=cw[bp-e5-1]end;ba=3+dz(2)elseif ba==17 then ba=3+dz(3)else ba=11+dz(7)end;if bp+ba>e5+e6 then return-6 end;while ba>0 do ba=ba-1;if bp<e5 then cu[bp]=S else cw[bp-e5]=S end;bp=bp+1 end end end;if(cu[256]or 0)==0 then return-9 end;local ec,ed,dW,dX=dR(cu,e5-1,15)if ec~=0 and(ec<0 or e5~=(ed[0]or 0)+(ed[1]or 0))then return-7 end;local ee,ef,dY,dZ=dR(cw,e6-1,15)if ee~=0 and(ee<0 or e6~=(ef[0]or 0)+(ef[1]or 0))then return-8 end;return dV(dQ,ed,dW,dX,ef,dY,dZ)end;local function eg(dQ)local dz=dQ.ReadBits;local cN;while not cN do cN=dz(1)==1;local eh=dz(2)local ei;if eh==0 then ei=e1(dQ)elseif eh==1 then ei=e3(dQ)elseif eh==2 then ei=e4(dQ)else return nil,-1 end;if ei~=0 then return nil,ei end end;dQ.result_buffer[#dQ.result_buffer+1]=l(dQ.buffer,"",1,dQ.buffer_size)local de=l(dQ.result_buffer)return de end;local function ej(X,ak)local dQ=dP(X,ak)local de,ei=eg(dQ)if not de then return nil,ei end;local ek=dQ.ReaderBitlenLeft()local el=(ek-ek%8)/8;return de,el end;local function em(X,ak)local dQ=dP(X,ak)local dz=dQ.ReadBits;local di=dz(8)if dQ.ReaderBitlenLeft()<0 then return nil,2 end;local dg=di%16;local dh=(di-dg)/16;if dg~=8 then return nil,-12 end;if dh>7 then return nil,-13 end;local dl=dz(8)if dQ.ReaderBitlenLeft()<0 then return nil,2 end;if(di*256+dl)%31~=0 then return nil,-14 end;local dj=(dl-dl%32)/32%2;local dk=(dl-dl%64)/64%4;if dj==1 then if not ak then return nil,-16 end;local dr=dz(8)local dq=dz(8)local dp=dz(8)local dn=dz(8)local aj=dr*16777216+dq*65536+dp*256+dn;if dQ.ReaderBitlenLeft()<0 then return nil,2 end;if not af(aj,ak.adler32)then return nil,-17 end end;local de,ei=eg(dQ)if not de then return nil,ei end;dQ.SkipToByteBoundary()local en=dz(8)local eo=dz(8)local ep=dz(8)local eq=dz(8)if dQ.ReaderBitlenLeft()<0 then return nil,2 end;local er=en*16777216+eo*65536+ep*256+eq;local es=LibDeflate:Adler32(de)if not af(er,es)then return nil,-15 end;local ek=dQ.ReaderBitlenLeft()local el=(ek-ek%8)/8;return de,el end;function LibDeflate:DecompressDeflate(X)local ds,dt=aq(X)if not ds then error("Usage: LibDeflate:DecompressDeflate(str): "..dt,2)end;return ej(X)end;function LibDeflate:DecompressDeflateWithDict(X,ak)local ds,dt=aq(X,true,ak)if not ds then error("Usage: LibDeflate:DecompressDeflateWithDict(str, dictionary): "..dt,2)end;return ej(X,ak)end;function LibDeflate:DecompressZlib(X)local ds,dt=aq(X)if not ds then error("Usage: LibDeflate:DecompressZlib(str): "..dt,2)end;return em(X)end;function LibDeflate:DecompressZlibWithDict(X,ak)local ds,dt=aq(X,true,ak)if not ds then error("Usage: LibDeflate:DecompressZlibWithDict(str, dictionary): "..dt,2)end;return em(X,ak)end;do D={}for et=0,143 do D[et]=8 end;for et=144,255 do D[et]=9 end;for et=256,279 do D[et]=7 end;for et=280,287 do D[et]=8 end;H={}for W=0,31 do H[W]=5 end;local ei;ei,E,C=dR(D,287,9)assert(ei==0)ei,I,G=dR(H,31,5)assert(ei==0)B=b2(E,D,287,9)F=b2(I,H,31,5)end;local eu={["\000"]="%z",["("]="%(",[")"]="%)",["."]="%.",["%"]="%%",["+"]="%+",["-"]="%-",["*"]="%*",["?"]="%?",["["]="%[",["]"]="%]",["^"]="%^",["$"]="%$"}local function ev(X)return X:gsub("([%z%(%)%.%%%+%-%*%?%[%]%^%$])",eu)end;function LibDeflate:CreateCodec(ew,ex,ey)if type(ew)~="string"or type(ex)~="string"or type(ey)~="string"then error("Usage: LibDeflate:CreateCodec(reserved_chars,".." escape_chars, map_chars):".." All arguments must be string.",2)end;if ex==""then return nil,"No escape characters supplied."end;if#ew<#ey then return nil,"The number of reserved characters must be".." at least as many as the number of mapped chars."end;if ew==""then return nil,"No characters to encode."end;local ez=ew..ex..ey;local eA={}for J=1,#ez do local dF=g(ez,J,J)if eA[dF]then return nil,"There must be no duplicate characters in the".." concatenation of reserved_chars, escape_chars and".." map_chars."end;eA[dF]=true end;local eB={}local eC={}local eD={}local eE={}if#ey>0 then local eF={}local eG={}for J=1,#ey do local eH=k(ew,J,J)local eI=k(ey,J,J)eE[eH]=eI;eD[#eD+1]=eH;eG[eI]=eH;eF[#eF+1]=eI end;eB[#eB+1]="(["..ev(l(eF)).."])"eC[#eC+1]=eG end;local eJ=1;local eK=k(ex,eJ,eJ)local eL=0;local eF={}local eG={}for J=1,#ez do local R=k(ez,J,J)if not eE[R]then while eL>=256 or eA[eL]do eL=eL+1;if eL>255 then eB[#eB+1]=ev(eK).."(["..ev(l(eF)).."])"eC[#eC+1]=eG;eJ=eJ+1;eK=k(ex,eJ,eJ)eL=0;eF={}eG={}if not eK or eK==""then return nil,"Out of escape characters."end end end;local eM=o[eL]eE[R]=eK..eM;eD[#eD+1]=R;eG[eM]=R;eF[#eF+1]=eM;eL=eL+1 end;if J==#ez then eB[#eB+1]=ev(eK).."(["..ev(l(eF)).."])"eC[#eC+1]=eG end end;local eN={}local eO="(["..ev(l(eD)).."])"local eP=eE;function eN:Encode(X)if type(X)~="string"then error(("Usage: codec:Encode(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;return j(X,eO,eP)end;local eQ=#eB;local eR="(["..ev(ew).."])"function eN:Decode(X)if type(X)~="string"then error(("Usage: codec:Decode(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if i(X,eR)then return nil end;for J=1,eQ do X=j(X,eB[J],eC[J])end;return X end;return eN end;local eS;local function eT()return LibDeflate:CreateCodec("\000","\001","")end;function LibDeflate:EncodeForWoWAddonChannel(X)if type(X)~="string"then error(("Usage: LibDeflate:EncodeForWoWAddonChannel(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if not eS then eS=eT()end;return eS:Encode(X)end;function LibDeflate:DecodeForWoWAddonChannel(X)if type(X)~="string"then error(("Usage: LibDeflate:DecodeForWoWAddonChannel(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if not eS then eS=eT()end;return eS:Decode(X)end;local function eU()local eL={}for J=128,255 do eL[#eL+1]=o[J]end;local ew="sS\000\010\013\124%"..l(eL)return LibDeflate:CreateCodec(ew,"\029\031","\015\020")end;local eV;function LibDeflate:EncodeForWoWChatChannel(X)if type(X)~="string"then error(("Usage: LibDeflate:EncodeForWoWChatChannel(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if not eV then eV=eU()end;return eV:Encode(X)end;function LibDeflate:DecodeForWoWChatChannel(X)if type(X)~="string"then error(("Usage: LibDeflate:DecodeForWoWChatChannel(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;if not eV then eV=eU()end;return eV:Decode(X)end;local eW={[0]="a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9","(",")"}local eX={[97]=0,[98]=1,[99]=2,[100]=3,[101]=4,[102]=5,[103]=6,[104]=7,[105]=8,[106]=9,[107]=10,[108]=11,[109]=12,[110]=13,[111]=14,[112]=15,[113]=16,[114]=17,[115]=18,[116]=19,[117]=20,[118]=21,[119]=22,[120]=23,[121]=24,[122]=25,[65]=26,[66]=27,[67]=28,[68]=29,[69]=30,[70]=31,[71]=32,[72]=33,[73]=34,[74]=35,[75]=36,[76]=37,[77]=38,[78]=39,[79]=40,[80]=41,[81]=42,[82]=43,[83]=44,[84]=45,[85]=46,[86]=47,[87]=48,[88]=49,[89]=50,[90]=51,[48]=52,[49]=53,[50]=54,[51]=55,[52]=56,[53]=57,[54]=58,[55]=59,[56]=60,[57]=61,[40]=62,[41]=63}function LibDeflate:EncodeForPrint(X)if type(X)~="string"then error(("Usage: LibDeflate:EncodeForPrint(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;local Y=#X;local eY=Y-2;local J=1;local aI={}local aE=0;while J<=eY do local Z,_,a0=g(X,J,J+2)J=J+3;local aF=Z+_*256+a0*65536;local eZ=aF%64;aF=(aF-eZ)/64;local e_=aF%64;aF=(aF-e_)/64;local f0=aF%64;local f1=(aF-f0)/64;aE=aE+1;aI[aE]=eW[eZ]..eW[e_]..eW[f0]..eW[f1]end;local aF=0;local aG=0;while J<=Y do local ae=g(X,J,J)aF=aF+ae*n[aG]aG=aG+8;J=J+1 end;while aG>0 do local f2=aF%64;aE=aE+1;aI[aE]=eW[f2]aF=(aF-f2)/64;aG=aG-6 end;return l(aI)end;function LibDeflate:DecodeForPrint(X)if type(X)~="string"then error(("Usage: LibDeflate:DecodeForPrint(str):".." 'str' - string expected got '%s'."):format(type(X)),2)end;X=X:gsub("^[%c ]+","")X=X:gsub("[%c ]+$","")local Y=#X;if Y==1 then return nil end;local f3=Y-3;local J=1;local aI={}local aE=0;while J<=f3 do local Z,_,a0,a1=g(X,J,J+3)Z=eX[Z]_=eX[_]a0=eX[a0]a1=eX[a1]if not(Z and _ and a0 and a1)then return nil end;J=J+4;local aF=Z+_*64+a0*4096+a1*262144;local eZ=aF%256;aF=(aF-eZ)/256;local e_=aF%256;local f0=(aF-e_)/256;aE=aE+1;aI[aE]=o[eZ]..o[e_]..o[f0]end;local aF=0;local aG=0;while J<=Y do local ae=g(X,J,J)ae=eX[ae]if not ae then return nil end;aF=aF+ae*n[aG]aG=aG+6;J=J+1 end;while aG>=8 do local dF=aF%256;aE=aE+1;aI[aE]=o[dF]aF=(aF-dF)/256;aG=aG-8 end;return l(aI)end;local function f4()eV=nil;eS=nil end;LibDeflate.internals={LoadStringToTable=bE,IsValidDictionary=ao,IsEqualAdler32=af,_byte_to_6bit_char=eW,_6bit_to_byte=eX,InternalClearCache=f4}

--SPLIT_FILE--  
----------------------------------------------------------------------
----------------------------------------------------------------------


































-- This code compresses all the lua source and 
-- packs it along with fonts and images, into a
-- single resource.h file that is then included 
-- in main.c
-- it also expands a bunch of typedefs into core.lua

local defstr
do
local defs = {
{"struct", "sg_buffer"},
{"struct", "sg_image"},
{"struct", "sg_sampler"},
{"struct", "sg_shader"},
{"struct", "sg_pipeline"},
{"struct", "sg_attachments"},

{"struct", "sg_range"},

{"enum", "sg_backend"},
{"enum", "sg_pixel_format"},

{"struct", "sg_color"},
{"struct", "sg_pixelformat_info"},
{"struct", "sg_features"},
{"struct", "sg_limits"},

{"enum", "sg_resource_state"},
{"enum", "sg_usage"},
{"enum", "sg_buffer_type"},
{"enum", "sg_index_type"},
{"enum", "sg_image_type"},
{"enum", "sg_image_sample_type"},
{"enum", "sg_sampler_type"},
{"enum", "sg_cube_face"},
{"enum", "sg_shader_stage"},
{"enum", "sg_primitive_type"},
{"enum", "sg_filter"},
{"enum", "sg_wrap"},
{"enum", "sg_border_color"},
{"enum", "sg_vertex_format"},
{"enum", "sg_vertex_step"},
{"enum", "sg_uniform_type"},
{"enum", "sg_uniform_layout"},
{"enum", "sg_cull_mode"},
{"enum", "sg_face_winding"},
{"enum", "sg_compare_func"},
{"enum", "sg_stencil_op"},
{"enum", "sg_blend_factor"},
{"enum", "sg_blend_op"},
{"enum", "sg_color_mask"},
{"enum", "sg_load_action"},
{"enum", "sg_store_action"},

{"struct", "sg_color_attachment_action"},
{"struct", "sg_depth_attachment_action"},
{"struct", "sg_stencil_attachment_action"},
{"struct", "sg_pass_action"},

{"struct", "sg_metal_swapchain"},
{"struct", "sg_d3d11_swapchain"},
{"struct", "sg_wgpu_swapchain"},
{"struct", "sg_gl_swapchain"},
{"struct", "sg_swapchain"},
{"struct", "sg_pass"},

{"struct", "sg_stage_bindings"},
{"struct", "sg_bindings"},
{"struct", "sg_buffer_desc"},
{"struct", "sg_image_data"},
{"struct", "sg_image_desc"},
{"struct", "sg_sampler_desc"},

{"struct", "sg_shader_attr_desc"},
{"struct", "sg_shader_uniform_desc"},
{"struct", "sg_shader_uniform_block_desc"},
{"struct", "sg_shader_image_desc"},
{"struct", "sg_shader_sampler_desc"},
{"struct", "sg_shader_image_sampler_pair_desc"},
{"struct", "sg_shader_stage_desc"},
{"struct", "sg_shader_desc"},

{"struct", "sg_vertex_buffer_layout_state"},
{"struct", "sg_vertex_attr_state"},
{"struct", "sg_vertex_layout_state"},
{"struct", "sg_stencil_face_state"},
{"struct", "sg_stencil_state"},
{"struct", "sg_depth_state"},
{"struct", "sg_blend_state"},
{"struct", "sg_color_target_state"},
{"struct", "sg_pipeline_desc"},
{"struct", "sg_attachment_desc"},
{"struct", "sg_attachments_desc"},
{"struct", "sg_trace_hooks"},

{"struct", "sg_slot_info"},
{"struct", "sg_buffer_info"},
{"struct", "sg_image_info"},
{"struct", "sg_sampler_info"},
{"struct", "sg_shader_info"},
{"struct", "sg_pipeline_info"},
{"struct", "sg_attachments_info"},

{"struct", "sg_commit_listener"},
{"struct", "sg_allocator"},
{"struct", "sg_environment_defaults"},
{"struct", "sg_metal_environment"},
{"struct", "sg_d3d11_environment"},
{"struct", "sg_wgpu_environment"},
{"struct", "sg_environment"},
{"struct", "sg_logger"},
{"struct", "sg_desc"},
}

local defstrings = {
  [[function def_external()
    ffi.cdef([[typedef enum sg_constants {
      SG_INVALID_ID = 0,
      SG_NUM_SHADER_STAGES = 2,
      SG_NUM_INFLIGHT_FRAMES = 2,
      SG_MAX_COLOR_ATTACHMENTS = 4,
      SG_MAX_VERTEX_BUFFERS = 8,
      SG_MAX_SHADERSTAGE_IMAGES = 12,
      SG_MAX_SHADERSTAGE_SAMPLERS = 8,
      SG_MAX_SHADERSTAGE_IMAGESAMPLERPAIRS = 12,
      SG_MAX_SHADERSTAGE_UBS = 4,
      SG_MAX_UB_MEMBERS = 16,
      SG_MAX_VERTEX_ATTRIBUTES = 16,      /* NOTE: actual max vertex attrs can be less on GLES2, see sg_limits! */
      SG_MAX_MIPMAPS = 16,
      SG_MAX_TEXTUREARRAY_LAYERS = 128
  } sg_constants;
]]}

local mkhd = assert(io.open("makeheaders", 'rb'), 'File not found')

if mkhd then
  os.execute("./makeheaders core/vector.c")
  os.execute("./makeheaders core/gfx.c")
  os.execute("./makeheaders core/main.c")
end

local gfx = assert(io.open("dep/sokol_gfx.h", 'rb'), 'File not found')
      gfx = gfx:read('*all')
for d, def in ipairs(defs) do
  local name = "typedef "..def[1].." "..def[2]
  local x = (string.find(gfx, name.." ") or string.find(gfx, name.."{"))
  x = x-1;
  local y = string.find(gfx, def[2]..";",x+name:len())+def[2]:len()
  str = gfx:sub(x,y)
  x = string.find(str, "#if")
  if x then 
    y = string.find(str, "#end",x)+6
    table.insert(defstrings,str:sub(1,x-1)..str:sub(y,-1))
  else
    table.insert(defstrings,str)
  end
end

local str = gfx:sub(gfx:find("// setup and misc functions"),gfx:find("// frame stats")-1)
str = str:gsub("SOKOL_GFX_API_DECL ","")
-- print(str)
table.insert(defstrings,str)


hmm = assert(io.open("dep/gb_math.h", 'rb'), 'File not found'):read('*all')
hmm = 
hmm:sub(hmm:find("typedef union gbVec2"),hmm:find("gbAabb3;")+8)..
hmm:sub(hmm:find("void gb_vec2_add"),hmm:find("enddef"))

hmm=hmm:gsub("GB_MATH_DEF ","")

local x = 0
while x do
  x = string.find(hmm, "#if")
  if x then 
    y = string.find(hmm, "#end",x)+6
    hmm = hmm:sub(1,x-1)..hmm:sub(y,-1)
  else
    break
  end
end

table.insert(defstrings,hmm)

gfx = assert(io.open("core/gfx.h", 'rb'), 'File not found'):read('*all')
table.insert(defstrings,gfx:sub(gfx:find("typedef"),gfx:find("#define INTERFACE")-1))

vector = assert(io.open("core/vector.h", 'rb'), 'File not found'):read('*all')
table.insert(defstrings,vector:sub(vector:find("typedef"),vector:find("#define INTERFACE")-1))

main = assert(io.open("core/main.h", 'rb'), 'File not found'):read('*all')
main = main:sub(main:find("sapp_desc")+43,main:find("#define INTERFACE")-1)
local x = main:find("typedef struct Thread"); y=main:find("};",x)+3;
main = main:sub(1,x-1)..main:sub(y,-1) 
main = main:gsub("images_t","//images_t")
table.insert(defstrings,main)

table.insert(defstrings,"\n]])\n  end\n")
defstr = table.concat( defstrings, "\n\n" )
end



--------------------------------------------------




local HEADER = 'unsigned char %s[] = {\n'
local FOOTER = '};\n'
local LENGTH = 'unsigned int %s_len = %s;\n'
function GetFilename(path)   
  local finding = true
  local i, j, n = 0,0,0
  while finding do 
    i, j = string.find(path, "/",j+1)
    if not i then 
      i, j = string.find(path, ".",n+1,true)
      return path:sub(n+1,i-1)
    end
    n = j
  end
end
-- Normalize filename
function xxdata(filename,data,name)
  local name = (name or filename):gsub(".png","")
  name = name:gsub('[%p%c%s]', '_')
  io.write(HEADER:format(name))
  for v = 1, #data do
    local b = string.format('0x%02x', data:byte(v))

    -- Indent block
    if v % 12 == 1 then
      b = '  ' .. b
    end

    -- Ignore comma for last byte
    if v < #data then
      b = b .. ', '
    end

    -- Add line break to line end
    if (v % 12 == 0) or (v == #data) then
      b = b .. '\n'
    end

    io.write(b)
  end

  io.write(FOOTER)
  io.write(LENGTH:format(name, #data))
end

function xxd(filename,name)
  -- Read file data
  local file = assert(io.open(filename, 'rb'), 'File not found')
  local data = file:read('*all')
  file:close()
  xxdata(filename,data,name)
end

define = [[
void include_images(images_t* images){ 
]]
pre_struct=[[
Image imgFromMem(void* ptr, size_t size);
typedef struct image_info_t { unsigned char* ptr; unsigned int len;} image_info_t;
typedef struct { char* key; unsigned char* ptr; unsigned int len  } image_hash_t;
]]
images_struct=[[
typedef struct images_t {
]]
image_list = "\n_internal_interface_image_list = { \n"
shader_structs = "\n function def_shader_structs() \nffi.cdef[[ \n"
shader_params = "\n_shader_param_list = { \n"
resource = io.open("core/resource.h","w+")
io.output(resource)
io.write("#include \"stb_ds.h\"\ntypedef struct Image Image;\n\n")
stage = 1
size_in,size_out = 0,0
code = "local source={} \n"

for f=#arg,1,-1 do 
  if arg[f]:find("file.png") or arg[f]:find("icon.png") then 
    table.remove(arg,f)
  end
end

for f,source in ipairs(arg) do 
  if source:sub(-3)=="png" then
    local nextone = (arg[f+1] and arg[f+1]:sub(-3)=="png")
    image_list = image_list.."  \""..GetFilename(source) 
              ..(nextone and "\",\n" or "\"\n}\n")
  end
end
local types = {"bool","int ","float","vec2","vec3","vec4","mat4"}
for f,source in ipairs(arg) do 
  if source:sub(-1)=="h" then
    shader_structs = shader_structs.."// ".. source .. "\n"
    local file = assert(io.open(source, 'rb'), 'File not found '..source)
    local text = file:read('*all')
    local nextone = (arg[f+1] and arg[f+1]:sub(-1)=="h")
    
    -- texture slots
    local texture_slots = ""
    local p,q = 1,1
    p,q = string.find(text,"SLOT_texture0 = 0;",p,true)
    while p do 
      p,q = string.find(text,"SLOT_",q,true),string.find(text,"=",q,true)
      if p>q then break end
      local name  = text:sub(p,q-2):gsub("SLOT_","")
      local index = text:sub(q+2,q+2)
      print("TEXTURE ","["..name.."]","["..index.."]")
      texture_slots = texture_slots.."\n    [\""..name.."\"] = "..index..","
    end

    -- shader param structs
    local p,q = 1,1
    while p do 
      p,q = string.find(text,"SOKOL_SHDC_ALIGN(16) ",p,true)
      if p then 
        p = string.find(text,"#pragma",p,true)
        local struct = text:sub(q,p-1)
        local _,s,t = 0,string.find(struct,"{",1)
        local shader_name = struct:sub(17,s-11)
        -- print(shader_name)
        shader_params = shader_params.."  "..shader_name.."={"
        shader_params = shader_params.."  "..texture_slots
        while s do 
          local first,last,m_type = 99999,99999
          for v,v_type in ipairs(types)do
            local i,j = string.find(struct,v_type,t,true)
            if i and i<first then 
              if v_type == "int " then 
                j=j-1
              end
              first,last,m_type = i,j,v_type:gsub("%s+", "")
            end
          end
          _,t = string.find(struct,";",last,true)
          if _ then 
            local name = struct:sub(last+2,t-1)
            local a,b = name:find("[",1,true)
            if a then name = name:sub(1,a-1) end
            -- print(m_type,name)
            shader_params = shader_params.."\n    [\""..name.."\"] = \""..m_type.."\","
            s = t
          else 
            break
          end
        end
        shader_params = shader_params..("\n  },\n")
        shader_structs = shader_structs..struct.."\n"
      end
    end
  end
end

shader_params = shader_params:sub(1,shader_params:len()-2)..("\n}\n")
shader_structs = shader_structs.."]] end"

print(image_list)
print(shader_structs)
print(shader_params)

for f,source in ipairs(arg) do 
  if source:sub(-3)=="png" then
    local name = GetFilename(source)
    images_struct=images_struct.. string.format(
      " image_info_t %s;\n",
      name
    )
  end
end

images_struct=images_struct.. [[
} images_t;
]]

local main_index
for f,source in ipairs(arg) do 
  if source:sub(-8)=="main.lua" then 
    main_index=f
  end
  if source:sub(-4)~=".lua" then
    arg[f-1],arg[main_index]=arg[main_index],arg[f-1]
    break
  end
end

for f,source in ipairs(arg) do 
  if source:sub(-3)=="ttf" then stage=2 end
  if source:sub(-3)=="png" then stage=3 end
  if source:sub(-1)=="h"   then stage=4 end
  
  if stage==1 then 
    print("source",source)
    local file = assert(io.open(source, 'rb'), 'File not found')
    if source:sub(-8)=="main.lua" then 
      code = code .. "\n return source"
      local comped = LibDeflate:CompressDeflate(code,{level = 5})
      -- print(code)
      print("comped",code:len(),comped:len(),comped:len()/code:len())
      xxdata("source_lua",comped)
      local text = file:read('*all')
      local defl = assert(io.open("dep/pack.lua", 'rb'), 'File not found')
            defl = defl:read('*all')
      local x = string.find(defl, "--SPLIT_FILE--")
      defl=defl:sub(0,x-1)
      -- print("defl:len()",defl:len(),print(defl))
      local main = 
       [[print("main.lua") if arg then args = arg; arg=nil end ]]
        ..defl
        ..image_list
        ..shader_structs
        .."\nfunction def_images_struct() \nffi.cdef[[\n"
        .."typedef struct image_info_t { unsigned char* ptr; unsigned int len;} image_info_t;\n"
        ..images_struct
        .."\nimages_t getInterfaceImages();"
        .."\n]]\n end\n"
        ..shader_params
        ..defstr
        ..text
        -- local test = io.open("test.lua","w+")
        -- test:write(main)
        -- test:close()
        -- print(main)
      xxdata("main_lua",main)
    else 
      -- print(source)
      code = code 
              .. string.format(
                    "source[\"%s\"]=[==[\n %s \n]==]\n",
                    source,file:read('*all')
                 ) 
    end
    file:close()
  end
  if stage==2 then 
    xxd(source,"fonts_"..GetFilename(source))
  end
  if stage==3 then 
    local name = GetFilename(source)
      

        xxd(source,source:gsub("res","images"))
        define=define.. string.format(
          "  images->%s = (image_info_t){images_%s, images_%s_len };\n",
          name,name,name,name,name
        )
        -- define=define.. string.format("image = (image_hash_t) {\"%s\",images_%s,images_%s_len};",name,name,name)
        -- define=define.. "shputs(image_hash,image);\n"
        -- define=define..[[printf("image_hash count: %i\n",shlen(image_hash));]]

  end
end

define=define.. string.format("  }")

io.write(pre_struct)
io.write(images_struct)
io.write(define)

