JFIF     "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777"H !1AQ"2aqB#R3b$Cr4Ss%Tt&c$!1AQ"a#2B ? }XuAo)8^ IƟ`vUp9jY0Ǧ w)E허2jU`SEKw5]kSno!]:?jc\غV7/9N+{t#8zd/޲3F/=ź3GNquV"/4:{z%ۣI'D@ %88^f}VV)S_2ed^Mx"͟?UC62Q%чmO͓ cq0rŖJ\Õ_Sݶ'|G.q޾D U]nP%EF>˲E"d&'f2s6H]4w IS˶4VbaQ+9]XtNx:M0JNxϙ⟟"{nr;|{%vo\z-wc,*|k}-m55o4W9ؓw߱Yzk .=/oϡȴ^9ҧʹamtQԬZ]4?egjrQ}+)MleE]MPEn!`IK2RUEwVIoͷcp;lśe7΄uN ;rПV8|e\׹9Y-V_G.)XԢOv<;_"ڜ]ߙEr݊'K{KuBJ}KI}24|"v)/ʻo5)6-Tjd7.C]Q&lU,Yk1P4~UKZs|$kX6+屷CUq+N(jlGrpG&UB3#k3\9qfg7O8Kim(AJOO~C#e`i0wĦij$cWh<dtQߺ"NOtG+ZǪ]b5%]v5$)u|qZ柡s-rۖu$MKڎCmN_V'/1u,21pvlc>қeNnֺ|bkl=lǷNOʣlz*]»vȎ[)j[fs[]:s#m6Qt6*Q+`};ßj[F_jcv`r#w}|k<ڞ/r53N8>Kh q_-_??@enſEܥ\D\YAEo+ ޟd}IcY7+t{=ɩ>}i\\JfxzVdSzᔢ]Q^CJի\iceitMM5hڦg')^ et#ۯ"ÿfF->4iؤ2ݷ6#p6^-R̫gETj^I.kӽUp~D9[:/>h> \gJ|ۿؘ>ml9jMK =+*2i=0RiͶۗV{"u]IH`9J_˹KƼK$X-|=ve/ bjxw.9i%NqVJcFYKcTtO,F;%67vYb8֝qq0tUt=DvawsS~~Edzr^F-v{c++ݔ\|9Iy #nOavOY=3690Tcrilwa\˓m$?箵S6U c(.~R7suMhqcMOnKoc*ȣȩEd'J ܜk*_q}%M/7c.|;trddbsdcJev85̤iW Ę 8C# .딖e$sk80^\J众2)Nm~|Idj_ O+6ǻ#(MIz4Qo:օY,:q]̌"lK}{F]ζ)h>ʶ ^ue78_G#rqv$wkk[Q c+վ+ĸZΝFB]VzoiJRke&Kgom_7Wef_7,osJɽE%lzBt>mRs)v8'P0ֲtrOg4p_2`GlhYڦDF/ӚKmtm'P2kqU765fJY:y؊.ox%8V_ִ̌ܞjpqwЮQ;iUcNoOoٸcY w*4soӵkqf$?-jy~0{>?DaL8XL/ɞo+'8 {ʸxգj#Dy)wk̘e۩+%}~;ڼ5xek|y-%ڱ-ʜe:EEScÚ5z|r'&I&яF*F7|[nRF =(4ۖ@. n7@xx:N^8Bg%u/ny6&dR{?8U_Q6Z߯-oh.NR]} qi6~H(j7*uF&l&o8ts]/P89:jW*$w׹Ӌ FxpsCJi.7N q4WU_}7*M#qWiصnk'4ݍl*t^ c<'d:~͗enFQRz9v~ddoTZ̚k7X(wUswO̙fոҁՕ[$IAI>WW~ĪEѢNoeutYߑ-Eixιpxq{FnyfRrjqU᫤]>wPU8)Y-7Wbq㛋w:7ܣ].j%K:y4] %9$I%pT(󨪙VqiYٓ4y~5S/XTDZM2lȪ; S~Kx:(Mn0';-{*qV&|W3S+\֔a{R{s=lYmN9Fn&o'}Vi( ?*qV5ѼCNsM饏zߴ$^O69@ ,$y|jE;gW/u|M?3+ZՕN86յw%|QO㏏S\E#ddsgl+Scl3~~CԕQľ?5_ z߿t11OĶ0>oB9E/SOSk+b&Yn>$툧eg) "!܉(1 uBoJ)/t/,:=7M+1ܺ#CmS^Nz 6[u&]+|Dfj:uZ5-Z^TjMtm>cȳ NdT_,M#Ex;pt۴ͮ#!N iKl!zPծ~$1SiO} HI&g Bf)b%Ko̧kumEnص;V?j>nltOMVۆl>.WueYaw2+qK,?uHiqqSM}~gu3xbcWSy/Xc{%sZ]uaUM;7:cb5G97'7þյW,;$ܛyVjl޻y7S;o6gf.Tг[7/i1Z^rE cUF'P1-?%u&q{fw~27ޡ ^w$?SwP[=R3Y73 4x(Kk&rLȫMKn:RjcI?3Al`vض[POĖSYujj6v+-[xҵ=~zNN>\ɲQ/uufo*e6l;31붏.>w6=7#7dFDc%ƶTbd;2/=?Asr! ~ZSS~I"9y]Hn,ĊJ7S}cK"amCg3yP=RQɤW}t;-{F+v+RɔڎB?º{SV묖kۏmK~%.Q;OfEf_Y/F-V-MdD)m.ZՍ8Y*h[g/6ydmCc[rdfʾ䖗gd$^֍^ʅѻL|<[݉\߯RiJUo';œN?B smS ܹkس,mRE^ѣlJ&.ċ԰YO:޼f\Z'HCѯU[ʩ1ff4S-٥YxTIGLiыr }L)edׂ*l|ٚuoxӿnWkTbbVm zT_'"x5Vިxo1ج^Fq6Sd3ws'/ڞ6m?}1OsRGݝ+,~ڬ%^p1ef5c25vq~﹉ă[r-eq] 8+/ESj}?mUE.xYK3"oƔ^Y9I]I ޑ" &*4.Jâ}ټQbXKJ񽼀ncg`+riܭ_'Bֽp%bX'7cB}WPm|zHָLJhj~E>i~Z$297|_hyΕ&s}ZϷ *j]:v.HK<SP8`Pƣ)r ,}8Wk[ArHgn=о7:J]TTP>OOj J_KyB\Ԥrm嬷ȫr{ݙ5R(FRЪ6q}KLmR'eޖz6[YތesYYL5Tr7s\^rؙV͸컬j5d?yk'b S }kra^ߚRH)[sg.fLM\u= vJQ]rVkZuoN}#G?yjO%|i2fKoӰღC P_Ϳ6Zr{e/m$i}9 G2')YG9KY>|1ӫ +v+i;h\Q@˿Lӭn˖ 7ck>Vr.D0)hC<˄4"0[eԬݭe+l2s3ss oX]1r]+VK vI;mZ')R6e5=/i@]H^Z۬՝EW.jƆf{8mXMV~_̝z^VR}T63}}k3+k3:j1Phlpi{欍BȽ}6w73GtUZv>4eUj$ xz$$D/߇ߟI"uk̜aƪ*ke/F:dһ_PE1ݡkp(5ʏ-ɮ{Yllԧg!ܝ g]i-umεŸxOê^=PR ##XeMy%2L~󜺶Hm ݙ2t_ƶz7'\Z4T<"AM-&xaC]a5.huQ۫$cMμ|h;.J.o߸sE-zU{d];|YLSMvSEneNKr1B[]NeonNߪ$4̘FPrkxޱ=0lr7Q%=$KQ;0r*XKdGۃ*]w-npᬶ\tt4>Dc[Ouo3/)-WҴ xs71eԤm*ٖ웗H''.Cnmy]݊Kra[9)Y#2U6d7tf.[R.GdE>#O_.+-K`{KonR_ÕM/)?:F,Xo1ƽRmz8C]lD %(x+d2Ah+\CCLJ!D65x\ȼv)\Nrp*[YُfL*PyVΚuWA K4hyYdwihNIy#ub?4NDϐ'4 :nFe(o%ve@@xl-k%QƭRP&kεMŪ-Ys2u ]T!}8*TQnZ}v =~mԧyDM&8K>2|Bnugܷ.wvCs̼5F^ubES7ݢM&4Ź-~mKx1((sr!M5uy\q)oy|a)ˣ,A?w"T휳2\F}PR-<2%`~4Z5\W"(USkGpT(~Qj>ɰ쏳ǓSKKx's]nEf'.iݙL>Moƹk7ݭ[.г6lk<;?)#E]xFU7'>vF%R;t:Җs}NSBWX=Y8ث}~G)S^^ƽwR[)/Fm-ڞTK~˓Z]U;RQ=M/"NԝP[-Y9t_8V+}P?Ue{M/O&WWKvc#r'KM'p[±vtpRC/W|7K2Rfm;ljm%Z]^T[6}6iTC }L[uxg7(Z}. SRI)jҞzȶ쳢oYRw$ŷ"J\ǭw{u'R taF{;3hHB\RP(*ZQ]y;;k٥nWbGKv-V?NDҞkd9@z LJ}Kc9C*?V-*[*۸-0.|󲝳ߗZK#%_OFGF$kC$[NNJ7Yn[k~Xzc+Sʲuhsw^^4+nElbƮKD,}YLV=i=|p|_=b5mȵ(~,em#Xƥ.sVoEaWXc.lY uG\m';'*\ӆ}|˯UfQBvo}/"zw + qvMrQ[[AdU2ٽCGgjؖS~Ev%9">$_2Sߚ%ѽ7jX(t#21r{̬F]b()?r[Rı)W[O/6]XL9 vuLh-Ȃ9"'7f!Փ䮿Bf}[lag֧]?Pc#D9EmfK7o*})+n!]qIo^FrNVNo!Eƃd#OP?%ۋ(mPu93ۣ{}2&$%cZ߯LҚY);U afԶd,*'6_?B:R~}^̬~mJ+vC}Ѩe"MY+mi :s쥸;iJeYvBddeK|#5/mzR]F2 JHUU )/S{Ic$=: W)>} @0#URsR=w"L{+ɞ)d|*qq2>[nƨDۋ-G[6½J|{Ѿ4MwyG-Σ Ze{ug>2|'zΤ2%xՑ*<Q̥T')uLkjn(zF-JOR}wn~FV5zq2m'^VS=7Y^RdfeO)>EpX붚w*r*w˿^kڴ{J;K۔sRŶU]p\zn@dx6[+yeH[_m_/I&mv|M5&&-G"v۴^{vg8Y(K_~h0e AxfrzڬkhS/Vy1ϯdW3'͹}{'V-:MW(V/ͷ*E7s\EmEW}bUr'k,P{9?B֫ #[uNrB,wo^{fdF(5tRf.2J-/:~ t0M"d_/c^32*q]yLl^2[ݥZc*vtm213r'tSuM-Խ#o/HF+2VEpmǦޟS?Rs+t:u G8n,Ԛf,hY8SX*rKf>+cpruɬ=DMrXgϸ:~ɲ ~]'5'kElw\=ڞAG&')G9R\_̝1K;nPg&T(ի[^Jҟ"qoӸ.W}3mF>'$<\U6-~?x?B~{^xkpv-vlߣe빹j\(ښsuu6lH(qoaYt?x8}Ie '@b%TݲygV.+O9/W4MsCMuFjYzG.{ds.k(>G~K?ni-=R r}r ?s̥%l5Ϛ9IN6~۩RĢWNʾE[|nb.HY—קWkr1ҺշMNDp)^¸R:w;u1 12]T/Uiʹd%2OC2K*r5S]g凫5 UQ.ȫ– /i91njFkQxuJ1rn%XDžy?s˗վuMGƋ/m^J*RsF))uF,'l{=|nFm9:N\%u#tnXE->e2Y0PũjUȨEŭ|'eʹ[o{Ցms%CGg/}t|snzrvm\g}cÊ94Pvg'L}ّg궮ԱߢO^f.W-sT]M˔ېе<^Н'KuNn_Vl8*Kж^ xsuW51-ᅱFzƉT-kY/9wzDޯ/XlW)gypǚjDɨ~{ݤHCim.[>rqE_Uرx/>|L64%aj;fxӱF(K֓J9՞ -K> I_5Enn´&=Oc%o̟IJZF$۲5I9Wݚ n.WTuѲӏ[4U/9.2zX5\j3ĎEsMq4%9.d[7јc9eNa+sjE';%s#ɤ`ףS=WI쫢.Mv:j/[3:rTF_zt:.z%udW%]xܮVz$Vŗ49[^y.խN~M&mx+wGR~_4KC[ʻ:v>03߶v9x-Mȧ$c:lrCWjeg%ֹ_Nh՝Qɏj^ϛr^.>WhlE5yֵ6\W^确]*гc&^NI[oCDn.ߑ!,m&M_/'Mn$s\r^8|uSZZ1|LV<(zq׮xmٚZƏ%.Ԁs^2𱸒O#&,s[mײ9kޖCoSq&俙qxP.N] 2UǎsM2iN.f r[mcQZmFُE{#[TbҔ*sfaSrn^8N<\_'MarJ6 EQғ|F[S'[~q~kmn[_x?B f5Q١X=g(~[Cx}GO ĺo'e)~dq(Ot`sN=~heu ::m'Cjj>~5V柙cyQD%uqEc{[l^U O]b~eŦۑ'W3&' 2V.^D%G S6\wYNO$. O+^ŵG~haEs^=1*bICzFF4O#,Wu3허ekB\I'tWMߩOG3iFz{rgeM9g r] i3gk&u1r/1kVgR-ɿuF .^;3;?3큦bN̂r4ovMkڞ}[:,IVG<};*-2",>K%bK2Ƨ[w!)ˤ;d?4%Ul2ږec4#ōIw^R_/TFX+*FM[F|a'ߚ2SIMeVGn ~&Y Ym(?ԛ],=|сG4yjk"Q^~ԗ^c,qqrg^-:Uc[E8>>k|nS..LBIc>3i|ZEZXAqm nuOm<; X~mrK=~ ƱrSN<U!F΋WS/|t?K)zd} ,C"ovx?bբs3mX3桭X֖˦kFddhg}$ggSo5jL*NdJis$ EQ\v=0HxzyW~FT_Ƶccg,&=_V(%kq+_÷O'[_[Uڽv F $Ξ9n5EN/4Yy/%*} .jΔ`V_6\VͲohzfOgޯzpj}y}v:34WH;+x7ӻu<ݦ"mJ/=>eoD֣c4kXW-[}٬6;t[Na_• _5i5˗sٴ]+e;Joj㼶ۙyLumo5&F)F\ {(sm_M>gzcr)KU̠Ħ=VDd'h;-aŤ9KٰqQܫަazMp4bk9 UX.ͮ]KeS5Uq[¹X0ɦ6]roFjʧ2׏6/C6eQE5KӰmsFnIz&`z팡-ٯ.ixyك?c2//z6M4W[]_"?Õ[? Vfvӳq]I5(d|MʝzcC*mN>B2gD+><e:Gh %UkW%zJ8k_ˠ=KFRfw{sŖ^q\/{v[Ω}gLjT[t_ޕg6G~rkkMcSRKբ54?SAûO1o%[>5/R~CioNdNʛćh>f6H8c/<1xd[ŦCEk.9"ej?w&O6^ژR[vrQ.z㎩f6:V8}hi2z~ s-w]+|I9s_C~>-S&9ZFVLf7-d'pՠplJ#mm؎s(?Ʋ?/A%_sXuGNnR}_dq>1ʍ|У3]NXYZʷ/&ܛ彖LS? 6]"_t5qP5Kq]^m91jW暹U6-5WU澦M0˵f2ӪǮ.P~? _nEJTcTei)ٳrۣ%x %gs}7l9'tb~dXst# r?}Weaq>=+to)7،E*vn\e_,\NFxcivz]tM˼?Oԝ2Zrλs-ĺEtonIIfm/9^[^EBUjOnr6vI& l]%0")2䒶-+R*zyX<> -X9GUo^xYQ8ιvixٔa\t)hv}ьոVU~tK,=_wLLa?TYIo]$`N6cbi?#7;MRt<.~Q-mob\\g5췍 ڌ_?8nfJN/Y͢n3?_sϩ{HiְPo'yS??_jߡWi5q? MWȲ)8a]lLˏ--b[TXlΫRy;o5뜾$HW.mm?շG[Ƀ seo5Q}Le%*،«~uU{R$t\^%!weX:G('6WupTS&~8=jo?2_PϖE[nf6Tٯ;GLW)NM[o*\j%.gb|䭹noOX:1R)UTj74˓]D_bʝkzNI.9|^G`KeQ{mOjX/sR7evdgi7qm}ތW&4=~|YY)?7Oj}xXkF×4c.l?i|b[5Ή5j-[Y\z<茲Z$Ff&o;gErǩݦ̪/q[&[/9uuzi;PS^_/?]=ΕqK~ӛ5'NM[m_Ϲc'[oӯE#g߂vvGNRo϶o5Ǩ[ɉtov2~i<7iSȜN(G5+/ٛMTܣukj鷣/$1˒!Mxr\ߤs1ZuMQȌ^]c$CXrj#N/˦Ķ9]Nzê5zi;W,v!ŧD6zğ7uR5^MW}>igl2U2nXo{}_w]&vte\Z3 MEEe/ 2s㗼S_bIղTI}|[Ye/c]*̪9u/DmyNxSDgi `Z?.RFj۪'~.[KVb޺o濡to?E#[.^y=q4F8ڎ/GX\.YW!Z.ѕtt:?gYYyU%Uw~ri>ȦKhg,5/=>V?TrN4aWO,oӕ7-SRi*"dܽpuaVQÞd-#J2Nr:#``ѧWR-F?I-T -cOT2pr?þזgE\Ij~L9%EMoџUؙt8_eYΧWjU}e9y9z/#TT-2dLt3H=ڼcKb'"uIٓ'[[߱F~\2]r%C]^VCLjm[cJNryf}ջ.[DEoRՒb'>fVy_c6[K4Na5>{ɳaw/Uj.Զ_K~?IeJ7OQx3IgFc*جɊǽ-o3Ӭp / ]7V*ENܜ[r/tOJΉw*ʨ*JFN^.WZeLgUwKi/M9y8dkOᛊHxGĶM*&#h/U|6D(uFyE5hYxiSEVm^D|,ۿCj;<*ouOkYpΔ2{x-L] !k2ا#IM'a7:M}M1Y儭Mnk[/;4Uwkkɫ%aɔoXVV$m;2Z4i9:>\Yů= ?[{t6,~!c`Un+dW.gKyIB]l+3kض(\MZ\}>k\C~閹l[ů]VNtƸr몮X+U>v'nv{y7s[г̭9Ctvt% GqT8=wa(6\Rd柮YWv^Fd^\+緉,+=-^S"k:NVu o[_TIѝ椯bF/G㿏dΙ?T}K-T)W>s?3M)V*,;P\,}B u{rDexڥVFfw}47׋w}]Դ 1dmk1V%/'T:Fǒ_TEe[l/l/ٯc{Ƀ[~`zj⾥r}Vܪ{M8Qv]$mU]8J2MngcxY?鑞.9HjxSy.fS(|]MgcK2$(jRQ3XO|<f:Jq4& fw|$N )A8ת99 mFNM*Dϒ NoIa9i9y?:D⻧߇\7ɧ]mu"-˥5/w̨_ 7DK['[2"(%xzT\*GT"+<,yX.lEJrfo?.4N;l>jmZߣ5FdB3\r,t,./S]Q{tm5lӕT~A [fv7Iہc: ΪN7I]2(|o$NLW"#~Dͭ=v-Mv{-lqn{I3xn'6.=DƟܖަ~deQV;k2Ei\[bӴ1_]OhZl朠&t3xkei+c\'ZԪ'hK梿X@cTԫ#emIz6e^i?8 NBc̆f+MׇdC]YSd%lώ8-c7eι/}_con/no\핍~[WNReXMo+اn ?#Ͷ-AUFN1V4!y,{1a$S﹑;Ǚr"__[o) xk}7EI/riwؙ7mR}`|yrEVdo/B# uٳiNQKQkᑑ^d@/=ˑɒ768fsuor9=7ףܹճpMr-$1uySOZN?đrqզ9F q=.!T?ػ bf{¯q=$^:!ES߿ Fu\OS,8e^UוS^hF4BQƺȪw-kF39@X06 Fv=Q^|ƞ5}2tnmG_|Λ(|%](-5>KȁN$=6lq).12 V6m$ׇlOcҫܸ K{;ľ>+Q?Rx-Keu uMy$i B}G*h$Q -W[-&a"[i\}~Ek$<~c{MffS eS.#\^lMiytު]9S{u4 {DFޅSź}R ]R$y;r/P̙3niXMt;&!rxw\ZFmQ"w\L{^۔K&/gr:m=2%5bwE"^e[\$ɟPi!U_rdS2d?=[!(I.rC QZEim%}|YmzZ_ά<ۡLQM|` ybPȏ}?]Eu[`kҫgFb~F}Q8NP>5lӳ^-K%Q}$sx7SvnfTƸ|Kzd'_ⰽח$4L Y?qy32t j2e ȜrJ{mبhۍUU'p#8y'ѝ=i+Tĩo7WYyČkL5؝M=%"Nt}eXW)N.~sv5pɮ sSQ[+-/}kVk'FEɩ9SE&T=&\緵 --tf.9Ѳ4_##_ɱTFV؞~YTddS&s=䟚Fb1._5}~gM'p#,U hs--XG wtԹTi7M:GYK5'^W?C>_Gq/S&d| k_gO ӊiJeHU G_ Êg#),}-:5>V1emq}t}q?meKU:BqJeiPɗ#\$sI} Z生ƫoo=V=pVcUg"%wEm叡vIdhrȔ~F]p58_.,O|'Ɇ^L!c6OWӷ{x9?Fp?ceOuT+Uɵݹ&gx9i퓃sxGIm}_3Īr#:ԣ?4בc[jö#B7KʌWNo)=+c }YvP{lv^r+5Vxx_:~=̌Q}CTy+Wh鸚f$101뢊F[#--Y\i@l)W8/E>8nlj/ktOľ,q*[sE[]:?ZeQvŔɺ|j(Wx,LW=:S?κq%81c)jJvODLiW,{96vr-2}-EH,}%3k#l5gl~x__W Sڎ 8YJQvA=QIWju6-X9$kWЩCI4UWd'&O/Cf=Pi/#+>n$KYst܅y4ʷD^~%~myj,s_4Q}΍Cή;SW:h=Ff{.B/inȇo=-T͸OY2}hlK}.m7-z?,f-/^b\QWs/_͔/3In[6M;l ygؼ!WUË_)D9YL4_>f}ϵ3hV5Oѣ(l8?L4蹥[-Э=7V{&ʢPʼ*3cMz>u4@[oM gKS[jy"Lھzɵfx)GE`ֿ.=kJ>/iˢ[j-qץQC B@o V(ʯG?Bܻ\I>=K-].(vOE.5׮=/Pf^&$caY9{3މ%YOxZ~6Z;;ԗ.NJzş/YϖĜ%ѿO^tY$ν4|e}2ɶU9A؜h˺LrIm%J.|I]kG|DzU k4'(T\9߱^!z -:mW^ <= <^2*;Seq(6ªsHf5ʸO{Ilr~G uJY^k5X_y;5'59O@ƣ̶>pnCOvNwX4oUUf]Џe%MV9Xm9]x'Q=82z)c/~1\~LSow>ﺍƻUql~Sqo羘sk}VjG71kYؽ]b4qnMӡ; w@̇IL㿗[43)]=v*)EH'a񖳋ҎTkxuXGK& ZIR(M8?:ixJp-dmckpu*%N^-7E3='ceE&';_J'Mw𶥏Y9+d9+>!e_Sn|VX -TZu]Ģ/6\ckr /ޗ/z[y.N:*k$ }Yǭ}GUm^-%dm;K_#ctBsg2:8rz-VE|T w.}w9NEPGnoCe8/&3qT}MJ̙Mۗ~哳,-WI_Bsh+~͛vN{ZdYKݲkr%+lo*re-ه?:vYqFfCsqMXRķ{yqgrx.oǓ\xdڗ_ZC9WomX|KmV_%UJܷr$drȳL~MoKyYLic Jq<1$UuٯTד374s<ĕ96춉r9 pGc9=p^:)ZJb&VӝXٽ 0/X& ۳*_ԙƏ.5J 6<$$6B0d_d?hqd>XCe- wO@pg:.>$.Ϣ~L޲|,{-ɪ2.u/Ds-[ُiVIWK5M#Fܭ3?x.)ۣ,wJ)Ȳڣ-#fbdq&Tͧ8Q,YqQ)/R­?\k˔[p_+ogzP[6r^o}_kT}JiJ;<ivEH8wI@MOPʊ\#+$%PDF-1.7 GIF89;
ANDA PELER
Server IP : 182.253.108.180  /  Your IP : 3.129.194.133
Web Server : Apache
System : Linux sma1wiradesa.sch.id 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
User : wijaya ( 1017)
PHP Version : 7.3.33-10+ubuntu18.04.1+deb.sury.org+1
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/lib/x86_64-linux-gnu/perl5/5.26/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /usr/lib/x86_64-linux-gnu/perl5/5.26/BerkeleyDB.pm
package BerkeleyDB;


