Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Landing page tests #242

Open
wants to merge 28 commits into
base: Dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8b275a3
Merge remote-tracking branch 'origin/main' into feat/seo-add-suspense
Ase020 Jun 10, 2024
2df85ac
add admin:sales-table & yearly-graph
Andrew-Ochieng Jul 11, 2024
10ffe38
Merge branch 'Dev' of github.com:SpaceyaTech/SYT-Web-Redesign into fe…
Andrew-Ochieng Jul 11, 2024
7609fe3
restyle trends-in-sales section sales graph
Andrew-Ochieng Jul 11, 2024
3375217
fix: merge-latest admin changes
Andrew-Ochieng Aug 29, 2024
109e960
tests: add landing-page-sections tests
Andrew-Ochieng Sep 3, 2024
5dedea0
fix: linting issues
alvyynm Sep 17, 2024
1da5576
fix: linting issues
alvyynm Sep 17, 2024
80a8872
fix(test): view more btn functionality test
alvyynm Sep 17, 2024
6de3e5d
fix: linting issues
alvyynm Sep 17, 2024
c96f67e
fix(test): 'check how we work' test
alvyynm Sep 17, 2024
234b04c
Merge branch 'Dev' into Landing-Page-Tests
sonylomo Sep 17, 2024
63b52fe
test: create data-testid in UpcomingEventCard component
alvyynm Sep 17, 2024
cffe922
feat: add props to Button component
alvyynm Sep 17, 2024
9b01d84
test: add data-testid props to Button component
alvyynm Sep 17, 2024
b8a9b9e
fix(test): properly check if Our Events section is visible
alvyynm Sep 17, 2024
6fb3cd1
fix(test): properly check if at least one event is shown
alvyynm Sep 17, 2024
cbe812d
fix(test): add appropriate selector to check for 'View More' events btn
alvyynm Sep 17, 2024
009df0b
test: assert clicking 'View More' events btn opens /events
alvyynm Sep 17, 2024
caed3c4
fix(test): add appropriate selector to check for 'WHAT WE DO' content
alvyynm Sep 17, 2024
4f3c640
fix(test): assert 'WHAT WE DO' content shows
alvyynm Sep 17, 2024
7ca29a5
fix(test): add appropriate selector to check for stats content
alvyynm Sep 18, 2024
4d16a04
fix(test): check 'OUR IMPACT' section title and stats card test
alvyynm Sep 18, 2024
baaaae5
fix(test): add test id to check for testimonial content
alvyynm Sep 18, 2024
b67ad5c
fix(test): check 'TESTIMONIALS' section title & testimonial test
alvyynm Sep 18, 2024
cb7b4cd
fix(test): add test id to check for faq accordion
alvyynm Sep 18, 2024
f343525
fix(test): check 'FAQ' section title & FAQ accordion test
alvyynm Sep 18, 2024
e3c3eed
Merge branch 'Dev' into Landing-Page-Tests
alvyynm Oct 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/components/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import React from "react";
import { FiArrowRightCircle } from "react-icons/fi";
import { Link } from "react-router-dom";

