From cf3b8372e09d29af447a9ee2510c77c7c362d8c5 Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Thu, 14 Nov 2024 14:38:52 +0100 Subject: [PATCH 1/9] Added new page for drawing a random card Signed-off-by: Christoph Niehoff --- apps/client/src/components/footer/footer.tsx | 10 ++- .../randomcarddisplay/randomCardDisplay.css | 14 +++ .../randomcarddisplay/randomCardDisplay.tsx | 87 +++++++++++++++++++ apps/client/src/index.tsx | 4 +- apps/client/src/pages/create.tsx | 41 ++++----- apps/client/src/pages/random-card.tsx | 41 +++++++++ apps/client/src/styles/create.css | 4 + packages/shared/src/utils/cardDefinitions.ts | 2 +- 8 files changed, 173 insertions(+), 30 deletions(-) create mode 100644 apps/client/src/components/randomcarddisplay/randomCardDisplay.css create mode 100644 apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx create mode 100644 apps/client/src/pages/random-card.tsx diff --git a/apps/client/src/components/footer/footer.tsx b/apps/client/src/components/footer/footer.tsx index d08e6220..b992f48a 100644 --- a/apps/client/src/components/footer/footer.tsx +++ b/apps/client/src/components/footer/footer.tsx @@ -20,10 +20,12 @@ const Footer: FC = ({ short = false }) => ( {' '} - made with{' '} at - Careem and{' '} - TNG Technology Consulting - - Elevation of Privilege was originally invented at Microsoft, - Cornucopia was developed at OWASP, Cumulus was started at{' '} +   + + TNG Technology Consulting + {' '} + and Careem - Elevation of Privilege was originally invented at + Microsoft, Cornucopia was developed at OWASP, Cumulus was started at{' '} TNG Technology Consulting, Elevation of MLsec was developed at{' '} Kantega AS. diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.css b/apps/client/src/components/randomcarddisplay/randomCardDisplay.css new file mode 100644 index 00000000..c50a7ee2 --- /dev/null +++ b/apps/client/src/components/randomcarddisplay/randomCardDisplay.css @@ -0,0 +1,14 @@ +.card-deck-selector-container { + display: flex; + flex-wrap: wrap; + justify-content: start; +} +.card-deck-selection { + width: 15rem; +} + +.card-container { + display: flex; + justify-content: center; + height: 600px; +} diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx new file mode 100644 index 00000000..e73fb1ae --- /dev/null +++ b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { Card, CARD_DECKS, GameMode, Suit } from '@eop/shared'; +import { FC, useEffect, useState } from 'react'; +import DealtCard from '../dealtcard/dealtcard'; +import './randomCardDisplay.css'; +import { Button, FormGroup, Input, Label } from 'reactstrap'; + +type SelectableCard = { + card: Card; + gameMode: GameMode; +}; + +const suites: Suit[] = ['A', 'B', 'C', 'D', 'E', 'T']; + +const RandomCardDisplay: FC = () => { + const allDecks = Object.keys(CARD_DECKS) as GameMode[]; + const [selectedDecks, setSelectedDecks] = useState(allDecks); + const [selectedCard, setSelectedCard] = useState( + undefined, + ); + const selectableCards: SelectableCard[] = []; + + selectedDecks.forEach((deck) => + suites.forEach((suit) => { + selectableCards.push( + ...CARD_DECKS[deck][suit].cards.map((card) => ({ + card, + gameMode: deck, + })), + ); + }), + ); + + const selectCard = () => + setSelectedCard( + selectableCards[Math.floor(Math.random() * selectableCards.length)], + ); + + useEffect(() => { + selectCard(); + }, []); + + const toggleCardDeck = (deck: GameMode) => { + if (selectedDecks.includes(deck)) { + setSelectedDecks( + selectedDecks.filter((selectedDeck) => selectedDeck !== deck), + ); + } else { + setSelectedDecks(selectedDecks.concat(deck)); + } + }; + + return ( + <> + + {allDecks.map((deck) => ( + + ))} + + {selectedCard && ( +
+ +
+ )} + + + ); +}; + +export default RandomCardDisplay; diff --git a/apps/client/src/index.tsx b/apps/client/src/index.tsx index 42e24034..c9abe757 100644 --- a/apps/client/src/index.tsx +++ b/apps/client/src/index.tsx @@ -1,9 +1,10 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { createBrowserRouter, RouterProvider } from 'react-router-dom'; +import About from './pages/about'; import App from './pages/app'; import Create from './pages/create'; -import About from './pages/about'; +import RandomCard from './pages/random-card'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -14,6 +15,7 @@ const router = createBrowserRouter([ { path: '/:matchID/:playerID/:credentials', element: }, { path: '/', element: }, { path: '/about', element: }, + { path: '/random-card', element: }, ]); root.render(); diff --git a/apps/client/src/pages/create.tsx b/apps/client/src/pages/create.tsx index 42a1ebe8..8edb0711 100644 --- a/apps/client/src/pages/create.tsx +++ b/apps/client/src/pages/create.tsx @@ -16,7 +16,6 @@ import { import type { PlayerID } from 'boardgame.io'; import _ from 'lodash'; import React, { ChangeEvent } from 'react'; -import { Link } from 'react-router-dom'; import { Button, Card, @@ -256,7 +255,7 @@ class Create extends React.Component { formatAllLinks(): string { return ( - 'You have been invited to a game of Elevation of Privilege:\n\n' + + 'You have been invited to a threat modeling game:\n\n' + Array(this.state.players) .fill(0) .map((_, i) => { @@ -270,19 +269,20 @@ class Create extends React.Component { const cardBody = !this.state.created ? (
-

- Elevation of Privilege (EoP) is the easy way to get started and learn - threat modeling. It is a card game that developers, architects or - security experts can play. -

-

- To learn more about the game, navigate to the{' '} - about page. -

- - To start playing, select the number of players and enter their names. - +
+

+

+ Or create a new game: +
+

- - Elevation of Privilege - + Threat Modeling {cardBody} diff --git a/apps/client/src/pages/random-card.tsx b/apps/client/src/pages/random-card.tsx new file mode 100644 index 00000000..8446dcb8 --- /dev/null +++ b/apps/client/src/pages/random-card.tsx @@ -0,0 +1,41 @@ +import React, { FC } from 'react'; +import Helmet from 'react-helmet'; +import { Card, CardBody, CardHeader, Col, Container, Row } from 'reactstrap'; +import Banner from '../components/banner/banner'; + +import Footer from '../components/footer/footer'; +import Logo from '../components/logo/logo'; +import RandomCardDisplay from '../components/randomcarddisplay/randomCardDisplay'; + +const RandomCard: FC = () => { + return ( +
+ + {/* @ts-expect-error This seems to be incorrectly typed in helmet*/} + + + + +
+ +
+ + Threat Modeling + +

Random Card

+ +
+
+ +
+ + +
+ + + +
+ ); +}; + +export default RandomCard; diff --git a/apps/client/src/styles/create.css b/apps/client/src/styles/create.css index e911b63b..8facce44 100644 --- a/apps/client/src/styles/create.css +++ b/apps/client/src/styles/create.css @@ -15,3 +15,7 @@ table { .text-input-wide { width: 100%; } + +.space-top { + margin-top: 2rem; +} diff --git a/packages/shared/src/utils/cardDefinitions.ts b/packages/shared/src/utils/cardDefinitions.ts index 8d6f1408..a9a79a2e 100644 --- a/packages/shared/src/utils/cardDefinitions.ts +++ b/packages/shared/src/utils/cardDefinitions.ts @@ -15,7 +15,7 @@ type CardDeckDefinitions = { [key in GameMode]: { [suit in Suit]: SuitDetails }; }; -const CARD_DECKS: CardDeckDefinitions = { +export const CARD_DECKS: CardDeckDefinitions = { [GameMode.EOP]: { A: { name: 'Denial of Service', From 98e0d02dbcc5a4806b9ec28fffdcae06db99fb2b Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Thu, 14 Nov 2024 14:50:47 +0100 Subject: [PATCH 2/9] bump version Signed-off-by: Christoph Niehoff --- apps/client/CHANGELOG.md | 12 ++++++++++++ apps/client/package.json | 2 +- apps/server/CHANGELOG.md | 7 +++++++ apps/server/package.json | 2 +- package-lock.json | 14 +++++++------- packages/cornucopia-cards/CHANGELOG.md | 2 ++ packages/cornucopia-cards/package.json | 2 +- packages/eslint-config/CHANGELOG.md | 2 ++ packages/eslint-config/package.json | 2 +- packages/prettier-config/CHANGELOG.md | 2 ++ packages/prettier-config/package.json | 2 +- packages/shared/CHANGELOG.md | 6 ++++++ packages/shared/package.json | 2 +- packages/typescript-config/CHANGELOG.md | 2 ++ packages/typescript-config/package.json | 2 +- 15 files changed, 47 insertions(+), 14 deletions(-) diff --git a/apps/client/CHANGELOG.md b/apps/client/CHANGELOG.md index 73903a8f..8524c50b 100644 --- a/apps/client/CHANGELOG.md +++ b/apps/client/CHANGELOG.md @@ -1,5 +1,17 @@ # @eop/client +## 1.1.0 + +### Minor Changes + +- Draw a random card. + +### Patch Changes + +- Updated dependencies + - @eop/shared@1.1.0 + - @eop/cornucopia-cards@1.1.0 + ## 1.0.1 ### Patch Changes diff --git a/apps/client/package.json b/apps/client/package.json index fee1fea3..9ecc5e2e 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,7 +1,7 @@ { "name": "@eop/client", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "main": "src/client/index.tsx", "scripts": { "build": "tsc -b tsconfig.app.json && vite build", diff --git a/apps/server/CHANGELOG.md b/apps/server/CHANGELOG.md index f6ff34ba..2ff08436 100644 --- a/apps/server/CHANGELOG.md +++ b/apps/server/CHANGELOG.md @@ -1,5 +1,12 @@ # @eop/server +## 1.1.0 + +### Patch Changes + +- Updated dependencies + - @eop/shared@1.1.0 + ## 1.0.1 ### Patch Changes diff --git a/apps/server/package.json b/apps/server/package.json index 313b70a5..8326a065 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,7 +1,7 @@ { "name": "@eop/server", "type": "commonjs", - "version": "1.0.1", + "version": "1.1.0", "scripts": { "build": "rimraf dist *.tsbuildinfo && tsc --build tsconfig.app.json", "dev": "cross-env TS_NODE_PROJECT=./tsconfig.app.json node --inspect --watch --unhandled-rejections=warn -r ts-node/register src/main.ts", diff --git a/package-lock.json b/package-lock.json index 0ca1a54d..79547529 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ }, "apps/client": { "name": "@eop/client", - "version": "1.0.1", + "version": "1.1.0", "dependencies": { "@eop/cornucopia-cards": "*", "@eop/shared": "*", @@ -116,7 +116,7 @@ }, "apps/server": { "name": "@eop/server", - "version": "1.0.1", + "version": "1.1.0", "dependencies": { "@eop/shared": "*", "@koa/cors": "^5.0.0", @@ -9802,7 +9802,7 @@ }, "packages/cornucopia-cards": { "name": "@eop/cornucopia-cards", - "version": "1.0.1", + "version": "1.1.0", "license": "CC-BY-SA-3.0", "devDependencies": { "@eop/eslint-config": "*", @@ -9829,7 +9829,7 @@ }, "packages/eslint-config": { "name": "@eop/eslint-config", - "version": "1.0.1", + "version": "1.1.0", "devDependencies": { "@eop/prettier-config": "*", "@eslint/js": "^9.9.0", @@ -9862,7 +9862,7 @@ }, "packages/prettier-config": { "name": "@eop/prettier-config", - "version": "1.0.1", + "version": "1.1.0", "devDependencies": { "eslint": "^9.9.0", "prettier": "^3.3.3" @@ -9886,7 +9886,7 @@ }, "packages/shared": { "name": "@eop/shared", - "version": "1.0.1", + "version": "1.1.0", "dependencies": { "boardgame.io": "^0.50.2", "lodash": "^4.17.21", @@ -9926,7 +9926,7 @@ }, "packages/typescript-config": { "name": "@eop/typescript-config", - "version": "1.0.1", + "version": "1.1.0", "devDependencies": { "@eop/prettier-config": "*", "prettier": "^3.3.3" diff --git a/packages/cornucopia-cards/CHANGELOG.md b/packages/cornucopia-cards/CHANGELOG.md index f539b2df..7e4c8b02 100644 --- a/packages/cornucopia-cards/CHANGELOG.md +++ b/packages/cornucopia-cards/CHANGELOG.md @@ -1,5 +1,7 @@ # @eop/cornucopia-cards +## 1.1.0 + ## 1.0.1 ## 1.0.0 diff --git a/packages/cornucopia-cards/package.json b/packages/cornucopia-cards/package.json index 1a828429..904b216a 100644 --- a/packages/cornucopia-cards/package.json +++ b/packages/cornucopia-cards/package.json @@ -1,7 +1,7 @@ { "name": "@eop/cornucopia-cards", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "description": "a version of the playing cards OWASP Cornucopia adapted for this game", "author": "TNG Technology Consulting", "license": "CC-BY-SA-3.0", diff --git a/packages/eslint-config/CHANGELOG.md b/packages/eslint-config/CHANGELOG.md index ec4f7ecb..1ce70e19 100644 --- a/packages/eslint-config/CHANGELOG.md +++ b/packages/eslint-config/CHANGELOG.md @@ -1,5 +1,7 @@ # @eop/eslint-config +## 1.1.0 + ## 1.0.1 ## 1.0.0 diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index b98cf479..62ba6fc7 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,7 +1,7 @@ { "name": "@eop/eslint-config", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "exports": { "./base": { "default": "./base.js" diff --git a/packages/prettier-config/CHANGELOG.md b/packages/prettier-config/CHANGELOG.md index eaaef924..7e984fa0 100644 --- a/packages/prettier-config/CHANGELOG.md +++ b/packages/prettier-config/CHANGELOG.md @@ -1,5 +1,7 @@ # @eop/prettier-config +## 1.1.0 + ## 1.0.1 ## 1.0.0 diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json index bd6e40ca..0917b654 100644 --- a/packages/prettier-config/package.json +++ b/packages/prettier-config/package.json @@ -1,7 +1,7 @@ { "name": "@eop/prettier-config", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "main": "prettier.config.mjs", "scripts": { "checkformat": "prettier . --check", diff --git a/packages/shared/CHANGELOG.md b/packages/shared/CHANGELOG.md index ebf17bbb..bca27788 100644 --- a/packages/shared/CHANGELOG.md +++ b/packages/shared/CHANGELOG.md @@ -1,5 +1,11 @@ # @eop/shared +## 1.1.0 + +### Minor Changes + +- Draw a random card. + ## 1.0.1 ## 1.0.0 diff --git a/packages/shared/package.json b/packages/shared/package.json index 45649be1..489ed924 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,7 +1,7 @@ { "name": "@eop/shared", "type": "commonjs", - "version": "1.0.1", + "version": "1.1.0", "main": "./dist/cjs/index.js", "types": "./dist/types/index.d.ts", "exports": { diff --git a/packages/typescript-config/CHANGELOG.md b/packages/typescript-config/CHANGELOG.md index d825fa68..76e9c74f 100644 --- a/packages/typescript-config/CHANGELOG.md +++ b/packages/typescript-config/CHANGELOG.md @@ -1,5 +1,7 @@ # @eop/typescript-config +## 1.1.0 + ## 1.0.1 ## 1.0.0 diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index 0ac6dd0b..75e1ae61 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,7 +1,7 @@ { "name": "@eop/typescript-config", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "scripts": { "checkformat": "prettier . --check", "format": "prettier . --write" From a9c869a5c4d83f2178b3b1b16fdbfce880bb703b Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Tue, 19 Nov 2024 09:17:05 +0100 Subject: [PATCH 3/9] Remove Helmet from random-card page Signed-off-by: Christoph Niehoff --- apps/client/src/pages/random-card.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/client/src/pages/random-card.tsx b/apps/client/src/pages/random-card.tsx index 8446dcb8..0e7c989e 100644 --- a/apps/client/src/pages/random-card.tsx +++ b/apps/client/src/pages/random-card.tsx @@ -1,5 +1,6 @@ +import '../styles/random-card.css'; + import React, { FC } from 'react'; -import Helmet from 'react-helmet'; import { Card, CardBody, CardHeader, Col, Container, Row } from 'reactstrap'; import Banner from '../components/banner/banner'; @@ -11,8 +12,6 @@ const RandomCard: FC = () => { return (
- {/* @ts-expect-error This seems to be incorrectly typed in helmet*/} - From 41d052ed691560bb5832b58ea4496d7fc0b4d594 Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Tue, 19 Nov 2024 09:19:19 +0100 Subject: [PATCH 4/9] refactor onclick handler Signed-off-by: Christoph Niehoff --- .../src/components/randomcarddisplay/randomCardDisplay.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx index e73fb1ae..cf15f199 100644 --- a/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx +++ b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx @@ -77,7 +77,7 @@ const RandomCardDisplay: FC = () => { />
)} - From 3916679d903a0588508b912f87c6eafb711fe2df Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Tue, 19 Nov 2024 09:26:10 +0100 Subject: [PATCH 5/9] Address review comments Signed-off-by: Christoph Niehoff --- apps/client/public/logo.png | Bin 18797 -> 22220 bytes .../src/components/dealtcard/dealtcard.tsx | 4 +- apps/client/src/components/footer/footer.tsx | 2 +- ...splay.css => randomCardDisplay.module.css} | 0 .../randomcarddisplay/randomCardDisplay.tsx | 69 ++++++------------ .../client/src/components/sidebar/sidebar.css | 9 +++ .../client/src/components/sidebar/sidebar.tsx | 15 ++-- apps/client/src/pages/create.tsx | 39 +++++----- apps/client/src/styles/about.css | 2 +- apps/client/src/styles/cards.css | 4 - apps/client/src/styles/create.css | 6 +- apps/client/src/styles/random-card.css | 3 + packages/shared/src/utils/cardDefinitions.ts | 3 +- 13 files changed, 74 insertions(+), 82 deletions(-) rename apps/client/src/components/randomcarddisplay/{randomCardDisplay.css => randomCardDisplay.module.css} (100%) create mode 100644 apps/client/src/styles/random-card.css diff --git a/apps/client/public/logo.png b/apps/client/public/logo.png index 8258a7c642d746c230c7a7b07b5a53fec064cd6c..049161581339da0abcf203a8228803444e37a711 100644 GIT binary patch literal 22220 zcmeIabx>E`_dj|-x-CrL4L04~p(r8-odRz_@{M$ZfP$caAfTiO(%p^1BZxEzNP{RX z-Fer+=M&$#znMGVnS1B{^DyJUIcJ}}*Is+&Ypvt+yLWC-lAR?(5QOrkyzG4hA(BK8 ze036hxKor=brOEnyC|#M-Pd=-Sli%?O)ZQtcFxvD7$YZBV+3*Px4f%GRfnP2nLHsP zt=n#WzSyDDDtEk%hB@3aBD9o?k8#?mCT_Zi(V}sA;zNYAmr6#bWDLF~_VPJrq_BCu zQ>pJJ(ec6)Dl&_Lcih$|sZD+nMQ~i-e^cvzGF|TE0e67;%^lg;g|5^)7s6?r&K5e+ zhR+PFk#6{?I?2v7y3y@Sy4J0)zi?Ilc~@0hm5s}5JvWIGKX^{?i`ghy9-~{7KI6f< z9g{nAb7r}GBS5>%EVY%P4Z?&e`IF(WMD}4y#z%Bua(O`AG!3DmTUO& zV4ds8j?D%ghL`zvLAf!WVo8e~H>0s_hQZWH_tTQT$rzrdH(^O9+!}ht@ZD+xS6C0q zC2q*JXi<>(|5eb;Y59Zl$F$#IMi`Ond(otgR;MF|KW=G5Yo%PgvZQ zpkslbsZ@pEgx`MY6d;&vCj5(BBUq(XE2iky%cA*4z0<9;EKS-eeBKvn^9V?pPJFw2 zosj=W;cSw+e3x@=gT&nSC7WwMnSEXv;;B3e(UI6>*qzT(c@wi3T1)zF=ksIn>rdL* z+cQO4H}b}LmApoItUr|ObrW%}+;pkR`W)o7Z#nv-JnNe4$6r*OtJp8ebGM{4r4x|K z_zr@Fud%%?3`?JPNojrOyXo1Q5&qW@O|0qe@_8dVoZnzkWQ}YMZA`80OmS8i zbWVK(oV}eG6B9hg{EI$IYemI>Pj6-WHy3~(98UVy99-<29F~?G|NVxooty(q@;5>M z$2V-1K~XvG8`7*Of9Vs-vVa;kCAq!#{Xf~|DX+ha=4xUCInvp_q_jO^uP9gI2cALDhkWu z4DC_!Zpw-=q3a7{afYT?;ln>Ujg5J+yh5C8+=7NeY`lg>Mr?xm0$gl-{6a$9`ho^R zg2o2_HPuZkTRVL#LnCx5n4H}d<`LpH;NuqHGGa3@6yjmy)#v45GZ5kxWaHN7=i@Tq z=Z zLv9{p0sh0Ou!h3daWbBm4^V~+OWnOG#>CCe`JX#?E%fb-;RP|K z+oo3bPXBqJY-(xrz)m0KCYJyYmk^y%+K#xTj zHUo^+N97bIID7;4A}nKLq;H3_QO4mc#F$W$FzB2Aeyj-Ugw?mxm({m3f=M~Kd4;*S zgt-Kjxp;+nIE6U{Sva|bIsa=s4r^-c{Qoo>RUVA!pCgwywT1Pa4{!a^s0T)m|6KjK zv@ktXB@E_JDTMV6|7^il-@yobNGHto=aJzfeJc|qupWPl>%Z=s{vSjEYhc79WNd86 zrq5$!%*HDuz{{r3&(F`sC&0_Y%gt%1Z)_~|KWDea8QVGP+Zaii03U%@AfAW3!dyK( zsB8aowBsWq^b~+$Y+PJy|6!QW-wfmUd&3;4&G^@jMLGU&JP|z{@Lxs--urV8j2GBK zj(;1&zj=n5o&OJi{yvNU4_APx|5@aJ#ovF}^$)xLR~-0X4gN>E{$bbuiUa?v!T(6t z|7+|b`%gM$WCc->BP2_0^)XwJXpvgWYuF+P`Em3g9ugIE8g3HX-Bgq#o+3X+Nl!|D z{kZ{xV33=#Qp!&Kb3?9fDr>PEyH8K!U&Q+DbYJA;k2AS?)P7EmLYXD&(YIFefgkU_ zNu4=C_2J5|_QWg>`a2?;Z{MW6CcSkp33I{rdaM8Y@0#X}wRSTXI^WqQfAb4{9eoNT z;;Z2QW#z{CdY7Bh`2`!At~Dc`NAr7dS!;V)RbhLL3maNPcjCqA(A-c`JvNa5{loVy zLJq&Y?jC=L2ft~|@LAE@(u!V$@Jlk4G#9-j;lraveeb$9aP+~X_C3xQ-`BO&S()!Qb|gWrT?FmMbSXwhIW{S}e-%(= zmYZe15?+GU;uE>k)5C|$F};5r36%lUAUP3rx8K#d`(yKYTsRF&a&tzO`TlS7D*`ok zKhh|74D#Ig@ZPbIfbsYuyX3T2r_iQXmU8Rbu}4GAThV&Lx-0#SEgW$a-!6?XvSq09*Iy6X&KLR8BC&^L6}(_;6jv#~MHgxcb0|sJ+O0$! zpB3OuCqn2jDBV8tIrpvRr-YOwTyKXGe$+UM&U@|0(snGLVe@&4=VghLnI4soflD8d zcZ#T)IkmCY}(=hFd%A@^8+P$800(RcfI?lvaQgm_%<9xnEf zNfbt~_$aMj@-Wz61!(X^jl6$)xNEvY&x<85X|KX7s25^F>-0HX)}*UfbvN0iP#BRtbXoGYzs|AzA?*Dj zBa>=A=WuLIWV+cS{;7wGb|QkX<{i@}KO zw4Q{}8{dkjqz5G#`Lm1XOlvym9vPP7Hr z^5V2r3*)K;-7PdHjey`icjcC?Zg4_U*0 zbpLdQo8hm*G-nqw%jEAQmda+O@kD?ZzLfAo8)ElW-m{Qffy{%iEs;9W1*xfMbf#_cV3Gm|7 ztg$@MSU7&r#oUxR9zZ^Pn+LUfe0I-_(9ugl{C84lc5ymOS1~qXLEu-FAs4d z2~6mc%|$}hEdIowhB4oZg-N_wh=Q8WxY-<(vOG9u{Pbd76i>#(?kJ)SBFWUlGuf!x zTxaku@fj`ZmZH(-tITclPoB)F=6QRC<{8CoMD%v)aisP-Dk5$#^yacC*NHyWu$P)S zjg93mG3t?uKLI06|2DR$qPR~Cp`o9=3gXuu03+Rv`ey2%l2>o8%G?wjtbD9-t>))! zPD{taA3BkKqrKw2m*l5ji&s}>P`_TLm@PL4i5NpSfwb1v$GV<9#lBfv9-p+t7lF%s z(J;HlC+T!Zb3yS~Q5C$Zz1Nh^ZYJ@|CwHQmxxEP)V?^H-o_ao0!oD+o!PMDwykYHI z&A;x?Pgcxs4^*oo`^}0>}#N*d^r;mm_e3 zt#F9%-8C5CB_a2son*#Cu$fD8TMWDTg_!ktJqok=2>0@VcN6a>U4e<4)AV`j8$2Vd zBkEfnJ>b4P7n`E!6xS#h2&L{8jAPw*tDJVftw&wv^II+U7}&3Ac3IrYShyV~aI@(l zp6~UNt`wyVd?YCYmdKm4RUn!qkg|5xXC?7gUoWevS$1XUpR0ei({}CAb~BITrLotr zL~jpY@BY$I3rB2fmie&GKxXum+3{Ph49w2FZ*ScGQknp}W71qyFdkm6V4S>?`ze4e z%{ft>%V_w+2hUY9e3B!eC`r#@MZ&zer+IT+KDJ~AViHmJ-S2WA&)`?N!#q;?%c&(O zETd=c`R8T(OQcsm-l`rXBtQOLGaWw@L!w*0(KH;1)JlS=9JRffBPB(%D;JMfwap(a zmb3A3e`tGMC}piQ{qsxQflkRvl=x1qW38J#`0at+&ZQQuJDDTxsW~@K;HfU3#8L{{ zZN$hHMbsi0dM$dmbnyu}f)LaUkmUTBtCp$QV4r_=kVd~%Hi>o5_Ntla9{uBe6MmBoVfc;pCNdAt0+eB;kTaO{CpuD7xgN&=YF`p&SRH};K&}=qj*U% za)WpnS@vnZsULGsWLjIUwFbDS-`G!QR9pKZ)_qK~%6f=Sq%}E>r%XkTljD82da3>6 z5Qf!jcZZi^iVOd(|T_3N140NSxo*r0C!0B*V zV~3ru=$6h0QSqJ|O7k``hcLkN;O_3u#&3R1pab_)&Zl3+#dg)g4lXk)elVjQ3rf#9 zcWwfKDymQ-aE8p%9ucV*5Mvf8*^CDEO_yQ9~15FhV6ksa{R!#H9C{PxakLTV1WRi7Q|9Vb!- zbGe~twu96CVkT2%RX&(6VpnD#h%Ng$wDm=5MaI}(b$4^dSF=?TFCf7?l)~qZmrJ(i zQ(sBZ@DdP<7k)Z<@cwSMqpIU7&B0Nfp%48K3v{NimQH4Stn4?ihmnoR=nCzt zvW!?dTmK~|MjRJJH&<@^z0_98>b1GL`l!rt$r)!3A}`sfP_@BZRwoHQMFx-+dyE%H ziaho|c*A+MeEYZ(zv$-AA&Hfbu7WHKFG{}J+|Uiv`Yv~~=Ty($#d|FJm*Np}3`Ofb zd}OMUw91d;EN}LVH`fQ5f^*AMZgc!$0XKfKtCy~wE3x0aD!@Oem-k_-fTKliQEAzr z#E3&JULc{c z8?z{S(HPb4y4l-08~HsVXWyvXR;@M2Kr!LN(wf5)nyh(*eW*pbZvXwOv z;V&no5kZmTF4TI$KgqkuiKwSNE5lnfFH=;5zQqdlpr+z;gz>bBA04yvDvpj;CsUVygqCl=eP~f%B+(ft4R+qEa@4Tm}_j5CS>}eS}t;7D? zr9iYpBklb) zOznH=+0r9PZy-()*M00T5>b@h{~|m4v|#>9lTK0U_s-qE$O#sYQyOI{Gtc>CSf3M` z%pM38iZTAS2wDhuL@4S{gZTw?EOO1CS$tb2cR^EcHvO}nhr^eq0xQKYQk0dqyq{{F zTF5+eq0YNNrK;xUQAC~*^mF(5HRsPNr(T%uk@~RJH(dY4uD%J%;;{b?#E_%vRuo7H zgx_3@B&}cjpT&}zPR{75Ub}pl`*>{>HJ@Rn>(6fJR%E8n`>i!1|K)K_|8JZ`Nuu^% zm?^MK+$h+YmoX;%H?F#O>$-3a1ugRSCO8W)Fg(jQN^Dyn(hvwlP^DL!UY8DX1ye{{ zbt@c#d#rl9N89-<6$0eGoEM>FGT6Hcm#M$1d1qtdJ{uG>yNJ-7ukA#}2U4iGq<*UpVnsEwO>%95*s)e#ikR(WDyk0zr z5V5i9@OLk>|2?>0-zmkR9hn=Ro}@Mg+2?18tZS;okA|uzuFD~qODNqDu0(Feor{C( zIM2prtz$)4S4ZKsF@vaFI(YCw0CLDLc~5Y4 zH6mtM8S8g@6<8aWqS5@a8u#BnCnE2N7U}D;MlcZQ#jE$M>&Cy{oV!X6VHW%OFdgpX zhRw%SOs`DXa?YLz?rkvG(iI7@))0bi2}{GFN5P?slsx)NE`AKU{ zqKEtjeTs-PRSAVesSD229WTTb*u0s!cEzgH>CuF!t@Ym?GtDGOSF_vA)O2xgC-iaq z+PPuR0F8~AIW4Q10vjb25|)C^wM$Bozv6^cM)w4|Gh2gh&-IlQECgJ;ne*fEkp|>` zGt)ehv_PCypp;XstQ^8P-3|V{Tuq6EJ#BBPbDKIS%Wqg zbHg90ja^uBs_H%J)(&pSA^$0XcrRb$f|?5hrU*z)N})Rv25#cg41sjCuKT5h z*2ww2W!NKG+hm@K`Ps`6zkjQ(^y&xZc{~v7S0ELi%B25EhL8f3fuXd=R6!cDxSXkV z+#Y}Ic8=!zjD-=$t1(Ss5Ny#F|0_$=z1waey)YJQF&6OTLikaypgba4WIEZ)NJwdzpENrWQPI66= z=a@a!Nv$Zg1;r)S0@#jyP8`54hUE^cB?~T-@3+rf6MYiE5VUM_p=*$5l*dGbZ^tlP zJA`hC2~;><1n-bpvIi?FH8oQob-`xeN@2=;!<|!#y&>Ccj;jITyZ`3zTpim}G3(Vv zG3_bJs3^C+<zWXFaICuQeB-@h6xY+MxmT;$!sAZYTce|()>Axa{ z4QJB}bKRR(32EQzZ&WKtY-Gbbj9-{6AOfeF3s22M^h2J23B--8-ARvActk@xZFzlv z3cTjA{CO3Z%3nSE9c1%J0?NR2TFSG%d347s99+p*Lh|6PoI68h245?GGW23tJ3DhT z2hVIJX0V^`dUB=w@^3bQOCA;DNdrd?a{$>+-{CsjZGO9l4d>YDqv%h5SzKj?gpTzf zLx4fPF=3%B8zPbGPV3v;S^A%>4TjAq4_f-jw zR(hv zGC)pFM($P&y!*UO`BEwKOuqH(4=laia=u)mnQbrbk+P?F&!j;E$9{)|U3F~BbHTSt zM!!n_Qh|Kv1@$TtWRDDk8b6vfBnEm^QLNq5#H#@rcg!ixV6Clu zf;DRr@@(!qhf)hSU|2T^{O04rh}7~7zKVKsA|%uh5!_p@@`!Y>Xn>3p)Gh6-2cP3= z3~0vSk@%lABYSs3gPn$oguYTS*c(p2`-}fg{+161U2pUuAc5hAtYN+>YxaBfz4+#Q ztBGBZv}yWBpVy<3%M!zcrwoDZ;N;Rp-P$3>bf5p)H~p9m+~I9Md|y8ZFus(stxwVo zEJ67DT-Z;Ul3=sHg}51O+C@Dt5%cqcuA?H($d9_Z@3LFI16l9+L1ng&_#{Vx>W=oe zV`_d)^*6TrYeF4UKIHTpI$GL>66>>hxIfRA3CwtQYJYou+SFF)rUwt+A%^`vp{_0m zjLj~)RIrUwqofx|iu*yejFp$et$hq@0SV(&{wnj+x|}$EPZ|ss%#p05$um9FpiG;` zbM3GRNbX$nq>0e*4KX&%(L`YY6Fg}&)FW`KQflzKyJxmMa`ET+``k36VC59)MYS>* zlx7<46p%Dp>oGG=y+542nSp==jbim30ehfyCKfJUfQ0Y*c0VqD?b*3e3(IuzV$fAA zeFv*FcMlqwZ@(PqTqsB1O8~glD`dwdUI{!^!+HyYy=eIS#W?rzr|jkuu&bVy7(H!+eT?K3fS!`6luch-rU%-`hT?0sTm3y= zYYN!z2S?t@5q{LzS&pTjhnVDB%nLM%DRG}YH|=5%kpKHYJZS*UB~x{xAABEk&pE4m zdWc+UziYMgCTm0u1W-3c2LC`(uVZg>ra8$%$jhPacq5Yj5)j~xQQxBmcfra1l*a3B z#pRSodhMS&c+o>#P5f5=b|p~Z?5c-}=-OOfQY%wsWn@&?@a2=isSsz|_cB~9n(p>) zniy8^&aA+b{zAfv)S83G-?0%9KLvn9Yw*<5a~|E!H{;}-_V}v0V+!rM7i(*F=RyGb z$p9q9x9$Uf6_}q!nSCdO=Kl4Ecr?1;@$H?q);Ug|w0Jq8a?T^1hOL0)l$B0QOdZ=` z`DT4u`kigC`ueS-VX%#c9G>a)UX+VJwtNuAOJHe}o*Dh}aQya#YQY2i;W3-DjSN(a zfCA)bCLSC|HCw9WC!LkW&2_-gjINYJZiIred*j)=fXF@w)%xJJ8D662#R(3S<~|?} zv(58IV=ZujGKop%Ti zQDsJZ%RBlI${OxmcibPHX$W?!k)6C!Ki@wQ%l8xj>RYX2^}(}g6TU5g%|>{x&h1!j z&@TXH6drCnQ^sOKEMpKMpYLZ+(_eIto|ulz(MKDSVcxrgYWNc`x=n!vm@qCej8P0P6_y-#{d*0 z@|IdekUzZuEck_b@|_t_@5#|L+&n4y9RPTeSg?8hky^cDLy01u*2AT&RSeUix`N4m zQ8JH43?&-Die!o)wQZ2TOHW3{yvGO*j}4)&=&J4-TOBpgCz>h-(@XKR52Y%6uT-VS zD2wMcFS2-%K$Xd>{Y+=g__PXm9e>@mnW{Z|cePTZ%}+^m8Mz-%3qR6w>O`CJcZL?G zj(W+{zyY#HuAcq&cIZa%+?kFxwFzp6SJ=xwkcFH)ujy${sp4Wk>)$tE9<@q-SY#lH zT&j9zZ@eMP<`s_pEEa9=?sAp+glugCxr$x)k97^))G4pj!)ark_aWm%Q^x?csukaF zi5VB2A4O~UF6K$U(S4a-#YWrI%ZJvn|%K5)o;LBtb1e0;09HE^~!rm@siphFkn+aff*?d&YhT10%=T(_=tJg^D zoA(i;u$O zaOj>3BJMk{#nugIDogWTz675~G~_+o^bG7`vYkHdvQ(z+jkdC?TP}n&Vvu&#{s1I2 zw$B|kc8_#R33EFeSBp-H+zL;ylzXbtltBcDOrcw%K~nHyTa7N4k?!NhJ7R=1a_FlD zZVUQS?XaO1hKm<}EVBi?b$f`|WWL6+Kzq+=Sd3k7_sXG@qA${_P`3f;AX;$VdP&SH4bC z<`+rjl0PP8FMk9=+Qe|(Az_1csCNoeVai{?(VY-3LsacF5SBe{kY6UZOkC?%&%6O{ zd;jbys=HaJXwK1zkx2jD$rWbk+VwrlmjzW^_8u+gH6m#hQM)KtdV}j^3_O0Pq04KB6Ef)UDr}i|zp}}csHq0ilwk7q_=5o2CxW1Q)OOhH|lq|6p zk<cL9E4Os0W(zPVW2q^OpZ zeHe}PW7^T^NEuuW!yVnAu9C*htY9-T^fcc4`&K|c+Y};(bY3q}YSYYs50yv@6K7@v z+6};Xr**1iS#UyBG+CGJ6sy7 zyW=C3TyvudF+Bpa9pgg^2L|8t#9U$n;Du|xuzv^lK2A9j?}rvQi<#O##KqYjkPqA_ zeyh8-;Aq!q-m9o3r1=?nk5+^wBmDt=ss5BaW0)@MmldN~G-h(?ic&FGO48=8z{1|z z%ddnqkSKyFH=r*y{#8>cn%>eP?m3-}lW@(j!Art3e+b36R~`9ND$&&EfnP%$I!m}- zwymH5yd+|Xl@JhTz71A7f~P?)$m$ibY!J*ql4G#VI_@ev^s;{+_wK=F#UqA zjs8%UxiQNr$*98;bHe&x&BXkc*M?EPv^=AFelQZ9LXdOqwB*^tit3pCh)S^7!H@Wo z>X%Q{5K|?zgy`GxHBBXFxA91$x1&(#V?7h5Q=P|6 z;{EPt2ZkihVzV?$!5c$@Rwkrqln)D7n_X?^hjhD=Uic28;;~o|+EXILW0GqS?Tv>e z0FFo!+=kW@h;$%aIe$Vt-&~1iPN-sNM5*GI4_Cp#5(J=X5+1UlawK~{&6{-lbaPi; ze#)}wN^Gbw+;&tNr9vqY}F^5XU-d2=mDUmvl}S-&*W3r65bi^f zwY&U!U00VcmxV~zT^@Qj#Em`)nEX0$GOfxF!%}M(*f{DO@F%hyC&D8Eo6zn&X-7UR zl0|WG{=uI65vp)eVP}oypiQVnprx7aG!e0!kc&=mKskHyV^Ci$sqRrZ@VFtd=lOdt zcC`YmsMgwk=dmbapEu@|qOC83{tBiIpS zk?OqNbYXa+k6y+ZWB~#>Nt4DLd4D);la@C>GoSD0L4{2H=$Bmi$}7g=i#rFn#rg7m z5Rz0?{&T_?b$3m0XKe^SHlVVYq^sb<2f(Vv?;=R0pb`s!Bvy2P80Q!xx^ghiv2X@z z>yN8i`KiM6Ur8!8yS-Zv-gE3-^W6U|fio)D-wUEW=!-7NeoHq;;ob6;=wky)kAWS} ziNGM?fmO5rfQ7Vbe5WD_1U!}_M810GUFs_t{FbuUbu1+(>rF-CCPW|8r-YMZ%T(@t z`jp@^j?PH%B+VNs+-q7-G09RPM7#)Q0JDou4=(cD0netnyB)f2fnp5Kjtrt1^;&<8 zuWbyftQwT8XH$4WG71T0|KJ={Mqa;Y+)rAVXlOMR3(o)?t#u`>uVeLh#qhLs@a;dH zD~`s!&dU=Fz47zaJHdM!4E{y=8lX*235orvf<{W`1_FpaYH&d#5GK4@h@~dBtn*}w ziLRz*O z6KV4_cq?+rPE$H#4_CiV=Wn^&k|J)3vT}W)SJ2LSH-|p<9D!7>;xA;11l7B*P$*ox z=9<~k0twYYQ8e{#X>wYaALu_W#sxxt2RUO1I;Jt=KcBy)J}(?ou^?%2aK%s6-9~A3 z!LiV@CQ*jCSFhx!NC1(fG>Rs~#e1$lp|86mzWnt?xBU@iA9*cZzEn5Ea{~ZX;jG7k ze)ExPsq8f<%%&)|xbk^A&qjyiGUpsU7pQKlU9=Pxo7~^SO)!`?i+6r6FtQrG5m_`7 z=E@{clIB@cFD|6Gx5IZU6PaR~99{}!NX17wmTNqZ5=e1gTVMG!vV9#tI_rC9OmhZ+ ze62GL=hlohUCipL*DZSDp1xJR{kHdH8-aFFa)Q{Io{j1*HC%F4%H$ve!KY6$Wmlrx zEF06$o+}9EU8nGVSl701OE%TcxP&3u{uwtFHt_Aj?9l$+S!#xB(Zx1}`1m2`A?cDd z`?kNNW2nVF2-B6cjH&S$*Mxt}Q)4Iu7!}&B3ajZOq|~RAE~T11PRcVG?}%eN7(STr z9De9-6CH3c*TSQ>e^a*T0V$sRB{+_xdeDaxjA2D4o84&iW$!YSq53xt)3eQAGWa^9 zpwp+({ZB6whHzr=Rf)B^`8lw%0PeScn4}5(rKc>Bxc1x^?Y8Q6a<84_Os;}xN_a$m zyq1ue6k$Uvpk5aP8)miQD^3x7deMiwG{`K`*kCdBI-s=pVtqF=QG zZ0^u|c{&Xr8rrO9&uM!q;&h0RB($C9{soDN6zd5yo@2Krjx$HHW|_PD@Dm5(A$EK< z!bc=g_&xSR6Z7eA4ZYoCk24!0~^&M`-S4=AqWot zwOZ2c=m(AR3RyWLdIgEsE}0ZLH$B!l@~3kN*=ht_l3BT7Y`A?1>QaFrxXM@?UzA*jykNid`XeGWSGBp0cN~|KIL`pd+$`K zOGi@UwELO~LDHbn2UE-6;P~N_inbpAZ8e+vr-t`=vU6L0eJ}3iou)%DDkzBtJ&)V2 zq871QYRq{u`R8BDE4!K`h;QVGGBT=^G%Do_(Xxn1l9@(fPq3CynszU8*hY%!&)zpu z`NompX86IQ`6}=`t(-wq!V2*Ipd-kA6mThw6@E)4(F6{$C;V+<3+E$?oB71h`B%)f zm^)Dv_OAo!aQLxUW@>%1SMS2dubAkPm`CnDPyq^?6Itw!;cwmgF#hk6J#K}rwF5Cx zo>v>yxb|(D9vX%4*S(wV4+uNvNgT97A`Ok}tyOt;A- zl}1O$GV6pdQp}Eh@PX=2(wZd{Vp7J`kV9~Hbo>MMOeWM(^Ip3e4;ec$ShN|Z+){(? z=8DH(umgE)-ATo_Lr~pP)uX1g%S!kTBEou zlc7@F{AMp=7!RpMyOhV4v2{LB$rHu~L4hq*>^P|p2JIe#WO%+TLyy=X6T$?Dr0k%P zm%kT~v{9(P0Gwe*3C(n1E;ePay_GvnAoZF0#x;-Y*Vy|yCXSP~Il&1*JzXr%_zUz> zT3*&LRLHLpVmbIVvjV-SW^Eqvq{;>so$mQ?ra&(Q#=V4uGkoXU0BEvPdWQ=?rLV=Nm#jBg}0OunqT}Y{zd5 z2nic12j8Hp81~xD*ahglz#TDb0BIYAv>}|naL!5>B=#5HA?zo4?mk~2Cy94Wg`?ND zNiqXRmgn>^M;o13$}CkL1c5NGBI`g!MX|;wJg*QmoO1&2zdOO&#?*W_PkkS1kit;w z^KDRv5+ItzKE9a+S&XEz6B#4o+aEX-0sX;eE`;T2mhWdQZ3`8UW!EHc)Mf>W45E;0 zyvM{8poQ9+-G%AOrg&ag!FEaxOuTGL{~nr8V(Q$D(Fqwd$lHbR%^UMZUDeaQFBdYO z^Ag!=9&<6!XQ4TQRu@`=l1Hi?Y#>Vw%!sPdIp(&L{WI1<)FU09WkkE_OyVQIAyMvnp{tp50vH37hx> z=_&+~Btq|D!ND#q-X||V0$uc=B-XUB(_6nuSv}kv(f;702!cHUrzhJSMoE1qIx2+< zZcxFEnAq3UwIK4{yT7>6W_T!FAWS!(p}qY;+eZ!ZI!vY{dRdQ>>I-${L0eKhMBWt? zW6D2-0^WTH4Y2gO!dK~Ydaps7It#kY@Q>cexy&;Ul;3pTq>g>IZKbY`AOahnZ06$DfC%%N>d_n>AfAY$hr(y&d>-J~~m z3%Xbj@)PwHWO5cy*#3%3U*a>I7;;BHdnlom?f)#XZ8~{wYp-#eq5D9U3(vpYR$yWM zh9+`92RgiTIxIdF<9+JZah-@~2rDsCuuTmR0($NqgVntN134P_tD*w)9z3Fb^(*M< zil*Lt%HZ{d2Zi+ot#cKKxVrgjY}Yt4xC@dXh0^iZXoDUkTSq+P5CxDP>pqTiyw|i= zQSRmeL59Zoa*$tP?p9Mg@`|FJ`yP_1tMRh}Rc10-%i!UYLC!AuvA}=DQLvz|OKO z#}0k2UjV z%g@I_zv0XM=W{Pf^*IY+(agMefoJtL~;YBn~NK?dd)SunV4O))N zdea`CL)$C8F;^+JPY{WilbJj4?yVPvL7ymmm{JKw!5zL6cy5)V6b~-7c0ArsuY#i_ zJMb*p*Mk;bY}k_w6wcO*p&y+D*Far44I(n9-Kvp!!M^1KCCl%p;3!>5vq(QwQHP60 zHD9=ly=V+!FX^Ve#IR@26TLEG#9tVMZ)|yF`=yxYXj-^HlogdnmC_*;{YiS+bs{O&Nf`5 zK)qDvr*?7cJr=^@c72e8+Nr+!Y&u_5R2ud4u7f5bbkNq0dBM-SpO8Vl6s=bixjP%G z58di$vlL0%5n@++(;fSk1vmX6rBF{DRI3HGP>Gs(wOM1o#>ih;EO06Eavgr?#Kx7` zlXzadXk|SqH21YD4M8Nk&fCz8XaRPG7laq3#$8*Wspu?dK8>zU75bc`de859o7kIl z^4I8+D4R%fC|`P>?on^=zOgmwDHc*|e)uRFtdK8+GF$G)f1E;QwKfTPxzPvyqP4!AFpfH&D5%fCjZl-^9$3Vu@dB+gn`D<>%lVCkSvQ zzl+%x@(U5qI4*>~*2_!)E-l_exn!khJO0F{D%AR2`Gh0dc&=ZHmB~YpQ6C^f_Tz;m zPleVe9@Q1>MS=RU9o#1rdS&W`?K?SUkj402Z2}B_C_f1ciTB#Tx}Npu%Mk6-)8yPe z&+8_c|31yLf1ayFWKne&1;WH%tYO*rjBkB%y)mVmHzX*v2>$|Vu&7|XdetnY9z9+m zzOfiULo4-ya4a(9l<7*xJgLxIOGVu5QKZug4*kpb-oetnmW@z{Qs~v+gEo8L_3^yZ zUYc|Gvc&DD50t8MjnwI;>Ck*?)KV#GM3&7 z)JnfKS5rP8qny*=Tlk=NH^>10;~Aim$=I^4RsSVnqv(%q%N-8ruU8fqQpoqB7GBmZ zU_wHO%45adHBTb`5m0lA(&ZHFBaU@$T6h-2P^PJ3vD9}m^vb=ZrS6(cm-pLQzPx-p zjv}k%i0LS**EZ0r+w)#(+-Cc-{gXGqo*;u~YoCIO@laIAEzgW&~T<41}`$;+occRSNdksu6cLK3>pCvc~cg`F-c_UE|x zy}cgF8w@UE5mW8bQST$T zDMHK>9P4wlnT?jU8B$3XRMniX#mImE0X(XK?>2<-rz$xzcW&Zq4IIpKT_QaE!bzUE zX;x3^ch`?z+<@NprVSmQT_<#VU(PLZZ+Qs~wCFS;m+$YVZoU-R(B4gqpCNfyho)lq zS_<9UUP${%5S*mogS7^kG_fZwOF9vM;S0}YMGX=ZJNzs>Ify6E0CLmWkZkDspyIS@ zAe`%+Ic9#z%canu3xa*@`)J0MVO15R6E$9iq066hH7%ShbEbViYBXw8T*{-I7o9%p zizK047}LgJZ7I!J<+n@=Z(oVo9Q1J^c+>^rbZc%AVq}kz^J?mUCgNR1q_`gFC`vj515M3k#u=#2 z&z+20={rBN_BFpd-qq=8HlC(7*a6S|-Xl64%f)CuZTewgx+?{$F1!wHf4ZqGO!%M? z0D8Grsj#K+ZAW?PufCdrgi0joI7$Hydaa=eLfXl|fb|P@Z(iqq@9v$*-2jFKiP?`i z%BQ{TP+`B|%MTuTR6&kVtLAaExc7@r`)O!8>fVX&;h$5+BAw5H!?%x4P=IwpzawI> z--W8%w+A7^@S#jSOOvYOG$ZZ8a6!Rz?)@Vnci>#HAqO>86@D+vgT@6tinVj78^Q}t zWM?UJt#VR`dvVnh$lrc(OykA#e8IPZU*6qe7d~oi&q>AnJdFDB>NPW`^SAx4)(hS} z_wm;B@w;j6?=+%RJYUdqlKU<8T_zy3O8amq$e^s_8dB2nVa2<`CoA3~#}cr^h4rdY#_!j4#E8 zJA+YTK)v#viPY_LBc3}e!^gYbWEUhzB=3`gCiE6dI~(3$=Tb_s5r=`%mT$ugA0Ex3 zn_=W-r9Y(-lagB;TbZKV0sZ}{n|i$NhTmW zr14w7*74ewX!FQxT#ool6N*#ANo508W>!&zwGpDnQ`?zB)l zSWK8cDgs~X*4{CN_|bUwVM>jV&%R%nwmX{wO1c$%hn5hAWcYd#EI_vB!s$DBR45kz-1b z6q)xA4z7Jm*ZPh4{u=%bjn@h!c%xD4ij)=-%j0Y&1Gn)Az6ogN=;DPOy8|nG4yazm z&3);^^H1c|bunIK0YZ-f^}8IgeY-4{8wY(Z{U;;|aOWjDM0kvek^9oH#%wNMjf;ZX zFxAH&+f%(fJIO?Ih@=Y%q(DQJQjEF&;tX##u|M9>A@V0-8&!7OA?n9m6h z6^?(Cf<^dYk-<_*MV2^AohycT-3dUECVDS3Ypc7hI9ufHf&gKz_1_{(g(QUmtgupN z%KC7ubm1g?_5j4YF;504as0kkq!^9=hNEKJ54_NKuolO2k%v+iEU)8r`^U?rM~zR^ zD{#bbPyBpJ`T&9Nsb~?_cQ)CZPEEhf`%M(_v~%j}JS+DGlpGK*&p=N5$8W(E%Z27Q*N}JU?$cq_S=-;yQ6fY0bfxJ>e0UgMZ1m$H>?ld^``QZ) z+_U$p>m9hrzmyu&AlZuW4$apx1EGq{l!T%b{kL(1X`MnHdt(a{BKCyH0Xk>MK|;%f zNCaUyi)T!`fM%{GWdn#0i2V%UAV&K-_}pRnpPBw&6agNEizyH@vZ%H;{TL1KHUtBhj+=vB}J__ohTisO-J6w`>kFvO^p)Ph{`S!8xAm z_&(3;c|HF>fByQXSNFN^YkaQHe1G0op{mNyC`jo^Aqb*)@mx+Ff{0`w2p>j*51v$g zL(qV~Zo10DTs0glT|G>lEuhEd4zDbjU)Y&iS*Tl>ntM5QTReiG7gR6g9&36|tWO6x zCLg4*dFJceys+<%eD^v0HWweBKtd6V!||8#K%J>?mbLh4`QwF&XO1000ez~(#0Cpg z>dJMG0=VTVk~F7B-^Q(bFGk*Up^P%v$k|R9;nT{00`F2{H6Ms=qfUPKoQPrain{(+ z?y8aLG4*SmHwFiusYp*_ytQ)gC5-Mp!uaW_9PN!RoqDaVg2n&OpZ}4-|0f9qejZ@} zW^tUifyifmuDx^ZmZfs&do1=Od{s6^yAU z2FO!Vx&579J(P&;9`KWRv_^w3bMrFzD$mWwy=DV#qkkS@`J_Bhy;ZBHTDdR4iDer< zu!^+>A4+#W*s>P$OfMu_D{kF={MC(L!qIlM{qH`E)j<)0k>PVekd2zp=ReIg|AyWZ zJh_sYF+2XoEKa3wK{pO*g-3lCj~0T2tb80+|GuH{L$E(7cjr$yYboy~C{;u_x~h|L zL)tF_2_YG~@tGv=m99nR=Qlofky8vXiizuze*Z)SaWdo95%RpWhcl|X+0k{kD=hB5 zF2ofEkwJlaLyY&0#4E=8euzF`(S6?}!RNSMF$9^YT`a8QC~dM9ZZ#p=-ZQwpp0O3d zB>t#Gg%%>CHo=2buQC2fz|OcZgg>#p4W2WT1*+V|O~raP=joy15#;ot?v0s7_FJwe zcr8fR(o0bK$;S9JE24k|BaukOxO~#FvpL5jKo1#Y;De>C=AIQ?rJxv)+8N2S;eu8# z!5~Nz0nRGmM(vQOW*!g>F;iW-2(3)GKrl5F$U%4MMUZNpcRd5xz)JSLq?)6gPed~P zSHapKr?KWNG!v2i*)4xB7-E$}iWs0xh-lfUPZJ6~L zusg%LFvPsV8@W#G2SMqr>k|psjvf1K7*zEH2pG~#Wq$6vRTo|lULoo92Ct|~o;d!+ z4~D8_E`Bd-ni)}eCY+>9qB@ORyo?2>65G^yKjjlV)#8f>Lbzl8`-bNqq#ASaAm-2a zh7C3X5t}tiRli%~ct8qjHlZwS_<8)4YhVN|b_+b7)EVdk6>HV(x=$u;Og9{^pH@iaoXxu?(l;Ws0JmyhAD?!gGe2Ch5-`ey zVxHr+noHy7(inqy0RxKrRgY}Lw06u(wu zX;E%jfJ5h(tf)@n?}w~1+0SnPcVWVka}6D}<}6)nzbHNR`BY7{OY`@BL=ds?pEnRq z`*m3eDoAF32j|f-7EMY_GW4v^w{ODpJrnWz_w!rmJBUV(5QvvLqIE@c^Zmy6b1yS_ zInUE0ciSzcaX3Wt7$>54`JZ2Czx;Gi%vM^{3~{^#mI;xdVr~=)mOe~9@eq6_j<_Be zbD`Mq?9VTLNuk6}&koA%cA5elp85Q(Bw^mXl@FAsN=q~)5tCGM24A^huMZqr78UW~ z6`8(^Bd-!k>B2mS_rspd(K$_4b~2J)H^pmDZW9En`_j5H(ibp6T~h*k{8{xKA+-z6 z{+VTmL&ujS{t2h3UZIug6MISkL2A922VIylNvX*!5;Eq+3oX7muTqlKTlQ-B>RS1G z@MMPtxB;l=UV!uT`d$iOciCI!ax0Id6nttG+_34kq)QA-{6(I?8rm4~KI9UC>ddMegZ02!uhy7fo8*b{h(27mKmFPCrCf1_jEGqq zw^!8$)`4u+0c1F~Alu%*!qnTW+LcowKIYWa2NRMoSKMe;0k=9CoOLRt2!su_--e+0 zsNPZIN7Jr{xpvKuCeVvi^)nbJ#~oLfk;(0#wH|-9R!L(wZrQ*;YHxrh7;s8_=~J%! zge_o6;3z`zBhd*8LnG!i{M}QWcHO*|J;zh09)d@%BEZ9Y--O!VEsZ^rNW~h z0JemCZP&o2SbJyK^-dJmKbI*B+B-7I7qi85Dc?UwZFvnnX?+Krpl)z;Ay8RH;CFaB8rI@3vt7 zG+pyFACrzD`miQ(_kh9j+Vrs7n#;jsd!9<09^RuTvefraJbd$JcZ5)}(at3qvk4i) z-w8T%7MpIQR^_HAHlF@t2CBaqe;NJ;J*L-7V`8^uSMdbzl`L=+T64xnm!==Ps0@xY z@EM-XO+>G@0cBmfT3C{BLLqSQn5QEAOzD?Un%zc91E;(mL8*b1TBEeP7gtmbXGUhs z;?}~ZHOQmgkCRlTY z3Ps|QrkR|%$K6td4uYRu@akO)KQGv;-~Va5GdjiBu)iYa5{l$@ z$h;rps>A?xQao z2zESLnOi{Nn0dgcH8~Rw@YVW^JAQDpG9jeVS*IqvL--1rg0UWZ4adxYNM*tE z2KSt>ntF6aQEqdTn6v9|ImSHZC6&q&6#s2yfg+%)ntM}t+|GWJ>h3HTqo*fVgQ4wg z&kbD0V%iJ70cY`VaR>dXa3SRsNnF>yam|HACq~twYUEni%*YP{LpS1j%G-?6`_q?^ z)T-<=UP2`ByQVr6QHgt-m}oI5%Qqf(!a(eE~M9N;f;yS2jg0F zs)QD6gif-VAyFKzAkCz4c+&QLz?aQsdAs&4*N3|Np^z^kzf;mKXJi}B#`U`y_sN}K zmpXh~0LiHUT~V`E5}X;{%^wi*m>#Y`Ck__aH_fb`pptAGoV;1+Hf(wZ zt-zJy0yh?MTV%*nD?(s)|IQyW-aJ$Ie@wHv=oKnc%h1PmFxt zbQo_Gn07hXZ{buguAB2R?Cg)zQFRc?Wlw7~<99kWUvRI}3uk`5j+#_!1o|NjCUFgm` zhuNtDd;bEH(_G$CRK;(9o~ql1hFOB8+o8En)4YVu)bAMlv(nJv!EW>Eym`=Xft@M4pl`>*R*GS zy-xDU%AmQH@*9xsLmdaCx5f@OicvL@yS9h^-3j;jykAz;@S08CTjrf&Hi;wOs*N4L zdnKAAz5HL&#Kh6=JMQ`}V`+qG6p}ybz03>=iDCN5f_TwsW_(c5R8GkLFV_JKSgtio zluf_ga+3A=e!*_^33FVdLs5O{!yB>x<(-mywu?X<{SV$PB$jr2*EL)08N1G)hd7ms zVD5Ltym(?};tdy^7bi^Q{qFg=bt$ z+9b)o>2zzFK0&qjA4L{bZ`-sfwxt<8pAzCh=)GZn-soyRT$8qLOXd6bjYU$|z**^% zu~f`$GWZ)h6_NMl(dIWPPbCr&j8M<7B{2wA0L}{AyLg(mS`VMye0W>LxalC0*LFDx zw!l*J)gw~mY$X_Yzo-5}jDDh?pacRw;R#-^R!`ZlUm-5D%?8!}Hm+4JJG*U4hh#E# zAdPC7dpU%}{*s_wcGHTUiAPv0b>%jF*0pfeVw#tF(0G@8&#+v0Ykb=Bfk_?fu7FPf z#s;R);Hh_ZsfBa}glV$6;yU=bn+H#_KC*w{=9Ft^2ePJtz0b-o(RnJaXxR2ogpTZb)dMKw!*Rg5i%O&_Q0r($RUgSE%GZ9;60K9d{Axu)VWD7xt}542u+FGv5`a z$-;Ofr^E5N0(bdAX;h;1=*1+;YY8>8{XQ%QoJ7WHYWb$mQ=K%UekF#po)7yr#Tyd| z{wrOUcGIT1V21%QUVaC?Alg~6>P!YB9Giw1@$w!^A@Ew>`_|d51x)*%4%K z6N*>>qpv%=3(?wQE(P`%6QVi8;coN+YjgaI84=5~EV@gfaS^t$rayk)PPz55&GLHA z>IPXLJ@_(x)K01De1jt3*y@K>-0okH5bB>F%X*s$M{BWdF(^z)y{3x}BPWYpSYMyd zU$-GRqCTlL9wZ=3rv>?P-fLs~$&(t9vsn-y`B{A=i5t z{~4?nIFz@Kp>!@^ZGv>#eieqZEMPt0?QjnZap`Nn4Ww7J&Z0{c9<;rcPf6^)aS7^a zB^H8ge*M~43h-%TvbTZNL=(s9Ro4WZIE${u8g*y^8S1OJ(-Xt~jO*H+LJuNAS}mhA z4)g%{kE=`uFG~|8WP6gn>FiWnc}xzjjI&{#M^quGJsjkaHuCVyotB?I-*mW4&SxS( zc^pmv$xP(|F|yj)JePLE(8YRI{SaS4I+*jL{{@X-3mP_~+XKqmp}&G6jxdzSb@p-K zAo-eI3i8tdOmB5v0K1>zV@k$ldiqp$DR{F`8LfJ;SP;}g3SxDhKTwKur#4C8iCLti z=JyMZ-Sx#*v{<8$G{V+)Xwf93Os3Fzq*d!wwyZV2xKCEc%HkBXe>aY=g=WP`AnqQvR z(`1Z!Sz{zBuB#(5X0-YyWd+-i zy-*dXd1YeK;M^jJ`kfL*>#*sK;9aQH& zO%p)M`qb?u>{d>N5sjX&rCbU8*G7LLiC~52doq}i@#Qp6)+|Tz^gcl+;&hv0X2j}Q zUpDn{VSBYgxl$>}9nLXW4}Xu-?co8-OvTa?ci)Gn$4y_tMG%<3_vnZslsfD_0P)&T z`KrIALW8t~BW`etPd`+}!1z&M#a=mi;A-XDeH)PCDR~%>!wEp52nweTI~c%^Kwz7B zn0B*c$#;ElcE`sfrOsn)9M%DfzvCGfkz=j5g&=3}5|U1}>1WYkh49O+0s$8clKw6P zR;1#0=h`UIh(rAAW09>+8%5wtx9pkx=Xjs}8&CE9`)8rH0|u&vqjmc|GD4=arfV^8QCdTU$4jh(|h|1S%RnS zDhLyTU#MTYSI<=TuzV8|t#I0%3g1Fg}Pl^z~ zW3L3Y6|nT<8Be=3ZZs!}t3iybU~i*QDgNJ0;01^Pw>{#uMN6Af;mZY7f*QnmIJ~Q% zv*&l=uK@!+j2O}ZrR$LP>BYZ8Mb`6hzk5fU;u;wUfK{NS(GzvNej5hk3gsX?uAzqJ zj>71VfTb52$QB5V#T&VuRW_01jSiN*2!j^bfc`?z$jhctzj38(wF zDei_Ph>~}N{#ai+MR}c!D`syE(?uxLrgeonTREb%-^tspIgI=258ISV|8f84`rtiK z80_GRZYkbH4yMY2eRRA|np5)*b;3cE>S?pThuI>h(CNOZvlBYiu-2E+_RnG}q-iGF zesiP`h1X}87T8-h~C_ae6#yuk4;==o6J2Qh7X?P>9N z^I85l6KC{pVLiXnokx748!?coJ2(@L8Dj&FPSOGbse|C{9b8NBa(P?MM7c^?gOPcaVaRo<)~<^ht2%;!cRA2?{e9^gso^zPjwivJy{Wk z#qJgsoVP(T*`V-L{b3K^JaL{JUBGJcYt_yk4vN1WP-2{N&;JypI+OX$S#rVopiTXq zJoleOoAXHq?8Bn{0-knskbcj@n1Qp$f$`gy$pc>^6Rmw$Pa3qhgG`b5eF+V_CSnpf zVi`^uIwIJ#4mb3Lw;RHC$#+;BfV4 z{YH<>X=Hx~RrPi9LLBM=y^C{pgwi(_V~B$c=1O*)!)3yAb>z(w&eD805Q_6D&Hn*8 zsK*=~t&anCnl}|u`<7U0jAS7`fET3i`exg$fx3e8 z_{YQE(rWWwElS5%4>=L_bHGDCi%{O2NQiLG21ysyx+0y9-5DCDkwuYvj;)Wk?Hm1B zXRn=|zUtC%nDlie=C-uX-=7VweO|rJUC1A|FYpS@cqNLJm@4bbHD?^?j@|2jK_~>i z^JbXuj6t&GaaXYMy7lGE4TXc{CvTuIm9M?504#b{!3Px1DE7b}WbT_J#TG~dZ=`0( zznK|XlZS?G>B>X@HU;r933&doYxP4QyVz2_-*R#wj=Yq;}%6j39;U zPFJ+4@0-I^Yb;lg254mLO2wnBdy7=~?VoTPEKA%ioO`Why_HxKH%qlkCFMLrX0npW z+sYqCJ^BDqz-f#IiHgn}!VA=qqa|+AUUz381o_#bgxaJ{v0ddX!AgLYif1fiOIfZ? zoCY>hi;F5*`vspCbbfON-T)N{wFjvAL4I1gZZ+nRKw0c}x^eA_^o}Aclb_Bm$3w^U z-B1z@>F*@@y4{+yKO6XyHfw9Odz(vbiDmYP@m}FFk|{rsnSTrruG}qTj{74{vvVzA zE?-TD(I5d}8llc^0HI=Vu~G6iJB&?fro1Hg%;tHF^2#lwNK=P zxB|nE!PxR^!J1i;N7&1`SDSy*4Wy^~3;!c5F57SfUXgo=g_HO1wXya-4 zedg3TDy*-2-SzK~UxplH%pa;!R#IusZDA|OsqvBK58^HSUXDUP`Oyyq0N@ca*I%Y_ z@HM{`1VE66w@%O)`ITj!{#;G$(GH;B31)_1xK>xWd%#H!7-Y$+^+n26{oK2$-B&T$ z`vn7JL)B#~sG(PV`LFUv4cO~BX5J%V+t;Y-YE)tiJ$$BpF_t?dwvhxlWH<156@U}@ zrqdr)Y7!+{>#R*M+!o9J7F(rQF2Nq8q~p1`nX=YuE!z1=(ridh$E9X!Pm3VK_Ngw9l=as8SAS#jyYP#cp9Adw zHd7zHI|m3K&mH<=?M-7!d3+c)846JkHGV#JJSO}g@ZSjg1n_gH_?Gz($e11}V8Kj0zwG>;j?%~v);V@%{OSd&UNO&%2E z=8E+W?f3!S>6X3wp~BQR5r66eVUIpm4K#qq_)<8hJ8dLz9^#SiX;!o`=n4QKicTcj z@Xlxl{HmUCDd_6OYZ~84K%9Oxf=pi+-6|{$TQ2hSafrgp{l+Kh(cjdi?cv5uGdjfk zGSn_^QO`IgW|uSY7=T68&kEU_IjWc_Ed=hSO26ZST3c`*l6>ZsPkrRt&$=TA?gI z_r-|489(on2L-5erlv-xs`5=2)Re9Fh#Rs}LIqN~(rl`a+Gv~ts|>Hua$#;TMD7KQ0RxiZ<)&i)u#4|Qcr&DVi3XUc!Z}Az>1r!HP^+2cw?<+sFCi0LxO#{+NOBr0PLk$0 zSH7X%rt@?z%E*G>YZ^#!#jhPmkh8E3YhoCWr~Pe@IBR`a6P}qY3$voV<6DG&9ps`^ znz*|&o(JN_!`SXgF(?KA%rc*Bm8v>tPlDX87{47nARhDd%rZ#Qedo9_>$;}-@7%e` zlc}&++}U*(gqcH18A7!MN|{en*P_rt43?Q(*Se@0T&E{ElI=eheJk-pG*gz?LqT%J zTUCUiPuc`Ph$qUO8v$S`lldI2A+leE(HG=_?$k0CpbtxZ53_T*?5;W1LIxT>d&>+>pp`$`p+oVy%cpP7V%GUlF`8<b9Hl_T33I_Z0i2I6^EsPUi2HAs)8$9mxFZr zYMR8i#;&Ey;yh=VmbQtI$GhQwVsqeQx@hC#I$74=RFC`+N{hAJCg&m&hg%yDDUlhT zEy;!TAY9+AJ_L0pu1!fV6O3Cg83-p;tlBgSn%2ZeXJx6VkSO*l^isg?Hg`8a05;Iawep7L8xV3Cryo|kgy z?QFw1>OLNe)_H?A1>@KWX?iPe&A|ggov*Ma)4mpu%?I>O4?p}An}}A0=SCu%vlehb z#QPoqUb$MWIV2RI_zfQ)XzNJu#bbVt&3tFWN+Aew@MC|+a9YN-DQ#xNH`ltbw2{Y=)a1Px}B--4R!-M{W9bz139GT zb61tI;sKh-H)zVjF-^J_DY7J;mzOwDusS-Ry)#f0i`NlKhf@;D^XSM1SfS@!j3>+s%6 z5u}8)vStChAsioCaMRy|8BYKC81N{eN93LM8zF{;Ybv%W1)MW^JR6C%0e>?0umxrE zY8q1ep`K)1jxN)capTX7H0egx@H7*MZu8-NctbDQ|9ooUtbi0y0?1ow09HZf(Jb!j zIdz}6l?8#H_cDhXA1c!ZT{y0@K(^H1+o=yR4d;^RbL@S@LF|4j)mo$d-I$)6Jb|P* zwuedaJ_?~)ehv!R!R;coyIj1@&hSn*hVzs?P*Ke7nu z0U;k$&A(HCm)9oSQo^Lvy$Mw_a4o^2m|%&wx25w>Y3_7cGGI&38yw~_@;MYa>feoP z_qbPRF7zFGS0wpdbJF5qGz1+~G}Cpu5@(E_&i!QxGb*&Nsq zQHDMC>N}!0LT-l$6ZR^dlrbgjKm)d6pENx)AGZgkOOKsriI?AW*d+U6G^DYeD!eCU z`VL}8!4jyK+0mzXn!>QBn>CzUDRDkklUIwr#zoQzwUx zORZE2*_I9{DccEVnS%>vO8Fsp41TS*o<-&`@E=WKEcMr-uMp%(frtb#=Ug|!Q^g$u zG-thXyA+E|abR!6&$9gZ`tjsPat&$(={U0$}XaJ4s5o^5ipu=`4UXN?I!Zw&%hwU`KTD zlHYR@mKr+y{%_g=>-?{kO2CRbeH7R8KYt9{ycx_C`?CMg|FEwbKYf=MP&FJ!bzZlkU_6u*n_oJnigdo9%=CuYG84Uax2zWzU;RrUb;QC{HA>=M zJ${}pZUKKls_DEfqXQ@u6Qy}*fK3Bd((>?tO_0*Jmxz)X#!UmkdVW*tKyh%0GE=^% z-M>J;9(fLVb10kyXGVNCATOd zia<`BwUiHD(6{PJMYKvN9+cGA;_-9I9)Zd7jqMC7=WT{567(IUJT#6zjK76^qd})S z{Y*R72(YYDZzN0k^Cw+U+)B@U@s^f?nZ*1^ZYW-|;LHid;a59OUIabz^%hefBhxLf zx%?p@5D@raFF$Gd&bM%C0CYJwfnBkN8=~RYpJxVqQbUh+{ZBAMqXJumWSV+aRm%PEwWE@RBWSj?^zf)Zh8#8hi&TR& z<3|>4cVZP6k|bIm@fLtGVeFfe&=+w}leSEk6HwN-Z4_YlzbDN729U7cu_@5>Q{chj z^>>lxzL{RHGFR5?4tGLx=El;ZVPKM~YGn^2k)hbshBz2r*;D#oQk)>9-pv-V3|NYs zq1sd0;kvbqa5{L@XJan~xGb`XuN-gREh4KPLz`QqUOth+O zt4-%Ib?n*qwrVV`=wIq0+s`mUkyEa1Q~Sv3(fsPs70rLPOK#WlHFx}f-@vD)&>+D} ze-xrTP+*tu6sF7wco?A6mfGJhmt2a=LP*M zG#3Psz}@BMhU^mi5z&!NGLy>-IsjVK^+OdBKKc)g(ee_)zjf(ecjC-%u>gr6A4;K`jhO-ZHMjz`h1}1<1Xui%wP2B9AXF`co zY|FI*U2H0MFb^+iDH!bt0c@N?Q?}8sj7F~r@$Wq=1ev)U6{lfDbDmG z7UWq{f{o96H{?ZVK%@kY=&uM5Y1xOa%rArL&e>&;c1G@M=rYv?q!SQRviFZcV%SrmMMew@(+?`c?yaY!X$bMF$WGsXbgnl7A+n*?|dOi;P6e@ z!FIOwhmKkRW$58LAT~V&tD>>B5uAUUFUz_rnxES+JlP6=r2837zd1p!M(R2 zOijlmLB31KJQ0GJfY<_2AN@%)$gbc+Etz0U&9ZKn*<9)1VI?)GV4R4qKoBjU`UX;k z){+$FHe^U{yDJiQnLC4FAJC=6wMM8TD-% z?g1IZaG#MD)zhuDSROuqt^B=~RM|c@iCbnh+|>xp=v%mO6u!Yjh;jbg-mj?%THU z8xLN=NTI0ihD&!KRU?Y#y=Pktgb;@gzZQvK0(w@nJ$&laTjRerxVts?gU#i+;@VE> z6}*n~k>)Ixip<aS+a*!p7m4_LV=<ZOdQQsR!&#?M;Mk-Xz<|o7bQQ1`0!(p zDMawvML|&J>>eNFn^{r$gY<1X;II-k=ipjeR~wXQj2QuU77)yja5G0=&IR=g2fh(el zng6*&+E##-61)L|WS0o|Ag&U?0l%=;{X)vO?LP=EsN6<*7NEBT^t40Y=kxNK-70Em zD!`-nY>dq9MehYGlZ_}hGOdsDR>Lif<_|?y5#a1L2_WrKe_s@376gU8oRUg7dzE7V zKL<43+_e5bWWGh%+uUPk7i7-o-Yq(V)CgB|4f8_IWcx(Frr|OInGc#^2Vdt^s_$B466njo66>@#xh)LN0js};c%~K)%9EEOCTLM# z01Weg6G6;7zrXYYxEB(_1z!cQ!Cp_X)=WUh0{lPsOW*<)2v<<==YXo>Musv#y1+WP z{{i7*w!k%vL$Gwb=m57p z5@aRXJV$MZ$F_=~x;dKq=^#D+TKo?9E@u{dZZ`M;ICju6!=!i=b$peOc6kl>i&c}m zAie+^Iv~sL-0TCj5y%`LH944rmLM;8p7r_J(O9wno!knubN}_)AD7a93!T+ud{Tqb zr}(KX*YvN=s&w{RT!Yh_^cT;?RG;YQtOgnQKK))Qf^!zYh;bek(6W2UI7a5{Mpo%| zXIwD>5=#Wq5Y51K0_fH3La){6t8&oZ%SguKF&F=GYWj@){r=GVAmdwGGeF{nK%g%{ z7mb+~dpZ&Y`u%|i-wG= z`V?8myiZ-EN#|VTTj8L_24pH$K2XsA_g->J%A=Uu`dPt|SdNc>EjK^D8{Y9VLtHgW z&?JFmI&g3&9RYlpsL*;o+?A(c(ZLHisXC_ONHp`&mbH{;`Wjtl!%@I@a5LpcAte;} z5%hVPd5ny{L!5ENOaZyOGd`{WuiOTF?<_CcI;QH*>YJm_0Q(C!38Kbn-ieP_G=K{S5)&=9gAIO2)0Y5hbM{3IoPWz8As`e;+ zr5%v|DU5IC!+Uh5c$U|caAe+F*P9vXQziLC{m#tYftMZJR@~9&RRgyKE@0;@Dl1Z;!Zh=`|IpF$qCM=>3C6q9Od2-*u;A_44Acr`&x`9@3&?KrzSTW`=ZTCf$> z|CYaOtT36|LONd|l}FIx;AMP?*=TfM@149=K)qDYaO+g$TXlBYmI}r2L=HTt88}pC zccWxqpAFj7-qFa$E3Y%7PfZ(uWkTBEf{@I5(F#{u2vis+H6Rxrl1PjE0z!HD} zdx^q;C)J+br!f1Iic1O0=w1qX?DwH4bOBie!T?27P8GPt!(6~mj9Tz57!CzzGrm;H zYyS060$iF<0^*;-@&8P?!R>{?^I^3^HvNmMFg)P;7UU=d9HWzmyE}g(IUHOlSXUW~ zJHH(FvK*UJ=vd!9LkwNuI5e}R0;SKsgCiV`sku2ylU)J>_L8JVQk8G3^NcVMw%bG^ zL-?VHq|mgto{AHv`90(*pkkvIKg&hhIUmsnP~|&|M$P zoX1aQ<0j3tPQj%qyG3a`YO}{3wS(5=5VHXYC#p9yxmtUa@4q*;j~v@eQ~pq%u73R& zAQUs3OW_fy@?pjIPUQSq6Wx?j6%gQdfcq2GkLB1l3Kv9q@|`CJ3-2`wjl25HMKN1| zi1>pMFP(Imj7+8@zH2}b$>spx{AlT>krfW;xYGv$e78R0{PK?L3V$%ji5i8OrFL@@ z!M(4VlZ8)>Unp7Hyq%nv*VkE22?Jl|;*$lw+&w$a2U}QOq_3~(n9qF2ROl!URIvdt z(8qWed6S;#MihcH2MK~IfJcLUcMePS>_6Cs114{-o=gAj?>o1n4KT!ny3)ovU4kRI zdmTw}q|x$#lwHrg+ohag3(@w7(n-(xH?30ODPp@Gns5>9qPv+ znDQW5$?!$Rs^!|6gcZVsxd-)Q>PtlZ!$r(OMX2%lquV`C0l}6RHJ~&u25I6@xtOJq zzCVC1`K7qzbKwAamFClsgQV}vt>c=r;jw3hb}oJuJhZ6IwY8vR9m=AWE!8`3 z+1k&tMc#AZeJz(DRYG7(nyKHv$Jr}Y9SK&;SO4tkEi0*w=SsHkNi*ElpjS*0gE z=qKd8PqIPnRL_1C;7&W^KmvdBZ%a@m`8BD9T0n}|G$npIsUT=Oatt*yNdoet4*cD< z%P!+50oc>E`mLKv4t?6|V(uIs;%*C*fH8hzQZ3a*)0_wIX-K?NBm*uxV5>%3wVHJ^ zx|ELv1R&oJz;r&ky1Va|@|Ol6%zUCbxh-ITa`F0ne}Ush+Z_8*mDRKh->AW4k=&8% z3e#dmG3V$&;(HR8m`~ZpX?x+I_L|;LG~jf!5lmKDkxptdiNjO9joWQOGlO&$piv1S z8F#!aYH#{UuVQrh4##bpU<)QXtg}+}6gL{myeO zbhji*iGa(RIey~Csm1;)yPhV=C?y49E{*@+_+=X7<<19ej9zBb4bqg(x?A65x@5`A zW|C3_Qz1=arUtw`Tfj%gXu2116*6M9dZo`XZv0%#1~_tfRo+fxm;j{8;=4$cJ{JS7 zR80G3Ef^#IhzU(t^FkT%35p@eABg3VzW6(Y>Eg9Ayb#S6W=hk~a2l}OEp&Z&lDf#N z1gqzhBrG?`Ok#e{=!rPxuoq=x+!oVV!G$(|Ro=IZD1Blb zvAqgHy#?wMxIZTnFzB}9`dt#AYvF@hV{k*ChQLh%G8rWB<*Ii7o6&x&|gs1HX2;*yzf5u$p3}k zakTp1zv*7(X-j)w4!U}_+p$s+|CZKJTSt)TD+(@1Ht$a!tqlW{6>9Ar@pnWjtoMjT zpnqR=Is?zBQcyxQb!&Rk&!6Tx8zYqF_Z1sT&gGm#HjshrVMU80x;X zh(KOT$jKsDw?T+;`HPh;HB`NofbL|0Xj{2k_1pTckGRmEJCV8Cp>%tG#de3D+_WgC zz`#|#-8F_M65*+msJ*HKpOi9sW@w!Th}~2eA%s%9t$ph2#*G>iH&&uTB4N}P;mpD! zZbeO1yzqHLUBo?8s8#L_p-h*OLw{Ot@~sGuK_uisFBy{^O;46tbfq18fG*!SX!l?D zwe%Ushe7W?0q?qf>bp1eY~|W*r0H$1oSy{_9mCJoc5q*0P8(^BT|KQl-w6+xqWI`c z#H@H7d}LfUyxvE-)-_BIhqKgqOY0jd9JWX9GrDEVlGKedolcGTha+qnPUZ_=WpUX2 zx1{^7&hL?<;z@q$&*K;^=^t|;Q4g8PWM5;{PQZpwD>tmL!{ZIENlw;d`-wqf=Y=_6U*5K!|=-i4Ue zPt3Xtw~~9^e!E>Z=9bhPV5IWjH>#>~J5E>7id8>v@)CT&)E?KF#-+Rv^tBI<Tu|m(tIX!y zAn~jxPd@f3|D?5!Ua`bR@e}g*nf0*-2$Y9OR!Qo?&OhncB%$|E;5HvPm}PoYSIw_| z9!kGKCI$CXm&-jnqjny?+WOvkj4DDNy+zY+^q$)O@Xsq@8Dlz#WwfNUEH0!|(j=YW zgj#!Wlk&vTH=g{eqjrTkfD8S4J0r^8%V-T$9JZ`5cs$NBXto5{5(TvU5 zz|wi8YN_Z0=-pRv7ruV$_q*+YkALqEOWyMQ!?+4FRA8K+(=HYIjyPNSO;KtGwY~(X zFlsfDg_jcZje%E*WN>#yM8vY7*BN3in!5`H#+u}cA%u+WNBv{P?ogyRRL(T{H)B1- zAnI4Za*j(I9y_`FpbZwMH6sJQ$c!B??51&}C}nEVu9VQZSw@ps7231N!(22qmS_-N zB3UPb5aK0x9s34k$|F8ng_1h_fU4 z*%a9>iI0|QH$4~;o`+;w&EX=$jBWtQ$nR4A`g`9q<&=+QFP#oKd#elsC0HIZ(=8f z?#hCtN$0;5-6r)ND1`ID^MG7KY@s z!wGMF3Vk`-vuX#vevJFthwPyLuoYG}@>hn7o!aF5lf!&~e)1OrXlUdfKJ@3B*~%B= zTbLc#)`tgyk{)1YISXYn*7dMBs7SP4W5li_Fj$oH!9< zObV$3O#!CNB8kgUMBAggk5_*8^ap#(Ux(z9ao?+f@1=ZJeGf7IoaT5A%M(#PX?1^@ zp-0)^^B_lI7iTU>XW_jPKHV1hLeTGpxs*}u>(C%>aDo^Giim@VK3X?MRQS82io=nerquF>9z48ITUQ`c>q@enDFO!+JU#9*+t+Y z)r)MLE&@o4*HB9#m=9b!Ru3X5H|Ifb9Lmi#yzJe7vdn`{7yOQRgb*sN!4G6o2FHAd zFBWS*H|x??C8a1WeMfDHkT`#;NHQr)- JN@Pvm{x1W!TfzVU diff --git a/apps/client/src/components/dealtcard/dealtcard.tsx b/apps/client/src/components/dealtcard/dealtcard.tsx index e258dffb..e7e1759c 100644 --- a/apps/client/src/components/dealtcard/dealtcard.tsx +++ b/apps/client/src/components/dealtcard/dealtcard.tsx @@ -11,14 +11,12 @@ interface DealtCardProps { const DealtCard: React.FC = ({ gameMode, card }) => { const roundedClass = gameMode === GameMode.CUMULUS ? `card-rounded-cumulus` : `card-rounded`; - const translationClass = - gameMode === GameMode.EOMLSEC ? `card-translate-left` : ``; return (
); }; diff --git a/apps/client/src/components/footer/footer.tsx b/apps/client/src/components/footer/footer.tsx index b992f48a..277de520 100644 --- a/apps/client/src/components/footer/footer.tsx +++ b/apps/client/src/components/footer/footer.tsx @@ -12,7 +12,7 @@ type FooterProps = { }; const Footer: FC = ({ short = false }) => ( - + v{packageJson.version} {!short && ( <> diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.css b/apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css similarity index 100% rename from apps/client/src/components/randomcarddisplay/randomCardDisplay.css rename to apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx index cf15f199..f4d08f86 100644 --- a/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx +++ b/apps/client/src/components/randomcarddisplay/randomCardDisplay.tsx @@ -1,62 +1,39 @@ import React from 'react'; -import { Card, CARD_DECKS, GameMode, Suit } from '@eop/shared'; -import { FC, useEffect, useState } from 'react'; +import { CARD_DECKS, GameMode, SUITS } from '@eop/shared'; +import { FC, useState } from 'react'; import DealtCard from '../dealtcard/dealtcard'; -import './randomCardDisplay.css'; +import classes from './randomCardDisplay.module.css'; import { Button, FormGroup, Input, Label } from 'reactstrap'; -type SelectableCard = { - card: Card; - gameMode: GameMode; -}; - -const suites: Suit[] = ['A', 'B', 'C', 'D', 'E', 'T']; - +const allDecks = Object.keys(CARD_DECKS) as GameMode[]; const RandomCardDisplay: FC = () => { - const allDecks = Object.keys(CARD_DECKS) as GameMode[]; const [selectedDecks, setSelectedDecks] = useState(allDecks); - const [selectedCard, setSelectedCard] = useState( - undefined, - ); - const selectableCards: SelectableCard[] = []; - - selectedDecks.forEach((deck) => - suites.forEach((suit) => { - selectableCards.push( - ...CARD_DECKS[deck][suit].cards.map((card) => ({ - card, - gameMode: deck, - })), - ); - }), + const selectableCards = selectedDecks.flatMap((deck) => + SUITS.flatMap((suit) => + CARD_DECKS[deck][suit].cards.map((card) => ({ + card, + gameMode: deck, + })), + ), ); - - const selectCard = () => - setSelectedCard( - selectableCards[Math.floor(Math.random() * selectableCards.length)], + const getRandomSelectableCard = () => + selectableCards[Math.floor(Math.random() * selectableCards.length)]; + const [selectedCard, setSelectedCard] = useState(getRandomSelectableCard()); + const selectCard = () => setSelectedCard(getRandomSelectableCard()); + const toggleCardDeck = (deck: GameMode) => + setSelectedDecks((selectedDecks) => + selectedDecks.includes(deck) + ? selectedDecks.filter((selectedDeck) => selectedDeck !== deck) + : [...selectedDecks, deck], ); - useEffect(() => { - selectCard(); - }, []); - - const toggleCardDeck = (deck: GameMode) => { - if (selectedDecks.includes(deck)) { - setSelectedDecks( - selectedDecks.filter((selectedDeck) => selectedDeck !== deck), - ); - } else { - setSelectedDecks(selectedDecks.concat(deck)); - } - }; - return ( <> - + {allDecks.map((deck) => ( {selectedCard && ( -
+
= ({ secret={secret} block size="lg" - color="success" + color="secondary" apiEndpoint="download" > Download Model @@ -66,7 +66,7 @@ const Sidebar: FC = ({ secret={secret} block size="lg" - color="warning" + color="secondary" apiEndpoint="download/text" > Download Threats @@ -96,8 +96,13 @@ const Sidebar: FC = ({ Pass )} - - +
+ +
); }; diff --git a/apps/client/src/pages/create.tsx b/apps/client/src/pages/create.tsx index 8edb0711..22996071 100644 --- a/apps/client/src/pages/create.tsx +++ b/apps/client/src/pages/create.tsx @@ -269,20 +269,6 @@ class Create extends React.Component { const cardBody = !this.state.created ? (
- -
-

-

- Or create a new game: -
-

) : (
@@ -549,7 +543,12 @@ class Create extends React.Component {
- + Copy All
diff --git a/apps/client/src/styles/about.css b/apps/client/src/styles/about.css index 3244b385..60beba59 100644 --- a/apps/client/src/styles/about.css +++ b/apps/client/src/styles/about.css @@ -1,3 +1,3 @@ html body { - background-color: #000; + background-color: #fff; } diff --git a/apps/client/src/styles/cards.css b/apps/client/src/styles/cards.css index 887df68a..5d65c4b2 100644 --- a/apps/client/src/styles/cards.css +++ b/apps/client/src/styles/cards.css @@ -24,10 +24,6 @@ border-radius: 25px; } -.card-translate-left { - margin-left: -5rem; -} - .playingCardsContainer { position: fixed; bottom: 0; diff --git a/apps/client/src/styles/create.css b/apps/client/src/styles/create.css index 8facce44..8ed24d28 100644 --- a/apps/client/src/styles/create.css +++ b/apps/client/src/styles/create.css @@ -1,5 +1,5 @@ html body { - background-color: #000; + background-color: #fff; } table { @@ -19,3 +19,7 @@ table { .space-top { margin-top: 2rem; } + +.centered { + text-align: center; +} diff --git a/apps/client/src/styles/random-card.css b/apps/client/src/styles/random-card.css new file mode 100644 index 00000000..60beba59 --- /dev/null +++ b/apps/client/src/styles/random-card.css @@ -0,0 +1,3 @@ +html body { + background-color: #fff; +} diff --git a/packages/shared/src/utils/cardDefinitions.ts b/packages/shared/src/utils/cardDefinitions.ts index a9a79a2e..1bae004a 100644 --- a/packages/shared/src/utils/cardDefinitions.ts +++ b/packages/shared/src/utils/cardDefinitions.ts @@ -1,7 +1,8 @@ import { GameMode } from './GameMode'; export type Card = string; -export type Suit = 'A' | 'B' | 'C' | 'D' | 'E' | 'T'; +export const SUITS = ['A', 'B', 'C', 'D', 'E', 'T'] as const; +export type Suit = (typeof SUITS)[number]; interface SuitDetails { name?: string; From 903cc84f49b9b997b62b74f50a3ad03c06273361 Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Tue, 19 Nov 2024 09:42:59 +0100 Subject: [PATCH 6/9] Fix alignment of dealt card Signed-off-by: Christoph Niehoff --- apps/client/src/components/dealtcard/dealtcard.tsx | 9 +++++++-- .../randomcarddisplay/randomCardDisplay.module.css | 2 ++ apps/client/src/components/sidebar/sidebar.tsx | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/client/src/components/dealtcard/dealtcard.tsx b/apps/client/src/components/dealtcard/dealtcard.tsx index e7e1759c..d09bc05b 100644 --- a/apps/client/src/components/dealtcard/dealtcard.tsx +++ b/apps/client/src/components/dealtcard/dealtcard.tsx @@ -6,9 +6,14 @@ import type { Card } from '@eop/shared'; interface DealtCardProps { gameMode: GameMode; card: Card; + isAlignedRight?: boolean; } -const DealtCard: React.FC = ({ gameMode, card }) => { +const DealtCard: React.FC = ({ + gameMode, + card, + isAlignedRight = false, +}) => { const roundedClass = gameMode === GameMode.CUMULUS ? `card-rounded-cumulus` : `card-rounded`; return ( @@ -16,7 +21,7 @@ const DealtCard: React.FC = ({ gameMode, card }) => { className={`playing-card ${getCardCssClass( gameMode, card, - )} active ${roundedClass} scaled-big aligned-right`} + )} active ${roundedClass} scaled-big ${isAlignedRight ? `aligned-right` : ``} `} /> ); }; diff --git a/apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css b/apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css index c50a7ee2..dc41ed7e 100644 --- a/apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css +++ b/apps/client/src/components/randomcarddisplay/randomCardDisplay.module.css @@ -5,10 +5,12 @@ } .card-deck-selection { width: 15rem; + cursor: pointer; } .card-container { display: flex; + position: inherit; justify-content: center; height: 600px; } diff --git a/apps/client/src/components/sidebar/sidebar.tsx b/apps/client/src/components/sidebar/sidebar.tsx index a8b5daf1..25eafbff 100644 --- a/apps/client/src/components/sidebar/sidebar.tsx +++ b/apps/client/src/components/sidebar/sidebar.tsx @@ -100,7 +100,7 @@ const Sidebar: FC = ({
From c77ff993ab8ad6c179fec1c8655685349f58a206 Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Tue, 19 Nov 2024 09:43:16 +0100 Subject: [PATCH 7/9] make logo clickable Signed-off-by: Christoph Niehoff --- apps/client/src/components/logo/logo.module.css | 3 +++ apps/client/src/components/logo/logo.tsx | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 apps/client/src/components/logo/logo.module.css diff --git a/apps/client/src/components/logo/logo.module.css b/apps/client/src/components/logo/logo.module.css new file mode 100644 index 00000000..424c1349 --- /dev/null +++ b/apps/client/src/components/logo/logo.module.css @@ -0,0 +1,3 @@ +.logo { + cursor: pointer; +} diff --git a/apps/client/src/components/logo/logo.tsx b/apps/client/src/components/logo/logo.tsx index 5d1888a0..3100be32 100644 --- a/apps/client/src/components/logo/logo.tsx +++ b/apps/client/src/components/logo/logo.tsx @@ -1,11 +1,13 @@ import type React from 'react'; import { useNavigate } from 'react-router-dom'; +import classes from './logo.module.css'; const Logo: React.FC = () => { const navigate = useNavigate(); return ( logo Date: Tue, 19 Nov 2024 09:47:36 +0100 Subject: [PATCH 8/9] fix linting Signed-off-by: Christoph Niehoff --- apps/client/src/components/sidebar/sidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/components/sidebar/sidebar.tsx b/apps/client/src/components/sidebar/sidebar.tsx index 25eafbff..ce8c3e2e 100644 --- a/apps/client/src/components/sidebar/sidebar.tsx +++ b/apps/client/src/components/sidebar/sidebar.tsx @@ -1,4 +1,4 @@ -import { GameMode, getDealtCard, ModelType, SPECTATOR } from '@eop/shared'; +import { getDealtCard, ModelType, SPECTATOR } from '@eop/shared'; import React from 'react'; import { Button } from 'reactstrap'; From 9c800c27180b9eaf1afcf84c5236c55133a48e94 Mon Sep 17 00:00:00 2001 From: Christoph Niehoff Date: Thu, 12 Dec 2024 12:09:57 +0100 Subject: [PATCH 9/9] Make background color white on all pages by refactoring CSS into an index.css Signed-off-by: Christoph Niehoff --- apps/client/src/index.tsx | 1 + apps/client/src/pages/about.tsx | 2 -- apps/client/src/pages/random-card.tsx | 2 -- apps/client/src/styles/create.css | 4 ---- apps/client/src/styles/{about.css => index.css} | 0 apps/client/src/styles/random-card.css | 3 --- 6 files changed, 1 insertion(+), 11 deletions(-) rename apps/client/src/styles/{about.css => index.css} (100%) delete mode 100644 apps/client/src/styles/random-card.css diff --git a/apps/client/src/index.tsx b/apps/client/src/index.tsx index c9abe757..271ea21e 100644 --- a/apps/client/src/index.tsx +++ b/apps/client/src/index.tsx @@ -6,6 +6,7 @@ import App from './pages/app'; import Create from './pages/create'; import RandomCard from './pages/random-card'; +import './styles/index.css'; import 'bootstrap/dist/css/bootstrap.min.css'; const container = document.getElementById('root'); diff --git a/apps/client/src/pages/about.tsx b/apps/client/src/pages/about.tsx index 4be12eff..6e4f4945 100644 --- a/apps/client/src/pages/about.tsx +++ b/apps/client/src/pages/about.tsx @@ -1,5 +1,3 @@ -import '../styles/about.css'; - import type React from 'react'; import type { FC } from 'react'; import { Card, CardBody, CardHeader, Col, Container, Row } from 'reactstrap'; diff --git a/apps/client/src/pages/random-card.tsx b/apps/client/src/pages/random-card.tsx index 0e7c989e..3eb633ef 100644 --- a/apps/client/src/pages/random-card.tsx +++ b/apps/client/src/pages/random-card.tsx @@ -1,5 +1,3 @@ -import '../styles/random-card.css'; - import React, { FC } from 'react'; import { Card, CardBody, CardHeader, Col, Container, Row } from 'reactstrap'; import Banner from '../components/banner/banner'; diff --git a/apps/client/src/styles/create.css b/apps/client/src/styles/create.css index 8ed24d28..6419573e 100644 --- a/apps/client/src/styles/create.css +++ b/apps/client/src/styles/create.css @@ -1,7 +1,3 @@ -html body { - background-color: #fff; -} - table { table-layout: auto; word-wrap: break-word; diff --git a/apps/client/src/styles/about.css b/apps/client/src/styles/index.css similarity index 100% rename from apps/client/src/styles/about.css rename to apps/client/src/styles/index.css diff --git a/apps/client/src/styles/random-card.css b/apps/client/src/styles/random-card.css deleted file mode 100644 index 60beba59..00000000 --- a/apps/client/src/styles/random-card.css +++ /dev/null @@ -1,3 +0,0 @@ -html body { - background-color: #fff; -}