#     Copyright (c) 1997-2015 Paul Marquess. All rights reserved.
#     This program is free software; you can redistribute it and/or
#     modify it under the same terms as Perl itself.
#

# The documentation for this module is at the bottom of this file,
# after the line __END__.

use 5.006;

use strict;
use Carp;
use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
		$use_XSLoader);

$VERSION = '0.55';

require Exporter;

BEGIN {
    $use_XSLoader = 1 ;
    { local $SIG{__DIE__} ; eval { require XSLoader } ; }
 
    if ($@) {
        $use_XSLoader = 0 ;
        require DynaLoader;
        @ISA = qw(DynaLoader);
    }
}

@ISA = qw(Exporter DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# NOTE -- Do not add to @EXPORT directly. It is written by mkconsts
@EXPORT = qw(
	DB2_AM_EXCL
	DB2_AM_INTEXCL
	DB2_AM_NOWAIT
	DB_AFTER
	DB_AGGRESSIVE
	DB_ALREADY_ABORTED
	DB_APPEND
	DB_APPLY_LOGREG
	DB_APP_INIT
	DB_ARCH_ABS
	DB_ARCH_DATA
	DB_ARCH_LOG
	DB_ARCH_REMOVE
	DB_ASSOC_CREATE
	DB_ASSOC_IMMUTABLE_KEY
	DB_AUTO_COMMIT
	DB_BACKUP_CLEAN
	DB_BACKUP_FILES
	DB_BACKUP_NO_LOGS
	DB_BACKUP_READ_COUNT
	DB_BACKUP_READ_SLEEP
	DB_BACKUP_SINGLE_DIR
	DB_BACKUP_SIZE
	DB_BACKUP_UPDATE
	DB_BACKUP_WRITE_DIRECT
	DB_BEFORE
	DB_BOOTSTRAP_HELPER
	DB_BTREE
	DB_BTREEMAGIC
	DB_BTREEOLDVER
	DB_BTREEVERSION
	DB_BUFFER_SMALL
	DB_CACHED_COUNTS
	DB_CDB_ALLDB
	DB_CHECKPOINT
	DB_CHKSUM
	DB_CHKSUM_FAIL
	DB_CHKSUM_SHA1
	DB_CKP_INTERNAL
	DB_CLIENT
	DB_CL_WRITER
	DB_COMMIT
	DB_COMPACT_FLAGS
	DB_CONSUME
	DB_CONSUME_WAIT
	DB_CREATE
	DB_CURLSN
	DB_CURRENT
	DB_CURSOR_BULK
	DB_CURSOR_TRANSIENT
	DB_CXX_NO_EXCEPTIONS
	DB_DATABASE_LOCK
	DB_DATABASE_LOCKING
	DB_DEGREE_2
	DB_DELETED
	DB_DELIMITER
	DB_DIRECT
	DB_DIRECT_DB
	DB_DIRECT_LOG
	DB_DIRTY_READ
	DB_DONOTINDEX
	DB_DSYNC_DB
	DB_DSYNC_LOG
	DB_DUP
	DB_DUPCURSOR
	DB_DUPSORT
	DB_DURABLE_UNKNOWN
	DB_EID_BROADCAST
	DB_EID_INVALID
	DB_EID_MASTER
	DB_ENCRYPT
	DB_ENCRYPT_AES
	DB_ENV_APPINIT
	DB_ENV_AUTO_COMMIT
	DB_ENV_CDB
	DB_ENV_CDB_ALLDB
	DB_ENV_CREATE
	DB_ENV_DATABASE_LOCKING
	DB_ENV_DBLOCAL
	DB_ENV_DIRECT_DB
	DB_ENV_DIRECT_LOG
	DB_ENV_DSYNC_DB
	DB_ENV_DSYNC_LOG
	DB_ENV_FAILCHK
	DB_ENV_FATAL
	DB_ENV_HOTBACKUP
	DB_ENV_LOCKDOWN
	DB_ENV_LOCKING
	DB_ENV_LOGGING
	DB_ENV_LOG_AUTOREMOVE
	DB_ENV_LOG_INMEMORY
	DB_ENV_MULTIVERSION
	DB_ENV_NOFLUSH
	DB_ENV_NOLOCKING
	DB_ENV_NOMMAP
	DB_ENV_NOPANIC
	DB_ENV_NO_OUTPUT_SET
	DB_ENV_OPEN_CALLED
	DB_ENV_OVERWRITE
	DB_ENV_PRIVATE
	DB_ENV_RECOVER_FATAL
	DB_ENV_REF_COUNTED
	DB_ENV_REGION_INIT
	DB_ENV_REP_CLIENT
	DB_ENV_REP_LOGSONLY
	DB_ENV_REP_MASTER
	DB_ENV_RPCCLIENT
	DB_ENV_RPCCLIENT_GIVEN
	DB_ENV_STANDALONE
	DB_ENV_SYSTEM_MEM
	DB_ENV_THREAD
	DB_ENV_TIME_NOTGRANTED
	DB_ENV_TXN
	DB_ENV_TXN_NOSYNC
	DB_ENV_TXN_NOT_DURABLE
	DB_ENV_TXN_NOWAIT
	DB_ENV_TXN_SNAPSHOT
	DB_ENV_TXN_WRITE_NOSYNC
	DB_ENV_USER_ALLOC
	DB_ENV_YIELDCPU
	DB_EVENT_FAILCHK_PANIC
	DB_EVENT_MUTEX_DIED
	DB_EVENT_NOT_HANDLED
	DB_EVENT_NO_SUCH_EVENT
	DB_EVENT_PANIC
	DB_EVENT_REG_ALIVE
	DB_EVENT_REG_PANIC
	DB_EVENT_REP_AUTOTAKEOVER_FAILED
	DB_EVENT_REP_CLIENT
	DB_EVENT_REP_CONNECT_BROKEN
	DB_EVENT_REP_CONNECT_ESTD
	DB_EVENT_REP_CONNECT_TRY_FAILED
	DB_EVENT_REP_DUPMASTER
	DB_EVENT_REP_ELECTED
	DB_EVENT_REP_ELECTION_FAILED
	DB_EVENT_REP_INIT_DONE
	DB_EVENT_REP_INQUEUE_FULL
	DB_EVENT_REP_JOIN_FAILURE
	DB_EVENT_REP_LOCAL_SITE_REMOVED
	DB_EVENT_REP_MASTER
	DB_EVENT_REP_MASTER_FAILURE
	DB_EVENT_REP_NEWMASTER
	DB_EVENT_REP_PERM_FAILED
	DB_EVENT_REP_SITE_ADDED
	DB_EVENT_REP_SITE_REMOVED
	DB_EVENT_REP_STARTUPDONE
	DB_EVENT_REP_WOULD_ROLLBACK
	DB_EVENT_WRITE_FAILED
	DB_EXCL
	DB_EXIT_FAILCHK
	DB_EXIT_FILE_EXISTS
	DB_EXTENT
	DB_FAILCHK
	DB_FAILCHK_ISALIVE
	DB_FAILURE_SYMPTOM_SIZE
	DB_FAST_STAT
	DB_FCNTL_LOCKING
	DB_FILEOPEN
	DB_FILE_ID_LEN
	DB_FIRST
	DB_FIXEDLEN
	DB_FLUSH
	DB_FORCE
	DB_FORCESYNC
	DB_FOREIGN_ABORT
	DB_FOREIGN_CASCADE
	DB_FOREIGN_CONFLICT
	DB_FOREIGN_NULLIFY
	DB_FREELIST_ONLY
	DB_FREE_SPACE
	DB_GETREC
	DB_GET_BOTH
	DB_GET_BOTHC
	DB_GET_BOTH_LTE
	DB_GET_BOTH_RANGE
	DB_GET_RECNO
	DB_GID_SIZE
	DB_GROUP_CREATOR
	DB_HANDLE_LOCK
	DB_HASH
	DB_HASHMAGIC
	DB_HASHOLDVER
	DB_HASHVERSION
	DB_HEAP
	DB_HEAPMAGIC
	DB_HEAPOLDVER
	DB_HEAPVERSION
	DB_HEAP_FULL
	DB_HEAP_RID_SZ
	DB_HOTBACKUP_IN_PROGRESS
	DB_IGNORE_LEASE
	DB_IMMUTABLE_KEY
	DB_INCOMPLETE
	DB_INIT_CDB
	DB_INIT_LOCK
	DB_INIT_LOG
	DB_INIT_MPOOL
	DB_INIT_MUTEX
	DB_INIT_REP
	DB_INIT_TXN
	DB_INORDER
	DB_INTERNAL_BLOB_DB
	DB_INTERNAL_DB
	DB_INTERNAL_PERSISTENT_DB
	DB_INTERNAL_TEMPORARY_DB
	DB_JAVA_CALLBACK
	DB_JOINENV
	DB_JOIN_ITEM
	DB_JOIN_NOSORT
	DB_KEYEMPTY
	DB_KEYEXIST
	DB_KEYFIRST
	DB_KEYLAST
	DB_LAST
	DB_LEGACY
	DB_LOCAL_SITE
	DB_LOCKDOWN
	DB_LOCKMAGIC
	DB_LOCKVERSION
	DB_LOCK_ABORT
	DB_LOCK_CHECK
	DB_LOCK_CONFLICT
	DB_LOCK_DEADLOCK
	DB_LOCK_DEFAULT
	DB_LOCK_DUMP
	DB_LOCK_EXPIRE
	DB_LOCK_FREE_LOCKER
	DB_LOCK_GET
	DB_LOCK_GET_TIMEOUT
	DB_LOCK_IGNORE_REC
	DB_LOCK_INHERIT
	DB_LOCK_MAXLOCKS
	DB_LOCK_MAXWRITE
	DB_LOCK_MINLOCKS
	DB_LOCK_MINWRITE
	DB_LOCK_NORUN
	DB_LOCK_NOTEXIST
	DB_LOCK_NOTGRANTED
	DB_LOCK_NOTHELD
	DB_LOCK_NOWAIT
	DB_LOCK_OLDEST
	DB_LOCK_PUT
	DB_LOCK_PUT_ALL
	DB_LOCK_PUT_OBJ
	DB_LOCK_PUT_READ
	DB_LOCK_RANDOM
	DB_LOCK_RECORD
	DB_LOCK_REMOVE
	DB_LOCK_RIW_N
	DB_LOCK_RW_N
	DB_LOCK_SET_TIMEOUT
	DB_LOCK_SWITCH
	DB_LOCK_TIMEOUT
	DB_LOCK_TRADE
	DB_LOCK_UPGRADE
	DB_LOCK_UPGRADE_WRITE
	DB_LOCK_YOUNGEST
	DB_LOGCHKSUM
	DB_LOGC_BUF_SIZE
	DB_LOGFILEID_INVALID
	DB_LOGMAGIC
	DB_LOGOLDVER
	DB_LOGVERSION
	DB_LOGVERSION_LATCHING
	DB_LOG_AUTOREMOVE
	DB_LOG_AUTO_REMOVE
	DB_LOG_BLOB
	DB_LOG_BUFFER_FULL
	DB_LOG_CHKPNT
	DB_LOG_COMMIT
	DB_LOG_DIRECT
	DB_LOG_DISK
	DB_LOG_DSYNC
	DB_LOG_INMEMORY
	DB_LOG_IN_MEMORY
	DB_LOG_LOCKED
	DB_LOG_NOCOPY
	DB_LOG_NOSYNC
	DB_LOG_NOT_DURABLE
	DB_LOG_NO_DATA
	DB_LOG_PERM
	DB_LOG_RESEND
	DB_LOG_SILENT_ERR
	DB_LOG_VERIFY_BAD
	DB_LOG_VERIFY_CAF
	DB_LOG_VERIFY_DBFILE
	DB_LOG_VERIFY_ERR
	DB_LOG_VERIFY_FORWARD
	DB_LOG_VERIFY_INTERR
	DB_LOG_VERIFY_PARTIAL
	DB_LOG_VERIFY_VERBOSE
	DB_LOG_VERIFY_WARNING
	DB_LOG_WRNOSYNC
	DB_LOG_ZERO
	DB_MAX_PAGES
	DB_MAX_RECORDS
	DB_MEM_LOCK
	DB_MEM_LOCKER
	DB_MEM_LOCKOBJECT
	DB_MEM_LOGID
	DB_MEM_THREAD
	DB_MEM_TRANSACTION
	DB_MPOOL_CLEAN
	DB_MPOOL_CREATE
	DB_MPOOL_DIRTY
	DB_MPOOL_DISCARD
	DB_MPOOL_EDIT
	DB_MPOOL_EXTENT
	DB_MPOOL_FREE
	DB_MPOOL_LAST
	DB_MPOOL_NEW
	DB_MPOOL_NEW_GROUP
	DB_MPOOL_NOFILE
	DB_MPOOL_NOLOCK
	DB_MPOOL_PRIVATE
	DB_MPOOL_TRY
	DB_MPOOL_UNLINK
	DB_MULTIPLE
	DB_MULTIPLE_KEY
	DB_MULTIVERSION
	DB_MUTEXDEBUG
	DB_MUTEXLOCKS
	DB_MUTEX_ALLOCATED
	DB_MUTEX_DESCRIBE_STRLEN
	DB_MUTEX_LOCKED
	DB_MUTEX_LOGICAL_LOCK
	DB_MUTEX_OWNER_DEAD
	DB_MUTEX_PROCESS_ONLY
	DB_MUTEX_SELF_BLOCK
	DB_MUTEX_SHARED
	DB_MUTEX_THREAD
	DB_NEEDSPLIT
	DB_NEXT
	DB_NEXT_DUP
	DB_NEXT_NODUP
	DB_NOCOPY
	DB_NODUPDATA
	DB_NOERROR
	DB_NOFLUSH
	DB_NOLOCKING
	DB_NOMMAP
	DB_NOORDERCHK
	DB_NOOVERWRITE
	DB_NOPANIC
	DB_NORECURSE
	DB_NOSERVER
	DB_NOSERVER_HOME
	DB_NOSERVER_ID
	DB_NOSYNC
	DB_NOTFOUND
	DB_NO_AUTO_COMMIT
	DB_NO_CHECKPOINT
	DB_ODDFILESIZE
	DB_OK_BTREE
	DB_OK_HASH
	DB_OK_HEAP
	DB_OK_QUEUE
	DB_OK_RECNO
	DB_OLD_VERSION
	DB_OPEN_CALLED
	DB_OPFLAGS_MASK
	DB_ORDERCHKONLY
	DB_OVERWRITE
	DB_OVERWRITE_DUP
	DB_PAD
	DB_PAGEYIELD
	DB_PAGE_LOCK
	DB_PAGE_NOTFOUND
	DB_PANIC_ENVIRONMENT
	DB_PERMANENT
	DB_POSITION
	DB_POSITIONI
	DB_PREV
	DB_PREV_DUP
	DB_PREV_NODUP
	DB_PRINTABLE
	DB_PRIORITY_DEFAULT
	DB_PRIORITY_HIGH
	DB_PRIORITY_LOW
	DB_PRIORITY_UNCHANGED
	DB_PRIORITY_VERY_HIGH
	DB_PRIORITY_VERY_LOW
	DB_PRIVATE
	DB_PR_HEADERS
	DB_PR_PAGE
	DB_PR_RECOVERYTEST
	DB_QAMMAGIC
	DB_QAMOLDVER
	DB_QAMVERSION
	DB_QUEUE
	DB_RDONLY
	DB_RDWRMASTER
	DB_READ_COMMITTED
	DB_READ_UNCOMMITTED
	DB_RECNO
	DB_RECNUM
	DB_RECORDCOUNT
	DB_RECORD_LOCK
	DB_RECOVER
	DB_RECOVER_FATAL
	DB_REGION_ANON
	DB_REGION_INIT
	DB_REGION_MAGIC
	DB_REGION_NAME
	DB_REGISTER
	DB_REGISTERED
	DB_RENAMEMAGIC
	DB_RENUMBER
	DB_REPFLAGS_MASK
	DB_REPMGR_ACKS_ALL
	DB_REPMGR_ACKS_ALL_AVAILABLE
	DB_REPMGR_ACKS_ALL_PEERS
	DB_REPMGR_ACKS_NONE
	DB_REPMGR_ACKS_ONE
	DB_REPMGR_ACKS_ONE_PEER
	DB_REPMGR_ACKS_QUORUM
	DB_REPMGR_CONF_2SITE_STRICT
	DB_REPMGR_CONF_ELECTIONS
	DB_REPMGR_CONF_PREFMAS_CLIENT
	DB_REPMGR_CONF_PREFMAS_MASTER
	DB_REPMGR_CONNECTED
	DB_REPMGR_DISCONNECTED
	DB_REPMGR_ISPEER
	DB_REPMGR_ISVIEW
	DB_REPMGR_NEED_RESPONSE
	DB_REPMGR_PEER
	DB_REP_ACK_TIMEOUT
	DB_REP_ANYWHERE
	DB_REP_BULKOVF
	DB_REP_CHECKPOINT_DELAY
	DB_REP_CLIENT
	DB_REP_CONF_AUTOINIT
	DB_REP_CONF_AUTOROLLBACK
	DB_REP_CONF_BULK
	DB_REP_CONF_DELAYCLIENT
	DB_REP_CONF_ELECT_LOGLENGTH
	DB_REP_CONF_INMEM
	DB_REP_CONF_LEASE
	DB_REP_CONF_NOAUTOINIT
	DB_REP_CONF_NOWAIT
	DB_REP_CONNECTION_RETRY
	DB_REP_CREATE
	DB_REP_DEFAULT_PRIORITY
	DB_REP_DUPMASTER
	DB_REP_EGENCHG
	DB_REP_ELECTION
	DB_REP_ELECTION_RETRY
	DB_REP_ELECTION_TIMEOUT
	DB_REP_FULL_ELECTION
	DB_REP_FULL_ELECTION_TIMEOUT
	DB_REP_HANDLE_DEAD
	DB_REP_HEARTBEAT_MONITOR
	DB_REP_HEARTBEAT_SEND
	DB_REP_HOLDELECTION
	DB_REP_IGNORE
	DB_REP_ISPERM
	DB_REP_JOIN_FAILURE
	DB_REP_LEASE_EXPIRED
	DB_REP_LEASE_TIMEOUT
	DB_REP_LOCKOUT
	DB_REP_LOGREADY
	DB_REP_LOGSONLY
	DB_REP_MASTER
	DB_REP_NEWMASTER
	DB_REP_NEWSITE
	DB_REP_NOBUFFER
	DB_REP_NOTPERM
	DB_REP_OUTDATED
	DB_REP_PAGEDONE
	DB_REP_PAGELOCKED
	DB_REP_PERMANENT
	DB_REP_REREQUEST
	DB_REP_STARTUPDONE
	DB_REP_UNAVAIL
	DB_REP_WOULDROLLBACK
	DB_REVSPLITOFF
	DB_RMW
	DB_RPCCLIENT
	DB_RPC_SERVERPROG
	DB_RPC_SERVERVERS
	DB_RUNRECOVERY
	DB_SALVAGE
	DB_SA_SKIPFIRSTKEY
	DB_SA_UNKNOWNKEY
	DB_SECONDARY_BAD
	DB_SEQUENCE_OLDVER
	DB_SEQUENCE_VERSION
	DB_SEQUENTIAL
	DB_SEQ_DEC
	DB_SEQ_INC
	DB_SEQ_RANGE_SET
	DB_SEQ_WRAP
	DB_SEQ_WRAPPED
	DB_SET
	DB_SET_LOCK_TIMEOUT
	DB_SET_LTE
	DB_SET_MUTEX_FAILCHK_TIMEOUT
	DB_SET_RANGE
	DB_SET_RECNO
	DB_SET_REG_TIMEOUT
	DB_SET_TXN_NOW
	DB_SET_TXN_TIMEOUT
	DB_SHALLOW_DUP
	DB_SNAPSHOT
	DB_SPARE_FLAG
	DB_STAT_ALL
	DB_STAT_ALLOC
	DB_STAT_CLEAR
	DB_STAT_LOCK_CONF
	DB_STAT_LOCK_LOCKERS
	DB_STAT_LOCK_OBJECTS
	DB_STAT_LOCK_PARAMS
	DB_STAT_MEMP_HASH
	DB_STAT_MEMP_NOERROR
	DB_STAT_NOERROR
	DB_STAT_SUBSYSTEM
	DB_STAT_SUMMARY
	DB_STREAM_READ
	DB_STREAM_SYNC_WRITE
	DB_STREAM_WRITE
	DB_ST_DUPOK
	DB_ST_DUPSET
	DB_ST_DUPSORT
	DB_ST_IS_RECNO
	DB_ST_OVFL_LEAF
	DB_ST_RECNUM
	DB_ST_RELEN
	DB_ST_TOPLEVEL
	DB_SURPRISE_KID
	DB_SWAPBYTES
	DB_SYSTEM_MEM
	DB_TEMPORARY
	DB_TEST_ELECTINIT
	DB_TEST_ELECTSEND
	DB_TEST_ELECTVOTE1
	DB_TEST_ELECTVOTE2
	DB_TEST_ELECTWAIT1
	DB_TEST_ELECTWAIT2
	DB_TEST_POSTDESTROY
	DB_TEST_POSTLOG
	DB_TEST_POSTLOGMETA
	DB_TEST_POSTOPEN
	DB_TEST_POSTRENAME
	DB_TEST_POSTSYNC
	DB_TEST_PREDESTROY
	DB_TEST_PREOPEN
	DB_TEST_PRERENAME
	DB_TEST_RECYCLE
	DB_TEST_SUBDB_LOCKS
	DB_THREAD
	DB_THREADID_STRLEN
	DB_TIMEOUT
	DB_TIME_NOTGRANTED
	DB_TRUNCATE
	DB_TXNMAGIC
	DB_TXNVERSION
	DB_TXN_ABORT
	DB_TXN_APPLY
	DB_TXN_BACKWARD_ROLL
	DB_TXN_BULK
	DB_TXN_CKP
	DB_TXN_FAMILY
	DB_TXN_FORWARD_ROLL
	DB_TXN_LOCK
	DB_TXN_LOCK_2PL
	DB_TXN_LOCK_MASK
	DB_TXN_LOCK_OPTIMIST
	DB_TXN_LOCK_OPTIMISTIC
	DB_TXN_LOG_MASK
	DB_TXN_LOG_REDO
	DB_TXN_LOG_UNDO
	DB_TXN_LOG_UNDOREDO
	DB_TXN_LOG_VERIFY
	DB_TXN_NOSYNC
	DB_TXN_NOT_DURABLE
	DB_TXN_NOWAIT
	DB_TXN_OPENFILES
	DB_TXN_POPENFILES
	DB_TXN_PRINT
	DB_TXN_REDO
	DB_TXN_SNAPSHOT
	DB_TXN_SYNC
	DB_TXN_TOKEN_SIZE
	DB_TXN_UNDO
	DB_TXN_WAIT
	DB_TXN_WRITE_NOSYNC
	DB_UNKNOWN
	DB_UNREF
	DB_UPDATE_SECONDARY
	DB_UPGRADE
	DB_USERCOPY_GETDATA
	DB_USERCOPY_SETDATA
	DB_USE_ENVIRON
	DB_USE_ENVIRON_ROOT
	DB_VERB_BACKUP
	DB_VERB_CHKPOINT
	DB_VERB_DEADLOCK
	DB_VERB_FILEOPS
	DB_VERB_FILEOPS_ALL
	DB_VERB_MVCC
	DB_VERB_RECOVERY
	DB_VERB_REGISTER
	DB_VERB_REPLICATION
	DB_VERB_REPMGR_CONNFAIL
	DB_VERB_REPMGR_MISC
	DB_VERB_REP_ELECT
	DB_VERB_REP_LEASE
	DB_VERB_REP_MISC
	DB_VERB_REP_MSGS
	DB_VERB_REP_SYNC
	DB_VERB_REP_SYSTEM
	DB_VERB_REP_TEST
	DB_VERB_WAITSFOR
	DB_VERIFY
	DB_VERIFY_BAD
	DB_VERIFY_FATAL
	DB_VERIFY_PARTITION
	DB_VERSION_FAMILY
	DB_VERSION_FULL_STRING
	DB_VERSION_MAJOR
	DB_VERSION_MINOR
	DB_VERSION_MISMATCH
	DB_VERSION_PATCH
	DB_VERSION_RELEASE
	DB_VERSION_STRING
	DB_VRFY_FLAGMASK
	DB_WRITECURSOR
	DB_WRITELOCK
	DB_WRITEOPEN
	DB_WRNOSYNC
	DB_XA_CREATE
	DB_XIDDATASIZE
	DB_YIELDCPU
	DB_debug_FLAG
	DB_user_BEGIN
	LOGREC_ARG
	LOGREC_DATA
	LOGREC_DB
	LOGREC_DBOP
	LOGREC_DBT
	LOGREC_Done
	LOGREC_HDR
	LOGREC_LOCKS
	LOGREC_LONGARG
	LOGREC_OP
	LOGREC_PGDBT
	LOGREC_PGDDBT
	LOGREC_PGLIST
	LOGREC_POINTER
	LOGREC_TIME
	);

sub AUTOLOAD {
    my($constname);
    ($constname = $AUTOLOAD) =~ s/.*:://;
    my ($error, $val) = constant($constname);
    Carp::croak $error if $error;
    no strict 'refs';
    *{$AUTOLOAD} = sub { $val };
    goto &{$AUTOLOAD};
}         

#bootstrap BerkeleyDB $VERSION;
if ($use_XSLoader)
  { XSLoader::load("BerkeleyDB", $VERSION)}
else
  { bootstrap BerkeleyDB $VERSION }  

# Preloaded methods go here.


sub ParseParameters($@)
{
    my ($default, @rest) = @_ ;
    my (%got) = %$default ;
    my (@Bad) ;
    my ($key, $value) ;
    my $sub = (caller(1))[3] ;
    my %options = () ;
    local ($Carp::CarpLevel) = 1 ;

    # allow the options to be passed as a hash reference or
    # as the complete hash.
    if (@rest == 1) {

        croak "$sub: parameter is not a reference to a hash"
            if ref $rest[0] ne "HASH" ;

        %options = %{ $rest[0] } ;
    }
    elsif (@rest >= 2 && @rest % 2 == 0) {
        %options = @rest ;
    }
    elsif (@rest > 0) {
	    croak "$sub: malformed option list";
    }

    while (($key, $value) = each %options)
    {
	$key =~ s/^-// ;

        if (exists $default->{$key})
          { $got{$key} = $value }
        else
	  { push (@Bad, $key) }
    }
    
    if (@Bad) {
        my ($bad) = join(", ", @Bad) ;
        croak "unknown key value(s) $bad" ;
    }

    return \%got ;
}

sub parseEncrypt
{
    my $got = shift ;


    if (defined $got->{Encrypt}) {
    	croak("Encrypt parameter must be a hash reference")
            if !ref $got->{Encrypt} || ref $got->{Encrypt} ne 'HASH' ;

	my %config = %{ $got->{Encrypt} } ;

        my $p = BerkeleyDB::ParseParameters({
					Password	=> undef,
					Flags		=> undef,
				}, %config);

        croak("Must specify Password and Flags with Encrypt parameter")
	    if ! (defined $p->{Password} && defined $p->{Flags});

        $got->{"Enc_Passwd"} = $p->{Password};
        $got->{"Enc_Flags"} = $p->{Flags};
    }
}

use UNIVERSAL ;

sub env_remove
{
    # Usage:
    #
    #	$env = BerkeleyDB::env_remove
    #			[ -Home		=> $path, ]
    #			[ -Config	=> { name => value, name => value }
    #			[ -Flags	=> DB_INIT_LOCK| ]
    #			;

    my $got = BerkeleyDB::ParseParameters({
					Home		=> undef,
					Flags     	=> 0,
					Config		=> undef,
					}, @_) ;

    if (defined $got->{Config}) {
    	croak("Config parameter must be a hash reference")
            if ! ref $got->{Config} eq 'HASH' ;

        @BerkeleyDB::a = () ;
	my $k = "" ; my $v = "" ;
	while (($k, $v) = each %{$got->{Config}}) {
	    push @BerkeleyDB::a, "$k\t$v" ;
	}

        $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
	    if @BerkeleyDB::a ;
    }

    return _env_remove($got) ;
}

sub db_remove
{
    my $got = BerkeleyDB::ParseParameters(
		      {
			Filename 	=> undef,
			Subname		=> undef,
			Flags		=> 0,
			Env		=> undef,
			Txn		=> undef,
		      }, @_) ;

    croak("Must specify a filename")
	if ! defined $got->{Filename} ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    return _db_remove($got);
}

sub db_rename
{
    my $got = BerkeleyDB::ParseParameters(
		      {
			Filename 	=> undef,
			Subname		=> undef,
			Newname		=> undef,
			Flags		=> 0,
			Env		=> undef,
			Txn		=> undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Must specify a filename")
	if ! defined $got->{Filename} ;

    #croak("Must specify a Subname")
    #if ! defined $got->{Subname} ;

    croak("Must specify a Newname")
	if ! defined $got->{Newname} ;

    return _db_rename($got);
}

sub db_verify
{
    my $got = BerkeleyDB::ParseParameters(
		      {
			Filename 	=> undef,
			Subname		=> undef,
			Outfile		=> undef,
			Flags		=> 0,
			Env		=> undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Must specify a filename")
	if ! defined $got->{Filename} ;

    return _db_verify($got);
}

package BerkeleyDB::Env ;

use UNIVERSAL ;
use Carp ;
use IO::File;
use vars qw( %valid_config_keys ) ;

sub isaFilehandle
{
    my $fh = shift ;

    return ((UNIVERSAL::isa($fh,'GLOB') or UNIVERSAL::isa(\$fh,'GLOB')) and defined fileno($fh) )

}

%valid_config_keys = map { $_, 1 } qw( DB_DATA_DIR DB_LOG_DIR DB_TEMP_DIR
DB_TMP_DIR ) ;

sub new
{
    # Usage:
    #
    #	$env = new BerkeleyDB::Env
    #			[ -Home		=> $path, ]
    #			[ -Mode		=> mode, ]
    #			[ -Config	=> { name => value, name => value }
    #			[ -ErrFile   	=> filename, ]
    #			[ -ErrPrefix 	=> "string", ]
    #			[ -Flags	=> DB_INIT_LOCK| ]
    #			[ -Set_Flags	=> $flags,]
    #			[ -Cachesize	=> number ]
    #			[ -LockDetect	=>  ]
    #			[ -Verbose	=> boolean ]
    #			[ -Encrypt	=> { Password => string, Flags => value}
    #
    #			;

    my $pkg = shift ;
    my $got = BerkeleyDB::ParseParameters({
					Home		=> undef,
					Server		=> undef,
					Mode		=> 0666,
					ErrFile  	=> undef,
					MsgFile  	=> undef,
					ErrPrefix 	=> undef,
					Flags     	=> 0,
					SetFlags     	=> 0,
					Cachesize     	=> 0,
					LockDetect     	=> 0,
					TxMax     	=> 0,
					LogConfig     	=> 0,
					MaxLockers     	=> 0,
					MaxLocks     	=> 0,
					MaxObjects     	=> 0,
					Verbose		=> 0,
					Config		=> undef,
					Encrypt		=> undef,
					SharedMemKey	=> undef,
					Set_Lk_Exclusive	=> undef,
					ThreadCount	=> 0,
					BlobThreshold	=> 0,
                    BlobDir	=> undef,
					}, @_) ;

    my $errfile  = $got->{ErrFile} ;				
    if (defined $got->{ErrFile}) {
	if (!isaFilehandle($got->{ErrFile})) {
	    my $handle = new IO::File ">$got->{ErrFile}"
		or croak "Cannot open file $got->{ErrFile}: $!\n" ;
	    $errfile = $got->{ErrFile} = $handle ;
	}
    }

    if (defined $got->{MsgFile}) {
        my $msgfile  = $got->{MsgFile} ;				
	if (!isaFilehandle($msgfile)) {
	    my $handle = new IO::File ">$msgfile"
		or croak "Cannot open file $msgfile: $!\n" ;
	    $got->{MsgFile} = $handle ;
	}
    }

    my %config ;
    if (defined $got->{Config}) {
    	croak("Config parameter must be a hash reference")
            if ! ref $got->{Config} eq 'HASH' ;

	%config = %{ $got->{Config} } ;
        @BerkeleyDB::a = () ;
	my $k = "" ; my $v = "" ;
	while (($k, $v) = each %config) {
	    if ($BerkeleyDB::db_version >= 3.1 && ! $valid_config_keys{$k} ){
	        $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
                croak $BerkeleyDB::Error ;
	    }
	    push @BerkeleyDB::a, "$k\t$v" ;
	    $got->{$k} = $v;
	}

        $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
	    if @BerkeleyDB::a ;
    }

    BerkeleyDB::parseEncrypt($got);

    my ($addr) = _db_appinit($pkg, $got, $errfile);
    my $obj ;
    $obj = bless [$addr] , $pkg if $addr ;
#    if ($obj && $BerkeleyDB::db_version >= 3.1 && keys %config) {
#	my ($k, $v);
#	while (($k, $v) = each %config) {
#	    if ($k eq 'DB_DATA_DIR')
#	      { $obj->set_data_dir($v) }
#	    elsif ($k eq 'DB_LOG_DIR')
#	      { $obj->set_lg_dir($v) }
#	    elsif ($k eq 'DB_TEMP_DIR' || $k eq 'DB_TMP_DIR')
#	      { $obj->set_tmp_dir($v) }
#	    else {
#	      $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
#              croak $BerkeleyDB::Error 
#            }
#	}
#    }
    return $obj ;
}


sub TxnMgr
{
    my $env = shift ;
    my ($addr) = $env->_TxnMgr() ;
    my $obj ;
    $obj = bless [$addr, $env] , "BerkeleyDB::TxnMgr" if $addr ;
    return $obj ;
}

sub txn_begin
{
    my $env = shift ;
    my ($addr) = $env->_txn_begin(@_) ;
    my $obj ;
    $obj = bless [$addr, $env] , "BerkeleyDB::Txn" if $addr ;
    return $obj ;
}

sub DESTROY
{
    my $self = shift ;
    $self->_DESTROY() ;
}

sub STORABLE_freeze
{
    my $type = ref shift;
    croak "Cannot freeze $type object\n";
}

sub STORABLE_thaw
{
    my $type = ref shift;
    croak "Cannot thaw $type object\n";
}

package BerkeleyDB::Hash ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			#Tie 		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

			# Hash specific
			Ffactor		=> 0,
			Nelem 		=> 0,
			Hash 		=> undef,
			DupCompare	=> undef,

			# BerkeleyDB specific
			ReadKey		=> undef,
			WriteKey	=> undef,
			ReadValue	=> undef,
			WriteValue	=> undef,

            # Blob
            BlobThreshold	=> 0,
            BlobDir	=> undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
	if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

    croak("-Tie needs a reference to a hash")
	if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;

    BerkeleyDB::parseEncrypt($got);

    my ($addr) = _db_open_hash($self, $got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr] , $self ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn}) 
            if $got->{Txn} ;
    }
    return $obj ;
}

*TIEHASH = \&new ;

 
package BerkeleyDB::Btree ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			#Tie 		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

			# Btree specific
			Minkey		=> 0,
			Compare		=> undef,
			DupCompare	=> undef,
			Prefix 		=> undef,
			set_bt_compress	=> undef,

            # Blob
            BlobThreshold	=> 0,
            BlobDir	=> undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
        if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
        if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

    croak("-Tie needs a reference to a hash")
        if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;

#    if (defined $got->{set_bt_compress} )
#    {
#
#        croak("-set_bt_compress needs a reference to a 2-element array")
#            if $got->{set_bt_compress} !~ /ARRAY/ ||
#
#        croak("-set_bt_compress needs a reference to a 2-element array")
#            if $got->{set_bt_compress} !~ /ARRAY/ ||
#               @{ $got->{set_bt_compress} } != 2;
#
#        $got->{"_btcompress1"} =  $got->{set_bt_compress}[0] 
#            if defined $got->{set_bt_compress}[0];
#
#        $got->{"_btcompress2"} =  $got->{set_bt_compress}[1] 
#            if defined $got->{set_bt_compress}[1];
#    }

    BerkeleyDB::parseEncrypt($got);

    my ($addr) = _db_open_btree($self, $got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr] , $self ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn}) 
            if $got->{Txn} ;
    }
    return $obj ;
}

