From e7500e5a128002a75fa3b6f097447e2a8845ecd7 Mon Sep 17 00:00:00 2001 From: Quicy <1728550853@qq.com> Date: Thu, 29 Jan 2026 14:57:14 +0800 Subject: [PATCH] feat: add layout of chat and login --- .vscode/settings.json | 10 +- packages/ui/components.json | 20 +++ packages/ui/package.json | 3 +- packages/ui/src/style.css | 142 ------------------ packages/web/package.json | 2 + packages/web/public/logo.png | Bin 0 -> 52617 bytes packages/web/src/App.vue | 4 +- .../src/components/MainContainer/index.vue | 13 ++ packages/web/src/components/Sidebar/index.vue | 103 +++++++++++++ packages/web/src/layout/mainLayout/index.vue | 7 + packages/web/src/main.ts | 1 - packages/web/src/pages/chat/index.vue | 22 +++ packages/web/src/pages/login/index.vue | 97 ++++++++++++ packages/web/src/router.ts | 29 +++- packages/web/src/style.css | 122 ++++++++++++++- packages/web/tsconfig.app.json | 2 +- packages/web/vite.config.ts | 1 + pnpm-lock.yaml | 82 ++++++++++ 18 files changed, 507 insertions(+), 153 deletions(-) create mode 100644 packages/ui/components.json create mode 100644 packages/web/public/logo.png create mode 100644 packages/web/src/components/MainContainer/index.vue create mode 100644 packages/web/src/components/Sidebar/index.vue create mode 100644 packages/web/src/layout/mainLayout/index.vue create mode 100644 packages/web/src/pages/chat/index.vue create mode 100644 packages/web/src/pages/login/index.vue diff --git a/.vscode/settings.json b/.vscode/settings.json index d0746e5f..ee2a1804 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,14 @@ { "editor.insertSpaces": true, "editor.detectIndentation": false, - + "editor.formatOnSave": false, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + "editor.tabSize": 2, - + "[typescript]": { "editor.tabSize": 2, "editor.insertSpaces": true @@ -33,4 +38,3 @@ "editor.insertSpaces": true } } - diff --git a/packages/ui/components.json b/packages/ui/components.json new file mode 100644 index 00000000..56f749c0 --- /dev/null +++ b/packages/ui/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "typescript": true, + "tailwind": { + "config": "", + "css": "src/style.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "composables": "@/composables", + "utils": "@/lib/utils", + "ui": "@/components", + "lib": "@/lib" + }, + "iconLibrary": "lucide" +} diff --git a/packages/ui/package.json b/packages/ui/package.json index 73d22b52..352848db 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -4,7 +4,8 @@ "private": true, "type": "module", "exports": { - ".": "./src/index.ts" + ".": "./src/index.ts", + "./style.css": "./src/style.css" }, "engines": { "node": "^20.19.0 || >=22.12.0" diff --git a/packages/ui/src/style.css b/packages/ui/src/style.css index 237f740a..5a7873ab 100644 --- a/packages/ui/src/style.css +++ b/packages/ui/src/style.css @@ -1,144 +1,2 @@ @import "tailwindcss"; @import "tw-animate-css"; - -@custom-variant dark (&:is(.dark *)); - -@theme inline { - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); -} - -:root { - --radius: 1rem; - /* Base colors - gray-50 / gray-900 */ - --background: oklch(0.985 0 0); /* gray-50 */ - --foreground: oklch(0.224 0 0); /* gray-900 */ - /* Card - white with gray border */ - --card: oklch(1 0 0); /* white */ - --card-foreground: oklch(0.224 0 0); /* gray-900 */ - /* Popover - white */ - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.224 0 0); - /* Primary - blue-500 */ - --primary: oklch(0.572 0.188 255.29); /* blue-500 */ - --primary-foreground: oklch(1 0 0); /* white */ - /* Secondary - gray-100 */ - --secondary: oklch(0.965 0 0); /* gray-100 */ - --secondary-foreground: oklch(0.224 0 0); /* gray-900 */ - /* Muted - gray-100 / gray-500 */ - --muted: oklch(0.965 0 0); /* gray-100 */ - --muted-foreground: oklch(0.539 0 0); /* gray-500 */ - /* Accent - gray-100 */ - --accent: oklch(0.965 0 0); /* gray-100 */ - --accent-foreground: oklch(0.224 0 0); /* gray-900 */ - /* Destructive - red-500 */ - --destructive: oklch(0.577 0.245 27.325); - /* Border - gray-200 */ - --border: oklch(0.922 0 0); /* gray-200 */ - --input: oklch(0.922 0 0); /* gray-200 */ - /* Ring - blue-500 */ - --ring: oklch(0.572 0.188 255.29); /* blue-500 */ - /* Charts */ - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - /* Sidebar - white */ - --sidebar: oklch(1 0 0); - --sidebar-foreground: oklch(0.224 0 0); - --sidebar-primary: oklch(0.572 0.188 255.29); /* blue-500 */ - --sidebar-primary-foreground: oklch(1 0 0); - --sidebar-accent: oklch(0.965 0 0); /* gray-100 */ - --sidebar-accent-foreground: oklch(0.224 0 0); - --sidebar-border: oklch(0.922 0 0); /* gray-200 */ - --sidebar-ring: oklch(0.572 0.188 255.29); /* blue-500 */ -} - -.dark { - /* Base colors - gray-800 / gray-100 */ - --background: oklch(0.298 0 0); /* gray-800 */ - --foreground: oklch(0.965 0 0); /* gray-100 */ - /* Card - gray-900 with gray-700 border */ - --card: oklch(0.224 0 0); /* gray-900 */ - --card-foreground: oklch(0.965 0 0); /* gray-100 */ - /* Popover - gray-900 */ - --popover: oklch(0.224 0 0); - --popover-foreground: oklch(0.965 0 0); - /* Primary - blue-500 */ - --primary: oklch(0.572 0.188 255.29); /* blue-500 */ - --primary-foreground: oklch(1 0 0); /* white */ - /* Secondary - gray-700 */ - --secondary: oklch(0.427 0 0); /* gray-700 */ - --secondary-foreground: oklch(0.965 0 0); /* gray-100 */ - /* Muted - gray-700 / gray-400 */ - --muted: oklch(0.427 0 0); /* gray-700 */ - --muted-foreground: oklch(0.642 0 0); /* gray-400 */ - /* Accent - gray-700 */ - --accent: oklch(0.427 0 0); /* gray-700 */ - --accent-foreground: oklch(0.965 0 0); /* gray-100 */ - /* Destructive - red-500 */ - --destructive: oklch(0.704 0.191 22.216); - /* Border - gray-700 */ - --border: oklch(0.427 0 0); /* gray-700 */ - --input: oklch(0.427 0 0); /* gray-700 */ - /* Ring - blue-500 */ - --ring: oklch(0.572 0.188 255.29); /* blue-500 */ - /* Charts */ - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - /* Sidebar - gray-900 */ - --sidebar: oklch(0.224 0 0); - --sidebar-foreground: oklch(0.965 0 0); - --sidebar-primary: oklch(0.572 0.188 255.29); /* blue-500 */ - --sidebar-primary-foreground: oklch(1 0 0); - --sidebar-accent: oklch(0.427 0 0); /* gray-700 */ - --sidebar-accent-foreground: oklch(0.965 0 0); - --sidebar-border: oklch(0.427 0 0); /* gray-700 */ - --sidebar-ring: oklch(0.572 0.188 255.29); /* blue-500 */ -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } -} \ No newline at end of file diff --git a/packages/web/package.json b/packages/web/package.json index 65992cf6..e5555319 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -9,6 +9,8 @@ "start": "vite preview" }, "dependencies": { + "@jamescoyle/vue-icon": "^0.1.2", + "@mdi/js": "^7.4.47", "@memoh/shared": "workspace:*", "@memoh/ui": "workspace:*", "@tailwindcss/vite": "^4.1.18", diff --git a/packages/web/public/logo.png b/packages/web/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7d6543cb5302ece33e652679d7f6b3f71fafb078 GIT binary patch literal 52617 zcmZr3X&{tan~B@LprVK(BV=hRREn}i6QbK@y)~umDWq)kbz6iqO{GE6LJJ{f-=^C} zt5VsQO30plo0;!9@60=9y7$L-znR{7&w0+XZ|4zaZD}@h+QMlfA|f-*HyhiCh={{S zagiy1!2iiKafU=h=7^XZZ`^)Nw4-uroX2hlg;7rRowoWKdT7E5QzZ#wV}`o9Fz$UehoSD!4=8Y$3s`eUo{)~809Qf+Dc@E*OU?Il_##eaFRwz}vf z=5B}V15;}?8du^k^L9uGraqlDQ)KqMzlHbwq@DmjJ)r3lFazQGwsq_qz?dCtk*IXviWA zb(D$pTwl0BW#SD4*1(ijbZq}AG9vX)8aWdf|D=|n#XDseI%SA>YdnI!c}c<+0iX}4 z1A1zbD~9F7`^mqZ^OKf$13ISqH#dPd5Osn?7r_A<*TcfyH+rV>NlmR5>o?-9a#mZU zUyVz`%;~LBXm2ib)ZNo%MBa^#t~O8+EtH%fGIp?m>2jZMh&FChD>4&?CP_WP2Ue)v z!W8Lolq;He%{n}E1Ac7(X@G{GjU0^DhSvyriWAs!9z^&JnJRMiWT-r!8F(O#il1)> z{OT=e_zl11Qr0T~@-7u;kz)pu4HMgH`-%?W9NINsTcn`o9~bO^37VpHIIE%66Qs38 zIwZ!ISU(D_$Kk{=F)D7^2HP%O6eTgSGJs6|Ipyvpz?d1FN51r1>;yX`sU>*w5XmeQ zpCQuS`BfeJZha9Ky$H;%zX>s`t zQD@WAg}k+R&$S&zF9QY|jR9t<0R7E;aGli%ZA*DHl+yqjJPz;1ScZCN+T9qz)rTa2 z2D8sS4<#NTBT}I)GE;JkU?S z{)H0vw0j8m1!OjqDFLsVB@EA}s!qRqO%NXV`CX^RRf`siTsM8aM;IV&dC|+j8H<&j zMXv76ILm*Hxl8<$3GeKByMfUu3Q@e%PPu!L|1@9`0$EqtlwaJ@Olt2gTw*wNP!R%7|P)_j<3uz7p1xdHXH~0lRu6;~chV zgstJ97`l15*tNu2B!^J)R4i$6g6YKT*iYcJkI-p%ta-1*V-%kB#Y%fC!s?cYZCpuK z6Vy%j5N*Llw-@LapstP~ikTy}9oJsy*VMlOQG`-S!oK;|vOG9(&a^IO2CQ8rq91j= zMOcMV-%iyFgHyOj0^3N%s^DxiWlrUl&?7iO?nuGYYtf&vBRIx9=fgng3M(}nk43i|6_jZ-gA{m>^$#N!nB5~!Nk&tfZoBP>tGdUZP1cWmU&Dlb?1YkV>q9^ z(}E)f8=)TpMF*x;3TdU5Ily<5uiufZydC-oKPb)|qvBsaz=79p?=%OA&7|9Etse>l@(|Pr%?zR>?$`i3>BeZ`!d9yl>8Wu=LmEom_OBo|i5ps(-+N z?1jJ1dlOWLFQ|?jONSG}w5Jw?UWT1^g@Z2Kv&+MRkB!C@!gX9B%IpAa z?6S(outEJxtYZ`ZX8&!a98@4!t7E*W6;!@!@@z0om4 z7!%$Fp=N;C^c{f7%--raKD>rIm}_}IWgdqUReX2diGBCh5q&Qx6-*{D^rVy3=b3W| zgZO?p$G1sWA_-Z(-0F7-y-#RfeNc=qZL6Sc;${f^Y}hn!>g< z*8ajO4TO7(kAsue&foUVLR{Gw_tIOXpJVS-nJ^CR7Ws z#Ux-0SwlZDDqT!}0%$Juu<2X0>Ah~QhQ%pxl^*JdHk}8XK1g4OoM;Tq&P9Z^xSQ&Z zB==FhCD&i@pEevK2)FxYcxqI3eu?*`&~8C^(8dGP-Sfe5_GkzdHowlZ2*<(1Fu%Zo zvQ4|4@dc?PQ(Ld{U`P)DnBK;&qoME3nhCTZzWwqK+%*f$0%9VAmD3 z|67Rv6LzSC1EPfhp>r}I%I=519v`oPVn>nE+7@OIisu3lM3v`(1N>^Qp=X36^U8Gb z7Z5}`h{S(+zm(9MI|m1!_Z$@E!=nd9^sdD6{WTsHmL;gbZ`~aL`1YL%BKUhCc}H<4 zzVbS3I@oay(`HAc%5V#bt&jxQL~H_Z=2j$3;e&Hr{3y;q zm8l2^tZSI#b3~#{MGyyBO933^V=v#?8dm%VI1nOwyX)SR$JfPPy}QwHHvCp564pJK zx@igjy@9E%xNDyt1f=h5piV>NOYjqA3G$V5I3nLO|Na88qgy7zzRONyzebD8i(bRk*$Z%+_0FHL7DsSSU7(=)+=E#Qx#Y^Pkq}Q9Cyrq@uRo|%0vMoj&*HPMu@PE z4Gk7#S#1I!Lc;!kl5O+L7U6I6Ubg}Ta($h5Bk|*4uqG`{*n!9jZn5{Jikr)D z^izLMyNlZ@ZB1DCaNQYK48!w9gK#9E@6JmB!%DeR_J2}M;6}?huz)b&ZGYhHL0KCG zQG%P)@bH-piLxX&^`p;UL~+WrI!OVwX969gOV54R=NV-8ZO$b_nrBXUBww})9H!@y z<;R{_b&;xeC=9Ksh(^5d0P#Ya>0f+a;H42TV323{Jzr`b;sNF-@lRF)G^a{{Z8+ab zx?~d_>M4jg02qWSsSM27Tu<{z{=(>k_5smMqy|30!nca#pYxfEY-X6q`z7@-q!P~e zIc~=+q3t|tA=x)20zosTZ?jxP$m3FaVuLp6s}^8YY;#q81%38Vri}O}@VTfTAf!0Y zJ~tPa_r==5qVw=yzEFpS>+`pPwOuK#*XkKXezh@-JUC0!gt*ehz-f%EUGmb@^5eBA{AA%iFt&fSBI!7jvnH}=e|M`WHbyj08w9<_5lBR!7 zT`Qqn$~ni=6<-v4K0EdFmo(YMkIq)47Y~Uy$TF5|+QWbRJ;TXg{&%D|NgmL~ybWec z#n<5+AB7;q7Wl5^2!$`!-@{P&LM=g45E&8nfWju}+XaVy%TU0{L5xd2r2{ZvvD3!BR`MjN>FCWL;4`4TJ zyFgLD%D&?#2rioPfzc8>QS@Czc6nW|*l33J{o9*0ZURb);3yU5QGB!YWpftOgst>#0T?RY<$?0weMsAmqo2JI8RG;fV~ij`mi-*`fN_`v_;w zc7%6)MnO948R8zlzg{gm6RL(Y4R3eQS*}0JMAEOseu7NTqj}35!pM24;p79;?;YlD z)L2XKs4ynx|EMmx?Y4#D)Af&4J@Xd4ezgEj+LUHJk%VlQ_9pOH#W@d7T3)#BGIEue zN#b!rGBg#CZ`t$lQh|f$oqzjMpFTkfa%=WIY5b(vnld&_N7(i5CZdN#Mm26S!!T zzMBd9Yme6sr-^@rRe3R#p)X+Yv%|g9_(o!o%)oQGhN##uP@8Cp9ttKr(Dwx7R!q~} zHobjb`nrD~^({JTVE%C>L+AN~t>w=yFvMesT=atbc+^3famnW9rOyk}7ubRAOt65( z)YAU6<-_PA-9zRvi=hL6;ahhHGtSP-M8^bKAVCt|w9vGXZI?(_|2G(&2#nyTqqzCO zUZqBaB2m2yF-dxL@@E8{dc;9K$0i9Ud{XAk+)xYt|Th0`PFC41JxPq%A1i|k^}bK^&iyxa%^pL!fZ z<~f?PXU4EIo`kWPNlI*XiF@lID$e7%j^f-GzKh&!Ig6-^gZx{ z_H;nyZu>_(-hfBvrF*9EAWuLAmAvkq{%Fw)^U}`?YSGJ}adsSkSiLqj)P?VU@mOPE z`kM#9^|^I9!BgklwM;mqMEaShNxC;{vk@0QW~*3UmnduO;%C)FW7Xs%FaB7M2>A$< zLfqRw-S{zVBb!i!3*=oVpbmT87c3{1BH6Xes7Iv?`(*m96-~yq2oDvYkee&P ziNp)7I0mj}hjt+h@C&UtU-MEWh|`?q0kwTOE)K{qVIC$F37RkJD{$&UTMV<=X{-z2U(qoN-GWwmL|c_eia21fn9s<07s~$XV-%N_-(M{woTHl znqCJkM>(q#qW!?J%=28pa8I0i27u$+!BjJ5>VNP6au42Rr}+!A38=Uu&kf;u%zJE#QEFx@=E`Q^DK`!WEMYR?x-gL$&@MrvHB+y&jNW>m)iV$g50! zv7;bv)GFYfcY|%K@nk$NbAq9x4=M$54cFT7ECP-rIHf6&V`ZNEgL*sW&VQeBZ3M3X z%QPg!k3{SapyuGYfZ69fZhH(VMrS!?ubp(bk{3K)4Q1-o=gVCW@HJ4RXE}gP@!tBs zYDqxS8{`{&sYnapA&eO(){o^75W?;N!t}cxD$wV&(077I*Io$-V>smabu zpkjI~Cvyb(NR;3^treAl9w9@*+9JZ|7H*0K`}$@l0953kb_4-uW%yEX?W;Ecpcz_0 zT^j9J!5eWdPt5N+8J_V6l~?caRk(@Z?iNE`v_=^`9Gt@Dzwv2#f-ZjM0^skKAWohN zSR3jA7YW8=4_U@`L!YD5i+E9cglU4?e42UrDq88mg|ST37vSf_iD7iyi6gYlDZ?W60#w+jo5RLMez7$q)cB{FAyW7U`jQYVx=1iiaDIWf zqG&ufGxfLT1nj5vpf`HhM7|#3;--AQHRd7I8o^U}nGJmR?yk9^79X-Ru=1H{n2$0r ztrgi1{-c$MSR>P&H9LP(=g0;bo-qTw%6EQ4?z3JdGrVZ1xzhCJy0hf!tVptDU5?5e znTO2p3atGO#Q5PGPW3YxFZI8v=R;imms8#T-W;=_t-2KXzPm+5qJ3de18Wm@3`SCQqI><&*DL70mlKDkE>sS4co;Ru8`t*ZiLu(lQV|Cx7tT2h)0Pqiq z{!+%_Hk?T~&gYGsEpT+rsaQUgIx2RQTTZ~y{g+6qiFIM82z_K zE&Eyu$59zO#y1bxi%CloED%}rAf4MIBh$dmn!`U_y%`EYBk#Cf5Mms2l5hg&*m*A@ zJj<~DfM?A|bzUMKG~{DBaNOZj4N zq^D0D9=`co8VG?fFuhet{So@IbQmi=k*y4| zAZ%h=1K4(qHvHnZoDO;$9T)h-x&9TRPK1qf@p46aYT5>RFvCDw#doiT z^DHvFcyh5S5bW;^zQS>iAh_}cViz<~#7JYjG#A0mQ%Jm&05XyZf8W0W@O zvadfur(1b7FA!p%bY9fRR0WG}McuE;C;wHkPy7h&0(fU{mhA@RO#Pebvf=y5y|Rb$ zlWFERPaV?SHn510tvRGbPtBJ!N?NXEOmxUUOIEBdivL^{KAl!t5m*NyZ%E&Q205eV z_9C{d(q*sVq~Sc{qBgf;9iNdHM9+bW;6Ew7z70K@K|#rVpMz#I0$B~?S4w_(4YcoQ z`PtChU$Qiht>LA3;zNI0^5-h8aG4{X-Su-B{RZyrIhC(YL_Zzc@;WsVQ?mA$(u-SO zRxG5R$I#rqw(}K1ct7-kLQ0{$MJfBt?UsMoA_6(>ZkpiB2X(-X{g7b}uPQ%Y&J9e8( zkOif8O*}hCh7`{_6ctI{&|)hu%Lp9Y7cavI9DjQKgRTcf9bk2y6_}9Wj(FG=Bq6zQPb40^xXvw; z;^X@e5)<_Un2X@}=6}JPBV6w+uY~ORkeI zu$Z341M@iKdB%la$35=F=~G2r_^ZVI2~SgeP^q6fHl?8Tgx7hG+p9b%8BT+W^s&dQ zQ?a^09_08dm^q!3g(!;gy*}y*120zScrMAUA@L%cmKc_3v z@2vk-3jeZ!1E00VKHf1Q>e?UMO!0Y`t7%hJ6&Y@Hz+X%Az(@PmcDri^9CnBf>8BIv z(deT{s8P6F$%x=4+DG76gfgIAFPKD=i8QhF6azK z$4|L|um^vwE@{dvt}-FUvc4X!wim1KnXF6-_#V=(NY5URf>j1)E0F?TC&Pbgwkq5F zd>>?|_Ds`wX&B&i4#Y zgWDyy>4Q9mOm1h_gy+W0McnherBtA^3xA4`S)l|=%kRwRFO5;4N{nky{s2WGC-cdV zPer3Cm3W5B5K?KAm^YSoV!_VS>6KWK92aM?cN*ZYdTx?Uv19($GK0#*YweL9A9e4< z^R!&I4P(J#Fmr!;O z?tQSvlheHTN?6B`TJG|F20L8R+?41wgR>Or$@>>Dj!HMoW4N~uv_Shql6rc`hy$(k z$>+1=yyVHW(%x5&6d&&ZEuYDHS@hOM^k{GF(iZUp5y40FO=BE+f#PY0TVIK9=wQ@pIYULxD1Np z4{jT?42X=wa{*WmZA83-@5W*uPJ%x+%k zsyIi2%6EH~xf*{>s8?mz8GsOPF%w9v@*w23n9WpnRzNNXmy*~A6zFv$YyqDr!KAZGb@=^8Zz><#gte)HugS@96Y`*n0We4@^xE9y1_U@ z6Rh%kQ%Y}Ji!ZG-l2c?%Obf6CZ)~^&h-zMVaNZW@a>7<=+UA{#q(isD$yXd?8SXLP zQ~T=2U%@Z3iw}Tok9-E{ZI6VKn@7mwv*h~VBgRCpz#k;ih)V-oONs8nF2oc>tieLY zcv}cNn^x*Dq&vXz+rMC_B}zKC zU(Cd6jd6}lZu=%q7H4k|ohRlV#~el9^IbC@;*gUo)MSH`IVU?b4WXCcWWy(xIRQ$o zJeu!9$(^;notU>3Aj)l%D{i~hs`SYJAo)pPW@Vshd2Nf@8541}%R&}jE=M`I6(&XIYK`ULK zHHdlja?l}hOzfPO$A6Y=*4CoXzWMDn!Q44DcRKeXh0ZdN!;S7{xW_c5)|QC{@)+`B zL66q{oqX8H2(tKa`4Y zjJ+|I=ltaazU6`_HY8r&k2`TpQK&lX)J+@*PjfpM=@>alIOmBim*yh`pG*6R54mKFYZZ3Wn?<&5b zyN`4HcJIzH-!T2Jw~ACwznNd3U;8Wg=TrsOByg2No(-81jfz7_-KUy!4jgoWp4ap> z!254^uj98#L(+u9*I4PO)VtMn9Tv_AB(k|UaW@8KqV#6g8iAfa9NUnb%W;60J4e^y z*@R<5Tp z*NEx=yV2k9%y;A_yj*|xf4DM0ux3tc#W0<<93nePI*Eeeu)Eh!HYI#HC+P> zMO`zkl_9u*n2sjAdDv$%-&70o=P}^Vmq(=41QTtB9)wZ!ohkt}$@7hpmvGH>*Ur$N zM@;B90E=3iRP+cCuKoL+Bjygo_Wx{XF!JRG1H46$r8^9U@O=A*?MEUYK{@ak{H)+s z+dMM+<5TvY=+b@i1JA)hqpOMPhY&QpDcVNppWF`7CA)c!r94%>ju(LtNsM%vD z8@$A^`WhwrK1camBZE>K+D`11T`)6r6VO&$iu!Rit(2_yc+Fwz>SF&jgM}ZSRUNQn zztr!T4vEgeuU6pJ{cW}(cgqi>_{yM7iVA&C;%oNzhA9l*)}&WCK7Nrr_u%~wi;1G8 zl7uztCct=$nFXSs9W?13GBt8y{elV&LSJzDYZtP{XMI6eow&@%{eb+9mnzVXP_%9v z-oAoyWs+t>F#4$s4XAlm(@2%~8Z}SsC_i7VjRJRG)8fBwKk=Ftiwlt;vGoAp zmjPP$1=9#jJb9#qqLivr%kWyd(A}pO(A0}M6<>xCq`$|MG*vgBE@={#R*+=a?@Wy% z%OCr?kyd)b>9{wg*Dh`BNl8;;$auFRJ-T5$4nC&^@0h`8VBLxjBNq++behYE8&>?) zs3*?tn}SnbO<>Lrsj)g$+t9f2$CDKl`LgxPNCDRUEyUhn=?#nF* zcCxMEXFhoQ5ZY@Z?;^CXp3*AZMq&!Szg|r8-LyH2aFFpGP&Cf%dAfDv&*941BfThG z`KAux3a5k{t^~P)g$Q~h?aL_WY>cFpKKKDv+HR1&)FwA@OMx;i+cCh1(wkK?wn1{_ zq(VNCG@@WoYof+EuEKsfzxSL%9i&4#Sw+i9KmE2)F0yWnFxgXw9s_Cet&Xza@T|4@ttQ*Gvtb&7AWK%_thok`s|l5 zIuOFC-n>6oYAkFy+A=PR{ZW%{HFj33oiq}``O%)Yr0pHbJc|sxz6r{Hca161$}GTc<~ahNo2A^CphW_7y!NIngt12TclIN$T7=k z=3!Y*xof4Xr-Og)-(gDBI#%DONRQ_*Tug`tz1i^!jPcfn6ONQ#rI4ZA6_kHo(g>VU zyAbfF5dlk@N{j;gItbUHSSm^wlEhp+sjbosM9%8eke52nU7s&$fpBIri^tz}L%Qs9 z1BY7DG`Z;em?Axd?O&`y8tL+4Nz+OVSXW$3i4Xl%NxM6oWEszbIb$1W8Sc=`B}pqy zae5pR5@pzT{e9pjXAx1m|3b?igqA!lq2@g2<%BkbL24L6OViCu7@$BvnLDBPal(kb z0PDumcagvctuI%#OytWs_XAQ+}R&{GQ4P-dwomwspadA$PmL|Pu zX2_Ho8a+=N25mveWU8xz;hn1w4DA$242=sf-YaTf9MYr*&Gwytbqqb`kXZe3mE!C zyA9+S5gjp?aBC}LnV=yNb_t2w$LALoq;6XWYS?)Xfz!W^y_?b-#A$`ZRF;Pl{YOSP zdDdVJ@=K@~p_aAZ~mgkv#u2(Lr9SGw{>OBa>n%xAn1I8CcfWQ83 z>&b!?*_9p2!c5mcfIq1s{X|^H>8LlNwtS4NR8`cQ_v;H%MO2SzdRR=uM z7g{|O^70VrAVT?T5iIOmdrOo5d-#y9DT<}Cn9mS$gQ>6Z5ZK)m3OM*LZ6OwoYkPYS zZTGJ$cVtUoGoPJVtpEKfa89%-R<}bJpUnKCrRV2EUgyb1N=C>p4Vrl_`x>n@@r->W z+4RNnVjp?dW0R7qnO&3HWciySf0*em?x*E=mOK~@xnWPp|4I96nG(DE8V#fvtHMoI zg&V&*bx@MgIeqW9NL{HkCoGGJLE$Ftje&sB#=HcFyAycA75Q(1DRS(WbZ~Funle4o z4yxcN$IlIV91sM3OI@~Dg9Cm(+$FINgQBFe^u3up`oJx(4!pBtF`Q@WUgI zId?Y#H7MD;_Ue+tKAI8@28}psq>+%|Mog1Oam*=_4$?-=CI+J_U??D?iRUE@H#t`o zuU|w8Q_@&s2vN{UPM|Syb|6QSl-qNGRYDnhGMQ%H$Aq-~7!wlhUhL+#D=5|bq4_U3 z<6`L$i{1?>)t?6AW?&?S*EP&%ta__R+P&OwAFbqE^tCf)++L1Ivf-NlI`2fc+{Dv& zYK;Ntn>7Q@yI=bLBK*AC1V6r3xeH2;*B>kPWr;IyGzCvZ^O|72Su^#7-7Rik#Q+G? zmlN4*`N%`O!fS}5P6Gm|7i`zS-LZFq4RNc%gZy$d_BepSyg(4X;Yw8lj!({cF|hhC z7aqhoCn9&`3nXLpGR8dSdr)jFq#6C;d&`WK6|#qdC?B=9uzrsI$>@Lm2g`P}PV$hJ zF-4LgKe{?9xLT3I`h(Ru%2iig^AC;||1G7O*zd*J(b5$eWD2t+Hryj89EvHSs94<2 zD1TtXjBFjI;NDw7>=iPSjcy|5z;fgn4LUCoH^Uf9IGv(Kg0b@{ky#88&O+n@D z`s_QaB7)yvE3m2FY!JbK+DDp#_QX3bv>OS!;SbP9wD*nt>Q>=bQ&Agw%Q`er%V|yp&@R;OGBmFT%QC+)1fB6mbczWsV5J0f zuYt?8cj2Z}dUMTZbT8Oa$yo#Gb<7r_58I))VAqe#>xHVkE8-K+P)@7>B%#H(L2yn> zDAR$!-h$R%i9jkfal;!}y&s2m^D`Hpz}ee1HnSaNMi+>>P3#C;C+q>Lx~2{GM+Wdi zbe@Evh`U7v1nk2)EtJrF^k6Xf$4jrUC669#h&vI%bmXwec|bx|#)I+Q{dW!^ky|q! z8B?;c+?054r3MPzs8v%gWsDX&sqS}^he`vJoV6q2WVd=_yOh|K52nP)bsH&?A2^{D zn=2Aw9RuCZS58&9C3$S18(LB-SlN&Q=5S%s(4=veJOlSS9o|oO}8QL@&sD3UtmszK<6NEGlqaSI}I^kkl#6o^S$6L zO=>RqVDEk;4S<(Ty(JbXoP53y6}=Spxt+QPu`W73rBTl@;1;=s4fz##|bZibUzu`ic2SyY%38O2hTj}Bak-np?HnxXB#1?=g8;*>CL zK$E{i_n+#A(oP6GYgS6IMPIMpg9DSb9Ba6*G3~|s`8^lfx+lM%diK7MVuTC5|9LiKM4nlO&(ys)>&t<_uq!i4LxVv=7*ag!JzmU zs}`*`q8>QC-VIk)+D4)peD~`ObP#x_>ZZZSfo9bN{BAcF?yJ`TqK;JkO|SXq<9@(U z;T;W69VEFLhWCSse#C!7%EEbSZLv^4Vlx;Zy_T8^xc$&4SthLG-k^(<2P#r|4b%Ah zTzcdnDO|rgP%!yPJuY^16ZW$%$R!n=e8Ryo>pHJY8rPr9T5vF0*we}kfOeN8Y3A-f zzgIN`9GNly#I>5<(~}FGD7~$BG&af9eq#GkG7_D%&M%5JEH|N$vhqIDC694t?=~iO zkF`RH;KFPtQ?;nTo%%~@vxj?3D7}3KkjLr07@q@Wwy#meI$$(}rrT^=~>eWIZ*9=F(9==P%6DF`$OQ_$$Tt(5V zz6`})J8N8hP?7GDx$SjsB6wjNz=}FH=Cuzh(c6}+x+IF1EVeZh^Z08j6lUvZP*~R{F+k+nAV+TA5}vt<;h;w)pY^ ziFIMCwn{PF=RW<5S2D)#r~pjNU1Fd3jUtAPDC?N75eWSqLMdXd2%|_|{zkI_T+k7w z9(E`?9LnnBFaFIKgs3E?1RG4dc;5zm(3ThB374z)L-TN(0n@@z3w6DG5m-gTe_w6w zhB{54u5l#i1HaXYM+9UkrltUq?3J5%_tdz6MK~Fr!q}t{HLUDAq>lrP=WV$^tL1iC z+p*rEfDtJS($SUqZ%>s_T90IBI#rlZG9HY^o!CHqQzxIgra{&2*x(AYE0QakpOqNY z`;?!8b}^2Z7Ac@k9U6`*#=9P@pm>g7v)fl`-!&wwnKu5w-;`(+BiA)>KicU$*)y;T zvZW{GeS^3H_r)vyfs@u-9~HQg9Ap$f##Vst!}=j5$bOB5Y%g|F49RNHqR$>~1wnHe zWsydXC={I~d*&Vr`;|G4=K>@cwWFg%s93xOH{TJ`WdZH+#uQS2`}1J2=4E9AoE*6N z__5f_>Dn7|qxaS?Yi(=3#&iUKiQEFp#(rqUuGKnt5*ata7&YN$?CbbKt+v z{}R5ED=`1dIfif_PonTv=g$AyJk#m7>y2FRQB0sa5oa;&4Wjcfz4rV3uLuXjAf7G& zRuh>2b@fW9>jZP5jd}CG$Rly@iB+P%_9~KL+;$9{FLCv(p&bZw-E+uNbd0^D6hEew zI%X>{F8M8B*w+V{QF=dehM^>-Tzu4)(krWVJg8RbWib1-Rt`AkR$4_XNI%o|l^MJ~ zNrY>!m2gpeNO}b&Ret&2lG>sMW8%(KO~vTxth~>;L0-D2-~6cYSGue&{oO~cq90mP zvue_yd$BOkfztcVzYf%NdzRb2lE-5Zb(ceJ%kz;ec4cD5sFCNR52%3AWib~*B0v?i zmPUqVPN3Wp1XI82(N}cDEJ5q@n-&*? z&c2$If!`_F zilnZLc~CxHI!pHRt1emE7qix$-s$-eLcA(gM*A$cH%t5SN4&QV+PA+@E{jN(`y6M& zJc64s9tBafyctF%0YWbKVfj`*LL8agWKkoURd9#c$DMKma+D<=XT_JF#ack6>FPluKOepWa?`T5Sm`2qteJ5F++r>D<1~ny@|qC znIUM0R^ou&;O9~gPZ6$di%nSy-VWV*pM4S$GdvU0j@`h4TbZJb0pe!t@vJq_`nAiH zsO06}(`yk{vNUV(gS1R?`6_TJ-8}S;Z6`QLKa7l+wsD2nJJp`N26bBLqvF2i3j?zH z-%2ObUbXoDI%_OHnESeUL3!*G=xl0Kz9b{C(hM9dpLYte zW9wN~PG6vnX*?IwTFFjjCdA^N_fXpye^ZT*8bTn=R)B|#gbBFnf0X(D5Qyv0c>opS47c4{|Uf24IbbB~LOR%){ z#X){P4jwRj2!34uss(8x-5WFU7u)Bj8}OH>K7x?tdYz}n``X?1a4{C*=d(}M9j_&U zb@hQxzZv7(Kzz5AnyIb}DrPJn^-V6%gpM(rM`y{`N8g;evhZTS)mgt06i0kv*iAEjmoqSWY^LmzMo#TJ_eF@=>#X9%K1yPl`_>x;<4HMIOv! zZB7iCo*!M3;Y2U>=nST0_;*6f;b9kOOss$y^m!7r8-n^@H5vHFQkGVF%2S1OC|?tr zgnMY_ws|GDJ(Ngco)V0XqspX1qw%-MB$xV!L&;D*# ziqFX4$&%aQ@IPpYzBr~)WxCTst*T;U@jlL2E~hGjzOpx(+WStmj8m=GGV6NLHqkS9 z_<*Akqxc0xao1|BWdwh~8?7fcWd^F^Pr0=fe;_bg52UjXH0Jg9?@>cX`fsE4;OR?ThlZ>{+0kJCEm90fu_hXG#$5YgD2ke7&ymNB*W*aTO5%Aa5Aarc$4}jHrL_g3e|?ok;`OfI=GJi|*j-3Di4Jh%pk;M~pcnyN9zfYs08@Jyb=J|OFD+p(9zk5aQslxv<`OYX#YyXrf zG)bqIumjtPnh9nq_0;Di9H2+jj!pERQ~v^Ea%Mn($kW4r4&x{c#fZ^VqzCVY8wPoh zaF}!1v+Q|>zvb=rirYSA#j|$Yv3d6^^G{9Vr5QCH&tCPrq53!$)e%)M-yY(d3oUIrtTxv7;eKD;tt6P_*eggD>=PFP$;ma7S zqK~8OI+06Vsc?3@J;S)`)}_xbSA24ke!_)ZNm$>RB#ip%!bW z0|zq`jNDyj3qRm8cqKAXNw+6&xPxUMsjp>&^OHjE9UzUDp6sfG8%s78U7jmXEJ_V% zTdA<;^qYibcD3%C=}!x1?OlMm-0n1@Z~rMU1oz%9N1Y&3#59j~FJg?J=?>XP>5VTM z`%-c{pxu*_5%>}u_0AJJmFR^h_fve*JK*Yq*Kr6NRMJ9RC_YbT>KYR(oI-*qKEu}! zmQb8B!d7-43%Oe7<=H;J4sI>I^nfa7wqwyk#!=STFLE_|6Dfe{TLEbv-_As6#hSj3 zR$7);ydPYPXE(#h^<$^E&`KxCA2Xsz(sCo8u677Hf{I7u^buVqsEtC6=+`An^PT+a zLYHP$Cm3>UbDxyUnc#k+_urvj6P9IHJYb1?34mHYbr(Nb$rW_&C4f(T?mu(?leB`J zqB!aOrw?=Q9O9j#xb~7$X&jqagc@6oCRh(g5#>69-<;iWxf1mL{Xjlw70%io0 zfFE@=x`e!BV{NY9lLh5eE0cK=hX=2AV4O+i_TV4WP(i+Y$`9|@^QO+oPrs#_)4SXfdPW-0Ix;d-S-|McEI# zvunVO@%(kZ-5l=T@cxcK3B|t(ZYY35Ql0aWvo(F~36C)H6%XlqN0qOH88?^^g92z4 zkEA^mK@l_;_8s~%!~S~bd5L8oii<67cRIahbi4%L#Y@^KDJ+X)ULAP;ul0S|(fd_M zrSfH$SS3r37jLw!K1=>*G9(^jj_+aksock<2$w=En)U#l>S1KUzzkXyL~A9vg%uC z9`-*+PPMO!B6}7GX^~3%kLM6$Oq}Z5kPn)1_5`cDGVNwa{8jUx{v}IeTE})>OFc?6 z_bX;U+sKjYXC1H^^?wfjOHv zbWs*c1$4>^UBEdqr;K|OyfOyZsPz!4S6#oGR&EZhijL8Q(^ zFwGgeZZ?9?E#zt^-mWhegJ*i$&RX!Y~Rucv{Xm$;Xk%%T%vu(qUgf~q<1x=)v`_K;%e4=`qHtfsV1S5=1li4P^H9o@ffghRzX?d0du>vpf& z3N5PYV;&CC9;99IO`I{drzCF%t52stxN1X2d)_r7Y4@O)jQ*CWw?oQg zalx&LpL5kY79pT1=}P&uA3h5h9UUD|A zq3d$V(%ftNTju7lHc2y#Iek~m%hO)p?uXW}xJT=)RJ?C9W3>uYNo#sbi*i>}-*iWm zr&R4xnxtTF5oWW)rE%Y_@Z{1CxK4h@qoza|;?qaj;Eo!@Jt=ltcFAoA5b9M9Azf`p zA4ZVp0~@eAk8y(aEnh8)(ij^GW>B1VI>2}O$*gebZ-Q#^{!5O>eXBqAdv));Q(VQa z-@E@Nr|Rv}LZ{wMJ_c?coJUu-^j3~%G`-)y8ywI}IyPY)X60Js+nhD$jH~xQyYO=~ zi>mRLa4VkT+u}m4-1oCAWm)P~BF!mkY=$;iDsZZk{PrdShKdx`C*e3y6k0DwY zPnric7~YkM3BoexBSrmpx6FU?*DYWK87~vT4ny*8!%mFu&M0|zD{t0wo-N}2$rUb7 zF!dl_e0g{_4De6bAsRH{j$m3w0}=$DjRZNaXF5T0E`vc)O0NCwU4Z}?y5sJ0>xmJT zAniwY-dxND*Ljq%mMiIKTlo7ClbFA1Pgz(>wvI--5>+}^{O={qQdwe)=-P58K6qbr zXdyxu8sOUtbOv^-w9uVr3O;D6#A8QrU1W`b!vvbo^{F3v9@ zoEOYD;UTnqp7lhQ9opU<`_E14d|DD5A#wqp@h)cc0t{^7&(J zw1&1k&C_paXX4sp&uD!nzw_OkX|i&6>{8S zh$M4`ID5Uve zm4l-hnnpvkIxoBS49zOv#FXF%mu&Vv+;v;BG%6S_Ixkc&hnkk;hWqmm-tV$J!W9KH z*jx{vcnnd-#1#(b`-HaNa`os6hyBx2mHa!7JW0iSz@vFYS95a=*Ou9=66=0YSu(t#x=i~bEyg*f#uJv zPZk0?gFoqE{blrjGH88!K_g9(3ZhrQ4%U>lkrq?_V zrjR=BeQ(ehSlH^M{?|P|pvMWOQiNlu*Xg#yhuHUV{FQ&h0Iq?oE3f^cBLT@v2b6ip%Vw zzP1^xqI=7=Oo(+)U@qyJR(102&at;m2_dutk`5e4ALh{y{oNd$c-_JQ=v}R82v`IC zb-;8iU+8*Re*^}YF5B;Wn*HHbp>$h=owBPs82kU3sC~Es-h?#D1%|c0->RI|yA8C= zALQjXmwsHej#cco^9~F?HNFC=$KLvA=s%W6N#oL+hxUF*u`HK$>1|IN?ks8A$r*bM zeJh0>1~4hL$#K$TxK{gjl=-w(^pxYbP1FUHAckTtA3!Mo`;6Uvb9nC2Z!>mzf6IqU zA47o|yMlkq2j>G&%d?KI$-?6~p&&z`L7BH0%tgZoju26^$-Q=)`Gbhm4IxJG-F1cWAmG*tBvAo zR-x$LnD{U;Dygay9Bqxux}*EF&uG8$ zdOzjj<+s=KANYoCu*^i&T?2<}wjOI6zuD}l*kNHFzsq95rgR zN}Q3OdMJk7V3ur~2eU9brHMA9s~N_LOfPZ~UTU1neLQ=1y+ppZgzY$vv*YnVX)0F^-YAIN1^`G&fD$vz(Wbl(fFUv%? zG!Z)e^h(`qdABFi*NX~tOG9NBCcAcRfg)stiJ_pIiB!KL+B9dG)o*!8ZoTmy+EjR! zFOw)1$2IxC&GLmm0RVvk&J@@z-;yqORQ7v&GZH2kO5`pFu`kbp6kW-#?wyvZ5{zd| zg|Wk{Nnv{9ALKM0Dh7t~*LM0q@s%0)y{hY~MYYaoe3bFGMIVShZ&utI@oRQz^?q9> zuF%COEo*t_QS1`bx3%uVz31Ik4a3!%beEv-Zh7QUr}wPxmR*cJg2QL)81q9|8n_iKYe+G{JmUaktzvdJ z2fA=GTN>sv3i_p?N$UKv{TCb5l=qex%dt!LOa2-7_%$R9GGYGDyk$XBi8W#5(ZrK% zZr+fbm9r$|^sJ#**JB;B%a<$Bmvq9HFD`XCFb7+QbZCC~!TG?O(95EE>Rhtwm;~r= zCGotvv)eUcw#6Nd?3WjQ#z4Q^hQbk_Btl|1n^o-%P75i-UoJHaMkA~_2!*DcYJZZw zMO8beFmtT~>Uex==Q!_P!N9ySCJC<@+?Dr7 zC1o6$=O>V#1VO$YYuzWf+bvWP#I)2^$mTlt_VVvi3t5+i5QVrE{JCBrP=L8K@41@g zPjEqY_+E?Q*`?D`=@X4f)U^<3s2q<%rG4n<_SvtnJQfWAGt;D{Le0N)<04z{q>87j zw|2*su6P;OS>twWhd(P;k-l1Ped`sc{z8c6o2GM~KeZs9{8p86oC?9D4GI_T98V8h zUHRPcHmRqf>mMQLuwQE3=)SJlnAm$CLWl%3Y($Utrx z%7#s@5MZV>WPMo;c_&J{y7JK4$}ixAKB$Q>e8kw76m(AL_7o5eE1yAl^{>&<{N{t- zMn_ZordLkfmk<~o4HHn%RkaDp;*O4<7v1{Tf5j+*t>gGxcO=rW$&PsIxGQgZr(S-j z%Y<&f3vE#8sbim@dBJFEC4Nzv$AH_xzdiPk$?*winX9-kr^gjdB&wR}4{iW9mHLn$ z%oIiOGAh{@_vRPRg9b={$N4oSWfet_4nhj=fC1cPgf{=TdktR1rMit)^m$ix551-Y zq)XLo=BS$i0m0(KNT5h0?;&%Q*GAAY62=C(Y^=*VTby|;O=_RWcBPgi&PNHD-; ztXr9zSFn(=d@MQ`ZrsGTE750X?JMc8_)zS1 z?s8b`4XK}bCdE66iEtgEt3h?^&b=j%KMZuI?NEuSSEdyelu)W*3fi@g#zcv&?n(|E zxY#-PeKBdIuwvYm(tA!eM1wTKswi4T8aY`}xRmshX2w$KtA<7vogEx^xzy5|s~k9L zTmRqImB&M!|9>MEWup`-l^mlaG;LANwj@VL&T`Dwq(jOI<%pSWzg>z&(vYK*5K1J% z?6ztoM>?FL4Ow^Y+wb+B&u3;n?C+m_WM}5{dB0z;*ZcK;9naV6rIe2XOxlwheoDW> zo9_oPyz~5c?gtgPE1KduE;@7bS7|ig=B4?N?l43NNS~&R9#Kj5e1|#F zLsf(|eqB61t55}A!8zP*$fJ3-qMA50lsXH;yWmSNG0Lb zM|NUo=R}WD_0ecg>CpezGHEeqt}^>%0V=I>Kl}`=wFB!l&-8@^e>=S9h!%TY#VK3B ziI~_uaD0jwb-P**F*qmU$cvN!JB5nr8}?_Iv;f(cp&}?BYD}0m6=xa*zBf~hG&nnuVN9NxSv|E2 zYF36dm>)|fV~0KW6fvRaEN@a5#@JWnM8agI0Tgt3t=AbL0I2A|Ih~+w)Tsipi=vty z^Gc_18DLzZ8_t>vjVb1vN%VA%wwT+iTtSw9mk@fDH`udKKWxG^L;XQ8Yqdamb7(d{ zSi#XRZW;n~)-BKl-vTH6`Cbk58vo1@J%%F$Ez0}rHe(6RHnl`T+wuVvqpm#{&6!@{ zSo?;_WVu{t-^=%3LpgRs+3Pa&5ml>Oy#9U0u^Xu)+nn|-gp+f+?MsYX?cljIi&1Us zME8kmTLo|^AV&PhkAYbpaPU^F^`jYIFO2_U4IbS=v(?V7uH*x%88L@8y-GTebv6A! z+;HN|xv1UVGKx{{u9}eQH4t80`}z46%GS6&O{T7GCKa`{Mfw!Sr`03Dy%`qO&hMLy z72XZ{zr5cK;ls=M+D`ipzAKVi0V9;$s)l;wD97qAnMaYW)cY# z^te1nJrqA0$UL7sSfn0a{X*U)f*o=ya62txC@U0t$3aYTqUPh)vUp~8Z9)?#6j35~ ztV|TRWPEm=Dekvjkj~`Km|%>dLo?FjV?hlP+%_llxM|7F&rs)eCJnFi;xSN%^rMu# zCkp0$mewa+$b^aB5PPJCHKXcLINh^*+PvizQw=Pt&dyBkdGvlY<|D?dbNq)6+|D$`w6G9j|MAW-|a-p>yv$qo9tZ zqvnda!q{G|iw$n3B~#+}N3M21Xlix5-p!`ve=k+Kb6lw2%vmc~=E#$pOWPv-rF|5- zeKNJeyCJgq;}c84NU62=Pfj;F1gGSUZMC?k*1@KEiD*S!2%B+{HCdl@@?{o*>_}xp zL>Ur@tjj=ll^7h{!%^joUlt_ewP(2~A?d6cXo3mPRbrcbAyGLn;dRrYE)FUij?8{K z^&i1Vh!;&>&E~_MInN-kNi>1_RJfSVddY^N|U)uRezvi}kK*F!3d zH}8I&|&;b)rSBwPH?e4t{F;8)xoq+Svv zRv9!SeLS+{JH#4Z%2dwo>;@o@B-T+8`WfGL{N!>Kiy`%?;BuHf^c-ZyOVOSqOPB_! zJVpA5M*@<7x4OciN!TVBYi12tXGFra6K`G&&DF*2sXL=w$8Njt7(ZlXx-<46G&fX} z4rxDq=WbZ>ouAZ8BlWUE>oU99!qNlRb{`I(*t&XabxVDHjE6CK_2^&uijiTH)$Vu8 z0!Ksajmg2jUv0xnS|sEI7^~*n*e+!bW_l|t3+>t}U_RK5Mt=|%Ye;Pte4}Cr7$=z2 z?nT5oO)as)|I9=^^~C;2!X zraZ1-|F~sCwVB6?^ljfhcegfz5Qu@H(Lc}w2KJAAL{5{RoeP_!byF)N&F0P(KLruB z*C<8Y9%r~Y<8H`xqX8XqxMRz-eVN(&*W+2qW;E++2$D$%u9tKGwR7*MjQ8eu(qm)> z`)Mu%uQS#imR1fgD|-n^_Tcx~Or!T55r2RGW_Ds1d7ur3%Nb?AOUu{Q0aN#c)`Xk2 zZ5Ep*tYK@mSU!`?$n!H`D^0j;i}iS=7M_w4GZNj30F|X#WcB)|YF61V;#;`{a9;wm zaQRy+1r|h$`Naz`rWYi0%V4;)uCb;5G>_%1Gsv5MhFcbz%SqP&XmJKCm4evk1pFi8 zq;MA=ZSO*TJ0u*`aqDMXDG{ZCxeTTN8J8(n!-y4E5+vuiZ^ZtQv_!U8pzr!h|GC*f z+5geW0MkIozUhVrf-`KW#X|`XuLZ!3v1T-`+s<+GL)fDoVaaJ9V$#=h$n(H!xM0t^ z(tx$f!F#S>+pQdEZfck%^l5Ehx`fM$M{SB_{wrJFNVu+KI(<*FHzN0rvp>EwYMeL% zC&fMRa)U=|o4wP(gzgP;pyW}Zj=WHFPCc+%ZO4%ZIR#FU8`3|NHC?%U;_Z>}H;%R^ zl=>gXHm!u->;t{mwhTOuP3J(|7KwcrxMcpS%4^;Iv3jZ>rFZCc2D9QD0CG!5)b3yX zpX2I$QSl&wTr<~Ia|{=uT}p}2GG!QokGa7*X9)T$(}jf1Atwn=z)@%ri8+8#o}n(> zML#E^Md3#Cs16kxIY)5;N1=!K2`x{nC2YiyMfCBl+1K*6ui(b2?ln8!A+qX2^>N>nwU@899IkX+ zu_6{s4wqZf%ft5B!@e}@Xuqe-6u-|+%8%=->p$Ajth*t2sxJ$wvhjjNsb-4Z4=SEV=S(|pr3R^A7HV41*;)Ama>@n_bavi zdp^Hdq-?#s&^)FzaG_P=a%!0=&S&zv#AAdbGYs*7+|`>$;LOC);|NqolFiT)6ZaCx zO*aaCtW}bgNO{4-SledJXJG{a!AI7A z(}!N+8q~RXENX?|`4s{^&v$5Xk2d!e=cTM*l4m#ER5?eEDHAqQw={D(rh+N~a7A5k z=>~Q-h3wW*i9xl6C@d;jVB2uu)Gj6KDBz~5sa$bPs}*#{zN;lTe@&kUBQISs60)Qo zZT0mN6)d5~sU*l5^^WyT+$nP!3m<{J`R3{k75Opa`^${eL(eEvGQZmOJQGIfrM&0* zk=L$WW4D~wg52|D$u+J;8)2y|EoM|orj5&d<+F5MX>H z#`&J%SSMz(qH*Br8atX0)*}E z>q4k8%Ksz&vvxwo-7+v)*tEiZM&yt&H9#S#15|W0YSTu>+lp7;-9fW%*|gEE8)(pM z!9WNY-PcV4n;x3&jNO`-y_9*~52~Qt1{@-E;+xWQ?vynY=IT*uL!qjAA6&D)fd6q= z#k%&`86xyY-bWYlf52g0VzuBEutc*#CQ^s8i4!2U zlI(FISPwxZr$uRpaa}PbnoCGuFiOqZ zKLY(JozA@PjWTZ>cxYxyc79>k<>$$0Tqq#X7_*eC|M1hnC|r;nhE6Joe`C!;!kM|X zpN0FHEYzFJ{*pVc?x`Ar>4cyWbtz(xRW?MfCS*K`ASm>($`nHl;H~e`{{*$81+OTe z`Y9-m`88(&K~_{``tYD~=0Q*;OXnTH-B`A0F0W4(+$kvkm~Q$hPe`=OnKcIlK{xCa zELb6s(|B8$C*>!WyxGQ$1z=QQG>WZ-B+3waP(@y3T&M?B6I^?*r4U(mZIeQzMNBqC zM%azCjg60*j1u!os|&ekTyJ@*8R2ZeO$1Yr*xC!I5)gJ2#P(z^Vy z2W~Vs*v^Vbr|kgEv+~W#p6`ueuGVnCf}iI?a{#UBNOsHNQ~uD82>zYwR?zDAy;a7D zJkw>M4?S_)4_5$6Wm{g7!N0%VG`Fkl{9jmbAXrE5VH8~8raE(H`*%hu{?g313L{17 zLHhj@H`=Pe%<-RetPW`#s&eaaD;R!q^ius>T~O2AiaO&fW&*s!b0#ufiiA>*Z=yW> zwurgYX3zQ3egAmUtZmD#Jha)fx-@HF8*~u(-BK`4OwAX5cp{2T%PF{Ip3>cRWNmnD z`7WAu6WlGj!wm^n&DGB~Tkceq82_G|SbXAdXp1pf`51sCt4C|uEl(t-PeISdYJHf& z(_KH4z-~D`GZhn2qEa+E98vP4Ye5RFs#fCGwE*SH$v3@)s{ltlTW@3GlFx9l`F=e~ zm>|1vX(e6+nCS-RYxDVfd^oJOI>kPXvIge7#J2pg?Z_LXX++ z6cY7TPZSUo$^+}WtGuzCuTLJ36J0U6NSp_6U0CUXMWdioG_j%6CnVYy9s!Hw`*GtWUbDk%W5f)+7*15#_Az$d96$h1xoF)boWggW5U2TrYtjiS+?R7Eu!-b zlqkuR*nU$Le7__)MYYa6m<#x2HmsR%rtIAKPSRV^&^j*x1cD(oGSNFG@ zO49AO#Gcz!^6}XvNAGZl6UM3~_QkrO=C^b}I?&%on__a~8%1zE0{)7n;)j$Gxqvtt z5uYg00NH|MpU9Q90-hc#>*glp+s#?8fC1oe)l4lT_${m&;Xyp@=MC;>&6>hT z9Mu5h$RE7e2|oZ*Ln;h_?&Va|ut<%ItFpd8Q)-}Dya!rlpkkp#G+KLDM(rZMnKGz0^ z{A0rS`JGY@CBN`%4u!|YB|n1wh#VG09w3@-|nEuj_U*K<2H za!;EqYWXAC9tKnoF8^7XKy`8=H}oz7?9|g1Qs(dwCRMf*W=Z~BoBZ>T#c>4&=M|?058cmm@@jh zq>>oVaRxKP_nhFc3bc9FBlrxQZN-VDc?i@vUfe=3FgYe7)W|}grg0Sz-J(r<-vTphG?Kf0Kq2zfjf$P*reu968()mt;V-H-CNt|oT?gz#48qJUymqbv zYvYcfk6xI$g7h`3*kd=`zYjbunrUlS*pNegxN5$dbbWY9c{!B+`G)v7$0RhhUamQs z18#MC>`>3!bXTpAp~D9-P_J zj3@~Kon9-_ob|BY2%iAJK`;o{M8FnRepX8JCmy_A59;H)zT94m4M7nUUuDxX`FB+%I|GdbD)afgrIDW@9{O< zTeMqGFA^k8Af65fDSS2bbY+uw^xd>W5qQ!DPDxEJwxWc7azt*Zj$Y&eJ zPmIE-mEP%Ac1u}rFc`2m+^0>TS4p-3%oga00$|CB6E@)`Q=z(W54JB0yJTLjHv!kk zOn>p2>*o63v)7xF?VI}QB1$Io1AZ-03WV7vhMVuWJjD$oZ!+}|k#CTJs;Q3LE5lgB zE!pC$7)S_og1Go3o7kQP8;s2oV?ms?S$d=)duL%OpBfT<#$yG=1qWlGv= zB~ePDA5GW5zsc8Fe+UsPRXCxbLF>eiB&vpv%@V>dkmOXR(2Jq*D8jgBmLrTicd6qF zi3_n!QRP8|=WShkm?OfV=92Mv2gj`_L?S%(`v)x(#+ktWrOJ_yighXLK3d$fmfpMg zVTx+c4d=pyXg}KGkj2cmzTkFkX){)gJRTH4vtItqykp#fX6+Ft#We3P&iGeKD5V$_ z&8JDZ!`5Y;Z9WO?e;l$-LCzy@=!hK*Mok$TE4$}%Vkg;ls~q!|=O6jHR&RC<6xO@= z*1mcPOV`e14NnfT@1=Jh-89fPr61WnX1C8Z!0|0eLDgh@IqfmPOUGV}O>7O1tJS42 zJrb5N-+oi3jCB@23NLv#=1cQxmU$p73SsA`TLjE|+j)&`ajH=>1?NNQ=2;-fOPx(i z`8m_}{oLt;EIMM6w}UC>weu5E9L2E%Lhy2bt$P@5m>~QCJM}z@iw^Ejj3QApbZq42 zGU*E42$+N>E@)Ql`N(Hd-r`I=@S~{-g2PyO(~BcGh6X}51dowrg|vZ}b%#==F=_K$ zJHJ3iyH6l)C*kmb(eT#w9J0u6a*r z{Y(weDq|n)8~0KCK7F03V7DwYm>yAxOfnem-9?trQINRDjRkBSfJvDXao;Q1Eddo% z@$8mrbu@aTRAXXnck7v;H7@aNv&O-{;Qu#y?S0COo+@7eh!odhjo6^*Z(8d4Fi>Y~ zg~k>0JpWS16OGH6y4~w!cEveZ-0+a0SX=h~SRKY2I2WK(?qO*RcRJ%D>B;r+)> zKedTZkC%CnJ0s5RiGtf|*eh(@cPi(4LwvrvW~R!P4w!_%7BPUfhHuX&$a=KBIGwPZ zd26O`fkI@d!Qcya>+>?7($lpf2~waljN?~4*Uf-?r*Zsyuq3mgvk*oKO62vvRD^li zLwfhioMwtaX{?^EI;y%y%CefU0xvOfRA*56I_WIulvVzZ zuE#&~lClv%^gk@j9tq7!mLX}ON(zcB7g%^_hY|l$!7MlZb}Gas zC-jwWcz5?9WLWw_EH~W@EC=?zm(hif0+ccf^iH`XmF}xnrf@Q9mmOQ4)H+4)t_8sI zPZMrWl2h4A+s2b)$0?VM2K1Tiw6O)-q8u+flHWN+v+p!sGS4}KLPjwo-_1KfF_|bC z^)Ze5A^e0R*CivNF6&O2VBzga_`v`> z-M-rAo^?vHl;5PKt~zC`hBCHCsEcg59-x?6&dW5e?rb9goBY4ZKmVSxJK(J{#As+2C-6La6 z{&wp-gt(_d15ZKk@Blp+k--qr-$ohhvd`GSbef48i84gdpR&1}q+;->>SPdbEd%a`jq7%WxcG(xT#d+UDr%>r`X7q85H ztF@pyc%Qf6j{d5PF!bC-)nw2oa2XAUAarP#VK$}{>lQ&)jW48!AXp?FW{2kNy%<%K1H_aNNQ&08+$_e;iXa07@Z#z36fo;9H z^l+8ajq$XUHa)HI+DXr+v1M)rJ0X*-Y~6Nbb8kgy*11u$aFez(e|>j%E9=yV?6y{j zJoFJp&gf-;P4)QwWYB?lN`h8UY1U)y#i;KqP=e0-T{z`%K>+_Yz)m|B)sW2qjeoYn zj(|lQR&B;Rq+*libn!VM41R79(G;IF_tVhNiF-)yd@^J7zALHSD&V0hw@yI8r16kD3vBtv2K&VbK6YJx~ zd$zpha)z@A{qDb3igPtcx?nt9oRdf>3=XXX4GEX1eNab4L`nXsvqmK?DJwMAF`dp0 ztT2P1*dXMsB+m8hf&T`588IbS1om4RlMSY>7eQyN4^lJV*exzcz!10<)S~~+ZDE3M z1{;ECkQ#c`6b!w|^R#AsY5i}sTmZ3tvARf=;`g!Bbs2NAtQTUcaozE|E&Vm zpcRJV#PxcKQ=P zodN(bT|5kW6}9DS5lPeIy!H<%PhwE(5T`RnNk<42Yc=2|4ezeFYSH{VGyvH4L6UHs z(b7DBql-Yp;7|}9@ACag{MGiXYsLfOR8&4JrA^zw*&}1$g0omD7w6%Ojo{^kj(HF5 z!t!y6(J+IqDgh*BupX?Fk~E*mm>PXKrcJA-cf>VFC60{`?}1U%_0vab{Y|Aq;Uycg zK!PA*1_@-}(bMqv$FlH}>SxQNcS38cg~HMoXJDXR|Ay5e=7s))V8Xao%mCmr33?^p zI^7PeyXNIftNId-wXXO<&FXWuFF+i*stx-GmV_-37T67vrynjbO8wt8T>M}Xm;|CLrmF6tT-5|=9@e>w+LgKT|qkZz=ZoZ?s+J| zn#7k!Rsv?} zr6_UP+$}^gyu?lJvQ0`^&0E@CM~(2ljdqOfgW1b$2l8CwkE0yn#0H)4l7Ek^ylmbx z(+rW%RsG56p4Oh34mTOa_BIPq#p)CGCNP9$1LjJSSJk+ZCxsODAN?qkysPQ<4|Ax+ zFoaX*Ej$@4U@_9=!%GVQaaZEZmV$uZt>)X@yC5I{uOP<%ak~UvO6WPaUYttq;mwhgH9SS2P`f( zNK8(K69CJNWeFSf9eU?hKEZemC|)aL+hkp&cQO`5OHk;@OIkH7j-^F9GhS_ zEm#T3V5m?xGECsFOw=5i@+m4Ay~pOa|Cj45y=^}ckl|d#h=(!>$Z*cNDw+RcR3bS2 zDbw{_=V?>&iY&i-VBcilECX1LT*?^$Jo#!vbjOWGalOu_rJjI#96$!E#S~pd5FGOT zP&UowV|dBIoJ%%sv5!YjE}ZoFa545mbkfN_%4PpgY0=|LKP>0Q0(Q$?+YQLqXq$s7 zrV3>bIB;@0t6eC@;PkHQ$O{-D82MtOL?8mz$YF3ue*<0x#oZCG?5m8n$wdGPZ~s2$ z0+4+|uLE{?+Jm&_A19m*aAojuCeR8F65o9bf560n@fe?2jjsZ0<*+ny=9p;v9QH}d z7O~V_9O3Y2^V1v|kuP^X+HqA<8iJ(9Dc15x_nKQO<^5M}U@Eh8Qb(C3HZLMda-&K(KhC zc+2USbDR8Fw~dX+BL;1CBlBP| z0ZgI5X)uCPPfmw{DKuT&svOx^_{&k`Oc7!is1H79JpfNXJd1rB z9W9opunkwI238k@1AJRjF^afH4H*%j-Vlf&5t`);&^erp=P9K4_M z{GSUl;Mb1-Rcc0-n%?^k!)LXlqNCn0yy4LttPq{`8MIMv&lerRuacGgQeSNKnn4U2 zoE4L`(X+26hW`9yr2cqlaPDReXZYQeYLLpYUv7yh%-dqgv+B%LAQ2XS^q)l#h_V7$ zFF{p-oe;#(11jc7fnX}061vy>z&wQ(4q$|4UM?pxeqGe z?6MPfB*)bg0sqSXVi)M`-27`tM8(Yv2?2D@7a&eE{0@Xwzp`NtiXv}GCIW^G1F$t$ zW(j# zo+tTvLC*5=a8Cf((G96LJNcKCw??8MzAZxtO=|9G#iHMUUl}4E1zxR6J8`ZvwqnNj z1#*dS$IWYgJ}1wewhsX2fY*m4dUMbRg5{p5L(<`%<6$sha#hr2IDaz=MUx5T1SG+& zK#W_FsiK4X3~dSI=dgZMcwr5YnMC@`RWSIGhOwDQvvi>rDn(vBd}3qfxUmh-)d;VA*!d=`i)gbS?@ZW~roI41Hb{Y`(1pq$*&tA74`N~K1&%_nM z&w;^DfzZ^Dn>X;{O76aKe6R;>IOq0J?$B6RECClR-^|lBRP?f^%8+!sanFbM1JS1%R3k2-8K4;? z%#UKU$UIK!F0kmGtf3Y8|`Cvdfky4arlY+Hfr~xcL#uj*V{fDPm ztO5xgV^}C{Cw{pfHG&NL(p@2#AlZsJ%+iy*s);$VS@dmC9CjZ-qOVXl5bR6D`(edq zRLlN!18g`a8IQW6oyj?|=Husr@d+gBz}=^q8Fcgj%Hb0zMcD0FZEeJ-Spd zbrHm=aprL3nWLbWo&g1YkXlM)4$$)|9o+`-gLy35lKp%NvKoaOxJj;~AhVf1){sF( z95_EecUDzDukfIIzQg~+;N^(H^PbFUzs7nf1a)D6d_@pW>*_i_1^Wflx%W;QDr!?s zlg5&L6H7h$g~qVII#9AFs^1?MniF9}kAe$nvk&Z-e6*e;9XxVCK_ACvN`)+rQ+DPM zU+mOmJh`_xfD3-0ufLlORTc2Cnp8SLk%O5CGq|Y}5A2jYHA!b?Qxlmn4u{|*x&NI* zjH|#?a#QJO3SQW)vIq#xsk-~`7cC2RS2r>g|)3 zT-q_#EokQ=O8{>+kCp9JkJ;;i#w@57MyClQbS7s?fp-1>SS7-`a|bs zA-Dezqa4VfbN3miy4Bp$@HOG3lF;!DMii8FYx~UY43180`(E_YZQ}Q5zcg3K8~i7* zU;%>hWyuE~vozgE1>AGF4Z(D;H?^UcX|5#25qFe`2C|-P=-xIvsKa>9~>Y5Z?fpM>^A08jFUmEo=NTHIq5`9So<|t(y7p& z*KmlfPg=>P2NIve03dcxg`w~vnaWwW1Y!*A6)wM;uP^uF<#0GJahIYU5c|~CmV_qM zJEW~(o-1eTAl9(gZCDd(VnBm)7X~3deU-D>_@5Tk9KrHKJT{PTC9V{q$86BKEkuaM zAsXN9zylf_n)#~$CGr*ba%>E7S3?mVAK)K6uuG_&FZfzM%w`&2DxKR@q^M1 z2}5dd#je9Uq^x)fov>Lrvf8X2`(~E}datLV)n?&LJ8@1wWyKZxHl9l7Yzg@!;!nZpWURXNWY$NZ-tuAh)T2Pf z9XcC_c$662Zule4K*pbl5^c#)4hfr>lCt7X_u_1K98qFsll3o6!XJ2YfgjDQu2dFi ziiM+n*Jt~jol7$j11|u4Q~U3I`*oDNw@d^?e6K38Kf(p@cY4;+I>I zsuQY->ReLcA_0#5yk2nZn?;gmw@!D!>a8_x;J3HqZ{_hQktdnStrMeq0wvDtP=t}V z7>)?4qC1gnJOIKY%?K1O1Qlya|US zI?tp!4lY&uv&MzGxUL{tIO7*ks0#-gY(CHN_0eZQ z;xr&}_{wBo!aLz8tR$tP6{9JlhqjvV^;+7`P(X%#mGLLUf)-ATZszbaRVI^&-4MC} z%1gT;Yu{L&aM%AM#lIsG_gQ5VSBgsdJyCq>70M|+c>jTWvC<7=1wV0J|EoWP6fb$5 zEQZMB5J!*V2^}m;^8}LOgoKW2Wh%j_=d2i{Sg{*Od`~15s#FQv#gqLoe03h{aa?i` z?;}F8pZXI};_g;cXgdK?JRxXDwCf=W2a*_kVVgrXo!~m5uX0G7i==pUI&Uxxwj8Xo zmL&_neSJ2?pSwRv?Mw6k?w;@2&K*O*TJNqwjdHu z(z9n%AFHdSqG_my^c>IeuHY_XmL5(N1~v_M_ht@rL}W4rd1n$aM-ko{pY_3{Uhoq? zvc-`Bp;sE346w;nJlV77fpat4hrj`m8~C?_=MNL3$5+u<`0KAz)*lTBrIE#JAkhzTR_VDwcW;a*6<;1!RKbA$-evPFAC!4`p=rR&?{=k;J z3(0BS-H)70c5a!eEL^h9qvbZnB1=7a=beA=h@nfCmt@8tDB9o*xo={UnJZ68i~G1B zTSzj4IO)5TA^ID-u%gf&u?4|;QF2DR!q$GSYmevvdqr=3Jg<7zNLf+5!V^YRlbUTT z_VaUfDpGx%y}|RTgXpaW2Y*DD63dHZ&wnR;$Qf0jcOb6YmNi6N4*Kq>Fd2n9g(RFy zi67m}qfY~u0HraHwJt8lg~zcT)n<2`Nh~E$@hZQ*jX@`d@mW|Gyayfwp=b#(4ikYs z(MvgaFai}gTSXW9yYtmtMaTK&1J%S+@N9GBupU=QcjXELQ0(58aQrFYkGW zZan+Bu-fklj~7OZo&7I9iS;|g3vTs&ap$_I9IoucT!jbddM(~p&Anc!b%J@^+s7Q; zuGX&~IimH9rqeTKz4J$S=doK^>Sv_-pxqFWhMawZ9j^UdhCa+AApBT!Dd`-tBvJ%t r<_QSQ%=BDs$Py3`_yKt?^8~EkBwlN9{7D`DkAR7h#m@AfslWXny0s-W literal 0 HcmV?d00001 diff --git a/packages/web/src/App.vue b/packages/web/src/App.vue index 31538144..a9f3c2c5 100644 --- a/packages/web/src/App.vue +++ b/packages/web/src/App.vue @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/packages/web/src/components/MainContainer/index.vue b/packages/web/src/components/MainContainer/index.vue new file mode 100644 index 00000000..a9fec0ce --- /dev/null +++ b/packages/web/src/components/MainContainer/index.vue @@ -0,0 +1,13 @@ + + + \ No newline at end of file diff --git a/packages/web/src/components/Sidebar/index.vue b/packages/web/src/components/Sidebar/index.vue new file mode 100644 index 00000000..b35b2818 --- /dev/null +++ b/packages/web/src/components/Sidebar/index.vue @@ -0,0 +1,103 @@ + + \ No newline at end of file diff --git a/packages/web/src/layout/mainLayout/index.vue b/packages/web/src/layout/mainLayout/index.vue new file mode 100644 index 00000000..a55a2a25 --- /dev/null +++ b/packages/web/src/layout/mainLayout/index.vue @@ -0,0 +1,7 @@ + + diff --git a/packages/web/src/main.ts b/packages/web/src/main.ts index 1f9340e4..23d5578d 100644 --- a/packages/web/src/main.ts +++ b/packages/web/src/main.ts @@ -4,7 +4,6 @@ import App from './App.vue' import router from './router' import { createPinia } from 'pinia' import i18n from './i18n' -import '@memoh/ui/style.css' createApp(App) .use(createPinia()) diff --git a/packages/web/src/pages/chat/index.vue b/packages/web/src/pages/chat/index.vue new file mode 100644 index 00000000..96f08f48 --- /dev/null +++ b/packages/web/src/pages/chat/index.vue @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/packages/web/src/pages/login/index.vue b/packages/web/src/pages/login/index.vue new file mode 100644 index 00000000..70dbff79 --- /dev/null +++ b/packages/web/src/pages/login/index.vue @@ -0,0 +1,97 @@ + + + \ No newline at end of file diff --git a/packages/web/src/router.ts b/packages/web/src/router.ts index 6ee43e8c..ae5e45f1 100644 --- a/packages/web/src/router.ts +++ b/packages/web/src/router.ts @@ -1,8 +1,35 @@ import { createRouter, createWebHistory } from 'vue-router' + +const routes = [ + { + path: '/', + redirect: '/login' + }, + { + name: 'Login', + path: '/login', + component: () => import('@/pages/login/index.vue') + }, { + name: 'Chat', + path: '/chat', + component: () => import('@/pages/chat/index.vue'), + } + +] + + const router = createRouter({ history: createWebHistory(), - routes: [], + routes, +}) +router.beforeEach((to) => { + const token = localStorage.getItem('token') + if (to.fullPath !== '/login') { + return token ? true : { name: 'Login' } + } else { + return token ? { name: 'Chat' } : true + } }) export default router \ No newline at end of file diff --git a/packages/web/src/style.css b/packages/web/src/style.css index bc69e207..4d09ef84 100644 --- a/packages/web/src/style.css +++ b/packages/web/src/style.css @@ -1,2 +1,122 @@ @import "tailwindcss"; -@import "tw-animate-css"; \ No newline at end of file +@import "tw-animate-css"; +@custom-variant dark (&:is(.dark *)); + +:root { + --radius: 0.65rem; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.488 0.243 264.376); + --primary-foreground: oklch(0.97 0.014 254.604); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.809 0.105 251.813); + --chart-2: oklch(0.623 0.214 259.815); + --chart-3: oklch(0.546 0.245 262.881); + --chart-4: oklch(0.488 0.243 264.376); + --chart-5: oklch(0.424 0.199 265.638); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.546 0.245 262.881); + --sidebar-primary-foreground: oklch(0.97 0.014 254.604); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.488 0.243 264.376); + --primary-foreground: oklch(0.97 0.014 254.604); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.809 0.105 251.813); + --chart-2: oklch(0.623 0.214 259.815); + --chart-3: oklch(0.546 0.245 262.881); + --chart-4: oklch(0.488 0.243 264.376); + --chart-5: oklch(0.424 0.199 265.638); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.623 0.214 259.815); + --sidebar-primary-foreground: oklch(0.97 0.014 254.604); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.439 0 0); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} + +@source "../../ui/src"; diff --git a/packages/web/tsconfig.app.json b/packages/web/tsconfig.app.json index 8d16e425..de5b78af 100644 --- a/packages/web/tsconfig.app.json +++ b/packages/web/tsconfig.app.json @@ -12,5 +12,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], } diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 5083dfe9..d992b7fe 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -25,6 +25,7 @@ export default defineConfig({ resolve: { alias: { '#': fileURLToPath(new URL('../ui/src', import.meta.url)), + '@': fileURLToPath(new URL('./src', import.meta.url)) }, }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f96928d6..b545fa1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -206,6 +206,12 @@ importers: packages/web: dependencies: + '@jamescoyle/vue-icon': + specifier: ^0.1.2 + version: 0.1.2 + '@mdi/js': + specifier: ^7.4.47 + version: 7.4.47 '@memoh/shared': specifier: workspace:* version: link:../shared @@ -1390,6 +1396,25 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jamescoyle/vue-icon@0.1.2': + resolution: {integrity: sha512-KFrImXx5TKIi6iQXlnyLEBl4rNosNKbTeRnr70ucTdUaciVmd9qK9d/pZAaKt1Ob/8xNnX2GMp8LisyHdKtEgw==} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1406,6 +1431,13 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@langchain/core@0.3.80': + resolution: {integrity: sha512-vcJDV2vk1AlCwSh3aBm/urQ1ZrlXFFBocv11bz/NBUfLWD5/UDNMzwPdaAd2dKvNmTWa9FM2lirLU3+JCf4cRA==} + engines: {node: '>=18'} + + '@mdi/js@7.4.47': + resolution: {integrity: sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==} + '@microsoft/api-extractor-model@7.32.2': resolution: {integrity: sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==} @@ -4914,6 +4946,34 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jamescoyle/vue-icon@0.1.2': {} + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.10.4 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4933,6 +4993,28 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(openai@4.104.0(encoding@0.1.13)(ws@8.19.0)(zod@4.3.5))': + dependencies: + '@cfworker/json-schema': 4.1.1 + ansi-styles: 5.2.0 + camelcase: 6.3.0 + decamelize: 1.2.0 + js-tiktoken: 1.0.21 + langsmith: 0.3.87(@opentelemetry/api@1.9.0)(openai@4.104.0(encoding@0.1.13)(ws@8.19.0)(zod@4.3.5)) + mustache: 4.2.0 + p-queue: 6.6.2 + p-retry: 4.6.2 + uuid: 10.0.0 + zod: 3.25.76 + zod-to-json-schema: 3.25.1(zod@3.25.76) + transitivePeerDependencies: + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - openai + + '@mdi/js@7.4.47': {} + '@microsoft/api-extractor-model@7.32.2(@types/node@24.10.4)': dependencies: '@microsoft/tsdoc': 0.16.0