From afb51aa043b5b6f29b3fa41e62889dc6e0a3174f Mon Sep 17 00:00:00 2001 From: Yogesh Kumar Date: Mon, 23 Mar 2026 19:13:33 +0530 Subject: [PATCH] Fix studio social metadata rendering --- AGENTS.md | 82 +++++++++++++++++++++ app/studio/layout.tsx | 71 ++++++++++-------- components/studio/studio-client-layout.tsx | 28 +++++++ public/relaycode-studio-logo.png | Bin 0 -> 23487 bytes public/relaycode-studio-logo.svg | 18 +++++ 5 files changed, 169 insertions(+), 30 deletions(-) create mode 100644 AGENTS.md create mode 100644 components/studio/studio-client-layout.tsx create mode 100644 public/relaycode-studio-logo.png create mode 100644 public/relaycode-studio-logo.svg diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c32ef7d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,82 @@ +# AGENTS.md - Relaycode + +## Project Overview + +Relaycode is a modern extrinsic builder for the Polkadot ecosystem, funded by a Web3 Foundation (W3F) grant. It provides a dual-pane interface for building, encoding/decoding, and submitting Substrate extrinsics with human-readable inputs on one side and encoded data on the other. + +## Tech Stack + +- **Framework**: Next.js 14 (App Router, SSR) +- **Language**: TypeScript (strict mode) +- **Styling**: Tailwind CSS + shadcn/ui +- **Polkadot Client**: [Dedot](https://github.com/dedotdev/dedot) (NOT @polkadot/api, which is deprecated) +- **Wallet**: LunoKit (planned M2 — NOT custom wallet provider) +- **State Management**: React Context API + hooks +- **Testing**: Jest + React Testing Library +- **Package Manager**: Yarn 1.x + +## Directory Structure + +``` +app/ # Next.js App Router pages + (marketing)/ # Landing/marketing pages + builder/ # Extrinsic builder tool +components/ + builder/ # Extrinsic builder components + params/ # Parameter type components + inputs/ # Substrate type input components (account, balance, enum, etc.) + ui/ # shadcn/ui base components +config/ # App configuration +context/ # React context providers +hooks/ # Custom React hooks +lib/ # Utility libraries +types/ # TypeScript type definitions +utils/ # Helper utilities +styles/ # Global styles +__tests__/ # Jest test files +docs/ # Documentation (public) +``` + +## Commands + +```bash +yarn dev # Start dev server +yarn build # Production build +yarn start # Start production server +yarn lint # Run ESLint +yarn test # Run Jest tests +yarn test:watch # Run tests in watch mode +``` + +## Architecture Notes + +**Three-layer architecture** (planned M2): +1. **Infrastructure** — providers, clients, wallet connection (LunoKit) +2. **Components** — reusable UI (params/inputs, builder panes) +3. **App** — pages, routing, layouts + +**Key patterns:** +- Path aliases via `@/*` mapping to project root +- shadcn/ui components in `components/ui/` — don't modify directly +- Input components in `components/params/inputs/` map to Substrate types +- Dedot client provides type-safe chain interactions via `DedotClient` + +## Code Conventions + +- TypeScript strict mode enabled +- Kebab-case for filenames (e.g., `key-value.tsx`, `vote-threshold.tsx`) +- Barrel exports from directories via `index.ts` +- React components use named exports +- `"use client"` directive for client components + +## Important Gotchas + +1. **Dedot, not polkadot-js** — This project uses Dedot as the Polkadot client. Do not import from `@polkadot/api`. +2. **LunoKit for wallet** — M2 will use LunoKit for wallet connection. Do not build custom wallet/keyring providers. +3. **shadcn/ui components** — Generated into `components/ui/`. Add new ones via `npx shadcn-ui add `. +4. **Next.js 14** — Uses App Router (not Pages Router). Layouts in `layout.tsx`, pages in `page.tsx`. +5. **No `lib/polkadot/`** — Legacy directory removed. Dedot is the only Polkadot integration. + +## M2 Implementation Reference + +See local `docs/m2-plan/` directory for detailed implementation plans (gitignored, not in repo). diff --git a/app/studio/layout.tsx b/app/studio/layout.tsx index b4e9864..72dcd21 100644 --- a/app/studio/layout.tsx +++ b/app/studio/layout.tsx @@ -1,37 +1,48 @@ -"use client"; +import type { Metadata } from "next"; +import type { ReactNode } from "react"; -import React from "react"; -import { NavBar } from "@/components/layout/site-header"; -import { ClientProvider } from "@/context/client"; -import { ContractProvider } from "@/context/contract-provider"; -import { StudioProvider } from "@/context/studio-provider"; -import { StudioNavCenter } from "@/components/studio/studio-nav-center"; +import { siteConfig } from "@/config/site"; +import { StudioClientLayout } from "@/components/studio/studio-client-layout"; + +const title = "Contract Studio — Smart Contract IDE for Polkadot Hub"; +const description = + "Write Solidity, compile to EVM or PVM, and deploy smart contracts on Polkadot Hub. No CLI or MetaMask required."; +const canonicalUrl = `${siteConfig.url}/studio`; +const imageUrl = `${siteConfig.url}/api/og/studio`; + +export const metadata: Metadata = { + title, + description, + alternates: { + canonical: canonicalUrl, + }, + openGraph: { + type: "website", + url: canonicalUrl, + title, + description, + siteName: siteConfig.name, + images: [ + { + url: imageUrl, + width: 1200, + height: 630, + alt: title, + }, + ], + }, + twitter: { + card: "summary_large_image", + title, + description, + images: [imageUrl], + }, +}; interface StudioLayoutProps { - children: React.ReactNode; + children: ReactNode; } export default function StudioLayout({ children }: StudioLayoutProps) { - return ( - - - -
- Contract Studio — Smart Contract IDE for Polkadot Hub | Relaycode - - - - - - - - - - } /> -
{children}
-
-
-
-
- ); + return {children}; } diff --git a/components/studio/studio-client-layout.tsx b/components/studio/studio-client-layout.tsx new file mode 100644 index 0000000..bfa2c74 --- /dev/null +++ b/components/studio/studio-client-layout.tsx @@ -0,0 +1,28 @@ +"use client"; + +import type { ReactNode } from "react"; + +import { NavBar } from "@/components/layout/site-header"; +import { ClientProvider } from "@/context/client"; +import { ContractProvider } from "@/context/contract-provider"; +import { StudioProvider } from "@/context/studio-provider"; +import { StudioNavCenter } from "@/components/studio/studio-nav-center"; + +interface StudioClientLayoutProps { + children: ReactNode; +} + +export function StudioClientLayout({ children }: StudioClientLayoutProps) { + return ( + + + +
+ } /> +
{children}
+
+
+
+
+ ); +} diff --git a/public/relaycode-studio-logo.png b/public/relaycode-studio-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..43cbe30d93de8b7f7f8bd921e469fc9aa85d5c95 GIT binary patch literal 23487 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