*BerkeleyDB::Btree::TIEHASH = \&BerkeleyDB::Btree::new ;

package BerkeleyDB::Heap ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

			# Heap specific
			HeapSize	=> undef,
			HeapSizeGb	=> undef,

            # Blob
            BlobThreshold	=> 0,
            BlobDir	=> undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
        if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
        if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

#    if (defined $got->{HeapSize} )
#    {
#
#        croak("-HeapSize needs a reference to a 2-element array")
#            if $got->{HeapSize} !~ /ARRAY/ ||
#
#        croak("-HeapSize needs a reference to a 2-element array")
#            if $got->{HeapSize} !~ /ARRAY/ ||
#               @{ $got->{set_bt_compress} } != 2;
#
#        $got->{"HeapSize"} =  $got->{HeapSize}[0] 
#            if defined $got->{HeapSize}[0];
#
#        $got->{"HeapSize"} =  $got->{HeapSize}[1] 
#            if defined $got->{HeapSize}[1];
#    }

    BerkeleyDB::parseEncrypt($got);

    my ($addr) = _db_open_heap($self, $got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr] , $self ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn}) 
            if $got->{Txn} ;
    }
    return $obj ;
}

sub TIEHASH
{
    die "Tied Hash interface not supported with BerkeleyDB::Heap\n" ;
}