function Button({ link, title }) {
function Button({ link, title, ...props }) {
return (
<Link
to={link}
role="button"
aria-label={title}
className="border rounded-full bg-white p-1 w-fit"
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
>
<div className="flex-center bg-green-light rounded-full px-3 py-1.5 gap-2">
<span className="capitalize text-green-header text-sm font-semibold">
Expand Down
2 changes: 2 additions & 0 deletions src/components/FAQ.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function FAQ({ questions = [] }) {
<div
key={question.id}
className="rounded-xl bg-white border shadow-sm mb-4 p-4"
data-testid="faq-accordion"
>
<h2 className="mb-4 font-semibold" id={`flush-heading${index + 1}`}>
<button
Expand Down Expand Up @@ -58,6 +59,7 @@ function FAQ({ questions = [] }) {
data-te-collapse-show
aria-labelledby={`flush-heading${index + 1}`}
data-te-parent="#accordionFlushExample"
data-testid="accordion-answer"
>
<div className=" ">{question.answer}</div>
</div>
Expand Down
8 changes: 7 additions & 1 deletion src/pages/landingPage/sections/OurEvents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ function OurEvents() {
<h4 className="text-green-dark text-[32px] leading-normal font-semibold">
Upcoming Events
</h4>
<Button link="/events" title="view more" />

<Button
link="/events"
title="view more"
data-testid="events-view-more"
/>
</div>

{isError && (
Expand Down Expand Up @@ -99,6 +104,7 @@ function UpcomingEventCard({ event }) {
<Link
to={`/events/${event.id}`}
className="bg-white border flex items-center flex-col md:flex-row justify-start rounded-xl p-4 gap-4 min-w-[320px] w-full"
data-testid="event-cards"
>
<div className="border bg-white p-1 rounded-lg w-full md:w-fit">
<div className="flex-center flex-col bg-green-light text-green-dark aspect-video md:size-[120px] rounded-[4px] font-bold">
Expand Down
2 changes: 1 addition & 1 deletion src/pages/landingPage/sections/StatsSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function StatsSection() {
A community geared towards holistic results{" "}
</h3>

<div className="w-full flex flex-col gap-6 p-2">
<div className="w-full flex flex-col gap-6 p-2 stats-card">
<div className="flex items-center flex-wrap md:flex-nowrap gap-4">
<div className="w-full flex-center flex-col gap-5">
<img src={teams} alt="teams" className="size-10 object-contain" />
Expand Down
5 changes: 4 additions & 1 deletion src/pages/landingPage/sections/TestimonialSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { testimonialData } from "../data";

function TestimonialSection() {
return (
<section className="max-w-1440 w-full mx-auto flex flex-col items-center gap-8 pt-2">
<section
className="max-w-1440 w-full mx-auto flex flex-col items-center gap-8 pt-2"
data-testid="testimonial-card"
>
<h3 className="w-full max-w-md text-green-header text-center font-semibold text-xl md:text-3xl">
What people are saying about us{" "}
</h3>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/landingPage/sections/WhatWeDo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function WhatWeDoCard({ card, index }) {
const { title, description, image, link } = card;
return (
<div
className={`border bg-white p-2 w-full rounded-2xl md:rounded-[20px] ${
className={`border bg-white p-2 w-full rounded-2xl md:rounded-[20px] what-we-do-content ${
index === 0 && "lg:col-span-2"
}`}
>
Expand Down
91 changes: 91 additions & 0 deletions tests/pages/landing-page.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,95 @@
})
).toBeVisible();
});

// eslint-disable-next-line quotes
test('Check "View More" button functionality', async ({ page }) => {
// Verify that the "View More" button is present and clickable
// eslint-disable-next-line quotes
const viewMoreButton = page.locator('text="View More"').first();
await expect(viewMoreButton).toBeVisible();
await expect(viewMoreButton).toBeEnabled();

await viewMoreButton.click();
await page.waitForTimeout(1000);
});

// Test "HOW WE WORK" section
test("Check 'HOW WE WORK' section title and content", async ({ page }) => {
// eslint-disable-next-line quotes
const howWeWorkSection = page.locator('text="How we work"').first();
await expect(howWeWorkSection).toBeVisible();
});

test("Check 'WHAT WE DO' section title and content", async ({ page }) => {
// eslint-disable-next-line quotes
const whatWeDoSection = page.locator('text="what we do"');
await expect(whatWeDoSection).toBeVisible();

const whatWeDoContent = page.locator(".what-we-do-content").first();
await expect(whatWeDoContent).toBeVisible();
});

test("Check 'OUR EVENTS' section title, events card, and 'View More' button", async ({
page,
}) => {
// eslint-disable-next-line quotes
const ourEventsSection = page.locator('text="our events"').first();
await expect(ourEventsSection).toBeVisible();

// checks if at least one event card is displayed
const eventCards = page.locator("data-testid=event-cards").first();
await expect(eventCards).toBeVisible();

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

1) [chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

1) [chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

1) [chromium] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

2) [webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

2) [webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

Check failure on line 62 in tests/pages/landing-page.spec.js

View workflow job for this annotation

GitHub Actions / tests

[webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title

2) [webkit] › pages/landing-page.spec.js:53:3 › Landing page tests › Check 'OUR EVENTS' section title, events card, and 'View More' button Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Error: Timed out 5000ms waiting for expect(locator).toBeVisible() Locator: locator('data-testid=event-cards').first() Expected: visible Received: <element(s) not found> Call log: - expect.toBeVisible with timeout 5000ms - waiting for locator('data-testid=event-cards').first() 60 | // checks if at least one event card is displayed 61 | const eventCards = page.locator("data-testid=event-cards").first(); > 62 | await expect(eventCards).toBeVisible(); | ^ 63 | 64 | const viewMoreEventsButton = page.locator("data-testid=events-view-more"); 65 | await expect(viewMoreEventsButton).toBeVisible(); at /home/runner/work/SYT-Web-Redesign/SYT-Web-Redesign/tests/pages/landing-page.spec.js:62:30

const viewMoreEventsButton = page.locator("data-testid=events-view-more");
await expect(viewMoreEventsButton).toBeVisible();
await expect(viewMoreEventsButton).toBeEnabled();
await viewMoreEventsButton.click();
expect(page.url()).toBe("http://localhost:5173/events");
});

test("Check 'OUR IMPACT' section title and stats card", async ({ page }) => {
// eslint-disable-next-line quotes
const ourImpactSection = page.getByText("our impact");
await ourImpactSection.scrollIntoViewIfNeeded();
await expect(ourImpactSection).toBeVisible();

const statsCards = page.locator(".stats-card");
await expect(statsCards).toBeVisible();
});

test("Check 'TESTIMONIALS' section title and testimonial card in marquee", async ({
page,
}) => {
// eslint-disable-next-line quotes
const testimonialsSection = page.getByRole("heading", {
name: "testimonials",
});
// await testimonialsSection.waitFor({ state: "visible", timeout: 60000 });
await testimonialsSection.scrollIntoViewIfNeeded();
await expect(testimonialsSection).toBeVisible();

// check if there's at least one testimonial card displayed
const testimonialCards = page.getByTestId("testimonial-card").first();
await testimonialCards.waitFor({ state: "visible", timeout: 60000 });
await testimonialCards.scrollIntoViewIfNeeded();
await expect(testimonialCards).toBeVisible();
});

test("Check 'FAQ' section title and FAQ accordion", async ({ page }) => {
// eslint-disable-next-line quotes
// check if faq section is visible
const faqSection = page.getByRole("heading", { name: "faq" });
await expect(faqSection).toBeVisible();

// check if at least one FAQ accordion is visible
const faqAccordions = page.getByTestId("faq-accordion").first();
await expect(faqAccordions).toBeVisible();

// check if clicking accordion, displays answer
await faqAccordions.click();

const accordionContent = page.getByTestId("accordion-answer").first();
await expect(accordionContent).toBeVisible();
});
});
37 changes: 37 additions & 0 deletions vite.config.js.timestamp-1724936058326-f5c1406d3f0ad.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// vite.config.js
import path, { dirname } from "path";
import { fileURLToPath } from "url";
import react from "file:///home/andrew-dev/Desktop/Dev/SYT/SYT-Web-Redesign/node_modules/.pnpm/@[email protected][email protected]_@[email protected]_/node_modules/@vitejs/plugin-react/dist/index.mjs";
import million from "file:///home/andrew-dev/Desktop/Dev/SYT/SYT-Web-Redesign/node_modules/.pnpm/[email protected][email protected]/node_modules/million/dist/packages/compiler.mjs";
import { defineConfig, loadEnv } from "file:///home/andrew-dev/Desktop/Dev/SYT/SYT-Web-Redesign/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/index.js";
var __vite_injected_original_import_meta_url = "file:///home/andrew-dev/Desktop/Dev/SYT/SYT-Web-Redesign/vite.config.js";
var __filename = fileURLToPath(__vite_injected_original_import_meta_url);
var __dirname = dirname(__filename);
var vite_config_default = defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
return {
define: {
"process.env.REACT_APP_API_BASE_URL": JSON.stringify(
env.REACT_APP_API_BASE_URL
)
},
plugins: [million.vite({ auto: true }), react()],
test: {
include: ["src/**/*.test.js"]
},
server: {
watch: {
usePolling: true
}
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
}
}
};
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS9hbmRyZXctZGV2L0Rlc2t0b3AvRGV2L1NZVC9TWVQtV2ViLVJlZGVzaWduXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvaG9tZS9hbmRyZXctZGV2L0Rlc2t0b3AvRGV2L1NZVC9TWVQtV2ViLVJlZGVzaWduL3ZpdGUuY29uZmlnLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9ob21lL2FuZHJldy1kZXYvRGVza3RvcC9EZXYvU1lUL1NZVC1XZWItUmVkZXNpZ24vdml0ZS5jb25maWcuanNcIjsvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlICovXG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG5pbXBvcnQgcGF0aCwgeyBkaXJuYW1lIH0gZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwidXJsXCI7XG5pbXBvcnQgcmVhY3QgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXJlYWN0XCI7XG5pbXBvcnQgbWlsbGlvbiBmcm9tIFwibWlsbGlvbi9jb21waWxlclwiO1xuaW1wb3J0IHsgZGVmaW5lQ29uZmlnLCBsb2FkRW52IH0gZnJvbSBcInZpdGVcIjtcblxuY29uc3QgX19maWxlbmFtZSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKTtcbmNvbnN0IF9fZGlybmFtZSA9IGRpcm5hbWUoX19maWxlbmFtZSk7XG5cbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoKHsgbW9kZSB9KSA9PiB7XG4gIGNvbnN0IGVudiA9IGxvYWRFbnYobW9kZSwgcHJvY2Vzcy5jd2QoKSwgXCJcIik7XG4gIHJldHVybiB7XG4gICAgZGVmaW5lOiB7XG4gICAgICBcInByb2Nlc3MuZW52LlJFQUNUX0FQUF9BUElfQkFTRV9VUkxcIjogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGVudi5SRUFDVF9BUFBfQVBJX0JBU0VfVVJMXG4gICAgICApLFxuICAgIH0sXG4gICAgcGx1Z2luczogW21pbGxpb24udml0ZSh7IGF1dG86IHRydWUgfSksIHJlYWN0KCldLFxuICAgIHRlc3Q6IHtcbiAgICAgIGluY2x1ZGU6IFtcInNyYy8qKi8qLnRlc3QuanNcIl0sXG4gICAgfSxcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIHdhdGNoOiB7XG4gICAgICAgIHVzZVBvbGxpbmc6IHRydWUsXG4gICAgICB9LFxuICAgIH0sXG4gICAgcmVzb2x2ZToge1xuICAgICAgYWxpYXM6IHtcbiAgICAgICAgXCJAXCI6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIFwiLi9zcmNcIiksXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFHQSxPQUFPLFFBQVEsZUFBZTtBQUM5QixTQUFTLHFCQUFxQjtBQUM5QixPQUFPLFdBQVc7QUFDbEIsT0FBTyxhQUFhO0FBQ3BCLFNBQVMsY0FBYyxlQUFlO0FBUG9LLElBQU0sMkNBQTJDO0FBUzNQLElBQU0sYUFBYSxjQUFjLHdDQUFlO0FBQ2hELElBQU0sWUFBWSxRQUFRLFVBQVU7QUFHcEMsSUFBTyxzQkFBUSxhQUFhLENBQUMsRUFBRSxLQUFLLE1BQU07QUFDeEMsUUFBTSxNQUFNLFFBQVEsTUFBTSxRQUFRLElBQUksR0FBRyxFQUFFO0FBQzNDLFNBQU87QUFBQSxJQUNMLFFBQVE7QUFBQSxNQUNOLHNDQUFzQyxLQUFLO0FBQUEsUUFDekMsSUFBSTtBQUFBLE1BQ047QUFBQSxJQUNGO0FBQUEsSUFDQSxTQUFTLENBQUMsUUFBUSxLQUFLLEVBQUUsTUFBTSxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUM7QUFBQSxJQUMvQyxNQUFNO0FBQUEsTUFDSixTQUFTLENBQUMsa0JBQWtCO0FBQUEsSUFDOUI7QUFBQSxJQUNBLFFBQVE7QUFBQSxNQUNOLE9BQU87QUFBQSxRQUNMLFlBQVk7QUFBQSxNQUNkO0FBQUEsSUFDRjtBQUFBLElBQ0EsU0FBUztBQUFBLE1BQ1AsT0FBTztBQUFBLFFBQ0wsS0FBSyxLQUFLLFFBQVEsV0FBVyxPQUFPO0FBQUEsTUFDdEM7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
Loading