From 52b2eb2529c781627d3280bc4b7d8dc149852380 Mon Sep 17 00:00:00 2001 From: Johannes Schriewer Date: Tue, 7 Jan 2025 23:18:58 +0100 Subject: [PATCH] Enable translation for entire project --- .gitignore | 1 + Readme.md | 23 +- docs/settings.jpeg | Bin 0 -> 81456 bytes inventory/locale/de/LC_MESSAGES/django.po | 561 ++++++++++++++++++ inventory/models/area.py | 17 +- inventory/models/box.py | 16 +- inventory/models/container.py | 17 +- inventory/models/distributor.py | 25 +- inventory/models/documentation.py | 9 +- inventory/models/form_factor.py | 17 +- inventory/models/item.py | 76 ++- inventory/models/layout.py | 15 +- inventory/models/manufacturer.py | 17 +- inventory/models/settings.py | 17 +- inventory/models/tag.py | 11 +- inventory/models/workshop.py | 19 +- inventory/templates/base.html | 20 +- .../templates/inventory/area_detail.html | 19 +- inventory/templates/inventory/box-detail.html | 5 +- .../templates/inventory/box-generic.html | 5 +- inventory/templates/inventory/cell.html | 11 +- .../inventory/distributor_detail.html | 36 +- .../templates/inventory/distributor_list.html | 13 +- .../templates/inventory/item_detail.html | 43 +- inventory/templates/inventory/item_list.html | 15 +- .../inventory/manufacturer_detail.html | 27 +- .../inventory/manufacturer_list.html | 13 +- inventory/templates/inventory/pagination.html | 9 +- inventory/templates/inventory/search.html | 9 +- .../templates/inventory/search_result.html | 21 +- .../inventory/search_result_item.html | 7 +- inventory/templates/inventory/set_index.html | 5 +- inventory/templates/inventory/tag_detail.html | 27 +- inventory/templates/inventory/tag_list.html | 11 +- .../templates/inventory/workshop_detail.html | 23 +- .../templates/inventory/workshop_list.html | 9 +- inventory/templates/registration/login.html | 21 +- inventory_project/settings.py | 5 + 38 files changed, 952 insertions(+), 243 deletions(-) create mode 100644 docs/settings.jpeg create mode 100644 inventory/locale/de/LC_MESSAGES/django.po diff --git a/.gitignore b/.gitignore index 31d08d6..db54a1f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ __pycache__ .python_version *.egg-info +*.mo media/ ./static/ diff --git a/Readme.md b/Readme.md index a06358c..9add83e 100644 --- a/Readme.md +++ b/Readme.md @@ -28,9 +28,16 @@ following might sound familiar: - ForgeJo: `git clone https://git.dunkelstern.de/dunkelstern/inventory.git` 2. Change to checkout: `cd inventory` 3. Install virtualenv and dependencies: `poetry install --no-root` -4. Migrate the Database: `poetry run python manage.py migrate` -5. Create an admin user: `poetry run python manage.py createsuperuser` -6. Run the server +4. If you want to use the system in another language than the default english set it + up in the `inventory_project/settings.py`: + ```python + LANGUAGE_CODE = 'en-us' # or something like 'de-de' + ``` + see the settings file for defined languages. +5. If you changed the language rebuild the translation files: `poetry run python manage.py compilemessages` +6. Migrate the Database: `poetry run python manage.py migrate` +7. Create an admin user: `poetry run python manage.py createsuperuser` +8. Run the server - Development server (not for deployment!): `poetry run python manage.py runserver` - Deployment via `gunicorn` on port 8000: `poetry run gunicorn inventory_project.wsgi -b 0.0.0.0:8000` @@ -51,6 +58,16 @@ go to `http://localhost:8000` to enter the inventory management system directly [the service file](inventory.service) in the root of this repository for an example. +### Changelog + +#### 1.1 + +- Part count can be configured to be available in settings +- Currency can be configured in settings +- Complete system is translateable (English and German are provided) + +![Settings](docs/settings.jpeg) + ### Screenshots #### Login diff --git a/docs/settings.jpeg b/docs/settings.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fa1ebf4af56d86e8c665c9df7cb5ad0dd1fb128e GIT binary patch literal 81456 zcmeFZcT`i^-anifbsRyRK|qwEGgJx1p@fcJM*>m;6HxN<0u^So=l??1oqS?8Q@_WthA_q%Jp zXYYN^*O9Lu06&`oVf3dYg{c`%lKT~{*yXzWs@7w*qp<~?Lp>OB_z<|nsBlCY3e8$Z^$n{uY{wLn$Kk=^j0>8;8 z9LpH^`ry9l`bOU@KI`s>fF0j|JU%4>K>%xj3E=l{`9J=BO#UPQKxYR4IPvt~VJ_JK zK=oq);1c)WVY1HvfS>*X0IGWb9ro`sxpz14?mys89$&xr@BjcdivWOgb^w5I9{?a= z|Btxi%YS3rFUL`m$9DN2AD#dofIHw9fGNNa;0jPZ=F|bd0n`9mUwMGrfD_+;qi@#} z$8_?Cli%paAAUIX!jw?Hc^( zuZqfd$dKs%V|a;Uy~n!$v-W?&pFWN>6guu3-+%w(cY-Is|L(-8Zx(*{z0iqYPhJpJ zy9G^te)p8Hh;+civbXH14Rvdni{{7QWk~%R(JAHc0>5$rXHOjGOz4CV;3lB&@2AHb z)&C=Z|3BPy6SX^bTO<&@;f1KUe(DR0X7KF2b8mxhR&Ik4?^Nq<9;Q05Mz3oD|9V-E zqFs}Rb7YDivuj}7*jWf{OZOi3i?Aup=JZ8k(K|}PU)9a*fQ>>FOJ1f`{^y5UY`5CU z<)P?KUkaUKtY>NVgVH!_kYi)?D-Z}Ikw`_wma&X%s#jc(c9Rr}1fo9$sQ&%mWpJXB z*6LSjyK^3DU|}Yh(Es)Xdy!$&_K9hkrcrt^K{uA+tD%*28ASv#M;fXu3U4iJ2HvJ;%ae?T|K zWsF1Zt?5Di*K8TVD=>uP&$070iAY20FbE5Wv!P~SY&XovGT^Nq(+Fd)0Qi3KA9l)* z`Gmw9iKJ`m`+}7b9|H$_GeBsI-Y{yt;`C#AmUkA}Q+Iqii|irqqW$Z!x_@Wxf6B>m zZ%zz4@5O!vbp7?aW8oJ*_$weZ>GS)bCFcXtLxm68bcS1v)Ww1FYhLSnmoAG2u?hHM zzH!m{zrY{N-c&uYOLkDa=Sbq1hLw%Go57=C)$@hvE39_cWLzK+NUp>7E$()I1-vxK zIXe0Z*cU&#?n|w6%cw;NA_h3f+alrN=}vK_YnG`CuRa%$X7+{8Qz}J^f=-Jt1l=k18J5_Be?);aL$;} zMNHPj^@vW!`RY;ces4Poa{A_-1h;^q>4>p8BO@zxCMc05_#`dnHq2}r8<`#?1RJ8q z;~v1RNzG*u^Hy>WTCA*M#b4sCIwPPrWvoOZ+KaBOcSAKTfz;fe$xr4C%r-u%sd*5A z2?mNpvJOW$f;(_SsGE`boDB{zmRcr+PqPiAc{QQEk6vfG4QH|k2S-aY^t%S3EHvIc z3T>`&X|j3NFRmf(E8sl2HfcsXfrNUkJUCXD22UBf)6ExkC4hpL!-q%WTFkB7Y=@Lw zxKb%3sTci2!>kZvE=v5evm|96sN^V9jfLEta(Yxcit~BB>rEU}iA`?ztr&MNntID1 zh}w^nBrE2+l>~pfQ*@plP9fuqiN(a52pEK{a@jqNmlTcJynhb%7~Wa}K~)IpjY<3S zH?U7v0}o}ptKrUN2lkaj8I@EA@pOT?MVF!}6V=AY2$B9ZBzFZIxm%mA@qtQCcF9m6 zCt{LApX1Hq<|sILh2fUrip+~3W?+pC0^#iU@&nIZ{`TB=e`d@Hx|DH56+2CGP#qS?WBNI&&eLL@kd;c~^1`Nac5b4$sgKWed^h(1{2oziz`9GwW64w)qu zYt5A(a#R?kEw37GX(iTY4w&adopU~6xKIX_Bz)fP<5$%{<*J?tH!Dh(R6|F9q2J-X zmCg5ExB(t`87}-;WNFtVgjT`7^5(!M9F*SI*VFP@9jwu>&4djR^|uwpozv8|QFSjL zJAl=~@G1>i4f~T}u~TV*>7J*-Z(EAM&14UcVd^0{%y_kQ9euJELY|2_9)(pjlZs2I z;U;G-mLeLPvorf(+;UodRk~&jk>yor?nhhK_t!FJx*1R4U z3+q^upc@S%cCYZmAsVCuBMX=?WL>{dX?~0PCf6YBO;%kq@49cfuaJ-5p23Rm6Pec8 zT1=sDR}E;OW@6cUas5FPgPd&GP(`fSZC`SCcL*#|eT=GI+;-H)?k@X_gd(qdl;BA# zOnYBLhygw5!YD+=K5H8e->&~*IerBU*B)lGZ_k}hbqcGHvo|~inYgH1C#A2*?hei$ zpBvtU%@uDRsS@HGK?t4XVvtd{uyKH93+ba++)%<^n{EVbmZi2tK;aZnieFHpkga^! zMH^bVQa4abaOhSN3X>l@-#0WS-ku8Q2)!p3iawZz>z5q01+@j6#@jKrJ5M1D`|GcC zLt$Vf6$rcs|3*t-C2?*Cjo`-F8E8P`pOmD$-{CmSIU?ZYLHg zbaHw|%cGuY#W3!?hRPslEx9l7ZL}yn{R3@Pw<H~5TbE_Bl~~Bk)^dm^|E(OBInaJP^CzHCgiMN1{ojCl*`wu{s`2zva)ho zE*_jp=*(Mq;)3gkDQmSalp@VvGhVu&w?BUhPmSZQ8hhX6k`3GI?K|KlmdAaQ;hGG6 z5U$AcIk+}e#}~LnB)Els8K)a98W}nMywtzltzc9nVbU+J26DlZJhGBFP9@E)tMt&I zsi{9_!s;9@5e>b`K^ygJgKBjWa-GF!YT3d0;IzP|vk92g2jK{~U)+in7-2IQN6lN& zGK`|S^`ZQ$B=TDG5+gH~&F0&og)qc8L^Hgoj9PTJ;*gFjbl3kIr5dhx#@#+rU{^KK z*l^uM`Z^7cu=)r(d%m1JnPZDll*0zL1(MnCS@-P3@dY(dgxIDv$J+_oMl&rHcume# z%!+01&@HU!1~U5YMAzef+w^uTt*bjAKe(E%mYL{aw;}G+;FGUspiVV2uOMZM&nC;j zUDObZ)W#G=3GtTe+3CJU$f4F^EAc@De9$bpMbOYcdF?}7vFB9UM*qHv!_v}>v2jOy z3aGfRfPKfCr(ZX7Q_;*K7lF3hbfV_WUZcn1vm_q{DO<9kx6)p^5ND!*VR1Icr71JgTdftWs?K(pEHn z31=e<^Ca>ZIo)uu(T9c%q6B}yJ<&0JR3^IiV&c>SFcX5RHVdvodgYXuGTGb+N}a%- z(&)}tz=deR$JVeRdmzV}I0FWnTLBM++WYGC#K2nmdq)pHJ~#r|e+5KK9yo?uCNHKh z9#|lR<1ovu_v!XCDr58w-$%w5MQsPCKX3>A8Wa2quK1$ae|H<+Luz%JOQG2a6B7j) z4F~)ltr|hi6>WHw?${SgOn7vf{;J)?va_DN0JT$)e#%?s>5s}&au`Ot)J1&mxx(-3 zIHOw7e5>0^B;xaJ5qfgHiV4f;e*7}0w*5%{q35%jv9-#|i?$va4c;hja1-O8(MbTG zCyrfN9)R_;EAuoYu3jlIo6a>*tl}S)K;}b@oFC;}J#F&tZ4=QuoAJ8g%S2_X!-D*W z@uUgY>}#sJ^4hloLr7fl_|yx&>o_iYsCF~(c|UtfEYodkdS{JPjbzszcnovY^WsQF z=N72aRMK+(pnh?1lxtP50=J%w@&*<G;x;LG?wAOMKhaQA2FH2u?(jUd%|p+CH%EO)eOn&Tn*)Y8Zd8T@ZY3XHc$(pbp*fF{K2}YQ3~LPb=evfaHJ`C0Aplf&NWQAL%gRw0- zAcPR4lrFN6yD@ih_mj}0=Tl)+C9(%5Halmnj;DHmH|oH!3y}a_0kC zPAJZZZQ$~b(_7Z%s?@c%FLi$4Bc*svRF$Y@-UH>M57IBlK^`;{Oe5azx}Id(ruR5J zQAke2D?KXS2cksaY)1)4TK*SNsASzu*+o=Ws&COt+Uo)9VdP6GgMMbpppxj4Fam3{ zRwT;SSqv2kyKrwq@lC(lN~u6>EQhHU8au96+1$e)b9%9F25iZ7Fwpa6c3jkOF0rG6Q8ScKihj=tZj+9Xm1)>@8C684ONfPy`Xa$=+|IV!}ot#OO=7@MY;O~ zO)X;g?ZvK&=b;q~v}szE6Y<@AxL+Mlr<-ZJ^=xVihM-dAYqIJ$snXib>m8wVelG9T zmz?>FhikA*E=?g3?k4odou$$9yObsOaQWk$ISPRsZ4!x6=art?QT#`l2*(H+{G1nS zpuYx+%`kXKBqx6??OceEG82c zFrL4(dakvEILNwTEHqGs?;RdLDAO zXCO`^d#Pcle5TRx?OKbz->}8QEp^Q>gw}$n@q-`4Z=^e&(*R3)$bY75$9x4uyj6?m zw?@n>=8b%)LKu3^stT8giqwuF5w=N6Q&tl2qYHlwq|b1?QldEzo9&F0)OC zZT`4WA6o~F#Sf9|qNJics$O4|P;OVb!C77UeQwyU*wgoS?ZX%7YUj?#Prd3nCwDQ( zpPp2Cj`9WeClUJEvL)09r#t9J9bU1qd3skh9zSu)e&O{gG?Y1PDP^-m;l#$qCCqyh zynEPQ(YrfJcRspQiS55tKc_PuHqOf@(W0%Bzi1jb=#KEo0JtGPme^ zwcRaFzgSY7Rpp?qj~-MEHG<5$q1Hz`x=lf%V(z5WUy zUYU#Zqvf#&jarU6N#iz3sfBEg$f{P-{U%^=Si+1>-dnT*8)iLfZLH*WpM?Py{VtPN zM!OR|5)#X2y247#;!A2%sI^u$ zCwGaqTBDbo2$u15Ej;tJ(*bvA*SX@RRcUY73U~(>#bq`Az$ve#H?&nMiE{aHF4_$B zBC@|m6iOI(QYsRzYT6V8HLT|hB5m44LX`7xtC8d%EO&K%a*|eGOn?AO z?li?Eu`ec8+ys>-x@YmPjQi;tLi(@qgCI`xaH>A;{ig}S4yFZRXq=3n9=xmpB;^3B zxajBOwlbv%w;<9={fjs%2xj!5UT=E?v=KD5uf$#|Fli>DIiwt}0`R&IStW04wV$rh zV?&R(uz(;CK3@TInC&Wa=^2&kv!mSuKixOI6JVc*Y9Hd3y!bZ{zaX+Xk%&gu=I72K>a7Cs7F#ygr0b{6zGwLqDP!ERvT|PkDS4q~JST%5=MuauvB8>p^*CF{+&`=Is3YhSG-S18L~7gDr*Y zhEGi*wdgb%%X=_;wco?(d-*8?RW!fC!s5MJT z9qI5v`dc%DI5mil=nO(fvkR4Da&}tYH!QYu0aw(a2C`JX+m>6f?>WR{jC-#KlYN3| zS8$jM(}#!X94pegvg!BQ5rq)Y2VAXo%^#y%yi@&i*4%Iu>XSRs22*$`k%Pd3-UP#D zyY%jA26QMLRyTf#%;%@`iNwH0& zYl%W0m(qLWf*d|}0mR_{8^`DWO`78goqT>2BXQWRieocm!7@3eX_;bjf1W7{c_ck* z+#jI#lb)L`WFm&3X=5d)QKR*M8;CxhOpp@j#x`?3L51g8g(zts4&YS!zs(Tz>n_hR zw!7GkDJg@9s)Au4);5195DYSiU2>+b)Yc0!jTW~>&7M|N1u#1-t^+y(^tfl1feaNp z6=4ks*L3#rhQ%J5Qs)vV?G@j0Ugd_`=P^X#5v3r}v6`jn4ALRKo+LYRw%k7vs^z*= z)3%xFE`yi0u4|>+)QdV=4^?F|Ld+KTbP=GVrux4mcE8UkIW68eQss^aO2nmZh7Tn$L%r|b>mcm}JG z9Lyr;{v7w9eIudtatnQD*nW;xakY}pGQRDD4<&~v$;Qrx52`^8HLaSK4OR^d)j^T` zP3q*Ki@bDTzD5o!K-0U9?UfyWDDR=Z7)Nx;z^L|aI7CN_Rh1u}3R-bk5`}h(bYnEZ zA96**&xoxUD^?u3lkg4iGkN?TykNTZ;Gnq_NYyx4 zftht}J_`&7F~=aZLZ6{B`qyRm8Rfl@4EmJ4woWKOS}!wby60g!(4pr{tny zK8#GKl&3qzrl{NQ5!=PLF*ZgKSoknvQF=^+29hGRJ(&^V#Cb5sQusDdYl1HrXT8RB zDnZj+F}CAF6=CB*>fCTNFv?@6c`jo;WN#uiKCd0OE1PvRVpl6@FA-4P2qAoz{Pn| zo^JtW~ z2DFy6k}&1eZMzn#%TRU_77Ue|-t4ci2Xp%>6KZ`XBBA|-oH$L<0Q&Fp#HAidehAL0 zX+2;^%1_asTQkJgF8W$pji-s_voE`~P6LcM1Z5^1cNk~-1n?N%UeR~P zmOVkatU~W05L>%C+{P*YkxHij>mH?Bl}hQ+EihGZ_E`QWH+m5sWlKRUuR&G=8Jmp5 zy;Lxm)6n#mTmXbU7Sbk?W0Txr$RORGfXm~n9OOfX?s8_x?tqYf`M5@U-hIw4jNnp> zXju#x@eEc-FOOzC?u|%CUUnLK-@P+aM_l0>MOZ%R5I*zDXA52J0J~h2A`vC?3)UjV z=FY5*(eU*bYf3F}p1Mk-t%iaAxfkuqDQ(FvA+gIm&^cK(n2Pir{9@K1eB5!UI$Bzu z{`(c))|UkSjU`+cA6}EL1xCHk5y44vuB8TuPnrtb9EmtRUeaQFS~isms1;LPq$&B@ zJs^*$o=7h?ja<`|Rkz%AZz1&e&4ke^!wUX$URi<`-s?jN(|T~zKf7Od;LZYRk>TtV z_h$Thj=_jWSNUp$yImfBJ*;lb^`UBYtRLniT-}mFFg7Bv`Dg}>N{%BPIG!2gKSAe+ zbE7bUBiEGG*~cLyZ0%7_lxp7K;$G^*^ecJDA4GMMkx(SFy6Y>T?S{FTF`@ZtpuuHk3+Q*7d<=DTH z!o$m}x(;mY(26e$pWz%r+JP&Iz-5GlWx7b`1*4o!#-i4tr5>a|CG z&ofd+v#o=43ygZK%}x@!ar)f&PkW+-;U`x;DV2eam8;wqtNZW0VHX=X!-LiiqgJLi zwy6lmUjhSz?hH2*5=D$m0`JTn&)QEo@?l99r5(vmSEOJF{?(#{xrmMV6}ERDaG0Tj z={a&R5n?rtKSQnIPTgngJcH=d+>X ztk^eZ&h#wvXSz9OdBH>}(`1Dj;2Pz2Y`Btpjj9z>>4wDtUR=_TC7|SMjnJ(d&WP;7 zj_{YvM!c6@d{0>rFvQ`SP8#o1=5rlP zAOD=#RUSx6ONA*Bb&yCkCr7?AJ^54ydCh55HljM+k*YwBB}#8!4l7U`ek?LU$s$X8 zwmIu2eW80b_ZiG0v?@6d+|X+U5v+P2y`-N;=AFaZDRLfGNwW#eHYN8!%<&E!=q)l=d9vQ?a<}pWh;dH zvY%0cqRW#?cJ;FCb#Gr%c`rpEwb;Pa}0 zrKXCSf!2amk*-O+reo6Akn8Afv1n4!t52gngIea%s$oegSL|=-XV@23zuTE#v6l$B zlA@Fe_h8kBV8NgJhA$BGJ`ETl8bDF`^iRA3!A~_5+VM_-B2oLq>IZ_G(<`5IwC=|7 zZ(ghEo4e4f$D^;)URK@u<7q>K(bVfCr)zOcpJ+6W1&`jH+S0} zMR0^uy1!Mabv3Vb&?g7ht&%O3g0CXx;|Cyr+eLsVJCXho=`b8Zb9=y2zNzZV3m;E( zreKUC*qmrRD?9)`XJ8!!CxKmLpiZ&WBSN@X(d|sZ6A+SSl&}9jW<7WPVne|82DV3) z;G7p*ea`91gdnPOcBz~-a_`XB@=QdE0sh^}W88s60zG;XXvEo0MwM_79Ta>qyRW$T z#p=zwhrjh+)2MP2({+?0f9Q;&E=m1fMxT?M2TPN}RXMyo1D))gIeRpj+T?Y&(g7WC zh)ebvJ;!=^scZ<;jX`{@4nt9MXyjcYiF$9apMMB{tJWpsHGypRx2L&=a*p!bFxBP=^CXXCC|H#{z<#UpiC)RHaisTBUw2zY;bgoK6nx_G z!m+Lx;sf#i)h;$e-*I$T?&0Kb^ryC^$=&JFEx|PtFXKFBb-n_?5-!_Vcu=xUOl$+w z(Hhr@w!hpJ9Ps4sXr8?HDJLc4PZ!LcK|X=?hb-zQo?5&}&J`ZIi@cKO#TnuZ6ZU%; zB@??@IT*k0dL5$F0&2MO@H#zH&}l+Ic05(0%wg9o+mK2$cJkTt^TZydJB)hI`)yy4 zv3Z0Ia%veE!Pm>z2Op};ulQ$uUh3U*-%8TA-B;nSFYZfC==mL~tUKST^m$-d_U9g} zb*`#rEm$y54{T>D0CLz<H=0Pfy zwG5(tjHxMhN+q8V2=1H=`s&f<9VD{a@-JhMEq)TUjy8Janc&wEU{U_ILa#1^wR*7q z+N>36HgZ8R#C7TfTY`!i7${oTQ^t62u;=ZN_V=Sn-s(#3J;@hD&@{PX7bc!X4OgUM zill^}wZk%|LcZiozs7N=!mBtlke z*UG&0IlNQT^M2Xm9pz(eEnCzr>}t7f#2-GDPI9uDCJQ(UUx=E$LlF7jU$}m zQYy*`)pjDxeIPEgND}8G{`9yR>T%P#qG)E*6gg}?7?eGcu1Td5N%cK$#AVK;N8CWu zD8+WJ;&w3k{%vy@)OWIRWo%#m-ime3Ri5gBr*#xWG77ZKGH;6z(@F(kQZ|vl#Jq# z+M)=mdEH>LsT`b7yp%NzltGjlIsG*~3o9O-(7oGJp2L^;?fv9@=ea0%IaVS%bBjoU z*|HzJu#==x<5(O>l!Fx>Lb3DS-I3>9y=_}H>@d%`BSfFuyD}^-Ph4ARG4zC1>duWgm0Sjhn31@J*z#OLZ}tusB+H_3~atXz35vFW+xGbX0Zr ze{HYo^Ri~jdPX?#+L5;`La2t1aFp#2(H+CWr<&Mb7Q7$24uyB#zn$h*S#E_X#L$S~4`Ku;P@4K}&!>#nA`4nf6l0&PoQvD@qfNf{~S8DKV3q@QW0 z9Db0FqLDtbv5sQT4(pmKjK~biD+hJ$!S{3&5JlColf1@&%%&ha=2DH9V=1j@7I3N0 z8*Y``8*E=Q`9+#w+td+MH}RQ%vHE`Z^2aj4rr=EPD!Y4;(S_nPTyg(ki-|$9l6;Jq z<(i#1B{nfK7dKTjiyb*S<@(we_0g+Fw#-#$mBY+D4O*$=>fr*{WLP1&lp%#u8=>om zx2nd2U;6YYE-jDV2Fn%q#_{S%FE#%tJCIh*MJjl=4G|Y1hyB&|lptWdsO)O3yS7ns zIULp^8_-ucF5OC*gWJ?BkHf%5#tOoEh2jdTunCv(3LH#Nb3l7Rcr7-E$J2TOvOSei z;CoT>?$dU8-KP#JThOn7JFL!I*1KM@M|n`uF2pVqlBcDSz!+H_;>x8o3N&^jxi(cc zGSiW2cS?(r+gr-jR;?yD=!2f<98A^n!Ur*j#F#ME5#Q0$6ttI%t3tJwhuH{Q7$?LJ zK9KezuwjX;lwjwo91pQfM@(r(2X#db=MHYozqA*IMit3$+r{yeaYPbQ7c@obQ*F__Hr_iPatn+{t%gQvIfpS#an$-@^V=TPvPnMvcX9_)>~ujU zwei*BLp6pf2%Hf+_^guWcGyKuS&5C}Xnm(tbOZ4v`r1oWR?WbuWG`lB?!gQ6Jy(QK z4+lkSauh~A?8{XC)a`1NRCEsitP-z`!y+1>M+PeaI}EkE~645&yiJ ztJM@cQr`7_c|LI+=F>z^hih2Ls+EU7=}HZU#K|I=LhhECrN3u>1<>;C7B)Ir)o-?v zy>|jXEv)S;eV%3qRSe!b*Xx-&-SK6IAQ!^`QP4p7;^SEp?9`{II?G|`!4<P$jB%n5dMj5S z^0C*8sgxMqLX_=J@bdb)zivNJ7iTF!aKtH$SH%%Lg6mKPx=duZotqh6pqRfTA}A-w z!~!S8{hRk{ptTf^kr4-ku$az8p(oSac@H|r`l%bhqHC4w`}QvvCOiuOcl@F9-F+3IyjAg4do73Yv2(j#*S zaB%Qu4J?eib{H^TA&E``(BG-on{?RdFRI@~ggXNfQyrOU4s;Ajt5l z3uwkhWzx2b*40xLapTdqfVaZ?RK4i_RLp8gu|zH_;BB&h-sz;i1$cMFLb zs>j%?9%$t177Wr5Txx3qc-&ElOWxdlz1!)0?vXmY$)m$Ri@%)DlQKB-$NZ+>oVCf? z-)2M1C0cBZ2A5LhMsYV_yK92Jo2ayG=4#pdksJ#yeKwH9@mI>bppP)#yfX(8XIQFA z5Aappnm6^tDq1K$f=k-w5+3w=UG08*!_36)|>J9eR20E~J`EM}lpRI>2Q-Iq$Y> zn}*MguK;Yts6lU7+pq2s(?ygNGc*+(Vf)3}Mz=c|&*wwAzcf;Z-fB3r(tZ! zUKPG$<8z-p9`3HGRztIwjV#cK6J4U}Y6cN&8#3zkh(YDGKY-%L)k@U%fZ6L^ZrXwb zAB!UR!_tX6GLMt)6R9AFo$%#cZ5X};tW%w{UTMz@Ys5&S-&Vmc)=iFjRX6PIRUV+c zSJ2N3UlQDiVG<%fMjVF))!4WrpwF>yI-=I~^3!;c}| zII_a9->|cP0k}+?z=W@~Ro*AMmh|@DP_^Y033!BbZO0ybu{ZW7@K#q_?9p-EDeHI1 zjDoOb{?eo}9RUd!Hr9SPGHL(lZgtG`)^t*xxql!STasU8o4@}$knpgK3L>DF2W@0_ z;GC!!gVbM|HuWLV?llwF)`Inwk+YAh7H9FMu8~P5fpxVAIwD-*0|H{`$?4y#C@G)0 zV)8U>ck*7g&@d2vO_~TSh6+i^1{(5hL$*0k)E7|%Y{UYClBSg|H+K#EmaHY1Xyd1 z;=*KycrvS~`|vtb|FnfV??L1EjM)hFSNjB&7`;0)uH59-<_yccBVbPPTOFa5=7|CQ zM!E3MV{OG+lMno#Jfb%#SLsnB7$&K5MpZmzwfe!zbz@V6X5x6F$_{wUk44KPF$i!= zC2FwNVX!W7)ZY~SO1(R{qW{Li)nB2?PX}SG#T{ksO1boKP)PE7mMWeY0M;wfmtk@* z2UN^z3L{3>f36ZwD+<>Nb!hW9(L_^<>o_~tPfJtp4a4(0j}#L|Rnu(K_RM&X=S4}x z@+zX9$6GT7Cco9VU3Ma<8YpCQZ-*SaZ=8~84d{BpcNPNs}(I_O-6*4wkC zt~j??Jh7EXC6$U!?)UX?mzf9>@36gOtX$#=>+ z_k|TS+ST>lLL$aT36^$cU9@&s>sp2kRA*^mV8zg8w%yS_WmW7-$$RR2O|NZwHzk9< zqV&=-OdlIq>liAnaMk8SN0_|6b9Kp;x0!dLFN1FV^-;wJ;`yjUIqiYpf4c~oQz*FK4%zMt z`bW6X-^;>G7beSLQJRv6yJr66zy4HqvJTr@O`C+AzVRg`XX*JR!CPVO#KH_COJjNO zHSOC!p9s7fVBUW7L8|K~@4^AN#(y9&J4gQucBTAgYHy<(`M^u}ABaD`K?!zP{R8&d zKb6XS=XG7t;2)YF{nM_5Q_t#N{1>C6|2Hu4|Dg%Rhgo_b=lC1)-@pGOB~u{H$jJ87 zy`$oW6FnfOk%oAKAK%2^3Nzgz*i>C7^?tV?Uh3lv&OiC5%BeYpe@UFqMc0=_T?`fa zd!<-ffet6aoP1d>oiTF%W6Q&WCFq~kv zM6k_%1yFtVt=0vG`3<+YG6#^WzMJRSSNpx66ue|Fa!Q^d8~+*Lb?E;zIQA&jq~OIi zdgu=&=c@hFUP()uQPuDDjUJd5_V$N^FxNy&d6ADQO}2?Qc(YQZn=jZ4ONQdiwEv3k zwY8m3Ky{qL>`wl|7y2Tf^e?cm11n>?`}fTM(Dg4cgD(n&$nuA%FaOf@FH^7FPi52W z{zkw5FJ1oucGL9#82*1s{GZM8|1_2Vk2`14O+WQ-1IRzRxcxJLr2pSe@>GZm$&SU! zNR&3mX1HTS@q-IVIYk$1e7qkylEXdT3+i2h!!i;Z@}Cc;yrUAUJZf?Fs~kzV}vZqgl7@b-0ZhS9+0(FYYT|(d(CXaoMPB9?*IUFgqT~&iC^Y zoEf|EFAsRWDdB=jF1ScOlJvI}T~v#s4T1xO#nhj)Xi*E3miIV*-R|VykG~5L%dfsn z@nGG)WqqLMS*1&r5YD(Zw*GEdA0lJ}W{ZYClsv`-oG?6f3fEsHh^tCOQ(2iW{&;&9 zy)PTih#g|;P)o}IZ_e#0j2I8!>l8U&(0pXWIp^X!Mf^ghFnQ!y8fg(SpuDPqPq&q1bh)lXG>k*<*umWX=6v-vXa%4Hu7H0_N`C z(w`1AQOY52f;x!0F!-<~;g26b@UMN0jA{6IJ858axo##1>swfq0wN3q7Cf}CCsWp~ zw}n)X-}y9rN9F_;VMVbitjnZ86733y4aH8q{oA*X8T{|)#DmQTUjYLi!r%6$Hul8q zrLR_8EJO7M94j`R8UYBcoHzYUUl7*sBiw*s( z3Z1krNaL?+Y9hm-_57{y6W+GQN?|-pPDR&8V9_fVb=VCw(9~KHgH}LmT}ob#f6YPa zBA_7lxeI)}Pov>z`i#NokbXexnhxDjLlwCkA3fA!sJRwoCv#<<*&V1$qk0!TINw_9 zpOrr8l|ARUe)TnHs%GV`yQ9XH_bb0(O}~hgIH^paX|I8cl$q!6gOe(1FP^fm7*9oA zPktLkjUj&ws5cj;%DDk)BFa8@2pFgXmDbP7{iHc;Sz@)b@APFNLreY~t{YmbzunPk zJyl+yFwCdY{u~S)Ul!-K)}-x~>gjgBpxB0Rn;*hVn3~g!U>bE>+|Ws;tfWz(N9<%9 zW4DtbB!W=0;W!|%HBB9xRzak3<7O%~(FhWLhrzqA)c{lD7j;+vq*-1DyqJT_oe6n5 zyFCyQ;`l%Vc3c7I){?L<<%|rfsd_CM+OMbSm)w}?Lu^DWvJFumg`POTgv07vr zGMM<<&cx{xkzi8el=G36EbKVBaqXbyS0dHBcnS->VWOuq_GQNv5h`61j)e$Yk3i!} zHJp>$6mA&W!i>N|ol^zpeT#k@-F`iu*qOmo^~RPt+s+ozX2ZnFgS|W6ecH<_B+~lv zl;XBcZNt~N0ofqRW?MC0*d-KdqA!ofMe>2V}m(?AY0Ck(X zo%4fmKKCO%Zz1ckyNX4+odsN|zg=8A5EN}w&pTk$LEFi(g{CCx#=PRf)l0DNsoo6v zFspaSsA18~`)|cgJa1PMs&B-~hgO*!}QQ zv+{0KkuBX6ss(;HHbspI>1Z6_zF<@FJ%o8(n2q!U?{f-X5yq8s!#==<=oG5FYcNpI z(ael6Wco|Q*n$Sw8GLLCOOZ()`&g{C^VC;>!FJZVo(eV;efJPrY>-yooB%&=2XHvp z@&>8QShi)ofX;PsW!&TDS}1iPg#2ylED!?`jV+M{WeL%9k6kWU+uZmlhxaLvo!@$3 zaS#$v^fHd&*lO5bB)Z2XN4;FV$T6v~ukwbJA5NUMbD=)0Bj84v>@mf;;AJW>z?I8F z=UvGx<&gXMAD{B`cPf<#$($;sRTy`f9xp#r$KBoZB~WvPx?Qxbki|y|w}}qH@)=LS z70b#U<_Vm$4-~_wPg08FL=mXgW@5cfG6mM(aBB=*yb@pE7xCcbn z*Hv`yJ-Z%lYn5)z;cuPlykg~-f_As=jnBK|QT8{ig7NF-pklV1k-FL@5Y#SDhr`3~ z^Tl{gDi)@(^?RP*=H7D6Hg>+4`}1i#km9!Bo8?`e5;=y=el^FtGvrCWQ-d4hNW6f! zc1`;QX(q#_J_KRoboKQp-(GMuaDLBQRa9Hy?v9T6<_b2q=!-{&VU#?z=yW}Pm?XX7 zBuHh1s3%ve0y{1|_(QI?tvL>Pv0M*NyBZDL&xg?>#O zJwNZ7F8i!Q$RB}&It>TKS=?g0;O5o(F)cSp!R$^2t5k{-M2V`dj@iFXXTSU=c8s9% zMTQRjh%^t78@ubQVfy&ne8!fD>men6LyMAk6Sa~%n@lKuyPIythxsU4xfek_| z8p}mqGAWiq83j@`;vIt;O&Zdu&scoAg@M``*Xrp4QxYSk8kTwcARZJje@$JerD`H) zt^wU%tREy$Qsb$qMb2NGMQ)zFp#?MYyr^%!A^(Q=i&fQoemk(DrXs+vnm=P^lLXy# z;kwGpB;f+!7v22E*?#qtvsK&iwFxEmk&O3M;;*!v6YP5@uixt$A7i0+knO{FD3u@Q zL+_ALf4|l=vCK3)!8enM9JRN?IE^S+#X5pQlg^P;GRn!-99qM2B1{4{E(+o|vm#o2 zoRwN1=OvsU1(m60)~d!DT6Q-qe_A+dq-4I@-U*g)ArF0Q`q4LLEU7gl0cM`Ha=IV71R_R_O{z_K@kbKNZy=Gbcw^SeiM7zqsx<^*evbugoQP1RS~h|uMkd5;tpfq zXdC-tSy8W}M&lT9ZB~O&APB_3v)&Al<+_Vi{9n3SNJxHCW-Se3_wRM;p;glC#s2bJ zC9Bw5gyKeojZNe2MKxxrmTPzSppkV@_G>a};KHROg@*b#B$8H-!tb3(6+!jpyXk=B| zw*Bx)>o2h+E#ApC)|~nMRvVkkM7VZo2LcP_m~Nf$t&E!dv%{o!>(h>xNQk*76g+zK zV%OMlo8&hVJt@@;=apgsHH^a^a(i+`BtFT*m(5Z_3I)8#a0%=J$T|~*d*DYJlfr6U z2Q332g*+=Zdls@(0qkf%(F^u3jQuc}9BD`O%&ZIIFzJ_Zc)hMzpO3icG08`t^V%Ti10&&a?oH|L~KpMRZGOV9p3haLE(51>u zk>#m#pa`cet|7Q<`C4Llw#e3~zdfNJx}%@{4yQ~3R!VO>g^~_hL}F84|Kks9hMlh1 zdEF~V&cOR@%d9R6O<_<31gDVSw)Uv9=&feM?HWODa2>b14u-5+zY4Zj2++_%)`zBH z!QlBu?8msM6}RgNzH+x3Xa91R3&06Y_J09#oraJAsqTC&C=JSGPrnZ#f{BYj&Mkf(Ypg9Pgr!O8mJ2I>47E|XXmBARZ z&K%l*lz%0+Vn{1ErE}9J1GzvTXt7icnGbhgW>o}Sq|XfT8iTLY>lI95i*p7_h4ANj z+iHtlvVAb8#xOOc@0YWDUC%8xS}kc`^F|6l)vL}z&I@N6Dg{krL!sM6P0*EM*>{?H z8lj%jlsaf;?sU*`a%J#U3$mK*5b|1xt{FX-%Eo+T?KMSM@3Bq#3%z^`?cAdxDk7O_ zumYk;7vf16eRA6~niv~CA7t227u4abp$QwjC;41XIf0l5c{(_2pxpCn#HP=?ax@Tgq!YSpW2hqD7l!oNCBm!5pZD)xAa`U#CjBc??ZFm~Cqzbp zE?T9zVz@a#o>dG7MHv1AGM8<<;So|H^9ysrquB#uZ-Fc?iEGHFz*v*LfuUn=z8K!`S0*)W|b!>2Q2hcukX7>ku zwu^3uuW*Bza@%Q|?YJc0c`H$a8pY&#?GWuV>t> z<{I@E8e8(hp*$`&V>vQKYK$%ef|T7c8~D7Y(pTy!^U|C1hwHo>nlTJx4_ky{NRC}P z7|csE;>S%RGqMPDm2iUZ!Z@kbUopacRx=&ihFX<`auoG*9L4X@HvI(LvDJV;&a=$-JAlehYgRO zbwVbECO5#UmY2Sx`w@Hc?fnin@-DxrZC-=>*H>uPQe;d$2p%q!;^@n8pF+Gs(cPO^ zSE0L_K8!6>c4v0fe~{r=YvPf{ev{MkYgt(^(npcl8(htUw53OAf_Xe*b7IOf|DK`_>QtZ~Wp%Kh*vHU6|%CVy-9eiOD=0 z6#Ks`(2Py$|am)wQ-x3+Cc`Fic#lF-3 z!|9e-qx4^5+DA(+$lw27`)KKd;qY7N)aIf6%l0uCtWrvlHu7F#a1If#o}$mXd9_(A zj)?dEM2EqlP9(9TG-`?1$v3`Y-+vNSRPSq5hgh|j%LmL3IBQ-;%g1X-wywx`l-(iZ znt&OarL!SzwVw6SSoF!fB+Tg`Kr(cG!i<1ARL1`!*JiVA`mvbur-c9K=ldVG!2jeK z<>EX0JrnwqYue#|o4BvCtLX93nL2~Xn8v2*|0>G+E?o0; zsOYk=|0~CM*LO7T3}{^oi~0(nPf9&G0YDQ zGd=iw;Z2p7k*UKE-YrOqo@zxK&|1%i&V`##IU0N^%a8c^diS-k>kYXW@ z7m!K)Oc#Y7s_EVFyX6;tF>*$MA8}K&ZLO4 zN-V3vwv)kNGZWf1|KcqdKV(`q+8%F5x&@S3VJJs|-40oSTi7$T=J$5$$&GMRki^fN z#;jl?lYywB-)^-0l3&I5(f)aZKP2-ZM7~C!a})x z)FX(Xg{OCxm*a3;;N2&$)*ql@6Io}-e48T{>GsA|9X?K7B|%UlP$$Aj(ZOj8X3B{% zbv;>BH~SjI@r^WGfAp?mHD0U!D4?DFL#OZV!hg*wGF@V;H0C@}pkzG3JBt zc6N=Wb1u5aX`h3BY~eH-ZtOc1t8c-oQ7LZxx|*b%jX{a12cdn9VbKrIer&@mb!g{x zbi-DU&+OE>?EA>9WbrkZ%en&hkfgGreAva^UxEN^03>#u{0YW3j+pm@He1n|B$QuR zCil1AKUIr}sYSylqfPq@yb{R^im|{%g^U$bSMi{wGI6VSzgALf!x6jYJpQ9-fc16i zu16|>-5bO)!xQ$haG$SSQrw+=-W}tedRH-f&QrG+23$bpvu3`DofT2E)U83mA_hoy zVN`ENms2%X@l3tIdi7JCt$k7Lg-p*}Xd}$oFBQzTb5_kqVCvz0orCuw0I;;9YtwNu zK|z^JW+|v;#!Ak-aI4$z4bjY5i8;}wHb%p`K-ZzBdtqR5BV(o-;Mxb42nC4L%;2Bb zRx#Dijk(+Jd%aRR>;$C{J3+3@k2NFlH}#PO%(YDO%}-Oivfsr13ihY16IyQ!r;+sw zG;J?eZpjZLR@S~?Ih%^+WS!|OO3XesmnWO^h2O-YAhMQoe;G>zbz7boI|(ajv&jgJ zY-gQHEw91oBp}c3A&ApzZu$w6$&WcdaQB!08HcBfYX$bPp(AShpw8-?C$jfY` z#SLgLbZzP2h z;Spu-Qn_tkAZ2@gm%qAEz34Z)Q0HgWRqU<5^3nyh^7@bTV4{_yR|dP2Kc}@B1Z%!& zag#6;s-I<(Z+L&bt6{mtZ}hNJOOiXqOR~XNH|ArTi{b$n{GQCbZ?JFDh1sZ9N!>DKzI0V1bUO3n7^FJek%lm!2KXWwB||IuDIp)20vGu2H#gz5Rc*f zqKVD=5j>@jL_3=SuJ-&h5_em1CJ{`b;nk3=PeTm4<4iS#eyYZAP{05*vo_#!KONRG z6_gGr%#`v)G?=xCT6}Mfbix%Y(`m&jf%MR}Yqw(j8iE%nwno#U-m+--%@+!$QpO?Xy@`mSC=d z8U`M7w?XMjo15Fkiz578q3?Ct&;d&i{@2ttpL$tb3947>T+*9K4&~UHXxW?VNRWjn zM_OFoeQH$lH?gh1|Bg8@Yx#16Cf~~i9X$Dsb4KAe_3T3aC(4Ih_tA{mNui`iwI3Wc z4D4K!!H@VXqF2gaX!`rFuXfTBud9dR<3xf<__}UW&a%EC|M_}DDQ@~!?euuQS3l~7 ztrFL>#^BPml2F1h)7*G9s7xHR)+O5BK^&mIiM2_!2=kuS$i47taW{%~GW@fZepZha zE=3`*^x+YpuRZUBr+Ad7QUm`;+PDP!>>E!;?-Pt*o0!l`DvnC+0rk>9)g3^7djhbg z^DO0@7v;d>>TvV^p-ercm;TMEbhzpCdyE`lq;10|B)0$t4yR9tHQ~)}J4ZEiZbS4! zKYMDJ0R~cmHbxadk%)_+CdW(hlo&=Mm;B3tSYz)?G0#F!Z$7hPL11gXt!4R*}*=27AWn8aJU(DbF)mA?0SUL~Lc*v1S0hTQQw z=iCWujCA2g>=(TuhFALXAg>z1G(MlA5B$uPL&PPUH?{s_Tmn zzFxk$Z?{Za$8LS6_WQqJ*>SYXdp)m9F7f`yoNbBtxlO(D)RV#MY6eQ>CGm!eo}Wz& zq~aG*dF2HqcXEH2R96@kJV5`5f{r#76ud)?X3E8b-+=pFGA(5oj&3X}Xu&ITM!<%% z%@raxKl}-)>mvxZOVhrRo5AeCp$#?5i#92=dpoLAe%5Xl{RmhE(A5w{!^@Vd>$a}V z#XMR2qb%|3B;ctdW4s+@GeAw39}{TxDx#HMSwwfy+;Kc z@AE5v`q*1KIpGhUu+;X#ka*#XHTT81O(cEni4X{=GL5K}GXH5Cbe1b=-41CfZ9aMP z$k@dDz=T71?&#-56qWd8F1myXWt$L2b%QPEs?&(gxPUc(1D7Nqkc}N`Y0M0HgLN5f z(5>>TJo~0v-c{fj)I|%ysdBR7t6EY^F`OO+x|+L*TEqj#@+GG>nD;&y4DN$# zB_WH`U~C(nDjy@$7{rwA2m$}${@5jjT2a6Ss*^9f8-<@swN*-TM;49mW>WdTpmkxq6URsIf8oDR)sQqxcI)dTH`CQ_f!1p@Wg0@p zYF!ZpTHeDq3_R|4cl{bk%6M<`^i(_TMF zX~wdA)66wG7cwv)m-3hPgaFkNkA2I=>1?7~+#nciVU=?=C!@xaSCOK0Er>e9m5;+W zJX=%vv@QFWI?1}7T63_cNxinavey$hYBQuAsnG4&qj6RjfVJZ_-N>fJbRb_uN^CM>&ZgC6WI0k@*=*a&GtV zzJv>lJrX;*a((z3FmXap=jqJSZKdQ`){@2j3`65?p@-lUyO=En2hG4tr`}@>ws|3G z^rJ-UHSO1kVgg8Y3J+397^AxT47v45LhdVQhZjByV2uKGE*`cl)S!RzIe&~3M9yot z93{V6l=8NdG<|RC*}0LINmoYlWZSFDhiu(tM}BB^$jRxyC3fpyFp~b;t2mWD#FfgB zu(P|Zw9&hnbiEi^zZN9Y-w*;}uqlEJNF~KQ1BhiAm726w=1tt&wO>z)HPFZKUiwEE z%dA6(9@j@Lmpn}+;v)=md=`r^kiU1#mHa{S9RQ3dzD+24X*zjbSu_22br%5uNoZW(b36b+nCtt~b&mEgfQ|9UY`f}vz%BxXdlIEy#yy+Kmu6jy$YXo4v@I@%x&FQfn zS>D?~UhCi06wJodU>EI21@~Y3BkGRPHPWTXwcXnRj2{h>P?w=w#V+M7AD(3G-f@bm zxOy@{uVto|VHLe}9;@gT+hJ4H*+Fq`^N5iKHL^a1;1d2ms9z69q-zapd|IidY@1;4 za?evPQ6$*)=hp5Hg5=9tWoK{RW?ZXF{x#sTjN3Z8aAo?}=C;RAo%r%ec!wNOLIl&c z`1qzblHsc`j_c)W^mWWcsO#_->uYaw-C;hH=x<`@vht$xZzPoPU9Y8~EB)Y6&p7TS zG*bMgy;0BrhC&f7;Y!WgUVj}zah)4pQ)n$OBq4tNH~tK{U9%ti6J0LzVUBX|T1LvC z{kz8u#>u7&5W0i2Qb3|);F|wZiUY2I%Y#lF6dW)ZZc%^NQVWEm)DCYMxwgZ(@H$sg zv19l#7*wNk5=h&`i&#MdHaJY}Y)kqoZ)E(DY>jgxxl+z0t-r6b9%2&j>+{i5jb~cU zV@5_J$f!oru7os!rI1(5-E||PK0>IVK*<>HcEruYzpQ1toKkn5vsd(XQ#>R&gNACd z)*(qhJoOp&UZ({a0@w>*(`_!LYzU|R*fnyB%6%M%qWBL#LEqLGNkiBDRjs~gp9u&s z+PtoqhJ`s37Rj(?H#y*X_doXsl zC3*NVmExPyd7){hck4;t#EN&ioOq1ZkwhNaF=p&!z8p$3UE*qPx`zagCM=zSk!frg z)r=kr!O_Y?a-G*RN6>pyGkt(!9}Ga_?dnk4WJXnQUb`Nrm1i(k4Pf^LMHp_%7Qlty zRga1G4b3Vd-Aej>X5KB7|B7=a1GSYqO4Ub5tcuA4%lI!gcz3l{{38t4?OsAhsIjEW z!#+s!m16DlWX>pIx#cir6NKZwyZ($uvv^nNBtB zwY}ieeAr)J_p#MnmY_N1GrsYp^Wa4Y!fj^9kKaF1E8nGBDGL%;R=?H#C+8N;zPJ>a zWUf60gDWTij0P^R*!2D3G5U3Op!Vf6;!YyOw!y!We4UqCxG2e6(~2YMNEK!R7~rn9Jh^b)O-o{_?wvNWQ+hT_Wi$WG=l0^p~yY9E{{i={h+q>k$ZNpHtgSX*WyVX@vQ1Z%4>t(_%4b= zo>bS0oBM?j<2z&f6~A=~940|sE2bJyQ&YC2>8)ShdC+ggy(~)jlPD zUY3r+u(6yw+7j9C4@Ui$e~XH{@y~+;Gcj&O_MN*o2+J6oVpw+-9<_8Uzc@OmX<(WV z;^hcq5!4+-qy%L=`P_<;)EIho(mas)aW&ZgHx?oGIPya*xkhh^@~SLy&@n}1{`9!e zL|7mxZ$;1cgg$&ebNio%yZ-HZ!8zViS%z{_g%KzXb#UMuOvg?yRX3%Y+_^B`&g29; z6KE`wAtGr-O?^Cj(Vf%t*sFRcv+WeyGK~!&&w);63;p^`Q7sg>Hi0yVyYA9*ESAv_ zoCYjVlnu&%0J+JMQF!w8{)FXQzSBO|59T-B)qsnH48KUTf{A+>srgPMd2pcLzZ?1K zFh3+z)bVoR-^99Kw&)GwPfzy{6(3zi$N28HUu zl~PN}Ny-~6c(^=kA8W^jMJR{@Nwm)r>mW&z3#{9>AT5;OyA&`ypq!X6UhM=WH`%S6 zo;GG3b-$TGLjGNS4I6w`X$8#A+3 zeLAwG?_er*y`eB6IBzh(x3Uss@dV6pso4;ULrmoEx;a{fMQeOXn^%meak>a1+4gPD zqrfbY^vAwl26VP$QHy8T5Pg|UZVvY;mo~TKGy@%`9Hpcd+c)*Yo$w1B!UgK-m|VW5 z`a`BL%PBIb`tybZxnN|+jkfMjSRgF2a^dk*duDRCqA;uJUIMUDQ?Q8YxE#4ZkF_rD7KOO=zK~yg~j@;n@IA`>dO(zsf``$6M9rz85i8F z**b$9=OM=jLLo}~HkBka4dX}K(HF{-t0C~DxTccE3C@O!E zQixcUlFE>KnVeAojAS|up&+m=1qFpC_kgNEL+17Xzr-`QkMK<_Z~xWA`0$vz)K~e0 zv;)|6DH3y5KSap_`E;zQJ1GM)R8Ru={_lVJD=22eaHUXfhw&f>3b}gRspRKlQ^x{r zs5XIS+YLO{%Ke`03BhRDSMe*~vA!~yA->9{-`Snl6a?Je9_ukBvTyG<#wo$VNIFseD zJalmWXq2s)&C4Cf1wf3Jazn(rYvcR(ZjEh))91zKWQbVA*nofjYI#|F;V=c}l$aKr zv<`rSPRvOdvQcg|K{;D7T4W6enr*s;?)83sOhcDVzn%SkaM%56=0uQ=jOoG9;((_| z<_SOZ&hC@3+KiLH*qXHz7NKV92vRYsdki%53J%ES&x@A#9viAJ)w|fE(c&*2jU_4i zux2`w7$S zamhvLJ9W#+r>A2=SlEjCaZ2eulFut3=ZSfx8RdPxIw4==y>SnM3_DOqw1VCHDB4^7 z%r_t(OuV|XDU!IMgo4R7OePdR`}_e&)sbgM5yRDQx#{d)7A&qo9)<|YA98bEo(f{U zk%H`cWsoREez*zHfUUa`0_5S{Y-!hwR4%v8<(2hnd-S{(WEP5S$*G{T*%YuGbbo$HA*534etvY ziFzuvy+6snqm49sJirlM>~Tb=D;|ZJtnOV;bC?;qZwN^&j0Z=bex~f6-MCSGzOPYh zLxi`|oF(v#*H41{GRGX{PHnw>y7Ysc(I@(#fvs1+&R>E-j{2~rrci(yPeumlAl`+u%4RK^!gXB(Un=km zz0NakBAKogeJsAS(TpQ<1{$&9Gcru3uw?}>3^FK@8@^__e5U64bO0ul5@qnxoo@Siy)no{g>kQ7)|f(Z z5m~UJ%S&?nd5+oDpkPW$(g!N0AL{lAro3O4vCp56OFYzDiJ^?1YaR=Eln{PvnR1Hh zrn*>dT)-J|O z+6w*}1NA@SJz4i>!C_a`oK8h>j7@QkiXK{54Z2(EC7|;MwZCZ)+Za&^`mdew{L{8U zsgWQ|aEB7sZ`_^C#CEfMNP}_r*Fn1Ft(ov9MgJv783sO$#FQ-nT=bA+Z<~nsZ9^}k`kK3YU#O>F zp$pHY6C%71rJ`)eBsS)NgDaa2_Y%=tKgcp(O5LQDmGWk27;}@hKN%*H-@Ln4P<$rWkmJ^;t652oc zX}zh%g>xB89Q%TZT#EG3@$sB~OoCzt76y_uh4i_U_|8l*Ub9!Yqkpn55V*TR@`s9@x97i_`=&F5)@j^o< zGb?0|KrjFVoKCy5PN8O^jUwL941x*g#%L{2sB;p6Vmi8TK&gOB0zj zEo$+(FfGe&`>t@t?anyNNdDSwV=kIpTT8Vb^!4i^iwY|T3y58?CdhynizurnZE}#FSZ`MLt+|0a@bqname@gy8 zY>kr_j^(Lc-t+xvV0fCN&9VJi@tL{G?J=+al>Bee8h6@E8_(N)jro{t`c16$3-+>= z3w6eYrG+OTe|H!AP9gUzzH*=OO)S482&lggaN7~>Y#H7AAf}gh$*bY^7*s#!lZ#W$ zdhe5Xo?I%YIA(EkfmVrt0p?wgivqBO(=sz^9%l(QIJdG;oK)*%B?!%4s0 zuPGH|kmLo8q=rxhK@0Oul;S$qo2mKsGB3Q0?soZ99cc9!k8K17)!2ZJfuCpvIo`)+DBQZCy8e&}}xp;EwY>lUbyk9Ac)(FHT#B0&YkCevI>n zAJfO^96SFupk0Wn!A#QIQC1D5|Q+cg0z=MC)kS6wh8~vRm zH9ZM~hB+w05I3jpurv~E_i4$8YnOKKpBNYW0T-~1Y+2W7=XhbnZP>1f0yh|*)=v~L@V9NzD0<=RI{jRhf~Y`4{VOem>*6~<-1&D=ve z>1$@{s7|}@rSR~{-kL{8>u&U(do{^&Cd-GyS+G})ru&>J!#9kvH-*spBOVov?OKJXZ881vgFP1~~dQriro=idzmP@7bAf}+c z0p{gtlxSWp@^m(Ivp(tOCoQ*l7}#q{_2^WNNsaA-?Z0Gl;>PSk?QU^RExaPLXArAu zaYI`&${zII)HcwQ#*Y)uby>347am13a3?X#l_V~u{>WBh1(Mc43)#+BFM2LLW+M@_ z9{sn@4WocfzBa9fLCpav`Vi;ze{7nc?UPT@=RlD@adRrR<@n&n0TDmh*tncLY8rNM z6)tB!a;zsrhq0gZUEO$xLRq_Kjoyk6t)%$Tjg-NTrXPaMX4uV{8;CbD(5;JM#=%0J zh!NT(V+-hP!MLaS`m3~*g{1!$G}w9p^@~T#;u=yx`-%|C70B)lD4u7D%;86(k+k@iP}2pdUHSSysyNHS z6!h@^DPPE6o{VvsbDr^S8_*%Mj5NT_4=-Tl&D_wc;o6of4Hs4DUt?F)zi;fo`pZ3c z)C`RypmG=57gEU?{7yV=dXo#VQEgq*YhqF}>~~F5-@^m9L|E?U;cXh08sxH~E zuOZML>4Svh{x3~A&vY;g`fuypTMrlNw)&&fY^*q<{o;rX`=15dv9Q7sRUAC1*K z;Oy63?hJDLp}Z|v$$!ZqDX|leDzmLDsSQNe_|f@p>rdKkMh}5}Vpg-)HV`;NZPojnfp&oMkYve04 zW_0s#aRwYG-JrKoqq{!Q6_T|*mZF0nH$g?oT(oorZJiA8^p#a!-ENqt&c83dkyg8W z_ei1dKu_gge7mjMr6%H2Pn4jC+as$KsJy5p60FhUck=;W3K5xMMse>ws zs(0^0;u-zhr$7N$;ue|)S?`XA4aDpcTIcNd*2T06-1>z zW6&7aode3s{P&t5f#q9~vcqdyEVU(q%J*;m1&oIU-mW(M;NELUC%+!~*Bz){zJ^^; zg4GYWdE_`1Ng(1j5db%f>yOoX75zuH`)<@x7;H&Fa7UK%>;8oY$Tcf-u#$*Ze$hjPrk#El@-(Vb&!gt$oOVUO z#t>H04is4YBD1GtXa$yeJ%egqEd>sRxwL%riM%xG-F`LC>12`zqRxuGN2Go>`ER2b z_zssXl5lx!!2?B`w)0wzJ$~UwiKtbJKg0b82X1w$si83v&SmJgKqxFJf8v>r3__MR z!5KE~*v@?}*gjHw;P&(S)3VVQ=$s6{?s+~?-|)5NPH}38iSizbg^NoH!tCML;RypT z_U3LbF2N<<+}q7sh+tzFUw%JOsjEY5$;Dw8Jr z^jB32k|9)#Sn~{ zKN8Kyp6;yfZm^fE8C7BRdBlHq4LYxc=qYt-fNSV%>M8qBk(=Z|h#w9iFXq@|W-A z&lu!Jdfkj{{P9|VU)fsd?-FkmbC?XsPQ%~9dfVMkcEbL1%D=f?q!U>&|5t;L{inhI zcj$;Unj#Mz7ZbDd-(IblKE(hT`@3ZahU9NzA3}6ywyLVD-o~Z0#|0>D*Ow)9uH+jX*ta&chM$q@82um~x4;-^A`}Qn}nf#<}?gPxfUq9VysAL;%2r zLIA-3ykN!CUF@idm_V=ZC>jZOkBg5e1ACSHvMjw_i>qmOmh4);9{QxLw z#(4nV(<-#&@we!6!vhr|34O$r0DC;s$uq6qfBUefbGT9THnU7ZMvJg@=)vNZ(?qtx4~5n8z|LL3oNk!$CRUX zk&v1CI+vei)M!*w;0dk?l4-Vm#zb~i^vk>9%?}*CZKWnJgkd1xiyp@o&48OJ0b<2v!2g+B; zSq%d8pjxK7E9vT;d5H=nipBNbrz5VfJu$0ITwWw@B-lTaLD7v1-dQ;G1S5$a1-0CI z@}Z@kK8~!TpAn{@P*%50%jv%vHPU|bsl7SOHl%G8euDg{x_ln#PMLv$duY^P`^)n@ zC`9XK{xrQoz0k|xnLUKVagEwX(~8~i&02m*Rdr9niNMP!r}F>$H5q0k?}jXA3v5FS zqf>zwh`CD5vza{z{9F)TfTX1Aw-l7vm}X+!l{egx^(^vdZkWP+h|PL*3;)VhekMGc z>GnTh2ByW3nt=EQJn??rv|hT_k$z zjG{oEijb(GJB!#e5h(Iw?A<33%@z5R)jB(hp_F(FEHOeQ%5XMyM0S&%nne zmCv4S{lVACQBEx1{k0(Lub|FEu0$XF7Kzw&B2-Va;X#PA#f*eMVIB*}GEa1= z(VboFoN1zXRQiZ=-O&4*Nr&XzNAKP5HR@VsLX~je#P(&C|7g4vFdXId=8tLaS^cB2 zoB&aZ?mkcxEMwun*aVf0vcJG4!dGCMh60L$&FRqj$- z_I=RIpJRHS`kxCWhz)}}&*Q#kX6Y4Vu9wjJw5pKk)&P&@@^N!t` z@lO~mZ<{W9>(H+tOsyf3F0Ohfh0Hwu z48tS`vu<{b!0Vd_ma4{_0RsBwj=ITR>%ClT)IZ9*LNC>;OHtY?J?em>F`zUfbtU)5 z?yENrExWDq?DGj7AV=8i_I1YI7x~KM;G|S@N{Ma_jEJTs3UmdI<7wOa; zQk_Zw3U*z?4zo#t;w4<1Y z(^|rCVAmVa#pjzwNPcLlaY#M{V7Xgp5px{5bWi zQlYO0?xwk)|6xZ~<=(J5IODNhm%=;63vKdo)lH)Qph};Tvv?Pr_v|YeQ%u625YIm^u=l!jJr6{zuH?)81Cq){qQw!y?WxZZUYU{~x2fFVFC zdPqPV3sB*%KTKwo$K!(XH>|g|iiOAHn;_ky^s|NdroZ)U_1N`t(SItII18bGGaSDC zc|b%f&nVE7gQW%Oz$A-{lg}WIy{p_gm367A14}^b-FA10HAtOLP+G?A3=wk}r2BG~XsrZ0v5^9fR z-lA$6yhUnJm}x?i^TC{k7H|@OHl-q>_ORPnz9m(aInh|KzWjtxU_|v&`fUJbk*TrN z^t#g_Y52#;%M)fyTNHoAF#6>q>8KyCCoQDiA8>Z36_e=#(yNf=)WM-U^Am|~0VTM? z*HyJYsT#U4y~9nkA%5jn+_5d_o-9o+eLG$l3nRL@mVc2equ}D}Os$_h-m_&r)SWXB z;m9Cc$x(9FBVLTMU&^1KV)0cM=RfUf#BYb_@K@v0b*zk-EPWm)Ep&A0BU0oDQ#r_- zI(k`A3)Q;JDiO^LO+nwp-liJrQP>4_oMcHRh(2PnPCH+iySPhrJ$DdT z{b|x-csM}#T&gs_7IeK|h%Ssz_I zV|IhTbjjkmA)t1f&EcGzpME0zpa=2yIk41f+yOAfVC-MY@9G%{k}Z_rB-e z&%M8M&inq}KkjGvW3%_#-?g*%+TT_7TF>`+M%N&qN&h#M_rw=16WUmZ9KTqA2c<19 z)8FjSp@J=*pLX0oT*DAyJ@Bj1Vi!*luFYwGSkXU>8D4y~mEH6bXwhI1Ypfo$BC}qO z7D|!aSOw6K>t8laOFxik_s0L|+BY=6ldq5>uvAr(F&IZA#^XyZVG0 z$HHg%MarqZ@BwDf)BbDPrv3aWxTAtSAQL(~sHeY~MV_I9LmN!d4jfh6l=JSvQ}0j* zO~o>kh*FyNlo%D=Hsn%~`*a=mGVFP;&mAg*%&fXazw-!zOU0yqP?~Q4P$RQ`E$R|d zi+v~G=aZc8RIICwbD-#xxGPN1K3%r8p=aSM&*MnImsf3COWVbTIRzX%8hbolvva*O zrqDl9_CTTo8FU1y|G9TX3}NbDSOeD*AtNM@vK~4uN;QeCjj|HjYn88d7x<-Id=(Ux zYwF*~eqL5-f=p4eH3p^%=};p9pjd~Z-zE`$m<93^Y2QnQX$M{wd=I`?T6GbNVJ$*z zXgaIsV?%aJ&A#$rK~8n|KBsG~aRBKjSfLLM9e{*1dU(S7Wx%kzn~bSa=$>K;QoS>g z7<%kYP<;sP`dmE{Fw<|Of__`)JL;`{dZyy}4nNG)6cmgRAx`m5sw=Db)0)CDZ0^^I z2Xu_1#rM=v6@I8xIG!WsuWw;)4-Rs>EECktRSC(@a*euGgCdWPC9X&PkS95;X8%jo z>vOg0ZMO55Q~(b8d2`YCXv_&`CRLn1P15@&Mo%Hv+TGcjUS7@!|bz2DFnwp z_ei3gse`o;^fMN1blpRvg>fTWx9XNt^*$%k}ad4cLY^-4eF8OTT%4(4C&6+#&LlEIc;HQ#B# z$%GW_G7(q6KTcox?$O8rw$oU8RO{?^RZ(&` z#BlJeXs0h&uQD|N05nE`wTEFF!1rUu##VAo6vT5D1s{tYbOae1UB6d`3Rs6)-MB@G zQc!m82o|7GON2zMGHZ*fTRELI+6Vek*7B>XNn85vp9+gGoct-*M*E7Q^qDL)oT4+c zuIbveHjUh3z{ehgfA@{60W@m}Kb9)R_Ta0E9*FtYnk@xw;ZL_N=U2^!RR>sKK!m7N zl`2klT@IP(LPaO6Kq9(oc|AfxvNybbhRZ-evieRN&vr8muNFGuFhB0cE(kudLvHDR zd7sPyx_C5?J8kUlkJm~!n=5ma1EQHDppNK#8Vy?t76d_C!Ip3}u^P3R;TnjTwmXqyn`#H3U&%MF6f{P6b*+}|akf|Sj*f;_bYiU)g;rlV){)HGDLpu-# z#*|Ut*axI_H*HFNas=CrnHpXk-(sU+q~P4rNIeT-davJu+4{Y<_u32iIyTC!lvsw6 zFo&BQb{5)$rAXO*-MT$X`qtM&M@uX(ZLq7f9g9#&ow3c1%kBe2RZ4SVz3KK7bak59 zOed5<$lwxUtMVI->LL38rTYF~dFJ-AkBL*^M~7FQ44rSjlLzV-XagiUq6+Vz?P#^E zKvO`hH+RJONnxb0$U4N4aZFnp;t(AT2vrrND7{G00?``iJ5u6fJB8MI2fvu#zPa-M zJrD7Jw}>@Wt_=vXY0c;A&xQ73$Wh>U>3N>h<^&{CAhn_*2b$DeW!j3M&AOuAB>X!i zmXnW~oDiUaLKmBcL!Vw{()8%@AWh(p|M6odR?R(f!_nx?X`~t#RKiAvNJanniRb$t zr%9S`Q~+E;^(zQcZ5;@?o#(w(G~3s#hF1?od1a;2HYw=fwYJD#&x<+J8S6 z{5R7-FSGSuRW@S*N!=P12ljhn@9*+>E`~~Sj7non|4jKWE{%V*-u>%#&NHTt7dk0( z4Tml9YN0o#R47eX)o-3m5yL?~Jp?Zc(qqDqY z{Y8``<@Zq54wJmwxyS}01mJ~`W#>FACZ+S4HSEQFR|^vjA8)&adURvrx7>w}LXE<0Ei_f_SWDjdebvE;#(9R$hp{bNm9%k> zrc?a7*I__wu!|y4oQ&psaQbR8tkmxM?%_Hi#g#+AH?5w|mUlHvY@afOamA78fP*F+*_knS9pqV3=xs z!B-xoP7*VJ#>JNyT(PoYouF+Yo>u1Qsn2i40x7n2V*AKGI5S=)mP$nx-CE z47}Z)d94MhpQcLI%ldZ&E7Q105{uLky}jqzMi)vtYMo-??;DE?kG{>C#k0In~h)ji|NoebyUW&3ae{mt8$DPc{(_Y%Wp+Y@^`z$ z|GLJ}YH~grFuA}KYkK{RbueE^Ya{8dG`$XeyZLH;eI|XN&fvM0e@5C(eU*)K7IP9^kvH3oY^#*7SMTcb_j%VJ!p1(0D_j+Jv= z9q6#=e!go<4+GTe`3Cq>LHJG=yY>9(E0sRQH}yJJ$VFJ~daHEnOjjgr153aQw&tJM zc5C#-Z8VJ3?#bKlulI)E4;4Q-T8RMI6V%@)A=%%zhei_WJJmr58$a z+Ue^vDOcQ9H}!QKW5W8LEd*bxBA;_Bss;{E4VZjze(2Ca2~R30}yE@OsmYZ^$1P1k4<;gol{!aXM&+-uMe zJDu%oDL*S~#p z&yj*o8U3V$2m>pRmLC&U)3(IUt1ge{DNJ<2!dms|&Z3vaTv#S*&wTOj6NNcGv-dju z&|_4&UP+FlOugCw8xborOo09h(_?@jUEH98=TEBN#ckS*ucO>15xL(qI&1hA4Nl)0 zHNEMWdi!OWQ05=&u=Nb_#2LuZtqOu?PfMwmPyCe0C?X{J9pt{BVnR^@E~3-~I%*_G zb}g)iL1AtOjjC37G!H?lvSlZa(|X~s*89VHQ{WrZT9u+jy9DqPFKP;BeNtA)&(VWY zuKzPO*|wE~+a?w-<1mWy<{nGOw~sWZKum7HRF9$+qodYaYkts_%^2_kQIu zr8g0!nbFRLi#2>_voA3AJd47<@=(S7eEM@v+>RisH)GzydT3;~vG0vGta5fiSJEZg$~u0V zY4u(H{YZjmXyaF&no<=zO4Y{a!&bq^>pMbyL5Ql?WMd-Lfl|pUw5O@IT~mU&1p9Dx zb){vD3EW@4+BDv&<|1#2cejIWaKc)gukLCKkt#~f?Db3uN?;o4y_z7CKxneo|CW;C zU?5#;MsTeT2#Bbg*iK?eYB!*|Bw_o4$I0GIAH7mksn-H2ypD(NA#AbMESr%;}Un%+Vy(%kjG!%ZPoD%%p zA?K#D&F0mNzKUI_t*$81A`JxI5O#Sd8^jS-!>RKk*BA59u8 zm`teQI|p`Y$qkI~vwxxmrvu)%E%m+ok>aJFOX+%{y8%6(*+EGe2kiz~x%k*QtNB_@ zE&OcyaL%AvdDmV=2#@x-nPb|NWh!0=_@V-fGK5&AiJlp(z=aRZ?@n7m>0sJ5qt!M- z0wvj}lH|4@(eMsUU~?fm1)46vD438{ichr4#G(K{{E>AOd2}|AW?L>1d{s!5P*d%>sc<2C zbNyLT#vfq3znvQHZEYMt;Ol*O0-9F|k4l&<0D%FVr~ zdsIg=d*^PM3a+uOir$!IB0}Dk&>Z%`^^sb+t`o9|1gs-@^+BOaM!9?9MxR)y-6*++&*sEc(+;f&G1DlPVl>4O?Ky55Y?&j(Ng!I389 zL;1>ZG#v3`;-IT^`V{Bnj3UPCcbB={+@cZfrnHQU3n-Ytpz&MGE)s`C#m4#u_nQI@ z*2>d!3WrTdW~B_l$iCu704NBaKzLlX88IVWZ&=`0e>zO{6np=N9Og~FS5bNPO047X zUPCY;F+~!yTp&(dL1Be#`+OUyPAKoaP(f(z{=i*iiJ51JUvLv!KO{-?C(OPuSf$U~f&ccD*ZC1bY0l!sG>QuW8xn5t5!TL(d2V4|H=@ z7$%@b-@x>xI(#ol*j|tBld7mBzo$g13JzbFmpi0SUhL{@DR5wfB(+p_il&qpcnQfF58gJcXJ%HXM-ds# z+qE?)wBt)dLhPIv&+Ce1->@f}*|;9*^5*%2idmaw%#?>z)xFWHiOnr#wYQcG1)Nfs z_kK3zaNvPCkxTg&T(CF#H?FZXN+u-LCEB>|b(0+5!hc_9mv*Mn!4$t?}p~c{*v0p$D58Ntq;RH6{47L@n*FHqhPotg*4k(VOBRBi@M8wq9oy7?E zPM3vaI8<(DY3tWj@H4_BO{tbNl-5Ps1(1m)}}~WKS;xJz?yeIKgQvVp^)#S3Ehho zTXRQn0*MG~x^0}+t2>|gk?4V6;ZXE;QL_pDUSJxHvfULEn$4I-nLA6je2{6`Y%SYtp9_TZSiw+b!0r@f3pJ0|Bs6)%xZ&nUnAJxKzq5>*e<`H4K3# z_F~d(xr*j0C{RUBO$+T)=-m<*7c&!@rYjp|dci-MTa+M}b=E|)+8>nIC+jyoJ|T)P zQ(=&W{rnw|@&|2E7;c!X84gvJwC#N$jj2dZV+e#o_Y|DnbWZnSU-}+_`c=lC`P4Oc zf&hjT+$QW~h-S!!o4egiNANrv#=#vfCnmiN6*8$V-HGY$RW*9BSM!Q;GiB}7SDswR zuz8M!q!&1yrDRL8`#CdJ!CqQ6*q%n1hb!VuXj^ansD^oKCb?JoYfaweo~EAby3;FM zP1TLO)qDP;M`j)!#`g8M4-e1K&Pv9jlUns=^Ko%MS`)R32iCVDLqt0Ld)KsiH~8W^ zf5F2X)eHPl3|Nsx{@jDq553CjhI{;BM|Xg3GO(GMQK&VTVzZ|0p+38oyGjGbU5j|B zdg;QL?bPohrb00OBX~xRv1t>rF{QK>SvmZi5bC<~seKuuw#z4>UUILDU4}MnFn|v}mb9ky0Ys-` zI~xYNFLlp#t--ChYrF5ocCAwrGrJuxAiE4Nk0hoBeOQ*8k9O)0LV3IzzTJ=DGh~&J z;U}qYOf9)0Q-o@JSYqdlvs#A0#@)45$qzY-IZRNL!)Mj#=` z*45oK1e_J}N9IoRPVOtQSgo;b@4!AMX96!GR`w+1B~aGyWH8-Ayr*KnQ#va$i9o>0 z-yjeKefB2{M0R5T->!)$kqRLwiY@>D1P zvmX&n{p10bFNS(G*6&&Yas6DK)v-UDQ5Jel+qN`hSR@MsSYalOzWc=0k~`h3GIzNm zO}FgP?x?ApA2g=L%GZ#*rM0eru9+pgIFwSj7Zut`us7o$W&JU{H33#r$ek# zKn%Bhf-cRQMrxJ&?b~o|9j*GTVJCw*WO@CR%i>|bYh5y1T#Y7LF|JES$|Wx#S6W9f za=%+D`Pjz|RR%OfkUJGzd)7B8aBNo^{Kh&roFtyN0cIQ&2!gYaZ{y2mIh+1kh1E;8 zN?{tl_3X?{WfKbF9Wo@4eE9-HtbjnIIVES1HJwFK>qb`{t$R=#wwzXgL=hA2+ZZ|W zy&vV{N^Zd>py$9}z8qUCBoL)@1Tq$kY`G<;nq8%oFcX#=Tsg2x2v7@Hsx{@~1Qk}B z+lwBmxJt#FBqmobAEF`Ss0e?**q2vfBKo{52dm3V&nuI$r|B2Qwy9xeGu`)~P)Ny1 zQ)2Uk6H(oViBn;OL2+uxs*rM%^j=JwJu{Kmfyf**_&@r`IT8*^uV?1>Jk zh|M+Z&synysy@PFwRIy$h9`B_Cl8uqG$}o$X?oP|-lo+tka#j<*;y2ws1iAIubze* zP|a>+ObI4LjIg7L`06UxuH+?)?-Y6o`sD(;@DEmnkcmLF2eYNGt!N>(NY|?zi>G!~ zrCv<>L7*%Umo!o_j=yX_`t3C%a}3VYlM76t90^a=_uP3LgnOj4vTQIZ#LVj+ngn5~ zf%2oVnn)rzlo@`X*-ch{r9`?M>ESNUIpr=eS=gg(mM?S@@3|cxaA?{Tv5P-pbCP3e zMZFNAf20-sbRsy}59^4O@>tE8Te2$;F1IX>Qh{{cF)7a~Eg_svVCrBYV%QB5|T zfteg@zODy)Iit|lsi7FN-CgZmu4(}F)5;LpM`wXlbmju5qGt7-my3 zPTqSQN9;DiMx{Cl>MmT%(P7uyho$DYee^isp*V?2yf$A;$QKa>EKtHn39KCH#GO)MP7S@k?A0tq`TI56>e`XRjN_UY)x{8yg))OiXp^ zVCdB zEx%ing>!Y^M4J>Yt`b88Zrdvbvb^s+Pt$o{LIj$Za%k9r*E47NmW z_&+O}2p*7|^lNYnx3w8zk+KkPy`-1{*2fbCb-p~DOvi6@D z|16yU-#q7^bLfA?+E4%LpTs@mk3ejp36 zUDNx}i_EzAMFOBX0`7R?Izr4V<$m<*D6uxu?>>L;D9thn^=O%oNRx*LQ|1Oja`h5n z`3-av-Bl6;9M9|20$5fOqz8D_&-PY)`?C9UF@=tH%hnCkujdrT7A@#OY#28it8;*1 zt5S0N?MXra=$qWHJXu!koSX#*HU?45hpl-w-c*pEbLq?FWrhHY8vtfD_`6Go!$=kA zK+5b#`zG@YQV@27EM!QyGZ>~uHpDQ%!%KF+z9HG@ zjO^)V0Y_Zf5m5yzJ=mz-Qq2%^z_o-d2^f7JmAV$8OAZ&xT6S3vo?t2o! zx~N!|cClC*i`3m#losp!ECd7V9F8%zCDPY5ga($iqMyFo8?%=fcDCimWDg|1?fPqNcw3Y}7|U6CMLfb*> zgylwHl*Yuzo6_@b>B1aLHFV#K;_PIN1=!gUo_v9yl;{A&Lhz`QlegN>rEND^?XLn zZtK{Zj^lyr1K3dXT=6W40%N$=mv9Et3sX+Kbi4>_)?gpL7K*F9|cX zGSCYRlUyCaM(FH{wEJy%6(O@W6=sW7jLL#-Dp)zR2||x>DiVUWAp@pY(y~J7R4yVu zwqA$sulvI!z_9K?D^eD%oo_16R{_KaOMDCgn(dAzt*v>|Q`T3B9+J?#%#lAD*@SAQ zM-Uc}NiHJq$ppy|j|$?V7=8yR$J-9dyx#eCjZ|?OY;=@q4&95nZCs~q&y|!Xs2QqU zliH()_10AaWcgdWZXx@Gnj7+D%jub1rUT~K685c*OmLJHs~BXe zUAA7iJ9g%627N^z84D1f$)ey#Z*!Tg{&wPTR)3)#`|Ant->m-3{$Eja&fFjQHSLG2 z8_Nv{Fg*y#l)v%pkAKV|GC;>ewrvfm?Mpu5+;GcFcQ z8zFN<>83Z82TXCv)iWp<;C;b0b&0P$BE4$2DwczyPrVuiE5{I}s&O%@!CZYyW3JL9 zG8uDxBdE`8D7fk$yOqDQ`sQbyslu9lPygcg4CYs!lhT=D#~WEk`|;?GfAA|s1`=P- z9e;(*?lh#C;lA>C5|7va@|5QS*O2|>l+C9?FyXGLAjkJ!8_}5$%3qlG$m(mi%Ij9* zX!ph{wqhTwbHM~r^=m1tKk0S+pbof=lGI^ak`3XXUvA^A#Wug#LXhH({05%24S-waA4q5&Fn&8p`|+>R#vJO>xspxQ5T!i!b-3zK|EGPp;>7 zP1!QMYMPb%C6B-IXnF2078f_Le^Hg44*zLFSuB2lQg~X|eWz-_FR{?9{#J6wZloq~ zcY0y;aXn1cTHY^ta$lgqmnq-BPkux{<*6Hqtv3aRroqRh-@~{)c1U_cQ8I}@NPKkt z>AbMlSDxX`I{-uDr)vb7ych>Ne%3U3w|`iqv^~Xou(>8zk?Vr>&Isb3I8FVwA zJrW-`wB4BYckcXuJotCyW&^u5NSPO{J!5&z&HZmu2#WD7&Uo4I7*@KYc+4|2U=}bA>*Vc4!&l2%q7JtJVBNaz5{XhEA z-=E-T3UzKq;;sXqxHVW28l7a#N>W9PnOxTDm!jOYhMF5vh3iYFUpPut;md~BnPP>) z9NWyI?}h4nNGMo_`I|jp&|wx7D44So4LUig9R3Vnjmu=%PWn~DZPo4u=@km}Fzf}b zO-G3_zNGUCDfzPO9`_gBpw z8Z@;n{9;QO+_*WQ<1O{asxPr-{ZW ztC$Ap!bA|7R%gmXzE65aP)yz0qscuZHZK?%R3+BJq_JyQ&4oK@EQ8X|e8I@hf((MTA}UE$?1-YhDn3l7^+MoY+i%PROY7 zjbVkvZ3k8R&rM-#ux%tczOr?>caF8hj$QPwa0)qYOi6LIVjbZ85Zs`q9h+QW3&J?)4J1 zZ3n&_$W@ZsGk86;MRm8LCMfA}J`biV6TYC?_sPbSaZ|>dQNADubvYbW$i*L7?MuS7 zbaprkMj~3@10{rHX(UgO-A9GtECx{smYQRg3m_~&t-|{I0L|Hu@P4Ce zPVbz2s7rR2bguh>&a=amL)&r2;I5m%5L|aKsOBUH%G!^QD;fIGLV8)e7&r{HFR&xH zRuvh;N7Q{39l@Grt!GkwqgGyO`r`}#zzqvi7v9I2<>j^O9({3UQb>kr4z*LUgM_r4 z=s3n2(&;xv_a{?a!ROsQvn%I!TvoM=HEasneU(W}yez zl&?HhO<0EVJu)MsE=zk zUOnLZbN|nB_`mxAk1lGulR<()IJvo1khk9)^!JZnSy#n0Y$X5o%}?Bm{o5bk zf!oyi!TqH;V%LYW4(1&1O4~Zyu`wAHvjYqp%pJOrZdx`^DX!%@OaY=DSeUa(3Z5pU zicGaWrgvKdBGP>@(6CC!3*7t!K8B0Q7n$5uWb+w7m!-zZyUu#CDIjulo4GM)> zrOvMy-w2dK;!+XA(WU&Z7{d6IMX5gGooMy^{%GC)Izz%j=u@Y4twVWPptv$H|KUV_ zPYYl~bB;4M{<$~?!zEtw?f22`ocZDcggk=u0+fGIBlMyhwtEu4MBpzD>qJ|)^tPj% zt)ov*ExM#n1SJ`DI#*{mj4?6g!TE!(KsYfM1SY}Tfumyy-Sx`#y?ECnCDx!ox*sNa z)A1=7W>jSFu&5Polw%9L;AAKZ3`=g&X*$dBPQt|dPO&H#P;e07_#+q9*w;F#no%?u z9Q%+(>CN#I#$Qghmppp7fI5HXjynm37K+$Zl=AshIsH!3SWISU%K)!h=Vyzj+oBq> zv#BClM!tu3lY(rGT*k}Ijhm%SeqLUgk>3oj_5IM66qLhdk|UD`7cvS~oVk+OKF!$O zg0*6lzCmpy-;$$#lgBPJ5737zAEPjJZG12rrXU@kPSH)5N{jcFCN14(Qo?A@z#2MW z=y7HKN8sXM;AN>bUcJ6L$3eA*B+h<7>dUjVP0(2jL)eXuOmlHxVA{O8K+_ZpePlIkd^- zzGL1eGv8=s?qh}a4Z9M{V*Bd8Q|z`JAFthjuNL93mG$#Qw)rX@F}04xQ#CJUYNK(g zr*cTNM?xznK6%8^6s1VXsmyJg>?O^CElg>dvp%k>GCwFiEjGK$uXac##)Jb;)%Iof z5y?2x*{DTIYC$r#Z`?AYeVj}367rSjkyW>MoAK_)!P#F7^X9^7tk2OJj}*_(?`y|t znGot%@caTBit$r7u~TjIm;#^5?I%a4rpjd(X>BFQ^?f@xScXgvVu?Hm{d^@YeCg#m zxUV!S3?C^sr8S!Gm}5~i=uND+f-mHPM@;}vOmw5dN3%TJ#$4`T{Y(pLVs(c=Y+tx! zTe(3{TJxa+-@>{2H4Be?+vc}Ap^JnSQ?Ka<4#~eGb-mb(bZ9@fLP@#O#)S4pR~8UITXt8Ltgze3OICTK4VEVWBB zZE{-Jgc;V(7dI%&d+Fe=Il3$WfT-tDMiyNPL0sNuClbO&c668_pmU70x?qK`)_qpb z=^`x_*MH@a<;(Cxrg&%P>$6Ucw{0bN)wAAZ3agPb+W3~K!x7l+>S&3zck7z{B3WsG z%bAR+fTqIzwuJV=UURSKsj1TyLAq7krK9-E3Zx=jPTC1-jB8DQn|Qj%c#~tAhdR)` z=*myi<_DNm`vbueU1QU@dD!LMq{Z=QSu5=q28K`Ylu0q!nYJtKXRY-MYHK0K7vRm- z$6IG%5m@;HkF{q7M=AoMJCC^TmOX z%(3Py_Aun3UGgpvw%3GH_?$pdyTc-D^{E$ERq1$sEpG}I@k)E z0Xk|_On!$>dqar?+o9up>Y6f!a0O-l7!kF;qVnO}Oof(AEe(oqu3p2PXas>sUq^GX zoEL_0CL`PF=>Af~$YLq_BBAiCpQFxHSNFP+{gE;2RQEOV=p5Bi6S@oku5~(lTk0jz zfrhHVZo(^4>y>AFqkCDO3j8u(lEd7YN*qtWQ<#ekIaecRNMNXyUXy744DJ~U1p&c6 z;9{w5pm3O)wa&gj-P)JR6eZ=lAhemQqj(G?pGfok1|00Os6?l%4vY- z0)j>yA>xn(0Z&7y_|%-J+fRhu?JcF zpBg9kWIw&$7q!M8mkwTjF%o-iPm1Tyl>hfiLt~)J{4BJK-Z3*B3@H%-Ma1F0{SPcw z{5vI<`#!#=t_??!^1eE!hgVW0IzQ0Pa7YK=8P~P85E&UJJ)Q>5FCq-Zn&G8>|s9B$%9ls3Y4Vy9pgBnU==iO2t z*)3j?tf}Jpm zs?y(2?)=7b+Sa?;}0dd86AjZci&3#dzyv?#{ywXh}b zLRqAq`z7HqZ!I4reXH-#r)u^X<(jh1bah&iYtW)kFe){n#No zx}@!0*x^9f>%?hPzMn52N_67gqrMCrMy)TuC%I5GrvSV2rG4EtvB3OUngDk^u$_O+ z@EcBbw)@A$u`-rw_SNwEf*=P3dP1RPIQ=%b>_R3TY>@hBR63&P$#7`Umb2t*qrrO4 zHMEvWgMpy_xXewRTE#F z`7(Q{zWWb$J)*q(*}KLBsR1K8GEBkRfWM|RB`o^!m1@LF?s#SM>x0U&tj>R?W&57* zD^Ixjm!oTa?{$A}-&ncU?)Ay(A6y6d_TR}j&Hqmop+8zEfeQj@to_?xlKkAfs`>*X zl!}8WdWz*Z;`53q?_(?DJypp)ZC}TJ(@T?NrC;cnHQQ1DSN=bQ=n9>3AFLp>bS&y7 zPkK713iRV1qhD%hKxZO0xAw78Q|%*PdAbZrUvNoATcLNG71IoOuaLEvFsIA z^)+-=uwNEZ-}Xpq9)z7^P&CUHK8{oyTc&3-j~x6_T=ByJK`1I-Zxr-l700( zY+U#9em_@2LnvM4h23UplWOpfLO@;mCGpZjZ}axBqiY92#va<~0qvOSsfE+uq)%yu zr`*jJK909YfxulhE)34Zas$ST4_cgn*0qSS@DWDAi`QH`TKvlM590-l-l6Y?(WEmVf8mYuFufi1KJQvkiTF42QL_yC%)`HKf4_6G zkP{Erj^g|4R^Yeu;niQ9*vr~~-J0;2&rtV*!=L|kTXONwtpEANB;ve^2YnSz|z4q@%dfYBp=(6>M z8K<==R3oEN$w3KsvK!FtV69ai&C>I+5O`5k%xOrkijKfb&$`KJ5kc3C`y#f2>(L-> zGjl9mRb>vknd@Cxx~!a!!RAH?!&u;TV4A;{B+OtWFK@e@1Pf9ha~kw)T-rXc^WMIV zS_lmj62{?+MztRAV4XElDHL*30ZiQI-83K?jvsfXZ+z# zzd9+;N+#%;33HOC;8~{av4dol9uh~8SuexSn-?>logNcm)2daMlm;NQdZ|}>L@dMI z!~`qay~6sEiUkOHg%~Z#;ai?wx+)ycXC28wGBylvwXu6nUEUcp&DSw=X@!8=!W1kz zT7x%>>A%A7w=I^*@@O)XuLcp5Y3oLW>9=o7a6gZiWLoE_RZaW58(fd_bZy5?I>f8Y zZ4nh7$@C8t^yt*>sar}{G?^ewOWe4CI??1fYPe@ecHJ4>U=9H6K#WXc0lZ3V1)zm2 zd~$y;7PF*7tm@QiEi9`uvH*cxF=S%zX=ArGY8P%SK$O{=Ux0m8W=33$bu-f#$_(1< zDNWgEHCvU8G-bi4tQEiM$uIFN%4XuMCx>5*he%DBADx- zs^Z{FRoAJ?+fCeAs*z9gJV2iPy-Ua(C?(AdOgtO(Pk_@e1MHf;x(e(e6zfgIf0!A zy~vomAUN(?IhrLeow^^BXL5f(I!TN=k_iG?ZuP&pstS%KOy^+_v&t+|f8w>GN44Wi zJ;Ijx1U7(t-fGZ}y>B0Z%xg>iH~fxfBfZxxYLxh@t>xlg+YSMm`7!2II5Z7Rr1Wcz zH`VZH1ORCP){%maf`WJs?iIOp@ht+Mtp^L4Iv0MJvTtW2G|cDjo4KV$x(a|m=I{5j z!dF{6@(sD&E0uuct4+r6w@+t+((N4dTl-q*nO1o?lczV$;v3f0Q>L%K9l%a`)tGvb z3~Pr2%i7yaz>@Z!8%DuKt@SL>JiUIcZg5 zqp3Gu;X=3v^Q#TxSUs+N<~b|%029EXa;V$$04$|1KJkC%Rx!S8HlP-3jw2GYwqUMV zoqN_X`2)r3!k@C#&pT*#`isJPx3E{MvD>g0i~TO#fpUD9MiV{hw!n19*C7LL7CdpiNjYQy zHO#Fiw}Vcb3U6!BAKwU0`lAnT5wjBQ)l4g){d8>p(!c^pL$z{LGIyGhkEUt*jxIqy zy~qSFl_kHk=sJ}!?5pN!;Lzq>m8ILO4KLLv0{L~lO;NFpg?ZO#xg?Ag?wgKL4~-)8wL;f+;UJm2kNMCqpK*JbT4I_4aFxwSF)uG6Pqth<@~y*xgFff z=Q{hb({Ict@4nlDu}EDK>f=yX%h1p6P992y)&U6){%s?$3~31ZjrFe`Lv(C2$q!8B z23tq=hCNSsfwh&S#v7^Y+B(L$%*pk2{kcTl@+M5@*t9k1?B=@lavz$*e?&UEyn3bCRBCRG z8E$IAXLz(qC^Cv&T!MbWs1MbF2?Hq=j#|1!F*GIP$Qc{>5X zj?NQ&2m4@918&asLWv8--2z)($IcSY9M`sXi=vHXVoJbZQEc#l5Nnl)m;Euk2XurIC=1P0XfZFB3CMV*;cm; zkZZ*=CrUR}3Xw1Zgf+aVP3C~B%UZAVpxi7Q*7=4;Ps2UNEXk95-?{Z$T_yBFG#XwD zSC5H8%$7+>lCO%fwE;3k)~RdOk=xh#A>e&~|>?=rgft@7rJ$-FZ8RuMiAN!q!Mc_eAOH#eE#Z zn_t+EaR|>Cd5L%2S?LW-!{R*L)?T3!?JfM)W8onIjyK94_^-cx*XOWH%K0Xn@1w*L zWfKeu&H3(mQqn{EoWyFd7XwqRa6e^Tr_fGz_`w`p+7a@AsYUS=-rfzss1=mDeyjcDK2T#LM}k|SJEZW>O{#1pMoEZVKhT^`!_|X^kood@53U9 z!K&0!%v^@j2ic=-C&I zLwjqL;8jlRuQL{$GqVSzDYnT}!q+{awJR`T%jGRE7L=dp zbk1D$-yEJB2&91u60x0dWT?=kE}Z@k=# zU4-ge533WdHQ<)YhUPKBD)Xc8Bq!|S@n8nwD221Rppefg*E=EnAto%O`~1QkRi&Cz zXz{Ub#-%qg1^Cg_U52e&ub(xPpXw7nV+GhQpzRrtWSe;mUHZzZ{Wg2H;l8-Yy4Dub z&syMZFK+q%%Ootu)GjX-4Qsqyox!&SEn$&(y#a85DPW;*&_Tk}$d`@>h+&+8v0G1e zqHCT-k-x!_Q_l?QhpciLA#g1)Eog zRbR+%J#Y$o^!~Pfn(MH^Q`C?H(M+;n(v4|4U1cEUIyf156_%ncOUQ{4Ftb23_SFW! zC`C!~$sq$UFBPNR-I7ozP3Kp$+%E=8lhPz+@ zK3TMA#5Sl2k;G??e{Mh68!rCc!+a}&k*CIkI$ zOLCeFVa3+~AdqIeiILGQB9=*1XU<6+Z%tYwNv;F&-s)Ei5fyY>^_>Ld=z1-ZCqeuY z(^=R)kvvss*(`|OXP*a4;i4z~N<&V?Di6(`bLcFIiCrv3P-vpJYTYqz5ji10!31S? zbSopKgRFz*3K0F2jy;E9=3Gr1s~*=H5p&jb^DN>Ojbh@Hd9$T$)+_voI~v93YJ%Ito6Mf_6nQ;!Ky96SuDTe4czSGga)1bc!h$8m@vlnD!zTsg?UP zaX8;LBFVq0tu!yV)|BVSkJ>UlvCy-2i3*2sY+z&39WubyMk_Ei@cd-;qo6G>)wz-N za9{k6beqg^?dWo{G6nz_ZLZ0iCdn&M0ovCws$tfIA;orLT>7HC2gI!HgG&+F&Lb+7 zCjCIAAKxSo85g^+Fy25(?WQtTgY7QpY*7XP&+GVwUP>5YKXo=CEvo8Nd z`@S?twU`A9`@czl@kPnv@L4Qf#!Bzy2MhK~2KFQX+&BD!tMe8wU49&q^f!9dW94%I07GU%t`nDJ^3ZYY~knZzEWMa-3G!I9*dP)CATg`I?V8m zn?RyJz}^O4=02QFZ*#}q`-xu0n`SMXPAS)iml{!tQe`ns27HH3$t() zLiww|gnB7Gl_AOn?xz{uSk~+;FMaIZ<31-|M8B}uG^)c1-;*5od|2>S=Q;z4jqhcA zFh@#YH=SerVbTfHn_TU0CsU{F$bDu7g1Ew@Vej}HA8`>svD$=337+xWUVt!r8_8Ak z{t$)7rUP+LooF$#%1y&o((>-THnXYtnncA5;tr{(y_)&a6MC-P?IjUT=w7)2Wr&ETdVd~5BL58?nmOC6ci!1f6 z#TDkfcCA}eCu8!ncoG9^;;(9Crz`wu);(lASQb)xG0M!VAh)GhkA#jAqwdQU70gKr zVk6wZ(J@q7&JGfF^O>c*HbpUh$+4W6Zs(R;$vRFKAIf@vBU$wolB+cY13Gi+D^-9q z_@}EM%Q*Bv2}@^}vRgf(rk;b&T(EGJS;~cW?Q!z$Q~|9!@nn4n7 zG|KuHcF^3cghQh_{XEU>L)lZ!a{Hfs>$#47SgmAYEZe>zd3ZjWg?6GeJel{z-egb1 zgJ&YRY)ERe>>!7r0Dx>Wu@VD%APB!2#L?YH^h}6fuSGvLue4uQc?NOV$BxA`N8*tSuEgMUXV(R}I6aBqs@j^RTp2C?;hx6rM`FwR~(Fz^wdhWF*E zGRylpo_o+9!3xM8el8w5EH*REm*mrDQF*>U;B7(MV;Ut>_dI8*1uPOrA3rl$5JRds znhgKGs+hgVe7Jbnu{*b&`+DUdehbpmbzlyyH)DTbN9FGEDPHso<$hx{o_I=){`Rs7 zF}T{cTo6|^&Xgw?E|N_8i$Z4+6z`9%R%k&XglTPpE+?CG*s+Eex>{<}x>vETq%-$H zhVA+o*26C#qqBDJo-dqZysef;^T}#Q(|)iw3=l>>(8=Iw!v&(c<#`H5)x)aJ;T%rb zu2r^w+0bky98GCyaI08@*jLpZeJq%L>Ymo#P=+y`uB4Dh`7#T|p}^_H!!YTwxIn_q zj_6Ua_BW1>F17RigVNjBZlvL~I08I~eT~>+CpUl7dF%FarO|MH44z6C++2moF6s%_ z`#&MI0}^hQeSByC>If1mTVZIVnv}SV5Ga5qs_ob6e4`|Re}U~ZTwhZh4XL6F6~xed z3UVFnLlO5M2$mq6$V;jwF{`4#Xy1C|3vZ2}&&pdVQs+PABUSZA$uaHm4Fi%Hoh}kW z59!$KNEPLsihW9k!!Q@8cGg5W9ovR?aC|@A%%o*hLP(FEzIj10un2hTBoHrQ_-(iG zTJ~I_!r|PQzGjDkY>`20Xu155^m-#PZ_KAXi{0^}UZr=g!=(h>UvvvZweC-Uq7hER zWUuJdGGA`EzPd|abVs)mI3~AJ4^tQ5dElHdO~5s3pBytLaZN{Px);C#k2QQ>+7xg& zvH44rkuwXVA2EemO5ki;i+gRJzen-0mRK9a=}5WaS!8jSdhhD+_auOQxq*x^o1gmJ zOGJj25-wHsTP{nL%s{w#0`B=D2TA$E!Ez%-MoK`pTQFzroFEz#T^|j8>Ra7?!$54h zb~~MPC@O**<{OA7C)AW%Pb}RxyG1z?U^UM!dxeiy$KL8-Os~q(U5iez{&JMjU9xE6Q zr2|3R<2ng8F8O;k1Z1<0nVJ6l;7eCPAwxw7ruIfTFY-Vy)Dfmn{@lqgkXIv-&N z<_~>rv&YFMUT_n&k}J*GDfheX55nnXUm)s}C%0hc*b5hrV)>&a6BI)BB--J(<$7zP z8B(6UC}bX)ddu9u{^wyaoP}~&8`gqdKq%myUeGLId=AoWrlJ`gCZiMYc9kPXP zi+oV}TwNXYVcZyRRhR&(!M~YUEvOzp>_T*H+g(j3-oTTj%3FB=)I>C}l@wUjH?ijo z8@x=FJJfUB4gpwTMJmm=pFK#%shL(0-bRV!lt$cFv7~@5yx;(UOo9%(7Hk5Z_jOje z!7hbwlv*4eT(2TecvZo=ZLY=Vg~~Wd3T0Q|0{Bh9lbP(Ar&L|2FEAIdNQ^7$KZhD1 z?6y)1S&oeLzPpFhhO+R)tlf;L`LiT`a~7Cb5KEMUq`+NSP-4G{;(xox!V&vTr1JUa z|KDlm@1^^{>L;DoZ*?no_^@%VUTP02ba`%pR0_Eb%$aAa*<;g<{8{X&Hdj0Ht8PUQ zUhvE-$~XXrgpOF;d+5c)z&ZmFlr&)oa{`XI;dge|PWGbIC(OGSt!z zm6|Q_MhjCmNBKB});wCYQr_=Wa_1Gcyy((15jeduGB118h&m*}*Zl~8A(dnY*4$c= zDBmGH%;SlfgQ|3dOayO+>Z`)BGaSnZ_bb{1?z|4yXQrHsT6`|fK&qTlQU@S+pClF~ zLmzE7%Ue|EXB35$GLG9)Q1G3IxrgD)SwR*N-)0iBEO;Ge%G0crI86dT<7<={IYvW< z$zCJpj}V|L)nYDX2+zj;>gRt+gJ+*-p0L#lov>AvA9g9#Kj?}WXVHC*4j(%S1Ryk; zcj^b$W%sNZZVfETzf%!DSHJQ;K6^ZU*JEqxd$x0S_Q$n0%O`BJ&pqK>1`9LCE62|M zpF9T79gm-|%|skIj=5g{`*WCfa$WP=wQ%SOo6KuA|LRZwQUlKvzBBhI>9@qIC^r9S zUVvMQ;f)k23UL)ow92`8v98GJHTgi<&(#`oaI4-2hglrhNE(uUmDPtq5f3uV7_(mA z85lg=46&&sY`WbRiRp$`U%A;wgBey@0nOA^tDY7aOa7K`(T-O-*S0rqWk_tJ+Kmw_ zEoTV@Fl+I>>##@&WT9Viclj_4%B6nIr~sl=7jJQVN1&x~g9W%*B1yl@@xUtSo;MwF zC-%!xvy0;53*Q1$)6H={SeGhtrYiS?6?!l^zHU2CF3Ci%@SmK|I730+@xK>vEl^0=c=| zUTQHtyFvR%!R}Odo2Bo)W4j#nFWH*yi#Kx`D=$vimX}W0w*wUM` zW(?MjR=28Sk6~oyj{Dp&i2_$W5k8LUjx z$*5`YyH2TZZoO-nRj;}1I-mDry7U%@W<~1=>Kp+br1kQWay?$@4!>F}fT7$U3pC0G zq+Fma0d^*D2Z;WB01DfEnbrEqZ^>Q8cxsUKN<>yGdJU~}A=F(>uDo-O?zYlkzijXY z>0PDHJC>{K7hv`SF1+6+Tu9U>@JcCd`~|C?Q*J-`B>!Z0JiknQVt$0FJ=A(My?XP{ zBF+wcoDuoheAGMY@FnT5>hAto0y{3U4HTJhkV9@eZtc_m&Q-WmUfR#b=CAmddoXA8x6^RWA;GR(A2~VffW2%C z6WKt(w2Es<5GBmw&0A13uI~wFunFw((dFjWeX#+H={Cx^oeMH{5opF~viWFoN`3TP z>!9hNTy%7;jr@$Pq}}}PMr5S(3!{j~LpK|pHL~A_)!S!tzCMola`T*HTW_TSEW2Ex zivBq+g{O$o-e}+=!yin)#KvRoNdDp>b`&8NT{+ z{MT&$lHPngB>H!_`5{6@d^^n+(@JZHHQBImvz%S);*hHc}Dkrfh0sKmLcDtnM@pJZ2pUq0s#A5o0eKIFi8A zrtl`{h+FD8OJQ;&kXy7i?l_VFa`5q{a?sFx-nkt>6HD_Ei+A#A#0yN%{aIlqIl>Wzgi8#$qRdiC|=9`l89|sF1iMr&AfPp=OSYdvQ zuBvWS4s+SSaqGbjRsH-B9_gIB@5qHOpSw~d@FWgbxYx{37w|rlRW_P2{JmF6xdl)f za$0F$TsU#gM3u59g#iFZXa7SuqAi(}o1cC7&{Zf<5v9^Max3mcHQ;1_*0 zA7|T=-KWkS0zPU=Owga$YZ+ah}JD%|OHP9aA6G9UcP3^?NzAXuzUhQb}D%pIN#Jna!*ut5Db zxtC@#{t~81=(1WYx>$mb`7j420m!HHwxffOoTz7&h@EdtiI|D95E61GepsaXo-o8* zzwOm`Q$m(6D5L%>*BFzUjH|qpK?mPuI`^wI8nqAKz3}t?!)aeGO*;gxm$N04!#WOJ zH~qd$&aU>;b<$XWNMTWjN7)`zBnDUHA%(bN+S?K{uGa^Gs6Wh-EI`E%Kly3+d%B{A zf3pPs_K@smiV5X5PRNWF{zlL@jB`X&a}q@oha&W?1zA`vC``7kiMt7fp|k-BurgdPk`(tI#WPHJ#F;Yh#J4Wlw~HkQ@!IYWhwzg&y84~#v0J2_-aBy@Q7gJ+TvCv3JebzCS` z9HGl>5^%VuI&f+3dUQH-2!M|j$a=Y#!a;B8GOxzO-2LhxL$>%DKtSWDLgc$ivV1-I;Ixk{r(>rlS zltHA?K@>=tH=IrLt{(v#v|0n*gC%iIK<>-S9 zRn?#{s>9#cxpoPf_pQSK`uU~Q5X*Ln99Gkw(e-Z) znMJ$HO&g&mDiwBvN6b-+IP)wkEyjX{kO*j#wTSQ_Wd#yCqWk7wq?gXr)vJl~u=~n! zzuXC&iFlgK#_#!0K{VeeE}XET6i(Ono)$KeMUv{=LiToBwZ{pI?4j4?SUHg(i>FSm9{PGaAzetc}RJ zBUXZ_LdBJ$b+27YEqD9PSt#4(omc;OwK)w20>M=EpTF=jEvqW2R$Uz_XCErsR2mcv zHm$ zewwnXGN)CaIXB6OljRcZts1QGCWwieDrP4;^-Z}K=C;h3je8~8XsK98Iz;X>8cny+ zSzJOSM49n4G_-6;eQY=htVn+Qj#9*-4W>!tzKq}pjDf-6dC7MMITH=$BZ8`)hpXCe zC&zZCj>>2Aj>}U$TiL0tI7cOre@Nj=N%=1 zrrXuRG#794Xr^@EZJcfNVNNe|C>^~bvMyTk1o|awcEyNK7unG`7n-)R(><~(?c~e$ z5?zjmM#L79_pO5JzN?$x^rl5@%9|>#*~C3~Qa0)o*Hw=uh07)T{9B*>b#zEDVrc-wYcn3F{1lV?sD!OR$3@9hp9r3|@ zGgEiVw+!#?@Wz8)CK+X~IFjt7te?t6noWlpL!nYj`A-(1s_a)ev{j)d4CTZS3ym{Rg6L=~ z;-RG2hHmq=R{W?=s}FMhZ~&5Q6=p%7_cvS$ZZ$omrwKJ;3d?79&M#YL0xUCA)|(id zsMJ_$9`M34Ubu5bPN&h7`To5$)bEcav{2+0S2~nMKv8e6h%G)f7dH+&QW5anQOlv>cjjGxd~}A>daZ6oX*Z|O zTQ=m_TzvQbHfc}OmJ*aD&{wD!xVIiyU;#2QM35f{=H5wa8Sq^7Dc5B5=MF4|SQDv} z&_g|?rUe-}GbfZD9LO2mugB+871XQoG$%PEhSOPcelWC7LpTp(I}AOl8LHxon$hvE zp^kWLN&-O&8NDV&g@R3Ezkp^Y>#B)N|MpmWg|fEl=1WDmY76H{v>C(G^C?fNCQ^$i z$B_rR$~qAHb^eFocLn%Ym_Yd)0kQ-#Cw?nihZO3_h_;ZkWWA*`+b?a@4ymi#e%zfz z3@=AB^Q$_?=C`u4HoR6x*VRV1`K(HdN7qDc7xV1tWv5MdzR|Q&Mu%MR>Xd1X z)0}lvfw4;+r9{z9@`k4tv~_WlG}=@2ME;rP%J!k?)Yl2RjU>VZ-EKlM+tI?T1+9OP zz0v(wgU9b6BYe?Ds<%}KnMQ59X;xQj4kta})#QAl zHKX*=ak`F{-V*f3_M`fsxQ{P)A# z9+~nN$RJ^`Oj1%Y&c3C)f$EBnXC2BV1i6>HSMZQHJvq<^DkZz&&$B*^=IlM-)y^@_ z>Xz4Chn`J~o|CLO6o@{Ud0#86vD&?QGqi%cA@BIc@wu!gwY26{Uw3xi%o>iJ_9vmb z5fj;;?(RL7jW#%xKfI#$1!?V&{Yj2*8an(h;kj{{Gi%}}Y*7(U=6+PH)p+tw!P95c z;NPS_|64tG7SFOuS3DcnW&Iyk{xf~|`0V@M%JyE3zgl!^CGE@IloPgkjrSYxcx`UJ zALLO|2^RfZ8n*t)=9}zYr(FU6Q*Kkcyr;D0WHpce5?-mbyf|rc!gh(Z!`AiQBQ)aF zkIo}A^VxrkSvcx{K4s7#J0aoI=STlbAD^xMxx;@R>;IE!PGQ*TLrz?GJP{3Jg?LPA zI3pTO?x%M8MEe{Z(w;ZA%9$r>cEX{>H9W_mkcfu)C!M)2gJh5@Y1!WyrT@N%iCo?J z<*%T=e&UNJbfqfCfOpMVB-<(BJ1ZE3a9m)XZiwNc@%E^4KfZ1|KL3m1pyj(=b>DA{ zgk^=>6|nh_g(Q>^I_~V;bh3HH{DHq5HMO{~aYem(h&HSG>p73PiUZZd`fl%S_+EVO z=Rf~P3L9dnN+87Pv;O`M^cniy&6x4~?A&xLe7PX23nqo9!mN|8{}Zq2zr?LmCqw@Y D&5(RF literal 0 HcmV?d00001 diff --git a/inventory/locale/de/LC_MESSAGES/django.po b/inventory/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..2cc50fb --- /dev/null +++ b/inventory/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,561 @@ +# Translation for Inventory management system +# Copyright (C) 2025 Johannes Schriewer +# This file is distributed under the same license as the Inventory package. +# Johannes Schriewer , 2025 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-07 23:07+0100\n" +"PO-Revision-Date: 2025-01-07 23:00+0100\n" +"Last-Translator: Johannes Schriewer \n" +"Language: German\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: .\inventory\models\area.py:8 .\inventory\models\box.py:10 +#: .\inventory\models\distributor.py:6 .\inventory\models\documentation.py:6 +#: .\inventory\models\form_factor.py:6 .\inventory\models\item.py:8 +#: .\inventory\models\layout.py:6 .\inventory\models\manufacturer.py:6 +#: .\inventory\models\tag.py:6 .\inventory\models\workshop.py:8 +#: .\inventory\templates\inventory\distributor_detail.html:26 +#: .\inventory\templates\inventory\item_detail.html:27 +#: .\inventory\templates\inventory\item_list.html:7 +#: .\inventory\templates\inventory\manufacturer_detail.html:26 +msgid "Name" +msgstr "Name" + +#: .\inventory\models\area.py:9 .\inventory\models\box.py:11 +#: .\inventory\models\distributor.py:7 .\inventory\models\form_factor.py:7 +#: .\inventory\models\item.py:9 .\inventory\models\layout.py:7 +#: .\inventory\models\manufacturer.py:7 .\inventory\models\tag.py:7 +#: .\inventory\models\workshop.py:9 +#: .\inventory\templates\inventory\distributor_detail.html:30 +#: .\inventory\templates\inventory\item_detail.html:31 +#: .\inventory\templates\inventory\item_list.html:9 +#: .\inventory\templates\inventory\manufacturer_detail.html:30 +msgid "Description" +msgstr "Beschreibung" + +#: .\inventory\models\area.py:11 +msgid "Show sub area" +msgstr "Unterbereiche anzeigen" + +#: .\inventory\models\area.py:13 +msgid "Allow sub-areas to be defined in this area" +msgstr "Erlaube Unterbereiche in diesem Bereich" + +#: .\inventory\models\area.py:15 .\inventory\models\box.py:14 +#: .\inventory\models\distributor.py:16 .\inventory\models\documentation.py:7 +#: .\inventory\models\form_factor.py:13 .\inventory\models\item.py:76 +#: .\inventory\models\layout.py:8 .\inventory\models\manufacturer.py:13 +#: .\inventory\models\tag.py:8 .\inventory\models\workshop.py:17 +#: .\inventory\templates\inventory\distributor_detail.html:89 +#: .\inventory\templates\inventory\item_detail.html:128 +#: .\inventory\templates\inventory\manufacturer_detail.html:57 +msgid "Created at" +msgstr "Erstellt am" + +#: .\inventory\models\area.py:16 .\inventory\models\box.py:15 +#: .\inventory\models\distributor.py:17 .\inventory\models\documentation.py:8 +#: .\inventory\models\form_factor.py:14 .\inventory\models\item.py:77 +#: .\inventory\models\layout.py:9 .\inventory\models\manufacturer.py:14 +#: .\inventory\models\tag.py:9 .\inventory\models\workshop.py:18 +#: .\inventory\templates\inventory\distributor_detail.html:91 +#: .\inventory\templates\inventory\item_detail.html:130 +#: .\inventory\templates\inventory\manufacturer_detail.html:59 +msgid "Changed at" +msgstr "Geändert am" + +#: .\inventory\models\area.py:24 +msgid "Area" +msgstr "Bereich" + +#: .\inventory\models\area.py:25 +#: .\inventory\templates\inventory\area_detail.html:25 +#: .\inventory\templates\inventory\workshop_detail.html:23 +msgid "Areas" +msgstr "Bereiche" + +#: .\inventory\models\box.py:12 .\inventory\models\distributor.py:14 +#: .\inventory\models\form_factor.py:11 .\inventory\models\item.py:58 +#: .\inventory\models\manufacturer.py:11 .\inventory\models\tag.py:17 +#: .\inventory\models\workshop.py:15 .\inventory\templates\base.html:58 +#: .\inventory\templates\inventory\distributor_detail.html:77 +#: .\inventory\templates\inventory\item_detail.html:54 +#: .\inventory\templates\inventory\manufacturer_detail.html:45 +#: .\inventory\templates\inventory\tag_list.html:9 +msgid "Tags" +msgstr "Tags" + +#: .\inventory\models\box.py:35 +msgid "Box" +msgstr "Kisten" + +#: .\inventory\models\box.py:36 +#: .\inventory\templates\inventory\box-generic.html:7 +#: .\inventory\templates\inventory\tag_detail.html:43 +msgid "Boxes" +msgstr "Kisten" + +#: .\inventory\models\container.py:9 .\inventory\models\layout.py:18 +msgid "Layout" +msgstr "Layout" + +#: .\inventory\models\container.py:35 .\inventory\models\container.py:45 +#: .\inventory\models\container.py:51 +#: .\inventory\templates\inventory\item_list.html:10 +msgid "Container" +msgstr "Behälter" + +#: .\inventory\models\container.py:46 +#: .\inventory\templates\inventory\area_detail.html:51 +#: .\inventory\templates\inventory\workshop_detail.html:49 +msgid "Containers" +msgstr "Behälter" + +#: .\inventory\models\container.py:56 +msgid "Index of compartment in layout" +msgstr "Index des Abteils im Layout" + +#: .\inventory\models\distributor.py:9 .\inventory\models\manufacturer.py:9 +#: .\inventory\templates\inventory\distributor_detail.html:40 +#: .\inventory\templates\inventory\manufacturer_detail.html:40 +msgid "Web link" +msgstr "Web link" + +#: .\inventory\models\distributor.py:10 +#: .\inventory\templates\inventory\item_detail.html:121 +msgid "Search link" +msgstr "Such-link" + +#: .\inventory\models\distributor.py:10 +msgid "Use {} for search placeholder" +msgstr "Benutze {} oder {0} als Platzhalter" + +#: .\inventory\models\distributor.py:11 +#: .\inventory\templates\inventory\distributor_detail.html:65 +msgid "Phone" +msgstr "Telefon" + +#: .\inventory\models\distributor.py:12 +#: .\inventory\templates\inventory\distributor_detail.html:71 +msgid "E-Mail" +msgstr "E-Mail" + +#: .\inventory\models\distributor.py:13 .\inventory\models\form_factor.py:9 +#: .\inventory\models\manufacturer.py:10 +#: .\inventory\templates\inventory\distributor_detail.html:35 +#: .\inventory\templates\inventory\distributor_list.html:15 +#: .\inventory\templates\inventory\manufacturer_detail.html:35 +#: .\inventory\templates\inventory\manufacturer_list.html:15 +msgid "Icon" +msgstr "Symbol" + +#: .\inventory\models\distributor.py:24 .\inventory\models\item.py:31 +#: .\inventory\templates\inventory\distributor_detail.html:6 +#: .\inventory\templates\inventory\distributor_detail.html:10 +#: .\inventory\templates\inventory\distributor_list.html:16 +#: .\inventory\templates\inventory\item_detail.html:96 +#: .\inventory\templates\inventory\item_list.html:15 +msgid "Distributor" +msgstr "Händler" + +#: .\inventory\models\distributor.py:25 .\inventory\templates\base.html:55 +#: .\inventory\templates\inventory\distributor_list.html:5 +#: .\inventory\templates\inventory\distributor_list.html:8 +#: .\inventory\templates\inventory\tag_detail.html:63 +msgid "Distributors" +msgstr "Händler" + +#: .\inventory\models\documentation.py:17 +#: .\inventory\models\documentation.py:18 .\inventory\models\item.py:52 +#: .\inventory\templates\inventory\item_detail.html:135 +msgid "Documentation" +msgstr "Dokumentation" + +#: .\inventory\models\form_factor.py:10 +#: .\inventory\templates\inventory\cell.html:16 +#: .\inventory\templates\inventory\item_list.html:25 +#: .\inventory\templates\inventory\search_result_item.html:6 +msgid "Datasheet" +msgstr "Datenblatt" + +#: .\inventory\models\form_factor.py:23 .\inventory\models\item.py:17 +#: .\inventory\templates\inventory\item_detail.html:68 +msgid "Form factor" +msgstr "Formfaktor" + +#: .\inventory\models\form_factor.py:24 +#: .\inventory\templates\inventory\tag_detail.html:121 +msgid "Form factors" +msgstr "Formfaktoren" + +#: .\inventory\models\item.py:11 +msgid "Size" +msgstr "Größe" + +#: .\inventory\models\item.py:13 +msgid "Number of sub-compartments this item takes up" +msgstr "Anzahl der Unterteilungen die dieses Teil benötigt" + +#: .\inventory\models\item.py:24 .\inventory\models\manufacturer.py:21 +#: .\inventory\templates\inventory\item_detail.html:85 +#: .\inventory\templates\inventory\item_list.html:12 +#: .\inventory\templates\inventory\manufacturer_detail.html:6 +#: .\inventory\templates\inventory\manufacturer_detail.html:10 +#: .\inventory\templates\inventory\manufacturer_list.html:16 +msgid "Manufacturer" +msgstr "Hersteller" + +#: .\inventory\models\item.py:37 +msgid "Distributor item no." +msgstr "Händler Bestellnummer" + +#: .\inventory\models\item.py:43 +#: .\inventory\templates\inventory\item_detail.html:107 +msgid "Price" +msgstr "Preis" + +#: .\inventory\models\item.py:49 +msgid "Last ordered on" +msgstr "Zuletzt bestellt am" + +#: .\inventory\models\item.py:63 +msgid "Count" +msgstr "Anzahl" + +#: .\inventory\models\item.py:66 +msgid "Number of parts available" +msgstr "Anzahl der verfügbaren Teile" + +#: .\inventory\models\item.py:69 +#: .\inventory\templates\inventory\item_detail.html:49 +msgid "Low watermark" +msgstr "Bestellgrenze" + +#: .\inventory\models\item.py:72 +msgid "Low watermark on which to alert ordering more" +msgstr "Untere Grenze ab der das Teil nachbestellt werden soll" + +#: .\inventory\models\item.py:75 +msgid "Custom metadata, used by templates" +msgstr "Metadaten die in der Vorlage verwendet werden können" + +#: .\inventory\models\item.py:98 +msgid "Item" +msgstr "Teil" + +#: .\inventory\models\item.py:99 +#: .\inventory\templates\inventory\box-generic.html:16 +#: .\inventory\templates\inventory\manufacturer_detail.html:64 +#: .\inventory\templates\inventory\tag_detail.html:113 +msgid "Items" +msgstr "Teile" + +#: .\inventory\models\layout.py:10 +msgid "Data" +msgstr "Konfiguration" + +#: .\inventory\models\layout.py:11 +msgid "Template name" +msgstr "Vorlage" + +#: .\inventory\models\layout.py:19 +msgid "Layouts" +msgstr "Layouts" + +#: .\inventory\models\manufacturer.py:22 .\inventory\templates\base.html:52 +#: .\inventory\templates\inventory\manufacturer_list.html:5 +#: .\inventory\templates\inventory\manufacturer_list.html:8 +#: .\inventory\templates\inventory\tag_detail.html:88 +msgid "Manufacturers" +msgstr "Hersteller" + +#: .\inventory\models\settings.py:13 +msgid "Default container to display when calling the index page" +msgstr "Standardbehälter der beim Aufruf der Index-Seite gezeigt werden soll" + +#: .\inventory\models\settings.py:17 +msgid "Show item count in overview and warn on low watermarks" +msgstr "Aktiviere die Mengenangaben und Nachbestellgrenzen" + +#: .\inventory\models\settings.py:19 +msgid "Currency" +msgstr "Währung" + +#: .\inventory\models\settings.py:19 +msgid "Currency name" +msgstr "Name der Währung" + +#: .\inventory\models\settings.py:20 +msgid "Currency symbol" +msgstr "Währungssymbol" + +#: .\inventory\models\settings.py:22 +msgid "Currency symbol at end" +msgstr "Währungssymbol am Ende" + +#: .\inventory\models\settings.py:24 +msgid "Currency symbol after amount" +msgstr "Zeige das Währungssymbol nach der Zahl an" + +#: .\inventory\models\settings.py:28 .\inventory\models\settings.py:31 +#: .\inventory\models\settings.py:32 +msgid "Settings" +msgstr "Einstellungen" + +#: .\inventory\models\tag.py:16 +#: .\inventory\templates\inventory\tag_detail.html:5 +msgid "Tag" +msgstr "Tag" + +#: .\inventory\models\workshop.py:11 +msgid "Show boxes" +msgstr "Behälter anzeigen" + +#: .\inventory\models\workshop.py:13 +msgid "Allow boxes to be defined directly in this workshop" +msgstr "Erlaube Behälter in dieser Werkstatt" + +#: .\inventory\models\workshop.py:26 .\inventory\templates\base.html:61 +#: .\inventory\templates\inventory\workshop_detail.html:5 +msgid "Workshop" +msgstr "Werkstatt" + +#: .\inventory\models\workshop.py:27 +#: .\inventory\templates\inventory\tag_detail.html:23 +#: .\inventory\templates\inventory\workshop_list.html:5 +#: .\inventory\templates\inventory\workshop_list.html:8 +msgid "Workshops" +msgstr "Werkstätten" + +#: .\inventory\templates\base.html:43 .\inventory\templates\base.html:46 +#: .\inventory\templates\base.html:47 +#: .\inventory\templates\inventory\distributor_detail.html:45 +#: .\inventory\templates\inventory\distributor_detail.html:58 +#: .\inventory\templates\inventory\search.html:5 +#: .\inventory\templates\inventory\search.html:8 +#: .\inventory\templates\inventory\search.html:13 +#: .\inventory\templates\inventory\search.html:14 +#: .\inventory\templates\inventory\search_result.html:6 +#: .\inventory\templates\inventory\search_result.html:9 +#: .\inventory\templates\inventory\search_result.html:14 +#: .\inventory\templates\inventory\search_result.html:15 +#: .\inventory\templates\inventory\tag_list.html:43 +#: .\inventory\templates\inventory\tag_list.html:44 +msgid "Search" +msgstr "Suchen" + +#: .\inventory\templates\base.html:68 +msgid "Logout" +msgstr "Ausloggen" + +#: .\inventory\templates\inventory\area_detail.html:16 +#: .\inventory\templates\inventory\area_detail.html:36 +#: .\inventory\templates\inventory\area_detail.html:62 +#: .\inventory\templates\inventory\box-detail.html:20 +#: .\inventory\templates\inventory\cell.html:19 +#: .\inventory\templates\inventory\distributor_detail.html:17 +#: .\inventory\templates\inventory\distributor_list.html:33 +#: .\inventory\templates\inventory\item_detail.html:18 +#: .\inventory\templates\inventory\item_list.html:28 +#: .\inventory\templates\inventory\manufacturer_detail.html:17 +#: .\inventory\templates\inventory\manufacturer_list.html:33 +#: .\inventory\templates\inventory\tag_detail.html:16 +#: .\inventory\templates\inventory\tag_detail.html:33 +#: .\inventory\templates\inventory\tag_detail.html:53 +#: .\inventory\templates\inventory\tag_detail.html:78 +#: .\inventory\templates\inventory\tag_detail.html:103 +#: .\inventory\templates\inventory\workshop_detail.html:16 +#: .\inventory\templates\inventory\workshop_detail.html:34 +#: .\inventory\templates\inventory\workshop_detail.html:59 +#: .\inventory\templates\inventory\workshop_list.html:21 +msgid "Edit" +msgstr "Bearbeiten" + +#: .\inventory\templates\inventory\area_detail.html:41 +#: .\inventory\templates\inventory\workshop_detail.html:39 +msgid "No areas defined" +msgstr "Keine Bereiche definiert" + +#: .\inventory\templates\inventory\area_detail.html:47 +#: .\inventory\templates\inventory\workshop_detail.html:45 +msgid "Create new area..." +msgstr "Neuen Bereich anlegen..." + +#: .\inventory\templates\inventory\area_detail.html:67 +#: .\inventory\templates\inventory\workshop_detail.html:64 +msgid "No containers defined" +msgstr "Keine Behälter definiert..." + +#: .\inventory\templates\inventory\area_detail.html:73 +#: .\inventory\templates\inventory\workshop_detail.html:70 +msgid "Create new container..." +msgstr "Neuen Behälter anlegen..." + +#: .\inventory\templates\inventory\box-detail.html:12 +#: .\inventory\templates\inventory\distributor_detail.html:9 +#: .\inventory\templates\inventory\item_detail.html:10 +#: .\inventory\templates\inventory\manufacturer_detail.html:9 +#: .\inventory\templates\inventory\tag_detail.html:8 +#: .\inventory\templates\inventory\workshop_detail.html:8 +msgid "Back" +msgstr "Zurück" + +#: .\inventory\templates\inventory\cell.html:21 +msgid "Details" +msgstr "Details" + +#: .\inventory\templates\inventory\cell.html:26 +#: .\inventory\templates\inventory\item_detail.html:42 +msgid "Low stock" +msgstr "Wenig Vorrat" + +#: .\inventory\templates\inventory\cell.html:43 +msgid "New item..." +msgstr "Neues Teil..." + +#: .\inventory\templates\inventory\distributor_detail.html:57 +msgid "Search query" +msgstr "Suchanfrage" + +#: .\inventory\templates\inventory\distributor_detail.html:83 +#: .\inventory\templates\inventory\item_detail.html:60 +#: .\inventory\templates\inventory\manufacturer_detail.html:51 +#: .\inventory\templates\inventory\tag_list.html:50 +msgid "No tags" +msgstr "Keine Tags" + +#: .\inventory\templates\inventory\distributor_list.html:8 +#: .\inventory\templates\inventory\tag_list.html:9 +#: .\inventory\templates\inventory\workshop_list.html:8 +#: .\inventory\templates\registration\login.html:5 +msgid "Inventory management" +msgstr "Inventarverwaltung" + +#: .\inventory\templates\inventory\distributor_list.html:43 +msgid "Create new distributor..." +msgstr "Neuen Händler anlegen..." + +#: .\inventory\templates\inventory\item_detail.html:36 +#: .\inventory\templates\inventory\item_detail.html:45 +msgid "Amount" +msgstr "Anzahl" + +#: .\inventory\templates\inventory\item_detail.html:46 +msgid "Update" +msgstr "Speichern" + +#: .\inventory\templates\inventory\item_detail.html:108 +msgid "Sum" +msgstr "Summe" + +#: .\inventory\templates\inventory\item_detail.html:114 +msgid "Last ordered" +msgstr "Zuletzt bestellt" + +#: .\inventory\templates\inventory\manufacturer_list.html:8 +msgid "Inventory Management" +msgstr "Inventarverwaltung" + +#: .\inventory\templates\inventory\manufacturer_list.html:42 +msgid "Create new manufacturer..." +msgstr "Neuen Hersteller anlegen..." + +#: .\inventory\templates\inventory\pagination.html:6 +#: .\inventory\templates\inventory\search_result.html:33 +msgid "First page" +msgstr "Erste Seite" + +#: .\inventory\templates\inventory\pagination.html:7 +#: .\inventory\templates\inventory\search_result.html:34 +msgid "Previous page" +msgstr "Vorherige Seite" + +#: .\inventory\templates\inventory\pagination.html:13 +#: .\inventory\templates\inventory\search_result.html:38 +msgid "Next page" +msgstr "Nächste Seite" + +#: .\inventory\templates\inventory\pagination.html:14 +#: .\inventory\templates\inventory\search_result.html:39 +msgid "Last page" +msgstr "Letzte Seite" + +#: .\inventory\templates\inventory\search_result.html:18 +msgid "Search result for" +msgstr "Suchergebnisse für" + +#: .\inventory\templates\inventory\search_result.html:27 +msgid "Nothing found" +msgstr "Nichts gefunden" + +#: .\inventory\templates\inventory\search_result_item.html:11 +msgid "Contained in" +msgstr "Im Behälter" + +#: .\inventory\templates\inventory\set_index.html:10 +msgid "Currently set as index page" +msgstr "Momentan als Index-Seite definiert" + +#: .\inventory\templates\inventory\set_index.html:12 +msgid "Promote to index page" +msgstr "Als Index-Seite definieren" + +#: .\inventory\templates\inventory\tag_list.html:55 +msgid "Create new tag..." +msgstr "Neues Tag anlegen..." + +#: .\inventory\templates\inventory\workshop_list.html:30 +msgid "Create new workshop..." +msgstr "Neue Werkstatt anlegen..." + +#: .\inventory\templates\registration\login.html:5 +msgid "Login" +msgstr "Einloggen" + +#: .\inventory\templates\registration\login.html:11 +msgid "Your username and password didn't match. Please try again." +msgstr "" +"Benutzername und Passwort passen nicht zusammen, bitte versuche es noch " +"einmal." + +#: .\inventory\templates\registration\login.html:17 +msgid "" +"\n" +" Your account doesn't have access to this page. To proceed,\n" +" please login with an account that has access.\n" +" " +msgstr "" +"\n" +" Dein Zugang hat keinen Zugriff auf diese Seite.\n" +" Zum Fortfahren bitte mit einem Zugang einloggen der die\n" +" entsprechenden Rechte besitzt!\n" +" " + +#: .\inventory\templates\registration\login.html:24 +msgid "" +"\n" +" Please login to see this page.\n" +" " +msgstr "" +"\n" +" Bitte einloggen um auf diese Seite Zugriff zu bekommen.\n" +" " + +#: .\inventory\templates\registration\login.html:49 +msgid "Lost password?" +msgstr "Passwort vergessen?" + +#: .\inventory_project\settings.py:121 +msgid "German" +msgstr "Deutsch" + +#: .\inventory_project\settings.py:122 +msgid "English" +msgstr "Englisch" diff --git a/inventory/models/area.py b/inventory/models/area.py index 275127d..0a5834f 100644 --- a/inventory/models/area.py +++ b/inventory/models/area.py @@ -1,14 +1,19 @@ +from django.utils.translation import gettext_lazy as _ from django.urls import reverse from django.db import models from .container import Container, CanBeContained class Area(CanBeContained, Container): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096) - show_sub_area = models.BooleanField(default=True, help_text="Allow sub-areas to be defined in this area") - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096) + show_sub_area = models.BooleanField( + _("Show sub area"), + default=True, + help_text=_("Allow sub-areas to be defined in this area") + ) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) @property def url(self): @@ -16,3 +21,5 @@ class Area(CanBeContained, Container): class Meta: ordering = ("name", ) + verbose_name = _("Area") + verbose_name_plural = _("Areas") diff --git a/inventory/models/box.py b/inventory/models/box.py index eca2fdc..f54e738 100644 --- a/inventory/models/box.py +++ b/inventory/models/box.py @@ -1,3 +1,4 @@ +from django.utils.translation import gettext_lazy as _ from django.urls import reverse from django.utils.text import slugify from django.template.loader import get_template, TemplateDoesNotExist @@ -6,15 +7,12 @@ from .container import CanBeContained, Container class Box(CanBeContained, Container): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096) - tags = models.ManyToManyField('inventory.Tag', blank=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096) + tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) - - class Meta: - verbose_name_plural = 'Boxes' + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) @property def template_name(self): @@ -34,3 +32,5 @@ class Box(CanBeContained, Container): class Meta: ordering = ("name", ) + verbose_name = _("Box") + verbose_name_plural = _("Boxes") diff --git a/inventory/models/container.py b/inventory/models/container.py index bfb81fb..b68508a 100644 --- a/inventory/models/container.py +++ b/inventory/models/container.py @@ -1,9 +1,16 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models from django.apps import apps class Container(models.Model): - layout = models.ForeignKey('inventory.Layout', on_delete=models.PROTECT, null=True, blank=True) + layout = models.ForeignKey( + 'inventory.Layout', + verbose_name=_("Layout"), + on_delete=models.PROTECT, + null=True, + blank=True + ) @property def subclass(self): @@ -25,7 +32,7 @@ class Container(models.Model): _, obj = self.subclass if obj is not None: return obj.name - return 'Container' + return _("Container") @property def url(self): @@ -34,15 +41,19 @@ class Container(models.Model): return obj.url return None + class Meta: + verbose_name = _("Container") + verbose_name_plural = _("Containers") class CanBeContained(models.Model): container = models.ForeignKey( 'inventory.Container', + verbose_name=_("Container"), related_name="%(class)s_related", null=True, on_delete=models.CASCADE ) - index = models.PositiveIntegerField('Index of compartment in layout') + index = models.PositiveIntegerField(_("Index of compartment in layout")) class Meta: abstract = True diff --git a/inventory/models/distributor.py b/inventory/models/distributor.py index 554d15c..52ee73c 100644 --- a/inventory/models/distributor.py +++ b/inventory/models/distributor.py @@ -1,22 +1,25 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class Distributor(models.Model): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096) - web_link = models.URLField(null=True, blank=True) - search_link = models.URLField(help_text='Use {} for search placeholder', null=True, blank=True) - phone = models.CharField(max_length=128, null=True, blank=True) - email = models.EmailField(null=True, blank=True, default=None) - icon = models.ImageField(null=True, blank=True) - tags = models.ManyToManyField('inventory.Tag', blank=True) + web_link = models.URLField(_("Web link"), null=True, blank=True) + search_link = models.URLField(_("Search link"), help_text=_("Use {} for search placeholder"), null=True, blank=True) + phone = models.CharField(_("Phone"), max_length=128, null=True, blank=True) + email = models.EmailField(_("E-Mail"), null=True, blank=True, default=None) + icon = models.ImageField(_("Icon"), null=True, blank=True) + tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) def __str__(self): return self.name class Meta: - ordering = ("name", ) \ No newline at end of file + ordering = ("name", ) + verbose_name = _("Distributor") + verbose_name_plural = _("Distributors") diff --git a/inventory/models/documentation.py b/inventory/models/documentation.py index d044092..e66e932 100644 --- a/inventory/models/documentation.py +++ b/inventory/models/documentation.py @@ -1,10 +1,11 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class Documentation(models.Model): - name = models.CharField(max_length=255, unique=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) file = models.FileField() @@ -13,3 +14,5 @@ class Documentation(models.Model): class Meta: ordering = ("name", ) + verbose_name = _("Documentation") + verbose_name_plural = _("Documentation") diff --git a/inventory/models/form_factor.py b/inventory/models/form_factor.py index 767ada2..d68815c 100644 --- a/inventory/models/form_factor.py +++ b/inventory/models/form_factor.py @@ -1,16 +1,17 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class FormFactor(models.Model): - name = models.CharField(max_length=255, unique=True, db_collation="numeric") - description = models.CharField(max_length=4096, db_collation="numeric") + name = models.CharField(_("Name"), max_length=255, unique=True, db_collation="numeric") + description = models.CharField(_("Description"), max_length=4096, db_collation="numeric") - icon = models.ImageField(null=True, blank=True) - datasheet = models.FileField(null=True, blank=True) - tags = models.ManyToManyField('inventory.Tag', blank=True) + icon = models.ImageField(_("Icon"), null=True, blank=True) + datasheet = models.FileField(_("Datasheet"), null=True, blank=True) + tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) def __str__(self): items = [self.name] @@ -19,3 +20,5 @@ class FormFactor(models.Model): class Meta: ordering = ("name", ) + verbose_name = _("Form factor") + verbose_name_plural = _("Form factors") diff --git a/inventory/models/item.py b/inventory/models/item.py index 676223f..474583a 100644 --- a/inventory/models/item.py +++ b/inventory/models/item.py @@ -1,32 +1,80 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models from .container import CanBeContained class Item(CanBeContained): - name = models.TextField(max_length=255, db_collation="numeric") - description = models.CharField(max_length=4096, db_collation="numeric") - size = models.PositiveIntegerField(default=1, help_text="Number of sub-compartments this item takes up") - form_factor = models.ForeignKey('inventory.FormFactor', null=True, blank=True, on_delete=models.PROTECT) - manufacturer = models.ForeignKey('inventory.Manufacturer', null=True, blank=True, on_delete=models.PROTECT) - distributor = models.ForeignKey('inventory.Distributor', null=True, blank=True, on_delete=models.PROTECT) - distributor_item_no = models.CharField(max_length=255, null=True, blank=True) - price = models.DecimalField(decimal_places=3, max_digits=7, null=True, blank=True) - last_ordered_on = models.DateField(null=True, blank=True) - documentation = models.ManyToManyField('inventory.Documentation', related_name='items', blank=True) - tags = models.ManyToManyField('inventory.Tag', blank=True) + name = models.TextField(_("Name"), max_length=255, db_collation="numeric") + description = models.CharField(_("Description"), max_length=4096, db_collation="numeric") + size = models.PositiveIntegerField( + _("Size"), + default=1, + help_text=_("Number of sub-compartments this item takes up") + ) + form_factor = models.ForeignKey( + 'inventory.FormFactor', + verbose_name=_("Form factor"), + null=True, + blank=True, + on_delete=models.PROTECT + ) + manufacturer = models.ForeignKey( + 'inventory.Manufacturer', + verbose_name=_("Manufacturer"), + null=True, + blank=True, + on_delete=models.PROTECT + ) + distributor = models.ForeignKey( + 'inventory.Distributor', + verbose_name=_("Distributor"), + null=True, + blank=True, + on_delete=models.PROTECT + ) + distributor_item_no = models.CharField( + _("Distributor item no."), + max_length=255, + null=True, + blank=True + ) + price = models.DecimalField( + _("Price"), + decimal_places=3, + max_digits=7, + null=True, + blank=True + ) + last_ordered_on = models.DateField(_("Last ordered on"), null=True, blank=True) + documentation = models.ManyToManyField( + 'inventory.Documentation', + verbose_name=_("Documentation"), + related_name='items', + blank=True + ) + tags = models.ManyToManyField( + 'inventory.Tag', + verbose_name=_("Tags"), + blank=True + ) count = models.PositiveIntegerField( + _("Count"), default=1, null=False, - help_text="Number of parts available" + help_text=_("Number of parts available") ) low_count = models.PositiveIntegerField( + _("Low watermark"), default=0, null=False, - help_text="Low watermark on which to alert ordering more" + help_text=_("Low watermark on which to alert ordering more") ) + metadata = models.JSONField(_("Custom metadata, used by templates"), blank=True, null=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) def __str__(self): items = [self.name, self.description] @@ -47,3 +95,5 @@ class Item(CanBeContained): class Meta: ordering = ("name", ) + verbose_name = _("Item") + verbose_name_plural = _("Items") diff --git a/inventory/models/layout.py b/inventory/models/layout.py index 1358194..645ec5f 100644 --- a/inventory/models/layout.py +++ b/inventory/models/layout.py @@ -1,16 +1,19 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class Layout(models.Model): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) - data = models.JSONField() - template_name = models.CharField(max_length=255, null=True, blank=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) + data = models.JSONField(_("Data")) + template_name = models.CharField(_("Template name"), max_length=255, null=True, blank=True) def __str__(self): return self.name class Meta: ordering = ("name", ) + verbose_name = _("Layout") + verbose_name_plural = _("Layouts") diff --git a/inventory/models/manufacturer.py b/inventory/models/manufacturer.py index 9a94be5..57e4ead 100644 --- a/inventory/models/manufacturer.py +++ b/inventory/models/manufacturer.py @@ -1,19 +1,22 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class Manufacturer(models.Model): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096, blank=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096, blank=True) - web_link = models.URLField(null=True, blank=True) - icon = models.ImageField(null=True, blank=True) - tags = models.ManyToManyField('inventory.Tag', blank=True) + web_link = models.URLField(_("Web link"), null=True, blank=True) + icon = models.ImageField(_("Icon"), null=True, blank=True) + tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) def __str__(self): return self.name class Meta: ordering = ("name", ) + verbose_name = _("Manufacturer") + verbose_name_plural = _("Manufacturers") diff --git a/inventory/models/settings.py b/inventory/models/settings.py index 71b066b..2953a9a 100644 --- a/inventory/models/settings.py +++ b/inventory/models/settings.py @@ -1,3 +1,5 @@ +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext from django.db import models @@ -8,20 +10,23 @@ class Settings(models.Model): default=None, null=True, blank=True, + help_text=_("Default container to display when calling the index page") ) track_amount = models.BooleanField( default=False, - help_text="Show item count in overview and warn on low watermarks" + help_text=_("Show item count in overview and warn on low watermarks") ) - currency = models.CharField(max_length=30, help_text="Currency name", default="Euro") - currency_symbol = models.CharField(max_length=20, default="€") + currency = models.CharField(_("Currency"), max_length=30, help_text=_("Currency name"), default="Euro") + currency_symbol = models.CharField(_("Currency symbol"), max_length=20, default="€") currency_symbol_position = models.BooleanField( + _("Currency symbol at end"), default=True, - help_text="Currency symbol after amount" + help_text=_("Currency symbol after amount") ) def __str__(self): - return 'Settings' + return gettext("Settings") class Meta: - verbose_name_plural = 'Settings' + verbose_name = _("Settings") + verbose_name_plural = _("Settings") diff --git a/inventory/models/tag.py b/inventory/models/tag.py index 895db0d..ac5a0e2 100644 --- a/inventory/models/tag.py +++ b/inventory/models/tag.py @@ -1,14 +1,17 @@ +from django.utils.translation import gettext_lazy as _ from django.db import models class Tag(models.Model): - name = models.CharField(max_length=255, unique=True, db_collation="numeric") - description = models.CharField(max_length=4096, db_collation="numeric") - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + name = models.CharField(_("Name"), max_length=255, unique=True, db_collation="numeric") + description = models.CharField(_("Description"), max_length=4096, db_collation="numeric") + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) def __str__(self): return self.name class Meta: ordering = ['name', 'pk'] + verbose_name = _("Tag") + verbose_name_plural = _("Tags") diff --git a/inventory/models/workshop.py b/inventory/models/workshop.py index d25cd4f..c06902f 100644 --- a/inventory/models/workshop.py +++ b/inventory/models/workshop.py @@ -1,16 +1,21 @@ +from django.utils.translation import gettext_lazy as _ from django.urls import reverse from django.db import models from .container import Container class Workshop(Container): - name = models.CharField(max_length=255, unique=True) - description = models.CharField(max_length=4096) - show_boxes = models.BooleanField(default=True, help_text="Allow boxes to be defined directly in this workshop") - tags = models.ManyToManyField('inventory.Tag', blank=True) + name = models.CharField(_("Name"), max_length=255, unique=True) + description = models.CharField(_("Description"), max_length=4096) + show_boxes = models.BooleanField( + _("Show boxes"), + default=True, + help_text=_("Allow boxes to be defined directly in this workshop") + ) + tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True) - created_at = models.DateTimeField(auto_now_add=True) - changed_at = models.DateTimeField(auto_now=True) + created_at = models.DateTimeField(_("Created at"), auto_now_add=True) + changed_at = models.DateTimeField(_("Changed at"), auto_now=True) @property def url(self): @@ -18,3 +23,5 @@ class Workshop(Container): class Meta: ordering = ("name", ) + verbose_name = _("Workshop") + verbose_name_plural = _("Workshops") diff --git a/inventory/templates/base.html b/inventory/templates/base.html index 908708a..8e9e976 100644 --- a/inventory/templates/base.html +++ b/inventory/templates/base.html @@ -1,6 +1,8 @@ {% load static %} +{% load i18n %} +{% get_current_language as LANGUAGE_CODE %} - + @@ -38,32 +40,32 @@ } } - +
- - + +
  • - +
  • - +
  • - +
  • - +
  • {% if user.is_authenticated %}
    {% csrf_token %} - +
    {% endif %} diff --git a/inventory/templates/inventory/area_detail.html b/inventory/templates/inventory/area_detail.html index 02e6d0b..748f2ae 100644 --- a/inventory/templates/inventory/area_detail.html +++ b/inventory/templates/inventory/area_detail.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% block title %}{{ area.name }}{% endblock %} @@ -12,7 +13,7 @@ {% block header_icons %} {% if user.is_staff %}
  • - +
  • {% include 'inventory/set_index.html' with item=area is_index=is_index %} {% endif %} @@ -21,7 +22,7 @@ {% block content %} {% if area.show_sub_area %} -

    Areas

    +

    {% translate 'Areas' %}

    @@ -32,22 +33,22 @@ {% empty %} - + {% endfor %}
    {% if user.is_staff %} - + {% endif %}
    No areas defined
    {% translate 'No areas defined' %}
    {% if user.is_staff %} -

    Create new area...

    +

    {% translate 'Create new area...' %}

    {% endif %} {% endif %} -

    Containers

    +

    {% translate 'Containers' %}

    @@ -58,17 +59,17 @@ {% empty %} - + {% endfor %}
    {% if user.is_staff %} - + {% endif %}
    No containers defined
    {% translate 'No containers defined' %}
    {% if user.is_staff %} -

    Create new container...

    +

    {% translate 'Create new container...' %}

    {% endif %} {% endblock %} \ No newline at end of file diff --git a/inventory/templates/inventory/box-detail.html b/inventory/templates/inventory/box-detail.html index 67976c8..0efd05b 100644 --- a/inventory/templates/inventory/box-detail.html +++ b/inventory/templates/inventory/box-detail.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% block head %} @@ -8,7 +9,7 @@ {% block title %}{{ object.name }}{% endblock %} {% block header_bar %} - + {{ object.name }} {{ object.description}} {% endblock %} @@ -16,7 +17,7 @@ {% block header_icons %} {% if user.is_staff %}
  • - +
  • {% include 'inventory/set_index.html' with item=object is_index=is_index %} {% endif %} diff --git a/inventory/templates/inventory/box-generic.html b/inventory/templates/inventory/box-generic.html index 995ea02..86e8ef2 100644 --- a/inventory/templates/inventory/box-generic.html +++ b/inventory/templates/inventory/box-generic.html @@ -1,9 +1,10 @@ {% extends "inventory/box-detail.html" %} +{% load i18n %} {% block content %} {% if box.box_related.exists %} -

    Boxes

    +

    {% translate 'Boxes' %}

      {% for b in box.box_related.all %}
    • {{ b.name }} ({{ b.layout.name }})
    • @@ -12,7 +13,7 @@ {% endif %} {% if box.item_related.exists %} -

      Items

      +

      {% translate 'Items' %}

        {% for item in box.item_related.all %}
      • {{ item.name }}
      • diff --git a/inventory/templates/inventory/cell.html b/inventory/templates/inventory/cell.html index 4c6281e..18e22ae 100644 --- a/inventory/templates/inventory/cell.html +++ b/inventory/templates/inventory/cell.html @@ -1,4 +1,5 @@ {% load static %} +{% load i18n %} {% load admin_urls %} {% load currency %} @@ -12,17 +13,17 @@
        {% if item.documentation.all %} - + {% endif %} {% if user.is_staff %} - + {% endif %} - +
        {% if settings.track_amount %} {% if item.count <= item.low_count %} -
        {{ item.count }}
        +
        {{ item.count }}
        {% else %}
        {{ item.count }}
        {% endif %} @@ -39,7 +40,7 @@ {% else %}
        {% if user.is_staff %} - + {% endif %}
        {% endif %} diff --git a/inventory/templates/inventory/distributor_detail.html b/inventory/templates/inventory/distributor_detail.html index 5dbd787..98c1725 100644 --- a/inventory/templates/inventory/distributor_detail.html +++ b/inventory/templates/inventory/distributor_detail.html @@ -1,19 +1,20 @@ {% extends "base.html" %} +{% load i18n %} {% load static %} {% load formatstring %} -{% block title %}Distributor: {{ distributor }}{% endblock %} +{% block title %}{% translate 'Distributor' %}: {{ distributor }}{% endblock %} {% block header_bar %} - - Distributor: {{ distributor.name }} + + {% translate 'Distributor' %}: {{ distributor.name }} {{ distributor.description }} {% endblock %} {% block header_icons %} {% if user.is_staff %}
      • - +
      • {% endif %} {% endblock %} @@ -22,26 +23,26 @@ - + - + {% if distributor.icon %} - + {% endif %} - + {% if distributor.search_link %} - + {% endif %} {% if distributor.phone %} - + {% endif %} {% if distributor.email %} - + {% endif %} - + - + {% if distributor.created_at != distributor.changed_at %} - + {% endif %}
        Name{% translate 'Name' %} {{ distributor.name }}
        Description{% translate 'Description' %} {{ distributor.description }}
        Icon{% translate 'Icon' %}
        Link{% translate 'Web link' %} {% if distributor.web_link %}{{ distributor.web_link }}{% else %}-{% endif %}
        Search{% translate 'Search' %}
        - - - + +
        Phone{% translate 'Phone' %} {{ distributor.phone }}
        Email{% translate 'E-Mail' %} {{ distributor.email }}
        Tags{% translate 'Tags' %}
          {% for tag in distributor.tags.all %}
        • {{ tag.name }}
        • {% empty %} - No tags + {% translate 'No tags' %} {% endfor %}
        Created at{{ distributor.created_at }}
        {% translate 'Created at' %}{{ distributor.created_at }}
        Last change{{ distributor.changed_at }}
        {% translate 'Changed at' %}{{ distributor.changed_at }}
        diff --git a/inventory/templates/inventory/distributor_list.html b/inventory/templates/inventory/distributor_list.html index 89a1629..2ddb359 100644 --- a/inventory/templates/inventory/distributor_list.html +++ b/inventory/templates/inventory/distributor_list.html @@ -1,18 +1,19 @@ {% extends "base.html" %} +{% load i18n %} {% load static %} -{% block title %}Distributors{% endblock %} +{% block title %}{% translate 'Distributors' %}{% endblock %} {% block header_bar %} - Inventory management - Distributors + {% translate 'Inventory management' %} - {% translate 'Distributors' %} {% endblock %} {% block content %} - - + + @@ -29,7 +30,7 @@ @@ -39,7 +40,7 @@ {% if user.is_staff %} -

        Create new distributor...

        +

        {% translate 'Create new distributor...' %}

        {% endif %} diff --git a/inventory/templates/inventory/item_detail.html b/inventory/templates/inventory/item_detail.html index e2a9316..9fb33a9 100644 --- a/inventory/templates/inventory/item_detail.html +++ b/inventory/templates/inventory/item_detail.html @@ -1,12 +1,13 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% load formatstring %} {% load currency %} {% block title %}{{ item }}{% endblock %} {% block header_bar %} - + {{ item.name }} {{ item.description }}{% if item.form_factor %}, {{ item.form_factor }}{% endif %} {% endblock %} @@ -14,7 +15,7 @@ {% block header_icons %} {% if user.is_staff %}
      • - +
      • {% endif %} {% endblock %} @@ -23,40 +24,40 @@
        LogoDistributor{% translate 'Icon' %}{% translate 'Distributor' %}
        {% if user.is_staff %} - + {% endif %}
        - + - + {% if settings.track_amount %} - + {% endif %} - + @@ -64,7 +65,7 @@ {% if item.form_factor %} - + - + - + - - + + {% endif %} {% if item.last_ordered_on %} - + {% endif %} {% if item.distributor_item_no %} - + {% endif %} - + {% if item.created_at != item.changed_at %} - + {% endif %} {% if item.documentation.exists %} - + @@ -26,7 +27,7 @@
        Name{% translate 'Name' %} {{ item.name }}
        Description{% translate 'Description' %} {{ item.description }}
        Amount{% translate 'Amount' %}
        {% csrf_token %} - - + +
        - Low watermark: {{ item.low_count }} + {% translate 'Low watermark' %}: {{ item.low_count }}
        Tags{% translate 'Tags' %}
          {% for tag in item.all_tags %}
        • {{ tag.name }}
        • {% empty %} - No tags + {% translate 'No tags' %} {% endfor %}
        Form factor{% translate 'Form factor' %} {% if item.form_factor.datasheet %} @@ -81,7 +82,7 @@ {% if item.manufacturer %}
        Manufacturer{% translate 'Manufacturer' %} {% if item.manufacturer.icon %}{% endif %}{{ item.manufacturer.name }} @@ -92,7 +93,7 @@ {% if item.distributor %}
        Distributor{% translate 'Distributor' %} {% if item.distributor.icon %}{% endif %}{{ item.distributor.name }} @@ -103,35 +104,35 @@ {% if item.price %}
        Price{{ item.price | currency:"detail" }} {% if settings.track_amount %}(sum: {{ item.value | currency:"long" }}){% endif %}{% translate 'Price' %}{{ item.price | currency:"detail" }} {% if settings.track_amount %}({% translate 'Sum' %}: {{ item.value | currency:"long" }}){% endif %}
        Last ordered{% translate 'Last ordered' %} {{ item.last_ordered_on }}
        Link{% translate 'Search link' %} {% formatstring item.distributor.search_link item.distributor_item_no %}
        Created at{{ item.created_at }}
        {% translate 'Created at' %}{{ item.created_at }}
        Last change{{ item.changed_at }}
        {% translate 'Changed at' %}{{ item.changed_at }}
        Datasheets{% translate 'Documentation' %}
          {% for doc in item.documentation.all %} diff --git a/inventory/templates/inventory/item_list.html b/inventory/templates/inventory/item_list.html index 694c1b4..e97bd8a 100644 --- a/inventory/templates/inventory/item_list.html +++ b/inventory/templates/inventory/item_list.html @@ -1,17 +1,18 @@ +{% load i18n %} {% load static %} - + - - + + {% if show_manufacturer %} - + {% endif %} {% if show_distributor %} - + {% endif %} @@ -21,10 +22,10 @@ diff --git a/inventory/templates/inventory/manufacturer_detail.html b/inventory/templates/inventory/manufacturer_detail.html index c5c675a..95fd99d 100644 --- a/inventory/templates/inventory/manufacturer_detail.html +++ b/inventory/templates/inventory/manufacturer_detail.html @@ -1,19 +1,20 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% load formatstring %} -{% block title %}Manufacturer: {{ manufacturer }}{% endblock %} +{% block title %}{% translate 'Manufacturer' %}: {{ manufacturer }}{% endblock %} {% block header_bar %} - - Manufacturer: {{ manufacturer.name }} + + {% translate 'Manufacturer' %}: {{ manufacturer.name }} {{ manufacturer.description }} {% endblock %} {% block header_icons %} {% if user.is_staff %}
        • - +
        • {% endif %} {% endblock %} @@ -22,45 +23,45 @@
          Name{% translate 'Name' %} DescriptionContainer{% translate 'Description' %}{% translate 'Container' %}Manufacturer{% translate 'Manufacturer' %}Distributor{% translate 'Distributor' %}
          {{ item.name }} {% if item.documentation.all %} - + {% endif %} {% if user.is_staff %} - + {% endif %} {{ item.description }}
          - + - + {% if manufacturer.icon %} - + {% endif %} - + - + - + {% if manufacturer.created_at != manufacturer.changed_at %} - + {% endif %}
          Name{% translate 'Name' %} {{ manufacturer.name }}
          Description{% translate 'Description' %} {{ manufacturer.description }}
          Icon{% translate 'Icon' %}
          Link{% translate 'Web link' %} {% if manufacturer.web_link %}{{ manufacturer.web_link }}{% else %}-{% endif %}
          Tags{% translate 'Tags' %}
            {% for tag in manufacturer.tags.all %}
          • {{ tag.name }}
          • {% empty %} - No tags + {% translate 'No tags' %} {% endfor %}
          Created at{{ manufacturer.created_at }}
          {% translate 'Created at' %}{{ manufacturer.created_at }}
          Last change{{ manufacturer.changed_at }}
          {% translate 'Changed at' %}{{ manufacturer.changed_at }}
          -

          Items

          +

          {% translate 'Items' %}

          {% url 'manufacturer-detail' manufacturer.id as this_url %} {% include "inventory/pagination.html" with url=this_url id="paginator_top" param="item" paginator=items %} diff --git a/inventory/templates/inventory/manufacturer_list.html b/inventory/templates/inventory/manufacturer_list.html index a94a0b5..9bd621e 100644 --- a/inventory/templates/inventory/manufacturer_list.html +++ b/inventory/templates/inventory/manufacturer_list.html @@ -1,18 +1,19 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} -{% block title %}Manufacturers{% endblock %} +{% block title %}{% translate 'Manufacturers' %}{% endblock %} {% block header_bar %} - Inventory management - Manufacturers + {% translate 'Inventory Management' %} - {% translate 'Manufacturers' %} {% endblock %} {% block content %} - - + + @@ -29,7 +30,7 @@ @@ -38,7 +39,7 @@
          LogoManufacturer{% translate 'Icon' %}{% translate 'Manufacturer' %}
          {% if user.is_staff %} - + {% endif %}
          {% if user.is_staff %} -

          Create new manufacturer...

          +

          {% translate 'Create new manufacturer...' %}

          {% endif %} diff --git a/inventory/templates/inventory/pagination.html b/inventory/templates/inventory/pagination.html index 1a99d24..20db3bc 100644 --- a/inventory/templates/inventory/pagination.html +++ b/inventory/templates/inventory/pagination.html @@ -1,15 +1,16 @@ {% load static %} +{% load i18n %} diff --git a/inventory/templates/inventory/search.html b/inventory/templates/inventory/search.html index 53a0af3..12fbcc4 100644 --- a/inventory/templates/inventory/search.html +++ b/inventory/templates/inventory/search.html @@ -1,15 +1,16 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} -{% block title %}Search{% endblock %} +{% block title %}{% translate 'Search' %}{% endblock %} {% block header_bar %} - Search + {% translate 'Search' %} {% endblock %} {% block content %}
          - - + +
          {% endblock %} \ No newline at end of file diff --git a/inventory/templates/inventory/search_result.html b/inventory/templates/inventory/search_result.html index ee74ecd..ff55f60 100644 --- a/inventory/templates/inventory/search_result.html +++ b/inventory/templates/inventory/search_result.html @@ -1,20 +1,21 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% load hilight %} -{% block title %}Search{% endblock %} +{% block title %}{% translate 'Search' %}{% endblock %} {% block header_bar %} - Search + {% translate 'Search' %} {% endblock %} {% block content %}
          - - + +
          -

          Search result for '{{ q }}'

          +

          {% translate 'Search result for' %} '{{ q }}'

          {% for result in results %}
          @@ -23,19 +24,19 @@
          {% empty %} -

          Noting found

          +

          {% translate 'Nothing found' %}

          {% endfor %} {% if pages > 1 %} {% endif %} diff --git a/inventory/templates/inventory/search_result_item.html b/inventory/templates/inventory/search_result_item.html index ea8c9e3..f4c2d7d 100644 --- a/inventory/templates/inventory/search_result_item.html +++ b/inventory/templates/inventory/search_result_item.html @@ -1,17 +1,16 @@ {% load static %} +{% load i18n %} {% load hilight %}

          {% if item.documentation.all %} - + {% endif %} {{ item | hilight:tokens }} {{item.form_factor.name}}

          -

          Contained in: {{ item.container.display_name }}

          +

          {% translate 'Contained in' %}: {{ item.container.display_name }}

            {% for tag in item.all_tags %}
          • {{ tag.name }}
          • - {% empty %} - No tags {% endfor %}
          diff --git a/inventory/templates/inventory/set_index.html b/inventory/templates/inventory/set_index.html index 906a896..5969b29 100644 --- a/inventory/templates/inventory/set_index.html +++ b/inventory/templates/inventory/set_index.html @@ -1,4 +1,5 @@ {% load static %} +{% load i18n %}
        • @@ -6,9 +7,9 @@
          diff --git a/inventory/templates/inventory/tag_detail.html b/inventory/templates/inventory/tag_detail.html index d90407b..b189cba 100644 --- a/inventory/templates/inventory/tag_detail.html +++ b/inventory/templates/inventory/tag_detail.html @@ -1,10 +1,11 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} -{% block title %}Tag {{ tag.name }}{% endblock %} +{% block title %}{% translate 'Tag' %} {{ tag.name }}{% endblock %} {% block header_bar %} - + {{ tag.name }} {{ tag.description}} {% endblock %} @@ -12,14 +13,14 @@ {% block header_icons %} {% if user.is_staff %}
        • - +
        • {% endif %} {% endblock %} {% block content %} {% if tag.workshop_set.count > 0 %} -

          Workshops

          +

          {% translate 'Workshops' %}

          {% for workshop in tag.workshop_set.all %} @@ -29,7 +30,7 @@ @@ -39,7 +40,7 @@ {% endif %} {% if tag.box_set.count > 0 %} -

          Boxes

          +

          {% translate 'Boxes' %}

          {% if user.is_staff %} - + {% endif %}
          {% for box in tag.box_set.all %} @@ -49,7 +50,7 @@ @@ -59,7 +60,7 @@ {% endif %} {% if tag.distributor_set.count > 0 %} -

          Distributors

          +

          {% translate 'Distributors' %}

          {% if user.is_staff %} - + {% endif %}
          {% for distributor in tag.distributor_set.all %} @@ -74,7 +75,7 @@ @@ -84,7 +85,7 @@ {% endif %} {% if tag.manufacturer_set.count > 0 %} -

          Manufacturers

          +

          {% translate 'Manufacturers' %}

          {% if user.is_staff %} - + {% endif %}
          {% for manufacturer in tag.manufacturer_set.all %} @@ -99,7 +100,7 @@ @@ -109,7 +110,7 @@ {% endif %} {% if items %} -

          Items

          +

          {% translate 'Items' %}

          {% url 'tag-detail' tag.id as this_url %} {% include "inventory/pagination.html" with url=this_url id="items_paginator_top" param="item" paginator=items %} {% include "inventory/item_list.html" with items=items show_manufacturer=1 show_distributor=1 %} @@ -117,7 +118,7 @@ {% endif %} {% if tag.formfactor_set.count > 0 %} -

          Form factors

          +

          {% translate 'Form factors' %}

            {% for formfactor in tag.formfactor_set.all %}
          • {{ formfactor.name }}
          • diff --git a/inventory/templates/inventory/tag_list.html b/inventory/templates/inventory/tag_list.html index 48cce2d..90bdb25 100644 --- a/inventory/templates/inventory/tag_list.html +++ b/inventory/templates/inventory/tag_list.html @@ -1,11 +1,12 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} {% load formatstring %} {% block title %}Tags{% endblock %} {% block header_bar %} - Inventory Management - Tags + {% translate 'Inventory management' %} - {% translate 'Tags' %} {% endblock %} {% block content %} @@ -39,19 +40,19 @@ }
            - - + +
              {% for tag in object_list %}
            • {{ tag.name }}
            • {% empty %} - No tags + {% translate 'No tags' %} {% endfor %}
            {% if user.is_staff %} -

            Create new tag...

            +

            {% translate 'Create new tag...' %}

            {% endif %} {% endblock %} \ No newline at end of file diff --git a/inventory/templates/inventory/workshop_detail.html b/inventory/templates/inventory/workshop_detail.html index 7250d35..cbeeb60 100644 --- a/inventory/templates/inventory/workshop_detail.html +++ b/inventory/templates/inventory/workshop_detail.html @@ -1,10 +1,11 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} -{% block title %}Workshop {{ workshop.name }}{% endblock %} +{% block title %}{% translate 'Workshop' %} {{ workshop.name }}{% endblock %} {% block header_bar %} - + {{ workshop.name }} {{ workshop.description}} {% endblock %} @@ -12,14 +13,14 @@ {% block header_icons %} {% if user.is_staff %}
          • - +
          • {% include 'inventory/set_index.html' with item=workshop is_index=is_index %} {% endif %} {% endblock %} {% block content %} -

            Areas

            +

            {% translate 'Areas' %}

          {% if user.is_staff %} - + {% endif %}
          @@ -30,22 +31,22 @@ {% empty %} - + {% endfor %}
          {% if user.is_staff %} - + {% endif %}
          No areas defined
          {% translate 'No areas defined' %}
          {% if user.is_staff %} -

          Create new area...

          +

          {% translate 'Create new area...' %}

          {% endif %} {% if workshop.show_boxes %} -

          Containers

          +

          {% translate 'Containers' %}

          {% for box in workshop.box_related.all %} @@ -55,18 +56,18 @@ {% empty %} - + {% endfor %}
          {% if user.is_staff %} - + {% endif %}
          No containers defined
          {% translate 'No containers defined' %}
          {% if user.is_staff %} -

          Create new container...

          +

          {% translate 'Create new container...' %}

          {% endif %} {% endif %} {% endblock %} \ No newline at end of file diff --git a/inventory/templates/inventory/workshop_list.html b/inventory/templates/inventory/workshop_list.html index 1455cd6..5f90644 100644 --- a/inventory/templates/inventory/workshop_list.html +++ b/inventory/templates/inventory/workshop_list.html @@ -1,10 +1,11 @@ {% extends "base.html" %} {% load static %} +{% load i18n %} -{% block title %}Workshops{% endblock %} +{% block title %}{% translate 'Workshops' %}{% endblock %} {% block header_bar %} - Inventory management - Workshops + {% translate 'Inventory management' %} - {% translate 'Workshops' %} {% endblock %} {% block content %} @@ -17,7 +18,7 @@
        {% if user.is_staff %} - + {% endif %}
        {% if user.is_staff %} -

        Create new workshop...

        +

        {% translate 'Create new workshop...' %}

        {% endif %} diff --git a/inventory/templates/registration/login.html b/inventory/templates/registration/login.html index c24efde..17228b7 100644 --- a/inventory/templates/registration/login.html +++ b/inventory/templates/registration/login.html @@ -1,21 +1,30 @@ {% extends "base.html" %} +{% load i18n%} {% block header_bar %} - Inventory management - Login + {% translate 'Inventory management' %} - {% translate 'Login' %} {% endblock %} {% block content %} {% if form.errors %} -

        Your username and password didn't match. Please try again.

        +

        {% blocktranslate %}Your username and password didn't match. Please try again.{% endblocktranslate %}

        {% endif %} {% if next %} {% if user.is_authenticated %} -

        Your account doesn't have access to this page. To proceed, - please login with an account that has access.

        +

        + {% blocktranslate %} + Your account doesn't have access to this page. To proceed, + please login with an account that has access. + {% endblocktranslate %} +

        {% else %} -

        Please login to see this page.

        +

        + {% blocktranslate %} + Please login to see this page. + {% endblocktranslate %} +

        {% endif %} {% endif %} @@ -37,6 +46,6 @@ {# Assumes you setup the password_reset view in your URLconf #} -

        Lost password?

        +

        {% translate 'Lost password?' %}

        {% endblock %} \ No newline at end of file diff --git a/inventory_project/settings.py b/inventory_project/settings.py index 13b5845..f76b75e 100644 --- a/inventory_project/settings.py +++ b/inventory_project/settings.py @@ -14,6 +14,7 @@ from typing import List import os import sys import asyncio +from django.utils.translation import gettext_lazy as _ if sys.platform == 'win32': asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) @@ -116,6 +117,10 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/3.0/topics/i18n/ +LANGUAGES = [ + ("de", _("German")), + ("en", _("English")), +] LANGUAGE_CODE = 'en-us'