package BerkeleyDB::Recno ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			#Tie 		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

			# Recno specific
			Delim		=> undef,
			Len		=> undef,
			Pad		=> undef,
			Source 		=> undef,
			ArrayBase 	=> 1, # lowest index in array
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
	if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

    croak("Tie needs a reference to an array")
	if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;

    croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
	if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;


    BerkeleyDB::parseEncrypt($got);

    $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;

    my ($addr) = _db_open_recno($self, $got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr] , $self ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn}) 
            if $got->{Txn} ;
    }	
    return $obj ;
}

*BerkeleyDB::Recno::TIEARRAY = \&BerkeleyDB::Recno::new ;
*BerkeleyDB::Recno::db_stat = \&BerkeleyDB::Btree::db_stat ;

package BerkeleyDB::Queue ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			#Tie 		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

			# Queue specific
			Len		=> undef,
			Pad		=> undef,
			ArrayBase 	=> 1, # lowest index in array
			ExtentSize      => undef,
		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
	if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

    croak("Tie needs a reference to an array")
	if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;

    croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
	if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;

    BerkeleyDB::parseEncrypt($got);

    $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;

    my ($addr) = _db_open_queue($self, $got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr] , $self ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn})
            if $got->{Txn} ;
    }	
    return $obj ;
}

