bAox53+-=k4cW_-Me>3jvaGdt-aTa{E=PY
z?Afyr3IzmSC9kNe2gD*GB1DK|M^L&21e)%jByz;R2nq^HP35`DvGO_VJg#YM-@bja
zDBF|#(I0Q8Ch>}hv=tRONk+)UD6o6~^PdWG?B5EI4}SaYH&)5lnZ)s)Qm{%#A~7H8Mi~<^R;Ob1jFOajol#xmF{zN2}I$9an~=`Wse+pPyesqWJOfpDWjL
z$#z^A&~kF)C(v3`^<@nW+3}zcQ3~VYj2=~eKL4*za+0ceS<$bD^l^4_fJMXxF+wsk
zH$R~i|As`mci!rcmCrooPe!tx1b*uxeHO$8ckS|hJiJ`k7#MzN6^+#|&G(A^_19nc
z^%>lftgP&sU-I?2!`He<1_lQ7-yA!3Z1ZOK-$MeP{Iih1ZpQnOHxx>RF{Qhz;2&V8
z>$6uBREGCUhY3#^IW#Gmxw*NT;lEbt^nY2PRyeq0HEjJ5YIE
z@9gOb{g*wAkkh>-PFu(EvsPY~(frrt9_GIye{}grdOs&$qISFRpA!|zM*pnx_WyM6
zbyvI}F=B~#cm8wD<=0_N`2+*ZH3a|rTkUle`mgW#zx&z$9O=(H5CW(FIly<<(LZsV
z{GXnZ_t$eOWfqeKg@lf=vf>;tnoF$gtOpd1q&xrItj%!qlgE!WZHLm?6=Q|x22*j$
zc2#O+?zSHtY)VC=;@Y)q<#UUv?VL6#cdOspT8%u-*l0iT{YD-N+bC|J%lacsI@DhcJ2{cA&fko^CVRFy{GT|-Kejl)3sS_ehV}6(D1NkmT9*?
zuTjR`>W?&H8wOT3m;);??-dQ
z^qAwqWCP%YcZIr!hPdsybMK+57SIyZvpm7KU2A?N5qeyib58t5>h?e487|4>|kb
z4j)T*XD5$YPq~N3mWb}3LoM=AGK$+;@NvrVD%C$8&HWt0!-w>xSNQV=2w5deCp#?6
zK6vop&TWW;$dz`(7PhsQ2>a%M?~Nwm!s)L2Kp%
zY^M*G78*R9EpronJcyp;+_A4Ye}0#HJ(WQNy}i9X
zJx3*C5t`@Y8Hb`|g8aF4UHa1dDZHYhnrUGCqN7;kKoQ&eh6eIww>=%jLRP~Q!)3g_)fzQQfn;3JYuUw(`Q&0q?
zW_{vs#_6RS))mD5wrb5_3pw$9uSnRxoZoaG_9wgOyTMc0u9|Bz$(29}4^4<;_VL%p&aui#gVRmifN8GHEKDn!)5Jwro7QPKfFX9p4?5oe+q
zg;g=_Y^`WFG`2G`H0*zKTKmwULtT1Ylpi18in|UD4(84F$KhB|FIT&L{(L?8ljSqJ3~mXZhANH#jIL0Rw2fUMvS@B)V
z=FP^Atw}DOCV)?NXoN35S+KDfIH{GauI~{|?cCEtN@-J}&9+&!O9u#d(#kl5zhUIouWZgeZA|&8f*{Yk#YJdgTZle1FsHCT+#-HE4+|UwfDcx%#!rH
z{D!HR%x-LK%&wfUZ_AeJF>(=T5v^Ih8Ylc(T2y2tYVqVmU(Fq2^;>bSyy=b)Pu6ym
z5^7a5j0JQ`wj|#~?C7`>i^&c+Y&?49*GIz4dMn@Vg}huBr@Sj2{eZ)lUu;=#dg%Au
zPxqQq3ftSYoS$@y7TO9QI&?ueC{8(%Mj^`6g4eGEcvff|MUm!og;w}y$!o+puM#%3
zg-qZwtMfW0YuWcjJWb-#rRll3fbS}XhK2}}ZQHjO?l1U=EMURp-0!xRf8r;>n3O!D
zrb~;ZT?BoLlnvp`h*u){N572=60{Js8dk^7ZU}ibn8odAC@9byW9O^y32eU
z;*`1A*kZ6=*jI!}oN9VMmH<0oGdXc@S5P7?JHH`dV#@dg5pOdHeq2qv{;)Q0Tt-!
zW!3M$>qxTl5@_=zGR=mb_L^?&I0IUZR+{_Emx}|5`P>>pIwc?cDMS%40*lwm;iyEu>!v;{=7bN--#IKPa=`NSK-*uql1x=m5{x19}fp>
z)Mv2WqeptUT`^oC5<1Dv8cT-n~f
zgndF8*l}{>UOsh-b+XFz*C(3`*lUE8w<(T#zI1V+_B5;al7@$eZGR3vu(T94|Nc4j
z{1a@l_sPOoJnG!+EITpo$&-twrYV}f7cREQ1n|{0{&{mHeBOkTz=1QU27kOxPH1vh
zFI98hWLDAMjP5Ts7jVth{_>?u^J8UPh}&$-Ayt$O)Vp@aCHqm+ZE-~}nR9M`T9cfs
z5-eyDYwhjwtSUro=^2Z|b7$w|)Kpva+o7EO7;#*ho1Yn{E^;Wv0}<S6-
z7Z$P}JosUvS-q;AU9})bm2%Vg-aT}5Qc(F;t=*KFmE}A&R`Tlb!u-5BQ_W$!iE4?C
zZ|irS*z#<<&iAT@c*4CYg=P2axg{gKftpvNN{cYlNRBsM2fipN59fhurlXc2>
z#0dG5mJ<=*zkPDzpHogn-1Kv&kWh4f_SX$8F3b^fCzYP8*(hkyuan^QFp&By;dA@R
z^OjkvskP8G(?qR&)pWyds&|dF>cDXh_n8{F}L-Zd}3RMMN3K2D`L6Y)30B@irUZC
zlGGXs3%jv%C@0esHL_xh)7q2s^i$I@Io}_bh+kEbqH(aRtnA|t3#;d!vS
z4AX8ZN}y$#&&jvBg!VjS(*El3XDUC(#spDE>8R}@pGoUkgD>xp2g=%pQS`NoUpn!h
zzp!|!b6QCRw_7DVUXCQ`eLJ@3xvz(;6V@f>nZjQ78*l$^JRvH&h&UC{2-s!%`1h=N
zn2B8ZKR({jf3INft$LQ}+oc&tN8yzy_;_hMG44pO!N!dn6^pVZxo;`f>t(UjjQ=IP
zG(V1l1Cmin~f!qT_#-N0wqgb02ZS{=8F=FyMh@yA`XuJirm)<%i`%Zln
zU%xsvWStK7;50z#HiC~{g+I`KeN)rTG-2x>Uy+1D?8Zv7%zD>lTdiE-snWr6wbW8z
zqxyP2oP4Xzj{PxFI1x29JXtJEV;jfGdQm%p`FMGGIXM&F+g|t=Hm~|TZbN*UH`(d$
zzmJQdAbi=z#AHxJVSLK)@7#0`RqfNqkF~@B&=K8m`YYJ>{>D~Ask^N2l~AVB`ae=@
zjf+GM5BV1>9T|p)kscsNryV)|1r4w(9>$K-8Rfse?*B+aT{OMo#9~+`-YSvA6%FUV
zQE%wt#7w&k#D;%;&;Lx;|I_P;zXYl?PoZzT_~qha@V`L+#Cg)c)Si|79EhSKITy(i;93xAp(=<&?e>!OKDK+ymIIomK$VqCoXh&@
z!$G>#fKGK?X{o{Y&tXW7SEQr>Z5n|ddy!gVJT)~pJX~8&&Qm=YEO9N1oyU}MZBbDXl!=~Y!OF(a2+qe|%B4e<8|)Ty%=sPBHOZFn^JR=&f6OyJoET_vw5gDZ|Um6w*wGV~3k
zG>roi&lHb)(EC!OIU{*Fv&D6rqwIF?-D{+;uMBYl<=zfd4cKU=)o;F3t=Mhv6j1KF
zs3^LTs?6=llP7=%V|B_}r7RWRWXlnnh@hYiYUNlltbwX_XPh~^?;f+U-<}wfnR%Ag
zp&|$+4|Svp)%LUQ2FZIsr0|dw$^+b#l$p4Rod2auosr2Q8eO~gB04NAj98ikRwe1p
z&bW7PK=Bpvt=qO8lDWbsG4tWex+4T;Ve9+XuV2SC>)fE1Zr(3kvQ*i1k*1nwHzN}y
zcoKHAkAMG#YH2^#<=i*4_sm@|GuG5z5|XZ<<08eA-1Abiz5GHDS<>sMv?|y*8bcM<
zJ68XS(>+nu6y6gjjBBHB+&Re2&3)#~nO(NlJ%0KCH1#kr!10Jj1=eemkGw{QMAE_q
z)zzm@o;=CQT3Eoxp`0-PvxNW|$kUbc!ysTW)uzC8FfRqFB`ms}V*T*zP0
zZ$)sk2Y+nMGRvRtaBa}Et!QYN>MHf3OKFCNvDVMQT&xukR5djQ1Jcns7|oay#0WZIH%KI*@#7l@ycU15v;&X#saLTDP}0DRG%
z5AbOGLRZJG44ya70gCRB7%e>-JXjedlrEsPqS!rk+BvSol;MQ)sZ&z8r2!8|XihT#
zBMN~v@WO@10Rd_uqV{VbUG3XxIiota1P1(`er
z1ynpIc?cv4)&a5d5HT@`Q1jCt*KCNxb{ov+uQJ1PNIIL8uEShD*3pX)e#6XPdM^7tVn?
zC?O%SG~MZbG^1f}`)uj4kmo#pZ{8di4HvW=%rtIFfh^(DE>4#wTWU&6WAHD#IMuf-
zjC>BeXlxumf2n4m1$(#vk`^dx-`vn(RpN25qm3C9d4D6|KjZ*cPUr61pPWu=WKRHo
z;2&6k9Fc|Mr?!SwsRv~W`Y^OZvbox%QermV0Fx8QMP}2nj
z1YyIIYe_VweQEZsT_%vi7!%sl-sJr2k#@dcKjVEWK~&MC_c#UzUuGgT5!%M
z4FP)IF)uIArmTtH2|;`VxgG1jOdyOP2l!jpI(HsZB^yZ748`I6nH(Q)NxFRz;p*+o
ztDLBLPhUT(Z1(|yd(CN}m=2&+-@bjLYqzcED5_|@SPj&lwBS=kG890>Gt%DmIN1NZ^%MqNdFGM3~-w^4$&MK{4`wXd~(w|q#oJ|6JFXTOzULA6x
zxa&@54QW4a@wBpUUC5+xK!ltz@Jt@EC>pQF`Y+Ho*=g_G+?-W^?bV6aB!VQZIYqZD
zEiDZJQffJB8>5~z29`rteL$$_l`6xvUCP`%4K~VZvt+;W_QIN1Q)Qkk0gz93<`>`!
zWvTqyMK4Zk7nP_vG&MF}gES}X3h#Kbb}`Ppl5h@04m_wd#idsE`k*5)KeupQOwaZ$
z_A-)^at@On%J)(C@Ns!#R1S2ywy?;j*dv0T@x0lewRssImy4T0d2HR|ciwlDoO}Ux
z`JaS9#dOKKjeGg&oTjM9cnH_Sx}kk>B)A!Qk?&sfkxd7GYN3QcnvQz+E)6QasHg+d
zG$LlZ+cDW-^`u*m_T@)bsu|VCvt`poR@Yrzu>@Jj#v->r{=G}fZWL>9XAU3LWg_{9
zPRzNU?PtxuUx(%nHU6DRT5@s|QY8*-70%Z5k8e1O9FO8ty~gv!X2^FH^uqx=Iv6=M
zFJ!-XROe^nh$y2Q?+tFlD^v7>Y5R^H6IkoQ!opl=FsK%WI871b_0TF^yyDB7RFPb@
z92YD)i`=qckqC%@dOF@)#Rc|-qE)+;aWMER>Xtu*@xGseox}kgDAXV8+?m^jwn<=i
z2?+^k&2^ZCUUJ@s%657%z?1Bv)rtdO_}F*~O^l}0UZ|OqWA)JKoMqPtY*M}rcff@~
zC3BU8ZL&AbuNLKfdH-k?3i9!Km#TFSMDuZ@*i;&lE2KOd+51rIscq!f6ve^T8g!+T
z2m}I`XpF;bUzD;YQCxU|*Qmb4QcJ5HH3=$=A*_X4^Fxt<^d^N?JQl>aB>HTI4uab+
zfw~y~J2SWWU}JUT8sMK?>(LH~HYh$BxIu_5e!Ab?2=++$aCU}xdVay`V{_8bRf?jj
z0izw?F9d}QZ>f*Iq22c-0zn1I%p*L!6YEaDDIAcdrY7k(r@{c<(3dS4%{s@o;|gt-
zW;^1|Ca;IE>n}Pg?f(K26>gwo^L)hVmsmuC_nBDY!1X~Kd1zaVzH1DhB09Ho_rl?FE
zh2eh;bPS%t+
zKb_6a#P={>B&(y7@cj96z$T2?K;U5Ha>(s6LI2=wH&m-s{VIBc5%5n#L*v=Ty(pBT
zeqFR|bhMV7A$75;!tg=IlS`1}JI
zy2$tJ#q^MCgHuRIh_yd5BlZ9~+QWwraqtH=j46$#Y?XzPp|rBnWPW-S3D1*Ux3Yyh
z-(oE24PE%`A-%0aVZ*WUF_kzhvTDr+G}(%=1L6HzX
zI8SuJ4_(c1WF$7?05uWem@XH5Gz_N}g6!Se=xQXo5MmFLZYv8hPMq-y0>+xSfmu*N
zX0~s5*Z~TBjC>R|O{yPh5K#*$Q2_>AgkRZj-v4algV#TP{6N>N9iu-e3n)726Vpln
zA<&rU;xa<7-*WWTx87c|d7s?qOAn^#@1AEjceouMSAr6S1PH;N1)X7x>!>&w5(w>x
zRjf`y!KDZB^jyOx>2^;G-6)8Y#f62=_Q9g|s?LWCVBptwq7{4<_SGQy?g~M!?JkF_+{XFW#rh}r&g@l`aYr?MiaiiY(
zoz`|T&8U-20<`N`^#e8#@J_ftKo1!cH)<3WyIQk;=hl?TUs{|)=L5~+T4LPUgB=!f
zaJ%D0Gt<-0*Rnt2U9N9QTVP(rG?>#TRWQ1ftCR%7EV&d;L9>yduib8W3Y
zJYH?uOQ4KiM%b*`xTiMFpa$JXb0C2XFS4q_`EJrWG~_|@h-;5rgcL>RLyHc=Qa4Sw
zG+h9|ijE$wbc72GE9CdHxTaSsw>?2*`Y
z0=MH*Bu|uG;}d#ighbLnQk#M@jJkW~;K48$LV?5v+w=1qFCtHXDlqQbhc-5(^%H!^
z$FIuO3J*GM+LJw`^*-5Aen2zy2z%
z%uS_FC;`Uif`p-FS|iTT))KMkS0GBgb>4m~4+B-bRUz)Kt{ecu*ilTnfW@J`27Lfp
zIXwQvZy%q64`!h}!E^>{`IbLV(YPI3wbHSPiikjKh29?>`;1vNx+3{i>ma8n=N+?4
zcU!I_*B<;gh3Bpyp-%UY`2OEWHfnmMMMXVu_T{1PMr;352qq~ZA@~>v?v3>Kvp09!
z+nO^uMh6528qbcn7G8w;!nl!h=~Nc<6c&f+u;kPi!iWCj2YYv_iF-F;imT{H=<7vBlYjfw{T%=ym=ak#<-AWfO-edG`>Z;w9V(
z8kcFRpP3&y{WDT~PCou9VfBXptwLA1H+hq$Y59q{)1bS
zj2REN=R2Z~0OwtT53jJ0(cC>#6UDe$E~!Dvzl1KgV{G^}OQGrAyV1rkUc7kicIP%k
zE~0SajzScfG3&7Rf;a#O9!}%(I+Dw1YboBBP=p6sa5RC{{%)
z2xzb%#n)H4Awi?C88uqW`o}{`UB3z^VRCd7ck2A?Suq48-1qIUaNI&O;zen94aSz|{tFbvzyh#Y=#CnL88FvC%98sT-bMOC
zPmAb4oAt_!DaC0c>r!s1rrkYAdxR36RkksmWcFmd$0_{;t%^0ZmC(LV9vCk!vuQ
zFYMmn&`_a_US%NLv3(EgRSpsEp*qmT4~`>C`kZj4m$<^Fn+`h3&TfcgwNqqEgA@b9
zd&%yqNl&FQrQ}|ooXYS`J{GiVWgPfB~x%uMWBc=-1+}!lU8yolqU=Z>}AGb^g9{y*uQKCk+`PJbl
zR89zMcV+-zK!^i{iDNV4y%w=^x~tccqzmK(Q@~_Cj{Mo<5C|j@^Oab~D|OQENW~
z!^6pK%K07K(`euOOkWg8@P(K8;H~Nb)}YInIqgrlS#&vx-Ot!^*gqW@2`YmqaqQCK
z_o1PMZeK0<6r_Ed?0#Q|MlHRRBYK>pB+=;AU7VkR(n77Nd7}H~G(EnUPThKF9rQ#0
z0Uo^>`w)wjM1=E=3>{cLZg7_;_#Pp3kuE@Nc0K_zdCB*ckDeb{DOLf+SQ?Dziln6H
z$qyesbWFf&7!et%$3vhGFF0*rlFK$XxM8+baO*VY6+s^FPxdRCOe2KXt$pyDI#iI6
z{3Y6pxh|W(Fv)k+CsWfi&6Di(^eNiA)B^M0OhtdwP^zJr#Z1z=yMf24a?@Nz!h(>^k^q(Ko_zlKpfExTNZ5>?)*XsBr=!U-IqS?*s~{PIew1YmD}dNJ3dWO
zB=jgTQSgAJd-d5a-b@W4`@5Psp%L5Lvh|g`Ua6XhurP>_7)S(V1f~6){NIx4(qo2R)Dt-etSEX?Pk@hyIAhFgOVg3g4*wdeWtOOEhNk~Y0Pes6Z9=*FIO@u=S
zAk6`M=D&P`we>WRJOuw!@Yb-}dXH}?Q3OuLQ1iUk&9Qofuk#e6<330U>q6iFMWlGUkQq!pHMnKp&7g3$ANS+(Dmqv(!ae(k@t;!e5In|kkI#{WuK?zlxR
zLzOqEfAjzLE8JsEiP|Grlu=#ize1ARL*)2DKIBOjJbTuBxHSt|5aKh%Vn7MQsZ!qT
zbqG0Vb4X8W#$UU;yGKSG0q4=l*l}MAaaFX8kCv|@eV8}^?1^L&WkN*40*U)M)JC3g
zjev8DIPlfcwlQ2{bJo6HyOhz0+AKO93IQFm(w(OI`k(L!+^GXN#YT7+V?g-fh08|7
zxWvQ}1be~i7b^P&&A$U>m#4s=@=zVk$HhoYejd!b0D*;@m6eri4jM;NKtKzws#g^p
z2}&15hn+Xb<@o7M4Sos`w8d8$-byuVV;|o5n=o
z?i`DOojZ0M@qs}p$!bJ1_Zb99w7kF}0jt}|gb37GoOx8Y4_45hBV
z-V#L}6+h2*DgjePnfq+Iy_JzXy{AOfWPWmir#$oq7G8|RB~iRV=9Km2d
z{CYD*$600f+52BHD`Emt*rXp)5hAA5bPLOgHVwWW;48G`0A3>`q+}Q)<^#{0p!OU{
z423wtkr9u|C@1#?%HZKchXCKBM17pg4npL{DS^VKpl-s*r8y50jZ(YN;mSpKpou>3
zbom)9V(YTL61xo#b_9YDBHuRU2N9A!E;AgL)#vQ76-a73H$&U0N3axrL>(v)R|S75
z^lpKoFG!$Ky1H~Me7h7wtUJJ5cPg8p4*JBkq9?El3aogtV|6B4OgOT=3xBU-p!a97
z_T3akbq>7urtgC$5hSCnhc8bIG;r}g2@emyyUXp4cjo=2E-zUS!q;noWn|x+I&a4s
zEf+yWRh)duiU}iIuQGW0td(7ZS{fUVyKigX0^IJ
z6_ctAVROfvduD;$><uEf}lOQUrTgcyg!92_hPWD0L7
zyo@Ck75C6~?RW%vTmUE(@c~%`wFo*3-Bv}1Nwz9>YFnbdgTry4CkH*icCz2Q*bK}h
z{-x!L`Mo*4tg=$ZDXPP^gx>He+dY71$*10fB&q&mur;futSk+@bn>TFOu^@njMxXy^!fZi=2Eb(FMaY_ksXJw}(0+r5y`<9sh3Dq4
zT)C5s`0;hYibJ)QcPJa-?oGw+_j{QpZ9s}0P2
z3Rz>X9NCYMV^q^)Gn*gWzyAi(2!FesS4~+MezK!`{=Pv^g0nM3mjz}9Aff~MyH9m>
zbQ}`wgHWLVQf{ms34Ia$@czTGIY$zvnltWkB+g4i1;h=PWC=Wo+yk>P}tt6&gFIc*c@`juw;H
z1Md{jhNj)yw#lXFTz!ySi++XQ1!}y!@hRA}yOYQIzeBi3_?)qf`V92~7DBowVjrKe
zijVKbJ7Mth-5~(#Zq3O>XrkztGx@5RUWvcWV$Q^WiE;B*`<-+L{vgu7^ETFkBDzEZ
zSm@+*SzNr7-n#9eiz
z3^qW|(KQa7B_6)|KnC$IFOSvl(zL#f{zp+gxJ|L?y~vyTsQx(P90`g2^(2%TUjrJP
z6Z2?wVERB-{je@k;0zl6a4z(5>s^F2
zm6eqrnHra;$e}D9AS#_Gg|xqJ^X95FGMw%m18=yq&{R*_vb@#!4ya+@h-3J&CR*G#
zP$6bPbB|BAo}vu%8#msEWC_W?zT3_&F0%v2Y5`Ob2R^=G?Stfm4gT+!lC642Pq*1G
z6(7qvvF-eYEf?;--Ju-qao|cDr<75my+KTdVXnXHVuGA+go%{u-?8>zpAPq^&EjcyG*D+8@_RS%w2uhs=dERU=zEE&
zRBacRYHOdEpa_mWg!yU>mfgEmkb}_crMof&*=O|djTi|NcnL>F85-w4ZeaD8NXm0quyHe_Wh0J331R2C1FQwf7=BOR=C;<>
zb$(=#
z5uvPQ?~TN5H~j-GUITNdE#ehw>AI35VqiiUuMQTV)&17?Hw^e#6JI~2q{D@S;unq53^}@1=
z%0wRmfv_+Ivj75FM^|^_?o(eebk*M$22jP$bHa^9Ow+IFJ-$TZ>LbN5r6zGpb&Ls^
z?vE#t903Z@Rba#n007`(FHiFxnVzbhHr;n^q
zxdzfjSo#itNS1y2boeCi(6wo%zM~5;Rc9B*nm>zGP83B87u>B(3c3M!I}z;%-dJK>
zdio?L;()sKjEn-jz428%dC+q4brU;935;+%4FYPwj-xvRaEU7F)#mNnHGjndtjqkt
zgI8lfa#>I*fTeei1Ont8f{JbW`W2<_z`lL^-W9X3un^vJ4-F2!^IiJ-Vbv-hu<>iI
z)#LStsw)KHAxBU_0JGpPne^4`>wkwi$H>T?3Zar#S6oajEzwZC{f%%%*Th5p?*IPFm!LEReq{6P^
zb*9R2Zx;C;UV*6eJ-|l6H-aq%*Ek_J%;k^^UD4?CjLy%P-K;DrIg6kaTbik&
z`!@#f+`AX#=NB{h1=#?a@56@-_RY6k{^KojR1uA?U-$4#fX)G-t1LW4ZojL4wvQf7
zHA;p#hEqV`X2=B)vt-}^xW8`tU|M`F+yYQ<5c=qv>`E)ciJ$#BWZPTGypb5^uv-kv
zZMtmGJ*P2KPG26Y!N#zesdtLLd@gl6I4w?AAeha^l?oxXEseT6&M(f5tR6BQ9?aS=
zV(UTf*ZQ*)VDkFP7c)e2JcE??$M3MDu$TK>$SB`iX2|%Otg51NEl4nZ+|j(Uq?{gB
z7~9i{@b<3z`>*X7LF@bW?E%y?y6q5kHbqm@n;lY(76fb@y0RMj#2Ban^iL>>dm&Ys
z!UL-@3zOOWfY#C;LG!zGBdTI-Em$dtn51~~PDvv;2-}d*0d1Na8|jlm)R{VwGADko&
zxN_jpdACL2FZ7n9p&r=S%!0mi4S3J2rEdI>!Aiw9KCl&Z$7Nf6UblX|*VB$}l3b>+
zOo(V3m1@|eTqYAJoUBv2?IynD?>=@6?X}H&&P0O_(K&_pUOwad_wVl(bC`#&=1q@4
zx>bpvKLn7*)z#Jb!~kXn=P^)NI^*d}R~9(%9f51mySvwX238i<%?pF6RggU=L8~Dy
zVVuwoJ_YI|MKzm9Z%amaVD&y@+UDTFZ@}OA@Sg3Hf;S+;q^%!AbmbZz1GDw0Y!I~t
z&zwnv4l1XLpXq`-ZgKVco%E$QH8&rm<<3F%n6UPx9{QK3*QdpP*3652_g1pspTl6N
zF3xvb0+@nO}oACDA{5+yQ~hCr1XZ&O(8&ta9trq|w7zS%AkOdw78IyG+PhnU^YgA51+i8Gf44GF-o
zqoV`7q!w|GZfn~^#qkmPwA&|;Ma-#0upJ;U();Tef5!Bl8C=MyIjl#H93NOuRWqwN
z7RqZg@f~dhQQ&0(fh=e^5E9zbjeIZj5`qNGBGVj8Jy~Is1M~X7hQ=0Dj8S7RGyw}1u+S969gt!$Dr`U$1;hdtihx*X
z3L^Y}3v*&}p6A2!;T_|3jCc}{z`obL)?9O5^SZ8CiPCTN&=Sta^>vaR>3P;f$nmfl3;Qjfg+X8R2}p8Fy(GpZDG8**bO9M
z&H0PCp9yrSYuC}_rkR;W^X6qgeE9JEc@X58agO(2ZtpztP$#FnNLR8UDgxz^l0KuB
z{Q*h_1lGT5{gy37*Vcq2?%0uO&7t@W0tl?E+S*$A?rN(^yWy#rR9omb(WOT0XJERn
z@G&3h-o1N#UUhZ#0>PW3zShhMS#VoPO_G~}`-+ctMt|3cDOP}z^Y#485_5}+QbIpF
zq({sMPN}2GW@%~pSQiRX(#Edvj|DTC+z}fBOG_)`274KIVxK;J5NxA->f61$ptpDG
zakCS8tScbt3##RmejV$o@)sV6ps2~2T@dalnG!sBO`h^G
zBWLF2YO^7$JqPftWSce%QyxEga_-!@z}KE(Bo|>#RCq5~qwhO)(rh}A^PE+~5wO%s
zvU26HO8B>@ldp?#;(Pe8NpX)r*T3JcER6Z7kc5gtEyHoyKEs_JgbO;@$w}TQ3%}ev
zI7x^47q5{=`_(%C{pG8-xJC?o_a)XKrPI!3&d%z)LNk9CnP~+ga!@ad5ch5VaF~i?7)UPx;KyPuf_Zq54@oZ=t9rJa7;6Lm+9yoBr<^9FDSFKYea`DD$y*tbwO67u&x>`tb$
z`>&03^K6X;wFQM4#|6^;prJ#RTfdHfJaZBj2k#mxV=3!R^aFSmDe7+*{w#Tl?08VeZRTBc)4Ri
z#MSr8W4y8+Tqy)t@7bfriZ|EzG2i_ax{F7~CvGAb(y9~H>b`N?e8ys51LR>t(~ryh
z_F4rwxqCgoeXQ?G1hy%NlsV6X6T`zPCCIPv|z{`If#zkgAW;=J1&c0Fp&
zK??luIQsF!^HIM2=d1N<^2j5}+rCgIhHu@jv5CjtO3f)!2}n}QrGUo1muZ`DdC5}A
zl4tGfWg?676+N%kn#eD!Rm{xJmvFDpz~CJlCY;W>YfYiu{QCZ&@A5i!n})t6
zxiVu(;aIXCP8%W}m5VpD)9&0UV~4Zq+MB1*it3a(jNeTxEG%IB!6n6k^Y+@kFTRv$
zdAq`ly==X73HxiDdwnGT+H1v%74Z1bj{^4$=@akbseb58WJweNFgH0jitg-H4wg%n
zJm-!6wxx%hoI^hzB=iw31IL1ctw!9mpu*UFiB=R01(dS8^LQ!6s&0znK5GY5qk$a!Rx6v=rlH~fy
zQl^PonMSv#hX;H+LAU+#WRUjg(R-z5EcLcuJvEZ_?J9{^^#n^G!Nyl!mODO>exe^Y
z?4hBd!QC1+W~9;tw~ZkFq;PJ;;nSTUkjyA_Vw>*WB|amK1QKWZF6!Fa3tH;Qvc6D=
z+$vmrdl+J$OBf%=#ckr(`t@Y?`6=cNE?gSc(zmRG!FdlkIa$Z*yn#@r%c+V4qi%5x
z-HRjAwmv3@q`|$b^IrZ5Hi*y%Rzuu>u_?-
z4aoj??yMwF-l@s!>17a~ZcXDbC&k+vwFg-Z1{fx;7YMaE*9cU9jNfOOv?8v0%yT%N
zPo6zXq96sr5NYhNlO8#cMF
zGF9eP2F4K1o<3>>dh6l_Ah0(*}bk&1WDlL9WWdt#>
zY*LFW8JlR%l|NXC{EoAN^mz^nCBdz}sX{~-vK|Po9BT;o{#DRWJV35#I;OSxK}j1C
z+pw?=`{b6W@c@q_7D`;7US94#s(y$>(-`Kz|D8dze(1T}uG%8h%zsCsE^KCq@;c8~
zZiKEvEa8OiC>VoidbqWfl~uCJBd+paQ<0&|b^0=?dew+Cq2Lq(PMYkR>d|&ab!tPq
z9$Ho&6}1;=4t#2CJkV>@ODY_*yo?bXS2}k7{@Npb7u!2f>;mkc&pfG4t)vfpg*p*P
zPFTDF{+Q%}pnehCZF7~{@#XF0Os5oDjlH;4=fm5P^Lt!$ORRrg-`;ZT#>yk(Z72M8
z>ii7hMFat?%zm`4V!aK
zsq{fd$VN^lNn--YD`>SSj=Su0bscpOGNTR}UBw0Z*`a&7LQNjaIEj!<3d0uxtX`_$
z8CF_as=dc|;iei3=xZR5WTG|&D?kIG#@{5|1!`Ik9h3t-$sx(#-`vqrG_V(rz4I@*
z@Y6;mQ4MqZJcrBk`u?j~2bbCY=3whESQ7Q}{@JW?8|2;UWZT~D^-Bo&J<(j{n%bTp
z<2i0&veyE3nNP*KbmeDl_~U7rnZ&Pfop)4}36%gnqAFde-g2B&f+M|d-K91e?ZC|X
zOEiz9mWhB#NoWz>C(rz7;wC8noc!uMzuN=a_@t{54qb*r!k)zY-_
z%Z{E&0f!UKx5o8*`E2RrDKR~UyJ#x7MpV!3UZ_w6QWa{Zgh9dP&0zR&uU4*D5#F42
zPkTw>#Y30>08l==s7e_v;*A@Vzq5Vmw07-?X=1}%$e8cYR&M^y1=^b0>fvcPHNfMi(wo2j`Y#0qg@Sya2Oqwh98ci2AWyhxzIdb7
ze!p`C2hCj;zf`l9ow;CBbaA9vF&47p1#b7MGzuiXzOHTp<$m*;dk*huo3g8DV<$MH
zdL}&84j2{jx45cbkf!H&>%c6qcv^knsTv6e)V#Uzqr9f5mrMeH5_&ZFRG-vSUCsPVcJZ_OcGJx~oS;m)#m`
z9+5D6MncMho`G5|4XOLg7fx}F&{>c?(XXVqxY*Cn@3dYF_epihkfNVvJkDr2-V#~y
z!D>oOU(1?4*nx_(Z<%yKRry5OR&9;}he0ojvCl6cn`OabxOv_&dv%EsMq$EL2ss
z?Bb%!FI6NPMc)`A#>RZe&KoNRS7w)3#h4=vfI78v*GXdM+~`32>8n5sw|Ls}xSdpz
zgWnm>*kc2DKqeYD#?0^jMr`H)&py5>IP>|6$tDtZ3|ej-8Zb>hK544w!2DTKtzV)V
zytOo@PmuW6wB)BW=VoR$-Prae;m0XcRKVG+e@HoBghs%k>R42Ksf#&Rgu~t+Yb+Wz
zTjDcRUv(?Kf*%gzaUPt67(CYTUVqCI`WsdZ
z7?cloraaB&<;4?Xx`(Tq+X{yj&kiQXsQlQ?%j&fFxrx(B1v4jeEFG`mlGI;6IMd~J!VM|_0T-(U!P^_
zPK9dAjg)RMSmy)JQe6v`0vIB23Q*OS2@@uWCX=7v!!W~qVB55H$=q#FP8B`b=lSUzfl@3x7>sWRMwJ
zuw=e{MhAe%=*Yt*fQpkKiE_0V6gsV1)c`Lh{S{5G1*WEUj|P9yT5tZfl_qiI=)+?5
z{*v!KeA2tERdM;f`}Fbu<3?_-`P{u4;!R$=eEGtmBS$ozsQY#V&aunme#~&azV5};
zXzLB?X3u`v6Xz9&!y5;`=0x53H}uRl#EfBUpsTzA8U4wZG-z59FZ
z;D8^KcFlT5C5nsF>>1ox9$X4gJsjMhDX2wQY`S0-x2Lq_t+&7A*f~R$!ji|MVhE!y
zHYB_Oqv9e_;;w{GiP^6RUrJG|eiJW>O>XvcDO72Ebj|?C(E;wo9Z%ZsaCSVpNM3Wq
ziSicn)2jQubs^W9@~swAse>orY1T*P@hijxAbmS7edWlAN8Bvmn6E
z^;Tu}BrRHKM%NpeZJ?npExl_#Bl+C{-Y{vdi}e)`sfn?ttA*t5kKLFVa#NbUofeikY#psh5*XS(!xw(;vEZQ6qzj1&&Td=k
zo|#wYQDHAG{HY}TaL!|x-&9wQ@@dv3$7Q-FCsWavY$U4By$FwQXq|M!6=7}a*YTdOw_1-_~pyb9uIMGuds`Z=4Blu=ioKAW|Q4i
zTI+^A$ED35y<4`xqV<1n?(4ZB74~OomNong5+A>e!NfOmh!T@{odu?TmDU@ojxKyr
zW8sj+^^S3!8;?YnCEc-+B9Ph{e#aBo!!E{;)aHr)9#_hf3|qCRtcYK#EvSwOr?Y+i
z=E!MiYC1HKrWzU;s2LTiUC&Utm^9eJ^~}8EW0ksh4~se-DxH~r-9NDoVo&wvVwGSj
zJBJ;Yt1a;N;h^9FF~8+;jR-FjCM=#fXH!0~bsk>V*~>N@4ku@g9ULxf&29-eM^(==
zT2hr4^#o{LNOA9LNwP|IxJK0H8EKiNCFVYT>cM_s<8Gyv2fE=Vi$`+>msdm?F6blY
z8cL&Nbx|%|geuTd)yQ3Ei2g|*Z55xyvzY~I9kII{G^_%Ug~o4Sl4y-aMr!z1T66Qd
z)sz~SJhi|YaPf5?oUkDNm**Y%_$>WnRoZo>n(yTtekCg*W8khWS@~m!g;QNCDfTx!
zOTS3k9uN@V)+1!Ehplkh($RT%=~i1pr6}LKg}4>E!E-x$^qAo+&Itn;(5#
z9H{jXy@kpTw}uZOA+i;yisQy>s!IBhvcp`%zC@dY&4KC>KF79d*VZk)=HH80_=AUc
z-SZB0UF2ofMO$BW(vL`x-mkBz!6w-6=4xC&=yS06IC(y!P3?NlPbgC_EWdMOQcGfO
zQOlPiE|cn=vH^xK(2gOj^Z#gdyP4`dUQOm7<}|G9d<(UBr|2<*vmd>Q1m}|
zX=?MW$nyrOk|ZKFZGa1&1nmM6vk4iQhRMGaS32F?+0z3Y#%ICTeNdOEn{Tk@*u~-~
zvRUy%y5R3|`t)gKovkw_NGJ-|ynT@Pa}<2eo|trn=cp-d)m#0^DOsy~^Gl1Yz10>D
z4W#UJ!;8rFpw{^7a=d$w-FSZA)0;PMvijjJo)O~#B895#STujBM`?g1v0N?ijMKd9
zr@@vdPRs&oQR`GwS4RozTK^_!b^kJpbUGaaeoNd=io&L$BKCdde~xkl3;?>K$9J6V0QpvjngXvdBnTbjAeExc%w
zWEU`2U)AB_Hk;zvS7KxREbVj)q(6)vGbVeBVN~kV2Sy-h^RM+%mmDXwQ^LyENG~iC
zW#q&)8$9(I8XAx*RGO|xMv;QRKZXuw?(-q^_+O5~ov_0uP=&SBi|qDVZ~MWq{Fg(Q
zb2#bs)^{n!Xf5pCzMmIaS*=*{zLa&01)A2XliKKkJJWEg6;cT$zB2FJZn>XXcy_es+jM!;h=f
z?ig+xB(v_+<(d;n$zG6>rICqs7;*Tw40vqVMKQz26^N7=MkbLFmyFDy;^PJlJ(jM)
zNFXkAx-klI&+orf=aFtdjInD$=6!E*ITJCO4qxX}=3L_%tT-vXw(7xcoV63XPcB#}
zufOm``mi#{C5p=z0^qZAt~{{|N)(0fWt^YsM>
z$m@j2e8*D~9||WVtZ)}{?OWu)Wv0+q*t>tff0h3n#j6~jv%3ZzpXX}cxKK198SH@f
zZQ|fT;dE=)z&0KiC|o$)YhS-8E$yMC)Ic;XRUQZ-(n9ajwQC0s9-IV;j)Fm9td9O^
z`sgyZ@_uM3#e_Bs19)`xFr}$WYyeo4uBDq8J^@?uci)#r}x^zFce(ZS4q;i5s#mbpopruEq@7iBKj9d&I-YC5P%
zvI4tQC5^n4u@FvM#8#bEHFuAB*tu=|oa+BwNWY@yGw;I$ToMS(Qej)&o#Q`l`1GZR
zq{>HXmlTiE(8yGcyE&L6?O#|799tVR){YXUTxM-)*?q+w+Kyl->|HrAvgoDcGMEtkV^Q})?C2W{s^^RSBTd|-NLV!0MR!A0Vy9Cz`VjqqF&)hfd
zkKayxsBq)zA!)!5G4<1mFFQS(X+FXBf&HDx;FkEvILA2=rxi=1l#i#y^;#OSGcorP
zY?M&~P=E+7XI8IN_yqfp#w_-(v6>xN9;4)!eN!7%s3l0hz{#~d2cRRlzKXkA;
zd-hoHo4sT0JnM2r*HJAcw4vQu?>LmbggsJyr4*ob^)thbH#cvkLL*Nu4-h+^G~Is8Z5#O*SKCwjEOn~TOc^tY0VnUjpBfGZCsrx
zo4a=DB2q;9GvsZH#{E0D!w#;A0EZ#7&6T^Vs9a~!ZPv^WN)cwFPoN@CpZ<&4i#Kl~
zlZNf9JwUXOqELC}!W4w6Q}p&$as(2tsHfeZ^Bs+fjWv06#f5ZkcnbF!`}8=@1G40X
z6Z2@h0dcN+RZ4?uUa-z^XiI91AWsfcEQ>Cf4lAF>G^_Z~Z%b6MJu%meGd`I@$zx8L
z6}pBd-ek_|oy57`zim8f5WNRHInC0dagOSVz+x}UTSKR{@7c3wd9$ozG+DtEnc1B$
zv41XCuKl^wIh!mKHePsZP`+68c(li~IptMpBc}uqchxH?6)fUi9B@IVgrwBZZBAXR
z(v8;ZYm74vxjeL9bTm=01b6S=9p5(3M&4H{+m_K^gn8GN+byYy<_>mI;AetC(c4dN
zQXg&m*+3-JelU*K=-*B}cX^};b;VIbcO}Mcm2D7xtbQnd4lXV5>-UV7gH>N)@$<=f
zaahOsu)2)v?M%T|{8PeLI5^B{IrDyh0Sp7^T;`=)0ynRHa?QA5dCbFsqHDH!cIU{@
zev?Z!ftKPeQT@^Tx{i{%aJoM1y+;=1(rJW54B}jrHb>5Wba|=4n8nQ>o)i?M{~9*3
zYl`wA4E37wp&WUvvY`8Ac65HBTA!oP^357^h35!kZCOginKSqGy38mA+`M~&3`9^H
zm`CsFgVu4Q7dt^|=xqJi43Lbl1e}$igHQin9yj-E+^e9_t76}2wbmiCJ|rNU68dFU(>E#JIC0Vfy}FH
z__@6TxOqcr${u1@MfM`sh>dZ?A&aS=cM@Hl;Ro`|@brl7z9zf&%?qD<-096ua{d;F
zsjd;1Vq+^<7txCwJvyvq(4fQo7vPAq{0~D&(nl@1;q&^nW5E#SLStqJLRLb0n0|Ds
z!LJ7o9^A7hhcq%K{q1c8XgQ!Tjr9-!EV*h(X7_b=WBbi_W{M9<;Uv4@&t8ucXdr)Z@FmE>;?!edEG`xxFE#-
zjeQE8s=iIt6&*_sf&YLb^;Y>QO(j~@b1ki{L2_o!oGH7kdhSE(z5Sofyhb=+BrJ{K
zSdMqna?HB^yMn(JkhE7J$m7|L7HMi})^#f*6V01-4Gx;R1vKWL2%OVu6RsVtT2dgm
zi1H6))^Q+M;Dm9bcU^=h;d^(%VJ~-kFfba^bmZvy2|KXIb@b2<-90M1YC>Kl`Xv_(
z$IhUAY}(-9Ns&pTbhNhi!;H(k)wnp#Lam6}f`x&bEq2+^yL*t6V-RgCH*?mXJK<@m
z0FfT9xbS#)d%r*-UOO8tYkvtJsvR1m7Z$1&HL`iDn))3dtv#CTE&R*psM>7$T!Z6g
zA1ou;|7r|>m&6&Z&p3!*-0AFST$S|lUDHCOFhFhYmePTPdshd6lJv+dSO^mIRZAqV
zr~n1$=XJp}-!BVmQ@&J5xbS>io?zcb-vEz~QyV`cIH^H?EbCCc5eKenvjZY&%GU^jfL9T$aqky0AE$D?oV0?T77t~@K
z8$<+t5m~S&w+aS!!JM_E9Ya9`aEl<#q|e3L)Z+Vt0Xlzl_=l&E^K}a*P5pTO)hJh4
zF|iTHqUV!ZHmtp}!Z>UJ(1NQjraHN~n}`d-o){+B*3wj|s
zhOFI!({X-M998_xE$9DiHpD$E&N4bs-u0cvGXx_ch%}HFs7~5?;V+6KfW0RR{*~$X
z`fbFxlRmg6iuj5=)kZV0Q*%?zJmY$It?qLMh205==mZRO6sT~?l2Eh3Dj5wAo7L2c
z8rt1H*v}4%J`V7ah{S~oj))?^LD|mgHt<+tqR_gtvA#HGXTWe-RRL;MQ`n9CwwHpd
zb26=K+fUQHP=fmVGxCx~O#D7DyNsVWXy{3Y4LgS^+mYlhmpy=)9=3sW=YKTrysI;=
zndDktWU*Bd%nhNIh@er8fFqZ}z~*yBsSuMuCJ|Ox(E-k7U8yQ2y1p!)wS3Zo;K9}u
zMS;LN2lnqbo-^k|WLbIHyJ4LcU3D~Jlf?~jtg#sGM68Yt^YAKo{Ma_xL+E)an7O&`
zACHl9>@b}fnnt4X^Po5Z=N~S
zbw|j*!Mm%HI%RC5&4UDb!KZ>Pt{K+d<4e2FFI|=UY;w>Q^OFtjP+SUfE*@kyA3ONh
ziP8=Ggy`LckRbPnn}>Rxj3D@piW^>=-fZ4jA#T*Nz4|D-Xr8=2&ifp>Yi$e)@%p}r
zx&`pkEcjG<@;t|^VBK_Ug>){9q2oRTj?p1pwR9+6me9($LX+aBo`;r7=_?^Wnw1ZJ
zqi-EobG5?u<;8KEe2z$aeD<_(#6gZ!nx!5ucr^4r?k}AMVYzz3cUyywMR5~nny=xu!@ow-W@8t31J4eSu
zxPCk-8};J5qLdhKm5o7;g;r-~cEUvkP``DlpBIT{n%sGW01;E;
z{dDtX1C0my1nyd2lSev^AruX>nJs#+weKei?+R#oOzw%ftisnccWUK}B~+i3s$I=b
zfXK4f*~;YK^f0M;v6w(Ml{wD&mx)HBB)Vh9K%G9)YV!5xS0~>4<};LL!*4Zryv}j0U7LFg&2e#Ua0f
zp5a6x(E3o-U(bx-X`1v9;PnmiUiv_=SVicLF`?${vJ+)rj`OR^B`iaQ^M*=h~mx;xb)BW4$RTI>J
z6D%#raHmbLB4ab*?__67WPZcp9<;Li=KqaeN>BgAJ4PSRI~n+*)PxbGG$rZze+{h)
zU$-1kzl&d7qB;3zEO$(ayMZaI1(y>yZrP(wyf>{@gNIgakx7Rdi&5}NprOL&QNENJ
zdov>=11CkAQLPDyYPY|*g$H6WI*hd3Ku#g1xp=oEx7n+y0M+#a;gzX1ujm$iLi_R;SN2Bkkk;qn!b$RJjgsEA-Oe-V9@6)04O4A+bj2+686S`&7e|zP_f!
z5-2fg6DSZxUG~>Y*Ozo>DF~BeX-Z$16%8!y<>f`iz{nuo%@{*WzW=wS`H*Pt+b6!h
z{6QIZ0pa5=Po_i3ZjD33kjnWn`my!+p=^S7Ce#F76~tsU(R#l1WF>~tXSg|8s};(u
zq*1rO{_?Il#astZR(b-BaKFZ*W!!CHzlb?!bpAm&x{pa~3wiJx6;^;L&~zIZ{DPir
z$F5z08y9zY@#@v`HEWU>vIP>X)VeaCzO9Urs-*R`(#;Yg07mAOKU}0pvz#a_)NORp
z_O+7owElW&Kloa}2Yi
zcI}$Q9-->&uB>b&iv!GG@a-d-AU2!vCj(jg%D^)NVIcbl1zDcX4GIat$1fjpMP{a;
zAP-pusjRnXe#w0$K96yYNWF9C+}Dn4A`Fd<8*8zx=wv$s$d8m7?ac=GN&L}hp~oxf
z``7!OrB5nC1cq%~TUQrldhRYa8R`+bE9bL2MV_6E9U`o{+(^qBB0K^8CkBFU`J=7e
z^C5qWeIsftqW%vAanqswMsl0TRzL?|xpF0zw~UoK@HH_L6g^%ejWNHYM;+hX7Mu${m;TtX7U$>xj+*r8QyV>aQNqCoRw*_id-wXbTtgy?
zmI@F5)=aGizQCVnM%-X2Dc;GIn2i~nYco<`Yo6fT&WAiC4j>n@a<^_e|~Q91Ojbj46WR4bNH`)`RA7=@FEgxzW-&%4nT6l-OKiNi$`TVQdif!
z2W80!W~-4Gao&bYyH9ofiz&>3ewJ}m>eT$MB0qIjGzDR8bv4tHX`(SWF$Co^R6KHZ
z8g+_A8+B&pYIYZqizX+G|{t0`5q^+T@Cur-i0mb0GsJ1Y$N
z`t6R>KoQ*+N@p4n1_=XM*TqOHv&NX1d+Wv|x>kBO-SN&mJ}#e=26ur(RZ&s#VR9`h
zI7ZS@9DD8l^;eLo9dB(@A3WHA!!we7VZlNP1QjJJ8*R>CLGP>JGcR$=AM*0@IY>67
z(jta6_09n|b!dRLQ4I$zy!xV_KJs)hDlyf7<(LRYmFz(G`A_W=UOQ_qckcQR;mYEM
zZ0lUK+@z}h%P4R{f`STCyj!p~b=^d9!jZu5_>ezMeJ><+Ah!c6Nr;%z^%@q!XOKcc
zr+soQYU3wtKKd#v(!zA-%vG=j>r^`Fr+7eYRvC9i@GD6kHLkML3jrcGSUD6*B=DkcO-A
zFRM*)CWZTxVHo@7)hl7sFC4Me#K`#M=0@i*TfB(S$T6gI3}76ojkbL+CYwgWe!`k)
z0SOle#0w`5^seD&v&kS;O?ZvE59^|2wUJ_jXxSCg_1c(mwdYmDnX^}7;9^04ePN7E
zpD|v?>J1)|wHQi_5*%~%t!X!IO#6A_4;4>hBxYu2BuL3zn;2$(*H^dpYkCw-5}%r#
zEuIyfB-Hf7Z8Gt8b10#8VV}i5Kl^cnW+eXbJfLdjq=sT&Z~>S~qnU3&91zG3!T{#P
zvbbTByde!6ZyvMY_P^lZ1vsEoab@hpwMZM}s89~b7-?|Q0`NwhU2rQk^(Cz|@M>3>
zRt_0dikkB(NrXWmIsx%_lzW<4;?zRA{vGj#)o)(ANutM>u^mOm9LY9TxrnGEV`Jf0QqafL)qeX&8
zS1~d~ib^eG_9-eh7)s)35d)*1eSryse3I>mq#d71?i)V89xxCn6ye2_Wi}W98%h>9
zb%f1tp_+CV`|7)#ePf+d)=}>Lf^zM(ACB)`>fQI#?~gi-id{G^aq+p!Eir~e{Twy5
z+*@r!60dZ69`-dFi(SKg9C(;MZC4aWbXGWok2rfjS6f(ONHv+Q9XHANL1~oG3Ij#w
zAL#Q$cdTm!$C+-e;2H~?9OS?5DZ$oplxQ@ZSAZFicUZ{ZFOABPyD+MMf1i`dZR89d
zb}ZWIT{C5GV2#XT@ru&YcUqH@Jg&~$owr~u{mH3wB;`9o4ojzg)$}AFwEv;+_)l8i
z4Te-Y8a(4y|DLyeC1SAitRfV_B6+XYK_
z1bPPq4jrNxG#RJZGOxI6*QgT18DR^OncPqsLeDY15rpG;)|eu*Qi=bEU;VD(7ROzV
zc#57WDy}0F_3;_W+NGYF;uT{*ZKkP-{JGPBrh9tYzEn#(pR?+FqqbkKL*UyG-8J>&
zU&U`WMjZvAU(F)&CmJ@0XbOpf#C{SSi}+;o0372-(r*N@2TXvyQv0r`g^#dr_wK`M
zdT3e={_YqC#Vrse1+lNR>uYQ@*cwpQxllgTmYWth3(P2)Y;FN;mQ4V@VFA$v_DRIu
zNd8s>A&@E_yloS*g|AP5Af<;84}84_f^haF^?FOcx}mU2&kpu5VF)x99T{U8MC|jg
z1BWDLRUdhK8wMFAfH;jAm#&DR_CQM
zQ}=ys?RX~skWSLohsiaed0?YF@&ByEOnxk_%rc)W*9;qz9ffOLlwN>Z&{2f
zOcVao5620S{fKXT6#ciR;HCdnipbsQ_K$Bz$tx!p{_8(JjFFCH(^uQaIdkque<0sF
zcu;HHa$iF6IDP%aXw%M*Be|qL`$Tvja$ikua{QEk{OoXlsgupfDoP3GWtc@^4xmnX6+tMrE)NAVyv|zXRL*#G1R~c-30lI<%FO9ZcP|
zk6tM)g?J0PNDx%JUEkagOkxIyE=mK4#lVDHTg~wmPynrGJ+wfNaxYK|7%)>^ZU=7cEL#VvnScoCV>)3d=NWE{PNl8R~F>%Y^>YeWJYxz#zMP)9~xs
z0|$z6-|CyIg!{q9jd*5W^yni-T0?mSglfO0Nf6?;NOjKqkDm_9!-O=ID}CygFv!$A
zo36vFMvGNXcycjkJ}h*$YlKHXF~`>@&Y50OG_w+jT5yXM9v@BAC7nJx^6Q%&>L+IN
zc>v#{s=WI#7k(3doTo^?XmZ4Rw={D}QLWf}LQH^gX&qsqxnV;M=r{S~EDPBK0wtCO
zdjB_GOLnhu5L;+c+`4^RRxcae!HP1MxxqByW*NSNfmxMMoa+B|wcf&6&&t!TJA1BhfZ9?Q)y#opENLC3*&$NLS%?
z5b4~vZcUrKo{OBj7+b>=8rit`5iV&$G0EfblybH$-me1RhZqITkXV&I3WJNj<2D=R
z!Ka;TVS9bE=0X*h#YK;~H%a=1-&X(rp>(Tb1Fz11Jji%4^MuUu$*>_YWd)7K`rpL*
z*R_RIHJ+;)*e6uDEzKWOm@JGHO?NYwDf_+gkQBbD&UqSPO;{43Q^vU99p_^~K5I)Z
z6sEM`F?MAZ;(r{)LN}C7pkK)xK(Wuw;{i1VsnUxzm9X>8{VFv
z!@r%N0+H$gw*m%*vcL?Ie`=jE3{THWfiTbbce2gjyj#5JPc$T~CNT~RDA
zXa`_2+!zL_#)p$nhILu8`;?
zj<_&G*P-C6s{;-gAs&yJ^?jhXel`BbN3?=Lmog%%b4OBIfUMgjZZ%1k7k0_G%(UA<
z`@y45q{VQ&0^TWD4qx21q01`LSng7|Q{f=^C7)-=4ojZEluon7e?*@dLWSXK3^=g)
z^i}Bf^+x&MI4F{+|BZt(;^u6SbG#oQ`kduq)=J&EVi*5fQfqK~up
z;dQV;s6W&*z|o2{h$z8twC)ifyqjM2tNwsRsk+@*k`=Ter(-`LB>54t&=D!Vlm-F*
zc80GTF(UzY6_e^p%E@{7%pz`;JvLIgCJT(!aF*}Wsww*ltsIAP7W~HS;jLQ^6yXW#
zWbJ+`8;e7vFq(wHPc;+)2TzD(G$A98Nb4)}-_e+i4UNp7833|$WJn7`$G-wu)9pwzUqC~=E{ow9<$QM>?K3zJ}n+nbsNUX
zG5n5LD3$D{ma1p2HfEcO-hXJbYpKcn=ci{+&KhE%xn4nPbW3MOmd&U@od-tu4HhJ1
zX&8IPKVSREcSU&6?ov1FgNF9Q-GUt5E(HA+TI!+_9{aDKLqC3eIX?TRe7RYNf^I5(
zPHcIv+xzaZnvn0ZGT%LTk$HAbwUsc9bM-W__2|?-x@atu2_Xc5Us@jcL;D&f#?uNz
z>ppur&Xlx&d#V*n+z?vmq#aZUUcw#x$E{l!Z3U<=oI7+7?~?gxLW{7sBC7fsJ=Nh4
z($Kuo4e&>K>SSJU;OUI;Ut_ORgU}XR1B^#R?&tA-n^8A^!^aao{LvK}XL?pvobn6O
zQ?!Rn1R6f=ev7P4s{ZoH1VF`>3K4?d7-3riG
z;8-GJ2pJ>|Y6HpsefypQzf`wOf$AnKMaVHSBIc~WE9vyFf2r0Ew(yrsxN&Ohl3I)B
zecf6!+KyFG^`PaI61?NcMWcofUqz!yl!N6_Ky`u;Vm#D0@#m+B
zuBLhVbVpD1%I~T=#7#YP_}35O7U9nrrm_?6Z%Ow_f3(|w5tgxT(}yha{e4pXqvdo3
zfNE(qu}hC-p3L%|BQJNabEko4f~w2?I0C%^suJ_g$1wMFm5wrbV|3Od#afHW%fG(A
z+PtZN;Uj2oN6z}-!^55Pu+fo|+i18w?KNP;ix*3iXWvbXuQ`^XPYWq0dYq>mUu^p4
z7qbO=AMSAYG9o0JZ1C0+fYf15R=#>Qns7xG`)Jd-&OU|mj(fh^OYpnTpqx^-wg<;o
z&*toYX=mk+V)I+zf0|+ckAn%;u?o
zMdj8Hv&ip?-I5?M(St*Y1QSBcNy3IeV%?q=9ciwo^w3sjJPd}H}d)gZ}HYND^Z5`}YSGRYVW)G{FRb9Uw8?k4{E*yDHt#~uX`Aws~
zN#n3P1GKcVLyvt3&aS?GZR}6~{g*FE3*&3vU9p5GC3BkXwt+~}q@eiI1M4=|#Zt+g
z7r%$D+;QS*aA4p{9cBFeGMvoZz_^doe<@jQ=RSC$oBF!W-(LQND{rDo)xR$;DM3mT
z@Z$VN)p6sVJhj$TQBUfAY1E&`iVvD#{xCfXx!L*+8`L9A${zrJG9;jC;~xIr-xp(T
zcefIY!-0WiZ{ONloXI&ypktTom+`?iv*w~9#_yA*dlHV`fJ^*3$^vXnBU=(zHKhHw
zKq*el#)u^n-IGOPRL#!s9-N}m%BZm}kMc>n_t$>AH_U&pR7RrXa#AR+PJANvHNz~Yj+n~4dfUN`r99+U*r{T
zm^CMwSYlak!4GT5ufASuabv}|Gy2-pB*~n=VWCbkesz57r&ajdr#&qV_!mc*e?*r>
z{Oag_^mFT9-(ODCz4Ns*
zpSk3fzvf7-n`@rlyC~s%3M9@1=G2?qLh~HRj-o?NHhQTu)Y)AA_4>R!Qoerx$T~m>!^bvAx4Vv=XJ}Y0$xY0
zez4(~t#8ykcBNHujQO$x}0F_edqwRte!C~Rf&
zvByaQN%5l29z3o3->dCMo%&M)YPyd4-=RzUJ2mV1t$Dex|a9n=_5PU5ZND>z+@x{Ehy)=mhacu;ION
zJ^`9fp$`Tykk)}dLkh!=y}i9H3vjhZn-%uc)Rt}kwNVSsNa0tHVCHvXG5+JDygl;3
zHiWAQT=tR-km(b&P%-f)=@3;Yt~&6c{3N*VEn{%#j5>=m_f;!1I%V`xs*V}fU&WQ0
z-%kq$dpT93aOHnqwq-&u;{K1{;zi@x4|VM#qyG?d;6O9PB9~fEZpNy$Pzb@t6d60-cw%xd>y9UJVC}YUT#5fUeEw@BRXjasA9Cm;UOiJQ
zm!oRWcrb*(aOLlx0`Ym408(SU)rdOFC
z^=?vV3(M>;>3&Wc4Ayp$T#ua_`ak!Zd#wePJL6IN5;njX2
zOHV)SZaD(Wr)8&3KK`+9-)0a!tEkn(TOHD~JYF(FIBey?!bWB{bhjx?X-UamY+fEk
z1QfJ*0kE_m!`wY8glgF$GYJw-+MlmUsTmHM_?Q~V1F}tZwZYfr_)hZ
z-ZkFEx-|A_bwvjA
z#wtrP1H2_uC2Hczf(6v+U^c?=eb1eaayPs$xk@xA_@?_YR*$j)5HN+&O%>|y?(R61
z$P}XWmh*Z3j5-@43rUm=!dAhryTHcB=cTiP0%L$W%gYe2(D;RrKD<_%lK*jBxK*#)!n*Oq!j5TE+m2iACh!&AueE*rHpwVmizPHdcgrA@bv
zf5p_}+v_cMWX=J-kL3rxl-R>bYvcc2xRGYlnW=k7PvjiuO-ic6?@1Vz2zPup;047_CL{?yfwB+wh)fC6vnXn!Z;lGu1bo68+aIa2M62x{|=_b>&?Lm>L(v
zuC~)J7^bIJ50M;d&IM3gmH@$0|0@$Mn;$Jdh?jXNuqU)P=G<^V7SyW`3j8d4OIAte
z&8g_Sj&kda8q1^LstiM^WP4Y%_L*kWJ+Xdn(BIz3y+XAs$)wmRd`1%U+4JU!HVlJZ
zh`*?eg?BrFm5Ch}*gsSlP<7*)dTR!G!Y*e(ceyaHKu^d%4L)=zR7dOqh$|*~>Qccm
z0BJP})+wh>q4U&-eF~gL!_R(8>;uT+G@QiDWxhYerNpFzDsnfblwXuq^!xVam)BVYc|J|{
zv|d|QT-+NiJ5q**z5&e|xGYQ&Q#qEItZsA1Jj3WpzN#Ip__kIet?d{z{a~>bi
zAoqxL`^U5x;LK+A{6*Jp-V#s&(bQk8o&kMg;FA=OhS=P?cFg)1R8Y=!tFZ-dt!gM)
zsuRYH8b#PR0ITs_pMyQ+Zv6g_%;WB5w+Oy4Q@$!{8O@-6@Uhqs=6av=tR)SNjdPEV
z{Qar*Nw~ei
zj{H^b)^v#`_s5@iNJ5IWWdDH!Yw1^0%|pCiljeP$L0_r(7O<)@MPnsz6P@#8(l_Js
z(MMUi5&siGr5iFNjO0UBVu`i`_fg=Fi#FE%L8Enb>oAgK^oxI0HuujBpEfKVnw%Q2
z+bgulEQe`mtOiygMob>{k0pQmF3);L^%QGv2!K1C_@l`-&0(wa-k&@f2+v86);qIQ
z^fWcAcyhj%aLQ-57F*Nt*z@bJhdvXw=Ip%c(cr?OGTG1rs(kSQI>uy4H5otozx>fdcW3r&hSQS9jmUU;
zFYW(!xBuf+jTQe#*dp>HykG7fhF((3F4^W`A4Hr8
z8KAqZ^j-Sf_3NyM-HK22Or_}^4E2u^OxW>uYlXyk)Tj^GLxdGY-gopXcf+i(d`x?}
zuz!BmjulayH>{=;jI=v7Y`9B^7QWL!DD{Og-Ot=VpSelFDFdQCHD&`@Q2h07j$(psd|D*{S?6ZTgHEVMvLG4Ea)XvgIlt>kKdl8=~?3&CVs8
zxebwj+J`T0%;M8QS6WH#6;{+u&aX>S-1KkhaqkFeGhaYN9a((xT>+bwh%egrqenj|
zynaoGw3XZ~{Os99nt@wRz#G!;TVnWR=Uq6i;9r);iJczTTfh$_OPM}%W{=0gaVyUi
zs-;-XJoACz`oI0at5UV_c_GcYvKX2K%ib-v=BVW1Ln&XMH>r3e0E0g2XJ_>s_vA^kb^7Lcz6WEYFp{%sD9uyp9SrWbp
z+++lSM)G0k6^n2m!L4NrIk9ZWM2Cs>FLw328#H>B#d*Gop;l5Ym)IA+Ha1QGeDdT|
ziHW|o@82J4n7d*{DS?!0f2K`RR%=*RwJi4O<0Iy@wzBCCC0~`4fbPh~*=;kg6S;Hu#SHyAw%Iu1QSa
zszwYMHZ0=+(6GY|(GLMnvmZ$iVHuL>G~~|HS5-O_M%HJOz3;B_lbh^PGY#U%eTIiOMl~sjMEd_`dkI#Lx@~|?9!RnLy3L4l6xJli+
z`;#NsY`to7b7s_&tAd(>eDLWOa9lhvMDj;9f|4@$#EC*$gFGbD&F1NSf;9B;_5Eqr
z&NTJ${E#it+^9f9jRIgXEm|W5hvW1E2-enpGN}>8)F%QfEy1TiRT@nsGexdteO%AR
zo}~Z)tV8W{=rbkSo64A!Lb&*{@4i=1K$Ll(gbsvsKxM{Qa*XQ(QnF=cBL)o`L@6kE
zbk)a>^>+9|FH)^?QS8{1-0Gt$`)4ZEi+L>l`e{XUg0RQVL{?^Q!7Qs?Jc8_JQYeD3}gV}=L4y_QH0l;#DiL3`{d-0uxq&G^}niiyc
z!Y0!Ec%*rl~=Vc$r_YTgNOtnaQtlPnviq}`O>diRrDQ^$~x7OqG9
z&i(##1~uLQ75W|%Rb7q8dp2H8Jn+cg`CFX~_zjUSe0nx~XA(rdcOw_f&ZhGpv%Q;5
z^|NXix#OpwNz2aPJ>4c6+K!L~5jJeMzG#gzskGf%c_SwR;IivVruk5IHGK{Wtk
z)NE0-8@d`Y82`WUuTbo~aYCC6&95VjIX&tT#zEQ+T=#U016{|7n!ioj&BJ#bZ5`i6
z#qK3X4O)J_!L98r*Z#8mLfggomE7kzP~ea*M%|=0YOA!+uu$mR@^ezIM<#M;JGb&7
zHTow40%QGip}$6%RnrK>7&cQ(C=BlHD{}Rfz14+b-`lq%?%Z)nA*0R8$S}QYrdxcn
zkH&SO%lC{KcJK1?SyYi>$Aa^_!FKQGS$kM9(_Y&cuD_xeALj?zrT-!9zqQ{52Wbr(R>s7#e#kO27eW9n
zLDSg$hoWzP0XPsp&X!&<6mg*?OfnS;Y&}TqP@fmbiY2$H4
zYw^1i(G-*tFO@xGC5v~)#>Pu~)NC6MweU=lQlBrjSD$*l*wK?AAH%z@*6$zd0YabB
zRJ~VLXRAtA
z=ZS@&1+*u#j*gmEdb(6cpPQ1XJ$%rpMYVa$CZbq5BmNks^6i7eIIGe8H1pI>eB
z!}ISx=8^KqMvd8JMq`3#A=8VpxGs@Yq4(Z*$3rb5wc?a6ZDuMam!hAOV3&@jrtzwU
zVHCInKUGrs_U;h~&By;+|61vx0kcAp{&@~;O#Eo~F8#;(@1m-g5N=i`%ePDF?(=1Q
zZBp*FZz)ROWHArAk;-K?2EY2FYj+PjfmC;2wX}inTO9@DPl_Pqf&qA04$;um^DR8T-uR6zHcoYDUC@;mz$OTC_PDVX*B_08P8d4`6j
z6LnVKZ0xkVV;2aKUz@CsL6<{}hFT_*19p5H<&r6E&n5X@>ehP7`#JUKQR$NHKlMv1
zzDI!oK)AcNZ9#Z%btQjA^S+Pa{Q5=2%3`L#z~HpZ-qw;YfC|JW!Z@z(O6q^9
zqo#Yr_`@>8m7-SI{N^XjmOv9h1WPD)`~yu~C(zcrNh0i^OPg)Kir#?(%9@q1CDUpu
zC@K7V+DvO6(zcMQnDnY+yLL_7bJgRuVl;L(U3&xsc<|!KGc<~}pDEo~zMy91
z`hCi}2F-DaW;PV3FfZ1mz1s~00Ig`o+O^RJ5)Q^1kOn%wuu&tUH!~^k5-Fyv_a?T5
zn)RXK0hu${pX3RGo<%)Z)5HD-Y2Oi}EiH|eT38o|ikI|cbkoY5tJmTx?|NmOM)~KegG@5BeEQl;buoVUt
ztAI*@Se77AOTktV6yy~|k=F)@xP_ZEb*Q*{TV2I0
zrl;c?9Rmfrz5P^Ge<5f6r?I+jyLV?vM_kXIJ7-bG2j=oa+p5?OI7b$Kd~gSN-F_4s
z;^q>s2z58Yfp_0B*;9l)1vX?m0iT9?LuEr;yM~Tp?L`eW6lNJ)C*a?J6u>Jm8{q9)
z0|WT9go@P@)-J-x-W_|K$%1#SUFgSUYJ1VUBHzo*@RwsjP(PqF3|VMOv~v|(c4Es@
zsT6JeqOEiJiqa_2wHLLQA4Y7}wb#N>&MQ2!+f8Fy?mlNf-gYoDaGl$8J
zI>nR2Mf&4U_5JK@fyoLK19{@>`kSwK`<2qQS#}XnKbidfa+C!MmO#RQB}UOb%SFD5
zHW79jj@mJFad<6AW$EN`;Ax*J6&0CI>L{MUgYCRNwF#flo+d
zBM~d0{0u3LWngtgY^D{hJw2yQ+YitwWMGwOPxCSpS0Pcdb~geVnDN1=V-m5?2B9^~
zXRBBl1WKK6(nSzVtdmWrfQ$+v+uZLIK=z)Mb(8(#DS%u(Pz8>TcM(NN2YhS_&z$j)
z_3)m6*ZPYZ(iFni8TA=q&@u8mgE7J=@qXIZmy??t15Fho-df`xUp-Y?h1C#M-|9nT
zBPjBMJWX67Lp}wZ2?e&X2?+{-H;DG1Nu}0_3O3hb`qe9_WB?i&$eynGl{QQpMJ%-Xa*?mGy&jCpI%iv_g@AAHnp8b=?j>ryS5~(@T%&a}U
z)$kESTt6rTn!_g{FP4iNmMdD2S^y>nwi7Tpf&{P!)hRWS!!9|sl9=I6#zp5PXQw%y
zuP+x^`tyeX$3kqHbwWi&1$GHCn78hgQ>L6l@E*ksg`!aeC=lWhd7$u8Pex*2e)#Wy
zAnMAzZEI(zVX&2r1>aZ5xD$z`L_R{p?oxHUu`{~+HtDkT#cA+>OG$|k<_VxmSS*J7
z`zN5AD|9#kYp!%i*L>v^%imWIIvsGf(3mI{zbVc4@r*4kAJo+y`uSTe(piIml;`Av
z1m)vTnES>aBa%EhU3R3^pbXx7eFFm@Xlqws7teG67+w)pJ=mGtr3Id{M6kc`
z37~;mp1`cG_5T=Njw>^}3+Cg5JFahNILcyyW<5^EVxAyBpFT*bLC*q0C|n)%aNr`w
z)VoGvmX+~dtp=yg2PMC}bp?{z5Ii)VmR)9P_cxxGs=di47a?IupY<91Qbzf-B6EI@Yl`C&tIY}+YT>-_lz?es0Kj7tf$ESolQU*)xBW&wjZ)s|?
zUv`p)QW^J-&1Y4uj!YG@w$95*ny8DG8-t^7xUwtlMPtln|Hc5ucU0dvCht(jqSNXO
zQOh$b4p@lH2Q4)Xx#}u@=VXUp^RC_A3Q}^3*ui^GX{zYguw`nzTjj|C2f1KM{dg|S
zQ|akbXsV8ogE8fXtIN_03c5h%Vbf&P4?j;tSI$p1`gvM#xbOF&F1E;^CB=miRkM6ik%5vCvcoc;w9Zow98WR1Gu?_^zpJm$9r8M=Oeu2Yic-8)6
z3^9FJ%U^>ZFA60@;FlapCoJs|;SrzK(E{i>nt*+rL296UEmvAfkF!O~Xvs5c&U&=c
zKYZ@t+qUh$*BNY!2LZ12zVck$xZb-_&Hi9Q=*j??I#$h}0#Qp4pmWqETg;y#;QDAw
zniZvc-qo|RRYxakEU|92P-j(xsjyWnjs)e)7rLXvRI&kZOlXbKkeSNr>YZ6lqm7Sm
zk(Zc+{YTu^IXIIE>6Lz-TO3!`QPB^iZ&KTiMti;qm>6tcNLQRFp0$MjH(D^$xa}Xj
zkf_SxX%onU^z*2=NJJh0EyB8XefTcA!%`qlkV;i}+aL!Lp&5(+SMbcZurehz6^6z4`RgNR2dU8`fNHP4xo+rXqKgwa-ii?B
z*w`2tDj7)T8v0fm?dzkY*#dxAKqW{K>3Y#Q6T9#Qz7u^FU+H|%x}s&;1nB#!hEyTr
z5%N3aWGLdQ2J)w|MIBc(L9~H{!qn6h1=#IQF6hI$*F)@Lv
zLJ(yCo-x%_n|-_LmBzWZLn~pV)Rdwx-}{D!zy0cj3pi`dLXrhAhJWCmq#K?>e$d_C
zi1EbPNmVR4T&uKQF-dO{i=TlQgtURz5{S>a(v6KTV>>|{1w-TUS9jAc&fY{@wNpKG
zGM9$h{B=kRC$Q?EqY-$3?9`lO_9AvUP=d0}EE0M_#5y@Wje-CobVW)@S}qY#ICN8W
z5GJs_55|uS-}oPt8U!Z!J7Jbavj35ulDg35;9`7{?O3|1P~$+Pb+969NkxYVo`Dvb
z1<7}^FlWe=u^}=S^4egE!}k}CZf(Ob&vMuJm*d_))gm~OsbL%;StB1prEt-LU<3yj
zJ{tA4-9%PC@;aKbz{2AoxwHvCeRi?MQIpPFzu0!6;5EH?jpOe4AL}urXf&7Y?q8H{
I3;x&t0An+OAOHXW
literal 0
HcmV?d00001
From d90256923955ab169bb39b9b75bbb7374d78e393 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 14 Oct 2025 19:40:55 +0100
Subject: [PATCH 03/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-localization-in-rhdh.adoc | 7 +-
...adding-localization-to-custom-plugins.adoc | 118 +++++-------------
.../ref-best-practices-for-localization.adoc | 34 +++++
3 files changed, 74 insertions(+), 85 deletions(-)
create mode 100644 modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 02bb79ac51..8466ea8a45 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -11,4 +11,9 @@ include::modules/customizing-the-appearance/proc-select-rhdh-language.adoc[level
include::modules/customizing-the-appearance/con-language-persistence.adoc[leveloffset=+2]
-include::modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc[leveloffset=+1]
\ No newline at end of file
+== Localization support for custom plugins
+
+include::modules/customizing-the-appearance/ref-best-practices-for-localization.adoc[leveloffset=+2]
+
+include::modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc[leveloffset=+2]
+
diff --git a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
index 04b505e1b4..945cd1df01 100644
--- a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
+++ b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
@@ -1,19 +1,17 @@
:_mod-docs-content-type: PROCEDURE
[id="proc-adding-localization-to-custom-plugins_{context}"]
-= Adding localization to custom plugins
-You can implement localization support in your custom Red Hat Developer Hub plugins so that your plugins are accessible to a diverse, international user base and follow recommended best practices.
+= Implementing localization support for your custom plugins
+You can implement localization support in your custom {product-very-short} plugins so that your plugins are accessible to a diverse, international user base and follow recommended best practices.
.Procedure
-. Create the following translation files in your plugin's `src/translations/ directory`:
+. Create the following translation files in your plugin's `src/translations/` directory:
+
-.`src/translations/ref.ts` English language reference
+.`src/translations/ref.ts` English reference
[source,json]
----
-src/translations/ref.ts - English Reference
import { createTranslationRef } from "@backstage/core-plugin-api/alpha";
-
export const myPluginMessages = {
page: {
title: "My Plugin",
@@ -31,21 +29,18 @@ export const myPluginMessages = {
},
};
-
export const myPluginTranslationRef = createTranslationRef({
id: "plugin.my-plugin",
messages: myPluginMessages,
});
----
-
+
-.`src/translations/de.ts` German language reference
+.`src/translations/de.ts` German translation
[source,json]
----
import { createTranslationMessages } from "@backstage/core-plugin-api/alpha";
import { myPluginTranslationRef } from "./ref";
-
const myPluginTranslationDe = createTranslationMessages({
ref: myPluginTranslationRef,
messages: {
@@ -58,18 +53,15 @@ const myPluginTranslationDe = createTranslationMessages({
},
});
-
export default myPluginTranslationDe;
----
-
+
-.`src/translations/fr.ts` French language reference
+.`src/translations/fr.ts` French translation
[source,json]
----
import { createTranslationMessages } from "@backstage/core-plugin-api/alpha";
import { myPluginTranslationRef } from "./ref";
-
const myPluginTranslationFr = createTranslationMessages({
ref: myPluginTranslationRef,
messages: {
@@ -82,18 +74,15 @@ const myPluginTranslationFr = createTranslationMessages({
},
});
-
export default myPluginTranslationFr;
----
-
+
-.`src/translations/index.ts` translation resource
+.`src/translations/index.ts` Translation resource
[source,json]
----
import { createTranslationResource } from "@backstage/core-plugin-api/alpha";
import { myPluginTranslationRef } from "./ref";
-
export const myPluginTranslations = createTranslationResource({
ref: myPluginTranslationRef,
translations: {
@@ -102,24 +91,21 @@ export const myPluginTranslations = createTranslationResource({
},
});
-
export { myPluginTranslationRef };
----
-. Create translation hooks
+. Create translation hooks file, as follows:
+
-.`src/hooks/useTranslation.ts` translation hooks
+.`src/hooks/useTranslation.ts` Translation hooks
[source,json]
----
-src/hooks/useTranslation.ts
import { useTranslationRef } from "@backstage/core-plugin-api/alpha";
import { myPluginTranslationRef } from "../translations";
-
export const useTranslation = () => useTranslationRef(myPluginTranslationRef);
----
-. Update your plugin components to replace hardcoded strings with translation calls:
+. Update your plugin components to replace hardcoded strings with translation calls. For example:
+
.Before (hardcoded):
[source,json]
@@ -139,11 +125,9 @@ const MyComponent = () => {
----
import { useTranslation } from '../hooks/useTranslation';
-
const MyComponent = () => {
const { t } = useTranslation();
-
return (
{t('page.title')}
@@ -153,21 +137,22 @@ const MyComponent = () => {
};
----
-. (Optional) For content with variables, use interpolation:
+. (Optional) If your content contains variables, use interpolation:
+
[source,json]
----
// In your translation files
'table.pagination.topN': 'Top {{count}} items'
+
+// In your component
+const { t } = useTranslation();
+const message = t('table.pagination.topN', { count: '10' });
----
+. (Optional) If your content contains dynamic translation keys (for example, from your plugin configuration):
+
[source,json]
----
-// In your component
-const { t } = useTranslation();
-const message = t('table.pagination.topN', { count: '10' });
-For dynamic translation keys (e.g., from configuration):
// Configuration object with translation keys
const CARD_CONFIGS = [
{ id: 'overview', titleKey: 'cards.overview.title' },
@@ -175,11 +160,9 @@ const CARD_CONFIGS = [
{ id: 'settings', titleKey: 'cards.settings.title' },
];
-
// In your component
const { t } = useTranslation();
-
const CardComponent = ({ config }) => {
return (
@@ -190,48 +173,37 @@ const CardComponent = ({ config }) => {
};
----
-
-. Export translation resources
+. Export the translation resources
+
[source,json]
+.`src/index.ts` file fragment
----
-In your plugin's src/index.ts:
// Export your plugin
export { myPlugin } from "./plugin";
-
// Export translation resources for RHDH
export { myPluginTranslations, myPluginTranslationRef } from "./translations";
-6. Configure in RHDH
-For RHDH (dynamic plugins configuration):
-Add to your dynamic-plugins.default.yaml:
+----
+. Update your `dynamic-plugins.default.yaml` file, as follows:
++
+[source,json]
+.`src/index.ts` file fragment
+----
backstage-community.plugin-my-plugin:
translationResources:
- importName: myPluginTranslations
ref: myPluginTranslationRef
-For local Backstage app development:
-// In your app's App.tsx
-import { myPluginTranslations } from "@my-org/backstage-plugin-my-plugin";
-
-
-const app = createApp({
- apis,
- __experimentalTranslations: {
- availableLanguages: ["en", "de", "fr"],
- resources: [myPluginTranslations],
- },
-});
----
-. Testing Your Translations
-+
+.Verification
+To verify your translations, create a test mock file. For example:
+
+.`src/test-utils/mockTranslations.ts` Test mock file
[source,json]
----
-Create test mocks (src/test-utils/mockTranslations.ts):
import { myPluginMessages } from "../translations/ref";
-
function flattenMessages(obj: any, prefix = ""): Record
{
const flattened: Record = {};
for (const key in obj) {
@@ -248,10 +220,8 @@ function flattenMessages(obj: any, prefix = ""): Record {
return flattened;
}
-
const flattenedMessages = flattenMessages(myPluginMessages);
-
export const mockT = (key: string, params?: any) => {
let message = flattenedMessages[key] || key;
if (params) {
@@ -265,37 +235,17 @@ export const mockT = (key: string, params?: any) => {
return message;
};
-
export const mockUseTranslation = () => ({ t: mockT });
-Update your tests:
-import { mockUseTranslation } from "../test-utils/mockTranslations";
+----
+.Update your tests
+[source,json]
+----
+import { mockUseTranslation } from "../test-utils/mockTranslations";
jest.mock("../hooks/useTranslation", () => ({
useTranslation: mockUseTranslation,
}));
-----
// Your test code...
-== Best practices
-* Never modify original English strings - Keep them exactly as they were
-* Use flat dot notation in translation files (e.g., 'page.title')
-* Use nested objects in the reference file for TypeScript support
-* Test with mocks to ensure translations work correctly
-* Add all languages to your app configuration
-
-== Common Patterns
-Use Case Pattern Example
-Simple text t('key') t('page.title')
-With variables t('key', {param}) t('table.topN', {count: '5'})
-Dynamic keys t(config.titleKey as any) t('cards.overview.title' as any)
-
-== Validation Checklist
-* All hardcoded strings replaced with translation calls
-* Translation files created for all target languages
-* Translation resources exported from src/index.ts
-* For RHDH: Dynamic plugins configuration updated with translationResources
-* For local app: App configuration updated with available languages
-* Tests updated with translation mocks
-* Language switching works in the UI
-* Fallback to English works for missing translations
\ No newline at end of file
+----
\ No newline at end of file
diff --git a/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc b/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
new file mode 100644
index 0000000000..7518d18632
--- /dev/null
+++ b/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
@@ -0,0 +1,34 @@
+:_mod-docs-content-type: REFERENCE
+
+[id="ref-best-practices-for-localization_{context}"]
+= Best practices for implementing localization support for custom plugins in {product-very-short}
+When you add localization support to your {product-very-short} plugins the following best practices help ensure that you establish a robust, type-safe, and future-proof localization workflow, separating the immutable source text from the organized key structure and ensuring reliable deployment across all targeted languages:
+
+Do not modify original English strings:: This preserves the source of truth for all translators, preventing unexpected changes that would invalidate existing translations and ensuring consistency across all versions.
+
+Use flat dot notation in translation files:: Flat dot notation, for example `page.title`, follows the standard `i18next` library convention, which optimizes runtime lookups and keeps the actual translation values concise and easy to manage for translation services.
+
+Use nested objects in the reference file for TypeScript support:: This allows the TypeScript compiler to enforce structural type checking on your translation keys, catching errors during development rather than at runtime.
+
+Test with mocks to ensure translations work correctly:: This isolates the translation logic, guaranteeing the correct keys are passed and rendered without relying on a full environment setup or external translation files during unit testing.
+
+Add all languages to your application configuration:: This ensures that the {product-very-short} application initializes and loads all necessary language resources at startup, making the locales immediately available for users to select in the UI.
+
+.Common patterns
+
+[cols="20%,35%,45%", frame="all", options="header"]
+|===
+| Use case | Pattern | Example
+
+| Simple text
+| `t('key')`
+| `t('page.title')`
+
+| With variables
+| `t('key', {param})`
+| `t('table.topN', {count: '5'})`
+
+| Dynamic keys
+| `t(config.titleKey as any)`
+| `t('cards.overview.title' as any)`
+|===
\ No newline at end of file
From 348bc29f886302d89984b067c2d056a56520e7fa Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 14 Oct 2025 23:49:50 +0100
Subject: [PATCH 04/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../con-language-persistence.adoc | 2 +-
.../proc-overriding-translations.adoc | 7 ++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/modules/customizing-the-appearance/con-language-persistence.adoc b/modules/customizing-the-appearance/con-language-persistence.adoc
index 8087ff8fc2..f41733fd18 100644
--- a/modules/customizing-the-appearance/con-language-persistence.adoc
+++ b/modules/customizing-the-appearance/con-language-persistence.adoc
@@ -13,7 +13,7 @@ Default language selection uses the following priority order:
. *Fallback priority*: If neither browser preferences nor configuration provide a match, defaults to `en`.
-Red Hat Developer Hub automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. To opt-out and use browser storage instead, add the following to your `app-config.yaml`:
+Red Hat Developer Hub automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. To opt-out and use browser storage instead, add the following to your `{my-app-config-file}` configuration file:
[source,yaml,subs="+quotes"]
----
userSettings:
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index bda680cf9c..8afe1c6f67 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,13 +2,14 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-In {product-very-short} 1.8, English and French are the supported languages. You can implement transalations for other languages by using an `allTranslations.json` file to override existing translation strings and updating the `i18n` section of your `{my-app-config-file}` configuration file.
+In {product-very-short} 1.8, English and French are the supported languages. You can implement transalations for other languages by using an `allTranslations.json` file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the translation override file.
.Prerequisitea
* You have enabled localization in your {product-very-short} application.
.Procedure
-. Download the translation strings.
+. In the top user menu, go to *Settings* > *General*.
+. Click on the download link in the *Translations* panel to download the default English translation strings.
. Create the JSON file containing all your translations, for example:
+
[id=i18n-enable]
@@ -37,7 +38,7 @@ In {product-very-short} 1.8, English and French are the supported languages. You
}
}
----
-. Login to your cluster and create a config map for your json translations:
+. Login to your cluster and create a config map for your translations override strings:
+
[source,bash]
----
From fe7f1d5fd50988999d959b423c85dcb7526328b2 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:06:12 +0000
Subject: [PATCH 05/54] Update
modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
Co-authored-by: Debsmita Santra
---
.../proc-adding-localization-to-custom-plugins.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
index 945cd1df01..29f5ff871e 100644
--- a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
+++ b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
@@ -176,7 +176,7 @@ const CardComponent = ({ config }) => {
. Export the translation resources
+
[source,json]
-.`src/index.ts` file fragment
+.`src/alpha.ts` file fragment
----
// Export your plugin
export { myPlugin } from "./plugin";
From a0336d1b7a1868dc8762ac744338b50168890e64 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:13:54 +0000
Subject: [PATCH 06/54] Update
modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
Co-authored-by: Debsmita Santra
---
.../proc-adding-localization-to-custom-plugins.adoc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
index 29f5ff871e..057a714b0f 100644
--- a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
+++ b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
@@ -188,12 +188,13 @@ export { myPluginTranslations, myPluginTranslationRef } from "./translations";
. Update your `dynamic-plugins.default.yaml` file, as follows:
+
[source,json]
-.`src/index.ts` file fragment
+.`dynamic-plugins.default.yaml` file fragment
----
backstage-community.plugin-my-plugin:
translationResources:
- importName: myPluginTranslations
ref: myPluginTranslationRef
+ module: Alpha
----
.Verification
From 31ea4395a9f9b9e8a3afcbb59fcbf75d03ef4633 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:15:26 +0000
Subject: [PATCH 07/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Debsmita Santra
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 8afe1c6f67..7768ae452c 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,7 +2,7 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-In {product-very-short} 1.8, English and French are the supported languages. You can implement transalations for other languages by using an `allTranslations.json` file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the translation override file.
+In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using an `allTranslations.json` file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the translation override file.
.Prerequisitea
* You have enabled localization in your {product-very-short} application.
From 4a64905507321f423469f360bd4ac844d701d86f Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 10:26:50 +0000
Subject: [PATCH 08/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../proc-customize-rhdh-language.adoc | 2 --
.../proc-overriding-translations.adoc | 36 ++++++++++---------
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-customize-rhdh-language.adoc b/modules/customizing-the-appearance/proc-customize-rhdh-language.adoc
index c0df299ad7..a64e242f67 100644
--- a/modules/customizing-the-appearance/proc-customize-rhdh-language.adoc
+++ b/modules/customizing-the-appearance/proc-customize-rhdh-language.adoc
@@ -9,8 +9,6 @@ The language settings of {product-very-short} use English by default. You can ch
* English
* French
-The default language is English, which automatically sets the light or dark theme based on your system preferences.
-
[NOTE]
====
English and French are the supported languages in {product-very-short} 1.8. You can add other languages in the the `i18n` section of your `{my-app-config-file}` configuration file.
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 7768ae452c..77fc620f95 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,14 +2,15 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using an `allTranslations.json` file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the translation override file.
+In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using a JSON file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
.Prerequisitea
* You have enabled localization in your {product-very-short} application.
.Procedure
-. In the top user menu, go to *Settings* > *General*.
-. Click on the download link in the *Translations* panel to download the default English translation strings.
+// This feature is not being included in 1.8
+// . In the top user menu, go to *Settings* > *General*.
+// . Click on the download link in the *Translations* panel to download the default English translation strings.
. Create the JSON file containing all your translations, for example:
+
[id=i18n-enable]
@@ -17,25 +18,28 @@ In {product-very-short} 1.8, English and French are the supported languages. You
[source,json]
----
{
- "plugin.npm.translation-ref": {
- "en": {
- "infoCard.title": "NPM Packet JSON {{packageName}}"
- },
- "de": {
- "infoCard.title": "NPM Pakettt JSON {{packageName}}"
+ "plugin.global-floating-action-button": {
+ "fr": {
+ "fab.quay.label": "QUAY French JSON",
+ "fab.quay.tooltip": "QUAY french tooltip JSON",
+ "fab.rbac.label": "RBAC French JSON",
+ "fab.rbac.tooltip": "RBAC french tooltip JSON"
},
- "zh": {
- "infoCard.title": "NPM 包 JSON {{packageName}}"
+ "en": {
+ "fab.quay.label": "QUAY EN JSON",
+ "fab.rbac.label": "RBAC EN JSON",
+ "fab.rbac.tooltip": "RBAC EN tooltip JSON"
}
},
- "catalog-import": {
- "en": {
- "defaultImportPage.headerTitle": "Import an existing Git repository JSON"
+ "plugin.global-header": {
+ "fr": {
+ "applicationLauncher.developerHub": "Developer Hub French JSON"
},
- "de": {
- "defaultImportPage.headerTitle": "Ein vorhandenes Git-Repository importieren JSON"
+ "en": {
+ "applicationLauncher.developerHub": "Developer Hub EN JSON"
}
}
+
}
----
. Login to your cluster and create a config map for your translations override strings:
From fead28bae0d0c4c959c07ee807347ebb725c9259 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 12:13:49 +0000
Subject: [PATCH 09/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../proc-enabling-localization-in-rhdh.adoc | 2 +-
.../proc-overriding-translations.adoc | 42 +++++++++----------
2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
index 5be7cc5254..b37961c882 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
@@ -4,7 +4,7 @@
= Enabling the localization framework in {product-short}
Enabling localization enhances accessibility, improves the user experience for a global audience, and assists organizations in meeting language requirements in specific regions.
-The language settings of {product-very-short} use English by default. In {product-very-short} {product-version}, you can choose to use one of the following supported languages:
+The language settings of {product} ({product-very-short}) use English by default. In {product-very-short} {product-version}, you can choose to use one of the following supported languages:
* English (en)
* French (fr)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 77fc620f95..a55242c320 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,9 +2,9 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using a JSON file to override the existing translation strings, and updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
+In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using a JSON file to override the existing translation strings, and by updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
-.Prerequisitea
+.Prerequisites
* You have enabled localization in your {product-very-short} application.
.Procedure
@@ -46,30 +46,30 @@ In {product-very-short} 1.8, English and French are the supported languages. You
+
[source,bash]
----
-oc create configmap all-translations --from-file=//allTranslations.json
+oc create configmap all-translations \
+ --from-file=//allTranslations.json
----
-. Update your Developer hub helm chart to mount the above config map in the app’s filesystem
+. Update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
-.. In the helm chart -> Root Schema -> Backstage chart schema -> Backstage parameters -> Backstage container additional volume mounts
+.. In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
-.. Select `Add Backstage container additional volume mounts` and add the following
-+
-[source,yaml]
-----
-MountPath: /opt/app-root/src/translation
-Name: all-translations
-----
+.. Select *Add Backstage container additional volume mounts* and add the following values:
-.. Add the translations to the `Backstage container additional volumes` in the helm chart
-+
-[source,yaml]
-----
-name: all-translations
-configMap:
- defaultMode: 420
- name: all-translations
-----
+mountPath::
+`/opt/app-root/src/translation`
+Name::
+`all-translations`
+
+.. Add the translations to the *Backstage container additional volumes* in the {product-short} Helm chart:
+
+name::
+`all-translations`
+configMap::
+defaultMode:::
+ `420`
+name:::
+`all-translations`
. Update the `i18n` section to your custom {product-short} `{my-app-config-file}` configuration file to include the translation override file:
+
From 0ac0c5332a360cc608aaf99b88c58cf3c8aeb38a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 15:09:42 +0000
Subject: [PATCH 10/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../proc-overriding-translations.adoc | 26 ++++++++++++++++---
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index a55242c320..6be3fdbe18 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -50,18 +50,36 @@ oc create configmap all-translations \
--from-file=//allTranslations.json
----
-. Update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
+. Update your deployment configuration based on your installation method:
-.. In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
+.. For an Operator-installed {product-very-short} instance, update your `Backstage` custom resource (CR).
+... In the `spec.application.extraFiles` section, add the translations custom app configuration as shown in the following example:
++
+.Backstage custom resource fragment
+[source,yaml,subs="+quotes"]
+----
+apiVersion: rhdh.redhat.com/v1alpha3
+kind: Backstage
+spec:
+ application:
+ extraFiles:
+ mountPath: /opt/app-root/src/translation
+ configMaps:
+ - name: all-translations
+----
+
+.. For an Helm-installed {product-very-short} instance, update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
+
+... In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
-.. Select *Add Backstage container additional volume mounts* and add the following values:
+... Select *Add Backstage container additional volume mounts* and add the following values:
mountPath::
`/opt/app-root/src/translation`
Name::
`all-translations`
-.. Add the translations to the *Backstage container additional volumes* in the {product-short} Helm chart:
+... Add the translations to the *Backstage container additional volumes* in the {product-short} Helm chart:
name::
`all-translations`
From 7128efcfa839c87262c8f4b5f644b8dae40d39b9 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Tue, 28 Oct 2025 15:28:12 +0000
Subject: [PATCH 11/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 6be3fdbe18..a231ab7f39 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -68,7 +68,7 @@ spec:
- name: all-translations
----
-.. For an Helm-installed {product-very-short} instance, update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
+.. For a Helm-installed {product-very-short} instance, update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
... In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
From 9e9d9b61b69731e5ecd465b172da9f3f75e083a6 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:29:48 +0000
Subject: [PATCH 12/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Karthik Jeeyar
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index a231ab7f39..f2cc48b587 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -63,7 +63,7 @@ kind: Backstage
spec:
application:
extraFiles:
- mountPath: /opt/app-root/src/translation
+ mountPath: /opt/app-root/src/translations
configMaps:
- name: all-translations
----
From 8a80b351a38bdd855413844cfcaeb25b3fa9516f Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:30:16 +0000
Subject: [PATCH 13/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Karthik Jeeyar
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index f2cc48b587..4a75b9048e 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -75,7 +75,7 @@ spec:
... Select *Add Backstage container additional volume mounts* and add the following values:
mountPath::
-`/opt/app-root/src/translation`
+`/opt/app-root/src/translations`
Name::
`all-translations`
From c27782cc5acbb1474df30738beeef302ce47d2ef Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:30:36 +0000
Subject: [PATCH 14/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Karthik Jeeyar
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 4a75b9048e..0ea4b8d38c 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -76,7 +76,7 @@ spec:
mountPath::
`/opt/app-root/src/translations`
-Name::
+name::
`all-translations`
... Add the translations to the *Backstage container additional volumes* in the {product-short} Helm chart:
From a357528dbe82ca791598b095ac63e7657cb8cfbf Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:31:04 +0000
Subject: [PATCH 15/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Karthik Jeeyar
---
.../proc-overriding-translations.adoc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 0ea4b8d38c..7c3c8b1822 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -101,7 +101,6 @@ i18n:
- fr
defaultLocale: en # Optional. Defaults to `en` if not specified.
overrides: # List of JSON translation files applied in order (last file wins). Each file may override/add translations for one or more plugins/locales
- - /.json
- - /.json
+ - /opt/app-root/src/translations/all-translations.json
----
From 851d31352af2c94cf0bbc3a2fb5255b1626c2f16 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:31:24 +0000
Subject: [PATCH 16/54] Update
modules/customizing-the-appearance/con-language-persistence.adoc
Co-authored-by: Priyanka Abel
---
.../customizing-the-appearance/con-language-persistence.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/con-language-persistence.adoc b/modules/customizing-the-appearance/con-language-persistence.adoc
index f41733fd18..df79b56914 100644
--- a/modules/customizing-the-appearance/con-language-persistence.adoc
+++ b/modules/customizing-the-appearance/con-language-persistence.adoc
@@ -13,7 +13,7 @@ Default language selection uses the following priority order:
. *Fallback priority*: If neither browser preferences nor configuration provide a match, defaults to `en`.
-Red Hat Developer Hub automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. To opt-out and use browser storage instead, add the following to your `{my-app-config-file}` configuration file:
+{product} automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. To opt-out and use browser storage instead, add the following to your `{my-app-config-file}` configuration file:
[source,yaml,subs="+quotes"]
----
userSettings:
From 863e698bff7145338e3d698d076df5f8a9abf844 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:31:46 +0000
Subject: [PATCH 17/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 7c3c8b1822..b5410f3a72 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -52,7 +52,7 @@ oc create configmap all-translations \
. Update your deployment configuration based on your installation method:
-.. For an Operator-installed {product-very-short} instance, update your `Backstage` custom resource (CR).
+.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR).
... In the `spec.application.extraFiles` section, add the translations custom app configuration as shown in the following example:
+
.Backstage custom resource fragment
From a854520aa4cf8e1213e2226aadf749c5a89dc557 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:33:28 +0000
Subject: [PATCH 18/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index b5410f3a72..4eb9aa9921 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -11,7 +11,7 @@ In {product-very-short} 1.8, English and French are the supported languages. You
// This feature is not being included in 1.8
// . In the top user menu, go to *Settings* > *General*.
// . Click on the download link in the *Translations* panel to download the default English translation strings.
-. Create the JSON file containing all your translations, for example:
+. Create the JSON file containing all your translation as shown in the following example:
+
[id=i18n-enable]
.`allTranslations.json` fragment with translation string overrides
From 1d2299b0ad8ad5e732c572c49b31f613d76e2a9a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:50:30 +0000
Subject: [PATCH 19/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 4eb9aa9921..d8f1914577 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -68,7 +68,7 @@ spec:
- name: all-translations
----
-.. For a Helm-installed {product-very-short} instance, update your {product-short} `Backstage` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
+.. For a Helm-installed {product-very-short} instance, update your {product-short} `{backstage}` Helm chart to mount in the {product-short} filesystem your files from the `all-translations` config map:
... In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
From f80edecfa69dd197d365704523932a29ed59507e Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:52:04 +0000
Subject: [PATCH 20/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index d8f1914577..623823d7c0 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -42,7 +42,7 @@ In {product-very-short} 1.8, English and French are the supported languages. You
}
----
-. Login to your cluster and create a config map for your translations override strings:
+. Log in to your cluster and create a config map for your translations override strings:
+
[source,bash]
----
From b4acbb659c9c9f2b9243290d86b76e5e3961a508 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:52:35 +0000
Subject: [PATCH 21/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 623823d7c0..47f5a76511 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -72,7 +72,7 @@ spec:
... In the {product-short} Helm chart, go to *Root Schema* → *Backstage chart schema* → *Backstage parameters* → *Backstage container additional volume mounts*.
-... Select *Add Backstage container additional volume mounts* and add the following values:
+... Select *Add {backstage} container additional volume mounts* and add the following values:
mountPath::
`/opt/app-root/src/translations`
From 27f76d48eb23739b6200a1f1d9de6fd05dfd3345 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:52:58 +0000
Subject: [PATCH 22/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 47f5a76511..f94795f00d 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -79,7 +79,7 @@ mountPath::
name::
`all-translations`
-... Add the translations to the *Backstage container additional volumes* in the {product-short} Helm chart:
+... Add the translations to the *{backstage} container additional volumes* in the {product-short} Helm chart:
name::
`all-translations`
From c2d345ed1cac3089af2897bb9b9669c81a3dc39e Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:53:19 +0000
Subject: [PATCH 23/54] Update
modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
Co-authored-by: Priyanka Abel
---
.../ref-best-practices-for-localization.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc b/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
index 7518d18632..a8e1b36646 100644
--- a/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
+++ b/modules/customizing-the-appearance/ref-best-practices-for-localization.adoc
@@ -2,7 +2,7 @@
[id="ref-best-practices-for-localization_{context}"]
= Best practices for implementing localization support for custom plugins in {product-very-short}
-When you add localization support to your {product-very-short} plugins the following best practices help ensure that you establish a robust, type-safe, and future-proof localization workflow, separating the immutable source text from the organized key structure and ensuring reliable deployment across all targeted languages:
+When you add localization support to your {product-very-short} plugins, the following best practices help ensure that you establish a robust, type-safe, and future-proof localization workflow, separating the immutable source text from the organized key structure, and ensuring reliable deployment across all targeted languages:
Do not modify original English strings:: This preserves the source of truth for all translators, preventing unexpected changes that would invalidate existing translations and ensuring consistency across all versions.
From 744683bbc996c59dd5d617b3701d8357fef4c0a2 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:53:38 +0000
Subject: [PATCH 24/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Priyanka Abel
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index f94795f00d..a67d9cde90 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -89,7 +89,7 @@ defaultMode:::
name:::
`all-translations`
-. Update the `i18n` section to your custom {product-short} `{my-app-config-file}` configuration file to include the translation override file:
+. Update the `i18n` section to your custom {product-short} `{my-app-config-file}` configuration file to include the following translation override file:
+
[id=i18n-override]
.`{my-app-config-file}` fragment with localization `i18n` fields
From a32ba21615983564946dffe6500a30e54ca552e6 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 30 Oct 2025 09:54:11 +0000
Subject: [PATCH 25/54] Update
modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
Co-authored-by: Priyanka Abel
---
.../proc-adding-localization-to-custom-plugins.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
index 057a714b0f..cfd33bc50e 100644
--- a/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
+++ b/modules/customizing-the-appearance/proc-adding-localization-to-custom-plugins.adoc
@@ -105,7 +105,7 @@ import { myPluginTranslationRef } from "../translations";
export const useTranslation = () => useTranslationRef(myPluginTranslationRef);
----
-. Update your plugin components to replace hardcoded strings with translation calls. For example:
+. Update your plugin components to replace hard-coded strings with translation calls as shown in the following example:
+
.Before (hardcoded):
[source,json]
From 0285a12a9dc0599d3198516a20305bf4012500da Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Fri, 31 Oct 2025 10:01:31 +0000
Subject: [PATCH 26/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-localization-in-rhdh.adoc | 4 +
...-enabling-localization-in-quickstarts.adoc | 79 +++++++++++++++++++
2 files changed, 83 insertions(+)
create mode 100644 modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 8466ea8a45..3b9fa3a34c 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -11,6 +11,10 @@ include::modules/customizing-the-appearance/proc-select-rhdh-language.adoc[level
include::modules/customizing-the-appearance/con-language-persistence.adoc[leveloffset=+2]
+include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
+
+//include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
+
== Localization support for custom plugins
include::modules/customizing-the-appearance/ref-best-practices-for-localization.adoc[leveloffset=+2]
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
new file mode 100644
index 0000000000..1f08ab510f
--- /dev/null
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
@@ -0,0 +1,79 @@
+:_mod-docs-content-type: CONCEPT
+
+[id="proc-enabling-localization-in-quickstarts_{context}"]
+= Enabling Quickstart localization in {product-very-short}
+
+You can enable translation key support for Quickstart titles, descriptions, and CTAs, so that users can onboard in their preferred language. In {product-short}, all existing and newly created Quickstart steps support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
+
+[NOTE]
+If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the Quickstart configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
+
+.Prerequisites
+* You have enabled localization in your {product-very-short} application.
+
+.Procedure
+
+. For *all* Quickstart steps (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the `quickstart` section of your custom `{my-app-config-file}` file, add the `titleKey`, `descriptionKey`, and `textKey` values, as follows:
++
+.`{my-app-config-file}` fragment
+[source,yaml,subs="+quotes"]
+----
+app:
+ quickstart:
+ # Existing Quickstart steps should also be updated with keys
+ - title: 'Setup Authentication' <1>
+ titleKey: steps.setupAuth.title <2>
+ description: 'Learn the basics of navigating the Developer Hub interface' <3>
+ descriptionKey: steps.setupAuth.description <4>
+ icon: 'home'
+ cta:
+ text: 'Get Started' <5>
+ textKey: steps.setupAuth.ctaTitle <6>
+ link: '/catalog'
+# ...
+----
+<1> (Mandatory) Fallback for the title.
+<2> Key for the translated title.
+<3> (Mandatory) Fallback for the description.
+<4> Key for the translated description.
+<5> (Mandatory) Fallback for the CTA text.
+<6> Key for the translated CTA text.
+
+. In your `dynamic-plugins.yaml` file, add the `translationResources` section to your `red-hat-developer-hub-backstage-plugin-quickstart` configuration, as follows:
++
+.`{my-app-config-file}` fragment
+[source,yaml,subs="+quotes"]
+----
+plugins:
+ - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart
+ disabled: false
+ pluginConfig:
+ dynamicPlugins:
+ frontend:
+ red-hat-developer-hub.backstage-plugin-quickstart:
+ # translationResources definition is required for translations to work
+ translationResources:
+ - importName: quickstartTranslations <1>
+ ref: quickstartTranslationRef <2>
+ # ... other configurations like mountPoints ...
+----
+<1> Name used to reference the import.
+<2> Reference to the resource definition.
+. In your translation file, map the keys from the first step to the localized strings for each supported language.
++
+.`allTranslations.json` fragment
+[source,yaml,subs="+quotes"]
+----
+"plugin.quickstart": {
+ "en": {
+ "steps.setupAuth.title": "Manage plugins EN",
+ "steps.setupAuth.description": "EN Browse and install extensions to add features, connect with external tools, and customize your experience.",
+ "steps.setupAuth.ctaTitle": "Start"
+ },
+ "fr": {
+ "steps.setupAuth.title": "Gérer les plugins FR",
+ "steps.setupAuth.description": "FR Parcourez et installez des extensions pour ajouter des fonctionnalités, vous connecter à des outils externes et personnaliser votre expérience.",
+ "steps.setupAuth.ctaTitle": "Commencer"
+ }
+}
+----
\ No newline at end of file
From 7bc89c6bb2736452301e7e0b6d043c94262c23ad Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Fri, 31 Oct 2025 15:25:58 +0000
Subject: [PATCH 27/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
...nabling-localization-in-sidebar-items.adoc | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
new file mode 100644
index 0000000000..30f26891e3
--- /dev/null
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -0,0 +1,64 @@
+:_mod-docs-content-type: CONCEPT
+
+[id="proc-enabling-localization-in-sidebar-items_{context}"]
+= Enabling Sidebar items localization in {product-very-short}
+
+You can enable translation key support for Quickstart titles, descriptions, and CTAs, so that users can onboard in their preferred language. In {product-short}, all existing and newly created Quickstart steps support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
+
+[NOTE]
+If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the Quickstart configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
+
+.Prerequisites
+* You have enabled localization in your {product-very-short} application.
+
+.Procedure
+
+. For *all* Quickstart steps (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the `quickstart` section of your `{my-app-config-file}` file, add the `titleKey`, `descriptionKey`, and `textKey`, as follows:
++
+.`{my-app-config-file}` fragment
+[source,yaml,subs="+quotes"]
+----
+quickstart:
+ # Existing Quickstart steps should also be updated with keys
+ - title: 'Setup Authentication' # MANDATORY: Serves as the fallback text
+ titleKey: steps.setupAuth.title # Key for the translated title
+ description: 'Learn the basics of navigating the Developer Hub interface' # MANDATORY: Fallback description
+ descriptionKey: steps.setupAuth.description # Key for the translated description
+ icon: 'home'
+ cta:
+ text: 'Get Started' # MANDATORY: Fallback CTA text
+ textKey: steps.setupAuth.ctaTitle # Key for the translated CTA text
+ link: '/catalog'
+----
+. In your {product-very-short} configuration file, to import your translation file, add the `translationResources` section to `dynamicPlugins:frontend:red-hat-developer-hub.backstage-plugin-quickstart` section:
++
+.`{my-app-config-file}` fragment
+[source,yaml,subs="+quotes"]
+----
+dynamicPlugins:
+ frontend:
+ red-hat-developer-hub.backstage-plugin-quickstart:
+ # translationResources definition is required for translations to work
+ translationResources:
+ - importName: quickstartTranslations # Name used to reference the import
+ ref: quickstartTranslationRef # Reference to the resource definition
+ # ... other configurations like mountPoints ...
+----
+. In your translation file, map the keys from the first step to the localized strings for each supported language.
++
+.`allTranslations.json` fragment
+[source,yaml,subs="+quotes"]
+----
+"plugin.quickstart": {
+ "en": {
+ "steps.setupAuth.title": "Manage plugins EN",
+ "steps.setupAuth.description": "EN Browse and install extensions to add features, connect with external tools, and customize your experience.",
+ "steps.setupAuth.ctaTitle": "Start"
+ },
+ "fr": {
+ "steps.setupAuth.title": "Gérer les plugins FR",
+ "steps.setupAuth.description": "FR Parcourez et installez des extensions pour ajouter des fonctionnalités, vous connecter à des outils externes et personnaliser votre expérience.",
+ "steps.setupAuth.ctaTitle": "Commencer"
+ }
+}
+----
\ No newline at end of file
From c7461be8cc6384efeca022b9e8fa890655d03042 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Fri, 31 Oct 2025 19:41:32 +0000
Subject: [PATCH 28/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-localization-in-rhdh.adoc | 2 +-
...nabling-localization-in-sidebar-items.adoc | 65 +++++++------------
2 files changed, 25 insertions(+), 42 deletions(-)
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 3b9fa3a34c..07dd74cd92 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -13,7 +13,7 @@ include::modules/customizing-the-appearance/con-language-persistence.adoc[levelo
include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
-//include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
+include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
== Localization support for custom plugins
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index 30f26891e3..dda5b89744 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -1,64 +1,47 @@
:_mod-docs-content-type: CONCEPT
-[id="proc-enabling-localization-in-sidebar-items_{context}"]
-= Enabling Sidebar items localization in {product-very-short}
+[id="proc-enabling-localization-in-sidebar-menu-items_{context}"]
+= Enabling sidebar menu items localization in {product-very-short}
-You can enable translation key support for Quickstart titles, descriptions, and CTAs, so that users can onboard in their preferred language. In {product-short}, all existing and newly created Quickstart steps support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
+You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
[NOTE]
-If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the Quickstart configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
+If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the sidebar menu items configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
.Prerequisites
* You have enabled localization in your {product-very-short} application.
.Procedure
-. For *all* Quickstart steps (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the `quickstart` section of your `{my-app-config-file}` file, add the `titleKey`, `descriptionKey`, and `textKey`, as follows:
+. For *all* sidebar menu items (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the `dynamicPlugins.frontend.default.main-menu-items.menuItems.default.home` section of your `{my-app-config-file}` file, add the `titleKey`, as follows:
+
-.`{my-app-config-file}` fragment
-[source,yaml,subs="+quotes"]
-----
-quickstart:
- # Existing Quickstart steps should also be updated with keys
- - title: 'Setup Authentication' # MANDATORY: Serves as the fallback text
- titleKey: steps.setupAuth.title # Key for the translated title
- description: 'Learn the basics of navigating the Developer Hub interface' # MANDATORY: Fallback description
- descriptionKey: steps.setupAuth.description # Key for the translated description
- icon: 'home'
- cta:
- text: 'Get Started' # MANDATORY: Fallback CTA text
- textKey: steps.setupAuth.ctaTitle # Key for the translated CTA text
- link: '/catalog'
-----
-. In your {product-very-short} configuration file, to import your translation file, add the `translationResources` section to `dynamicPlugins:frontend:red-hat-developer-hub.backstage-plugin-quickstart` section:
-+
-.`{my-app-config-file}` fragment
+.Example `{my-app-config-file}` fragment
[source,yaml,subs="+quotes"]
----
dynamicPlugins:
frontend:
- red-hat-developer-hub.backstage-plugin-quickstart:
- # translationResources definition is required for translations to work
- translationResources:
- - importName: quickstartTranslations # Name used to reference the import
- ref: quickstartTranslationRef # Reference to the resource definition
- # ... other configurations like mountPoints ...
+ default.main-menu-items:
+ menuItems:
+ default.home:
+ title: Home
+ titleKey: menuItem.home
+ icon: home
+ priority: 100
+ enabled: true
----
-. In your translation file, map the keys from the first step to the localized strings for each supported language.
+. In your translation file, map the `titleKey` from the first step to the localized strings for each supported language.
+
-.`allTranslations.json` fragment
+.Example `allTranslations.json` fragment
[source,yaml,subs="+quotes"]
----
-"plugin.quickstart": {
- "en": {
- "steps.setupAuth.title": "Manage plugins EN",
- "steps.setupAuth.description": "EN Browse and install extensions to add features, connect with external tools, and customize your experience.",
- "steps.setupAuth.ctaTitle": "Start"
- },
- "fr": {
- "steps.setupAuth.title": "Gérer les plugins FR",
- "steps.setupAuth.description": "FR Parcourez et installez des extensions pour ajouter des fonctionnalités, vous connecter à des outils externes et personnaliser votre expérience.",
- "steps.setupAuth.ctaTitle": "Commencer"
+{
+ "rhdh": {
+ "en": {
+ "menuItem.home": "Home"
+ },
+ "fr": {
+ "menuItem.home": "Accueil"
+ }
}
}
----
\ No newline at end of file
From 064d75b41c686259febc015a782146a43c986ae2 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sun, 2 Nov 2025 11:01:32 +0000
Subject: [PATCH 29/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
...-configuring-a-floating-action-button.adoc | 4 ++
.../assembly-configuring-the-quickstarts.adoc | 2 +
.../assembly-customizing-the-appearance.adoc | 2 +
assemblies/assembly-localization-in-rhdh.adoc | 6 ++-
...upport-for-the-floating-action-button.adoc | 51 +++++++++++++++++++
...ing-action-button-as-a-dynamic-plugin.adoc | 37 ++++++++++++++
...ref-floating-action-button-parameters.adoc | 12 +++++
...nabling-localization-in-sidebar-items.adoc | 4 +-
8 files changed, 114 insertions(+), 4 deletions(-)
create mode 100644 modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
diff --git a/assemblies/assembly-configuring-a-floating-action-button.adoc b/assemblies/assembly-configuring-a-floating-action-button.adoc
index 319cb61067..d2d36469d2 100644
--- a/assemblies/assembly-configuring-a-floating-action-button.adoc
+++ b/assemblies/assembly-configuring-a-floating-action-button.adoc
@@ -8,4 +8,8 @@ You can use the floating action button plugin to configure any action as a float
include::modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc[leveloffset=+1]
+// Localization
+include::modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc[leveloffset=+1]
+// END Localization
+
include::modules/configuring-a-floating-action-button/ref-floating-action-button-parameters.adoc[leveloffset=+1]
diff --git a/assemblies/assembly-configuring-the-quickstarts.adoc b/assemblies/assembly-configuring-the-quickstarts.adoc
index 8d5801327a..59f87c0a84 100644
--- a/assemblies/assembly-configuring-the-quickstarts.adoc
+++ b/assemblies/assembly-configuring-the-quickstarts.adoc
@@ -11,3 +11,5 @@ include::modules/configuring-the-quickstarts/proc-customize-rhdh-quickstart.adoc
include::modules/configuring-the-quickstarts/proc-disabling-rhdh-quickstart.adoc[leveloffset=+2]
include::modules/configuring-the-quickstarts/proc-starting-and-completing-modules-in-quickstarts.adoc[leveloffset=+1]
+
+include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
diff --git a/assemblies/assembly-customizing-the-appearance.adoc b/assemblies/assembly-customizing-the-appearance.adoc
index 2c69959e63..c91ff6b7c9 100644
--- a/assemblies/assembly-customizing-the-appearance.adoc
+++ b/assemblies/assembly-customizing-the-appearance.adoc
@@ -36,6 +36,8 @@ include::modules/customizing-the-appearance/proc-configuring-dynamic-plugin-menu
include::modules/customizing-the-appearance/proc-modifying-or-adding-rhdh-custom-menuitem.adoc[leveloffset=+2]
+include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+2]
+
include::modules/customizing-the-appearance/proc-customizing-entity-tab-titles.adoc[leveloffset=+1]
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 07dd74cd92..150261b037 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -11,9 +11,11 @@ include::modules/customizing-the-appearance/proc-select-rhdh-language.adoc[level
include::modules/customizing-the-appearance/con-language-persistence.adoc[leveloffset=+2]
-include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
+// include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
-include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
+// include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
+
+//include::modules/customizing-the-appearance/proc-enabling-localization-in-floating-action-button.adoc[leveloffset=+1]
== Localization support for custom plugins
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
new file mode 100644
index 0000000000..fc5b10c824
--- /dev/null
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -0,0 +1,51 @@
+[id="proc-enabling-localization-in-floating-action-button_{context}"]
+= Enabling floating action button localization in {product-very-short}
+
+You can enable translation key support for floating action buttons, so that users can onboard in their preferred language. In {product-short}, all existing and newly created floating action buttons support localization using dedicated translation keys.
+
+The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+
+== Built-in translation keys
+The plugin provides built-in translation keys organized under the `fab` namespace:
+
+* `fab.create.label` - "Create"
+* `fab.create.tooltip` - "Create entity"
+* `fab.docs.label` - "Docs"
+* `fab.docs.tooltip` - "Documentation"
+* `fab.apis.label` - "APIs"
+* `fab.apis.tooltip` - "API Documentation"
+* `fab.github.label` - "GitHub"
+* `fab.github.tooltip` - "GitHub Repository"
+* `fab.bulkImport.label` - "Bulk Import"
+* `fab.bulkImport.tooltip` - "Register multiple repositories in bulk"
+* `fab.quay.label` - "Quay"
+* `fab.quay.tooltip` - "Quay Container Registry"
+
+== Supported languages
+The plugin includes translations for:
+
+* English (default)
+// * German (de)
+* French (fr)
+// * Spanish (es)
+
+== Ensuring backward compatibility when providing translation support
+To ensure backward compatibility while providing translation support when available, the following order is used to resolve string translations:
+
+. If the `labelKey` is provided, the plugin will attempt to resolve the translation key
+. If the translation key is found, it will be used as the label
+. If the translation key is not found, the plugin will fall back to the label property
+
+[NOTE]
+The same logic applies to `toolTipKey` and `toolTip`.
+
+== Internal translation implementation
+The plugin uses a centralized translation system where:
+
+* The `useTranslation()` hook is called in components that render floating action buttons to ensure proper translation context initialization
+* The translation function (`t`) is passed down to child components that need to resolve translation keys
+* This internal architecture prevents infinite re-render loops and ensures stable component rendering
+* All components that use `CustomFab` must provide the translation function as a prop
+
+[NOTE]
+When extending or modifying the plugin components, ensure that the `useTranslation()` hook is called in parent components and the `t` prop is passed to `CustomFab` instances to maintain proper translation functionality and prevent rendering issues.
\ No newline at end of file
diff --git a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
index 4193f14924..409d51e84d 100644
--- a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
+++ b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
@@ -203,3 +203,40 @@ To configure a floating action button as a dynamic plugin, complete any of the f
text: Bulk import
----
`frontend:mountPoints:importName`:: Enter the import name with an associated component to the mount point.
+
+= Translation support
+The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+
+.Example using translation keys in dynamic configuration
+[source,yaml]
+----
+- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
+ disabled: false
+ pluginConfig:
+ dynamicPlugins:
+ frontend:
+ red-hat-developer-hub.backstage-plugin-global-floating-action-button:
+ mountPoints:
+ - mountPoint: application/listener
+ importName: DynamicGlobalFloatingActionButton
+ - mountPoint: global.floatingactionbutton/config
+ importName: NullComponent
+ config:
+ icon: github
+ label: 'GitHub' # Fallback text
+ labelKey: 'fab.github.label' # Translation key
+ toolTip: 'GitHub Repository' # Fallback text
+ toolTipKey: 'fab.github.tooltip' # Translation key
+ to: https://github.com/redhat-developer/rhdh-plugins
+ - mountPoint: global.floatingactionbutton/config
+ importName: NullComponent
+ config:
+ color: 'success'
+ icon: search
+ label: 'Create' # Fallback text
+ labelKey: 'fab.create.label' # Translation key
+ toolTip: 'Create entity' # Fallback text
+ toolTipKey: 'fab.create.tooltip' # Translation key
+ to: '/create'
+ showLabel: true
+----
\ No newline at end of file
diff --git a/modules/configuring-a-floating-action-button/ref-floating-action-button-parameters.adoc b/modules/configuring-a-floating-action-button/ref-floating-action-button-parameters.adoc
index 1f2c3d54e4..d6be21b37c 100644
--- a/modules/configuring-a-floating-action-button/ref-floating-action-button-parameters.adoc
+++ b/modules/configuring-a-floating-action-button/ref-floating-action-button-parameters.adoc
@@ -21,6 +21,12 @@ Use the parameters as shown in the following table to configure your floating ac
| Not applicable
| Yes
+| `labelKey`
+| Translation key for the label. If provided, will be used instead of label when translations are available.
+| `String`
+| Not applicable
+| No
+
| `icon`
| Icon of the floating action button. Recommended to use filled icons from the link:https://fonts.google.com/icons[Material Design library]. You can also use an svg icon. For example: ``
| `String`, `React.ReactElement`, `SVG image icon`, `HTML image icon`
@@ -63,6 +69,12 @@ Use the parameters as shown in the following table to configure your floating ac
| Not applicable
| No
+| `toolTipKey`
+| Translation key for the tooltip. If provided, will be used instead of toolTip when translations are available.
+| `String`
+| Not applicable
+| No
+
| `priority`
| Order of the floating action buttons displayed in the submenu. A larger value means higher priority.
| `number`
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index dda5b89744..a929bab8d7 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -3,10 +3,10 @@
[id="proc-enabling-localization-in-sidebar-menu-items_{context}"]
= Enabling sidebar menu items localization in {product-very-short}
-You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
+You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
[NOTE]
-If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the sidebar menu items configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
+If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the sidebar menu items configuration (`title`). If no translation key is defined at all, the original text is displayed.
.Prerequisites
* You have enabled localization in your {product-very-short} application.
From 63b80696b49fe39782c2a2d715e0e7c653219dff Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sun, 2 Nov 2025 11:33:57 +0000
Subject: [PATCH 30/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-customizing-the-appearance.adoc | 4 ++--
.../proc-enabling-localization-in-sidebar-items.adoc | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/assemblies/assembly-customizing-the-appearance.adoc b/assemblies/assembly-customizing-the-appearance.adoc
index c91ff6b7c9..04358576b8 100644
--- a/assemblies/assembly-customizing-the-appearance.adoc
+++ b/assemblies/assembly-customizing-the-appearance.adoc
@@ -32,12 +32,12 @@ include::modules/customizing-the-appearance/con-about-rhdh-sidebar-menuitems.ado
include::modules/customizing-the-appearance/proc-customize-rhdh-sidebar-menuitems.adoc[leveloffset=+2]
+include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+2]
+
include::modules/customizing-the-appearance/proc-configuring-dynamic-plugin-menuitem.adoc[leveloffset=+2]
include::modules/customizing-the-appearance/proc-modifying-or-adding-rhdh-custom-menuitem.adoc[leveloffset=+2]
-include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+2]
-
include::modules/customizing-the-appearance/proc-customizing-entity-tab-titles.adoc[leveloffset=+1]
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index a929bab8d7..40b868d2a5 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -1,7 +1,7 @@
:_mod-docs-content-type: CONCEPT
-[id="proc-enabling-localization-in-sidebar-menu-items_{context}"]
-= Enabling sidebar menu items localization in {product-very-short}
+[id="proc-translating-the-sidebar-menu-items_{context}"]
+= Translating the sidebar menu items in {product-very-short}
You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
From b8fa956acce293527c4ebfa5c2ec68aeefd20d65 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sun, 2 Nov 2025 11:47:31 +0000
Subject: [PATCH 31/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../proc-enabling-localization-in-sidebar-items.adoc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index 40b868d2a5..a929bab8d7 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -1,7 +1,7 @@
:_mod-docs-content-type: CONCEPT
-[id="proc-translating-the-sidebar-menu-items_{context}"]
-= Translating the sidebar menu items in {product-very-short}
+[id="proc-enabling-localization-in-sidebar-menu-items_{context}"]
+= Enabling sidebar menu items localization in {product-very-short}
You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
From a6cde1fc746c5ef6320dae19a80766aaa0689d73 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:05:28 +0000
Subject: [PATCH 32/54] Update
modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../proc-enabling-localization-in-sidebar-items.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index a929bab8d7..adb1d510b3 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -35,7 +35,7 @@ dynamicPlugins:
[source,yaml,subs="+quotes"]
----
{
- "rhdh": {
+ "{product-very-short}": {
"en": {
"menuItem.home": "Home"
},
From cac8ecdb9e82c9cfc968ee6b58374ea40ea3bb32 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:08:51 +0000
Subject: [PATCH 33/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...con-localization-support-for-the-floating-action-button.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index fc5b10c824..b2adb84fdc 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -3,7 +3,7 @@
You can enable translation key support for floating action buttons, so that users can onboard in their preferred language. In {product-short}, all existing and newly created floating action buttons support localization using dedicated translation keys.
-The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
== Built-in translation keys
The plugin provides built-in translation keys organized under the `fab` namespace:
From b4339278642ce4a84ee29fa28493ecd5c08a63de Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:09:26 +0000
Subject: [PATCH 34/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...on-localization-support-for-the-floating-action-button.adoc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index b2adb84fdc..0953c6e9a2 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -5,8 +5,7 @@ You can enable translation key support for floating action buttons, so that user
The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
-== Built-in translation keys
-The plugin provides built-in translation keys organized under the `fab` namespace:
+The plugin provides the following built-in translation keys organized under the `fab` namespace:
* `fab.create.label` - "Create"
* `fab.create.tooltip` - "Create entity"
From 5467d90b38ddc1965d2a852caa78c4c707c9c2c1 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:10:19 +0000
Subject: [PATCH 35/54] Update
modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../proc-enabling-localization-in-quickstarts.adoc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
index 1f08ab510f..06618f3893 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
@@ -6,7 +6,9 @@
You can enable translation key support for Quickstart titles, descriptions, and CTAs, so that users can onboard in their preferred language. In {product-short}, all existing and newly created Quickstart steps support localization using dedicated translation keys (`titleKey`, `descriptionKey`, `cta.textKey`).
[NOTE]
+====
If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the Quickstart configuration (`title`, `description`, `text`). If no translation key is defined at all, the original text is displayed.
+====
.Prerequisites
* You have enabled localization in your {product-very-short} application.
From fb5e8a4f781d592460bc4f77656ff141fb155711 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:10:52 +0000
Subject: [PATCH 36/54] Update
modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...-enabling-localization-in-quickstarts.adoc | 27 ++++++++++---------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
index 06618f3893..76de3b8dd8 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
@@ -23,23 +23,26 @@ If a translation key is present but the corresponding localized string is missin
app:
quickstart:
# Existing Quickstart steps should also be updated with keys
- - title: 'Setup Authentication' <1>
- titleKey: steps.setupAuth.title <2>
- description: 'Learn the basics of navigating the Developer Hub interface' <3>
- descriptionKey: steps.setupAuth.description <4>
+ - title: 'Setup Authentication'
+ titleKey: steps.setupAuth.title
+ description: 'Learn the basics of navigating the Developer Hub interface'
+ descriptionKey: steps.setupAuth.description
icon: 'home'
cta:
- text: 'Get Started' <5>
- textKey: steps.setupAuth.ctaTitle <6>
+ text: 'Get Started'
+ textKey: steps.setupAuth.ctaTitle
link: '/catalog'
# ...
----
-<1> (Mandatory) Fallback for the title.
-<2> Key for the translated title.
-<3> (Mandatory) Fallback for the description.
-<4> Key for the translated description.
-<5> (Mandatory) Fallback for the CTA text.
-<6> Key for the translated CTA text.
++
+where:
+
+`title`:: (Mandatory) Fallback for the title.
+`titleKey`:: Key for the translated title.
+`description`:: (Mandatory) Fallback for the description.
+`descriptionKey`:: Key for the translated description.
+`text`:: (Mandatory) Fallback for the CTA text.
+`textKey`:: Key for the translated CTA text.
. In your `dynamic-plugins.yaml` file, add the `translationResources` section to your `red-hat-developer-hub-backstage-plugin-quickstart` configuration, as follows:
+
From 8d43fec67592e2054acb115b24aefd6d15cd3aa2 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:11:24 +0000
Subject: [PATCH 37/54] Update
modules/customizing-the-appearance/proc-overriding-translations.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../proc-overriding-translations.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index a67d9cde90..f055905a4d 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -55,7 +55,7 @@ oc create configmap all-translations \
.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR).
... In the `spec.application.extraFiles` section, add the translations custom app configuration as shown in the following example:
+
-.Backstage custom resource fragment
+.{product-custom-resource-type} custom resource fragment
[source,yaml,subs="+quotes"]
----
apiVersion: rhdh.redhat.com/v1alpha3
From fab49904c4f64a493661c51c222134b977810f10 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:11:38 +0000
Subject: [PATCH 38/54] Update
modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../proc-enabling-localization-in-sidebar-items.adoc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index adb1d510b3..0560d1ffbc 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -6,7 +6,9 @@
You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
[NOTE]
+====
If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the sidebar menu items configuration (`title`). If no translation key is defined at all, the original text is displayed.
+====
.Prerequisites
* You have enabled localization in your {product-very-short} application.
From 0ed67ed2d912434d5dcfc6691863ff53136a6f5a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:12:41 +0000
Subject: [PATCH 39/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...on-localization-support-for-the-floating-action-button.adoc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index 0953c6e9a2..162e3c0282 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -20,8 +20,7 @@ The plugin provides the following built-in translation keys organized under the
* `fab.quay.label` - "Quay"
* `fab.quay.tooltip` - "Quay Container Registry"
-== Supported languages
-The plugin includes translations for:
+The plugin includes translations for the following supported languages:
* English (default)
// * German (de)
From 6d9b8571b719c6c2e1bddfa79ff842234de7b21b Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:13:16 +0000
Subject: [PATCH 40/54] Update
modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../proc-enabling-localization-in-quickstarts.adoc | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
index 76de3b8dd8..52033fbb39 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc
@@ -58,12 +58,17 @@ plugins:
red-hat-developer-hub.backstage-plugin-quickstart:
# translationResources definition is required for translations to work
translationResources:
- - importName: quickstartTranslations <1>
- ref: quickstartTranslationRef <2>
+ - importName: quickstartTranslations
+ ref: quickstartTranslationRef
# ... other configurations like mountPoints ...
----
-<1> Name used to reference the import.
-<2> Reference to the resource definition.
++
+where:
+
+importName::
+Enter the name used to reference the import.
+ref::
+Reference to the resource definition.
. In your translation file, map the keys from the first step to the localized strings for each supported language.
+
.`allTranslations.json` fragment
From 7e76a5f3e3f73ab7d25a3e4b1f9078e4ba5c4aaf Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:16:54 +0000
Subject: [PATCH 41/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...con-localization-support-for-the-floating-action-button.adoc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index 162e3c0282..6468082b49 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -35,7 +35,9 @@ To ensure backward compatibility while providing translation support when availa
. If the translation key is not found, the plugin will fall back to the label property
[NOTE]
+====
The same logic applies to `toolTipKey` and `toolTip`.
+====
== Internal translation implementation
The plugin uses a centralized translation system where:
From 7e262498feb03f12a06f32bf9e64ccf9ffd115e3 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:19:57 +0000
Subject: [PATCH 42/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../con-localization-support-for-the-floating-action-button.adoc | 1 -
1 file changed, 1 deletion(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index 6468082b49..3bb2fe40e0 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -27,7 +27,6 @@ The plugin includes translations for the following supported languages:
* French (fr)
// * Spanish (es)
-== Ensuring backward compatibility when providing translation support
To ensure backward compatibility while providing translation support when available, the following order is used to resolve string translations:
. If the `labelKey` is provided, the plugin will attempt to resolve the translation key
From 4afcc344b7392fed4ba4c4707aa29924a67b670a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:20:37 +0000
Subject: [PATCH 43/54] Update
modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...n-localization-support-for-the-floating-action-button.adoc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index 3bb2fe40e0..59721cb286 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -47,4 +47,6 @@ The plugin uses a centralized translation system where:
* All components that use `CustomFab` must provide the translation function as a prop
[NOTE]
-When extending or modifying the plugin components, ensure that the `useTranslation()` hook is called in parent components and the `t` prop is passed to `CustomFab` instances to maintain proper translation functionality and prevent rendering issues.
\ No newline at end of file
+====
+When extending or modifying the plugin components, ensure that the `useTranslation()` hook is called in parent components and the `t` prop is passed to `CustomFab` instances to maintain proper translation functionality and prevent rendering issues.
+====
\ No newline at end of file
From 5550874a6d182c1b01c6408323eed33fb4210c11 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:24:41 +0000
Subject: [PATCH 44/54] Update
modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...-configuring-floating-action-button-as-a-dynamic-plugin.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
index 409d51e84d..839085be18 100644
--- a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
+++ b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
@@ -205,7 +205,7 @@ To configure a floating action button as a dynamic plugin, complete any of the f
`frontend:mountPoints:importName`:: Enter the import name with an associated component to the mount point.
= Translation support
-The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
.Example using translation keys in dynamic configuration
[source,yaml]
From 959a98839b6053e800e4c90d0ecae153d346edaf Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:25:20 +0000
Subject: [PATCH 45/54] Update
modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
...-configuring-floating-action-button-as-a-dynamic-plugin.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
index 839085be18..d3163cee3a 100644
--- a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
+++ b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
@@ -207,7 +207,7 @@ To configure a floating action button as a dynamic plugin, complete any of the f
= Translation support
The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
-.Example using translation keys in dynamic configuration
+Example for using translation keys in dynamic configuration:
[source,yaml]
----
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
From 629fd9ffd22def8470ab0ff0011641a87187e861 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 16:25:52 +0000
Subject: [PATCH 46/54] Update
modules/customizing-the-appearance/con-language-persistence.adoc
Co-authored-by: Judith Magak <124673476+jmagak@users.noreply.github.com>
---
.../con-language-persistence.adoc | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/modules/customizing-the-appearance/con-language-persistence.adoc b/modules/customizing-the-appearance/con-language-persistence.adoc
index df79b56914..cd22f24fe5 100644
--- a/modules/customizing-the-appearance/con-language-persistence.adoc
+++ b/modules/customizing-the-appearance/con-language-persistence.adoc
@@ -17,7 +17,11 @@ Default language selection uses the following priority order:
[source,yaml,subs="+quotes"]
----
userSettings:
- persistence: browser # <1>
+ persistence: browser
----
-<1> To opt-out and use browser local storage, set this value to `browser`. Optionally, set this value to `database` to persist across browsers and devices. This the default setting and does not require this configuration to be set.
++
+where:
+
+userSettings:persistence::
+Enter `browser` to opt-out and use browser local storage. Optionally, set this value to `database` to persist across browsers and devices. This the default setting and does not require this configuration to be set.
From eee8f7fdfdac2187688da5a4aed585d82cde5b3d Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:19:57 +0000
Subject: [PATCH 47/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
...ization-support-for-the-floating-action-button.adoc | 10 +++++++++-
...ing-floating-action-button-as-a-dynamic-plugin.adoc | 5 ++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
index 59721cb286..6794473a93 100644
--- a/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
+++ b/modules/configuring-a-floating-action-button/con-localization-support-for-the-floating-action-button.adoc
@@ -3,7 +3,7 @@
You can enable translation key support for floating action buttons, so that users can onboard in their preferred language. In {product-short}, all existing and newly created floating action buttons support localization using dedicated translation keys.
-The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
The plugin provides the following built-in translation keys organized under the `fab` namespace:
@@ -27,6 +27,14 @@ The plugin includes translations for the following supported languages:
* French (fr)
// * Spanish (es)
+// [NOTE]
+// ====
+// To add localization support for a new floating action button item, you can add any arbitrary key name for the `labelKey` and `toolTipKey` properties and provide corresponding translations for those keys.
+
+// If you add a new floating action button item, you can add localization support by adding an arbitary label key and tool tip key
+
+// ====
+
To ensure backward compatibility while providing translation support when available, the following order is used to resolve string translations:
. If the `labelKey` is provided, the plugin will attempt to resolve the translation key
diff --git a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
index d3163cee3a..a523dc2c5e 100644
--- a/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
+++ b/modules/configuring-a-floating-action-button/proc-configuring-floating-action-button-as-a-dynamic-plugin.adoc
@@ -205,7 +205,7 @@ To configure a floating action button as a dynamic plugin, complete any of the f
`frontend:mountPoints:importName`:: Enter the import name with an associated component to the mount point.
= Translation support
-The *Global Floating Action* button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
+The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use `labelKey` and `toolTipKey` properties to provide translation keys instead of static text.
Example for using translation keys in dynamic configuration:
[source,yaml]
@@ -216,6 +216,9 @@ Example for using translation keys in dynamic configuration:
dynamicPlugins:
frontend:
red-hat-developer-hub.backstage-plugin-global-floating-action-button:
+ translationResources:
+ - importName: globalFloatingActionButtonTranslations
+ ref: globalFloatingActionButtonTranslationRef
mountPoints:
- mountPoint: application/listener
importName: DynamicGlobalFloatingActionButton
From 4e5f01e3929a85db2f6c85f4a23b5754836e081a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Fri, 7 Nov 2025 10:39:59 +0000
Subject: [PATCH 48/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
...enabling-localization-in-sidebar-items.adoc | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
index 0560d1ffbc..175bfcd6df 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc
@@ -3,7 +3,7 @@
[id="proc-enabling-localization-in-sidebar-menu-items_{context}"]
= Enabling sidebar menu items localization in {product-very-short}
-You can enable translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
+You can add translation key support for sidebar menu items, so that users can onboard in their preferred language. In {product-short}, all existing and newly created sidebar menu items support localization using the `titleKey` translation key.
[NOTE]
====
@@ -15,7 +15,7 @@ If a translation key is present but the corresponding localized string is missin
.Procedure
-. For *all* sidebar menu items (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the `dynamicPlugins.frontend.default.main-menu-items.menuItems.default.home` section of your `{my-app-config-file}` file, add the `titleKey`, as follows:
+. For sidebar menu items in your configuration file, you must define both the original text and the new localization keys. For example, in the `dynamicPlugins.frontend.default.main-menu-items.menuItems.default.favorites` section of your `{my-app-config-file}` file, add the `titleKey`, as follows:
+
.Example `{my-app-config-file}` fragment
[source,yaml,subs="+quotes"]
@@ -24,10 +24,10 @@ dynamicPlugins:
frontend:
default.main-menu-items:
menuItems:
- default.home:
- title: Home
- titleKey: menuItem.home
- icon: home
+ default.favorites:
+ title: Favorites
+ titleKey: menuItem.favorites
+ icon: favorite
priority: 100
enabled: true
----
@@ -37,12 +37,12 @@ dynamicPlugins:
[source,yaml,subs="+quotes"]
----
{
- "{product-very-short}": {
+ "rhdh": {
"en": {
- "menuItem.home": "Home"
+ "menuItem.favorites": "Favorites"
},
"fr": {
- "menuItem.home": "Accueil"
+ "menuItem.favorites": "Favoris"
}
}
}
From 59085491410300957942344711af7117314d3709 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 13:04:03 +0000
Subject: [PATCH 49/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-localization-in-rhdh.adoc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 150261b037..8a4b0442fd 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -5,12 +5,12 @@
include::modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc[leveloffset=+1]
-include::modules/customizing-the-appearance/proc-overriding-translations.adoc[leveloffset=+2]
-
include::modules/customizing-the-appearance/proc-select-rhdh-language.adoc[leveloffset=+1]
include::modules/customizing-the-appearance/con-language-persistence.adoc[leveloffset=+2]
+include::modules/customizing-the-appearance/proc-overriding-translations.adoc[leveloffset=+1]
+
// include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
// include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
From 1cdf2844c33a6e8a49452fef67ef1962165ae9b4 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 16:29:38 +0000
Subject: [PATCH 50/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
assemblies/assembly-localization-in-rhdh.adoc | 6 +--
.../proc-overriding-translations.adoc | 42 ++++++++++++++-----
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 8a4b0442fd..2f3e848cd4 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -9,15 +9,15 @@ include::modules/customizing-the-appearance/proc-select-rhdh-language.adoc[level
include::modules/customizing-the-appearance/con-language-persistence.adoc[leveloffset=+2]
-include::modules/customizing-the-appearance/proc-overriding-translations.adoc[leveloffset=+1]
-
// include::modules/customizing-the-appearance/proc-enabling-localization-in-quickstarts.adoc[leveloffset=+1]
// include::modules/customizing-the-appearance/proc-enabling-localization-in-sidebar-items.adoc[leveloffset=+1]
//include::modules/customizing-the-appearance/proc-enabling-localization-in-floating-action-button.adoc[leveloffset=+1]
-== Localization support for custom plugins
+== Localization support for plugins
+
+include::modules/customizing-the-appearance/proc-overriding-translations.adoc[leveloffset=+2]
include::modules/customizing-the-appearance/ref-best-practices-for-localization.adoc[leveloffset=+2]
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index f055905a4d..c207821f9a 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,7 +2,14 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-In {product-very-short} 1.8, English and French are the supported languages. You can implement translations for other languages by using a JSON file to override the existing translation strings, and by updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
+//In {product-very-short} 1.8, English and French are enabled by default. You can implement translations for other languages by using a JSON file to override the existing translation strings, and by updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
+
+//In {product-very-short} 1.8, English and French are enabled by default. You can implement translations for other languages by adding the language translation strings to a file that overrides the existing translation strings. You must also update the `i18n` section of your `{my-app-config-file}` configuration file to add the new `locale` and your translation override file.
+
+//In {product-very-short} 1.8, English and French are enabled by default. You can add a translation strings file to your {product-short} deployment that you can use to override the default translation strings, or to implement translations for other languages.
+
+In {product-very-short} 1.8, you can override plugin translation strings without modifying the plugin source code.
+
.Prerequisites
* You have enabled localization in your {product-very-short} application.
@@ -11,7 +18,7 @@ In {product-very-short} 1.8, English and French are the supported languages. You
// This feature is not being included in 1.8
// . In the top user menu, go to *Settings* > *General*.
// . Click on the download link in the *Translations* panel to download the default English translation strings.
-. Create the JSON file containing all your translation as shown in the following example:
+. Create a translation stings file containing all your translation as shown in the following example:
+
[id=i18n-enable]
.`allTranslations.json` fragment with translation string overrides
@@ -19,27 +26,26 @@ In {product-very-short} 1.8, English and French are the supported languages. You
----
{
"plugin.global-floating-action-button": {
+ "en": {
+ "fab.quay.label": "QUAY EN JSON",
+ "fab.rbac.label": "RBAC EN JSON",
+ "fab.rbac.tooltip": "RBAC EN tooltip JSON"
+ },
"fr": {
"fab.quay.label": "QUAY French JSON",
"fab.quay.tooltip": "QUAY french tooltip JSON",
"fab.rbac.label": "RBAC French JSON",
"fab.rbac.tooltip": "RBAC french tooltip JSON"
- },
- "en": {
- "fab.quay.label": "QUAY EN JSON",
- "fab.rbac.label": "RBAC EN JSON",
- "fab.rbac.tooltip": "RBAC EN tooltip JSON"
}
},
"plugin.global-header": {
- "fr": {
- "applicationLauncher.developerHub": "Developer Hub French JSON"
- },
"en": {
"applicationLauncher.developerHub": "Developer Hub EN JSON"
+ },
+ "fr": {
+ "applicationLauncher.developerHub": "Developer Hub French JSON"
}
}
-
}
----
. Log in to your cluster and create a config map for your translations override strings:
@@ -104,3 +110,17 @@ i18n:
- /opt/app-root/src/translations/all-translations.json
----
+.Additional resources
+// * link:{customizing-book-link}#configuring-templates[Enabling floating button localization in {product-short}]
+// * link:{customizing-book-link}#configuring-templates[Enabling Quickstart localization in {product-short}]
+// * link:{customizing-book-link}#configuring-templates[Enabling sidebar menu items localization in {product-short}]
+
+{context}
+
+* xref:proc-enabling-localization-in-floating-action-button_configuring-a-floating-action-button[Enabling floating button localization in {product-short}]
+* xref:proc-enabling-localization-in-quickstarts_customizing-the-quickstarts[Enabling Quickstart localization in {product-short}]
+* xref:proc-enabling-localization-in-sidebar-menu-items_customizing-appearance[Enabling sidebar menu items localization in {product-short}]
+
+// * xref:proc-enabling-localization-in-floating-action-button_{context}[fggdsg]
+// * xref:proc-enabling-localization-in-quickstarts_{context}[fggdsg]
+// * xref:proc-enabling-localization-in-sidebar-menu-items_{context}[fggdsg]
\ No newline at end of file
From 2b314199d7ae085e91d3ba7728e72a6a56b4c00a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 19:27:03 +0000
Subject: [PATCH 51/54] RHIDP-8635-1 - Comprehensive documentation for
developers on adding localization support to custom plugins
---
.../customizing-the-appearance/con-language-persistence.adoc | 2 +-
.../proc-overriding-translations.adoc | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/customizing-the-appearance/con-language-persistence.adoc b/modules/customizing-the-appearance/con-language-persistence.adoc
index cd22f24fe5..9c0e28ba50 100644
--- a/modules/customizing-the-appearance/con-language-persistence.adoc
+++ b/modules/customizing-the-appearance/con-language-persistence.adoc
@@ -19,7 +19,7 @@ Default language selection uses the following priority order:
userSettings:
persistence: browser
----
-+
+
where:
userSettings:persistence::
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index c207821f9a..602c019e97 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -58,7 +58,7 @@ oc create configmap all-translations \
. Update your deployment configuration based on your installation method:
-.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR).
+.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR). For more information about configuring a CR, see link:https://docs.redhat.com/en/documentation/red_hat_developer_hub/{product-version}/html/configuring_red_hat_developer_hub/provisioning-and-using-your-custom-configuration#using-the-operator-to-run-rhdh-with-your-custom-configuration[Using the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration].
... In the `spec.application.extraFiles` section, add the translations custom app configuration as shown in the following example:
+
.{product-custom-resource-type} custom resource fragment
From a9120d4ea24c80bad39a55f3310e9128bcdb5c9a Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 19:42:52 +0000
Subject: [PATCH 52/54] RHIDP-8635-1 - [testday] Fix typo in localisation docs
---
.../customizing-the-appearance/con-language-persistence.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/customizing-the-appearance/con-language-persistence.adoc b/modules/customizing-the-appearance/con-language-persistence.adoc
index 9c0e28ba50..5e6097f3d3 100644
--- a/modules/customizing-the-appearance/con-language-persistence.adoc
+++ b/modules/customizing-the-appearance/con-language-persistence.adoc
@@ -23,5 +23,5 @@ userSettings:
where:
userSettings:persistence::
-Enter `browser` to opt-out and use browser local storage. Optionally, set this value to `database` to persist across browsers and devices. This the default setting and does not require this configuration to be set.
+Enter `browser` to opt-out and use browser local storage. Optionally, set this value to `database` to persist across browsers and devices. This is the default setting and does not require this configuration to be set.
From 3b42cd3d12e64ba6c80cd8b175ebb5d9dc56beb8 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 20:09:43 +0000
Subject: [PATCH 53/54] RHIDP-8635-1 - [testday] Localization: Add link to oc
installation
---
.../proc-overriding-translations.adoc | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index 602c019e97..f335b73e3d 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -2,17 +2,11 @@
[id="prov-overriding-translations_{context}"]
= Overriding translations
-//In {product-very-short} 1.8, English and French are enabled by default. You can implement translations for other languages by using a JSON file to override the existing translation strings, and by updating the `i18n` section of your `{my-app-config-file}` configuration file to include the JSON translation override file.
-
-//In {product-very-short} 1.8, English and French are enabled by default. You can implement translations for other languages by adding the language translation strings to a file that overrides the existing translation strings. You must also update the `i18n` section of your `{my-app-config-file}` configuration file to add the new `locale` and your translation override file.
-
-//In {product-very-short} 1.8, English and French are enabled by default. You can add a translation strings file to your {product-short} deployment that you can use to override the default translation strings, or to implement translations for other languages.
-
In {product-very-short} 1.8, you can override plugin translation strings without modifying the plugin source code.
-
.Prerequisites
* You have enabled localization in your {product-very-short} application.
+* For an Operator-installed {product-very-short} instance, you have installed the {openshift-cli}. For more information about installing `oc`, see {ocp-docs-link}/html/cli_tools/openshift-cli-oc#installing-openshift-cli[Installing the OpenShift CLI].
.Procedure
// This feature is not being included in 1.8
@@ -58,7 +52,7 @@ oc create configmap all-translations \
. Update your deployment configuration based on your installation method:
-.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR). For more information about configuring a CR, see link:https://docs.redhat.com/en/documentation/red_hat_developer_hub/{product-version}/html/configuring_red_hat_developer_hub/provisioning-and-using-your-custom-configuration#using-the-operator-to-run-rhdh-with-your-custom-configuration[Using the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration].
+.. For an Operator-installed {product-very-short} instance, update your `{product-custom-resource-type}` custom resource (CR). For more information about configuring a CR, see link::https://docs.redhat.com/en/documentation/red_hat_developer_hub/{product-version}/html/configuring_red_hat_developer_hub/provisioning-and-using-your-custom-configuration#using-the-operator-to-run-rhdh-with-your-custom-configuration[Using the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration].
... In the `spec.application.extraFiles` section, add the translations custom app configuration as shown in the following example:
+
.{product-custom-resource-type} custom resource fragment
From 6ef43d33e69f09ae6352f83e2b8b2b7130d80665 Mon Sep 17 00:00:00 2001
From: Gerry-Forde <63045020+Gerry-Forde@users.noreply.github.com>
Date: Sat, 8 Nov 2025 20:52:36 +0000
Subject: [PATCH 54/54] RHIDP-8634-2 - [testday] Localization: Update
enablement and language selection
---
assemblies/assembly-localization-in-rhdh.adoc | 1 +
.../proc-enabling-localization-in-rhdh.adoc | 2 ++
.../proc-overriding-translations.adoc | 2 +-
.../customizing-the-appearance/proc-select-rhdh-language.adoc | 3 ++-
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/assemblies/assembly-localization-in-rhdh.adoc b/assemblies/assembly-localization-in-rhdh.adoc
index 2f3e848cd4..8785703aef 100644
--- a/assemblies/assembly-localization-in-rhdh.adoc
+++ b/assemblies/assembly-localization-in-rhdh.adoc
@@ -1,4 +1,5 @@
:_mod-docs-content-type: ASSEMBLY
+:context: assembly-localization-in-rhdh
[id="assembly-localization-in-rhdh_{context}"]
= Localization in {product}
diff --git a/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc b/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
index b37961c882..50c1c05076 100644
--- a/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
+++ b/modules/customizing-the-appearance/proc-enabling-localization-in-rhdh.adoc
@@ -18,9 +18,11 @@ The language settings of {product} ({product-very-short}) use English by default
.`{my-app-config-file}` fragment with localization `i18n` fields
[source,yaml,subs="+quotes"]
----
+...
i18n:
locales: # List of supported locales. Must include `en`, otherwise the translation framework will fail to load.
- en
- fr
defaultLocale: en # Optional. Defaults to `en` if not specified.
+...
----
\ No newline at end of file
diff --git a/modules/customizing-the-appearance/proc-overriding-translations.adoc b/modules/customizing-the-appearance/proc-overriding-translations.adoc
index f335b73e3d..e5264a0319 100644
--- a/modules/customizing-the-appearance/proc-overriding-translations.adoc
+++ b/modules/customizing-the-appearance/proc-overriding-translations.adoc
@@ -12,7 +12,7 @@ In {product-very-short} 1.8, you can override plugin translation strings without
// This feature is not being included in 1.8
// . In the top user menu, go to *Settings* > *General*.
// . Click on the download link in the *Translations* panel to download the default English translation strings.
-. Create a translation stings file containing all your translation as shown in the following example:
+. Create a JSON file containing the translation strings that you want to override, as shown in the following example:
+
[id=i18n-enable]
.`allTranslations.json` fragment with translation string overrides
diff --git a/modules/customizing-the-appearance/proc-select-rhdh-language.adoc b/modules/customizing-the-appearance/proc-select-rhdh-language.adoc
index dfa6c335d1..3bb91ca3fc 100644
--- a/modules/customizing-the-appearance/proc-select-rhdh-language.adoc
+++ b/modules/customizing-the-appearance/proc-select-rhdh-language.adoc
@@ -11,10 +11,11 @@ You can choose to use one of the following supported languages:
.Prerequisites
* You are logged in to the {product-short} web console.
+* You have xref:proc-enabling-localization-in-rhdh_{context}[enabled the localization framework] in your {product-very-short} instance.
.Procedure
-. From the {product-short} web console, click *Settings*.
+. From the {product-short} web console, click the down arrow next to your profile name, then click *Settings*.
. From the *Appearance* panel, click the language dropdown to select your language of choice.
+
image::rhdh/customize-language-dropdown.png[]
\ No newline at end of file