From cb2c0f8e785a746702273716cdf579078ae4d0e7 Mon Sep 17 00:00:00 2001 From: Andrey Cunha Date: Sat, 14 Feb 2026 23:37:32 -0300 Subject: [PATCH] att --- __pycache__/trf.cpython-311.pyc.2092010911952 | Bin 0 -> 32577 bytes __pycache__/trf.cpython-311.pyc.2230932420912 | Bin 0 -> 38956 bytes __pycache__/trf.cpython-311.pyc.2382066170064 | Bin 0 -> 33510 bytes __pycache__/trf.cpython-311.pyc.2533927434448 | Bin 0 -> 34172 bytes __pycache__/trf.cpython-311.pyc.2691276814640 | Bin 0 -> 39271 bytes __pycache__/trf.cpython-311.pyc.2693554719680 | Bin 0 -> 32563 bytes __pycache__/trf.cpython-311.pyc.2733743963568 | Bin 0 -> 38956 bytes trf.py | 1190 +++++++++++++++++ 8 files changed, 1190 insertions(+) create mode 100644 __pycache__/trf.cpython-311.pyc.2092010911952 create mode 100644 __pycache__/trf.cpython-311.pyc.2230932420912 create mode 100644 __pycache__/trf.cpython-311.pyc.2382066170064 create mode 100644 __pycache__/trf.cpython-311.pyc.2533927434448 create mode 100644 __pycache__/trf.cpython-311.pyc.2691276814640 create mode 100644 __pycache__/trf.cpython-311.pyc.2693554719680 create mode 100644 __pycache__/trf.cpython-311.pyc.2733743963568 create mode 100644 trf.py diff --git a/__pycache__/trf.cpython-311.pyc.2092010911952 b/__pycache__/trf.cpython-311.pyc.2092010911952 new file mode 100644 index 0000000000000000000000000000000000000000..cc6ec8783387d341826761cad0dd400a73bdef68 GIT binary patch literal 32577 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 M;dGUFAR7Vxe<=}-761SM literal 0 HcmV?d00001 diff --git a/__pycache__/trf.cpython-311.pyc.2230932420912 b/__pycache__/trf.cpython-311.pyc.2230932420912 new file mode 100644 index 0000000000000000000000000000000000000000..f716bcc21c8d8b73d1f40cd4a7a5962414222f07 GIT binary patch literal 38956 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∓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 literal 0 HcmV?d00001 diff --git a/__pycache__/trf.cpython-311.pyc.2533927434448 b/__pycache__/trf.cpython-311.pyc.2533927434448 new file mode 100644 index 0000000000000000000000000000000000000000..f78c84b0c7686fdca5fe7a272c3215d4e9b29701 GIT binary patch literal 34172 zcmdVDdvF_9x+m6+_lpGh0N)SrA&HN$YE`AJ)UAsDNJ7Um ziAz!fYiHd!)UGFduYI%yxaPdbJjxTha36AZ)Uf^oP)Fb!7xQem77cfZ6Kt<@Ldj1w9QQN)mE$M4{4DF?hO1e;QpB^X;|Vyif34SMXtc1T_aIzASzY6|_jK2~7YWSNne!I6ZmmHP0 z2KSm*xmSyOuG~GR>bW}HYgy%9J?^y%4Jc0|{!QLeZ^5%Dv%SziW)hkazfEv?`AhBD ziea&q)vl@pEqH2;(CW2iYM~AOwL&{`EA`s)G4rlWyfuioE>m)$-1ngvhLGdkf31l;Ev|K=b!RSq_sod;B4o`U~oFHbK^$Ow6A+yoSF8I`=$cksqyYn z|77;;1BvnJ)+OwE%?TLLC*wxZrUpb{8Jky z{Nv+ZVPhcZ7rlYmquEpfV;e;8ga@HMe_%r{|K&+t>DefHr~P6uuu<@j&P;lzf`JVa zc$wMWKPRn=o+)9%yTLc<8TSU#=1Z>xN7xId4Wc(VBTkLxY8rKGz@OUTo81V#$%VK$ zJj)M(SGQ4^59V5r<3dGu10+T1!G93ezNeMIu9#w<}AuLiyk$LB84@< zT;JljOS$|*nz(Lxi8)R%sMAyX!rGuU|I{U_2X=(Cabwn9czt|oL!8?<_=xZRic0kr zRq!Kz&sS8eS^Z3KY{Pc9DXkAoPxyjq?SywKZMfhGc(-jym(7S10neCs&6uas!p>L)26Ml~nNE?)!ZkBic}i?TWGDWCzXX`$Qa0!Hlh;nh`jR%6Y;(;G zJTO`!TVI=feKz{+5C3BBFH-ihh&feW9pi6w#D+c^N;nfQ->&(a7e9P4KDh8~vVB{! z@#$pw({sljSRAsYHNNY9+t$UltqbGHw!L!O-lS!pY}q&0_rPkO-x(dfdFic7@#9p94*lu2Ir;9ah8X1}LOnOH~(w32tNxv{NL2lc~$jdXH3FQterD#I@ zv^EeF)Ao@O&(xGZ=pk$!7#U$jPiuWsL9qjo#PtB5a4a8Ic(H{-2~e8^E&@*?+$A* zV`bMh`9zn!MZBOc^3ep7I#;m)sZkRyI|Q>}QP-bf$(Le^4{5`?U_O8g*5{K5>D0Nb z+**QF9c!8|o^!+cAmOph5z>bAw{7Y&6^@aR7K5u~km0CLKtU3M^v?v-#=y+zs5cOp zZDn}S)%(m57bqjYIOU&lW$x`6^GpQ1J6&lV5u3`ipl4LntWlXNT#tB{Xh%`fT1*!h zO|5V%_}4BzO>V+qN+^x7w07JZ#H4fb*udb>$eB~e(+<(&3wTGy{NhLeXmBPVR#QCN zshKG%>VPQvMVkL#@rr2+VqnI9#TUFNmQ%Vt1PBwdG3_?6!JOtrni7OpS+;2{CVO!| z;smId6Iqa*2rMYei1Hq@b~eiM0bTS!8Ac|?IZf5~t@Vr6`lPi{wl)Gwn%AT%s&DL+ zE7~Pn`$L;!{^0ea*N(nDn|La6G->OWZQT(*WisD4)h(LplBNdP)F7D}Qg+AnE7z{P zadrM`MEB5MasBGGt1)xZ-YVN$DbeHngYqV+`RLt#0G!G4V{-X1$#(2vnKL?eqao(G z(HyUq%iIw|%DwUD4L@!8r0I6kefNPy_kp`RlI|0-`-D__E;4p~;@U)PbDU3>w#ucg z@gBK!jf8XPTtxezwCwG!SRh&6CYQI}FJHGwT#7+EPtjKaO74_r+6XFnWLg-*&{c}8nkaRM!rEXC4oon79M|PX2qfdODS%LR zu3ZYBQMVq?6;f*NIW6C9CSogd|u!{t6B-$9OFA3hE|L$%Z)f zTW`hE40V#5n)|sI+u5{4sVzGM&F!M;5Qv@+>q0uw1R_T#=xDJwTY?22KflII3^x4K zXrAY$tZiHm7tp<;xvD+Ky~6X{IgZCKM8v&*FwLC?r@%1bc@-G{5pMylY{6SkPs~hS z06NwAr?CjbDvDOfHn!9s#VQ#Nw_bb>*{7}K@nhkPwSHPleb0c{z9~;y&+Y_>tU-Ha zF>1+#S7ZtJsnNty+&zYW;BNuYT;-Km7MUyNn`5;}bDL}i^{LZ$#RI9T+8e$lPHXOB zAaXEOS$Ds3-D2gsL{O?+m#o|(S8kCiciz!N22%D)43?6vl%qa26A!)1i#JV`(z*HKqOs0{O6&T;G2C?MlH*7S2`;nwcS(n;Uw|w4asfdY#74YIs0KGOBt` zj>MyuQ)9t=uMv1b6XMX;S~c@0p6fSwICrSWUwp-$q>h7j*A32U&j;3v`;d%y768qz z5xrP&%v`|oJ1F|5MH)oFwT$eg-kn_&Yh!J3P=N7M zNvm77y6;;zE?PGxtv#}}=f3snMeEZ^>kiqvL(=VF<4aXFI;6t}RRRv8eyOv^;a+~I zUndM6bBMdbiJjod6b!@sbAlFJ8B|`LGrUSX4XRufFRVsqMZ=j@B&)the3yuENXv(D zT+&9csU|$5-n4!UY=@wD5rKshmL04G5hTr|f6Dvn$aGMgLWJ*8q~ib>24+j7I&$H< z{hB>#s+CQ(bG;A2WAMyfox7T{m0Uk^?MQSq_Egf=B-@(q+tx1H*2V(~@FO|j_PLYGD>~N)KSWkk(E+gWhg7Ta!oCO`rmhk!29zhv>dN6)?t4NJxvs{D zLtGmdG@&4wqn#6VgrTTJuW$;+!b~ySeqQ)~PuJ#f$G)BCyW!p(c6WB+`cyb{URck9 zo(ePS6L`ss#L|WU7!{)zSB82=7ctB>XJ=elBw&CXRbHX(<-CSvUP*~2|5?8 zjXrBH?cL0Mw%Kxk*Zzj%0axx_)c^lHL?Jq#v}a9$TgiyRSvq=Z&57J0m;eI!V|581(rT694X6p}9#tjblzJn5FW>AV$^-sFu~>ijz9V z57Nm?gEBR!NAK_0w|mcd!HpTdV;?zKcb~0b_%eel*=0)xW$Kg~rgknE4a=(8F_I+! zvDWv}v=zb=KcY$=1X!WV8zg&c{6KYl&H7{O3x@lX`7o3^! zkBHuJ@6~kGwCKO;oAd`pl;D68K3Z5w20X@y36UYj)d&ejWIWNjMqSkqiO?*XIr3{9 zQ03a7E*lQfOU?~S9_7gk@`#F8W>GL_bn$}J@=yN+&Y$JH0{52%!tXFd>|sMlgB8TC zuyK{r7(@CeER88-601U{Cn-nRfHeg_zdK}j%@RT>LWaU}0f`f*RySBcTJl5%dBy{7 zLt1yq@0(KiGC9TW(Vk%6U@=Y&FNO*H03gi=)0)XmX}xDGh*gQv zJ0*-v`vag^uZo1812kt~iJ=?{55Hu@7w}JDZFphAKk66XK#c1Y^)mo;Rg?9)>6$6J zCb~ZM)cvyd#j^Hf*;=`5ZPK((HmyTfHCyLvqr2l}pSIrKAepx(&D&-3_PGNoYe}90 z04)Y8?c%kIZ(N$c6uBI^JU=)$@UXOe?og_&|`fm6lhf=n($iR{w!AmBtd9Bpc6WJQAiLQ&*%w7y&O&LCVq3MYS(J$C$YV2q=5En3+4xkF(V( zduj)*QpJkGeikZPn+iP5u4pfQzE;qLb%GX5NMk2Kqfn6q{gTSCe37S6#>u25pJHyEUYnL0i5w`KJV1km@~i1RYry$K~UU=_0LTyioGGEo{Z8S5bWmPMUiKO<`N37inIs1g5IU*AA3tzOyw0{Cs1` ztm=10b$e%eohf7tne+9H$xs_E3t67l2jDsS*zuL)QE|s`JJhYr@Wu?X`}O?axTJK#gaGbgM!o zNVnvP(k&D`7(*qGEpK(G^oi0e6pd2%$Pu&w2?kU!FY?ZV0wz;}+xPaAT+exbg*tE1Sa2STL>0#|<^B zTQBUIa$tqMHXj2^CM~V7=UcPu>rhk3HKqx-gjzz4S9ozls4-rdkDqsiTGVNShgcUc z7$*fWk)lv@s|dgG-28c=HdGO+3^_wpq3Tdgs5VrGS)uNhWmLmMS3vm>VV;`bh5uPW z16rbf=Kn;>7Mj`zNY%&(In=;l?~u#m3VJR;Z^$M1U2Klu$s)O2t%G1j23!Yyfl&yK zT!Pm%@e*0hiySIM(!{2=Dr;woMDjxJgo;5i$&#m66_wVamLAy!kKhlWImV$-F%|Tys)Yz@ znrglwq0UWi9E8w|WokBkafQ68nJ-6GJcS2DA{50afT|KKyGhp!tvtPVcGsU?3%Q5? z8%mf&lBfdbcIAxsyzPzkzIpM+#as}3@3ii+_tlIpO(E4r?ap5C893hN)x6|4ik61J z7nKZO@Q^=n@Y#r-V~iX_h|iC^`I32OL4SaL4;IrH96|3VdNGEK()^_~4+V_NX@k<2 zbKLzoh3Gc`<|B^x%#4I9AsFI&UFoBh$= z=*y|b7Ld+P1OdeORDDC7k8O)>OSQGf4rhN$TCSmWNlVcTTunnX$SQS)=r!-8FA&HL zW2`C2@9{sflCF(wjF88~Y^l=g1aE-kQGT~})|4Hg%!M&Obw#{^V;rt;MOzkEDggA(EDV3=Ve`1{41pP z4;iul5zhxU0c1vO-A<`)=R#SmH+Cpq{{Fsq_a*DQOCiws+*zz=<=11E+fXdQW}=<+Px0+MikC{g~pi<^wB;nlG&& z4Ireep0v`GBiW`*Q$vnW^QD!R8<`ptsixB=VE9qYD}l5gif(?2N@;2SN?MCT ziNrz`;{bs+0Gj(Bf9zM#&$=f>IwJLJmi*6wNP%aT99&uD4f7JTCiUfCGZ@jO%AAFq z0jaDj(F(PSirOXaEN@0Mf|0&d1?2U7N$q=WvC(%rZgs?;eYYzH;bRR@PF+*vXsWIu za_m7}Tf8r!Nt7itA0A59b;)&*IOOUAdiRnt_1)QwYqFzX25jn= zoBE^Hhn24QF{yGR&IRwC?@QZ`()sKKY3ya`SvpfKtLlD!3Gc*rK0 zgf?;XwjDD|(z#uBZjT&X(&r;lMdn-`lybE#F_YB#)WQ*| zWpA=(pIoyqawO$!jGm2!WB#PGTXuFsGF#sk+a5n3A57M7mg_f1jZ9AG z#%`%$W3pnCT(K$Ak6L!%WnJ-u(5{_8mE5}|4Zb7^7bRi(e`1YLQy<%z;NRIB+ZWp> zSFc~<9OrirP}^dw$t>NBgf1|KjlC`rXp{-Lby7;nuO(vAeBN^WWEXe!6v` zA-R69ynb)8Zl7GYFKT>H?M}E88y7?+m#FSxbrZ`fF646Tf9A`f=cMO{lS41aLoY1$ zzaaI$@MYtM#OOko+`TW^xLsil93 zI(6a8`mV&#g7fxpvVOZ?d znXKO}*YB2azA%D_yY@@Fj!Vxz_vN|s(u*%8&w1o?p2cT9(z71r3H|M(N;i<|pO(fi zM@?wKr?%k1*0rBjB!-9x{9t2zV{|B1dE;F4+=3X@JgC7MAys)MRau4p(E7DrTU-7I z4j`)kqlv4je{<%>OjMU@2G7k@b`YAY1m8Rq?T@uUHsWk~(6k}pNj7bgn>NL?G3~bx z>JgK7f`G_^RE;ZUg6PfJ0@2&U+QwKQW{viys%zr9XgC^9)ik_sde;;$d&hdq8nYty z`}TM33zc`Z%5Y8A49GPDQq91(c$v1Xsphq*wsoo2uGHEsDOX4S1kK{K)_^OhfHHDD z27G;tr@s0uPnc#YsNrmm$d*7kkk^0MVn41keW9})FSCB(-~q+A5Ue6LhzKTv1!y8I|qkySY2>UG}AqCquLqJDx2atb)WT4jdZh`br|7vu^Rwm>2-{#&|7zz8Zg z&aP!_W2_E}S$`|N&_6HEfu{V;_eLdBD7uDi%~$ftE#$ad92Pc zL*=#1cjO6j4O^hGT7qoyP2?&5h5)NedQ;4iiVFB&!86;W5GqWLy~1M5Mios8AQ{rm zc~o*9O|;z!+S3-**t9`WSYe)(gYKDS_OrDs1@2B zTPzi!Xr|rEFG=N>Vy(Zgmycj7cqw_rBOmcdUf<#opLE0*eF`9dvdFAe(%Qj;{pg0& z?Bai-@_-5yC$Vp0*1JsKrBq!i@joNJoyxHV4(bObBzZ+SaDHT!U0XrmJbUN)yRAvr zfb1GTXtMm03~0S1TQ5nvOUpY(4%uBplIrDfVMi!d$y1NIFgiwvzXEkR$Zc^Iq3?hl zcDjrkqAdXnW_I702{R$goN-&=wr1QmxJ!TtO9yAGpjsz_Aw^U%V@CjFPr%&|`jSQYV4cI?$;K=Edv(?#{*%U@auYe@dm8#f%rv~~ddKGB+ zX>UNu4B}Gakzk22>+}YoM2%dC^EK%aFMET&squ7q|G>~Q14GE}MDM9%1E-G+9-4Iu z-Yfoz8Sr*oU}t67I~4V~lgH0s?KN`nRPW%kXO8sFmR-rRypR=Rd8JFA8yM{G9eL)| z$^J8^PY$Ka4jez(cXFin`00UDgT1GZJa-bEm^uN&2yheD5MKuckP zQ}%Yr-kvhL;=Ph_4bGH(jbvY=ioEY`k20mF>}`_0EoE$qw@Ah|oY{c7m`5@;<4oC` zC3|zq+9X+qjjs$l~6mi6V|SS$?QzSCuR-{HM#}mdW9?g|Zp-5Wu7r zV7wxI7#qXlgyWVSf*w<*flBpwya`F3A!NM5O=}^O!!>MzOpg5Z7&3IN7A)*qfnh^_ zyI^Bit5CwOMxm5lwSt|lVYA?1{;HL?Bno9AqZ+RZni)Q9fppsxGK+?gMbw4#87W{e zL{h*{u*Lhkq<}3##dk~igvub%Wtk&bz(LPT0w4u!ffUdQDWLTqIn64hNpe3c?U-67 zStPli4HCiXWfDP>{8@3QX4xH*{aJd~b3g`I`la#YV%s$;5s;i`}mQo|~|?F~rzsv+UpS|s6Gx$LclQYTe@hR~|guA;oF zL)CLnhaAXJE&KY@b1aaFsq;|#@P1{;txP3p`_pqP%a1#C`f4AOo7O4-H+$VDs>yD5-5OP5L6se%l zBDAg`6Z{Lv1aC2!VB4(7PrOgrMga;bq$2)4lY)Y$J&BE}AoM0ZB$|7yL~bL|QQb&2 zvl!?YlsX3QJo~Bh)0u^5Ke>AQ>L<;&n-NrWGHOTsF`koOR~2|#ovBH6fM{}c;Gh+tcfz7zhj<94)){*moNkK z09Xup#E%en)_nc~V`HDcpjw>KLa_q>Zw>-vB!ERrvnOv3$OfCUvcZ)b;wBX(Clq}0 zhR6v8`=}+_kqQX~_bF$hrFi|FxuMiQN#vAW_JuSgQEcqRpMm3_L^3G8OBvq+C=&lM zQA1wx_r$f3mHZ9hJ;V#CH-C1U> z;et5R6Ud1zP2`~tls1!#^$Uh@#Q%$)`YnOa3EZPcjTy zzJ*NEl95TyFqtI5$I2uFOeRV2F)~SrHX=tAVWc)up3r`HI9azru7h@kgM^U)MZ!p$ z`tNSOyW?If9LbJB8L(+kZW@eQQ_UTTV^Z_eQq%KyhVSi?_B;n6rL#4DS#knP8J)XQ zHER;}Qq7hnEj$lv)+W|VHCvbT@IXpZyH4>M$!p?jI}*F3nr%yF@>;msHY8Kivt%W& zE$1yEFXWKx6S%u$sf;VDU8>}o=-I|?Qp4o05B%!L-3jURNOJc}^6r-)xsrBIM9rxR z2-!4cb@A=&vH(FZd@IXKX^Kq*7IxnL3pkR_eX?`kpDQngVD%&6)6E}Z<0_oLJpAjS zUz}K7yh?HC-5_I)cP4yN%l2f=4!LFriCEjCBTJlpZD}5S&DpE$e;|O;xwyL4SdG*= zq@2mx({k-;h)=7Uq8H=F*sF^5AZV69fjsr0y(S|~h4l1cb=~7-rwoM+0dFPidSt-r z9=RHg|4$`5{dCQOIoY{W?u3+fmt4IILcitm)B0uz6Dt~}3U}htuQ%Tb{O$H%ZC~u} zle+sJG;jQ+eqr=Z=P&%pO$X&o2b0Z*SNl)UoTX@%L@_Mt|4wMaSa) zQ_}uZ*=N@MVj{VzPu|p*Z0?tv`=f^+9ylZ&7?RGu_~lEZk}#fp>7xA7#l^E1rLz|y z==^j5!dLGvI+I;{F3i6fn@70xph}o3c5D6wln2wFOY%?e~uLN zkcM#E61Lmqq@Z7{w;$hS`eK*mgvt7QBM+#e2du!TOjz`}rdTFGMh?LC(tN-#+nNKW zY@kHIKE}cy;u-|wE#mN-R%Y3*w$qJfm!ILU9O`8rq=PiOW{&)JA+Se_ZSX*0Z^cqs zlv2SO4Q7qyN3pFKY&=>mrmd)KdYF7LEKjjmA$etsKd{A#sqAO?D+e|!8HCb|wL42l z1E0Q-3C(tY8dbGHD?xS;^S6jig6$1qbKzzJbuAOiH^(ZmhHYS#6euc(ir=(^u}Z44 z`ElF|O48O)30Nhiq0*3ru}Um)TG}o4G6EkIMrxF>~kRoZ_Pk z`~he|V`m-IkICYO$CX*fuw0a-y`nk&V}BQ;*AX$RBG>KeI2izw1Uk%K=;A_FIf*)1TO$n((eBLCT#QeXTwNyFYC_g z8&j06`6yW>ZMTlLjvn_-T|OV^+&Q~0n+r?3KO+#!rUm8fj8JT5Eh_XR6VTzN`k@!H z)%D4X#JiYTw`$Zru^=w-F(A_lBR1Q;CerX9oN)sVWm7C@fC63eEdNUIF#4RSP+;%- zg~zE;Zs`iU&tG7#F_>>vvRvkKsar3@_+slO#>`^NsIUGX9J2==pUHRYYGSu8El=E~ zY^R+f7A~h6$S)*bChq`1T1P66;$zneZo9JiQ_sleG=G6@^vjd(P-BFuu`pdgvojKY zHNrhWtHmOkT~Qibn_ahOI~Z}zvJy{)eTEo*GEBe>Oa%S_#~k-Z3s+K?GL@v9Q%f4X z%L2kK3ykIx!`B?Z9|+71fJC*GEpaxz{&l z0?d}BI?ilkyA+)_>))z>v++h_($p-Qn&*1|er3}G-<89jm;?qI6AF<$;wC>n~CMYctrjyyeI z7pY5>%^moA>~%bvGMz}7EKt;-X7_T^nLrlj(EJ;nFlFbW#lk)waiY^)ha2AZjKydTPdUc zkv)+;DVyW^;cJJn8UEP(vB)vRCTpGX(+ho4!*-lW+YZ^bL$dAo7DcLdrz+~GNvi6o zNh)iyX9Ki9QCl_x+JgbTfhk`7cAvf9uKC<<>2J_~Ue5!nNDi7X8OhPKjN~ZL1Sv8k z0=q!GO72j^8z!qkVkvR1U>jzc?h20`9I*bg;+<8k|8Q|C<+7vL-~;SAne&l~l_%7u zVT-x?w8wd60s>}MRK$T;y=u&&oeYqI>Bykr6PG?mfM7Rv&RzT-to{i=Gx8k=QfGf#TB+W9Cy=b}ldJn8wv@G+5UMLx z(M+}CqCyq`dRrIONYdh4P)Cm z;*{WDioXUWFbQ^qmzaU1m7h=rE6Yk+nP;h{L6WU#6wQ^ZYvaC%mYh$K#D{Eqvx2i}N z7+!M(KZQ$9YkgG((88KkzyUba+E*(t;MJAE=2LVSVg%eWpqdSXj~v*H!$glT2Dy=} zjz3zPwL8y{)(Teeu{MM8{737aEZ)XP))W3&-^7Gx5`Gm zF1`_Znc2#0GZco_Qd{(}ws_dsa_ijv#-7E-o@C=@xp8xQu3+FEFgJa(DX2D(lMpm1X78#B=V49S;N>iFqgLp`y1% z#k(mo|FE(R=At)4I$}3A9}jT6X8+d#T?Qa~MLdx%_z3D5!=rp=KWcHa4d-bvAg2m$In z+2ygaE-ocg$FvR}y$JKmfmvq;J*b1*2tVvW3Q*%NFmk-*{`x(O>-Qwr?~~W>yH`#o zkB`f?<7}BWzbAH7vaZERPaL^#b1m9jNn5LIYn5!RDM#fE!%fRumiKlhg7-J}E^h2i zZtRmc_T4)bwIm(S$c|?sy~_uR#?1T-#AS~1i2h+^&CSDa9gaN*!<202 z$P#BJ!=eC@{*=8zvUem-|NQJv&o20q8}`c^_TMX!Hk`qU{d2J4d~^F-+hYfl6>V|_ zi(e55;l_iCs%Y@d9XEE|-1pYLWJNpdJX2y7kSvw7#dPt0sip%b-sYz1EmN%W&C(mC z*mvb{-n6}Ci=9q7T4hJ8iKy~>D<&0%PjX>8+6mt;R~G7=>8ZppVn+Tb4>!!A)+ zyY@}`f};jBTK34zcdw%{fJ|XdkFgQ?TRLd+YC>8cj{)^hfVM)=@fEbUb?T4Wgke*v z0L_v`o|FIIK(nit_X$z0=}Ay6qZsJR6Qk2dgtRT&q%>iRZW@uD1Udk|+KncJ1>{D! z$#|~lnN%#CGvpyQAs7a+2t#1|ub;l$(|@urk03;n8LxyG@DLmSYw7+v0+d@p=A`_U zHfBF^LKtEtJ6h#5-m}FIz;Nlfceb_w6{v6RB6RQzBn5O(*SyepZ>{vgOH!E!CvBZ= zj@L=$T@j;V5B=D+WAB*~?e{x(FLv%ucJ7rs_ujoCoqj>`jz^9qZ5L(R#V1A>*0-$h z9Zm@MyZ0}4?@x9gkh>4u+a{eIk$jh<)}&)Xc1%QiA3oOJx?LHCw%mB5!DwNh2V!6C z7|l@)ct66IjCR4UJPfxWyxHTg!Hfy<4B~qQaBBfI@0q|5DPTf8$+kL${A7|RJ?7@` z{Eh<~@TS}5B8msHmppwVSTGb%sY+6aMzSwaL^&{u2mM7ko}}!MU|6YV|3gasWCPL+ zHSs4Il4|o)A!DJEzM8fX*C`tj#I{0u323gsOj58wUR3lnHaQf=9O9UKsU}-{dHK?m zE@y(-%;8)YsROrUYVkg8;P{DOQa7Hh~)%mj|}wLD#`66 zP(`4cKn;Oz0u2NR#jtp3Eey!J?P<&5-ogIk1N8NUg5^VwNKsIZnhe1}3E+caL68ex zd<+8L8B=tINCODp+@bXmktbQAgyEwtlCD-kd*X@ZMik<{BC`bOp zHYbdC%8BIJEjxCvgu9judUIK-qVndpx3;~x{l@l4{{wq%to$Ufnai5o2`kS<$H}ZgAHFi*Y4;<`0%{Yl) z5o1L~r#KM65a$IfxoFWBN5Jv}pDZcnf*TMQ4Y~Yaw2p!HmK4z-ApBQGRf48?ITJRi zSRSiASH!u727eKUI&8)=iiw|L@vc2=Rq@ZQtCXf_p@dY6mO?8F_thvNY)?0dr;%$%ylmr?=mX(+6J}y-H5ii(;5+DCj zQD1`PD+$vExAFu7${D38nndk|pCSs`F|Fk!BWm;?cBmGt4t3edD&gbG8!B6+j}$2u ztQya*&TrLtMdeyGUXjJaRpXUEVZKE>q*hI@Xh+nl@tjYXZ`BjVD^d;-s&84A_a4}~ zT!LM_0ulf!BkpkdRnm|7Rrn`TbTtxlP){;hYLBbnzNs6E1eqO-z zcr!t63yYq%WcKcmktPyLJ^m@B2u`Mm0(!wuAF)zC60_30xXxQ z!jxg_v0ou32qyn%fE6sQ#a{0;FNitfC~c;1V2)6!@I{&|^`m@!MbG%oY2M4`<1GKC z;Ht2490irYKF%^*ouQeEZwN##Jp^Djk*ezMJ3AJg9SdQ}*^zV($j*U?1z)AQZ(qA; zUmKrEOhWOu3btO7_UC2$^We8+zF1`itHs_S+dCq<2M&BFk?~)iPgbsxE7wSsoryAh zl0|l`2XCg-5z&&Uom*pmhX0zuNbiGs`f9?=yEE|@lg*pu=FL*`4w%fT-znGcykEb6 zv3`HD{(xM6AaeXcZA0wY_s_h0CcZ1#xKVE0C^c?fcq&=DO|IQ`zjpUx?e1jlUb%K} zYAJ0x4g0bH!t6~oT{mPU;nN?Hug@*t&&vp`c&h(l&j@q{RjH^RMNE-HVBri zhFU1x0z{60(yN5frBpJkVnqk?!;QvG1e2au?io;ram&ZOg{>^LboPLc&EowMW_ zKGop5->_}5VcSBObd$fAY#5OnMqnVQp(}Cjj_y~6WWzqWVPDkzpk~X$ImND0RR2)P z0cs-+Fc00lq{a1N>$;EKAGj08ldU`C)*Y#g_eipJo7@V^cO4(^_+Urk#bnzqxoubW zZZ`7T^&k5_@JXBYC)f7MYkO0!H6NQlFef^dxBb(+jjivWd-q)Y6{XIXs!=vpPzJt+ zwoAny2*6ub!Mxx8v4N|k&!V9|3gJric&~*jb6I_&N^>VF8D#0Vpihw=IZRv?bT}GP z&bkLqNQmA%cjH{DrYY`xr!=u3`SJbkwH* z_clG;%Eut};$9li`v_o2aN>Tr2HlRLPlYMp1*1i@f*y!%%Rb;K5{01bpJ2FzVGxE; z7~UX}gLs-EKSeIu^TdX$NTyjBsHD+I-$R?r{pcfNWcV-(OeVc07KClFiumDMKOkiq ztWMORvPzHf1&}zrFm$Kl7iZe{qavWH#- z;Gw;INlzXaaI9Z4lFNjR5ld!rSvW_baB3E z$xe|dy_JAc_f+llh1N-rZwlX8rN+*80L*x6DS$0p)p-0MQ>KHx78^c}JtKNYJb_W4 z4+?6e{up#`Q^cW6jiQp;m~rjhZOGu0>LxDXvF)vh!idjyX%JWC+0e{G2IO^2{7Mq=8>gpYy{d-k+#Q zj3#P69Aw^NP|j(rP$A^$le;U!uUYsX82nm`=&#pi9&ps~_%h&f@HK_~A%A1HmT!t- zDB_YhEO+f@uDj3yK|nFE8Tsni^AP0n)d`?*T#7*x&+m*30gv-LqsoQ33xG+_S4IQ$ zK9#WAu#d$F+O@a z)*cJoa^JvqAo5fD&~*if_?P+UDBZctQ`6IR1!%JI%`qXq1$)7E+yXj>ccG14ia}E- z_j=@7>Gddl39_dm7}7q=^9D+mu6Nq+1n&0Tx%#Va#lHf)sHx+fi9<^qE_ZZyhVHiA zIr}RRWAGM({rm|H53Ig2{F;UTq44gQj?>v9vy0kVNn4vTl|~G2nC4CR!dgiwv|4SY z_=1O{?7pLQ(b1YJtstVp?qrU-B`a6f_BCfHgH9{J9Fc{3%iKVuGtxfa89kRcbEikL b>`7Yo$bh=NvTm=GJ(n6eT^%xHQ_cSiAy*Z= literal 0 HcmV?d00001 diff --git a/__pycache__/trf.cpython-311.pyc.2691276814640 b/__pycache__/trf.cpython-311.pyc.2691276814640 new file mode 100644 index 0000000000000000000000000000000000000000..5e20918994cca59d843897f459248ad0327b3baa GIT binary patch literal 39271 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 literal 0 HcmV?d00001 diff --git a/__pycache__/trf.cpython-311.pyc.2693554719680 b/__pycache__/trf.cpython-311.pyc.2693554719680 new file mode 100644 index 0000000000000000000000000000000000000000..3100eabe31baa0473acacf7fa64a9782637191df GIT binary patch literal 32563 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 literal 0 HcmV?d00001 diff --git a/__pycache__/trf.cpython-311.pyc.2733743963568 b/__pycache__/trf.cpython-311.pyc.2733743963568 new file mode 100644 index 0000000000000000000000000000000000000000..f716bcc21c8d8b73d1f40cd4a7a5962414222f07 GIT binary patch literal 38956 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∓;x0**-HUBjYh)q-Q%Hm+Y9cBuj6mTb8(D@HzSYG527XmT!!r zt>O|tBzNs%uKQK&QV48DzAE|xYzg?PIA}aBg`kn=d&9#Z^n7nbxiEJgFzI<`BtYNe zj83ylA#j-SNDD?NoBKlQJ_On0WpuA2}Uu ziw5p?+{Q{PbWi0&*JU8^ukw*GdUBPgqNnRJ&}8GAqC#vlmf6{H7xW&t3$5%@2pU7# z&m-4zpGW>nP=6M{koF|c8z@-1-fO!TxZi*8`mei{`(@x|O)c+=A6(*axu?4~e82VH z*rCs2+fHK0R5ZEld0UI$?M8~4lx6vMP8w+CN zh>G~3_t3xMwh+`Fq_kgJ;^=z6?S9}v|NZNqAnkO&3>?v%*6`@tmWQ7+|3BtGg|Ujx z7M@wu)=1hKm@kG6ubbvgbA69XN@3P$E5)v_jYL~2BS?lMV zp$zkg0p^IG*IVWW!=2%_`Oe6>_?de>l4W Dict[str, Any]: + parts = jwt_token.split(".") + if len(parts) != 3: + return {} + payload_b64 = parts[1] + "=" * (-len(parts[1]) % 4) + raw = base64.urlsafe_b64decode(payload_b64.encode("utf-8")) + return json.loads(raw.decode("utf-8")) + + +@dataclass +class TokenCache: + bearer: Optional[str] = None + exp_epoch: int = 0 + + def valid(self, skew_seconds: int = 30) -> bool: + return bool(self.bearer) and (time.time() < (self.exp_epoch - skew_seconds)) + + +class Auth: + def __init__(self, s: requests.Session): + self.s = s + self.cache = TokenCache() + + def get_bearer(self) -> str: + if self.cache.valid(): + return self.cache.bearer # type: ignore + + r = self.s.get(TOKENS_URL, timeout=30) + r.raise_for_status() + body = r.json() + + if not body.get("success"): + raise RuntimeError(f"Token API retornou success=false: {body}") + + bearer = body["data"][0]["token"] # já vem "Bearer ..." + jwt = bearer.split(" ", 1)[1] if bearer.lower().startswith("bearer ") else bearer + exp = int(_jwt_payload(jwt).get("exp") or 0) + + self.cache = TokenCache(bearer=bearer, exp_epoch=exp) + return bearer + + def invalidate(self) -> None: + self.cache = TokenCache() + + +# ----------------------------- +# PDF: download + leitura texto (fallback) +# ----------------------------- +def baixar_pdf_bytes(url_pdf: str, session: requests.Session) -> BytesIO: + r = session.get(url_pdf, timeout=120) + r.raise_for_status() + return BytesIO(r.content) + + +def ler_texto_pdf(pdf_bytes: BytesIO) -> str: + texto_total = "" + with pdfplumber.open(pdf_bytes) as pdf: + for pagina in pdf.pages: + texto = pagina.extract_text(layout=True) or "" + if texto: + texto_total += texto + "\n" + return texto_total + + +# ----------------------------- +# EXTRAÇÃO: Remuneração Franquia +# 1) tenta por TABELA (mais confiável) +# 2) se falhar, cai no TEXTO (como antes) +# ----------------------------- +def _norm(s: str) -> str: + return re.sub(r"\s+", " ", (s or "")).strip().lower() + + +def _parse_money_pt(s: str) -> float: + s = (s or "").strip() + # "12.769,43" -> "12769.43" + if "," in s: + s = s.replace(".", "").replace(",", ".") + return float(s) + + +def _money_from_text(s: str) -> Optional[float]: + if not s: + return None + m = re.search(r"\d{1,3}(?:\.\d{3})*,\d{2}|\d+\.\d{2}", s) + if not m: + return None + try: + return _parse_money_pt(m.group(0)) + except Exception: + return None + + +def _float5_from_text(s: str) -> Optional[float]: + if not s: + return None + m = re.search(r"\d+(?:[.,])\d{5}", s) # 1,00000 / 1.00000 + if not m: + return None + x = m.group(0) + x = x.replace(".", "").replace(",", ".") if "," in x else x + try: + return float(x) + except Exception: + return None + + +def _pick_first_number(s: str) -> Optional[str]: + if not s: + return None + m = re.search(r"\b\d{3,}\b", s) + return m.group(0) if m else None + + +def _extract_date_pt(s: str) -> Optional[str]: + if not s: + return None + s = re.sub(r"(?<=\d)\s+(?=\d)", "", s) + m = re.search(r"\d{2}\.\d{2}\.\d{4}", s) + return m.group(0) if m else None + + +def _date_from_iso(s: Optional[str]): + if not s: + return None + try: + return datetime.strptime(s, "%Y-%m-%d").date() + except Exception: + return None + + +def _date_from_br(s: Optional[str]): + if not s: + return None + try: + return datetime.strptime(s, "%d.%m.%Y").date() + except Exception: + return None + + +def _isolar_bloco(texto: str, titulo_regex: str, proximos_titulos_regex: List[str]) -> Optional[str]: + t = " ".join((texto or "").split()) + m0 = re.search(titulo_regex, t, flags=re.IGNORECASE) + if not m0: + return None + after = t[m0.start():] + + end_pos = None + for rx in proximos_titulos_regex: + m = re.search(rx, after, flags=re.IGNORECASE) + if m: + end_pos = m.start() + break + + return after[:end_pos] if end_pos is not None else after + + +def extrair_remuneracao_franquia_por_tabela(pdf: pdfplumber.PDF) -> Optional[Dict[str, Any]]: + """ + Extrai APENAS a tabela do bloco: + "Notas Fiscais de Serviço de taxa de remuneração de Franquia" + + Regra para não confundir com "Venda de Produtos": + - o header TEM que ter "valor taxa" e "fat.conv" + """ + for page in pdf.pages: + tables = page.extract_tables() or [] + for tbl in tables: + if not tbl or len(tbl) < 2: + continue + + # procura um header que tenha as colunas específicas do bloco de remuneração + header_idx = None + header_join = "" + for i, row in enumerate(tbl[:8]): + header_join = " | ".join(_norm(c) for c in row if c) + # precisa ter essas chaves (venda não tem "valor taxa") + if ("valor taxa" in header_join) and ("fat" in header_join) and ("dados pagamento" in header_join): + header_idx = i + break + + if header_idx is None: + continue + + header = [_norm(c) for c in tbl[header_idx]] + + def idx_like(keys: List[str]) -> Optional[int]: + for j, h in enumerate(header): + for k in keys: + if k in h: + return j + return None + + i_emissao = idx_like(["emissão", "emissao"]) + i_nota = idx_like(["nota fiscal"]) + i_valor_taxa = idx_like(["valor taxa"]) + i_valor_desc = idx_like(["valor desconto"]) + i_fat = idx_like(["fat.conv", "fat conv", "fat"]) + i_valor_nf = idx_like(["valor nf"]) + i_enc = idx_like(["encargos"]) + i_dp = idx_like(["dados pagamento"]) + + # essenciais do bloco + if i_emissao is None or i_nota is None or i_valor_taxa is None or i_valor_nf is None or i_dp is None: + continue + + # lê a primeira linha "real" de dados (normalmente só tem 1) + for row in tbl[header_idx + 1:]: + if not any((c or "").strip() for c in row): + continue + + emissao_cell = row[i_emissao] if i_emissao < len(row) else "" + nota_cell = row[i_nota] if i_nota < len(row) else "" + + emissao = _extract_date_pt(_cell(emissao_cell)) + nota = _pick_first_number(nota_cell or "") + + if not emissao or not nota: + continue + + valor_taxa = _money_from_text(row[i_valor_taxa]) if i_valor_taxa < len(row) else None + valor_desconto = _money_from_text(row[i_valor_desc]) if i_valor_desc is not None and i_valor_desc < len(row) else None + fat_conv = _float5_from_text(row[i_fat]) if i_fat is not None and i_fat < len(row) else None + valor_nf = _money_from_text(row[i_valor_nf]) if i_valor_nf < len(row) else None + encargos = _money_from_text(row[i_enc]) if i_enc is not None and i_enc < len(row) else None + + # Dados pagamento: várias linhas data + valor + parcelas: List[Dict[str, Any]] = [] + dp = row[i_dp] if i_dp < len(row) else "" + pares = re.findall( + r"(\d{2}\.\d{2}\.\d{4})\s+(\d{1,3}(?:\.\d{3})*,\d{2}|\d+\.\d{2})", + dp or "" + ) + seen = set() + for data, v in pares: + try: + val = _parse_money_pt(v) + except Exception: + continue + k = (data, val) + if k not in seen: + seen.add(k) + parcelas.append({"data": data, "valor": val}) + + return { + "tipo_bloco": "TAXA_REMUNERACAO", + "emissao": emissao, + "nota_fiscal": nota, + "valor_taxa": valor_taxa, + "valor_desconto": valor_desconto, + "fat_conv": fat_conv, + "valor_nf": valor_nf, + "encargos": encargos, + "parcelas": parcelas, + "error": None, + } + + return None + + +def _cell(c: Any) -> str: + return " ".join(str(c or "").split()) + + +def _table_text(tbl: List[List[Any]]) -> str: + return " | ".join(_norm(_cell(c)) for row in tbl for c in (row or [])) + + +def _strip_accents(s: str) -> str: + return "".join(ch for ch in unicodedata.normalize("NFD", s or "") if unicodedata.category(ch) != "Mn") + + +def _tipo_bloco_fallback(tbl: List[List[Any]]) -> str: + t = _strip_accents(_table_text(tbl)) + if "outras notas de debito" in t or "outras nfs servicos" in t: + return "OUTRAS_NOTAS_DEBITO" + if "outras notas de credito" in t: + return "OUTRAS_NOTAS_CREDITO" + if "despesas de propaganda" in t or "esforcos de marketing" in t: + return "DESPESAS_MARKETING" + if "devolucao da franquia" in t: + return "DEVOLUCAO_FRANQUIA" + if "venda de produtos" in t: + return "VENDA_PRODUTOS" + return "BLOCO_ALTERNATIVO" + + +def extrair_bloco_com_informacao_por_tabela(pdf: pdfplumber.PDF) -> Optional[Dict[str, Any]]: + """ + Fallback geral: encontra o primeiro bloco com emissao + nota, + quando TAXA_REMUNERACAO estiver vazio. + """ + for page in pdf.pages: + tables = page.extract_tables() or [] + for tbl in tables: + if not tbl or len(tbl) < 2: + continue + + header_idx = None + for i, row in enumerate(tbl[:10]): + header_join = _strip_accents(" | ".join(_norm(_cell(c)) for c in (row or []))) + has_emissao = "emissao" in header_join + has_nota = ( + ("nota fiscal" in header_join) + or ("nota debito" in header_join) + or ("nota credito" in header_join) + or ("n nota" in header_join) + or ("nota - duplicata" in header_join) + ) + has_valor = ("valor nf" in header_join) or (re.search(r"\bvalor\b", header_join) is not None) + if has_emissao and has_nota and has_valor: + header_idx = i + break + + if header_idx is None: + continue + + header = [_strip_accents(_norm(_cell(c))) for c in tbl[header_idx]] + + def idx_like(keys: List[str]) -> Optional[int]: + for j, h in enumerate(header): + for k in keys: + if k in h: + return j + return None + + def idx_like_prefer(keys: List[str]) -> Optional[int]: + for k in keys: + for j, h in enumerate(header): + if k in h: + return j + return None + + i_emissao = idx_like(["emissao"]) + + i_nota = idx_like_prefer([ + "n nota debito", + "n nota credito", + "nota fiscal", + "nota debito", + "nota credito", + "nota - duplicata", + "nota duplicata", + "n nota", + ]) + i_valor_nf = idx_like(["valor nf", "val. nf autorizado", "valor da nf"]) + + i_valor = idx_like(["valor"]) + + i_enc = idx_like(["encargos"]) + + i_dp = idx_like(["dados pagamento"]) + + + if i_emissao is None or i_nota is None: + continue + + for row in tbl[header_idx + 1:]: + if not any(_cell(c) for c in row): + continue + + emissao_cell = row[i_emissao] if i_emissao < len(row) else "" + nota_cell = row[i_nota] if i_nota < len(row) else "" + + emissao = _extract_date_pt(_cell(emissao_cell)) + nota = _pick_first_number(_cell(nota_cell)) + if not emissao or not nota: + continue + + valor_nf = None + if i_valor_nf is not None and i_valor_nf < len(row): + valor_nf = _money_from_text(_cell(row[i_valor_nf])) + if valor_nf is None and i_valor is not None and i_valor < len(row): + valor_nf = _money_from_text(_cell(row[i_valor])) + + encargos = _money_from_text(_cell(row[i_enc])) if i_enc is not None and i_enc < len(row) else None + + parcelas: List[Dict[str, Any]] = [] + dp = _cell(row[i_dp]) if i_dp is not None and i_dp < len(row) else "" + pares = re.findall( + r"(\d{2}\.\d{2}\.\d{4})\s+(\d{1,3}(?:\.\d{3})*,\d{2}|\d+\.\d{2})", + dp or "" + ) + seen = set() + for data, v in pares: + try: + val = _parse_money_pt(v) + except Exception: + continue + k = (data, val) + if k not in seen: + seen.add(k) + parcelas.append({"data": data, "valor": val}) + + return { + "tipo_bloco": _tipo_bloco_fallback(tbl), + "emissao": emissao, + "nota_fiscal": nota, + "valor_taxa": None, + "valor_desconto": None, + "fat_conv": None, + "valor_nf": valor_nf, + "encargos": encargos, + "parcelas": parcelas, + "error": "Taxa de remuneracao sem dados; usado bloco alternativo com informacao", + } + + return None + +def extrair_remuneracao_franquia_por_texto(texto: str) -> Dict[str, Any]: + """ + Fallback (como você já fazia): acha a seção por regex e tenta extrair + emissão, nota e parcelas. (Os valores podem falhar dependendo do PDF.) + """ + bloco = _isolar_bloco( + texto, + titulo_regex=r"Notas\s+Fiscais\s+de\s+Servi.{0,3}o\s+de\s+taxa\s+de\s+remunera.{0,5}o\s+de\s+Franquia", + proximos_titulos_regex=[ + r"\bLink\s*:", + r"Notas\s+de\s+Despesas\s+de\s+Propaganda", + r"Outras\s+Notas\s+de\s+D[eé]bito", + r"Outras\s+Notas\s+de\s+Cr[eé]dito", + ], + ) + if not bloco: + return { + "tipo_bloco": "TAXA_REMUNERACAO", + "emissao": None, + "nota_fiscal": None, + "valor_taxa": None, + "valor_desconto": None, + "fat_conv": None, + "valor_nf": None, + "encargos": None, + "parcelas": [], + "error": "Seção não encontrada", + } + + b = " ".join(bloco.split()) + + m = re.search(r"\b(\d{2}\.\d{2}\.\d{4})\s+(\d{4,})\b", b) + if not m: + return { + "tipo_bloco": "TAXA_REMUNERACAO", + "emissao": None, + "nota_fiscal": None, + "valor_taxa": None, + "valor_desconto": None, + "fat_conv": None, + "valor_nf": None, + "encargos": None, + "parcelas": [], + "error": "Não achei emissão + nota", + } + + emissao = m.group(1) + nota = m.group(2) + + # parcelas depois de "Dados Pagamento" + idx_dp = b.lower().find("dados pagamento") + dp = b[idx_dp:] if idx_dp != -1 else b + + pares = re.findall( + r"\b(\d{2}\.\d{2}\.\d{4})\s+(\d{1,3}(?:\.\d{3})*,\d{2}|\d+\.\d{2})\b", + dp + ) + parcelas: List[Dict[str, Any]] = [] + seen = set() + for data, v in pares: + try: + val = _parse_money_pt(v) + except Exception: + continue + k = (data, val) + if k not in seen: + seen.add(k) + parcelas.append({"data": data, "valor": val}) + + # aqui você pode manter os valores como None no fallback + return { + "tipo_bloco": "TAXA_REMUNERACAO", + "emissao": emissao, + "nota_fiscal": nota, + "valor_taxa": None, + "valor_desconto": None, + "fat_conv": None, + "valor_nf": None, + "encargos": None, + "parcelas": parcelas, + "error": None, + } + + +def extrair_remuneracao_franquia(pdf_bytes: BytesIO) -> Dict[str, Any]: + """ + Função única que você chama no seu fluxo: + - tenta tabela (melhor) + - se não conseguir, cai no texto (como era) + """ + # tenta bloco principal por tabela (melhor cenário) + with pdfplumber.open(pdf_bytes) as pdf: + via_tabela = extrair_remuneracao_franquia_por_tabela(pdf) + if via_tabela: + return via_tabela + + # fallback texto do bloco principal + pdf_bytes.seek(0) + texto = ler_texto_pdf(pdf_bytes) + via_texto = extrair_remuneracao_franquia_por_texto(texto) + if via_texto.get("emissao") and via_texto.get("nota_fiscal"): + return via_texto + + # se TAXA_REMUNERACAO estiver vazio, tenta qualquer outro bloco com dados + pdf_bytes.seek(0) + with pdfplumber.open(pdf_bytes) as pdf: + via_fallback = extrair_bloco_com_informacao_por_tabela(pdf) + if via_fallback: + return via_fallback + + return via_texto + + +def _tem_emissao_nota(d: Optional[Dict[str, Any]]) -> bool: + if not d: + return False + return bool(d.get("emissao") and d.get("nota_fiscal")) + + +def _dados_bloco(d: Dict[str, Any]) -> Dict[str, Any]: + return { + "emissao_nf": d.get("emissao"), + "nota_fiscal": d.get("nota_fiscal"), + "valor_taxa": d.get("valor_taxa"), + "valor_desconto": d.get("valor_desconto"), + "fat_conv": d.get("fat_conv"), + "valor_nf": d.get("valor_nf"), + "encargos": d.get("encargos"), + "parcelas": d.get("parcelas") or [], + } + + +def extrair_remuneracao_franquia_detalhado(pdf_bytes: BytesIO) -> Dict[str, Any]: + principal: Optional[Dict[str, Any]] = None + fallback: Optional[Dict[str, Any]] = None + + pdf_bytes.seek(0) + with pdfplumber.open(pdf_bytes) as pdf: + via_tabela = extrair_remuneracao_franquia_por_tabela(pdf) + if via_tabela: + principal = via_tabela + + if not principal: + pdf_bytes.seek(0) + texto = ler_texto_pdf(pdf_bytes) + principal = extrair_remuneracao_franquia_por_texto(texto) + + principal_ok = _tem_emissao_nota(principal) + if not principal_ok: + pdf_bytes.seek(0) + with pdfplumber.open(pdf_bytes) as pdf: + fallback = extrair_bloco_com_informacao_por_tabela(pdf) + + escolhido = fallback if fallback else principal + if not escolhido: + escolhido = { + "tipo_bloco": "TAXA_REMUNERACAO", + "emissao": None, + "nota_fiscal": None, + "valor_taxa": None, + "valor_desconto": None, + "fat_conv": None, + "valor_nf": None, + "encargos": None, + "parcelas": [], + "error": "Falha na extração", + } + + warnings: List[str] = [] + if not principal_ok and fallback: + warnings.append("Taxa de remuneração sem dados; usado bloco alternativo") + if principal and principal.get("error"): + warnings.append(str(principal.get("error"))) + + blocos: List[Dict[str, Any]] = [] + if principal: + blocos.append({ + "tipo": "TAXA_REMUNERACAO", + "encontrado": principal_ok, + "dados": _dados_bloco(principal) if principal_ok else None, + "erro": None if principal_ok else principal.get("error"), + }) + if fallback: + blocos.append({ + "tipo": fallback.get("tipo_bloco"), + "encontrado": _tem_emissao_nota(fallback), + "dados": _dados_bloco(fallback), + "erro": fallback.get("error"), + }) + + return { + "bloco_principal": "TAXA_REMUNERACAO", + "status_principal": "ok" if principal_ok else "sem_dados", + "bloco_utilizado": escolhido.get("tipo_bloco"), + "resumo": { + "emissao_nf": escolhido.get("emissao"), + "nota_fiscal": escolhido.get("nota_fiscal"), + "valor_nf": escolhido.get("valor_nf"), + "encargos": escolhido.get("encargos"), + }, + "blocos": blocos, + "warnings": warnings, + "escolhido": escolhido, # compatibilidade com estrutura atual + } + + +# ----------------------------- +# CLIENTE PRINCIPAL +# ----------------------------- +class Client: + def __init__(self): + self.s = requests.Session() + self.auth = Auth(self.s) + + def _headers_json(self) -> Dict[str, str]: + return { + "Authorization": self.auth.get_bearer(), + "Accept": "application/json", + "Content-Type": "application/json", + "Origin": "https://extranet.grupoboticario.com.br", + "Referer": "https://extranet.grupoboticario.com.br/", + "User-Agent": "Mozilla/5.0", + } + + def get_franchises(self, only_channels: Optional[Set[str]] = None) -> List[str]: + r = self.s.get(STORES_URL, headers=self._headers_json(), timeout=30) + if r.status_code in (401, 403): + self.auth.invalidate() + r = self.s.get(STORES_URL, headers=self._headers_json(), timeout=30) + r.raise_for_status() + + body = r.json() + seen = set() + codes = [] + + for item in body.get("data", []): + if only_channels is not None and item.get("channel") not in only_channels: + continue + code = item.get("code") + if code is None: + continue + code = str(code).strip() + if code and code not in seen: + seen.add(code) + codes.append(code) + + return codes + + def get_documents_page(self, cp_id: int, document_type: str, franchises: List[str], offset: int, limit: int): + params = {"cpId": cp_id, "documentType": document_type, "offset": offset, "limit": limit} + payload = {"franchises": franchises} + + r = self.s.post(DOCS_URL, headers=self._headers_json(), params=params, json=payload, timeout=60) + if r.status_code in (401, 403): + self.auth.invalidate() + r = self.s.post(DOCS_URL, headers=self._headers_json(), params=params, json=payload, timeout=60) + + r.raise_for_status() + return r.json() # {"total":..., "documents":[...]} + + def get_presigned_pdf_url(self, document_type: str, franchise_id: str, image_name: str) -> str: + url = f"{HANDLE_URL}/{document_type}/{franchise_id}/{image_name}/download" + + headers = { + "Authorization": self.auth.get_bearer(), + "Accept": "application/json", + "Origin": "https://extranet.grupoboticario.com.br", + "Referer": "https://extranet.grupoboticario.com.br/", + "User-Agent": "Mozilla/5.0", + } + + r = self.s.get(url, headers=headers, timeout=60) + if r.status_code in (401, 403): + self.auth.invalidate() + headers["Authorization"] = self.auth.get_bearer() + r = self.s.get(url, headers=headers, timeout=60) + + r.raise_for_status() + + # pode vir JSON com {"url": "..."} ou texto puro + try: + body = r.json() + if isinstance(body, dict) and "url" in body and isinstance(body["url"], str): + return body["url"] + except Exception: + pass + + return r.text.strip() + + def processar_pagina( + self, + cp_id: int = 10269, + document_type: str = "EFAT", + offset: int = 0, + limit: int = 25, + only_channels: Optional[Set[str]] = None, + ) -> Dict[str, Any]: + franchises = self.get_franchises(only_channels=only_channels) + + page = self.get_documents_page(cp_id, document_type, franchises, offset, limit) + docs = page.get("documents", []) + total = int(page.get("total") or 0) + + out = [] + for d in docs: + franchise_id = str(d.get("franchiseId") or "").strip() + image_name = str(d.get("imageName") or "").strip() + + base_item = { + "id": d.get("id"), + "UUID": d.get("UUID"), + "franchiseId": franchise_id, + "imageName": image_name, + "emissionDate": d.get("emissionDate"), + } + + if not franchise_id or not image_name: + out.append({**base_item, "error": "sem franchiseId/imageName"}) + continue + + try: + presigned = self.get_presigned_pdf_url(document_type, franchise_id, image_name) + + pdf_bytes = baixar_pdf_bytes(presigned, self.s) + extra_detalhado = extrair_remuneracao_franquia_detalhado(pdf_bytes) + extra = extra_detalhado.get("escolhido", {}) + + out.append({ + **base_item, + "bloco_principal": extra_detalhado.get("bloco_principal"), + "status_principal": extra_detalhado.get("status_principal"), + "bloco_utilizado": extra_detalhado.get("bloco_utilizado"), + "resumo": extra_detalhado.get("resumo"), + "blocos": extra_detalhado.get("blocos"), + "warnings": extra_detalhado.get("warnings"), + "tipo_bloco": extra.get("tipo_bloco"), + "emissao_nf": extra.get("emissao"), + "nota_fiscal": extra.get("nota_fiscal"), + "valor_taxa": extra.get("valor_taxa"), + "valor_desconto": extra.get("valor_desconto"), + "fat_conv": extra.get("fat_conv"), + "valor_nf": extra.get("valor_nf"), + "encargos": extra.get("encargos"), + "parcelas": extra.get("parcelas"), + "error": extra.get("error"), + }) + + except Exception as e: + out.append({**base_item, "error": f"falha_processar_pdf: {e}"}) + + return { + "total": total, + "offset": offset, + "limit": limit, + "count": len(docs), + "hasNext": (offset + limit) < total, + "items": out + } + + +# ----------------------------- +# SQL SERVER: persistência +# ----------------------------- +class SqlServerSink: + def __init__(self, connection_string: str): + self.connection_string = connection_string + self.cn = None + self.cur = None + + def __enter__(self): + try: + import pyodbc # type: ignore + except Exception as e: + raise RuntimeError("pyodbc não encontrado. Instale com: pip install pyodbc") from e + + self.cn = pyodbc.connect(self.connection_string, timeout=30) + self.cn.autocommit = False + self.cur = self.cn.cursor() + return self + + def __exit__(self, exc_type, exc, tb): + if self.cur is not None: + try: + self.cur.close() + except Exception: + pass + if self.cn is not None: + try: + if exc_type is None: + self.cn.commit() + else: + self.cn.rollback() + except Exception: + pass + try: + self.cn.close() + except Exception: + pass + + def reconnect(self) -> None: + try: + if self.cur is not None: + self.cur.close() + except Exception: + pass + try: + if self.cn is not None: + self.cn.close() + except Exception: + pass + + import pyodbc # type: ignore + self.cn = pyodbc.connect(self.connection_string, timeout=30) + self.cn.autocommit = False + self.cur = self.cn.cursor() + + @staticmethod + def _is_comm_error(e: Exception) -> bool: + msg = str(e) + return ("08S01" in msg) or ("10054" in msg) or ("communication link failure" in msg.lower()) + + def ensure_schema(self) -> None: + assert self.cur is not None + self.cur.execute( + """ +IF OBJECT_ID('dbo.TrfDocumento', 'U') IS NULL +BEGIN + CREATE TABLE dbo.TrfDocumento ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + UUID VARCHAR(80) NOT NULL UNIQUE, + IdExterno BIGINT NULL, + FranchiseId VARCHAR(20) NULL, + ImageName VARCHAR(150) NULL, + EmissionDate DATE NULL, + EmissaoNF DATE NULL, + NotaFiscal VARCHAR(40) NULL, + ValorNF DECIMAL(18,2) NULL, + Encargos DECIMAL(18,2) NULL, + AtualizadoEm DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME() + ); +END; + """ + ) + self.cur.execute( + """ +IF OBJECT_ID('dbo.TrfParcela', 'U') IS NULL +BEGIN + CREATE TABLE dbo.TrfParcela ( + id BIGINT IDENTITY(1,1) PRIMARY KEY, + DocumentoId BIGINT NOT NULL, + NumeroParcela INT NOT NULL, + DataVencimento DATE NOT NULL, + ValorParcela DECIMAL(18,2) NOT NULL, + CONSTRAINT FK_TrfParcela_Documento + FOREIGN KEY (DocumentoId) REFERENCES dbo.TrfDocumento(id), + CONSTRAINT UQ_TrfParcela UNIQUE (DocumentoId, NumeroParcela) + ); +END; + """ + ) + self.cur.execute( + """ +IF OBJECT_ID('dbo.TrfDocumento', 'U') IS NOT NULL + AND COL_LENGTH('dbo.TrfDocumento', 'id') IS NULL + AND COL_LENGTH('dbo.TrfDocumento', 'DocumentoId') IS NOT NULL +BEGIN + EXEC sp_rename 'dbo.TrfDocumento.DocumentoId', 'id', 'COLUMN'; +END; + +IF OBJECT_ID('dbo.TrfParcela', 'U') IS NOT NULL + AND COL_LENGTH('dbo.TrfParcela', 'id') IS NULL + AND COL_LENGTH('dbo.TrfParcela', 'ParcelaId') IS NOT NULL +BEGIN + EXEC sp_rename 'dbo.TrfParcela.ParcelaId', 'id', 'COLUMN'; +END; + """ + ) + self.cur.execute( + """ +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name='IX_TrfDocumento_NotaFiscal' AND object_id=OBJECT_ID('dbo.TrfDocumento')) + CREATE INDEX IX_TrfDocumento_NotaFiscal ON dbo.TrfDocumento(NotaFiscal); +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name='IX_TrfDocumento_UUID' AND object_id=OBJECT_ID('dbo.TrfDocumento')) + CREATE UNIQUE INDEX IX_TrfDocumento_UUID ON dbo.TrfDocumento(UUID); +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name='IX_TrfDocumento_Franchise_Emission' AND object_id=OBJECT_ID('dbo.TrfDocumento')) + CREATE INDEX IX_TrfDocumento_Franchise_Emission ON dbo.TrfDocumento(FranchiseId, EmissionDate); +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name='IX_TrfParcela_DocumentoId_DataVenc' AND object_id=OBJECT_ID('dbo.TrfParcela')) + CREATE INDEX IX_TrfParcela_DocumentoId_DataVenc ON dbo.TrfParcela(DocumentoId, DataVencimento); + """ + ) + self.cn.commit() + + def upsert_documento(self, item: Dict[str, Any]) -> Tuple[int, bool]: + assert self.cur is not None + uuid = item.get("UUID") + if not uuid: + raise ValueError("item sem UUID") + + resumo = item.get("resumo") or {} + self.cur.execute("SELECT id FROM dbo.TrfDocumento WHERE UUID = ?", uuid) + row = self.cur.fetchone() + + if row: + documento_id = int(row[0]) + self.cur.execute( + """ +UPDATE dbo.TrfDocumento +SET IdExterno=?, FranchiseId=?, ImageName=?, EmissionDate=?, + EmissaoNF=?, NotaFiscal=?, ValorNF=?, Encargos=?, + AtualizadoEm=SYSUTCDATETIME() +WHERE id=? + """, + item.get("id"), + item.get("franchiseId"), + item.get("imageName"), + _date_from_iso(item.get("emissionDate")), + _date_from_br(resumo.get("emissao_nf")), + resumo.get("nota_fiscal"), + resumo.get("valor_nf"), + resumo.get("encargos"), + documento_id, + ) + return documento_id, False + + self.cur.execute( + """ +INSERT INTO dbo.TrfDocumento ( + UUID, IdExterno, FranchiseId, ImageName, EmissionDate, + EmissaoNF, NotaFiscal, ValorNF, Encargos +) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); + """, + uuid, + item.get("id"), + item.get("franchiseId"), + item.get("imageName"), + _date_from_iso(item.get("emissionDate")), + _date_from_br(resumo.get("emissao_nf")), + resumo.get("nota_fiscal"), + resumo.get("valor_nf"), + resumo.get("encargos"), + ) + self.cur.execute("SELECT id FROM dbo.TrfDocumento WHERE UUID = ?", uuid) + new_id = self.cur.fetchone() + if not new_id: + raise RuntimeError("Falha ao recuperar id após inserir TrfDocumento") + return int(new_id[0]), True + + def replace_parcelas(self, documento_id: int, item: Dict[str, Any]) -> None: + assert self.cur is not None + self.cur.execute("DELETE FROM dbo.TrfParcela WHERE DocumentoId = ?", documento_id) + + parcelas = item.get("parcelas") or [] + if not parcelas: + return + + rows = [] + for idx, p in enumerate(parcelas, start=1): + dt = _date_from_br(p.get("data")) + val = p.get("valor") + if dt is None or val is None: + continue + rows.append((documento_id, idx, dt, val)) + + if rows: + self.cur.fast_executemany = True + self.cur.executemany( + "INSERT INTO dbo.TrfParcela (DocumentoId, NumeroParcela, DataVencimento, ValorParcela) VALUES (?, ?, ?, ?)", + rows, + ) + + def persist_items(self, items: List[Dict[str, Any]]) -> Tuple[int, int]: + count = 0 + novos = 0 + for item in items: + err = item.get("error") + err_txt = str(err) if err is not None else "" + if err_txt.startswith("falha_processar_pdf"): + continue + if not item.get("UUID"): + continue + try: + doc_id, is_new = self.upsert_documento(item) + self.replace_parcelas(doc_id, item) + except Exception as e: + if not self._is_comm_error(e): + raise + # reconecta e tenta uma única vez o item atual + self.reconnect() + doc_id, is_new = self.upsert_documento(item) + self.replace_parcelas(doc_id, item) + count += 1 + if is_new: + novos += 1 + return count, novos + + +def sincronizar_paginas_sqlserver( + connection_string: str, + cp_id: int = 10269, + document_type: str = "EFAT", + limit: int = 100, + start_offset: int = 0, + only_channels: Optional[Set[str]] = None, + commit_cada_paginas: int = 1, +) -> Dict[str, Any]: + cli = Client() + offset = start_offset + paginas = 0 + docs_persistidos = 0 + total = None + + with SqlServerSink(connection_string) as sink: + sink.ensure_schema() + while True: + pagina = cli.processar_pagina( + cp_id=cp_id, + document_type=document_type, + offset=offset, + limit=limit, + only_channels=only_channels, + ) + if total is None: + total = int(pagina.get("total") or 0) + + itens = pagina.get("items") or [] + persistidos_pag, novos_pag = sink.persist_items(itens) + docs_persistidos += persistidos_pag + paginas += 1 + + if paginas % commit_cada_paginas == 0: + sink.cn.commit() + + print(f"[sync] offset={offset} count={len(itens)} novos_pag={novos_pag} persistidos={docs_persistidos} total={total}") + if not pagina.get("hasNext"): + break + offset += limit + + sink.cn.commit() + + return { + "total": total, + "paginas_processadas": paginas, + "documentos_persistidos": docs_persistidos, + "offset_final": offset, + } + + +def sincronizar_incremental_sqlserver( + connection_string: str, + cp_id: int = 10269, + document_type: str = "EFAT", + limit: int = 100, + only_channels: Optional[Set[str]] = None, + max_paginas_sem_novidade: int = 3, + max_paginas: int = 20, +) -> Dict[str, Any]: + cli = Client() + offset = 0 + paginas = 0 + docs_persistidos = 0 + docs_novos = 0 + sem_novidade = 0 + total = None + + with SqlServerSink(connection_string) as sink: + sink.ensure_schema() + while True: + pagina = cli.processar_pagina( + cp_id=cp_id, + document_type=document_type, + offset=offset, + limit=limit, + only_channels=only_channels, + ) + if total is None: + total = int(pagina.get("total") or 0) + + itens = pagina.get("items") or [] + persistidos_pag, novos_pag = sink.persist_items(itens) + sink.cn.commit() + + docs_persistidos += persistidos_pag + docs_novos += novos_pag + paginas += 1 + sem_novidade = 0 if novos_pag > 0 else (sem_novidade + 1) + + print( + f"[inc] offset={offset} count={len(itens)} novos_pag={novos_pag} " + f"sem_novidade={sem_novidade}/{max_paginas_sem_novidade} total_novos={docs_novos}" + ) + + if sem_novidade >= max_paginas_sem_novidade: + break + if paginas >= max_paginas: + break + if not pagina.get("hasNext"): + break + offset += limit + + return { + "total": total, + "paginas_processadas": paginas, + "documentos_persistidos": docs_persistidos, + "documentos_novos": docs_novos, + "offset_final": offset, + "parada_por_sem_novidade": sem_novidade >= max_paginas_sem_novidade, + } + + +# ----------------------------- +# RUN +# ----------------------------- +if __name__ == "__main__": + # Modos: + # - "full": carga completa paginada + # - "incremental": para após X páginas sem novidades + # - "json": só imprime uma página em JSON + RUN_MODE = "full" # "full" | "incremental" | "json" + + if RUN_MODE in ("full", "incremental"): + SQLSERVER_CONN = ( + "DRIVER={ODBC Driver 17 for SQL Server};" + "SERVER=10.77.77.10;" + "DATABASE=GINSENG;" + "UID=andrey;" + "PWD=88253332;" + "TrustServerCertificate=yes;" + ) + if RUN_MODE == "incremental": + resultado = sincronizar_paginas_sqlserver( + connection_string=SQLSERVER_CONN, + cp_id=10269, + document_type="EFAT", + limit=100, + start_offset=0, + only_channels=None, + commit_cada_paginas=1, + ) + else: + resultado = sincronizar_incremental_sqlserver( + connection_string=SQLSERVER_CONN, + cp_id=10269, + document_type="EFAT", + limit=100, + only_channels=None, + max_paginas_sem_novidade=3, + max_paginas=20, + ) + else: + c = Client() + resultado = c.processar_pagina( + cp_id=10269, + document_type="EFAT", + offset=0, + limit=25, + only_channels=None, + ) + + print(json.dumps(resultado, ensure_ascii=False, indent=2)) +