*BerkeleyDB::Queue::TIEARRAY = \&BerkeleyDB::Queue::new ;

sub UNSHIFT
{
    my $self = shift;
    croak "unshift is unsupported with Queue databases";
}

## package BerkeleyDB::Text ;
## 
## use vars qw(@ISA) ;
## @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
## use UNIVERSAL ;
## use Carp ;
## 
## sub new
## {
##     my $self = shift ;
##     my $got = BerkeleyDB::ParseParameters(
## 		      {
## 			# Generic Stuff
## 			Filename 	=> undef,
## 			#Flags		=> BerkeleyDB::DB_CREATE(),
## 			Flags		=> 0,
## 			Property	=> 0,
## 			Mode		=> 0666,
## 			Cachesize 	=> 0,
## 			Lorder 		=> 0,
## 			Pagesize 	=> 0,
## 			Env		=> undef,
## 			#Tie 		=> undef,
## 			Txn		=> undef,
## 
## 			# Recno specific
## 			Delim		=> undef,
## 			Len		=> undef,
## 			Pad		=> undef,
## 			Btree 		=> undef,
## 		      }, @_) ;
## 
##     croak("Env not of type BerkeleyDB::Env")
## 	if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
## 
##     croak("Txn not of type BerkeleyDB::Txn")
## 	if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
## 
##     croak("-Tie needs a reference to an array")
## 	if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
## 
##     # rearange for recno
##     $got->{Source} = $got->{Filename} if defined $got->{Filename} ;
##     delete $got->{Filename} ;
##     $got->{Fname} = $got->{Btree} if defined $got->{Btree} ;
##     return BerkeleyDB::Recno::_db_open_recno($self, $got);
## }
## 
## *BerkeleyDB::Text::TIEARRAY = \&BerkeleyDB::Text::new ;
## *BerkeleyDB::Text::db_stat = \&BerkeleyDB::Btree::db_stat ;