lQMJyQ0st35wfQ_r~&eV=lwQlAm zr?5BR>@=>YVK|mogzUWz8Uzdx8?T!?08>Hbul3lHR8I;zF?e2V3ormCkeNVY?VJZP zDf}I9vHFBM*HQBPw_~ryTq?RbuqSj~ca03v7}VwmL3>H04(P2h+c)92B9ncMT7kx$ zcB^V%%JTiqL;-c`%?inV1rWPUtlU&|0nfHmGb&fDrsqC>j%mfs`^KGVg;vjr@rT-4 z&&I|Vp=`0uq)33Txs)P;1`BmTsko@Dr*wGn*F%mueU1gEcQd}&Exj^r6Pd!uFe>{Q ziQduqWlKAd6n0Ch2YT~A^|k=piD0Rc^xGJtk*h}1%^Lqr*lH3j6L1BT{Tk3TQzG>$ zscNG4#E(yf(fCl%wS`T|4$$y9{SH7GNXqM2;}}#kR0rVBY8Lbyj^NjVqJ0Jgi@l!@ za%5wF``lauP9*|}h%RPtoIH8;JK&l@rG4C%4(mi)_c$B9Um&z)lLLNbyH$#^nbg}J zU!q%N)(aygoM+_a5(Zrvf}22imf_F34EFd2`Z!XpU#T4RVP4d?-1B-hP8hW8Vd6i%d}X7V+5s%Z<|LAuQj$&VO4Q4AV_LUMnuJI zN^2*IKKAcFc2VF2s`4#WxlDecL;nxxbM8`^-3QAa7*f=|v@g7GJR8x9Npi&_y~NUi zdKQvze56Pf;-UQ>2pg;ABW;skNy3&rZcis`%&;HlbOBa7;o|dg@ubgl$4q+F5*yFB zvue31$xv=k1+0X2k?sLT!K`ltk;w1YnwDCUAwtV{d@W9`t`qmjECMVJ76J(ZEPkaQ z(_2}a`^x!vsrDn1X(7W^rCru8r8aFqbZ~nvKR3ud!V=RR;SQR*jHP~@Vgs_CF)I8) zF+q~g7z*`U<&p92vq#$Yh31PB$cJztDAivrw8k6i`!Rfod!KeO5rEi zW-J7zR@K9LLae2GwY?gfHQ4Itv#bs!ilt(EnhLR-pCuVKMjHE2xxmRn3 z)~XiW17?Qy_<5U5nt|HAQ8dq9L+3CEeY$pa2t8^H970{;M5(1#x|eMIFBVXT69+u- z8O;{2K;+#IeF5@3`{;C=%McIPUlu+?$}K66@iTJXQ0JcO{r3Hx#QW74dAgWQkBKw7 zMuhkm8gDLJufx*snf6}0g;N83{rZ{#STeK5HPgJO<{UE^N}-nc3LDM|g=0}E!|Uay z<|Lb$SgGw6y)(F_$$e@oo60?YSi6b*0>tgOVkZW-VO8qyb#nE1Vp{6BKSrflzsh}j zkRs-#yKH3066O_?pKhdH%QPWvA78CXpO1}LHiV|b6!j?9bi7$?Uzc1?b2>$em6v{n z+j^lzIf1@?v{PM(nOB=8Rdu%bVc{Hs%M&RNFNxUXO%)bIw4*3FY

2`9YWN*!>2D z^AFsu7kn$-L*Xb3Ho}KZ?(dkPy5x&Cc~S8`+HQbK%Nx%s6j4ef zyALOuVmX?lh!sso&E9}~FY5RMVru5U7N5kSI8lbaN2|srl*~)BmjO$Gk z2xhsn^`d5pH}9*?rUH0cawoghPpKn3PPs;<90=fdFP_G++CIeIt&f8rsOgvdq4JA_B?v#<=$%)s=ajThQ+n;yQ-mE+?z_pC z9f$j!-8BLf8loTULhu=#gUI0#$!6%2c7zA&Wf(4oB}C|zRO;M{G@r#>jI!oT7BK1D z5-LUzuu$!y$njZ)ZNNqX=tK?Qd8vryi3;uc+o{k=Uy&l@@-rRI5&oZkkX_ z6YdqKN+HXS#QF1@YxF_DiP$nA^`GtEq06`urA2Ouzfr2tMUot?Il7lkWPYB@cqu|7 zrIFE<;E|6tFKSBpoZkctSIsA&ooQqsaO$*ax1G;S{8CB77cpYC(Y^f88c$0jeni80+1kv

UVR7Lr~@yM}f zf81JA_F1f9k#!$K{fUlBp6^T6?P#;+Xu7`NHhwZ8-Ppawdli(E*IX}d3#dIoKlQPR z`p9!rtxsngF1(i()Ga`lZS(w!@rpj*{7A7o}Pm4^YmA< zVEQ%nb|{H>JfgksXMxofh^H$u*9Fyhso%11HdPh-Hq1%t@+MmI3~MLH89Y?)dp8Pr z1wTEgn7sVv@i4`{$Iy#SE8D%3khaeuQjRqw!%8_(IM-@-HDwAzk!1=I=k{V)FwL%3VpL7!QjA!(_BFf*ts&?N`}|p>)fc zRGRoPUds?_p_h51!tmH5{=W9|5lwwlpyP8+&;N{TbgTek0ElY}v#@ep+4H4e`Hyrn zX=|q>vN_8)*Lz~9dFY*##^ZvTZ>~K=qH=2F*~inr%J(`M6-m?gvRFNhX7m{NJsxZ% znfJLjICjnCyPchrbpFzVdqZ=JSNrP^iau}|fME7$JCdd-dsw#Uw)MS^!;(QmzsBz76Bz4n~hBdB$O8*@gwMnD1i zDfnqSkoWS`qRl6nYgP78m=dJ31c)S}_H@s1OeqyH$`3*K2)ADJFKYa{-AKXGh&Pm# zrd;X3*1xs3GG54u`TD?XowYa%vS~&U8`VfiW51+UT^mf0(Q{#huPsOfiFyh`z?De7ATX${X=1stvRFfQOiwtVK3f? zas*CXMitx9R@JrbFZ*EFNz$2V`);CBBG2Ed(0--a2>|-8;`ZRYQdO4iF76mp=n8Rv zuUdjx4LSb`Y#y51WSoKUvJI%(0}*l8n#4E058S)$3|)#Keh=P%rjiVfZ-wmGZV? zOI(gVwl(fJuC?oyEn&#l&|p-T3ez5>gDI+A0cay<{dZs}(IaFe-@=bp?26TFr&P zl;PX34`b?+)vhNSp_6`xvSp)#u3@YrqK8rgOxX*iS{&3OM(jU08XuIOCyGVvwJ>Yz zjt&N$a7&H2bE_StLzcxJ>Be>#fi)TGNqK&BXVevD6b!drb6b z!=^lbSngd^EGzc>6I}|{~a$}x%862n5-GF@}d zCSz_Opq9VBmstbV*YX45%-jKh!Jy; zs!vnI6Jnwa*N-0qk?#MYjSgAl|bwG3%FQ zelU)n8d^D^G~a+c=P_p=qFm!H{)J!wXlgacT$Bk+6#1=DNok|(m|@%_VNNI68%DTF zwJQ8SuHYw8ZsXK+C0!M~#dwoGDxc6_@~}}v7PT18v*^g@jK@FWXZEVWOD`Or$r~zD@4VSG&9&S3|SUL=KP%d_fbT`qLuS8-JV@YEI=C zctk0}LXYN?IqY1txh29~E2%V~nGvr(n&CPl&3u|!Hyl(<{9=?yCR)2~Po9XR@Y)#^ zqgB*tPUM%&`+a_J#Tk7$+1U#+40ahMqageA)0WEqoRCE|cA#OYuoD-E=XT13m0?61; z9NwCTswBH)So{z)_(HgcN7)vv1*Td_BNNv$S%r?F)>KkpLh3cFgF&1>(+Ks^&?D!g zFk|{7t3J%+!LNCi+myWEg$JCF7hma~X-Nfui3MErrz=ls-k|vkC;}W45}e*kwiE$t z9r)FFKA}gO14N-L&^PrgcR}DWN)Bm;Qdl_O)ke*1*&D-O^q?sb399ag=PM`l{fIKd zeGo<(=|{!)#*mi=2-t%QX3uh%s%AlPC4^0e*x%1haS@o@-CWAyK1Vbj(laP8Smw3Z zrvc6Mu~e|WFXQ%+zw_&#IN{wo9_^Ek{e6SO2pGy`?Dxo3`Kw9Uf^GWbh_&@slQP2w z?A8DL;JSeAsH7QmYIIGq(`#W+kk^&;eGLfIlpX(?j!3wSE@*1?iniNb4KEx2> z{i{jIf}4!&sA>LvXUHR%mhXg|N&Hung3V%?oza*6mCQZ?rCz+nR{`_Sb);f|CdGOk zr}}q!-@pne76c2B|B&#xk{POI>>;Y(y#)YQ4r^cOX=s zfn^*2Opx^ z1I!Ox5`>jMjq(t2J=-xOye0eoyyEc3Qyxr(1Z}&ZS}-)x(3?}BgGmWq&r|2HH^-HI z=wLF5;tXzF4;bh^+rWnMV*-djnAc{+)#!CVG0hnUjSyO37P$D)aKRba{z^cU{xtsi z`R%5dDjvX>ZTl80P8thEYoiWV`{@@2+DcSi~BQ;On5M&Ok{4tDsnfT~Y5`wGM| zl}o<)z)a!5q`Q{YujouQprc%csu5)7)IjfECaIf#7`oJRKUIlS?M2K8%mod1oP1z# zWnsE*#+-ii9JR2Zz$VY?H1Ze_U(eeZdo4hV$gZ{LwN|aG3???r-ogM=kbAHBL-TwL zj5_I?%L~D{yjVwIZCZJOQ6j{;WRdjV_wC1a4Bl>762b!f;h+`YB(4~y=fNW&afax< z38Mn1X3`8W>Mo$rilXI>dOlP5KhMxWy=(x;m8WabbyCL>HZfxbOl6!dUS7{**Pz!M znbiJ*zDM_o6A~53 z*06$?j33SxPYx|f=tgM)1UWk}7P=l*(NBKz0@WBWvbuJ-?CQ)9M-D|V^S)RyWMnSj z&1@)e+B$QJYkMgV(1R*BYgiK_8qf;Z{~oj7OOn&{cX5K*kn@`JF1{JbL%a5X_Xl>JO#t1B#rrW@T!aY0Z9`?QpQU zl@XY3kpP3*=#mLl#g7yY!t6sz=YrNKCejA{y4OGNe#{Zk)jg&rJ?jj3$Z|O_38w3N zA+VL3^fn!ZL@qSc*O+<7)k&?9&urznclKc7(0PJJ>PB2~Vw4N=4wR|KRM=}m0>$$4 zS)#liqI?EnJ~*BvZU^3rB{}q1@QCFXU=F1?cA?Gvnl8QbqGH-OStXhL_B41 z1)$*3X{>6U;WXq(QSk|oqJs$cLO+U?2Xa;U@p=M-??RskOvG2we;NY=$23MgSt@&P zt>vE@zdRwRm4jvOU2xD?;_eOYqz0M`9B?bg+o)-oP zGY@YAdD`)#w4jC?t2lD_yOaI-T6L?nhn$s-%K(=f_Swc9=>a1-+ zrHNey9JZEKb1=TL8EXlDSS+5ky64PZ^e%Z)OI(gu2}(CxhA&I>xnrPJ!Q3frhBQ`| z9lIV58XH+5q?@wr5Y5{S#_9 z^krTHGB_sYh>skaW$cwJkG0I$Wwqg3;LA)JNebR--~%m3q{wh@2U?l^*;y~C3HI%V znP`!aI*gBx3gt~He3`Wn%vW3V}2Sey66tagyleJ{*>)}X|G&&iCOp%l<9m>Am?tOn}bnboJ`!C#Izw`Y* z=KcMC*7y7KdObNLdiIU(s2Ec}6Fu-c?CXBtQ(eWEt{#~UnU~9M=JOMD#xVejfsvw! z*TCd3xMt0V5jws0Zf7FdSD3q!=4qGPd(Ao5}-hVLa^3M9f zC8CYD?)Y-Q^kHn*&4i}CSGCttP0wN*I2AE7(oZMy`0t$SH=Zoc4WS*Wc=AV8Er^gR zm$xf4pDRn=8!SJl97U^#gAY=yMUj7-x(yugmGth-d6P;mu}r%~(D7Ig23XL8WQL=8 z+AVSfF&8!m!RY;==dfVF=Y8d=HY@odaM|ljdl(}nG%(FnEAXguRYR9q3u$r%ybEDz z@-=u9hZj#%ku}#i2#^a5L5TQVUcP|`g5lp7-SI5*OWSp`H2=ihVb`1efmGa;o4Kh@BcgZn>FXY$ zS)o#O?{=>lg732Af>VRveHBUTaT6FcM08_!Eam~bewrBDS^%6uZ_3~J2-8|;2!Gnf z33apY@7ES4PEDOYsNCnWZv~wvA8SSSyGP5ni*zxK7rWff-@ltSMZaC4&wXJvCB8_E zyCYsCqiwL9wT@UJG!Zl zN9QcV33!QBp&JT#Wu)<@lj5pl?*qEEAMNjZsPpU>KIFLjk!Vlxcfb1TxGK!1qGxZx z#X|AmPf6)BBg3#E$`(8DF1dt!RhXcQ7l(O(Jef3@5}{RAW>(RY*dX46o6OY?C2c72 zyd9i8F&OBn8b$yIyL^V4OMu90dCp`)XL)e1kxZsmXS6}^xw!S?H)bB>CzM!G#n6FA z@4q#7lCose@epQc8{6vDBBJ9O=k7$%4!6HcyepuZS|7sX>0F{14HG(#ie z^QOi`@z;qByXPkTuCDC#$>S4c8+>%?uos9h#uO%OmGXu;sK!y)@Lyo1dPFVlzaG6g zhC3;tb6&nDa0$x%jx(Lw@fyR${Dri8U$6S_>s%@QMp-u*4;2To$Q0kNE^(0a*wz_T za`yaV0g-or2{|ZbpXsiXy44D>PGrwO)zEgngxmBhuQ=hT<=%2W**!3Lp3to-mRD#x zZ(v=PSFB+y0>`AbFaGbRIFW*L6cOOMG`u$?4cE=7<%d}0{9SdV#HiWb`cE0B< z=uf@D3v)MzJpaOWG3`6!=WzP5?L$8~kv}x(E?V5TY%*vHY3<>@?$Evp?_OIW8QQos z8W4;K$WDO7J#GE64V`1A@8oVFk$Au1{CA&JUwlP24jVAqQXa?sxdGd$fg?P|#mA*? zk)Ogoq;?@=GpuAq^DF6qYw2|XA&HgOUPV=E!=*_Zz>rXp;+gsVY1Rm6ND}zX#5hgZ zgodunFxGnYZ+)DF??!7?Y*9|aq9K6oh!??4n(~hl*te7;+sh;I?`m-NeYX*-#AljB z)^P(9ZdIzBZWh&}XcQFWbuNc+$s_aiBcN(dQf}c)x4&DoO(*a-*F$-k*l}|`*RDeD zc_Q8cYBbeS2J5Aq9`@!2i*RVoWFJm!bH^F)yH;+XKCd!OSv(%2bvJq=;7-uRY3uLK z(Y>#Y%(KFmg~MnbUO|-!7hZQdaWCw8JY(%Rf1Rd7)e(}K`YJ&o@OKIujylYgi~uW&xm~#<#5fXl@`2WNjC&2{{8_T zYJp?sE14P!F|pq-RJ85D3pg*xmaxON$Alv2iDsrk?TIMD=<1S?ur5=9$BDErQKpxj znMB2iL-*WV=ZsMJuxlnsGZ|~dO^E&D zpt}b*GZ~XY1cK-sLqTS)h(}zeb6-?cnQXgA0YnEGX;#3=3=cByJ^z2r|7uN}(j);7 z4%T;P!?xdy@b=XQtH_ zmJPWE>V5ghB08(@L=a(pTqb!#sb;Qck14YUq0mwYvMvu25h*$(kgSJecmbOi2j0f^ z6X#W@fa;JzwDw^2R3e_h4s6u(YJfRu$nu!Q8d++`Sj2C)HQ>jKz^9g(4oKz4uxjpyW?Z3-XdQ` z!=83J;86DxJe3GOb>IX`KnR2KC|1>L;3ZHyaBEPSYZ2%M9rTO7k!NuKwb0tmCfZjZpYi)K+W*R_>xk$yLs7)9g zw#W>IV&CMqXr2H`i2cWo_&zs7Ei`F|YcnhoeQuw(IuZ)q&)In;M969Un`)~u9g6E( zA8)Jt$6suVROvq2SD7P}TzD2U^Qy+>8BWHmW?2bLi>&ThAWhK_mOPPA1N01qpr`_0 z?XXs(DR0)A*yJk*;zL@xqEwf9F;SS+(&5OfuBm8?!G<*vZZ0(5~# zSXDM#(~u<+<&(8TSH)Jv4;cfIb=TrwLw&G#h8sK`>Xl}NlgiB&Pj=;U6%62if2+c3 z*Y^$)UnUY4e6U7AnP0a;mNFs|oJ_SQl;=%RFS<~V_Cj&zn1GzyOg z!fnQ%B+2rSh1{qsKM`Eov0s3;fE1^~V!OA-#T$P56I|R(DgEU!W4z?(h3JCO0;3cS znxYWyD{~y<)7b+HC}wIn#wyNW6z+HmRig@M?Cv77oUBbX)?FwdCerJC97HtyC=`!%aLuXfJjdha6AdYfGi``1ybQ3>ek6o4oY^bbIybF#H-c?>fR< zm{II#DT{mqp6BIn0Vwii-qaV3zX*;&EO4&m(U*Qvr~` + + + + + + + + + + Relaycode + + + + + STUDIO + +