package BerkeleyDB::Unknown ;

use vars qw(@ISA) ;
@ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
use UNIVERSAL ;
use Carp ;

sub new
{
    my $self = shift ;
    my $got = BerkeleyDB::ParseParameters(
		      {
			# Generic Stuff
			Filename 	=> undef,
			Subname		=> undef,
			#Flags		=> BerkeleyDB::DB_CREATE(),
			Flags		=> 0,
			Property	=> 0,
			Mode		=> 0666,
			Cachesize 	=> 0,
			Lorder 		=> 0,
			Pagesize 	=> 0,
			Env		=> undef,
			#Tie 		=> undef,
			Txn		=> undef,
			Encrypt		=> undef,

		      }, @_) ;

    croak("Env not of type BerkeleyDB::Env")
	if defined $got->{Env} and ! UNIVERSAL::isa($got->{Env},'BerkeleyDB::Env');

    croak("Txn not of type BerkeleyDB::Txn")
	if defined $got->{Txn} and ! UNIVERSAL::isa($got->{Txn},'BerkeleyDB::Txn');

    croak("-Tie needs a reference to a hash")
	if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;

    BerkeleyDB::parseEncrypt($got);

    my ($addr, $type) = _db_open_unknown($got);
    my $obj ;
    if ($addr) {
        $obj = bless [$addr], "BerkeleyDB::$type" ;
	push @{ $obj }, $got->{Env} if $got->{Env} ;
        $obj->Txn($got->{Txn})
            if $got->{Txn} ;
    }	
    return $obj ;
}


package BerkeleyDB::_tiedHash ;

use Carp ;

#sub TIEHASH  
#{ 
#    my $self = shift ;
#    my $db_object = shift ;
#
#print "Tiehash REF=[$self] [" . (ref $self) . "]\n" ;
#
#    return bless { Obj => $db_object}, $self ; 
#}

sub Tie
{
    # Usage:
    #
    #   $db->Tie \%hash ;
    #

    my $self = shift ;

    #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;

    croak("usage \$x->Tie \\%hash\n") unless @_ ;
    my $ref  = shift ; 

    croak("Tie needs a reference to a hash")
	if defined $ref and $ref !~ /HASH/ ;

    #tie %{ $ref }, ref($self), $self ; 
    tie %{ $ref }, "BerkeleyDB::_tiedHash", $self ; 
    return undef ;
}

 
sub TIEHASH  
{ 
    my $self = shift ;
    my $db_object = shift ;
    #return bless $db_object, 'BerkeleyDB::Common' ; 
    return $db_object ;
}

sub STORE
{
    my $self = shift ;
    my $key  = shift ;
    my $value = shift ;

    $self->db_put($key, $value) ;
}

sub FETCH
{
    my $self = shift ;
    my $key  = shift ;
    my $value = undef ;
    $self->db_get($key, $value) ;

    return $value ;
}

sub EXISTS
{
    my $self = shift ;
    my $key  = shift ;
    my $value = undef ;
    $self->db_get($key, $value) == 0 ;
}

sub DELETE
{
    my $self = shift ;
    my $key  = shift ;
    $self->db_del($key) ;
}

sub CLEAR_old
{
    my $self = shift ;
    my ($key, $value) = (0, 0) ;
    my $cursor = $self->_db_write_cursor() ;
    while ($cursor->c_get($key, $value, BerkeleyDB::DB_PREV()) == 0) 
	{ $cursor->c_del() }
}

sub CLEAR_new
{
    my $self = shift ;
    $self->truncate(my $count);
}

*CLEAR = $BerkeleyDB::db_version < 4 ? \&CLEAR_old : \&CLEAR_new ;

#sub DESTROY
#{
#    my $self = shift ;
#    print "BerkeleyDB::_tieHash::DESTROY\n" ;
#    $self->{Cursor}->c_close() if $self->{Cursor} ;
#}

package BerkeleyDB::_tiedArray ;

use Carp ;

sub Tie
{
    # Usage:
    #
    #   $db->Tie \@array ;
    #

    my $self = shift ;

    #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;

    croak("usage \$x->Tie \\%hash\n") unless @_ ;
    my $ref  = shift ; 

    croak("Tie needs a reference to an array")
	if defined $ref and $ref !~ /ARRAY/ ;

    #tie %{ $ref }, ref($self), $self ; 
    tie @{ $ref }, "BerkeleyDB::_tiedArray", $self ; 
    return undef ;
}

 
#sub TIEARRAY  
#{ 
#    my $self = shift ;
#    my $db_object = shift ;
#
#print "Tiearray REF=[$self] [" . (ref $self) . "]\n" ;
#
#    return bless { Obj => $db_object}, $self ; 
#}

sub TIEARRAY  
{ 
    my $self = shift ;
    my $db_object = shift ;
    #return bless $db_object, 'BerkeleyDB::Common' ; 
    return $db_object ;
}

sub STORE
{
    my $self = shift ;
    my $key  = shift ;
    my $value = shift ;

    $self->db_put($key, $value) ;
}

sub FETCH
{
    my $self = shift ;
    my $key  = shift ;
    my $value = undef ;
    $self->db_get($key, $value) ;

    return $value ;
}

*CLEAR =    \&BerkeleyDB::_tiedHash::CLEAR ;
*FIRSTKEY = \&BerkeleyDB::_tiedHash::FIRSTKEY ;
*NEXTKEY =  \&BerkeleyDB::_tiedHash::NEXTKEY ;

sub EXTEND {} # don't do anything with EXTEND


sub SHIFT
{
    my $self = shift;
    my ($key, $value) = (0, 0) ;
    my $cursor = $self->_db_write_cursor() ;
    return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) != 0 ;
    return undef if $cursor->c_del() != 0 ;

    return $value ;
}


sub UNSHIFT
{
    my $self = shift;
    if (@_)
    {
        my ($key, $value) = (0, 0) ;
        my $cursor = $self->_db_write_cursor() ;
        my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) ;
        if ($status == 0)
        {
            foreach $value (reverse @_)
            {
	        $key = 0 ;
	        $cursor->c_put($key, $value, BerkeleyDB::DB_BEFORE()) ;
            }
        }
        elsif ($status == BerkeleyDB::DB_NOTFOUND())
        {
	    $key = 0 ;
            foreach $value (@_)
            {
	        $self->db_put($key++, $value) ;
            }
        }
    }
}

sub PUSH
{
    my $self = shift;
    if (@_)
    {
        my ($key, $value) = (-1, 0) ;
        my $cursor = $self->_db_write_cursor() ;
        my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) ;
        if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND())
	{
            $key = -1 if $status != 0 and $self->type != BerkeleyDB::DB_RECNO() ;
            foreach $value (@_)
	    {
	        ++ $key ;
	        $status = $self->db_put($key, $value) ;
	    }
	}

# can use this when DB_APPEND is fixed.
#        foreach $value (@_)
#        {
#	    my $status = $cursor->c_put($key, $value, BerkeleyDB::DB_AFTER()) ;
#print "[$status]\n" ;
#        }
    }
}

sub POP
{
    my $self = shift;
    my ($key, $value) = (0, 0) ;
    my $cursor = $self->_db_write_cursor() ;
    return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) != 0 ;
    return undef if $cursor->c_del() != 0 ;

    return $value ;
}

sub SPLICE
{
    my $self = shift;
    croak "SPLICE is not implemented yet" ;
}

*shift = \&SHIFT ;
*unshift = \&UNSHIFT ;
*push = \&PUSH ;
*pop = \&POP ;
*clear = \&CLEAR ;
*length = \&FETCHSIZE ;

sub STORESIZE
{
    croak "STORESIZE is not implemented yet" ;
#print "STORESIZE @_\n" ;
#    my $self = shift;
#    my $length = shift ;
#    my $current_length = $self->FETCHSIZE() ;
#print "length is $current_length\n";
#
#    if ($length < $current_length) {
#print "Make smaller $length < $current_length\n" ;
#        my $key ;
#        for ($key = $current_length - 1 ; $key >= $length ; -- $key)
#          { $self->db_del($key) }
#    }
#    elsif ($length > $current_length) {
#print "Make larger $length > $current_length\n" ;
#        $self->db_put($length-1, "") ;
#    }
#    else { print "stay the same\n" }

}



#sub DESTROY
#{
#    my $self = shift ;
#    print "BerkeleyDB::_tieArray::DESTROY\n" ;
#}


package BerkeleyDB::Common ;


use Carp ;


sub STORABLE_freeze
{
    my $type = ref shift;
    croak "Cannot freeze $type object\n";
}

sub STORABLE_thaw
{
    my $type = ref shift;
    croak "Cannot thaw $type object\n";
}

sub DESTROY
{
    my $self = shift ;
    $self->_DESTROY() ;
}
sub Env
{
    my $self = shift ;
    $self->[1] ;
}

sub Txn
{
    my $self = shift ;
    my $txn  = shift ;
    #print "BerkeleyDB::Common::Txn db [$self] txn [$txn]\n" ;
    if ($txn) {
        $self->_Txn($txn) ;
        push @{ $txn }, $self ;
    }
    else {
        $self->_Txn() ;
    }
    #print "end BerkeleyDB::Common::Txn \n";
}


sub get_dup
{
    croak "Usage: \$db->get_dup(key [,flag])\n"
        unless @_ == 2 or @_ == 3 ;
 
    my $db        = shift ;
    my $key       = shift ;
    my $flag	  = shift ;
    my $value 	  = 0 ;
    my $origkey   = $key ;
    my $wantarray = wantarray ;
    my %values	  = () ;
    my @values    = () ;
    my $counter   = 0 ;
    my $status    = 0 ;
    my $cursor    = $db->db_cursor() ;
 
    # iterate through the database until either EOF ($status == 0)
    # or a different key is encountered ($key ne $origkey).
    for ($status = $cursor->c_get($key, $value, BerkeleyDB::DB_SET()) ;
	 $status == 0 and $key eq $origkey ;
         $status = $cursor->c_get($key, $value, BerkeleyDB::DB_NEXT()) ) {
        # save the value or count number of matches
        if ($wantarray) {
	    if ($flag)
                { ++ $values{$value} }
	    else
                { push (@values, $value) }
	}
        else
            { ++ $counter }
     
    }
 
    return ($wantarray ? ($flag ? %values : @values) : $counter) ;
}

sub db_cursor
{
    my $db = shift ;
    my ($addr) = $db->_db_cursor(@_) ;
    my $obj ;
    $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
    return $obj ;
}

sub _db_write_cursor
{
    my $db = shift ;
    my ($addr) = $db->__db_write_cursor(@_) ;
    my $obj ;
    $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
    return $obj ;
}

sub db_join
{
    croak 'Usage: $db->BerkeleyDB::db_join([cursors], flags=0)'
	if @_ < 2 || @_ > 3 ;
    my $db = shift ;
    croak 'db_join: first parameter is not an array reference'
	if ! ref $_[0] || ref $_[0] ne 'ARRAY';
    my ($addr) = $db->_db_join(@_) ;
    my $obj ;
    $obj = bless [$addr, $db, $_[0]] , "BerkeleyDB::Cursor" if $addr ;
    return $obj ;
}

package BerkeleyDB::Cursor ;

sub c_close
{
    my $cursor = shift ;
    $cursor->[1] = "" ;
    return $cursor->_c_close() ;
}

sub c_dup
{
    my $cursor = shift ;
    my ($addr) = $cursor->_c_dup(@_) ;
    my $obj ;
    $obj = bless [$addr, $cursor->[1]] , "BerkeleyDB::Cursor" if $addr ;
    return $obj ;
}

sub c_get_db_stream
{
    my $cursor = shift ;

    my $addr = $cursor->_c_get_db_stream(@_);
    my $obj ;
    $obj = bless [$addr, $cursor] , "BerkeleyDB::DbStream" if $addr ;
    return $obj ;
}

sub db_stream
{
    my $db = shift ;
    my ($addr) = $db->_db_stream(@_) ;
    my $obj ;
    $obj = bless [$addr, $db] , "BerkeleyDB::DbStream" if $addr ;
    return $obj ;
}

#sub gdbs
#{
#    my $cursor = shift ;
#
#    my $k = '';
#    my $v = '';
#    $db->partial_set(0,0) ;
#    ok $cursor->c_get($k, $v, DB_FIRST) == 0, "set cursor"
#        or diag "Status is [" . $cursor->status() . "]";
#    $db->partial_clear() ;
#    is $k, "1";
#}

sub DESTROY
{
    my $self = shift ;
    $self->_DESTROY() ;
}


package BerkeleyDB::TxnMgr ;

sub DESTROY
{
    my $self = shift ;
    $self->_DESTROY() ;
}

sub txn_begin
{
    my $txnmgr = shift ;
    my ($addr) = $txnmgr->_txn_begin(@_) ;
    my $obj ;
    $obj = bless [$addr, $txnmgr] , "BerkeleyDB::Txn" if $addr ;
    return $obj ;
}

package BerkeleyDB::Txn ;

sub Txn
{
    my $self = shift ;
    my $db ;
    # keep a reference to each db in the txn object
    foreach $db (@_) {
        $db->_Txn($self) ;
	push @{ $self}, $db ;
    }
}

sub txn_commit
{
    my $self = shift ;
    $self->disassociate() ;
    my $status = $self->_txn_commit() ;
    return $status ;
}

sub txn_abort
{
    my $self = shift ;
    $self->disassociate() ;
    my $status = $self->_txn_abort() ;
    return $status ;
}

sub disassociate
{
    my $self = shift ;
    my $db ;
    while ( @{ $self } > 2) {
        $db = pop @{ $self } ;
        $db->Txn() ;
    }
    #print "end disassociate\n" ;
}


sub DESTROY
{
    my $self = shift ;

    $self->disassociate() ;
    # first close the close the transaction
    $self->_DESTROY() ;
}

package BerkeleyDB::CDS::Lock;

use vars qw(%Object %Count);
use Carp;

sub BerkeleyDB::Common::cds_lock
{
    my $db = shift ;

    # fatal error if database not opened in CDS mode
    croak("CDS not enabled for this database\n") 
        if ! $db->cds_enabled();

    if ( ! defined $Object{"$db"})
    {
        $Object{"$db"} = $db->_db_write_cursor()
         || return undef ;
    }

    ++ $Count{"$db"} ;

    return bless [$db, 1], "BerkeleyDB::CDS::Lock" ;
}

sub cds_unlock
{
    my $self = shift ;
    my $db = $self->[0] ;

    if ($self->[1]) 
    {
        $self->[1] = 0 ;
        -- $Count{"$db"} if $Count{"$db"} > 0 ;

        if ($Count{"$db"} == 0)
        {
            $Object{"$db"}->c_close() ;
            delete $Object{"$db"};
            delete $Count{"$db"};
        }

        return 1 ;
    }

    return undef ;
}

sub DESTROY
{
    my $self = shift ;
    $self->cds_unlock() ;	
}

package BerkeleyDB::Term ;

END
{
    close_everything() ;
}


package BerkeleyDB ;




1;
__END__




Anon7 - 2022
SCDN GOK